Codebase Structure, Architecture & Code Standards
Related Documentation
- Project Overview & PDR - Project goals, scope, and requirements
- Codebase Summary - High-level overview of repository structure and technologies
Guiding Principles
- YAGNI (You Ain't Gonna Need It): Do not add functionality until it is deemed necessary. Avoid premature optimization and feature creep.
- KISS (Keep It Simple, Stupid): Favor simple, straightforward solutions over complex ones. If a piece of code is hard to understand, it's probably wrong.
- DRY (Don't Repeat Yourself): Abstract common logic into reusable functions or components, but not prematurely. A little duplication is better than the wrong abstraction.
Monorepo Standards
- Workspace Boundaries:
nextjs: Contains only front-end application code.supabase: Contains only database and backend configuration.docs: Contains only documentation.
- Dependency Rules:
- The
nextjsapp can depend on root-level packages. - Do not create circular dependencies between workspaces.
- Use
pnpmto manage workspaces and dependencies.
- The
Directory Conventions
- /nextjs/app: Follows Next.js App Router conventions. Group feature-specific files (e.g., components, services) within their respective route segments.
- /supabase/migrations: All database schema changes must be managed through versioned migration files generated by the Supabase CLI.
- /docs: All developer and project documentation lives here.
- /openspec: All major architectural decisions or new features must start with a proposal here.
- New Top-Level Dirs: Adding a new top-level directory requires an OpenSpec proposal to justify its necessity (e.g., a shared
packages/uilibrary).
Module & Feature Organization
- New Feature in Next.js:
- Create a new route segment in
/nextjs/app/(main)/my-feature. - Co-locate components, services, and types related to that feature within the
my-featuredirectory. - Shared components go in a top-level
/nextjs/componentsdirectory.
- Create a new route segment in
Data Access & Supabase Usage
- RLS is Mandatory: All tables must have Row-Level Security policies. Publicly accessible data should have a specific, read-only policy.
- Schema Changes: All schema changes must be done via
supabase db diffand committed as a new migration file. Do not make changes directly in the Supabase dashboard. - Migration Governance: See
docs/onboarding-guide/database-migrations.md.
Authentication & Authorization Patterns
- The canonical approach is summarized in
docs/onboarding-guide/authentication.md. - Use the Supabase client for all authentication operations.
- Authorization is enforced at the database level via RLS, not in the application code. See
docs/onboarding-guide/authorization-rls.md.
Error Handling & Logging
- Minimal Strategy:
- Use a centralized logging service (to be determined).
- API routes should catch errors and return a consistent JSON error format.
- What Not To Do: Do not
console.logsensitive information. Do not expose raw database errors to the client.
Configuration & Secrets
- Use
.env.localfor local development secrets. - All secrets exposed to the browser must be prefixed with
NEXT_PUBLIC_. - Server-side secrets should be accessed directly via
process.env. - Avoid scattering configuration; centralize it where possible.
Performance & Optimization Guidelines
- When to Optimize: Optimize only when there is a measured performance problem.
- Forbidden Patterns:
- Fetching large datasets without pagination.
- Complex joins in hot paths; favor denormalization where appropriate.
- Blocking the main thread with long-running synchronous operations.
- See
docs/onboarding-guide/performance-optimization.md.
Security Standards
- OWASP Top 10: Be mindful of common vulnerabilities like Injection, Broken Authentication, and Sensitive Data Exposure.
- Least Privilege: RLS policies should be as restrictive as possible.
- No Client Secret Leaks: Never expose your Supabase
service_rolekey or any other private key to the client-side code.
Testing Standards
- Unit Tests: Required for all pure business logic (e.g., utility functions).
- Integration Tests: Required for all new API routes to test their interaction with the database.
- Smoke Tests: A basic set of E2E tests should be run against a deployed environment to ensure critical paths are working.
Pull Request & Spec Process
- Trivial Change: A small bug fix or documentation update can be a direct PR.
- Proposal Required: Any new feature, breaking change, or significant refactor must have an approved OpenSpec proposal before implementation begins. The PR description must link to the proposal.
Documentation Update Requirements
- New Component: Add JSDoc or TSDoc comments.
- New API Route: Update the API documentation, including request/response formats.
- Architectural Change: Update the relevant sections in the
/docsdirectory.
Anti-Patterns
- Fat API Routes: Keep API routes thin. Move business logic into service functions.
- Bypassing RLS: Using the
service_rolekey in the Next.js app is a major security risk and is forbidden. - Manual DB Changes: Making schema changes via the Supabase UI will cause migration drift and is forbidden.
Checklist for New Feature Merge
- Linked OpenSpec proposal is approved.
- Code adheres to all standards in this document.
- Unit and/or integration tests are included and passing.
- Documentation (
/docs) is updated. - CI checks are all passing.
- PR has been reviewed and approved by at least one other team member.