Full-Stack AI Application

DentFlow AI

Modern dental practice management with AI-assisted diagnostics, patient management, and intelligent scheduling. Next.js 16 + Prisma + OpenAI.

📅 2026 🔌 Under development Stack · TypeScript · Next.js 16 · Prisma · PostgreSQL · OpenAI · Radix UI · Tailwind · next-auth 🔗 GitHub

01 The Problem

Dental practices are small businesses running on outdated software. Legacy practice management systems (PMS) are monolithic, on-premise, and built with technology stacks from a decade ago. Dentists juggle multiple windows — one for scheduling, one for billing, one for charting, one for imaging — with little to no integration between them. Patient data lives in silos, appointment scheduling is a manual puzzle of provider availability, procedure duration, and equipment constraints, and there is no AI assistance for diagnostics or treatment planning.

The core question: could a modern, AI-native web application replace the fragmented legacy stack? Not just digitising existing workflows, but reimagining them — with AI-assisted X-ray analysis, intelligent scheduling that understands procedure constraints, and a unified patient record that surfaces insights instead of just storing data.

02 Architecture

DentFlow AI uses Next.js 16 App Router with Server Actions as the primary data mutation layer. The application is organised into feature modules that each own their data, UI, and business logic — Patient Manager, Appointments, AI Assistant, Billing, and Settings — all sharing a common data layer through Prisma ORM.

Next.js 16 (App Router, Server Actions)
├── Patient Manager
├── Appointments
├── AI Assistant (OpenAI)
├── Billing
└── Settings
    │
    ▼
Data Layer
├── Prisma ORM → PostgreSQL
└── OpenAI API (AI Diagnostics)

Auth: next-auth (Credentials + OAuth)
⚡ Design Decision

Server Actions were chosen over a separate API layer for data mutations because they eliminate client-server boilerplate, run type-safe queries through Prisma, and enable optimistic UI updates with zero extra plumbing. For webhook or third-party integrations, we fall back to Route Handlers.

03 Tech Stack

Every component was chosen for developer experience, type safety, and accessibility. TypeScript runs from the database schema (Prisma) through to the UI (Tailwind + cva).

Component Chosen Technology Role
Runtime TypeScript End-to-end type safety, schema to UI
Framework Next.js 16 App Router Server components, Server Actions, file-based routing, streaming SSR
ORM & Database Prisma ORM + PostgreSQL Type-safe queries, migrations, relation management
AI / LLM OpenAI API (GPT-4o / Vision) AI diagnostic assistance, X-ray analysis, treatment suggestions
UI Components Radix UI (Dialog, Popover, Select, Tabs, Tooltip) Accessible, composable, unstyled primitives
Styling Tailwind CSS + cva Utility-first styling with component variants
Authentication next-auth v5 Credentials + OAuth, session management, middleware protection
Utilities date-fns, bcryptjs, Vitest Date manipulation, password hashing, testing
Why This Stack

Next.js 16 App Router with Server Components eliminates the client-side JavaScript tax for data-heavy pages. Prisma + PostgreSQL provides a type-safe database layer that catches schema errors at compile time. Radix UI delivers production-grade accessibility without visual opinionation. Together they compose into a stack that scales in complexity without scaling in cognitive overhead.

04 Key Challenges

📝 1. Healthcare Data Sensitivity (PHI Compliance)

Dental practices handle Protected Health Information (PHI) — patient records, X-rays, treatment plans, insurance details. HIPAA compliance requires airtight authentication, role-based access control, data encryption at rest and in transit, and audit logging. Every Server Action and Route Handler must verify the user's identity and authorisation before touching patient data. We enforce row-level security through Prisma's where clauses validated against the session user, never trusting client-side identifiers.

🔬 2. AI Diagnostics — Vision API for X-Ray Analysis

Integrating OpenAI's Vision API for dental X-ray interpretation presented a unique challenge: how do you surface AI insights without overstating certainty? Dental diagnostics are nuanced — a radiolucency could be caries, a restoration shadow, or an artefact. We implemented a tiered confidence scoring system: findings below 70% confidence are flagged as possible findings requiring clinical confirmation, between 70–90% as likely findings, and above 90% as high-confidence findings. Every AI suggestion is accompanied by the source region of interest (bounding box or heatmap) and a disclaimer that the AI is an assistant, not a replacement for a licensed dentist.

📅 3. Scheduling Complexity — A Constraint Satisfaction Problem

