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

16 KiB

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.

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