Files
band-management/CLAUDE.md
bert.hausmans 1cb7674d52 refactor: align codebase with EventCrew domain and trim legacy band stack
- 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
2026-03-29 23:19:06 +02:00

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

  1. Migratie(s) aanmaken en draaien
  2. Eloquent Model met relaties, scopes en HasUlids
  3. Factory voor test-data
  4. Policy voor autorisatie
  5. Form Request(s) voor validatie
  6. API Resource voor response transformatie
  7. Resource Controller
  8. Routes registreren in api.php
  9. PHPUnit Feature Test schrijven en draaien
  10. Vue composable voor API calls (useModuleNaam.ts)
  11. Pinia store indien cross-component state nodig
  12. Vue pagina component
  13. Route toevoegen in Vue Router