# Crewli - Setup Guide This guide walks you through setting up the Crewli project from scratch. ## Cursor AI Configuration The project includes comprehensive AI instructions: ``` .cursor/ ├── instructions.md # Quick start and common prompts ├── ARCHITECTURE.md # System design and database schema └── rules/ ├── 001_workspace.mdc # Project structure and conventions ├── 100_laravel.mdc # Laravel API patterns ├── 101_vue.mdc # Vue + Vuexy patterns └── 200_testing.mdc # Testing strategies ``` **Read these files first!** They contain everything Cursor needs to generate code correctly. ## Prerequisites Install these before starting: ### macOS (Homebrew) ```bash # PHP 8.3 brew install php@8.3 brew link php@8.3 # Composer brew install composer # Node.js (via fnm) brew install fnm fnm install 20 fnm use 20 # pnpm npm install -g pnpm # Docker Desktop # Download from: https://www.docker.com/products/docker-desktop/ ``` ### Verify Installation ```bash php -v # Should show 8.3.x composer -V # Should show 2.x node -v # Should show v20.x pnpm -v # Should show 8.x or 9.x docker -v # Should show Docker version ``` --- ## Step 1: Start Docker Services ```bash cd crewli make services ``` This starts: - **MySQL 8.0** on port 3306 - **Redis** on port 6379 - **Mailpit** on port 8025 (email testing UI) --- ## Step 2: Create Laravel API Open the project in Cursor and use this prompt: ``` Create a new Laravel 12 project in the api/ folder. Requirements: - Use the command: composer create-project laravel/laravel api - After creation, install Sanctum: composer require laravel/sanctum - Configure for API-only (we don't need web routes) - Set up CORS for localhost:5173, localhost:5174, localhost:5175 - Use MySQL with these credentials: - Host: 127.0.0.1 - Database: crewli - Username: crewli - Password: secret Follow the conventions in .cursor/rules for code style. ``` ### Manual Alternative ```bash cd crewli composer create-project laravel/laravel api cd api composer require laravel/sanctum php artisan install:api ``` Then configure `api/.env`: ```env DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=crewli DB_USERNAME=crewli DB_PASSWORD=secret FRONTEND_ADMIN_URL=http://localhost:5173 FRONTEND_APP_URL=http://localhost:5174 FRONTEND_PORTAL_URL=http://localhost:5175 SANCTUM_STATEFUL_DOMAINS=localhost:5173,localhost:5174,localhost:5175 SESSION_DOMAIN=localhost ``` **Production (domain `crewli.app`):** set `APP_URL=https://api.crewli.app`, point `FRONTEND_ADMIN_URL` / `FRONTEND_APP_URL` / `FRONTEND_PORTAL_URL` to `https://admin.crewli.app`, `https://app.crewli.app`, and `https://portal.crewli.app`, and `SANCTUM_STATEFUL_DOMAINS=admin.crewli.app,app.crewli.app,portal.crewli.app` (hostnames only). Each SPA build should use `VITE_API_URL=https://api.crewli.app/api/v1`. Full template: `api/.env.example`. The product uses **`crewli.app`** only; **`crewli.nl`** is for a future public marketing site, not this API or SPAs. --- ## Step 3: Vuexy frontends (this repo) This monorepo already contains three SPAs under `apps/`: | Directory | Role | Typical Vuexy source | |-----------|------|----------------------| | `apps/admin/` | Super Admin | full-version (TypeScript) | | `apps/app/` | Organizer (main product) | full-version or customized starter | | `apps/portal/` | External portal (volunteers, token links) | stripped starter / custom layout | If you ever need to re-copy from a Vuexy ZIP, use the paths above — not legacy `apps/band` or `apps/customers`. ```bash # Example only — adjust to your Vuexy download path cp -r ~/Downloads/vuexy/typescript-version/full-version/* apps/admin/ ``` --- ## Step 4: Configure SPAs ### Install Dependencies ```bash cd apps/admin && pnpm install cd ../app && pnpm install cd ../portal && pnpm install ``` ### Create Environment Files **apps/admin/.env.local** ```env VITE_API_URL=http://localhost:8000/api/v1 VITE_APP_NAME="Crewli Admin" ``` **apps/app/.env.local** ```env VITE_API_URL=http://localhost:8000/api/v1 VITE_APP_NAME="Crewli Organizer" ``` **apps/portal/.env.local** ```env VITE_API_URL=http://localhost:8000/api/v1 VITE_APP_NAME="Crewli Portal" ``` ### Dev server ports From the repo root, `make admin`, `make app`, and `make portal` start Vite on **5173**, **5174**, and **5175** respectively. If you run `pnpm dev` manually, configure the same ports in each app’s `vite.config.ts` under `server.port`. --- ## Step 5: API client in SPAs `apps/admin/src/lib/api-client.ts`, `apps/app/src/lib/api-client.ts`, and `apps/portal/src/lib/api-client.ts` share the same pattern: `VITE_API_URL` base, Bearer token from the `accessToken` cookie, 401 → clear cookies and redirect to `/login`. Build new composables on `apiClient`; keep Vuexy `useApi` for template demos only. --- ## Step 6: Create database schema Implement migrations from the canonical schema, not a legacy intranet model: - **`docs/SCHEMA.md`** — table list, columns, indexes - **`.cursor/ARCHITECTURE.md`** — overview and relationships - **`.cursor/rules/103_database.mdc`** — ULIDs, soft deletes, index rules **Checked-in foundation (this repo):** Laravel defaults (`users`, `cache`, `jobs`) then `2026_04_07_*` migrations: Sanctum tokens → Spatie permission → activity log → `organisations` → `organisation_user` → `events` → `user_invitations` → `event_user_roles`. New modules should append migrations with a later timestamp in dependency order. Typical next expansion order from `103_database.mdc`: festival sections, time slots, persons, shifts, … Then run: ```bash cd api && php artisan migrate ``` --- ## Step 7: Start development Open separate terminals (or use the Makefile from the repo root): ```bash # Tab 1: Services (Docker) make services # Tab 2: Laravel API make api # Tab 3: Admin SPA (optional) make admin # Tab 4: Organizer SPA (optional) make app # Tab 5: Portal SPA (optional) make portal ``` --- ## Building features Use Cursor with **`CLAUDE.md`** and **`.cursor/instructions.md`**. Example directions: ### Authentication ``` Wire Sanctum API auth: login, logout, me; form requests; API resources; Vue apps use axios + token storage (see .cursor/rules). ``` ### Events module (Crewli) ``` Events nested under organisations: ULID PK, OrganisationScope, policies, EventResource, feature tests (200/401/403/422). ``` ### Portal token flow ``` Portal token middleware and routes for artist/supplier contexts; document links on https://portal.crewli.app/... (see .cursor/rules/102_multi_tenancy.mdc). ``` --- ## Troubleshooting ### MySQL Connection Refused ```bash # Check if Docker is running docker ps # Restart services make services-stop make services ``` ### CORS Errors Check `api/config/cors.php` allows your frontend origins. ### Vuexy TypeScript Errors ```bash cd apps/admin pnpm install pnpm type-check ``` --- ## Next steps 1. Services running (Docker) 2. Laravel API configured and migrated 3. SPAs installed (`apps/admin`, `apps/app`, `apps/portal`) 4. Environment files for API + each SPA 5. Authentication and organisation switching 6. Events, sections, time slots, shifts 7. Persons, crowd types, portal flows 8. Accreditation, briefings, operational modules per roadmap in `.cursor/instructions.md`