4.8 KiB
4.8 KiB
Quality gates — editable and deletable nodes
Checklist for the implement stage. Automatic tests live in
crabidy-core/src/lib.rs, tidaldy/src/lib.rs, and
cbd-tui/src/app/{bindings,mod}.rs test modules; run with
devenv shell -- cargo test --workspace (network-dependent tidaldy tests
stay #[ignore]). 10 tests fail at gate-writing time — they define the
target.
Contract & wire
- Proto changes are additive only: existing field numbers untouched;
LibraryNodeChild.is_editable = 5,is_deletable = 6;RenameLibraryNodeandDeleteLibraryNoderpcs present. Old clients keep working against the new server. rpc.rs(server) maps errors per the documented contract for both new rpcs:NotSupported→failed_precondition,InvalidInput→invalid_argument, everything else →internal. Nocolor-eyrereport or debug formatting of internals leaks intoStatusmessages.ProviderOrchestrator::{rename,delete}_lib_noderoute/tidal-prefixed paths to the Tidal client and answer anything else (including the synthetic root/) withNotSupported— same prefix discipline ascreate_lib_node.- Both new commands follow the existing bounded(1)-reply rendezvous pattern; no new unbounded channels anywhere in the feature.
Provider semantics (tidaldy)
rename_lib_nodetrims the new title; empty/whitespace →InvalidInput; any path that is not aSearchTerm(including/tidal/searchitself) →NotSupported; validation happens before any network call.- Rename replaces the term in place (keeps its list position);
renaming onto an existing term merges (the old slot is removed, no
duplicates ever); renaming an unknown term registers the new one
(stale-client forgiveness). Returns
get_lib_node(new_path)— the node at its new percent-encoded path. delete_lib_nodeaccepts onlySearchTermpaths (NotSupportedotherwise), removes the term idempotently (unknown term → success), and returns the refreshed/tidal/searchparent node.rename_search_term/remove_search_termfollow the established lock discipline: poison-tolerant, thesearch_termslock is never held across anawait.- Term children returned by the
Searcharm setis_editable: true, is_deletable: true; nothing else in the provider sets either flag. - Queued search tracks keep playing after a rename/delete of their term:
get_urls_for_track/get_metadata_for_trackresolve from the track id embedded in the path, independent of term registration.
No panics on user input (hard rule)
- All
todo!()stubs from api-design are gone (grep the workspace). - Rename/delete failures (network, auth, malformed paths from stale
clients) surface as
ProviderError/Status, never a panic; the TUI's rename and delete paths handle an error reply without crashing the orchestrate task (log + stay put).
TUI behavior
eopens the overlay only when the selected itemis_editable, prefilled with the current title;dsendsDeleteNodeonly when the selected itemis_deletable; both are silent no-ops otherwise (including when nothing is selected or the list is empty).- The overlay carries its purpose: submit sends
CreateNodeforInputPurpose::CreateandRenameNodeforInputPurpose::Rename; the rendered label distinguishes them (new node:vsrename:). While the overlay is open the bindings table stays unreachable (existing input-mode bypass, unchanged). - Delete is deliberately unconfirmed (architecture/node-editing.md D4); the open question about confirmation for higher-value nodes is preserved in the architecture doc, not silently dropped.
- Modifiable children are visibly marked in the library list (
[e],[d]or[ed]suffix,COLOR_SECONDARY), coexisting with the[%]marker for creatable ones. RpcClient::rename_library_nodeevicts the old path and the parent entry, then caches the node under its new path;delete_library_nodeevicts the deleted path and the parent, then caches the returned parent. No stale/tidal/searchlisting can resurrect an old term.- On successful rename the library navigates into the renamed node; on successful delete it shows the refreshed parent; on failure the library stays where it was.
Code quality
- Public items added in all five crates have doc comments matching final
behavior; the
e/dbindings appear in the help modal automatically. - No new dependencies.
devenv shell -- cargo fmt --check,cargo clippy --workspace(no new warnings),cargo test --workspaceall pass.