diff --git a/.claude/commands/audit-design-system.md b/.claude/commands/audit-design-system.md new file mode 100644 index 000000000..0bffe84dc --- /dev/null +++ b/.claude/commands/audit-design-system.md @@ -0,0 +1,61 @@ +# Audit & Fix Design System Usage + +Audit the specified files or directories for proper design system usage. **Fix every issue found immediately.** + +## Key Concept + +The design system is **`@trycompai/design-system`** — an external npm package. It is the **single source of truth** for all UI components. + +**`@comp/ui` is the OLD component library** being phased out. It should ONLY be used as a last resort when there is absolutely no equivalent in `@trycompai/design-system`. + +## Rules + +### 1. Always check `@trycompai/design-system` first + +For every `@comp/ui` import you find: +1. Check if the component exists in `@trycompai/design-system` by looking at the package exports +2. If it exists → **migrate immediately** +3. Only if there is absolutely NO equivalent in the design system should `@comp/ui` remain + +Do NOT maintain a hardcoded list — **always check the actual DS package exports** to see what's available. The DS is actively growing and may have new components. + +### 2. Use DS primitives for layout, text, and spacing + +- **Pages**: Use `PageLayout` and `PageHeader` — not custom `
` wrappers +- **Spacing/Layout**: Use `Stack` (vertical), `HStack` (horizontal), `Grid` — not `
` +- **Text**: Use `Text` with `size`, `weight`, `variant` props — not raw `

`, ``, or `

` with Tailwind text classes +- **Sections**: Use `Section` with `title`/`description` — not custom card/header combos +- **Settings**: Use `SettingGroup` and `SettingRow` for settings pages +- **Empty states**: Use `Empty`, `EmptyHeader`, `EmptyTitle`, `EmptyDescription` +- **Tables**: Use DS `Table` with `variant="bordered"` for data tables +- **Icons**: Use `@trycompai/design-system/icons` — not `lucide-react` or `@carbon/icons-react` + +### 3. DS component constraints + +These `@trycompai/design-system` components do **NOT** accept `className`: +- `Text` — wrap in `
` if custom styling needed +- `Stack`, `HStack` — wrap in `
` if custom styling needed +- `Badge` — wrap in `
` if custom styling needed +- `Button` — use `variant`/`size` props; wrap in `
` for positioning + +If you see `className` passed to any of these, **fix it by wrapping in a div**. + +### 4. Component patterns + +- **Sheet**: `Sheet > SheetContent > SheetHeader + SheetBody` +- **Drawer**: `Drawer > DrawerContent > DrawerHeader > DrawerTitle` +- **Collapsible**: `Collapsible > CollapsibleTrigger + CollapsibleContent` + +## Process + +1. Read every file in the target path +2. For every `@comp/ui` import, check the `@trycompai/design-system` package to see if an equivalent exists +3. **If yes**: Change the import and update any incompatible props +4. Look for raw HTML layout patterns (`
`, `

`) that should use DS primitives (`Stack`, `Text`, etc.) +5. Check for `className` on DS components that don't support it — **wrap in div** +6. After all fixes, run `bun run --filter '@comp/app' build` to verify +7. Report a summary of what was migrated/fixed + +## Target + +$ARGUMENTS diff --git a/.claude/commands/audit-hooks.md b/.claude/commands/audit-hooks.md new file mode 100644 index 000000000..479dabd26 --- /dev/null +++ b/.claude/commands/audit-hooks.md @@ -0,0 +1,37 @@ +# Audit & Fix Hooks / API Usage + +Audit the specified files or directories for proper hook and API usage patterns. **Fix every issue found immediately.** + +## Forbidden Patterns (fix on sight) + +1. **`useAction` from `next-safe-action`** — Replace with a custom SWR hook or `useOrganizationMutations`/`usePolicyMutations`/etc. that calls `apiClient` directly +2. **Server actions that mutate via `@db`** — Delete the server action and ensure the component uses an API hook instead. Read-only server actions are OK temporarily. +3. **Direct `@db` access in client components** — Replace with `apiClient` call via a hook +4. **Direct `@db` access in Next.js pages for mutations** — Replace with `serverApi` call +5. **Raw `fetch()` without `credentials: 'include'`** — Replace with `apiClient` +6. **`apiClient` with third argument** (e.g., `apiClient.post(url, body, orgId)`) — Remove the third arg. Org context comes from session cookies. + +## Required Patterns (add if missing) + +1. **Data fetching in client components**: Must use `useSWR` with `apiClient` or a custom hook (e.g., `useTask`, `usePolicy`) +2. **Mutations in client components**: Must use custom hooks wrapping `apiClient` (e.g., `useOrganizationMutations`, `useRiskActions`) +3. **Data fetching in server components**: Must use `serverApi` from `apps/app/src/lib/api-server.ts` +4. **SWR hooks**: Use `fallbackData` for SSR initial data, `revalidateOnMount: !initialData` +5. **API response handling**: Lists = `response.data.data`, single resources = `response.data` +6. **`useSWR` `mutate()` safety**: Guard against undefined in optimistic updaters +7. **`Array.isArray()` checks**: When consuming data from SWR that could be stale + +## Process + +1. Read every file in the target path +2. Search for forbidden patterns (`useAction`, `@db` imports in client code, raw `fetch`, server action imports) +3. **Fix each issue immediately**: + - If `useAction` → create or use an existing API hook, remove server action import + - If raw `apiClient` in component → move to a hook if it's a repeated pattern + - If `@db` in client/page mutation → replace with `serverApi` or `apiClient` hook +4. After all fixes, run `bun run --filter '@comp/app' build` to verify +5. Report a summary of what was fixed + +## Target + +$ARGUMENTS diff --git a/.claude/commands/audit-rbac.md b/.claude/commands/audit-rbac.md new file mode 100644 index 000000000..31b4fbc66 --- /dev/null +++ b/.claude/commands/audit-rbac.md @@ -0,0 +1,36 @@ +# Audit & Fix RBAC / Audit Logs + +Audit the specified files or directories for RBAC and audit log compliance. **Fix every issue found immediately.** + +## Rules + +### API Endpoints (NestJS — `apps/api/src/`) +1. **Every mutation endpoint** (POST, PATCH, PUT, DELETE) MUST have `@RequirePermission('resource', 'action')`. If missing, **add it**. +2. **Read endpoints** (GET) should have `@RequirePermission('resource', 'read')`. If missing, **add it**. +3. **Self-endpoints** (e.g., `/me/preferences`) may skip `@RequirePermission` — authentication via `HybridAuthGuard` is sufficient. +4. **Controller format**: Must use `@Controller({ path: 'name', version: '1' })`, NOT `@Controller('v1/name')`. If wrong, **fix it**. + +### Frontend Components (`apps/app/src/`) +1. **Every mutation element** (button, form submit, toggle, switch, file upload) MUST be gated with `usePermissions` from `@/hooks/use-permissions`. If not: + - **Create/Add buttons**: **Wrap** with `{hasPermission('resource', 'create') &&