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.
branchIdis a business sub-scope inside an organization, not the tenant key.- New CRM production work should follow the
productsandusersmodule architecture, while usingLayout.mdas 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:
authchatcrmelementsexample-dashboardformskanbannotificationsoverviewproductsprofilereact-query-demosetupusers
Freeze recommendation:
- Treat
productsandusersas 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.mdskeleton. - 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
apiClientfrom 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 insrc/auth.ts,src/db/schema.ts, andsrc/lib/auth/*. - The skill says
src/features/products/api/service.tsandsrc/features/users/api/service.tsstill call mock data. They now call local route handlers throughapiClient.
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:
KBarSidebarProviderAppSidebarSidebarInsetHeaderInfobarProviderInfoSidebar
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
PageContainerfor 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}.tssrc/features/users/api/{types,service,queries,mutations}.tssrc/features/<feature>/components/**src/features/<feature>/schemas/**when forms exist
Freeze recommendation:
- CRM production work should follow the same split:
api/types.tsapi/service.tsapi/queries.tsapi/mutations.tscomponents/**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
InfoSidebarplusinfoContent.
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
useAppFormfromsrc/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.tsxis 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
Sheetfor 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.mdTemplate 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.tssrc/app/api/products/[id]/route.tssrc/app/api/users/route.tssrc/app/api/users/[id]/route.tssrc/app/api/organizations/route.tssrc/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:
usersorganizationsmembershipsproducts
Current conventions:
- IDs for app-owned auth entities are
textprimary keys. - Organization-scoped business entities include
organizationId. - Timestamps are timezone-aware and default to
now. users.activeOrganizationIdstores active workspace context.memberships.permissionsis an array column.
Freeze recommendation for CRM vNext:
- Every CRM entity that belongs to a tenant must carry
organizationId. branchIdshould be an additional column where needed for business scoping, not a replacement fororganizationId.- 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.tsprotects 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 assuper_admin | usermemberships.role: organization role such asadmin | usermemberships.businessRole: business/department role such asit_admin,helpdesk,auditormemberships.permissions: fine-grained permissions array
Relevant code:
src/lib/auth/rbac.tssrc/lib/auth/session.tssrc/config/nav-config.tssrc/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
organizationIdas the tenant boundary. - Active context switching works at the organization level via
users.activeOrganizationIdand/api/organizations/active. - CRM mock services use
branchIdinside domain records such as customers, enquiries, quotations, and approvals, which implies branch is a nested business scope.
Frozen convention:
organizationId= tenant / workspace / company group scopemembership= user access inside organizationbranchId= 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
mongodbfromsrc/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.mdfor 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.
- Use
- Data model:
- Every CRM entity stores
organizationId. - Add
branchIdonly as sub-scope where operationally required.
- Every CRM entity stores
- Feature shape:
- Follow
types.ts -> service.ts -> queries.ts -> mutations.ts -> components.
- Follow
- Auth:
- Gate all real CRM reads and writes through
requireOrganizationAccess().
- Gate all real CRM reads and writes through
- UI:
- Use
PageContainer. - Use
Layout.mdTemplate A for detail pages and Template B for list pages. - Reuse shared shadcn primitives, theme system, icons registry, and infobar pattern.
- Use
- Data fetching:
- Server prefetch with
getQueryClient() HydrationBoundary- client consumption through React Query
- Server prefetch with
- Forms:
useAppForm- Zod schema
- React Query mutations
- Tables/lists:
- Keep
nuqsfilter/sort/page conventions - Reuse
useDataTablewhen the UX is tabular
- Keep
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.mdAGENTS.mdsrc/auth.tssrc/lib/auth/session.tssrc/lib/auth/rbac.tssrc/db/schema.tssrc/components/ui/**src/components/layout/page-container.tsxsrc/components/themes/**src/styles/theme.css
Files to avoid using as production references:
src/constants/mock-api.tssrc/constants/mock-api-users.tssrc/features/crm/api/service.tssrc/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.tsis still in-memory mock state and currently usesbranchIdacross 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.tsprotects 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:
- Define CRM Drizzle tables with
organizationIdas the tenant boundary andbranchIdas optional business sub-scope. - Add shared CRM API contracts under
src/features/crm/api/types.tsthat reflect real route handler payloads. - Introduce CRM route handlers under
src/app/api/crm/**and gate them withrequireOrganizationAccess(). - Replace
src/features/crm/api/service.tsmock-backed functions withapiClientcalls to local route handlers. - Keep existing CRM route/page structure where possible, but refit the data path to the real app boundary.
- For list pages, preserve current query, pagination, sort, and hydration conventions.
- For detail pages, implement UI against
Layout.mdTemplate A using existing shared primitives and theme tokens. - 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.mdas CRM layout source of truthproductsandusersas production architecture reference