diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index c80482a..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,21 +0,0 @@ -# CLAUDE.md - -This is a Next.js 16 + shadcn/ui admin dashboard starter kit. - -## Key References - -- **[AGENTS.md](./AGENTS.md)** — Full project overview, tech stack, structure, conventions, data fetching patterns, deployment -- **[docs/forms.md](./docs/forms.md)** — Form system: TanStack Form + Zod, composable fields, validation, multi-step, sheet/dialog forms -- **[docs/themes.md](./docs/themes.md)** — Theme system: OKLCH colors, adding themes, font config -- **[docs/nav-rbac.md](./docs/nav-rbac.md)** — Navigation RBAC: access control, Clerk integration -- **[docs/clerk_setup.md](./docs/clerk_setup.md)** — Clerk auth setup: organizations, billing, environment variables - -## Critical Conventions - -- **React Query** for all data fetching — `void prefetchQuery()` on server + `useSuspenseQuery` on client (standard TanStack pattern), `useMutation` for forms, `HydrationBoundary` + `dehydrate` for hydration, `` for streaming -- **API layer** per feature — `api/types.ts` → `api/service.ts` → `api/queries.ts`; queries use key factories (`entityKeys.all/list/detail`); components import from service and queries, never from mock APIs directly -- **nuqs** for URL search params — `searchParamsCache` on server, `useQueryStates` on client, use `getSortingStateParser` for sort (same parser as `useDataTable`) -- **Icons** — only import from `@/components/icons`, never from `@tabler/icons-react` directly -- **Forms** — use `useAppForm` + `useFormFields()` from `@/components/ui/tanstack-form` -- **Page headers** — use `PageContainer` props (`pageTitle`, `pageDescription`, `pageHeaderAction`), never import `` manually -- **Formatting** — single quotes, JSX single quotes, no trailing comma, 2-space indent diff --git a/docs/implementation/task-a-template-audit.md b/docs/implementation/task-a-template-audit.md new file mode 100644 index 0000000..53a4846 --- /dev/null +++ b/docs/implementation/task-a-template-audit.md @@ -0,0 +1,426 @@ +# 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//`. +- 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//components/**` +- `src/features//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()`. +- 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 ` - ); - }) - ) : ( -
- No workspace found yet. Create your first workspace to unlock organization-scoped - product management. -
- )} - - - - - - Create workspace - - This flow is limited to super admins in the organization RBAC model. - - - -
- - setWorkspaceName(event.target.value)} - placeholder='Acme Studio' - disabled={isCreating} - /> -
- -
-
- - - ); -} diff --git a/src/app/example/dashboard/workspaces/team/[[...rest]]/page.tsx b/src/app/example/dashboard/workspaces/team/[[...rest]]/page.tsx deleted file mode 100644 index ec78ce7..0000000 --- a/src/app/example/dashboard/workspaces/team/[[...rest]]/page.tsx +++ /dev/null @@ -1,55 +0,0 @@ -'use client'; - -import PageContainer from '@/components/layout/page-container'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; -import { teamInfoContent } from '@/config/infoconfig'; -import { useSession } from 'next-auth/react'; - -export default function TeamPage() { - const { data: session, status } = useSession(); - const activeOrganization = session?.user?.organizations.find( - (organization) => organization.id === session?.user?.activeOrganizationId - ); - const canManageTeam = - session?.user?.systemRole === 'super_admin' || - (session?.user?.activeOrganizationId && - (session.user.activeMembershipRole === 'admin' || - session.user.activePermissions.includes('users:manage'))); - - return ( - - Select a workspace where you are an admin to manage team settings. - - } - > - - - {activeOrganization?.name} - - This placeholder keeps the route alive while the full membership CRUD flow is still - being migrated off Clerk Organizations. - - - -
-
Current role
-
- {session?.user?.activeMembershipRole ?? 'member'} -
-
-
- Next iteration can add invites, membership edits, and permission management against the - `memberships` table introduced in this migration. -
-
-
-
- ); -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 3fc6142..e2f49e4 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -6,14 +6,13 @@ import ThemeProvider from '@/components/themes/theme-provider'; import { cn } from '@/lib/utils'; import type { Metadata, Viewport } from 'next'; import { cookies } from 'next/headers'; -import Script from 'next/script'; import NextTopLoader from 'nextjs-toploader'; import { NuqsAdapter } from 'nuqs/adapters/next/app'; import '../styles/globals.css'; const META_THEME_COLORS = { - light: '#ffffff', - dark: '#09090b' + light: '#f9fbfa', + dark: '#001e2b' }; export const metadata: Metadata = { @@ -34,16 +33,18 @@ export default async function RootLayout({ children }: { children: React.ReactNo return ( - +