crabidy/plan/jamendo.md

74 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Task plan — jamendo provider
Ordered, independently verifiable tasks for `/jamendo`
(architecture/jamendo-provider.md, quality/jamendo.md). Each cites the gate/test
it satisfies.
## Crate scaffold
- [x] **P1** — Add `jamendody` to `Cargo.toml` workspace `members`; create
`jamendody/Cargo.toml` mirroring `soundclouddy` (deps: `async-trait`,
`crabidy-core`, `reqwest`, `serde`, `thiserror`, `tokio`, `toml`, `tracing`;
dev-dep `tokio` full). *Verify:* `cargo metadata` lists the crate.
## Network seam (api.rs)
- [x] **P2** — Domain types `JamTrack` (id, title, artist, album,
duration_secs) and `JamAlbum` (id, title, artist, tracks); `FetchError`
(`Http`, `Decode`, `NotFound`, `Unauthorized`, `NotStreamable`). *Verify:*
compiles. (G2)
- [x] **P3**`Jam` trait: `search_tracks`, `search_albums`, `album_tracks`,
`track_detail`, `track_stream`. Doc each with error behavior. *Verify:*
compiles. (G2/G10)
- [x] **P4**`JamApi` (reqwest): `new(client_id, audioformat, timeout)` with a
timeout-bearing client and redacting `Debug`; `get_json` helper adding
`client_id` + `format=json`, decoding the `{headers, results}` envelope,
mapping non-success/404/401 to `FetchError`. `limit.min(200)` cap. *Verify:*
`cargo build`. (G3/G4/G5/G9)
- [x] **P5** — Defensive DTOs (`#[serde(default)]`) for track/album/envelope and
`into_track`/`into_album`. *Verify:* build + a decode unit test on a JSON
fixture. (G9)
## Provider logic (lib.rs)
- [x] **P6**`PROVIDER_ROOT`, segment consts, `JamPath` enum + `parse_path`.
*Verify:* T2, `foreign_and_malformed_paths_reject`. (D3)
- [x] **P7**`Settings` (`client_id: Option<String>` + bounds) with redacting
`Debug`. *Verify:* T10 `settings_debug_redacts_client_id`. (G3)
- [x] **P8**`Client` + `with_api`, search-term store helpers
(`store_add/remove/snapshot`), `search_limit`/`album_limit`. *Verify:*
compiles. (D3)
- [x] **P9** — Node builders: `root_node` (search only), `store_node`,
`search_term_node` (tracks + albums), `album_node`, `list_node`, `jam_track`.
*Verify:* T1, T4, T5, T7, T11. (D3/D4)
- [x] **P10**`ProviderClient` impl: `init` (require non-empty `client_id`,
else `Config`), `settings`, `is_track_path`, `get_urls_for_track` (→
`track_stream`), `get_metadata_for_track`, `get_lib_root`, `get_lib_node`
(download blessing), `create/rename/delete_lib_node`. *Verify:* T3, T6, T8,
T9. (D4/G1/G2/G6)
## Tests (tests.rs)
- [x] **P11**`FakeJam` + `FailingJam` fixtures and all T1T11. *Verify:*
`cargo test -p jamendody`. (all tests)
## Orchestrator + settings wiring (crabidy-server)
- [x] **P12**`settings.rs`: `jamendo` in `ALL_PROVIDERS` (8→9),
`ProviderToggles.jamendo`, defaults, `provider_toggles()`. *Verify:* build +
existing settings tests. (G6)
- [x] **P13**`provider.rs`: `jamendo_client` field, `jamendo_owns`,
`jamendo_provider`, non-fatal `build()` block (reads `jamendo.toml`),
`is_track_path` arm, `get_lib_root` child (gated on `is_some`), `get_lib_node`
arm, `get_urls_for_track`/`get_metadata_for_track` arms, create/rename/delete
arms. *Verify:* `cargo build -p crabidy-server`. (D1/G6/G8)
## Verification gate
- [x] **P14**`cargo fmt --check`, `cargo clippy -- -D warnings`,
`cargo test` green across the workspace. Re-read G1G10 against the diff.
- [ ] **P15 (live gate, R1)** — with a real `client_id` in `jamendo.toml`, browse
`/jamendo/search/<term>`, queue and **play** a track: confirm audio plays via
the existing windowed-HTTP path, seek bar correct (duration from metadata),
clean EOS, no panic. Deferred to a run with network + a key.