Copilot Instructions TypeScript Lambda On this page
💻 Tech stack​
NextJS + Tailwind CSS
AWS Serverless (Lambda, API Gateway, DynamoDB, S3)
Stripe for billing
Auth with Clerk
PDF reporting
Email notifications with AWS SES
Unit and integration tests with Jest
CDK Typescript for infrastructure as code
GitHub Actions for CI/CD
Typescript for type safety
ESLint and Prettier for code quality
Uses npm workspaces for monorepo structure
Node v22.x
All code is written in TypeScript
Uses AWS CDK for infrastructure
Always use the latest version of AWS CDK
Node version is specified in the .nvmrc file
NPM repositories are configured in the .npmrc file
Command line tools are defined in the package.json file
Configuration Files​
ESLint : Follow rules specified in .eslintrc.config.mjs for code quality
TypeScript : Adhere to compiler options in tsconfig.json
Renovate : Dependency updates managed via renovate.json
CDK : Reference cdk.json for CDK app settings and context values
Git : Honor exclusions in .gitignore
Prettier : Code formatting defined in .prettierrc
npm : Package access configured in .npmrc
GitHub Actions : Workflows configured in .github/workflows/*.yml
When modifying any configuration file, ensure to update documentation accordingly
TypeScript​
Use strict mode in tsconfig.json
Use tsc for type checking
Strict Types are defined in the frontend/types directory for both frontend and backend
Use interface for defining types
Use type for defining unions or complex types
Avoid enum — prefer as const objects with derived union types; use enum only when required for interoperability with external libraries
Never use Record<string, any> – use typed objects or Record<string, unknown> with narrowing
Use unknown for values that can be of any type but need type checking before use
Use any only as a last resort when type safety cannot be guaranteed
Use never for functions that never return (e.g., throw an error)
Use void for functions that do not return a value
Use Promise<T> for asynchronous functions that return a value
Use Promise<void> for asynchronous functions that do not return a value
Use async/await for asynchronous code
Use import statements for importing modules
Use export statements for exporting modules
Prefer named exports over default exports
Lambda Functions​
Always written in TypeScript
Organize in src/lambda/{lambdaName} directories for individual lambdas
src/lambda/ must be configured as a separate npm workspace
Filename must match the lambda name in camelCase format
Each lambda must have:
Its own package.json
Its own tsconfig.json
Its own .gitignore
Jest tests in its own test directory
Always use the NodeJSFunction construct from AWS CDK
Specify runtime as Runtime.NODEJS_20_X
API methods for example: ['GET', 'POST', 'PUT', 'DELETE'] should be in a single lambdas
Workspace Frontend​
Style Consistency​
All new product sections must use shared UI components from src/frontend/components/ui where possible.
Tailwind CSS configuration is centralized; do not override styles locally unless necessary.
Follow the design tokens and UI patterns documented in /docs/frontend/style-guide.md.
When adding new UI components, update the style guide and, if using, Storybook stories.
Ensure all frontend code is reviewed for visual and interaction consistency with existing sections.
Workspace Shared​
Domain Model Definitions​
All domain models (e.g., Building, LedgerEntry, Unit) are defined in shared/models/.
Always import types from shared/models in all backend, frontend, and lambda code.
Update or refactor model definitions only in this folder.
When adding new models, create a new file in shared/models and export from shared/models/index.ts.
All models must include an ownerId field for SaaS multi-tenancy. This is assigned at master account creation and used as the subdomain name.
All API, DynamoDB, and business logic must scope data by ownerId.
On signup, only master accounts are created, requiring a max 40 character valid word for the subdomain. Sub-users can only be invited by the administrator via the users screen.
Use Clerk.com organization feature for member management and invitations.
Lambda@Edge must augment all API claims with the ownerId from the subdomain.
This ensures consistency, easy refactoring, and version control of all domain types and multi-tenant logic.