Dental appointment scheduling is deceptively complex. Each procedure has a duration range (30–180 minutes), requires specific provider qualifications, may need specialised equipment (e.g., surgical microscope, cone-beam CT), and must account for insurance pre-authorisation windows. Adding operatories (treatment rooms) as a shared resource turns scheduling into a multi-dimensional constraint satisfaction problem. We modelled this as a backtracking solver with forward-checking, pruning infeasible slots before presenting options to the frontend. The solver runs on the server and returns the top 5 available slots ranked by a heuristic that balances provider preference, patient history, and practice revenue.

🚀 Optimisation

The scheduling solver caches provider availability intents per session and incrementally invalidates only affected slots when a booking is created or cancelled. For a typical 5-provider practice with 8 operatories, the solver returns results in under 15ms on a cold start — fast enough for real-time UI feedback as the user adjusts date or provider filters.

🔌 4. Offline Resilience

Many dental clinics operate in areas with unreliable internet connectivity. A patient check-in or treatment note cannot wait for a round trip to the cloud. We implemented a local-first pattern using Service Workers and IndexedDB for caching critical data (today's appointments, active patient charts), with a background sync queue that replays mutations when connectivity is restored. Conflict resolution uses a last-writer-wins strategy with server-side timestamps, sufficient for the single-clinic use case where two staff members rarely edit the same record simultaneously.

Lesson Learned

Local-first adds an order of magnitude of complexity to state management. We initially tried an optimistic update approach everywhere, but it made the offline sync queue fragile. The simpler pattern — treat the server as source of truth, cache aggressively, and let the sync queue replay in sequence — proved more reliable. Offline support is not something you bolt on at the end; it must be designed from the database schema up.

Code Highlight

The Prisma schema models dental appointments with provider assignment, procedure duration, and insurance linkage — a constraint-satisfaction foundation for intelligent scheduling.

model Appointment {
  id          String   @id @default(cuid())
  patientId   String
  providerId  String
  startTime   DateTime
  endTime     DateTime
  duration    Int      // Minutes
  status      Status   @default(SCHEDULED)
  procedure   String   // Procedure code
  notes       String?
  insuranceId String?

  patient     Patient   @relation(fields: [patientId], references: [id])
  provider    Provider  @relation(fields: [providerId], references: [id])
  insurance   Insurance? @relation(fields: [insuranceId], references: [id])
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  @@index([providerId, startTime])
  @@index([patientId])
}

05 Results

AI Diagnostic Assistant (Vision API)
Full-Stack Next.js 16 + Prisma + PostgreSQL
Accessible Radix UI Components
Secure next-auth + bcryptjs

DentFlow AI is under active development. The architecture is fully established and core modules are operational. The Next.js 16 App Router foundation with Server Actions provides a clean, type-safe data flow. Prisma + PostgreSQL handle persistence with full migration management. The OpenAI integration routes diagnostic requests through a carefully calibrated confidence pipeline. Radix UI components deliver a keyboard-navigable, screen-reader-friendly interface out of the box. Authentication with next-auth v5 supports both credentials and OAuth providers.

06 What I Learned

DentFlow AI has been a deep exploration of building healthcare software with modern web technologies. Key takeaways:

📚 Lesson 1

Healthcare software is about restraint, not feature count. The temptation to add more AI capabilities is constant, but every diagnostic suggestion carries liability. Designing the AI confidence tiers — and building UI that honestly communicates uncertainty — was harder than wiring up the API call. In healthcare, the most important feature is knowing when not to act.

📚 Lesson 2

Prisma + Server Actions create an incredibly tight feedback loop. Schema changes flow into type-safe queries that the compiler validates before the code reaches a browser. There's no REST API versioning, no JSON serialisation mismatch, no undocumented endpoint. The cost is vendor lock-in to the Prisma ecosystem, but for a single-codebase full-stack application, the productivity gain is substantial.

📚 Lesson 3

Scheduling is a systems design problem disguised as a CRUD feature. What looks like "create an appointment" quickly becomes a constraint solver involving provider calendars, operatory availability, procedure durations, equipment requirements, and insurance rules. Abstracting that complexity behind a clean API — while keeping the UI responsive — required thinking in terms of search spaces and heuristics, not database queries.

📚 Lesson 4

Accessibility is part of the data model, not the UI layer. Using Radix UI primitives enforces accessible patterns at the component level, but true accessibility means thinking about keyboard workflows for scheduling, screen reader announcements for AI diagnostic results, and focus management in multi-step forms. These concern the data flow, not just the visual presentation.