Add the shared domain event bus #18

Closed
opened 2026-07-18 20:48:29 +00:00 by hugo · 1 comment
Owner

Goal

Add the single domain-event path used to keep desktop, CLI, MCP, TUI, server, and future remote clients synchronized after mutations.

Current state

  • specs/events.allium defines entity and settings events.
  • db_notifications exists for CLI-to-desktop synchronization, but there is no in-process event bus.
  • Desktop state is refreshed through feature-specific message paths.
  • CLI, MCP, server, and TUI are not implemented.

Required behavior

  • Define the minimal typed events from specs/events.allium for entity create/update/delete and settings changes, including project scope and identifiers needed by clients.
  • Publish events from the shared mutation boundary so desktop and future clients observe the same result regardless of caller.
  • Provide subscribe/unsubscribe behavior and deterministic delivery to active clients.
  • Refresh affected desktop state from events without feeding the same mutation back into the engine or duplicating notifications.
  • Preserve the server-selected UI language for server-rendered clients.
  • Integrate db_notifications as the process boundary for CLI writes: CLI-originated events are persisted, consumed once by the desktop watcher, marked seen, and pruned under cli_sync.allium rules.

Implementation notes

  • Keep one event enum and one bus implementation. Do not build a broker or event-sourcing layer.
  • Put emission in shared engine/service mutation paths, not separately in every UI.
  • Avoid holding database transactions or UI locks while notifying subscribers.
  • Follow red/green TDD and use specs/events.allium plus specs/cli_sync.allium as normative behavior.

Acceptance criteria

  • Representative post, media, tag, template, script, project, and settings mutations emit exactly one appropriate event.
  • Multiple subscribers receive events in order; unsubscribe stops delivery.
  • A desktop-originated write does not re-enter through db_notifications.
  • CLI notification consumption, seen marking, and processed/unprocessed pruning are tested.
  • Existing desktop refresh behavior continues to work through the shared path.
  • cargo fmt --all -- --check, cargo build --workspace, and cargo test --workspace pass.
## Goal Add the single domain-event path used to keep desktop, CLI, MCP, TUI, server, and future remote clients synchronized after mutations. ## Current state - specs/events.allium defines entity and settings events. - db_notifications exists for CLI-to-desktop synchronization, but there is no in-process event bus. - Desktop state is refreshed through feature-specific message paths. - CLI, MCP, server, and TUI are not implemented. ## Required behavior - Define the minimal typed events from specs/events.allium for entity create/update/delete and settings changes, including project scope and identifiers needed by clients. - Publish events from the shared mutation boundary so desktop and future clients observe the same result regardless of caller. - Provide subscribe/unsubscribe behavior and deterministic delivery to active clients. - Refresh affected desktop state from events without feeding the same mutation back into the engine or duplicating notifications. - Preserve the server-selected UI language for server-rendered clients. - Integrate db_notifications as the process boundary for CLI writes: CLI-originated events are persisted, consumed once by the desktop watcher, marked seen, and pruned under cli_sync.allium rules. ## Implementation notes - Keep one event enum and one bus implementation. Do not build a broker or event-sourcing layer. - Put emission in shared engine/service mutation paths, not separately in every UI. - Avoid holding database transactions or UI locks while notifying subscribers. - Follow red/green TDD and use specs/events.allium plus specs/cli_sync.allium as normative behavior. ## Acceptance criteria - Representative post, media, tag, template, script, project, and settings mutations emit exactly one appropriate event. - Multiple subscribers receive events in order; unsubscribe stops delivery. - A desktop-originated write does not re-enter through db_notifications. - CLI notification consumption, seen marking, and processed/unprocessed pruning are tested. - Existing desktop refresh behavior continues to work through the shared path. - cargo fmt --all -- --check, cargo build --workspace, and cargo test --workspace pass.
hugo added the enhancement label 2026-07-18 20:48:29 +00:00
Author
Owner

Implemented in a2abb90 and pushed to origin/main.

