Files
alla-allaos-fullstack/docs/implementation/task-a-template-audit.md
2026-06-11 16:55:45 +07:00

427 lines
16 KiB
Markdown

# Task A Template Audit
## 1. Executive Summary
This repository is already partway through the migration described in the project instructions. The current production-facing baseline is `Auth.js` plus app-owned `users`, `organizations`, and `memberships`, with `products` and `users` already using Route Handlers plus Drizzle. The dashboard still contains a mix of real app patterns and template/demo seams, so Task B should extend only the migrated patterns and avoid inheriting placeholder implementations.
The convention freeze for ALLA OS CRM vNext should be:
- Primary tenant boundary is `organizationId`.
- Membership, role, and permission checks live inside the active organization context.
- `branchId` is a business sub-scope inside an organization, not the tenant key.
- New CRM production work should follow the `products` and `users` module architecture, while using `Layout.md` as the structural UI source of truth for CRM pages.
No required audit path was missing. `Layout.md`, `AGENTS.md`, `README.md`, `package.json`, `src/db/schema.ts`, `src/lib/auth`, `src/app/dashboard`, `src/features`, and `src/components` are all present.
## 2. Project Structure
Observed top-level implementation anchors:
- App Router lives under `src/app`.
- Shared UI primitives live under `src/components/ui`.
- Layout primitives live under `src/components/layout`.
- Feature modules live under `src/features`.
- Drizzle schema is centralized in `src/db/schema.ts`.
- Shared auth helpers live under `src/lib/auth`.
- API boundaries live under `src/app/api/**`.
Observed feature directories:
- `auth`
- `chat`
- `crm`
- `elements`
- `example-dashboard`
- `forms`
- `kanban`
- `notifications`
- `overview`
- `products`
- `profile`
- `react-query-demo`
- `setup`
- `users`
Freeze recommendation:
- Treat `products` and `users` as the authoritative app-owned CRUD reference.
- Treat `crm`, `example-dashboard`, `forms`, `react-query-demo`, and several dashboard demo routes as template/demo seams unless and until they are migrated behind route handlers and auth-aware persistence.
## 3. Layout.md Findings
`Layout.md` is a structural skeleton, not a token source. It explicitly says no design tokens, colors, text, or icons are embedded directly and everything is represented by semantic placeholders.
Important frozen rules from `Layout.md`:
- CRM detail pages should use Template A.
- CRM list pages should use Template B.
- Page composition should remain slot-based: header, action row, preview, progress, main column, side column, dialogs.
- Layout spacing should map to semantic spacing slots rather than inventing page-local spacing rules.
- Cards, tabs, summary grids, timelines, and action rows are part of the intended page grammar.
- Detail pages are expected to support status-driven actions, preview panels, and side-column quick info where the business flow needs them.
Implication for Task B:
- Build CRM UI by mapping repository components and tokens onto the `Layout.md` skeleton.
- Do not invent a new page grammar if the existing template already covers the CRM use case.
## 4. kiranism-shadcn-dashboard Skill Findings
The skill is directionally correct but partially stale relative to the current repo state.
Still valid:
- Use Auth.js, Drizzle, route handlers, and app-owned org/membership semantics.
- Keep feature code under `src/features/<name>/`.
- Use `types.ts -> service.ts -> queries.ts -> mutations.ts`.
- Use local `apiClient` from feature services.
- Prefer server prefetch plus `HydrationBoundary`.
Stale compared with current code:
- The skill says there is no committed `auth.ts`, Drizzle schema, or shared RBAC model. Those now exist in `src/auth.ts`, `src/db/schema.ts`, and `src/lib/auth/*`.
- The skill says `src/features/products/api/service.ts` and `src/features/users/api/service.ts` still call mock data. They now call local route handlers through `apiClient`.
Convention freeze:
- Use the skill for architecture direction.
- Use the repository code as the final source of truth when the skill and code disagree.
## 5. Routing Convention
Observed routing pattern:
- Global dashboard shell: `src/app/dashboard/layout.tsx`
- Feature pages: `src/app/dashboard/**/page.tsx`
- API boundaries: `src/app/api/**/route.ts`
- Auth entrypoint: `src/app/api/auth/[...nextauth]/route.ts`
Dashboard routes currently mix three categories:
- Migrated app-owned routes: `product`, `users`, `workspaces`
- Template utility/demo routes: `forms`, `react-query`, `elements`, `overview`, `kanban`, `notifications`, `billing`, `profile`
- CRM demo routes: `crm/**`
Freeze recommendation:
- New CRM production pages should live under `src/app/dashboard/crm/**`.
- Production data for CRM must move through `src/app/api/crm/**` or feature-specific route handler namespaces, not direct mock service access.
## 6. Dashboard Layout Convention
`src/app/dashboard/layout.tsx` establishes the dashboard shell:
- `KBar`
- `SidebarProvider`
- `AppSidebar`
- `SidebarInset`
- `Header`
- `InfobarProvider`
- `InfoSidebar`
`src/components/layout/page-container.tsx` is the standard page wrapper and should remain the default page-level container:
- Handles title and description through `Heading`
- Supports page header actions
- Supports access fallback state
- Supports loading skeleton state
Freeze recommendation:
- Use `PageContainer` for dashboard pages instead of composing page headers ad hoc.
- Preserve the existing shell and only replace inner feature content.
## 7. Feature Folder Convention
Strong existing reference pattern:
- `src/features/products/api/{types,service,queries,mutations}.ts`
- `src/features/users/api/{types,service,queries,mutations}.ts`
- `src/features/<feature>/components/**`
- `src/features/<feature>/schemas/**` when forms exist
Freeze recommendation:
- CRM production work should follow the same split:
- `api/types.ts`
- `api/service.ts`
- `api/queries.ts`
- `api/mutations.ts`
- `components/**`
- `schemas/**` for form validation
## 8. Component Convention
Observed shared conventions:
- Shared UI primitives live under `src/components/ui/**`.
- Icons should be imported from `@/components/icons`.
- Page headers should go through `PageContainer`.
- Contextual documentation uses `InfoSidebar` plus `infoContent`.
Server/client split:
- Server components are the default for route entry pages.
- Client components are used for interactive tables, forms, switchers, and session-driven sidebar behavior.
- `AppSidebar`, `OrgSwitcher`, forms, and table shells are client components.
Freeze recommendation:
- Keep route pages server-first.
- Push interaction into feature components and shared UI primitives.
## 9. Form Convention
Observed form system:
- Primary form hook is `useAppForm` from `src/components/ui/tanstack-form.tsx`.
- Typed field helpers come from `useFormFields<T>()`.
- Validation is Zod-based.
- Form dialogs/sheets submit through React Query mutations.
Observed sheet/dialog pattern:
- `src/features/users/components/user-form-sheet.tsx` is the best current reference.
- Forms use `Sheet`, `SheetContent`, `SheetHeader`, `SheetFooter`.
- Submit button uses `<Button isLoading={isPending}>`.
Freeze recommendation:
- CRM forms should use `useAppForm`, typed fields, Zod schemas, and mutation-backed submission.
- Prefer `Sheet` for create/edit overlays when the current dashboard pattern already uses it.
## 10. Table Convention
Observed table pattern:
- Shared table shell is `src/components/ui/table/data-table.tsx`.
- State management helper is `src/hooks/use-data-table.ts`.
- URL state is driven by `nuqs`.
- Feature table pages prefetch on the server and render table components on the client.
Key conventions:
- Manual pagination, sorting, and filtering are expected.
- Query string keys are standardized via `src/lib/searchparams.ts`.
- Data tables rely on TanStack Table and TanStack Query.
Freeze recommendation:
- CRM list pages should keep the same table state model when the UI is tabular.
- If a CRM list is card-based per `Layout.md` Template B, the server data contract can still reuse the same filter, sort, and pagination conventions.
## 11. API / Server Action Convention
Observed production boundary:
- Feature services call `apiClient`.
- Route handlers perform auth, access control, and database work.
- Current repo prefers route handlers over direct client-to-DB access.
Observed examples:
- `src/app/api/products/route.ts`
- `src/app/api/products/[id]/route.ts`
- `src/app/api/users/route.ts`
- `src/app/api/users/[id]/route.ts`
- `src/app/api/organizations/route.ts`
- `src/app/api/organizations/active/route.ts`
Freeze recommendation:
- CRM production code should follow route handlers plus Drizzle, not in-memory feature services.
- Server actions are acceptable only when they fit naturally, but route handlers are the stronger established repo pattern.
## 12. Drizzle / Database Convention
Observed schema in `src/db/schema.ts`:
- `users`
- `organizations`
- `memberships`
- `products`
Current conventions:
- IDs for app-owned auth entities are `text` primary keys.
- Organization-scoped business entities include `organizationId`.
- Timestamps are timezone-aware and default to `now`.
- `users.activeOrganizationId` stores active workspace context.
- `memberships.permissions` is an array column.
Freeze recommendation for CRM vNext:
- Every CRM entity that belongs to a tenant must carry `organizationId`.
- `branchId` should be an additional column where needed for business scoping, not a replacement for `organizationId`.
- Audit and workflow entities should reference organization first, then branch if applicable.
## 13. Auth Convention
Current auth baseline is real and already committed:
- Auth.js config lives in `src/auth.ts`.
- Credentials provider checks `users.password_hash`.
- Session is enriched with organizations, active organization, membership role, business role, and active permissions.
- `src/proxy.ts` protects dashboard and protected API routes.
Preferred server helpers:
- `requireSession()`
- `requireSystemRole()`
- `requireOrganizationAccess()`
Freeze recommendation:
- All new CRM protected routes should use shared helpers from `src/lib/auth/session.ts`.
- Do not introduce Clerk or alternate auth paths.
## 14. Organization / Membership / Permission Convention
Current app-owned model:
- `users.systemRole`: global role such as `super_admin | user`
- `memberships.role`: organization role such as `admin | user`
- `memberships.businessRole`: business/department role such as `it_admin`, `helpdesk`, `auditor`
- `memberships.permissions`: fine-grained permissions array
Relevant code:
- `src/lib/auth/rbac.ts`
- `src/lib/auth/session.ts`
- `src/config/nav-config.ts`
- `src/hooks/use-nav.ts`
Freeze recommendation:
- CRM authorization must be organization-aware first.
- Membership role and explicit permissions should gate organization-scoped actions.
- Business role can layer domain-specific behavior but should not replace organization membership checks.
## 15. Branch Scope Convention
Task A explicitly requires organization-first scoping. The current repo supports that direction.
Evidence:
- Existing real entities use `organizationId` as the tenant boundary.
- Active context switching works at the organization level via `users.activeOrganizationId` and `/api/organizations/active`.
- CRM mock services use `branchId` inside domain records such as customers, enquiries, quotations, and approvals, which implies branch is a nested business scope.
Frozen convention:
- `organizationId` = tenant / workspace / company group scope
- `membership` = user access inside organization
- `branchId` = business branch / operational document scope inside organization
Do not design CRM around branch-first tenancy.
## 16. UI / Design Token Convention
Observed visual/token system:
- Theme system lives under `src/components/themes/**`.
- Theme CSS entrypoint is `src/styles/theme.css`.
- Default theme is `mongodb` from `src/components/themes/theme.config.ts`.
- Multiple named themes already exist; this repo already has a tokenized visual system.
Observed dashboard tone:
- Sidebar-based admin shell
- Sticky translucent header
- Theme switching and documentation sidebar
- shadcn cards, sheets, dialogs, tables, and Radix-based interactions
Freeze recommendation:
- Reuse the existing theme/token system.
- Use `Layout.md` for CRM structure, but map it onto current shadcn/tailwind/theme primitives.
- Do not create a parallel design system for Task B.
## 17. CRM vNext Recommended Convention
Recommended convention freeze for Task B:
- Routing:
- Use `src/app/dashboard/crm/**` for pages.
- Add route handlers under `src/app/api/crm/**` or sub-feature namespaces.
- Data model:
- Every CRM entity stores `organizationId`.
- Add `branchId` only as sub-scope where operationally required.
- Feature shape:
- Follow `types.ts -> service.ts -> queries.ts -> mutations.ts -> components`.
- Auth:
- Gate all real CRM reads and writes through `requireOrganizationAccess()`.
- UI:
- Use `PageContainer`.
- Use `Layout.md` Template A for detail pages and Template B for list pages.
- Reuse shared shadcn primitives, theme system, icons registry, and infobar pattern.
- Data fetching:
- Server prefetch with `getQueryClient()`
- `HydrationBoundary`
- client consumption through React Query
- Forms:
- `useAppForm`
- Zod schema
- React Query mutations
- Tables/lists:
- Keep `nuqs` filter/sort/page conventions
- Reuse `useDataTable` when the UX is tabular
## 18. Files That Should Not Be Touched
For Task B, these should be treated as source-of-truth or stable infrastructure unless there is a deliberate migration step:
- `Layout.md`
- `AGENTS.md`
- `src/auth.ts`
- `src/lib/auth/session.ts`
- `src/lib/auth/rbac.ts`
- `src/db/schema.ts`
- `src/components/ui/**`
- `src/components/layout/page-container.tsx`
- `src/components/themes/**`
- `src/styles/theme.css`
Files to avoid using as production references:
- `src/constants/mock-api.ts`
- `src/constants/mock-api-users.ts`
- `src/features/crm/api/service.ts`
- `src/features/crm/api/queries.ts`
- other demo/template routes that still depend on mock or placeholder data
These legacy/demo files do not need immediate deletion, but Task B should not extend them as the long-term production path.
## 19. Risks / Concerns
Key risks before Task B:
- The repo currently mixes migrated app-owned code and demo/template code, so copying patterns from the wrong feature can reintroduce mock architecture.
- `src/features/crm/api/service.ts` is still in-memory mock state and currently uses `branchId` across CRM records without a real persisted organization boundary.
- Some nav and page access behavior is client-visible UX filtering only; all CRM protection must still be enforced server-side.
- `src/proxy.ts` protects broad route classes, but fine-grained CRM permission rules will still need route handler or page-level checks.
- Existing skill text is partially stale, so implementation decisions should always be verified against repository code.
## 20. Task B Implementation Plan
Recommended path for Task B:
1. Define CRM Drizzle tables with `organizationId` as the tenant boundary and `branchId` as optional business sub-scope.
2. Add shared CRM API contracts under `src/features/crm/api/types.ts` that reflect real route handler payloads.
3. Introduce CRM route handlers under `src/app/api/crm/**` and gate them with `requireOrganizationAccess()`.
4. Replace `src/features/crm/api/service.ts` mock-backed functions with `apiClient` calls to local route handlers.
5. Keep existing CRM route/page structure where possible, but refit the data path to the real app boundary.
6. For list pages, preserve current query, pagination, sort, and hydration conventions.
7. For detail pages, implement UI against `Layout.md` Template A using existing shared primitives and theme tokens.
8. Only after the boundary is real should branch-specific business logic be layered into CRM workflows.
Final convention freeze:
- Organization-first
- Membership-aware
- Branch as sub-scope
- Route-handler plus Drizzle
- Server-enforced RBAC
- `Layout.md` as CRM layout source of truth
- `products` and `users` as production architecture reference