Skip to main content

Root Directory

App workspace

App/
├── src/ # Source code
├── public/ # Static assets (images, icons, brand)
├── next.config.mjs # Next.js config (image domains, etc.)
├── tsconfig.json # TypeScript config (`@/*` → `./src/*`)
├── tailwind.config.ts # TailwindCSS theme + plugins
├── postcss.config.mjs # PostCSS configuration
├── vercel.json # Vercel deployment config (branch → environment mapping)
├── package.json # Dependencies + scripts
├── yarn.lock # Lockfile
└── components.json # shadcn/ui registry config

Repository layout

civiq-validation/
├── App/ # The Next.js application (described above)
├── docs/ # Docusaurus documentation site (this site)
├── supabase/
│ ├── functions/ # Edge Functions (Deno) — see Supabase Backend docs
│ ├── migrations/ # SQL migrations
│ ├── snippets/ # Saved SQL snippets
│ ├── templates/ # Auth email templates
│ ├── seed.sql # Seed data for local dev
│ └── config.toml # Supabase CLI config
└── README.md

Configuration files

FilePurpose
next.config.mjsImage domain allow-list (Supabase Storage host) + experimental flags
tsconfig.jsonTS compiler options + @/* path alias
tailwind.config.tsTheme, plugins (tailwindcss-animate), content globs
vercel.jsonBranch-based deployments for main, dev, staging
package.jsonProject metadata, runtime + dev dependencies, scripts (dev, build, start)
components.jsonshadcn/ui configuration
supabase/config.tomlLocal Supabase project + edge-function settings

Middleware Entry Point

Location: src/middleware.ts

Purpose: Next.js Edge middleware entry. Delegates to src/lib/supabase/updateSession.ts, which refreshes the Supabase session, redirects unauthenticated requests to /auth/sign-in, and POSTs to /api/permissions/revalidate on real browser refreshes.

Permission-key gating itself does not live in the middleware. See Middleware & Route Protection.

File Naming Conventions

Server Actions

  • Pattern: *-action.ts (e.g. create-campaign-action.ts).
  • Marked with "use server". Returns FormState.

Services

  • Pattern: get*.ts, fetch*.ts, create*.ts, update*.ts.
  • Server-only. Returns QueryResponse.

Components

  • Pattern: kebab-case.tsx. Domain-grouped under src/components/{domain}/.

Types

  • Pattern: camelCase.ts named after the domain noun.

Hooks

  • Pattern: use*.ts / use*.tsx.

Best Practices

  1. Separation of Concerns

    • Actions handle mutations and call services.
    • Services handle data access and never mutate UI.
    • Components handle UI; route guards handle access.
    • Types provide envelopes (QueryResponse, FormState).
  2. Code Organization

    • Group by domain (campaign, petitions, teams).
    • Co-locate Zod schemas with the form they validate.
  3. Reusability

    • Common UI primitives in components/ui/ and components/common/.
    • Sidebar bundles in components/routes/ read permissionKeys from TeamsContext.
  4. Type Safety

    • All public surfaces typed; runtime validation via Zod at every action boundary.

Directory size summary (approx)

DirectoryFilesPurpose
actions/30+Server Actions for mutations
app/100+Next.js routes, pages, layouts, API routes
components/250+React components (UI, domain features, route bundles)
context/7React Context providers
hooks/12Custom React hooks
lib/25+Utilities, Supabase clients, permission/Redis helpers
middleware/10+Legacy route pipelines (reference); active middleware lives at src/middleware.ts
services/50+Data access layer (incl. accessCheck/, roles/)
types/19TypeScript types