Implementation:

  • Added one typed, project-scoped DomainEvent enum and deterministic in-process EventBus with ordered multi-subscriber delivery and explicit unsubscribe/drop behavior.
  • Emitted create/update/publish/delete events from shared post, media, tag, template, script, project, search-setting, AI-setting, and UI-setting mutation boundaries after successful work and outside database savepoints.
  • Added the Diesel-generated project_id migration and notification queries, plus CLI event capture/persistence, atomic consume-once/seen marking, deterministic ordering, legacy-row scope recovery, and 1-hour processed/24-hour unprocessed pruning.
  • Added a 100 ms desktop watcher that consumes CLI rows and uses the same event path to refresh project-scoped lists/editors, close deleted tabs, preserve dirty buffers, and avoid write-back or duplicate toasts/notification rows.
  • Persisted ui.language as the server-selected global setting; startup uses it before menu creation and events relocalize active clients without rewriting the setting.
  • Updated events.allium, cli_sync.allium, README, RUST_PLAN_CORE.md, and RUST_PLAN_EXTENSION.md.

Neutral review:

  • Compared every broadcast family and desktop handler with bDS2, and checked behavior against events.allium and cli_sync.allium.
  • The review found and fixed deterministic unsubscribe cutover and compatibility for pre-migration notification rows lacking project scope.
  • No remaining issue, bDS2, or Allium gaps found.

Verification:

  • allium check/analyse for both specs: no findings (informational unused-field notices only)
  • cargo fmt --all -- --check
  • cargo build --workspace
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace: all enabled tests passed; 2 existing keychain tests remained explicitly ignored
  • Dedicated coverage includes exact event cardinality across all required mutation families, publish/delete mapping, subscriber order/unsubscribe, desktop no-op notifier, CLI capture/consume/seen/prune, legacy migration compatibility, desktop refresh/delete behavior, dirty-buffer preservation, and shared locale behavior.
Implemented in a2abb90 and pushed to origin/main. Implementation: - Added one typed, project-scoped DomainEvent enum and deterministic in-process EventBus with ordered multi-subscriber delivery and explicit unsubscribe/drop behavior. - Emitted create/update/publish/delete events from shared post, media, tag, template, script, project, search-setting, AI-setting, and UI-setting mutation boundaries after successful work and outside database savepoints. - Added the Diesel-generated project_id migration and notification queries, plus CLI event capture/persistence, atomic consume-once/seen marking, deterministic ordering, legacy-row scope recovery, and 1-hour processed/24-hour unprocessed pruning. - Added a 100 ms desktop watcher that consumes CLI rows and uses the same event path to refresh project-scoped lists/editors, close deleted tabs, preserve dirty buffers, and avoid write-back or duplicate toasts/notification rows. - Persisted ui.language as the server-selected global setting; startup uses it before menu creation and events relocalize active clients without rewriting the setting. - Updated events.allium, cli_sync.allium, README, RUST_PLAN_CORE.md, and RUST_PLAN_EXTENSION.md. Neutral review: - Compared every broadcast family and desktop handler with bDS2, and checked behavior against events.allium and cli_sync.allium. - The review found and fixed deterministic unsubscribe cutover and compatibility for pre-migration notification rows lacking project scope. - No remaining issue, bDS2, or Allium gaps found. Verification: - allium check/analyse for both specs: no findings (informational unused-field notices only) - cargo fmt --all -- --check - cargo build --workspace - cargo clippy --workspace --all-targets -- -D warnings - cargo test --workspace: all enabled tests passed; 2 existing keychain tests remained explicitly ignored - Dedicated coverage includes exact event cardinality across all required mutation families, publish/delete mapping, subscriber order/unsubscribe, desktop no-op notifier, CLI capture/consume/seen/prune, legacy migration compatibility, desktop refresh/delete behavior, dirty-buffer preservation, and shared locale behavior.
hugo closed this issue 2026-07-19 11:49:19 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: hugo/RuDS#18