Reflects the post-S1+S2a+S2b database state. Nothing but SCHEMA.md changed. - Header: Version → 2.0, added v2.0 changelog entry covering the 13 new tables, the 3 dropped legacy tables, the preserved person_section_preferences, organisations.default_locale, and the events.registration_show_* drops. - Table of Contents: updated §3.5.5b name to "Section Preferences", added entries for §3.5.10 Email Infrastructure, §3.5.11 Rules, §3.5.12 Form Builder (which were already in the file but missing from the TOC). - §3.5.1 organisations: added default_locale column (FormLocaleResolver fallback chain, ARCH §16.2). - §3.5.1 events: removed registration_show_section_preferences + registration_show_availability columns with a pointer at form_fields.is_portal_visible / conditional_logic. - §3.5.4: removed the never-created volunteer_profiles table block; the other three tables in that section (volunteer_festival_history, post_festival_evaluations, festival_retrospectives) are unchanged. - §3.5.5b: renamed to "Section Preferences"; design note pointing at events.registration_show_section_preferences replaced with a pointer at form_fields.is_portal_visible / conditional_logic. - §3.5.9: renamed to "Check-In & Operational"; removed the never-created public_forms stub and the colliding legacy form_submissions block (both documented planned-but-never-created tables) with a short note pointing at the Form Builder as the home for form concepts. Flagged separately below because it's technically beyond the task's explicit scope but unavoidable (SCHEMA.md would otherwise describe two different tables under the same name). - §3.5.12 Form Builder: summary replaced with full per-table documentation for all 13 tables in the ARCH §4 order — user_profiles, form_schemas (polymorphic owner, public_token rotation with public_token_previous + public_token_rotated_at, edit_lock_*), form_schema_sections, form_field_library, form_fields, form_submissions, form_submission_section_statuses, form_submission_delegations, form_values (observer-driven typed columns value_indexed/number/date/bool and form_value_options multi-value rebuild per ARCH §7.2), form_value_options, form_templates, form_schema_webhooks, form_webhook_deliveries. Added short notes on activity log strategy and the §31.10 FORM-02 tag-sync listener. Migrations-vs-ARCH discrepancies (migrations win, per CLAUDE.md): - form_values carries created_at / updated_at timestamps, though ARCH §4.4 does not list them. Documented as present. - form_webhook_deliveries has no timestamps columns; last_attempt_at is the effective timestamp. Documented as such. - form_schema_webhooks stores url / secret as encrypted TEXT columns (Eloquent-cast encryption); ARCH says "encrypted" without specifying. Documented the column type. - public_forms + legacy form_submissions documented in §3.5.9 never existed in the DB (confirmed via Schema::hasTable). Removed those doc stubs; the naming collision with the new Form Builder form_submissions made leaving them in place a correctness hazard.
Crewli
Multi-tenant SaaS platform for event and festival operations: planning, people, accreditation, artist advancing, volunteer shifts, briefings, and show-day tooling (Mission Control). The backend is a JSON-only Laravel API; all user interfaces are Vue 3 single-page apps.
What Crewli covers
- Organisations & events — Multi-tenant data with organisation-scoped access; events move through a defined lifecycle (draft → published → registration → buildup → show day → teardown → closed).
- Festival structure — Sections, time slots, shifts, assignments, claiming/approval flows for volunteers and crew.
- People & crowds — Crowd types (crew, volunteers, artists, guests, press, partners, suppliers), persons, lists, and (planned) rich accreditation (items, zones, hand-out).
- Artists & advancing — Booking status, stages/timetable concepts, advance sections and token-based portal access for external artists.
- Communication — Briefings, campaigns, and operational messaging (see architecture doc for target modules).
- Portal (external users) — One portal app, two modes: login (Sanctum) for long-term users such as volunteers, and token access for per-event links (e.g. artists, suppliers).
Implementation is phased; the authoritative feature and schema list lives in the architecture and design references below.
Applications
| App | Path | Port | Role |
|---|---|---|---|
| Organizer | apps/app/ |
5174 | Main product for org and event staff: events, sections, shifts, people, artists, accreditation, briefings, reports. Includes Platform Admin section for super admins (/platform/*). |
| Portal | apps/portal/ |
5175 | External users: stripped layout; login- or token-based access. |
All apps talk to the API over CORS with Laravel Sanctum tokens.
Tech stack
| Layer | Technology |
|---|---|
| API | PHP 8.2+, Laravel 12, Sanctum, Spatie Permission (and Activity Log / Media Library where used) |
| Data | MySQL 8, Redis (cache/queues) |
| Frontends | Vue 3, TypeScript, Vite, Vuexy + Vuetify, Pinia, TanStack Query, VeeValidate + Zod |
| Local services | Docker Compose (MySQL, Redis, Mailpit) |
Rule of thumb: business tables use ULID primary keys; event-related data is scoped by organisation (global scopes + policies), not ad hoc where clauses in controllers.
Project structure
crewli/
├── api/ # Laravel 12 REST API (JSON only)
├── apps/
│ ├── app/ # Organizer SPA (primary UI + platform admin)
│ └── portal/ # External portal SPA
├── docker/ # Docker / Compose assets
├── docs/ # SETUP, API notes, schema notes
├── resources/
│ ├── design/ # Product source of truth (design docs, see table below)
│ └── vuexy-admin-*/ # Vuexy template reference (bundled kit)
├── .cursor/ # ARCHITECTURE.md, instructions.md, rules for AI/helpers
└── Makefile # Dev commands
Vuexy @core/ and @layouts/ in each app should stay untouched; customize via app config, navigation, and app-level components.
Quick start
# 1. Infrastructure
make services
# 2. API env, dependencies, database (see docs/SETUP.md)
cd api && cp .env.example .env && composer install && php artisan key:generate && php artisan migrate
# 3. Run API + the SPAs you need (separate terminals)
make api
make app
make portal
Detailed setup: docs/SETUP.md.
Development URLs
| Service | Development | Env / notes |
|---|---|---|
| API | http://localhost:8000/api/v1 | Base path /api/v1 |
| Organizer | http://localhost:5174 | FRONTEND_APP_URL |
| Portal | http://localhost:5175 | FRONTEND_PORTAL_URL |
| Mailpit | http://localhost:8025 | Local mail capture |
Production (crewli.app)
Domains: crewli.app is this product (API + organizer + portal SPAs, transactional email from the app, seeds, etc.). crewli.nl is reserved for a future public marketing site only — do not point this codebase's APP_URL, CORS, Sanctum, or app mail at crewli.nl.
Typical layout (configure the same values in api/.env — see api/.env.example):
| Service | URL | Env variable |
|---|---|---|
| API | https://api.crewli.app |
APP_URL |
| Organizer | https://crewli.app |
FRONTEND_APP_URL |
| Portal | https://portal.crewli.app |
FRONTEND_PORTAL_URL |
Frontends: set VITE_API_URL=https://api.crewli.app/api/v1 in each app's env for production builds. SANCTUM_STATEFUL_DOMAINS must list the hostnames only of the two SPAs (e.g. crewli.app,portal.crewli.app).
Makefile commands
make services # MySQL, Redis, Mailpit
make services-stop
make api # Laravel on :8000
make app # Organizer on :5174
make portal # Portal on :5175
make migrate
make fresh # migrate:fresh --seed
make db-shell
Documentation
| Resource | Contents |
|---|---|
| resources/design/ | Canonical product specs in Markdown. Referenced by .cursor and CLAUDE.md as source of truth for features and data model: design-document.md, dev-guide.md, start-guide.md. |
| .cursor/ARCHITECTURE.md | System diagram, apps, multi-tenancy, roles, event lifecycle, API route map, core schema overview (summarises resources/design when present) |
| .cursor/instructions.md | Quick reference, phased roadmap, module build order |
| .cursor/rules/ | Workspace, Laravel, Vue, testing conventions |
| docs/SETUP.md | Environment and local setup |
| docs/API.md | API notes (if maintained) |
| docs/SCHEMA.md | Schema notes (if maintained) |
Testing
cd api && php artisan test
Feature tests should cover happy paths plus 401 (unauthenticated), 403 (wrong organisation), and 422 (validation) where applicable.