Thank you for contributing to this project! Please follow these standards to ensure code quality, maintainability, and security.
- Use npm exclusively as the package manager for this project.
- Do not use yarn, pnpm, or other package managers.
- Always use
npm installto install dependencies, notyarn installorpnpm install. - Commit
package-lock.jsonto the repository (neveryarn.lockorpnpm-lock.yaml).
- Do NOT use
console.log,console.error,console.warn,console.info, orconsole.debugin any production or shared code. - All logging must use the Winston logger (
import logger from "@/lib/logger") in server-side code only (server actions, API routes, backend utilities). - Never import or use
@/lib/loggerin client components or client hooks. This will break the build. - In client components/hooks, use
console.erroronly for actionable errors in development. Do not log routine or non-actionable information. - Remove any logs that are not valuable for debugging or operational insight.
- Never add logs for routine permission checks, database queries, or other noise.
- All code must pass ESLint (
npm run lint). - The
no-consolerule is enforced: no directconsole.*calls are allowed in production/shared code. Client code may useconsole.errorfor actionable errors in development only. - Use Prettier or the project's formatting rules for code style.
- Run
npm run typecheckto ensure TypeScript types are correct before committing.
- Use TypeScript for all code.
- Prefer interfaces over type aliases.
- Export all types from
types/index.ts. - Import types from
@/types. - If referring to DB types, use
@/db/schema. - Use proper type imports:
import type { ... }for type-only imports.
- Never expose secrets or sensitive values to the frontend.
- Use the
NEXT_PUBLIC_prefix only for variables that must be accessed in the frontend. - Update
.env.examplewhen adding or changing environment variables. - Store all secrets in
.env.local(never commit this file). - DB_LOG_QUERIES: Set to
truein.env.localto enable Drizzle ORM query logging in development. Leave blank or set tofalseto disable noisy query logs and keep dev logs clean. - Required for SSR: Set
AMPLIFY_APP_ORIGIN=https://yourdomain.comfor server-side auth flows (use HTTPS in production).
- JWT Configuration: When using NextAuth, explicitly set
session: { strategy: "jwt" }in configuration. - Session Security: Always configure NextAuth with appropriate callbacks for JWT and session management.
- Role-Based Access: Use the
hasToolAccess()function to check permissions before allowing access to protected resources. - Middleware Protection: Implement authentication checks in
middleware.tsfor protected routes.
- Security Groups: Apply least-privilege principles. Never allow 0.0.0.0/0 unless absolutely necessary.
- Encryption: Enable encryption at rest for all data stores (RDS, S3, etc.).
- SSL/TLS: Enforce SSL on S3 buckets and use minimum TLS version 1.2.
- IAM Policies: Follow least-privilege principles. Use the CDK's
ConfirmPermissionsBroadeningcheck. - Secrets Management: Use AWS Secrets Manager for all sensitive configuration. Never hardcode secrets.
- Field Naming Convention: Database column names use snake_case. The RDS Data API adapter automatically transforms these to camelCase for TypeScript compatibility. Never manually transform field names.
- Parameterized Queries: Always use parameterized queries with the RDS Data API:
await executeSQL( "SELECT * FROM users WHERE id = :id", [{ name: "id", value: { longValue: userId } }] )
- Transaction Management: Use
executeTransaction()for operations that modify multiple tables. - Connection Security: Access the database only through RDS Data API, never direct connections.
- Type Casting: When the automatic transformation doesn't match your type interface, use double casting:
const result = await executeSQL(query) return result as unknown as YourType[]
- Always configure Amplify with
ssr: truein Next.js applications:Amplify.configure(config, { ssr: true })
- Use
runWithAmplifyServerContextfor all server-side Amplify operations. - Import server-side APIs from the
/serversub-path (e.g.,aws-amplify/auth/server).
- Development: Use
npm run dev --turbofor faster local development with Turbopack. - Imports: Import specific components rather than entire libraries:
// Good import TriangleIcon from '@phosphor-icons/react/dist/csr/Triangle' // Bad import { TriangleIcon } from '@phosphor-icons/react'
- Images: Use
next/imagewith properwidthandheightorfillprops.
- Separation of Concerns: Keep presentation, business logic, and infrastructure in separate layers
- Server-First: Prefer server components and server actions over client-side logic
- Consistency: All server actions must return
ActionState<T>for uniform error handling - No Business Logic in Components: Business rules belong in
/actions, not in UI components - Infrastructure Abstraction: Database and external services accessed only through adapters in
/lib
Follow the consistent ActionState<T> pattern for all server actions:
export async function actionName(): Promise<ActionState<ReturnType>> {
const session = await getServerSession()
if (!session) return { isSuccess: false, message: "Unauthorized" }
try {
const result = await executeSQL(...)
return { isSuccess: true, message: "Success", data: result }
} catch (error) {
return handleError(error, "Operation failed")
}
}- Use structured error handling with
AppErrorand error levels (USER, SYSTEM, EXTERNAL). - Handle refresh token errors gracefully in authentication flows.
- Provide meaningful error messages that help users understand what went wrong.
When documenting code or in comments, include file references in the format path/to/file.ts:lineNumber for easy navigation.
- Use kebab-case for all files and folders.
- Use the
@alias for imports unless otherwise specified. - Follow existing naming patterns in the codebase.
- Place shared components in
/components. - Place one-off route components in
/_componentswithin the route. - Follow project structure and naming conventions.
- Keep components focused and single-purpose.
- Add or update tests for new features and bug fixes.
- Include tests for authentication flows and protected routes.
- Test error scenarios and edge cases.
- Do not break existing tests.
- Run all tests before submitting a PR (
npm test).
- Run
npm run lintto check for linting errors. - Run
npm run typecheckto verify TypeScript types. - Run
npm testto ensure all tests pass. - Update
CLAUDE.mdif you've made architectural changes. - Update relevant documentation for API changes.
- All PRs must pass CI (lint, build, and tests) before merge.
- All PRs must be reviewed and approved by at least one other contributor.
- Use the PR template and complete all checklist items.
- Include clear descriptions of what changed and why.
- Reference any related issues or tickets.
- Update documentation as needed for new features, changes, or fixes.
- Document security implications of changes.
- Keep
CLAUDE.mdup to date with architectural decisions. - Use clear, concise comments for complex logic.
By following these guidelines, you help keep the codebase clean, maintainable, and production-ready. Thank you for your contributions!