# Laravel Jukebox API - Quick Reference

## 🔐 Authentication
- **Method**: Laravel Sanctum (Bearer Token)
- **Register**: `POST /register` - Creates user with 'user' role
- **Login**: `POST /login` - Returns Bearer token
- **Logout**: `POST /logout` - Deletes token
- **Me**: `GET /me` - Current user info

## 📊 Database
```
Roles (id, name)
Users (id, name, email, password, role_id)
├─ belongs_to: Role
└─ belongs_to_many: Track (likes table)

Labels (id, name)
├─ has_many: Artist
└─ has_many: Album

Genres (id, name)
└─ belongs_to_many: Track (track_genre table)

Artists (id, name, cover_path, release_date, label_id, duration)
├─ belongs_to: Label
└─ belongs_to_many: Track (artist_track table)

Albums (id, title, cover_path, release_date, duration_seconds, type, label_id)
├─ belongs_to: Label
└─ has_many: Track

Tracks (id, title, file_path, duration_seconds, album_id)
├─ belongs_to: Album
├─ belongs_to_many: Artist (artist_track table)
├─ belongs_to_many: Genre (track_genre table)
└─ belongs_to_many: User (likes table)
```

## 🔓 Public Endpoints
```
POST   /register
POST   /login
```

## 🔒 Authenticated Endpoints (All require Bearer token)

### Account Management
```
POST   /logout
GET    /me
PUT    /me (User update - not implemented yet)
```

### User Likes
```
GET    /me/likes              - Get liked tracks
POST   /tracks/{id}/like      - Like a track
DELETE /tracks/{id}/like      - Unlike a track
```

### Browse (Read-only)
```
GET    /labels
GET    /labels/{id}
GET    /genres
GET    /genres/{id}
GET    /artists
GET    /artists/{id}           (includes: label, tracks.album, tracks.genres)
GET    /albums
GET    /albums/{id}            (includes: label, tracks.artists, tracks.genres)
GET    /tracks
GET    /tracks/{id}            (includes: album.label, artists, genres)
```

## 👑 Admin-Only Endpoints (role_id where role.name='admin')

### Create/Update/Delete
```
POST   /labels              POST   /genres              POST   /artists
PUT    /labels/{id}         PUT    /genres/{id}         PUT    /artists/{id}
DELETE /labels/{id}         DELETE /genres/{id}         DELETE /artists/{id}

POST   /albums              POST   /tracks
PUT    /albums/{id}         PUT    /tracks/{id}
DELETE /albums/{id}         DELETE /tracks/{id}

POST   /users               GET    /users
PUT    /users/{id}          GET    /users/{id}
DELETE /users/{id}
```

## 📝 Controllers
| Controller | Methods | Purpose |
|-----------|---------|---------|
| AuthController | register, login, logout, me | User authentication |
| UserController | index, show, update, destroy | User management (admin) |
| ArtistController | index, show, store, update, destroy | Artist CRUD |
| AlbumController | index, show, store, update, destroy | Album CRUD |
| TrackController | index, show, store, update, destroy | Track CRUD with pivot syncing |
| GenreController | index, show, store, update, destroy | Genre CRUD |
| LabelController | index, show, store, update, destroy | Label CRUD |
| LikeController | index, like, unlike | User favorites |

## 🛡️ Middleware
- `auth:sanctum` - All authenticated routes
- `admin` - Admin-only routes (checks role.name === 'admin')

## 🔑 Key Validation Rules

### Registration
- name: required, string, max:255
- email: required, email, unique:users
- password: required, string, min:8, confirmed

### Artist/Album/Track Creation
- Supports partial nullable fields
- Artist: name (required), cover_path, release_date, label_id, duration
- Album: title (required), cover_path, release_date, duration_seconds, type, label_id
- Track: title (required), file_path (required), duration_seconds, album_id, artist_ids[], genre_ids[]

## ⚠️ Notable Limitations
- ❌ No pagination on list endpoints (returns all records)
- ❌ No search/filtering capabilities
- ❌ No rate limiting
- ❌ No API resources/transformers (direct model JSON)
- ❌ No CORS config file (relying on Sanctum defaults)
- ❌ No endpoint documentation/OpenAPI spec
- ❌ Minimal test coverage
- ❌ Only UserFactory (no factories for other models)

## 🚀 Quick Start

```bash
# Register
curl -X POST http://localhost/api/register \
  -H "Content-Type: application/json" \
  -d '{"name":"User","email":"user@example.com","password":"password123","password_confirmation":"password123"}'

# Response
{
  "token": "1|abc123...",
  "user": {
    "id": 1,
    "name": "User",
    "email": "user@example.com",
    "role": {"id": 1, "name": "user"}
  }
}

# Use token in subsequent requests
curl -X GET http://localhost/api/me \
  -H "Authorization: Bearer 1|abc123..."

# Like a track
curl -X POST http://localhost/api/tracks/1/like \
  -H "Authorization: Bearer 1|abc123..."

# Get liked tracks
curl -X GET http://localhost/api/me/likes \
  -H "Authorization: Bearer 1|abc123..."
```

## 📁 Directory Structure
```
/app
  /Http
    /Controllers (8 controllers)
    /Middleware (EnsureAdmin)
  /Models (7 models)
  /Providers
/routes
  /api.php (main API routes)
  /web.php (minimal web routes)
/database
  /migrations (11 migrations)
  /seeders (DatabaseSeeder - creates 1 test user)
  /factories (UserFactory only)
/config
  /sanctum.php (token auth config)
  /auth.php (authentication guards)
```

## 🔄 Response Formats

### Success (Single Resource)
```json
{
  "id": 1,
  "name": "Artist Name",
  "created_at": "2026-04-21T...",
  "updated_at": "2026-04-21T..."
}
```

### Success (List)
```json
[
  { "id": 1, "name": "Item 1" },
  { "id": 2, "name": "Item 2" }
]
```

### Delete (204 No Content)
```
No body
```

### Error (ValidationException)
```json
{
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The email has already been taken."]
  }
}
```

### Error (403 Forbidden - Admin Only)
```json
{
  "message": "Forbidden."
}
```

## 🔗 Relationship Eager Loading (Controllers)
- Artist show: `with(['label', 'tracks.album', 'tracks.genres'])`
- Album show: `with(['label', 'tracks.artists', 'tracks.genres'])`
- Track show: `with(['album.label', 'artists', 'genres'])`
- Track index: `with(['album', 'artists', 'genres'])`
- Likes index: `with(['album', 'artists', 'genres'])`

## 🗄️ Database Connection
- Type: MySQL
- Host: 172.17.0.1 (Docker)
- Port: 3306
- Database: jukebox
- User: jukebox_admin
- Password: Super

---

**Full documentation available in: `/API_DOCUMENTATION.md`**
