- Update API: events, users, policies, routes, resources, migrations - Remove deprecated models/resources (customers, setlists, invitations, etc.) - Refresh admin app and docs; remove apps/band Made-with: Cursor
4.6 KiB
4.6 KiB
EventCrew — Claude Code Instructies
Project Context
EventCrew is een multi-tenant SaaS platform voor event- en festivalbeheer. Gebouwd voor een professionele vrijwilligersorganisatie, met SaaS-uitbreidingspotentieel. Design Document: /docs/EventCrew_Design_Document_v1.3.docx
Tech Stack
- Backend: PHP 8.2+, Laravel 12, Sanctum, Spatie Permission, MySQL 8, Redis
- Frontend: TypeScript, Vue 3 (Composition API), Vuexy/Vuetify, Pinia, TanStack Query
- Testing: PHPUnit (backend), Vitest (frontend)
Repository Structuur
- api/ Laravel backend
- apps/admin/ Super Admin SPA
- apps/app/ Organizer SPA (hoofdapp)
- apps/portal/ Externe portals (vrijwilliger, artiest, leverancier)
Apps & Portal Architectuur
- apps/admin/ = Super Admin — platformbeheer, organisaties aanmaken
- apps/app/ = Organizer — event management per organisatie
- apps/portal/ = Externe gebruikers — één app, twee toegangsmodi:
- Login-based (auth:sanctum): vrijwilligers, crew — persons met user_id
- Token-based (portal.token middleware): artiesten, leveranciers, pers — persons zonder user_id
CORS
Drie frontend origins configureren in zowel Laravel (config/cors.php via env) als Vite dev server proxy:
- admin: localhost:5173
- app: localhost:5174
- portal: localhost:5175
Backend Regels (STRIKT VOLGEN)
Multi-tenancy
- ELKE query op event-data MOET scoperen op organisation_id
- Gebruik OrganisationScope als Eloquent Global Scope op alle event-gerelateerde modellen
- Nooit directe id-checks in controllers — gebruik altijd Policies
Controllers
- Gebruik Resource Controllers (index/show/store/update/destroy)
- Namespace: App\Http\Controllers\Api\V1\
- Alle responses via API Resources (nooit model-attributen direct teruggeven)
- Validatie via Form Requests (nooit inline validate())
Modellen
- Gebruik HasUlids trait op alle business-modellen (GEEN UUID v4)
- Soft deletes op: Organisation, Event, FestivalSection, Shift, ShiftAssignment, Person, Artist
- GEEN soft deletes op: CheckIn, BriefingSend, MessageReply, ShiftWaitlist (audit-records)
- JSON kolommen ALLEEN voor opaque configuratie — nooit voor queryable data
Database
- Primaire sleutels: ULID via HasUlids (niet UUID v4, niet auto-increment voor business tables)
- Elke migratie in volgorde aanmaken: eerst foundation, dan afhankelijke tabellen
- ALTIJD composite indexes toevoegen zoals gedocumenteerd in het design document sectie 3.5
Rollen & Permissies
- Gebruik Spatie laravel-permission
- Check rollen via $user->hasRole() en Policies — nooit hardcoded role strings in controllers
- Drie niveaus: app (super_admin), organisatie (org_admin/org_member), event (event_manager etc.)
Testing
- Schrijf PHPUnit Feature Tests per controller
- Minimaal per endpoint: happy path + unauthenticated (401) + wrong organisation (403)
- Gebruik factories voor alle test-data
- Draai tests NA elke module: php artisan test --filter=ModuleNaam
Frontend Regels (STRIKT VOLGEN)
Vue Componenten
- Altijd <script setup lang='ts'> — nooit Options API
- Props altijd getypeerd met defineProps<{...}>()
- Emits altijd gedeclareerd met defineEmits<{...}>()
API Calls
- Gebruik TanStack Query (useQuery / useMutation) voor ALLE API calls
- Nooit direct axios in een component — altijd via een composable in composables/api/
- Pinia stores voor cross-component state — nooit prop drilling
Naamgeving
- DB kolommen: snake_case
- TypeScript/JS variabelen: camelCase
- Vue componenten: PascalCase (bijv. ShiftAssignPanel.vue)
- Composables: use-prefix (bijv. useShifts.ts)
- Pinia stores: use-suffix store (bijv. useEventStore.ts)
UI
- Gebruik ALTIJD Vuexy/Vuetify componenten voor layout, forms, tabellen, dialogen
- Nooit custom CSS schrijven als een Vuetify klasse bestaat
- Responsief: mobile-first, minimaal werkend op 375px breedte
Verboden Patronen
- NOOIT: $user->role === 'admin' (gebruik policies)
- NOOIT: Model::all() zonder where-clausule (altijd scopen)
- NOOIT: dd() of var_dump() achterlaten in code
- NOOIT: .env waarden hardcoden in code
- NOOIT: JSON kolommen gebruiken voor data waarop gefilterd wordt
- NOOIT: UUID v4 als primaire sleutel (gebruik HasUlids)
Volgorde bij elke nieuwe module
- Migratie(s) aanmaken en draaien
- Eloquent Model met relaties, scopes en HasUlids
- Factory voor test-data
- Policy voor autorisatie
- Form Request(s) voor validatie
- API Resource voor response transformatie
- Resource Controller
- Routes registreren in api.php
- PHPUnit Feature Test schrijven en draaien
- Vue composable voor API calls (useModuleNaam.ts)
- Pinia store indien cross-component state nodig
- Vue pagina component
- Route toevoegen in Vue Router