Folder Structure
A complete walkthrough of CareNova's project directory — what lives where and why it is organized that way.
Written By Dev010
Last updated 20 days ago
CareNova follows a consistent folder structure that mirrors the architecture — every file has a clear home and a clear reason for being there. This guide walks through each directory so you can navigate the codebase confidently from day one.
Root Directory
carenova-app/
├── app/ # Next.js App Router — all routes and pages
├── components/ # Reusable UI components
├── lib/ # Shared logic, actions, DB, cache, auth
├── contexts/ # React contexts (preferences, theme)
├── types/ # Shared TypeScript type definitions
├── messages/ # next-intl translation files
├── docs/ # Internal documentation
├── migrations/ # SQL migration files
├── scripts/ # Seed and utility scripts
├── public/ # Static assets served at /
├── INSTALL.sql # Master database installation SQL
├── middleware.ts # Next.js middleware (auth, routing, license)
├── next.config.js # Next.js configuration
├── tailwind.config.ts # Tailwind CSS configuration
└── tsconfig.json # TypeScript configurationapp/
The app/ directory contains all routes using the Next.js App Router file-system convention.
app/
├── layout.tsx # Root layout — fonts, providers, globals
├── page.tsx # Public landing page (clinic-type branching)
├── fonts.ts # Font loading configuration
├── globals.css # Global CSS and design tokens
├── _components/ # App-level shared components (e.g. landing FAQ)
├── api/ # API route handlers
│ ├── patients/export/ # CSV export for patients
│ ├── appointments/export/# CSV export for appointments
│ ├── teeth-image/ # Teeth image handler for odontogram
│ └── cron/cleanup-auth/ # Auth cleanup cron job endpoint
├── (auth)/ # Auth route group — no dashboard layout
│ ├── login/
│ ├── signup/
│ └── auth/callback/ # Supabase OAuth callback
├── (dashboard)/ # Dashboard route group — sidebar + header layout
│ └── dashboard/ # All dashboard module pages
├── blog/ # Public blog index and post detail
├── appointment/ # Public appointment booking page
├── portal/ # Patient portal (placeholder)
└── policies/[slug]/ # Dynamic policy pagesRoute groups in parentheses — (auth) and (dashboard) — are a Next.js convention. The group name does not appear in the URL. They exist purely to apply a shared layout to everything inside them without affecting the route path.
app/(dashboard)/dashboard/
All dashboard module pages live here. Each module is a folder with its own page.tsx and optional sub-routes.
dashboard/
├── layout.tsx # Dashboard layout — sidebar, header, auth check
├── page.tsx # Role-specific dashboard home
├── _components/ # Dashboard-wide shared components
│ ├── app-sidebar.tsx # Sidebar shell
│ ├── nav-main.tsx # Navigation items with role/permission filters
│ ├── dashboard-header.tsx
│ ├── nav-user.tsx # User menu in sidebar footer
│ ├── theme-switcher.tsx
│ ├── revenue-chart.tsx
│ ├── activity-chart.tsx
│ └── ...
├── patients/
│ ├── page.tsx # Patient list
│ ├── new/page.tsx # Create patient
│ └── [id]/
│ ├── page.tsx # Patient detail
│ └── edit/page.tsx # Edit patient
├── appointments/
│ ├── page.tsx
│ └── [id]/edit/page.tsx
├── calendar/page.tsx
├── medical-records/
│ ├── page.tsx
│ ├── vitals/page.tsx
│ ├── clinical-notes/page.tsx
│ ├── diagnoses/page.tsx
│ ├── attachments/page.tsx
│ └── visit-timeline/page.tsx
├── odontograms/page.tsx
├── prescriptions/
│ ├── page.tsx
│ └── new/page.tsx
├── test-reports/
│ ├── page.tsx
│ ├── new/page.tsx
│ ├── tests/page.tsx
│ ├── methodologies/page.tsx
│ ├── turnaround-times/page.tsx
│ ├── sample-types/page.tsx
│ └── categories/page.tsx
├── invoices/
│ ├── page.tsx
│ ├── new/page.tsx
│ └── [id]/page.tsx
├── payments/page.tsx
├── expenses/
│ ├── page.tsx
│ └── new/page.tsx
├── billing/
│ ├── page.tsx
│ └── new/page.tsx
├── services/page.tsx
├── departments/page.tsx
├── inventory/
│ ├── page.tsx
│ ├── new/page.tsx
│ └── [id]/
│ ├── page.tsx
│ └── edit/page.tsx
├── staff/page.tsx
├── lab-vendors/
│ ├── page.tsx
│ └── new/page.tsx
├── blog/
│ ├── page.tsx
│ └── categories/page.tsx
├── permissions/page.tsx
├── landing-settings/page.tsx
├── pending-approval/page.tsx
├── settings/page.tsx
└── coming-soon/page.tsxcomponents/
Reusable UI components that are referenced across multiple pages or modules.
components/
├── ui/ # shadcn/ui primitives
│ ├── button.tsx
│ ├── card.tsx
│ ├── dialog.tsx
│ ├── input.tsx
│ ├── select.tsx
│ ├── sheet.tsx
│ ├── table.tsx
│ └── ... # All shadcn components
├── landing/ # Public landing page components
│ ├── dental/ # DentalHero, DentalServices, DentalFooter, etc.
│ ├── ophthalmology/ # OphthalmologyHero, OphthalmologyServices, etc.
│ └── general/ # GeneralHero, GeneralServices, etc.
├── dashboard/ # Shared dashboard components
│ ├── full-profile-button.tsx
│ └── ...
└── settings/ # Settings UI components
└── landing/
├── landing-page-settings.tsx
├── colors-tab.tsx
└── content-tab.tsxComponents specific to a single module live inside that module's folder under app/(dashboard)/dashboard/{module}/_components/ rather than in the top-level components/ directory. Only genuinely shared components belong at the top level.
lib/
The core of the application logic — server actions, database access, auth helpers, caching, validation schemas, and constants.
lib/
├── actions/ # Server Actions ("use server")
│ ├── patient-actions.ts
│ ├── appointment-actions.ts
│ ├── invoice-actions.ts
│ ├── payment-actions.ts
│ ├── expense-actions.ts
│ ├── medical-records-actions.ts
│ ├── prescription-actions.ts
│ ├── lab-test-actions.ts
│ ├── staff-actions.ts
│ ├── inventory-actions.ts
│ ├── service-actions.ts
│ ├── department-actions.ts
│ ├── odontogram-actions.ts
│ ├── permission-actions.ts
│ ├── auth-actions.ts
│ ├── clinic-actions.ts
│ ├── landing-settings-actions.ts
│ ├── blog-actions.ts
│ ├── blog-category-actions.ts
│ └── notification-actions.ts
├── auth/ # Auth utilities
│ ├── index.ts # getAuthUser, getCurrentUser, requireRole
│ ├── require-permission.ts # requirePermission, checkPermission
│ ├── audit.ts # Auth audit log, rate limiting
│ ├── session-tracking.ts # Session create, revoke, cleanup
│ └── password-policy.ts # Password validation rules
├── cache/ # Caching helpers
│ ├── index.ts # getCachedCurrentUser, getCachedClinic, etc.
│ └── invalidators.ts # Cache invalidation functions
├── constants/ # Shared constants
│ ├── permissions.ts # PERMISSION_KEYS, DEFAULT_ROLE_PERMISSIONS
│ ├── expenses.ts # Expense category constants
│ └── landing-defaults.ts # Default settings per clinic type
├── data/ # Static default data
│ └── landing-defaults/
│ ├── dental.json
│ ├── ophthalmology.json
│ └── general.json
├── db/ # Database layer
│ ├── index.ts # Drizzle client instance
│ ├── schema.ts # All table definitions (single source of truth)
│ └── seed.ts # Seed script
├── supabase/ # Supabase client helpers
│ ├── server.ts # createClient() for server components/actions
│ ├── middleware.ts # updateSession() for middleware
│ └── admin.ts # getSupabaseAdmin() using service role key
├── validations/ # Zod schemas
│ ├── patient.ts
│ ├── appointment.ts
│ ├── invoice.ts
│ └── ...
├── preferences/ # User/clinic preference constants
│ └── constants.ts # Cookie names, locale options, etc.
├── utils/ # General utility functions
│ └── safe-async.ts # Background task error wrapper
├── config.ts # siteConfig (debug flag, site URL, etc.)
├── debug.ts # Conditional debug logger
└── i18n.ts # next-intl i18n configurationKey Files to Know
These files have outsized importance in the codebase — understanding them makes everything else easier to navigate.
messages/
Translation files for next-intl. Organized by locale at the top level for dashboard strings, and by clinic type and locale for landing page strings.
messages/
├── en.json # Dashboard translations — English
├── fr.json # Dashboard translations — French
├── es.json # Dashboard translations — Spanish
├── ar.json # Dashboard translations — Arabic
└── landing/
├── dental/
│ ├── en.json
│ ├── fr.json
│ ├── es.json
│ └── ar.json
├── general/
│ └── ...
└── ophthalmology/
└── ...public/
Static assets served directly by the web server at the root URL.
public/
├── landing/
│ ├── dental/ # Default dental landing images
│ ├── ophthalmology/ # Default ophthalmology landing images
│ └── general/ # Default general landing images
├── teeth/ # Teeth images for odontogram
│ └── ... # Populated by npm run download-teeth
└── ... # Favicons, og images, etc.Landing images in public/landing/ are the fallback defaults. When a clinic uploads custom images via Landing Settings, those Supabase Storage URLs are used instead.