147 lines
6.1 KiB
Markdown
147 lines
6.1 KiB
Markdown
# Crewli — Zero-Compromise Vibe Coding Aandachtspunten
|
|
|
|
Referentiedocument voor het aansturen van AI agents (Claude Code & Cursor).
|
|
Alle 18 principes zijn verwerkt in de master prompts. Dit document dient als
|
|
overzicht en review-checklist.
|
|
|
|
---
|
|
|
|
## De 18 principes — waar ze landen
|
|
|
|
| # | Principe | Master Prompt CC | Master Prompt Cursor | Sectie |
|
|
|---|----------|:---:|:---:|--------|
|
|
| 1 | Architectuur eerst | ✅ Regel 1 | — | Architecture & design |
|
|
| 2 | Delete > Adapt | ✅ Regel 2 | ✅ Regel 7 | Architecture & design |
|
|
| 3 | Strict layering | ✅ Regel 3 | ✅ Regel 4, 6 | Architecture & design |
|
|
| 4 | Contract-first | ✅ Regel 4 | ✅ Regel 2, 3 | Architecture & design |
|
|
| 5 | Tests als design | ✅ Regel 11, 12 | — | Testing |
|
|
| 6 | Idempotency & resilience | ✅ Regel 21 | — | Resilience & operations |
|
|
| 7 | Naming is architecture | ✅ Regel 9 | ✅ Regel 16 | Code quality |
|
|
| 8 | Security & auth direct goed | ✅ Regel 16, 17 | ✅ Regel 17 | Security & multi-tenancy |
|
|
| 9 | Performance by design | ✅ Checklist | ✅ (via composable pattern) | Verification |
|
|
| 10 | Consistency > cleverness | ✅ Regel 5 | ✅ Regel 8 | Architecture & design |
|
|
| 11 | Observability dag 1 | ✅ Regel 22 | — | Resilience & operations |
|
|
| 12 | Versioning & backward compat | ✅ Regel 23 | — | Resilience & operations |
|
|
| 13 | Data model = heilig | ✅ Regel 13, 14, 15 | — | Data & persistence |
|
|
| 14 | Prompt discipline | ✅ Hele structuur | ✅ Hele structuur | (Meta) |
|
|
| 15 | Perfectie vs. pragmatiek | ✅ Regel 3 + 5 | ✅ Regel 8 | Architecture & design |
|
|
| 16 | Zero TODO | ✅ Regel 7 | ✅ Regel 14 | Code quality |
|
|
| 17 | Single Source of Truth | ✅ Regel 6 | ✅ Regel 9 | Architecture & design |
|
|
| 18 | Definition of Done | ✅ Checklist | ✅ Regel 19 | Verification |
|
|
|
|
---
|
|
|
|
## Projectspecifieke aandachtspunten (bovenop de 18)
|
|
|
|
### Bestandspaden — correcte referenties
|
|
|
|
| Wat | Correct pad | Fout (oude pad) |
|
|
|-----|-------------|-----------------|
|
|
| Schema definitie | `/dev-docs/SCHEMA.md` | `/docs/SCHEMA.md` |
|
|
| API contract | `/dev-docs/API.md` | `/docs/API.md` |
|
|
| Design document | `/dev-docs/design-document.md` | `/docs/design-document.md` |
|
|
| Dev guide | `/dev-docs/dev-guide.md` | `/docs/dev-guide.md` |
|
|
| User docs (VitePress) | `/docs/` | — |
|
|
| Workspace rules | `/CLAUDE.md` (root) | — |
|
|
| Axios instance (app) | `apps/app/src/lib/axios.ts` | `src/utils/api.ts` etc. |
|
|
|
|
### PHP Enums — verplicht voor alle status/type velden
|
|
|
|
Agents gebruiken graag string literals. Dwing af:
|
|
|
|
```php
|
|
// ❌ VERBODEN
|
|
$assignment->status = 'approved';
|
|
Rule::in(['pending_approval', 'approved', 'rejected'])
|
|
|
|
// ✅ VERPLICHT
|
|
$assignment->status = ShiftAssignmentStatus::APPROVED;
|
|
Rule::enum(ShiftAssignmentStatus::class)
|
|
```
|
|
|
|
Alle bestaande/verwachte Enums (uit SCHEMA.md):
|
|
- `BillingStatus` — trial|active|suspended|cancelled
|
|
- `EventStatus` — draft|published|active|completed|archived
|
|
- `PersonStatus` — invited|applied|pending|approved|rejected|no_show
|
|
- `ShiftAssignmentStatus` — pending_approval|approved|rejected|cancelled|completed
|
|
- `InvitationStatus` — pending|accepted|expired|revoked
|
|
- `CrowdListType` — internal|external
|
|
- `BookingStatus` — pending|offer_sent|confirmed|cancelled|declined
|
|
- `AdvanceSectionStatus` — not_started|in_progress|submitted|approved
|
|
|
|
### Service Layer — wanneer wel/niet
|
|
|
|
**Gebruik een Service class wanneer:**
|
|
- Business logic meer is dan "opslaan wat de FormRequest valideert"
|
|
- Meerdere modellen gewijzigd worden in één actie
|
|
- Side effects nodig zijn (notifications, activity log, queue jobs)
|
|
- Dezelfde logica vanuit meerdere controllers aangeroepen kan worden
|
|
|
|
**Voorbeelden in Crewli:**
|
|
- `ShiftAssignmentService` — assign, claim, approve, reject (status machine + notifications)
|
|
- `PersonIdentityService` — deduplicatie, user_id matching
|
|
- `AccreditationService` — toekennen, intrekken, budget checks
|
|
- `ZenderService` — SMS/WhatsApp via externe API
|
|
|
|
**Geen Service nodig voor:**
|
|
- Simpele CRUD zonder business logic (locations, crowd_types, accreditation_categories)
|
|
- Hier volstaat de controller direct
|
|
|
|
### Spatie Activity Log — verplicht gebruik
|
|
|
|
```php
|
|
// In elke Service method die state wijzigt:
|
|
activity()
|
|
->causedBy($user)
|
|
->performedOn($shift)
|
|
->withProperties([
|
|
'old' => ['status' => $oldStatus->value],
|
|
'new' => ['status' => $newStatus->value],
|
|
])
|
|
->log('shift.assignment.approved');
|
|
```
|
|
|
|
### Multi-tenancy mentale test
|
|
|
|
Bij elke nieuwe controller, voer deze test uit:
|
|
1. Maak in je hoofd twee organisaties: Org A en Org B
|
|
2. Gebruiker X hoort bij Org A
|
|
3. Kan X via de API data van Org B zien? → BUG
|
|
4. Kan X via de API data van Org B wijzigen? → CRITICAL BUG
|
|
5. Kan X via de API afleiden dat data van Org B bestaat? → SECURITY ISSUE
|
|
|
|
### Idempotency checklist voor queued jobs
|
|
|
|
Elke Job moet deze vragen beantwoorden:
|
|
- Wat gebeurt er als deze job 2x draait? → Geen dubbele side effects
|
|
- Wat als het model intussen verwijderd is? → Graceful exit, geen crash
|
|
- Wat als de externe API (Zender) een timeout geeft? → Retry met backoff
|
|
- Wat als de status intussen veranderd is? → Check-before-act
|
|
|
|
---
|
|
|
|
## Review checklist — na elke Claude Code / Cursor sessie
|
|
|
|
### Backend (Claude Code output)
|
|
- [ ] Geen TODO/FIXME/HACK (`grep -rn "TODO\|FIXME\|HACK" api/app/`)
|
|
- [ ] Geen UUID v4 (`grep -rn "uuid(" api/database/migrations/`)
|
|
- [ ] Geen `Model::all()` zonder scope
|
|
- [ ] Geen business logic in controllers (alleen HTTP + delegate to Service)
|
|
- [ ] PHP Enums gebruikt (niet string literals)
|
|
- [ ] Activity log in Service methods
|
|
- [ ] Tests draaien groen (`php artisan test`)
|
|
- [ ] Migratie heeft `down()` method
|
|
- [ ] Policies compleet (geen `return true` placeholders)
|
|
- [ ] N+1 check: `with()` in index/show actions
|
|
- [ ] `/dev-docs/API.md` bijgewerkt
|
|
|
|
### Frontend (Cursor output)
|
|
- [ ] Geen `any` types (`grep -rn ": any\|as any" apps/*/src/`)
|
|
- [ ] Geen directe axios imports in components
|
|
- [ ] Types gedefinieerd in `src/types/`
|
|
- [ ] Drie states: loading, error, empty
|
|
- [ ] Zod schema voor formulieren
|
|
- [ ] Vuetify componenten (geen onnodige custom CSS)
|
|
- [ ] Mobile responsive op 375px
|
|
- [ ] `npx tsc --noEmit` groen
|