pub(super) fn handle_delete_workspace(
state: &mut State,
workspace_id: String,
_force: bool,
) -> Vec<Event>Expand description
Phase E.2 — delete a workspace from canonical state. Idempotent:
deleting a missing workspace is a silent no-op. Cascades to the
workspace’s tabs (E.2b) and through to each tab’s blocks (E.3):
every tab whose workspace_id matches is removed from
state.tabs, and each block in those tabs is removed from
state.blocks, before the workspace itself goes away. Cascade
events are NOT emitted individually — subscribers observing
WorkspaceDeleted are expected to drop dependent state (mirrors
how wcore::delete_workspace cascades in SQLite).
The force parameter (Step 5 PR 2) is provenance-only: it carries
through to the durable saga log when the saga drives this dispatch
(force = true), and is ignored by the reducer’s cascade logic.
The reducer is a pure mutator — it must always cascade to keep
in-memory state consistent regardless of whether a saga or a
legacy/internal path is calling.