84 lines
2.5 KiB
Plaintext
84 lines
2.5 KiB
Plaintext
---
|
|
description: Fastify backend, API design, Prisma, auth, and error handling
|
|
globs: apps/api/**/*
|
|
alwaysApply: false
|
|
---
|
|
|
|
You are working on the backend in `apps/api`.
|
|
|
|
## Backend framework
|
|
- Use Fastify as the default backend framework.
|
|
- Prefer Fastify plugins and encapsulation patterns over ad hoc global behavior.
|
|
|
|
## API design
|
|
- Keep business logic out of route handlers.
|
|
- Route handlers should be thin and focused on:
|
|
- validation
|
|
- auth/context
|
|
- calling application services
|
|
- shaping responses
|
|
- Prefer explicit service-layer or domain-layer boundaries for business logic.
|
|
|
|
## Validation and contracts
|
|
- Validate all incoming requests with Zod or approved schema wrappers.
|
|
- Validate file uploads and all user-controlled input.
|
|
- Avoid trusting frontend input.
|
|
- Use explicit schemas for request and response shapes where practical.
|
|
|
|
## API documentation
|
|
- Maintain Swagger/OpenAPI support.
|
|
- New or changed endpoints should update the API schema/docs as part of the work.
|
|
- Keep API docs accurate and usable.
|
|
|
|
## Data access
|
|
- Prefer Prisma as the default ORM unless explicitly directed otherwise.
|
|
- Use Postgres as the primary relational database.
|
|
- Store relational/domain data in Postgres.
|
|
- Store document/image metadata in Postgres and file binaries in appropriate storage.
|
|
- Avoid leaking raw ORM/database logic into unrelated layers.
|
|
|
|
## Auth and permissions
|
|
- Roles and permissions are first-class concerns.
|
|
- Design with support for:
|
|
- board members
|
|
- treasurers
|
|
- owners
|
|
- tenants
|
|
- future administrative roles
|
|
- Support passwordless authentication patterns:
|
|
- magic link
|
|
- OIDC
|
|
- passkeys
|
|
- Do not hard-code assumptions that one deployment always maps to one HOA.
|
|
- Self-hosted mode supports single tenancy.
|
|
- SaaS mode must remain compatible with future or current multi-tenant architecture decisions.
|
|
|
|
## Auditing
|
|
- All destructive or sensitive actions must be auditable.
|
|
- Deletions and other important changes should be recorded in an audit log.
|
|
- Prefer soft-delete or explicit audit-aware flows where appropriate.
|
|
- Do not implement silent destructive behavior.
|
|
|
|
## Error handling
|
|
- Use explicit, typed, and user-safe error handling.
|
|
- Never use silent catch blocks.
|
|
- Do not swallow errors.
|
|
- Return structured, predictable error responses.
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
// BAD: silent catch
|
|
try {
|
|
await doSomething();
|
|
} catch {}
|
|
|
|
// GOOD: log, type, rethrow or return structured error
|
|
try {
|
|
await doSomething();
|
|
} catch (e) {
|
|
logger.error({ err: e }, 'doSomething failed');
|
|
throw new ServiceError('Operation failed', { cause: e });
|
|
}
|
|
```
|