crabidy/plan/queue-order.md

7.0 KiB
Raw Permalink Blame History

Plan: queue de-duplication and sorting

Executes architecture/queue-order.md against the gates in quality/queue-order.md. The wire and the stubs already exist (api-design); what follows fills them in, in dependency order. Every task names how it is verified.

1. The wire

  • T1 — Proto: DedupQueue, SortQueue, QueueSort. Two RPCs, the strategy enum, DedupQueueResponse.removed, with the semantics documented at the wire. Verified by: it compiles through tonic-prost-build; G21 by reading.
  • T2 — Rights matrix. Both methods as QueueOwner, added to the pinned method list. Verified by: auth.rs::the_method_table_pins_every_rpc_of_the_service (G11).

2. Pure order logic (crabidy-server/src/queue_order.rs)

  • T3 — track_id. Provider-scoped item id, else the whole path. Verified by: a_provider_item_id_identifies_a_track_across_paths, ids_are_scoped_to_their_provider, a_captured_copy_is_not_its_streaming_source, without_an_id_the_path_is_the_identity (G2).
  • T4 — duplicate_positions. Survivor = current, else earliest; ascending, unique, never the current position; safe on an empty queue and an out-of-range current. Verified by: duplicates_after_the_first_are_removed, the_playing_entry_survives_its_group, nothing_to_do_is_an_empty_list, positions_come_back_ascending_and_are_unique (G1).
  • T5 — sort_permutation. Decoratesortundecorate with keys built once; compound artist key; case-insensitive text; unknown-last in both directions; Reverse ignores the direction; Unspecified is the identity. Verified by: every_strategy_returns_a_permutation, sorting_by_artist_groups_albums_and_keeps_track_order, text_sorts_ignore_case, descending_reverses_the_key_but_not_the_blanks, unknown_durations_sort_last_in_both_directions, reverse_flips_the_current_order_and_ignores_the_direction, an_unspecified_strategy_changes_nothing, sorting_nothing_does_not_panic (G3, G4, G5).

3. Queue state (crabidy-server/src/lib.rs)

  • T6 — QueueManager::dedup. Delegates the removal to remove_tracks; returns the count. Verified by: dedup_removes_later_copies_and_reports_the_count, dedup_keeps_the_playing_track_playing, dedup_of_a_clean_queue_changes_nothing, dedup_leaves_the_queue_playable (G1, G6, G7).
  • T7 — QueueManager::sort. Permute tracks; shuffle off ⇒ identity play order with current_offset on the current track, shuffle on ⇒ remap. Verified by: sorting_reorders_the_queue_and_follows_the_current_track, sorting_without_shuffle_changes_what_plays_next, sorting_with_shuffle_on_preserves_the_shuffled_play_sequence, sorting_with_shuffle_on_still_reorders_the_visible_queue, sorting_an_empty_or_single_queue_does_not_panic, an_unspecified_sort_leaves_the_queue_alone (G6, G5).

4. Server plumbing

  • T8 — Playback loop arms. Lock, mutate, broadcast; dedup replies with its count and skips the broadcast when it removed nothing. Verified by: dedup_command_removes_duplicates_and_replies_with_the_count, dedup_command_answers_zero_without_broadcasting, dedup_command_survives_a_dropped_result_channel, sort_command_reorders_the_queue_and_broadcasts_it, queue_order_commands_reach_the_persist_channel (G8, G9, G10, G12).
  • T9 — RPC handlers. Unspecified/unknown → InvalidArgument before the loop sees it; the count passes through verbatim. Verified by: sort_queue_refuses_an_unnamed_strategy, sort_queue_forwards_the_strategy_and_direction, dedup_queue_returns_the_loops_count (G10, G12).

5. TUI

  • T10 — Client RPC methods (dedup_queue, sort_queue) and the MessageFromUi/MessageToUi variants. Verified by: compiles; exercised through the dispatch tests.
  • T11 — Bindings. u dedup, S sort menu, queue scope only. Verified by: queue_order_keys_are_bound_in_the_queue_only, chords_are_unique_within_scope (G17).
  • T12 — sort::choose + the menu table. Lowercase ascending, uppercase descending, reverse case-insensitive, unclaimed keys unclaimed. Verified by: a_lowercase_key_sorts_ascending_and_its_capital_descending, reverse_ignores_the_case, keys_the_menu_does_not_offer_are_not_claimed, the_table_is_consistent (G15).
  • T13 — sort::render + popup_area. Centered, Clear-backed, clamped to the frame. Verified by: the_overlay_lists_every_strategy_with_its_key, a_tiny_frame_clamps_the_popup.
  • T14 — App::handle_sort_key. Modal: sort-and-close, Esc/q/S close, anything else ignored. Verified by: a_sort_menu_key_sends_the_strategy_and_closes_the_menu, escape_closes_the_sort_menu_without_sorting, an_unknown_key_leaves_the_sort_menu_open (G15).
  • T15 — Dispatch + event-loop routing + render hook. Empty-queue guards on both actions; the menu is checked before the bindings table. Verified by: dedup_asks_the_server_only_with_a_non_empty_queue, the_sort_menu_opens_only_with_a_non_empty_queue.
  • T16 — The pane's dedup notice. show_dedup_result + notice() expiry + title precedence (visual > filter > notice > register). Verified by: the_dedup_result_appears_in_the_title, the_dedup_result_expires, an_active_search_outranks_the_dedup_result (G18).

6. CLI

  • T17 — queue dedup / queue sort <key> [--desc]. ValueEnum strategy. Verified by: queue_dedup_takes_no_arguments, queue_sort_parses_a_strategy_and_an_optional_direction (G19).
  • T18 — wire_sort / sort_label and the printed results. Dedup prints its count including 0. Verified by: the parse tests plus reading (G18, G19).

7. Web client

  • T19 — RPC methods, Dialog::Sort, actions, keymap entries, toolbar buttons, key routing. Verified by: queue_order_keys_match_the_tui, the_sort_table_is_consistent (G16, G17).
  • T20 — sort_menu_key. The web port of sort::choose, plus the close keys. Verified by: the_sort_menu_maps_keys_to_strategies_and_closes_on_escape (G15, G17).
  • T21 — SortMenu component + notify. Rows clickable and typeable, dedup count in a toast. Verified by: the wasm build (build-web) plus reading (G16, G18).
  • T22 — Web help overlay entries for u and S. Verified by: every_action_reachable_from_help_table plus reading (G20).

8. Documentation

  • T23 — docs/src/queue.md: the two order operations in the queue model, the duplicate rule, the strategies, and the shuffle interaction.
  • T24 — docs/src/clients/tui.md key table and docs/src/clients/cli.md command list. Verified by: reading; the book builds (G20).

9. Close-out

  • T25 — Full check. cargo test (workspace), cargo clippy --all-targets -D warnings, cargo fmt --check, cargo test -p cbd-tui --no-default-features, and the web build. Then plan/summary.md.