# priyanshuraj20/dentwise architecture

> Architecture diagram of the GitHub repository priyanshuraj20/dentwise, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-25). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/priyanshuraj20/dentwise
- Repository: https://github.com/priyanshuraj20/dentwise

## Overview

1. **Overall shape**
   - Dentwise is a Next.js App Router SaaS with a mixed server/client architecture.
   - The app is split into user-facing experiences: landing, appointment booking, dashboard, admin management, Pro upsell, and an AI voice experience.

2. **Route-level domains**
   - `src/app/page.tsx` is the marketing landing page.
   - `src/app/appointments/page.tsx` contains the booking flow.
   - `src/app/dashboard/page.tsx` is the authenticated patient dashboard.
   - `src/app/admin/page.tsx` is the staff/admin console.
   - `src/app/pro/page.tsx` handles the paid-plan surface.
   - `src/app/voice/page.tsx` exposes the voice-agent experience.

3. **Authentication and access control**
   - The repo is built around **Clerk** for sign-in, identity, and subscription-aware access.
   - `src/proxy.ts` is the route boundary for auth/redirect logic.
   - `src/components/UserSync.tsx` and `src/lib/actions/users.ts` indicate a user-sync step between Clerk identity and the app’s own user record.

4. **Booking workflow**
   - The appointment experience is a multi-step client flow in `src/components/appointments/*`.
   - The booking path is explicitly staged as doctor selection → time/service selection → confirmation.
   - Hooks such as `src/hooks/use-doctors.ts` and `src/hooks/use-appointment.ts` likely coordinate fetching and state across those steps.

5. **Core data model and persistence**
   - **Prisma** is the data access layer, with the schema in `prisma/schema.prisma`.
   - `src/lib/prisma.ts` centralizes database access to a **PostgreSQL** backend.
   - The main persisted entities appear to be users, doctors, and appointments, since those are the server action modules present under `src/lib/actions/`.

6. **Server-side application logic**
   - Business operations are concentrated in Next.js server actions:
     - `src/lib/actions/appointments.ts`
     - `src/lib/actions/doctors.ts`
     - `src/lib/actions/users.ts`
   - This keeps write operations, validation, and database mutations on the server boundary rather than in client components.

7. **Email notification pipeline**
   - `src/app/api/send-appointment-email/route.ts` is a dedicated API route for sending transactional mail.
   - `src/lib/resend.ts` integrates with **Resend**.
   - `src/components/emails/AppointmentConfirmationEmail.tsx` defines the email content used for booking confirmations.
   - Net effect: booking data flows from the app into email delivery after persistence.

8. **Admin and operational console**
   - The admin area is built from a client shell plus focused management widgets:
     - `AdminDashboardClient.tsx`
     - `AdminStats.tsx`
     - `DoctorsManagement.tsx`
     - `RecentAppointments.tsx`
   - This subsystem is for operational visibility and CRUD-like maintenance of doctors and appointments.

9. **AI voice agent and paid-plan boundary**
   - `src/app/voice/page.tsx` and `src/components/voice/VapiWidget.tsx` integrate the **Vapi** voice agent.
   - `src/components/voice/ProPlanRequired.tsx` suggests the voice feature is gated behind subscription level.
   - The `pro` route appears to be the plan-upgrade/billing boundary that unlocks voice capabilities.

10. **UI system and client data fetching**
   - The app uses a shared design system built from **shadcn/ui** primitives in `src/components/ui/`.
   - Page-specific UI is organized into feature folders like `landing`, `dashboard`, `appointments`, `admin`, and `voice`.
   - `src/components/providers/TanStackProvider.tsx` shows **TanStack Query** is used for client-side caching and fetching where interactive screens need it.

11. **Runtime and deployment boundaries**
   - The project runs as a modern Next.js full-stack app on **Vercel**.
   - External dependencies are environment-driven: Clerk, PostgreSQL, Resend, and Vapi.
   - Static assets live in `public/`, while `next.config.ts`, `prisma/`, and the App Router directories define the main operational boundaries.

12. **Key end-to-end data flow**
   - Authenticated user enters the booking flow → selects doctor/time → server action writes to PostgreSQL via Prisma → confirmation email is sent through Resend → appointment becomes visible in dashboard/admin views.
   - The voice/pro flow is parallel: authenticated user enters `/voice` → entitlement is checked via subscription state → Vapi widget provides the AI interaction if allowed.

