refactor(peer): split local library and operation UI events
Replace the `a9f9845` local-update dedup cache with explicit peer event semantics. Local scans now emit `LocalLibraryChanged` when the library changes, while operation mutations emit `ActiveOperationsChanged` from the mutation path. Tauri keeps joining those facts into the existing `games-list-updated` payload, so the frontend contract stays stable. This removes the cache/invalidation coupling between scan emission and operation state. The remaining forced local snapshot is explicit: accepted game directory changes can refresh the UI for an equivalent new path without sending a peer library delta. Operation guard cleanup and liveness cancellation now publish the same active operation snapshot as normal command-handler transitions. The peer CLI JSONL events follow the same split with `local-library-changed` and `active-operations-changed`. Test Plan: - `just fmt` - `CARGO_BUILD_RUSTC_WRAPPER= just test` - `CARGO_BUILD_RUSTC_WRAPPER= just clippy` - `git diff --check` Refs: CLEAN_CODE_PLAN_1.md
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# Clean Code Plan 1: Split Local Library and Operation UI Signals
|
||||
|
||||
## Goal
|
||||
|
||||
Replace the `a9f9845` local-update dedup cache with explicit event semantics.
|
||||
The peer runtime should report local library changes and active operation
|
||||
changes as separate facts, while the Tauri layer keeps joining those facts into
|
||||
the existing `games-list-updated` payload for the frontend.
|
||||
|
||||
## Architectural Picture
|
||||
|
||||
The current overloaded shape makes `LocalGamesUpdated` carry two independent
|
||||
signals:
|
||||
|
||||
- local library contents, whose source of truth is `LocalLibraryState` and
|
||||
`LocalLibraryState::update_from_scan`;
|
||||
- active operation status, whose source of truth is `Ctx::active_operations`.
|
||||
|
||||
The clean boundary is:
|
||||
|
||||
- peer scanning emits a local-library event when the scanned library state
|
||||
changes, with an explicit force policy for accepted path changes where the UI
|
||||
needs a fresh snapshot but peers do not need a delta;
|
||||
- operation-state mutation emits an operation snapshot when the mutation
|
||||
happens;
|
||||
- Tauri owns UI joining: it stores the latest catalog/local games and latest
|
||||
operation snapshot, then emits `games-list-updated` for the frontend.
|
||||
|
||||
That keeps the frontend contract stable while removing the cross-cutting cache
|
||||
and every manual invalidation call.
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
1. Remove commit `a9f9845` from the local branch history before implementing
|
||||
the replacement, so the final code is not built on the band-aid.
|
||||
2. Replace `PeerEvent::LocalGamesUpdated { games, active_operations }` with:
|
||||
- `PeerEvent::LocalLibraryChanged { games }`;
|
||||
- `PeerEvent::ActiveOperationsChanged { active_operations }`.
|
||||
3. Add one operation-snapshot publisher near the peer event helpers. All normal
|
||||
operation mutations must go through helpers that mutate
|
||||
`Ctx::active_operations` and then emit `ActiveOperationsChanged`.
|
||||
4. Make `OperationGuard` publish an operation snapshot when it performs
|
||||
exceptional cleanup on drop, so cancellation or aborted tasks do not leave UI
|
||||
state stale.
|
||||
5. Keep the existing scan behavior that freezes active game summaries while an
|
||||
operation is running, but emit `LocalLibraryChanged` only when
|
||||
`update_from_scan` returns a real delta or the scan was explicitly forced by
|
||||
an accepted path change.
|
||||
6. Update the Tauri event loop to reconcile `ActiveOperationsChanged`
|
||||
independently, and call `emit_games_list` after both library and operation
|
||||
state changes.
|
||||
7. Update focused tests in peer handlers, local monitor, liveness, context guard,
|
||||
and Tauri reconciliation to prove:
|
||||
- unchanged settled scans do not emit local-library events;
|
||||
- operation starts/transitions/ends emit authoritative snapshots;
|
||||
- exceptional guard cleanup clears the operation snapshot;
|
||||
- Tauri still emits the same `games-list-updated` UI payload.
|
||||
8. Update `CLEAN_CODE.md`, `crates/lanspread-peer/ARCHITECTURE.md`, and
|
||||
`crates/lanspread-peer/README.md` so the docs describe the new shape rather
|
||||
than the dedup warning.
|
||||
|
||||
## Review Gates
|
||||
|
||||
- No `last_local_update_key`, `LocalUpdateKey`, or invalidate helper remains.
|
||||
- No operation-state mutation that should be visible to the UI bypasses the
|
||||
snapshot publisher.
|
||||
- The peer event names reflect domain facts, not UI implementation details.
|
||||
- Tauri remains the compatibility boundary for the frontend payload.
|
||||
- Verification runs through `just fmt`, `just test`, `just clippy`, and
|
||||
`git diff --check`.
|
||||
Reference in New Issue
Block a user