diff --git a/.agents/skills/audit-design-system/SKILL.md b/.agents/skills/audit-design-system/SKILL.md new file mode 100644 index 0000000000..a0c7d0dc22 --- /dev/null +++ b/.agents/skills/audit-design-system/SKILL.md @@ -0,0 +1,23 @@ +--- +name: audit-design-system +description: Audit & fix design system usage — migrate @trycompai/ui and lucide-react to @trycompai/design-system +--- + +Audit the specified files for design system compliance. **Fix every issue found immediately.** + +## Rules + +1. **`@trycompai/design-system`** is the primary component library. `@trycompai/ui` is legacy — only use as last resort when no DS equivalent exists. +2. **Always check DS exports first** before reaching for `@trycompai/ui`. Run `node -e "console.log(Object.keys(require('@trycompai/design-system')))"` to check. +3. **Icons**: Use `@trycompai/design-system/icons` (Carbon icons), NOT `lucide-react`. Check with `node -e "const i = require('@trycompai/design-system/icons'); console.log(Object.keys(i).filter(k => k.match(/YourSearch/i)))"`. +4. **DS components that do NOT accept `className`**: `Text`, `Stack`, `HStack`, `Badge`, `Button` — wrap in `
` for custom styling. +5. **Button**: Use DS `Button` with `loading`, `iconLeft`, `iconRight` props instead of manually rendering spinners/icons. +6. **Layout**: Use `PageLayout`, `PageHeader`, `Stack`, `HStack`, `Section`, `SettingGroup`. +7. **Patterns**: Sheet (`Sheet > SheetContent > SheetHeader + SheetBody`), Drawer, Collapsible. + +## Process +1. Read files specified in `$ARGUMENTS` +2. Find `@trycompai/ui` imports — check if DS equivalent exists +3. Find `lucide-react` imports — find matching Carbon icons +4. Migrate components and icons +5. Run build to verify: `bunx turbo run typecheck --filter=@trycompai/app` diff --git a/.agents/skills/audit-hooks/SKILL.md b/.agents/skills/audit-hooks/SKILL.md new file mode 100644 index 0000000000..7c14d1a240 --- /dev/null +++ b/.agents/skills/audit-hooks/SKILL.md @@ -0,0 +1,34 @@ +--- +name: audit-hooks +description: Audit & fix hooks and API usage patterns — eliminate server actions, raw fetch, and stale patterns +--- + +Audit the specified files for hook and API usage compliance. **Fix every issue found immediately.** + +## Forbidden Patterns (fix immediately) + +1. **`useAction` from `next-safe-action`** → replace with SWR hook or custom mutation hook +2. **Server actions mutating via `@db`** → delete and use API hook instead +3. **Direct `@db` in client components** → replace with `apiClient` via hook +4. **Direct `@db` in Next.js pages for mutations** → replace with `serverApi` +5. **Raw `fetch()` without `credentials: 'include'`** → use `apiClient` +6. **`window.location.reload()` after mutations** → use SWR `mutate()` +7. **`router.refresh()` after mutations** → use SWR `mutate()` +8. **`useEffect` + `apiClient.get` for data fetching** → replace with `useSWR` +9. **Callback props for data refresh** (`onXxxAdded`, `onSuccess`) → remove, rely on SWR cache sharing + +## Required Patterns + +- **Client data fetching**: `useSWR` with `apiClient` or custom hook +- **Client mutations**: custom hooks wrapping `apiClient` with `mutate()` for cache invalidation +- **Server components**: `serverApi` from `apps/app/src/lib/api-server.ts` +- **SWR**: `fallbackData` for SSR data, `revalidateOnMount: !initialData` +- **API response**: lists = `response.data.data`, single = `response.data` +- **`mutate()` safety**: guard against `undefined` in optimistic update functions +- **`Array.isArray()` checks**: when consuming SWR data that could be stale + +## Process +1. Read files specified in `$ARGUMENTS` +2. Find forbidden patterns and fix them +3. Ensure all data fetching uses SWR hooks +4. Run typecheck to verify: `bunx turbo run typecheck --filter=@trycompai/app` diff --git a/.agents/skills/audit-rbac/SKILL.md b/.agents/skills/audit-rbac/SKILL.md new file mode 100644 index 0000000000..df0786bcb0 --- /dev/null +++ b/.agents/skills/audit-rbac/SKILL.md @@ -0,0 +1,42 @@ +--- +name: audit-rbac +description: Audit & fix RBAC and audit log compliance in API endpoints and frontend components +--- + +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**. +5. **Guards**: Use `@UseGuards(HybridAuthGuard, PermissionGuard)` at controller or endpoint level. Never skip PermissionGuard. +6. **Webhooks**: External webhook endpoints use `@Public()` — no auth required. + +### 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') &&