85 lines
4.0 KiB
Markdown
85 lines
4.0 KiB
Markdown
# Quality gates: captures
|
|
|
|
Criteria the implementation must satisfy beyond the automatic tests
|
|
(`crabidy-server/src/capture.rs`, `crabidy-server/src/capture_store.rs`,
|
|
`fsdy/src/lib.rs`, plus the TUI tests added during implementation). Each
|
|
gate is pass/fail by reading the code.
|
|
|
|
## Shared walk (refactor)
|
|
|
|
- [x] Bookmarks and download captures run through **one** walk
|
|
(`capture::capture_into`/`write_tree`); `bookmark_store` keeps no copy
|
|
of the worklist, caps, tmp-and-swap, or cleanup logic.
|
|
- [x] The refactor is behavior-preserving for bookmarks: every existing
|
|
`bookmark_store` test passes unchanged (module path of `CaptureError`
|
|
aside).
|
|
- [x] The walk stays iterative (worklist), all-or-nothing, and removes the
|
|
temp folder on every failure path — including failed downloads and the
|
|
byte budget.
|
|
|
|
## Download sink
|
|
|
|
- [x] Every external call is bounded: connect timeout on the shared HTTP
|
|
client and one per-track deadline covering URL fetch, request, and the
|
|
whole body stream. No retries.
|
|
- [x] Bodies are **streamed** to disk (never buffered whole) and counted
|
|
against the capture's byte budget while streaming; exceeding it is
|
|
`TooLarge`, not partial data left behind.
|
|
- [x] Non-2xx responses and transport errors are typed
|
|
(`CaptureError::Download`) — no panic on any network condition.
|
|
- [x] Download log lines carry paths, names, and counts — never stream
|
|
URLs (they embed tokens) and never file contents.
|
|
- [x] The toml is written only after its audio file succeeded, with a
|
|
relative `file` playable naming the sibling
|
|
(`TrackFile::from_track_with_file`); the audio name shares the toml's
|
|
order prefix and sanitizer (`capture::audio_file_name`).
|
|
- [x] Downloads run sequentially inside the one spawned capture task; the
|
|
orchestrator loop keeps serving commands during a capture.
|
|
|
|
## Opt-in (is_downloadable)
|
|
|
|
- [x] Tidal sets the flag centrally: nodes are downloadable when queueable
|
|
or when they list tracks; children mirror `is_queable`. No per-arm
|
|
copies to drift.
|
|
- [x] Every other provider (fs, queues, bookmarks, captures, orchestrator
|
|
root) leaves the flag `false` — a capture can never be built from
|
|
another capture's or bookmark's links masquerading as sources.
|
|
- [x] The server enforces the blessing at the capture root (directory
|
|
source: its own node; track source: its parent node) with
|
|
`CaptureError::Unsupported`; an unreadable root is `BadSource`.
|
|
|
|
## RPC and orchestrator
|
|
|
|
- [x] `CaptureLibraryNodeRequest.download` is additive: old clients (no
|
|
flag) keep getting bookmarks, byte-for-byte.
|
|
- [x] Error mapping: `InvalidName`/`BadSource` → `invalid_argument`;
|
|
`TooLarge`/`Disabled`/`Unsupported` → `failed_precondition`;
|
|
download/walk/write failures → `internal`.
|
|
- [x] The orchestrator routes `/captures` in every `ProviderClient` method
|
|
(same completeness as `/bookmarks`), and `get_lib_root` lists the
|
|
`captures` child only when the instance exists.
|
|
- [x] Captures init is non-fatal: no config dir or an unopenable store
|
|
disables download captures and the `/captures` mount, never the server
|
|
(and never bookmarks).
|
|
- [x] `/captures` mounts with an editable top level (no reserved names):
|
|
captures are renamable (`e`) and deletable (`d`) like bookmarks.
|
|
|
|
## TUI
|
|
|
|
- [x] `W` (shift) is bound in `Scope::Library` with a help description and
|
|
passes the bindings-table invariant tests unchanged; `w` behavior is
|
|
untouched.
|
|
- [x] The capture overlay opens for `W` only when the bare selection is
|
|
queueable **and** downloadable; tracks inherit their node's flag;
|
|
marks are ignored. Label: `capture` (vs `bookmark`).
|
|
- [x] `MessageFromUi::CaptureNode` carries `download`; a failed capture is
|
|
logged and never tears down the poll loop.
|
|
|
|
## Hygiene
|
|
|
|
- [x] New public items are documented; docs state error/edge behavior.
|
|
- [x] `clippy -D warnings`, `fmt`, `taplo`, `markdownlint` clean on the
|
|
whole workspace; all tests green.
|
|
- [x] `architecture/captures.md` reconciled where the implementation
|
|
diverged (e.g. the exact tidal flag rule).
|