# Backend Specification

## Core Technology Stack
- **Runtime:** Node.js (TypeScript)
- **Framework:** Fastify
- **Communication:** REST API (primary)
- **Queueing:** BullMQ with Redis

## 1. API Architecture

### **Library Management**
- `GET /api/tracks`: Paginated list of tracks (supports sort/filter).
- `GET /api/tracks/{id}`: Full track metadata.
- `GET /api/search?q={query}`: Fuzzy search via Typesense.
- `POST /api/library/reindex`: Manual trigger for the indexing worker.

### **The Vibe Engine (Recommendation)**
- `GET /api/vibe`: Returns a **Sequence Chunk** of track IDs. 
  - *Client Implementation:* Uses TanStack Query to implement a "Look-ahead Buffer."
- `GET /api/vibe/from-genre?genre={id}`: Generates a session based on a specific genre.

### **The Lifecycle (Dislike/Removal)**
- `POST /api/dislike/{track_id}`: Moves track to `PENDING_REMOVAL` (State: `HIDDEN`).
- `DELETE /api/dislike/{id}`: Restores track to `LIBRARY`.
- `GET /api/dislikes`: Lists all tracks in the quarantine.
- `POST /api/dislikes/sweep`: Manual trigger for the background cleanup worker.

### **Session Management**
- `GET /api/sessions/current`: Returns the metadata for the current `ACTIVE` recommendation batch.
- `POST /api/sessions/heartbeat`: Updates `last_interaction_at` for the active batch.

## 2. The "Rolling Window" Algorithm

To provide an infinite, evolving stream, the backend implements a **Stateful Sequence Generator**.

### **Algorithm Steps:**
1. **Seed Selection:** Identify the `center_track_id` (the last successfully played track).
2. **Candidate Generation:**
   - **Primary (80%):** Fetch tracks similar to the `center_track_id` (Metadata + Audio Feature match).
   - **Discovery (20%):** Fetch tracks from the **Probation Pool** (newly acquired recommendations).
3. **Sequence Construction:**
   - Group results into a "Chunk" (e.g., 20 tracks).
   - Apply **Batch Rules**:
     - Max 1 song per artist in a single chunk.
     - Max 2 songs per genre in a single chunk.
     - Mix in "probation" tracks at a controlled rate.
4. **Response:** Return a JSON array of track objects with pre-calculated sequence order.

## 3. Business Logic Invariants

- **The "No Ghost" Rule:** The backend MUST verify file existence before returning a track in a `Vibe` sequence.
- **The "Success-Driven Center" Rule:** The `center_track_id` is updated ONLY when a track's `completed` flag is set to `true` via `/api/history`.
- **The "Atomicity" Rule:** All state transitions (e.g., `PENDING_REMOVAL` $\rightarrow$ `DELETED`) must be handled within a database transaction.
