# Architecture Rules

These rules describe the approved implementation patterns for ALLA OS.

New work should extend these patterns instead of inventing parallel architecture.

## Frontend Architecture

- Use Next.js App Router.
- Prefer server components by default.
- Use client components only for interactivity, browser APIs, or client-side state/query hooks.
- Use `PageContainer` for dashboard page headers and top-level content framing.
- Keep business-facing CRM UI aligned with `docs/business/crm-terminology.md` and `src/features/crm/shared/terminology.ts`.

### Data Loading Pattern

- For data-heavy dashboard/app pages, prefer server prefetch plus `HydrationBoundary`.
- Client tables and detail panes should consume prefetched data with `useSuspenseQuery()`.
- Define query options and query keys in `src/features/<feature>/api/queries.ts`.
- Keep filters in URL state with `nuqs` when the page supports shareable filtering.

Reference examples:

- `src/features/users/components/user-listing.tsx`
- `src/features/crm/customers/components/customer-listing.tsx`
- `src/app/dashboard/crm/settings/user-role-assignments/page.tsx`

### UI Composition Rules

- Reuse shadcn/ui primitives from `src/components/ui/**`.
- Reuse table shell components from `src/components/ui/table/**`.
- Reuse `useDataTable` for table state orchestration.
- Reuse TanStack Form wrappers from `@/components/ui/tanstack-form` and field components from `@/components/forms/fields`.
- Do not create a parallel CRM design system or terminology layer.

## Backend Architecture

- Use Route Handlers under `src/app/api/**` as the HTTP boundary.
- Keep route handlers thin: auth, validation, service call, response mapping, and audit.
- Put business logic in feature or foundation service layers under `src/features/**`.
- Use Drizzle ORM for database access.
- Keep direct database access out of client components.

### Route Structure Pattern

Approved structure:

1. `requireOrganizationAccess()` or another shared auth helper
2. request parsing and schema validation
3. build resolved access/security context when the feature is scope-sensitive
4. call feature/foundation service
5. emit audit/security events through shared audit services
6. return typed JSON/stream response

Reference examples:

- `src/app/api/crm/quotations/route.ts`
- `src/app/api/crm/approvals/route.ts`
- `src/app/api/crm/reports/pipeline/route.ts`
- `src/app/api/crm/reports/export/route.ts`

## Module Structure

Preferred feature layout:

```text
src/features/<feature>/
  api/
    types.ts
    service.ts
    queries.ts
    mutations.ts
  components/
  schemas/
  server/
```

Rules:

- components import contracts from `api/types.ts`
- UI calls query options from `api/queries.ts`
- UI mutations reuse shared mutation configs from `api/mutations.ts`
- services in `api/service.ts` call route handlers through `src/lib/api-client.ts`
- server business logic stays under feature/foundation server services

## Service Layer Pattern

- Services own business rules, persistence orchestration, and reusable data shaping.
- Services may call other services when extending an existing foundation.
- Services should not depend on UI concerns.
- Report services must use dataset/builders/filter layers instead of embedding ad hoc SQL in routes.
- PDF flows must use the PDF and artifact foundations instead of custom rendering paths.

Reference services:

- `src/features/crm/reports/server/service.ts`
- `src/features/foundation/approval/server/service.ts`
- `src/features/foundation/pdf-generator/server/service.ts`
- `src/features/foundation/storage/service.ts`

## Query Pattern

- Define centralized query key factories in each feature's `api/queries.ts`.
- Keys should group into `all`, `lists()`, `list(filters)`, `details()`, `detail(id)`, and child-resource keys where applicable.
- Server pages prefetch query options and dehydrate.
- Clients read the same keys with `useSuspenseQuery()`.

Reference examples:

- `src/features/products/api/queries.ts`
- `src/features/users/api/queries.ts`
- `src/features/crm/reports/api/queries.ts`

## Mutation Pattern

- Centralize mutation configs in `api/mutations.ts`.
- Shared mutation configs must retain cache invalidation.
- After create: invalidate list-level keys.
- After update: invalidate list and detail keys.
- After delete: invalidate lists and remove stale detail queries.
- Refresh related tabs, counts, previews, and approval panels when they depend on the changed entity.

## Audit Pattern

- Use `auditCreate()`, `auditUpdate()`, `auditDelete()`, or `auditAction()` from `src/features/foundation/audit-log/service.ts`.
- Reuse existing entity types and action naming where possible.
- Security-sensitive denials use `crm_security_access` through `auditCrmSecurityEvent()`.
- Report view/export events use `crm_report`.

Reference examples:

- `src/features/foundation/audit-log/service.ts`
- `src/features/crm/security/server/service.ts`
- `src/features/crm/reports/server/exports/service.ts`

## Security Pattern

- Organization access starts with `requireOrganizationAccess()`.
- CRM authorization must use resolved access, not raw role strings.
- Use `resolveCrmMembershipAccess()` for effective permission/scope unions.
- Use `buildCrmSecurityContext()` for scope-aware CRM services.
- Use `resolveCrmAccess()` / report-context builders for report routes.
- Scope checks must enforce branch, product, ownership, and pricing visibility server-side.

Reference docs:

- `docs/security/crm-authorization-boundaries.md`
- `docs/security/crm-access-enforcement-inventory.md`
- `docs/security/team-scope-limitations.md`

## Explicitly Forbidden

- business logic in route handlers
- client-side only authorization
- direct role-string CRM authorization
- direct DB access from client code
- duplicate export/report/PDF/approval/security foundations
- new Clerk integration
- new SWR or Redux data architecture for app-owned features
- new React Hook Form usage in this repo