Main entry points: [`src/proxy.ts`](https://github.com/priyanshuraj20/dentwise/blob/main/src/proxy.ts) (Auth proxy), [`src/app/appointments/page.tsx`](https://github.com/priyanshuraj20/dentwise/blob/main/src/app/appointments/page.tsx) (Booking page), [`src/lib/actions/appointments.ts`](https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/actions/appointments.ts) (Appointment actions), [`src/app/dashboard/page.tsx`](https://github.com/priyanshuraj20/dentwise/blob/main/src/app/dashboard/page.tsx) (Patient dashboard)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_app["App surfaces"]
  node_landing_page["Landing page<br/>route<br/>[page.tsx]"]
  node_appointments_page["Booking page<br/>route<br/>[page.tsx]"]
  node_dashboard_page["Patient dashboard<br/>route<br/>[page.tsx]"]
  node_admin_page["Admin console<br/>route<br/>[page.tsx]"]
  node_pro_page["Pro page<br/>route<br/>[page.tsx]"]
  node_voice_page["Voice page<br/>route<br/>[page.tsx]"]
end

subgraph group_features["Feature UI"]
  node_appointment_flow["Booking flow<br/>client workflow"]
  node_admin_widgets["Admin widgets<br/>admin UI<br/>[AdminStats.tsx]"]
  node_dashboard_widgets["Dashboard widgets<br/>patient UI<br/>[WelcomeSection.tsx]"]
  node_landing_sections["Landing sections<br/>marketing UI<br/>[Hero.tsx]"]
  node_voice_widgets["Voice widgets<br/>voice UI<br/>[VapiWidget.tsx]"]
end

subgraph group_backend["Server core"]
  node_route_proxy{{"Auth proxy<br/>middleware boundary<br/>[proxy.ts]"}}
  node_appointment_actions{{"Appointment actions<br/>server actions<br/>[appointments.ts]"}}
  node_doctor_actions{{"Doctor actions<br/>server actions<br/>[doctors.ts]"}}
  node_user_actions{{"User actions<br/>server actions<br/>[users.ts]"}}
  node_prisma_db[("Prisma DB<br/>database access<br/>[schema.prisma]")]
  node_resend_api["Resend mail<br/>email integration<br/>[resend.ts]"]
  node_vapi_api["Vapi client<br/>voice integration<br/>[vapi.ts]"]
  node_send_email_route{{"Email API<br/>api route<br/>[route.ts]"}}
end

subgraph group_shared["Shared system"]
  node_user_sync["User sync<br/>identity bridge<br/>[UserSync.tsx]"]
  node_tanstack_provider["Query provider<br/>client provider"]
  node_email_template["Confirm email<br/>email template"]
end

node_route_proxy -->|"guards"| node_landing_page
node_route_proxy -->|"guards"| node_appointments_page
node_route_proxy -->|"guards"| node_dashboard_page
node_route_proxy -->|"guards"| node_admin_page
node_route_proxy -->|"guards"| node_pro_page
node_route_proxy -->|"guards"| node_voice_page
node_landing_page -->|"renders"| node_landing_sections
node_appointments_page -->|"renders"| node_appointment_flow
node_appointments_page -->|"syncs"| node_user_sync
node_dashboard_page -->|"renders"| node_dashboard_widgets
node_dashboard_page -->|"depends on"| node_user_sync
node_admin_page -->|"renders"| node_admin_widgets
node_pro_page -.->|"unlocks"| node_voice_page
node_voice_page -->|"renders"| node_voice_widgets
node_appointments_page -->|"reads/writes"| node_appointment_actions
node_appointment_flow -->|"calls"| node_appointment_actions
node_appointment_flow -->|"fetches"| node_doctor_actions
node_admin_widgets -->|"manages"| node_doctor_actions
node_admin_widgets -->|"reviews"| node_appointment_actions
node_user_sync -->|"writes"| node_user_actions
node_appointment_actions -->|"persists"| node_prisma_db
node_doctor_actions -->|"persists"| node_prisma_db
node_user_actions -->|"persists"| node_prisma_db
node_send_email_route -->|"sends via"| node_resend_api
node_send_email_route -->|"uses"| node_email_template
node_appointment_actions -.->|"triggers"| node_send_email_route
node_voice_widgets -->|"integrates"| node_vapi_api
node_appointments_page -.->|"uses"| node_tanstack_provider
node_dashboard_page -.->|"uses"| node_tanstack_provider

click node_landing_page "https://github.com/priyanshuraj20/dentwise/blob/main/src/app/page.tsx"
click node_appointments_page "https://github.com/priyanshuraj20/dentwise/blob/main/src/app/appointments/page.tsx"
click node_dashboard_page "https://github.com/priyanshuraj20/dentwise/blob/main/src/app/dashboard/page.tsx"
click node_admin_page "https://github.com/priyanshuraj20/dentwise/blob/main/src/app/admin/page.tsx"
click node_pro_page "https://github.com/priyanshuraj20/dentwise/blob/main/src/app/pro/page.tsx"
click node_voice_page "https://github.com/priyanshuraj20/dentwise/blob/main/src/app/voice/page.tsx"
click node_route_proxy "https://github.com/priyanshuraj20/dentwise/blob/main/src/proxy.ts"
click node_appointment_flow "https://github.com/priyanshuraj20/dentwise/blob/main/src/components/appointments/DoctorSelectionStep.tsx"
click node_admin_widgets "https://github.com/priyanshuraj20/dentwise/blob/main/src/components/admin/AdminStats.tsx"
click node_dashboard_widgets "https://github.com/priyanshuraj20/dentwise/blob/main/src/components/dashboard/WelcomeSection.tsx"
click node_landing_sections "https://github.com/priyanshuraj20/dentwise/blob/main/src/components/landing/Hero.tsx"
click node_voice_widgets "https://github.com/priyanshuraj20/dentwise/blob/main/src/components/voice/VapiWidget.tsx"
click node_user_sync "https://github.com/priyanshuraj20/dentwise/blob/main/src/components/UserSync.tsx"
click node_tanstack_provider "https://github.com/priyanshuraj20/dentwise/blob/main/src/components/providers/TanStackProvider.tsx"
click node_appointment_actions "https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/actions/appointments.ts"
click node_doctor_actions "https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/actions/doctors.ts"
click node_user_actions "https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/actions/users.ts"
click node_prisma_db "https://github.com/priyanshuraj20/dentwise/blob/main/prisma/schema.prisma"
click node_resend_api "https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/resend.ts"
click node_vapi_api "https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/vapi.ts"
click node_email_template "https://github.com/priyanshuraj20/dentwise/blob/main/src/components/emails/AppointmentConfirmationEmail.tsx"
click node_send_email_route "https://github.com/priyanshuraj20/dentwise/blob/main/src/app/api/send-appointment-email/route.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_landing_page,node_appointments_page,node_dashboard_page,node_admin_page,node_pro_page,node_voice_page toneBlue
class node_appointment_flow,node_admin_widgets,node_dashboard_widgets,node_landing_sections,node_voice_widgets toneAmber
class node_route_proxy,node_appointment_actions,node_doctor_actions,node_user_actions,node_prisma_db,node_resend_api,node_vapi_api,node_send_email_route toneMint
class node_user_sync,node_tanstack_provider,node_email_template toneRose
```

## Components

### App surfaces

Next.js routes and top-level user experiences

- [Landing page](https://github.com/priyanshuraj20/dentwise/blob/main/src/app/page.tsx): route · Marketing homepage · `src/app/page.tsx`
- [Booking page](https://github.com/priyanshuraj20/dentwise/blob/main/src/app/appointments/page.tsx): route · Multi-step appointment flow entry · `src/app/appointments/page.tsx`
- [Patient dashboard](https://github.com/priyanshuraj20/dentwise/blob/main/src/app/dashboard/page.tsx): route · Authenticated patient view · `src/app/dashboard/page.tsx`
- [Admin console](https://github.com/priyanshuraj20/dentwise/blob/main/src/app/admin/page.tsx): route · Staff management surface · `src/app/admin/page.tsx`
- [Pro page](https://github.com/priyanshuraj20/dentwise/blob/main/src/app/pro/page.tsx): route · Paid-plan and upgrade surface · `src/app/pro/page.tsx`
- [Voice page](https://github.com/priyanshuraj20/dentwise/blob/main/src/app/voice/page.tsx): route · AI voice experience entry · `src/app/voice/page.tsx`

### Feature UI

Domain-specific client components and screens

- [Booking flow](https://github.com/priyanshuraj20/dentwise/blob/main/src/components/appointments/DoctorSelectionStep.tsx): client workflow · Doctor, time, and confirmation steps · `src/components/appointments/DoctorSelectionStep.tsx`
- [Admin widgets](https://github.com/priyanshuraj20/dentwise/blob/main/src/components/admin/AdminStats.tsx): admin UI · Stats, doctor CRUD, and recent appointments · `src/components/admin/AdminStats.tsx`
- [Dashboard widgets](https://github.com/priyanshuraj20/dentwise/blob/main/src/components/dashboard/WelcomeSection.tsx): patient UI · Overview, actions, and next appointment panels · `src/components/dashboard/WelcomeSection.tsx`
- [Landing sections](https://github.com/priyanshuraj20/dentwise/blob/main/src/components/landing/Hero.tsx): marketing UI · Hero, pricing, CTA, and explainer sections · `src/components/landing/Hero.tsx`
- [Voice widgets](https://github.com/priyanshuraj20/dentwise/blob/main/src/components/voice/VapiWidget.tsx): voice UI · Vapi embed and subscription gate · `src/components/voice/VapiWidget.tsx`

### Server core

Server actions, persistence, and API boundaries

- [Auth proxy](https://github.com/priyanshuraj20/dentwise/blob/main/src/proxy.ts): middleware boundary · Route-level auth and redirect logic · `src/proxy.ts`
- [Appointment actions](https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/actions/appointments.ts): server actions · Write and read appointment state · `src/lib/actions/appointments.ts`
- [Doctor actions](https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/actions/doctors.ts): server actions · Doctor lookup and maintenance logic · `src/lib/actions/doctors.ts`
- [User actions](https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/actions/users.ts): server actions · User persistence and synchronization logic · `src/lib/actions/users.ts`
- [Prisma DB](https://github.com/priyanshuraj20/dentwise/blob/main/prisma/schema.prisma): database access · Central database client and schema-backed persistence · `prisma/schema.prisma`
- [Resend mail](https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/resend.ts): email integration · Transactional email delivery · `src/lib/resend.ts`
- [Vapi client](https://github.com/priyanshuraj20/dentwise/blob/main/src/lib/vapi.ts): voice integration · Voice-agent service configuration · `src/lib/vapi.ts`
- [Email API](https://github.com/priyanshuraj20/dentwise/blob/main/src/app/api/send-appointment-email/route.ts): api route · Dedicated appointment-email sending endpoint · `src/app/api/send-appointment-email/route.ts`

### Shared system

Reusable UI, providers, hooks, and integration helpers

- [User sync](https://github.com/priyanshuraj20/dentwise/blob/main/src/components/UserSync.tsx): identity bridge · Connects Clerk identity to app user records · `src/components/UserSync.tsx`
- [Query provider](https://github.com/priyanshuraj20/dentwise/blob/main/src/components/providers/TanStackProvider.tsx): client provider · Client caching and fetching setup · `src/components/providers/TanStackProvider.tsx`
- [Confirm email](https://github.com/priyanshuraj20/dentwise/blob/main/src/components/emails/AppointmentConfirmationEmail.tsx): email template · Appointment confirmation email content · `src/components/emails/AppointmentConfirmationEmail.tsx`

## Connections

- Auth proxy → Landing page: guards · Applies route access logic before public and protected pages
- Auth proxy → Booking page: guards · Controls access to booking flow
- Auth proxy → Patient dashboard: guards · Protects authenticated dashboard
- Auth proxy → Admin console: guards · Restricts staff console
- Auth proxy → Pro page: guards · Checks plan-related access
- Auth proxy → Voice page: guards · Restricts voice experience by entitlement
- Landing page → Landing sections: renders · Composes marketing sections
- Booking page → Booking flow: renders · Hosts the booking workflow
- Booking page → User sync: syncs · Ensures authenticated user exists in app DB
- Patient dashboard → Dashboard widgets: renders · Composes patient overview panels
- Patient dashboard → User sync: depends on · Requires synced user context
- Admin console → Admin widgets: renders · Composes admin management UI
- Pro page → Voice page: unlocks · Plan boundary for voice capabilities
- Voice page → Voice widgets: renders · Loads voice-agent interaction UI
- Booking page → Appointment actions: reads/writes · Fetches doctors and creates appointments
- Booking flow → Appointment actions: calls · Submits booking steps to server actions
- Booking flow → Doctor actions: fetches · Loads available doctors for selection
- Admin widgets → Doctor actions: manages · CRUD operations for doctors
- Admin widgets → Appointment actions: reviews · Displays recent and scheduled appointments
- User sync → User actions: writes · Creates or updates app user records
- Appointment actions → Prisma DB: persists · Stores appointment data in PostgreSQL via Prisma
- Doctor actions → Prisma DB: persists · Reads and updates doctor records
- User actions → Prisma DB: persists · Stores synced user records
- Email API → Resend mail: sends via · Delegates outbound email delivery
- Email API → Confirm email: uses · Renders appointment confirmation content
- Appointment actions → Email API: triggers · Kicks off confirmation email after booking
- Voice widgets → Vapi client: integrates · Embeds the voice-agent runtime
- Booking page → Query provider: uses · Interactive client fetching and cache support
- Patient dashboard → Query provider: uses · Client-side data access for dashboard widgets
