161 lines
5.9 KiB
Markdown
161 lines
5.9 KiB
Markdown
# 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
|