# DriveTime Planner API ## Base URL `https://api.fahrschultermin.de/api/v1` ## Authentication JWT Bearer Token. Login returns a token valid for 8 hours. ``` Authorization: Bearer ``` ## Endpoints ### Auth | Method | Path | Description | |--------|------|-------------| | POST | `/auth/login` | Login with email/password, returns JWT | | POST | `/auth/logout` | Logout (client-side token discard) | | GET | `/auth/me` | Current user info (requires auth) | ### Bootstrap | Method | Path | Description | |--------|------|-------------| | GET | `/bootstrap` | Full frontend data: user, tenant, students, instructors, lessonTypes, templates (requires auth) | ### CRUD | Method | Path | Description | |--------|------|-------------| | GET | `/students` | List students (requires auth) | | POST | `/students` | Create student (requires auth) | | PATCH | `/students/{id}` | Update student (requires auth) | | DELETE | `/students/{id}` | Delete student (requires auth) | | GET | `/instructors` | List instructors (requires auth) | | POST | `/instructors` | Create instructor (requires auth) | | PATCH | `/instructors/{id}` | Update instructor (requires auth) | | GET | `/appointments` | List appointments, optionally filter by `from`/`to` query params (requires auth) | | POST | `/appointments` | Create appointment with instructor conflict detection (requires auth) | | PATCH | `/appointments/{id}` | Update appointment with conflict check (requires auth) | | DELETE | `/appointments/{id}` | Delete appointment (requires auth) | | GET | `/lesson-types` | List lesson types (requires auth) | | GET | `/license-class-templates` | List license class templates with requirements (requires auth) | ## Error Responses | Code | Meaning | |------|---------| | 400 | Bad Request — missing or invalid parameters | | 401 | Unauthorized — missing or invalid JWT | | 404 | Not Found — resource doesn't exist or wrong tenant | | 409 | Conflict — e.g. instructor has overlapping appointment | | 500 | Internal Server Error | ## Environment Variables | Variable | Description | |----------|-------------| | `JWT_SECRET` | 256-bit secret for JWT signing (required) | ## Example ```bash # Login TOKEN=$(curl -s -X POST https://api.fahrschultermin.de/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"admin@nordring.test","password":"Tanja82"}' | jq -r '.token') # Get bootstrap data curl https://api.fahrschultermin.de/api/v1/bootstrap \ -H "Authorization: Bearer $TOKEN" | jq . # Create appointment curl -X POST https://api.fahrschultermin.de/api/v1/appointments \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"instructor_id":1,"lesson_type_id":1,"start_at":"2026-05-25 10:00","end_at":"2026-05-25 11:00","title":"Test"}' ``` ## Tech Stack - Slim 4 (PSR-7 HTTP factory) - Eloquent ORM (Illuminate Database) - Firebase JWT for authentication - PHP-DI for dependency injection - CORS middleware (tuupola/cors-middleware)