diff --git a/dev-docs/SETUP.md b/dev-docs/SETUP.md index 3dd923f2..114cf420 100644 --- a/dev-docs/SETUP.md +++ b/dev-docs/SETUP.md @@ -1,269 +1,216 @@ -# Crewli - Setup Guide +# Crewli — Working in this repo -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. +A guide for developers continuing work on the Crewli codebase. Assumes you've cloned the repo and have basic terminal familiarity. ## Prerequisites -Install these before starting: +Install these once before starting: -### macOS (Homebrew) +| Tool | Version | Install (macOS via Homebrew) | +|------|---------|------------------------------| +| PHP | 8.4 | `brew install php@8.4 && brew link php@8.4` | +| Composer | 2.x | `brew install composer` | +| Node.js | 20 LTS | `brew install fnm && fnm install 20 && fnm use 20` | +| pnpm | 9.x | `npm install -g pnpm` | +| Docker Desktop | latest | https://www.docker.com/products/docker-desktop/ | + +Verify: ```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/ +php -v # 8.4.x +composer -V # 2.x +node -v # v20.x +pnpm -v # 9.x or 10.x +docker -v # any recent version ``` -### Verify Installation +## First-time setup + +From the repo root: ```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 -``` +# 1. Backend dependencies +cd api && composer install ---- +# 2. Frontend dependencies +cd ../apps/app && pnpm install -## Step 1: Start Docker Services +# 3. Backend env file +cd ../../api +cp .env.example .env +php artisan key:generate -```bash -cd crewli +# 4. Frontend env file +cd ../apps/app +cp .env.example .env.local + +# 5. Start Docker services (MySQL, Redis, Mailpit) +cd .. 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: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 +# 6. Database setup cd api -composer require laravel/sanctum -php artisan install:api +php artisan migrate --seed + +# 7. Frontend post-install (icon build + MSW worker) +cd ../apps/app +pnpm run build:icons +pnpm run msw:init + +# 8. Verify everything works +cd ../../api +php artisan test ``` -Then configure `api/.env`: +If `php artisan test` is green, you're ready. + +## Daily workflow + +Three terminal tabs, plus an optional fourth for the queue worker: + +| Terminal | Command | Where it runs | Port | +|----------|---------|---------------|------| +| 1. Services | `make services` (from repo root) | Docker | 3306 (MySQL), 6379 (Redis), 8025 (Mailpit) | +| 2. API | `make api` (from repo root) | Laravel dev server | 8000 | +| 3. SPA | `make app` (from repo root) | Vite dev server | 5174 | +| 4. Queue worker (optional) | `cd api && php artisan queue:listen redis --queue=emails` | Local PHP | n/a | + +The queue worker is only needed when you're triggering email flows (registration, password reset, email change, invitations). Routine UI work doesn't require it. + +Stop services when done: `make services-stop`. + +## Environment variables + +### `api/.env` + +The defaults from `.env.example` cover local development. Key entries: + ```env -DB_CONNECTION=mysql -DB_HOST=127.0.0.1 -DB_PORT=3306 DB_DATABASE=crewli DB_USERNAME=crewli DB_PASSWORD=secret - -FRONTEND_APP_URL=http://localhost:5174 -FRONTEND_PORTAL_URL=http://localhost:5175 -SANCTUM_STATEFUL_DOMAINS=localhost:5174,localhost:5175 +QUEUE_CONNECTION=redis SESSION_DOMAIN=localhost +FRONTEND_APP_URL=http://localhost:5174 +SANCTUM_STATEFUL_DOMAINS=localhost:5174 +APP_URL=http://localhost:8000 ``` -**Production (domain `crewli.app`):** set `APP_URL=https://api.crewli.app`, point `FRONTEND_APP_URL` / `FRONTEND_PORTAL_URL` to `https://crewli.app` and `https://portal.crewli.app`, and `SANCTUM_STATEFUL_DOMAINS=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. +For production deployment (registered domain `crewli.app`): ---- - -## Step 3: Vuexy frontends (this repo) - -This monorepo already contains two SPAs under `apps/`: - -| Directory | Role | Typical Vuexy source | -|-----------|------|----------------------| -| `apps/app/` | Organizer + Platform Admin (main product) | full-version (TypeScript) | -| `apps/portal/` | External portal (volunteers, token links) | stripped starter / custom layout | - -Super admin functionality lives in `apps/app/` under `/platform/*` routes, accessible to `super_admin` users. - ---- - -## Step 4: Configure SPAs - -### Install Dependencies - -```bash -cd apps/app && pnpm install -cd ../portal && pnpm install -``` - -### Create Environment Files - -**apps/app/.env.local** ```env -VITE_API_URL=http://localhost:8000/api/v1 -VITE_APP_NAME="Crewli Organizer" +APP_URL=https://api.crewli.app +FRONTEND_APP_URL=https://crewli.app +SESSION_DOMAIN=.crewli.app +SANCTUM_STATEFUL_DOMAINS=crewli.app ``` -**apps/portal/.env.local** +`crewli.nl` is reserved for a future marketing site only — not the application. + +### `apps/app/.env.local` + ```env -VITE_API_URL=http://localhost:8000/api/v1 -VITE_APP_NAME="Crewli Portal" +VITE_API_URL=http://localhost:8000 +VITE_APP_NAME="Crewli" ``` -### Dev server ports +For production: `VITE_API_URL=https://api.crewli.app`. -From the repo root, `make app` and `make portal` start Vite on **5174** and **5175** respectively. If you run `pnpm dev` manually, configure the same ports in each app’s `vite.config.ts` under `server.port`. +## Common tasks ---- - -## Step 5: API client in SPAs - -`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: +### Run tests ```bash -cd api && php artisan migrate +# Backend (PHPUnit, all tests) +cd api && php artisan test + +# Backend (specific filter) +cd api && php artisan test --filter=ShiftTest + +# Backend (with coverage) +cd api && php artisan test --coverage + +# Frontend (Vitest, all tests) +cd apps/app && pnpm test + +# Frontend (typecheck) +cd apps/app && pnpm typecheck + +# Frontend (lint) +cd apps/app && pnpm lint ``` ---- - -## Step 7: Start development - -Open separate terminals (or use the Makefile from the repo root): +### Database reset ```bash -# Tab 1: Services (Docker) -make services - -# Tab 2: Laravel API -make api - -# Tab 3: Organizer SPA (optional) -make app - -# Tab 4: Portal SPA (optional) -make portal +cd api && php artisan migrate:fresh --seed ``` ---- +This drops all tables, re-runs migrations, and re-seeds. Useful when schema changes or seeders are updated. -## Building features +### Inspect routes -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). +```bash +cd api && php artisan route:list --path=api/v1 ``` -### Events module (Crewli) +### Build for production -``` -Events nested under organisations: ULID PK, OrganisationScope, policies, EventResource, feature tests (200/401/403/422). +```bash +cd apps/app && pnpm build ``` -### Portal token flow +Output lands in `apps/app/dist/`. The `deploy.sh` script handles the rest for VPS deploys. -``` -Portal token middleware and routes for artist/supplier contexts; document links on https://portal.crewli.app/... (see .cursor/rules/102_multi_tenancy.mdc). +### Static analysis (optional) + +```bash +cd api && composer analyse # Larastan / PHPStan level 6 +cd api && composer rector --dry-run # Rector findings ``` ---- +## Documentation reference + +The `dev-docs/` directory is the developer source of truth. The most-used files: + +| File | Purpose | +|------|---------| +| `/CLAUDE.md` | Project conventions, vibe-coding principles, Vuexy-first decision tree (auto-loaded by Claude Code) | +| `dev-docs/SCHEMA.md` | Database schema (current version v2.x, kept in sync with migrations) | +| `dev-docs/API.md` | API contract | +| `dev-docs/AUTH_ARCHITECTURE.md` | Auth design (httpOnly cookies, MFA, impersonation, portal tokens) | +| `dev-docs/CLAUDE_CODE_TOOLING.md` | The `.claude/` deterministic guard-rail layer (hooks, subagent, slash commands) | +| `dev-docs/VUEXY_COMPONENTS.md` | Vuexy component registry — consult before writing any frontend | +| `dev-docs/BACKLOG.md` | Tracked tech debt and follow-ups | +| `dev-docs/ARCH-*.md` | Architecture decisions per workstream (consolidation, form builder, bindings, API validation) | + +The `docs/` directory (separate from `dev-docs/`) is end-user VitePress documentation in Dutch. ## Troubleshooting -### MySQL Connection Refused -```bash -# Check if Docker is running -docker ps +### MySQL connection refused -# Restart services -make services-stop -make services +```bash +docker ps # check containers are up +make services-stop && make services # restart ``` -### CORS Errors -Check `api/config/cors.php` allows your frontend origins. +### Port 8000 already in use + +Something else is bound to port 8000. Find it: `lsof -i :8000`. Kill it or change `make api` to use another port. + +### Frontend TypeScript errors after pulling main -### Vuexy TypeScript Errors ```bash cd apps/app -pnpm install -pnpm type-check +pnpm install # picks up new dependencies +pnpm typecheck # confirm clean ``` ---- +### Queue worker not picking up jobs -## Next steps +Confirm Redis is running: `docker ps | grep redis`. If yes, restart the queue worker — long-running listeners can drift after long idle periods. -1. Services running (Docker) -2. Laravel API configured and migrated -3. SPAs installed (`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` +### Test suite is slow + +PHPUnit defaults to a single process. Parallel: `cd api && php artisan test --parallel`.