UI Play → engine → event → UI
Implementation brief for aidj-platform and aidj-ui. This completed historical slice introduced the metadata playground; see current status for implemented scope and remaining acceptance work. Build four virtual decks controlled by a local human actor. This phase has no audio and no hardware connection.
Deliverables
dj-domain: IDs, a four-deck-capable state model,Play/Pause, command results, and playback events.booth-engine: single ordered reducer, command validation, identity, and ownership generation.virtual-booth: injected clock, synthetic tracks, explicit play/pause and end-of-track behavior.booth-apiandboothd: local HTTP snapshot and JSON WebSocket connection with receipts and events.aidj-ui(Next.js): connection status, deck state, Play/Pause controls, pending/rejected feedback, and a visible “metadata-only · no audio” label.
Acceptance criteria
- Play produces exactly one applied transition and updates all connected clients from server state.
- Pause freezes position; resuming advances from the same frame.
- Duplicate command IDs do not repeat an action.
- An unauthorized actor or stale ownership generation is rejected without state mutation.
- UI reload leaves daemon state and transport running; reconnect obtains a consistent snapshot/cursor.
- A disconnected client cannot submit stale queued controls when it reconnects.
- A scripted fixed-step run produces the same ordered events and final state on repetition.
Verify reducer and clock behavior in Rust tests, API ordering/reconnect in integration tests, and the actual browser command loop with two clients. Generate the fixture locally; no music downloads are required.
Then add tempo, beatgrid-derived position, channel controls, journaling, and audio in milestone order. Do not present EQ/fader state as audible DSP until the renderer consumes it.