# Crewli — Cursor Master Prompt # Plak dit BOVEN elke task. Vervang [TASK] onderaan. ## MANDATORY PREAMBLE Read `@CLAUDE.md` and `@dev-docs/SCHEMA.md` before starting. Use `@workspace` for full codebase context. These documents are your source of truth. If modifying existing code, read the current implementation first. Understand the patterns already in use before writing anything new. ## PROJECT CONTEXT Crewli — multi-tenant SaaS for event/festival management. - **Frontend:** Vue 3 + TypeScript + Vuexy 9.5 (Vuetify 3.10) + Pinia + TanStack Vue Query + VeeValidate + Zod - **Three SPAs:** - `apps/admin/` — Super Admin (port 5173) - `apps/app/` — Organizer main app (port 5174) - `apps/portal/` — Dual-mode portal (port 5175) - **API base:** `VITE_API_URL` from `.env.local` (default `http://localhost:8000`) - **Axios instance:** `src/lib/axios.ts` — this is the ONLY axios instance. Never create another. Never import axios directly in components. - **Backend Enums:** PHP Enums in `api/app/Enums/` define all valid status/type values. TypeScript equivalents must mirror these exactly in `src/types/`. ### Frontend file structure (per app) ``` src/ ├── lib/axios.ts # Singleton axios instance (DO NOT DUPLICATE) ├── types/ # TypeScript interfaces per module │ └── [module].ts ├── composables/api/ # TanStack Query composables per module │ └── use[Module].ts ├── stores/ # Pinia stores (cross-component state only) │ └── use[Module]Store.ts ├── pages/ # Page components │ └── [module]/ │ ├── index.vue # List view │ └── [id].vue # Detail view (or side panel) └── router/ # Vue Router config ``` --- ## ZERO-COMPROMISE RULES — VIOLATIONS ARE BLOCKERS ### TypeScript & typing 1. **NO `any` TYPES. EVER.** Every variable, prop, emit, return type, ref, reactive, computed, and API response is fully typed. If you don't know the type, check the backend API Resource in `api/app/Http/Resources/` — that defines the contract. Create matching interfaces in `src/types/[module].ts`. 2. **TYPES FIRST.** Before writing any composable or component for a new module, create the TypeScript interfaces in `src/types/[module].ts`. These mirror the backend API Resource shape. Include: - Entity interface (e.g., `Shift`, `Person`, `Event`) - Create/Update DTOs (matching backend Form Request fields) - Enum-like union types or const objects matching backend PHP Enums - Paginated response wrapper if applicable 3. **ENUMS AS CONST OBJECTS.** Mirror backend PHP Enums as TypeScript const objects with `as const`, not as loose string unions scattered across files: ```typescript // src/types/shift.ts export const ShiftAssignmentStatus = { PENDING_APPROVAL: 'pending_approval', APPROVED: 'approved', REJECTED: 'rejected', CANCELLED: 'cancelled', COMPLETED: 'completed', } as const export type ShiftAssignmentStatus = typeof ShiftAssignmentStatus[keyof typeof ShiftAssignmentStatus] ``` ### Architecture & patterns 4. **NO DIRECT AXIOS IN COMPONENTS.** All API calls go through composables in `composables/api/use[Module].ts` using TanStack Query (`useQuery` / `useMutation`). Components never import axios or `src/lib/axios.ts`. The composable is the only layer that knows about HTTP. 5. **NO OPTIONS API.** Always `