Coding Guidelines¶
General Principles
- AI-first coding using Cline, human-reviewed
- Language: TypeScript
- Modular, scalable folder structure
- Use Yarn for package manager
- Logs should be done using the current loggers.
- ESLint ignores should not be considered unless is a last resource.
- Husky is running with a pre-commit hook, that runs tests, linter and prettier.
- Minimum coverage for unit tests should follow industry standards: statements: 80, branches: 75, functions: 80, lines: 80,
App (Next.js in Vercel)
- Use App Router structure
- TailwindCSS (latest stable)
- Shadcn for components and blocks (layouts)
- If you need to make a new component because it is not in Shadcn, make it so it can be reused when possible
- State management via React Context or React Query with Supabase where needed
- Supabase is configured to send changes realtime so add the listeners as needed.
- It should be a responsive app, so mobile responsive needed.
- Each feature/component must have a unit test, using Jest, React Testing Library, MSW (Mock Service Worker) and @testing-library/react-hooks. Use others if needed.
- Each component should have it's own React Storybook
- Each new task should create/update the documentation in markdown
- Store sensitive info via Vercel Env variables, not hardcoded
- API routes are also hosted in Vercel
Logging Standards
- Use
clientLoggerfor all app logging: clientLogger.error()- Logs errors to console and sends to Grafana/Loki in productionclientLogger.info()- Logs info messages to console (development only, automatically suppressed in production)clientLogger.warn()- Logs warnings to console (development only, automatically suppressed in production)clientLogger.debug()- Logs debug messages to console (development only, automatically suppressed in production)- Never use
console.log()directly - always use clientLogger - Error logs are always sent to monitoring, while info/warn/debug are development-only helpers
Service Layer Standards
- Location:
/packages/app/src/services/ - Naming: Use camelCase for service files (e.g.,
projectService.ts, notproject.service.ts) - Return Type: Always use consistent service response pattern:
interface ServiceResponse<T> { data: T | null; error: Error | null; } - Error Handling:
- Use clientLogger.error() for all errors
- Return errors in response object, don't throw
- Provide meaningful error context
- Multi-step Operations:
- Handle cleanup on failure (e.g., delete uploaded files)
- Log orphaned resources for manual cleanup
- Testing:
- Achieve 100% coverage
- Avoid
anytypes even in tests - Use proper type assertions for mocks
- File Uploads:
- Follow the attachment table pattern
- Store files in organized paths within storage buckets
- Include bucket name in storage paths
Database (Supabase)
- Use RLS (Row Level Security) on tables
- Use Realtime in tables.
- Migration files for any database changes should be created.
AI Code (Genkit)
- Use NodeJS Typescript
- Store sensitive info via AWS Parameter Store, not hardcoded
Environment Management
- Three environments: local dev, staging and prod. This is across all, so different databases, different env variables, ability to differentiate in Grafana the logs, etc.
- Use GitHub Actions for CI/CD pipeline with env vars managed per stage
Documentation
- Every module should include a
README.mdwith (only if it makes sense, mainly for API contracts): - Purpose
- Interface contracts
- Example inputs/outputs
- Environment variable needs