> Cross-cutting conventions that apply to all packages in the monorepo.
## General Rules
### No emojis
Never use emoji characters anywhere in this codebase: not in source code, UI text, console output, log messages, comments, or documentation. Use plain text instead.
### Language: TypeScript everywhere
- All packages use TypeScript with `strict: true`
- No `.js` files in source (except config files: `jest.config.js`, `next.config.js`)
- All files use `.ts` or `.tsx` extension
### Formatting: Prettier
```json
// .prettierrc
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2,
"arrowParens": "always",
"endOfLine": "lf"
}
```
### Linting: ESLint
Use a flat config (`eslint.config.js`) with TypeScript support:
1.**Shared Layer (`packages/shared`)**: Write validation schema and enum tests first in `tests/`. Implement schemas and types inside `src/`.
2.**Database Layer (`packages/api`)**: Write schema and repository integration tests first in `tests/` (using `mongodb-memory-server`). Create Mongoose schema and Repository in `src/`. All reads must use `.lean().exec()`.
3.**Service Layer (`packages/api`)**: Write service unit tests first in `tests/` using the `createMockRepository` helper to mock repository methods. Implement business logic Service class inside `src/` using Awilix constructor injection.
4.**Route Layer (`packages/api`)**: Write Fastify route plugin tests first in `tests/` using `app.inject` and resolving mocks. Implement the Fastify route plugin inside `src/`.
5.**Web API Client (`packages/web`)**: Write service unit tests first in `tests/` utilizing MSW to mock backend requests. Implement frontend service in `src/`.
6.**Web UI (`packages/web`)**: Write component and page tests first in `tests/` using React Testing Library role queries. Create Next.js pages and components inside `src/` (Server Components by default).
**Mandatory Verification**: Every task must end with `npm run build`, `npm run test:cov`, and `npm run lint` all passing with the defined coverage thresholds.
2.**Server Components by default** — only add `'use client'` when interactive
3.**Feature components** in `components/features/` — organized by domain (products, pantry, etc.)
4.**UI components** in `components/ui/` — generic, reusable, no domain logic
5.**Hooks** in `hooks/` — custom hooks for data fetching, state management
6.**Services** in `services/` — API client wrappers
### Shared
1.**Only pure TypeScript** — no Node.js, no browser, no framework code
2.**Types, enums, Zod schemas, pure utils** — nothing else
3.**Barrel exports** — every directory has `index.ts`
4.**Use `type` modifier for type-only exports/imports**
## Getters and Setters
Use TypeScript `get`/`set` accessors when a property simply exposes or lightly wraps a private backing field. Use a plain method only when the operation is async, takes multiple parameters, or has meaningful side effects beyond assignment.
```typescript
// Good:Simple exposure of a private field — use accessor
class ApiClient {
private _accessToken: string | null = null;
set accessToken(token: string) {
this._accessToken = token;
}
get accessToken(): string | null {
return this._accessToken;
}
}
// Good:Side effects / async / multiple params — use a method