feat(kc): server integration — SSE subscriptions, live fetch, and write-back for viewers #43

Closed
opened 2026-02-18 21:17:43 +00:00 by forbes · 0 comments
Owner

Summary

Wire live data fetching, SSE event subscriptions, and server write-back into the viewer widgets. This connects the offline-capable viewers to the running Silo server for real-time updates and bidirectional sync.

Background

Phases 1–5 build viewers that operate on local silo/ data. This phase adds the network layer: viewers that can fetch fresh data from the server, subscribe to SSE events for live updates, and push edits back on commit.

The SSE broker infrastructure already exists in silo_commands.py (SiloEventListener), and the Activity panel already subscribes to events. Viewer widgets subscribe to the same broker.

Server API availability (as of Feb 2026)

Based on silo-server documentation review:

Feature Server Status Endpoint
Revisions fetch Implemented GET /api/items/{pn}/revisions
Metadata read/write Implemented GET/PUT /api/items/{pn}/metadata
Lifecycle transitions Implemented PATCH /api/items/{pn}/metadata/lifecycle
Tag management Implemented PATCH /api/items/{pn}/metadata/tags
Schema form descriptor Implemented GET /api/schemas/{name}/form
Dependency resolution Implemented GET /api/items/{pn}/dependencies/resolve
Macro source fetch Implemented GET /api/items/{pn}/macros/{filename}
SSE event stream Implemented GET /api/events
File download Implemented GET /api/items/{pn}/file/{rev}
Approval API Not implemented DB tables exist (migration 018), no REST handlers. Tier 4 on roadmap.
Job queue runtime Not implemented DB tables exist (migration 015), no REST endpoints or queue backend.

In scope (this issue)

History Viewer

  • Refresh button: Fetches via _client.get_revisions(pn) and replaces local snapshot
  • SSE subscription: revision_created signal triggers auto-refresh
  • Merge strategy: Server revisions are authoritative — replace local snapshot on refresh

Metadata Editor

  • Schema-driven fields: Fetch GET /api/schemas/{name}/form for dynamic field rendering (replaces flat key-value fallback)
  • Write-back on commit: Queue changes via PUT /api/items/{pn}/metadata
  • Lifecycle transitions: Enable QComboBox when connected; calls PATCH /api/items/{pn}/metadata/lifecycle
  • Tag sync: Calls PATCH /api/items/{pn}/metadata/tags on save when connected
  • Edit conflict handling: If Metadata Editor has unsaved changes and a Silo Pull updates metadata.json, show a field-by-field diff dialog

Dependency Table

  • Server resolution: Calls GET /api/items/{pn}/dependencies/resolve for availability status
  • Download: Calls SiloSync.download_file(pn) for unresolved items
  • Refresh: Re-checks resolution status after downloads complete

All viewers

  • Connection check: On widget creation, check _server_mode. If offline, display "Offline — showing cached data" banner and disable server-dependent controls.
  • Reconnect handling: When connection status changes, refresh active viewers.

Out of scope (deferred)

Approvals Viewer server integration

  • No server API exists. The SiloApprovalsViewer will continue to display local silo/approvals.json snapshot only.
  • Deferred until Tier 4 Approval/ECO workflow is implemented on the server.

Job Viewer server integration

  • No job queue runtime or REST endpoints exist despite DB tables being present.
  • The SiloJobViewer will continue as a local YAML editor only. Run button and status panel deferred.
  • Deferred until Tier 3 Compute infrastructure is implemented on the server.

Files to modify

File Change
src/Mod/Create/silo_viewers.py Add server fetch, SSE subscription, offline banner, and write-back logic to History, Metadata, and Dependency viewers
src/Mod/Create/silo_document.py Connect viewer refresh to SSE broker events

Technical notes

Cross-module import pattern

Viewers live in src/Mod/Create/ but _client, _server_mode, and SiloEventListener live in mods/silo/freecad/silo_commands.py. Imports must be guarded:

try:
    import silo_commands
    _client = silo_commands._client
    _server_mode = silo_commands._server_mode
except ImportError:
    _client = None

SSE event subscription pattern

Each widget that needs SSE creates its own SiloEventListener() instance (matching existing pattern in SiloAuthDockWidget and SiloStartView).

Acceptance criteria

  • History Viewer refresh button fetches live revisions from server
  • History Viewer auto-refreshes on revision_created SSE event
  • Metadata Editor lifecycle transitions call server API when connected
  • Metadata Editor tag sync calls server API when connected
  • Metadata Editor write-back pushes on document commit when connected
  • Dependency Table uses server-side resolution check when connected
  • Dependency Table download button fetches unresolved dependencies
  • All viewers show "Offline — showing cached data" banner when disconnected
  • All viewers re-enable server controls on reconnect

Dependencies

  • Phase 1 foundation (#37)
  • Phase 2–5 viewer widgets (#38, #39, #40, #41)
  • Existing SSE broker in silo_commands.py (SiloEventListener)
  • Existing Silo client API methods in silo-client

References

  • docs/src/silo-server/SPECIFICATION.md — API endpoint reference
  • docs/src/silo-server/STATUS.md — implementation status
  • docs/src/silo-server/GAP_ANALYSIS.md — approval/job gaps
  • Silo Metadata Viewport Specification §9 (Server Integration)
  • docs/SILO_VIEWPORT_PLAN.md Phase 7
  • mods/silo/freecad/silo_commands.pySiloEventListener class
## Summary Wire live data fetching, SSE event subscriptions, and server write-back into the viewer widgets. This connects the offline-capable viewers to the running Silo server for real-time updates and bidirectional sync. ## Background Phases 1–5 build viewers that operate on local `silo/` data. This phase adds the network layer: viewers that can fetch fresh data from the server, subscribe to SSE events for live updates, and push edits back on commit. The SSE broker infrastructure already exists in `silo_commands.py` (`SiloEventListener`), and the Activity panel already subscribes to events. Viewer widgets subscribe to the same broker. ## Server API availability (as of Feb 2026) Based on silo-server documentation review: | Feature | Server Status | Endpoint | |---------|--------------|----------| | Revisions fetch | **Implemented** | `GET /api/items/{pn}/revisions` | | Metadata read/write | **Implemented** | `GET/PUT /api/items/{pn}/metadata` | | Lifecycle transitions | **Implemented** | `PATCH /api/items/{pn}/metadata/lifecycle` | | Tag management | **Implemented** | `PATCH /api/items/{pn}/metadata/tags` | | Schema form descriptor | **Implemented** | `GET /api/schemas/{name}/form` | | Dependency resolution | **Implemented** | `GET /api/items/{pn}/dependencies/resolve` | | Macro source fetch | **Implemented** | `GET /api/items/{pn}/macros/{filename}` | | SSE event stream | **Implemented** | `GET /api/events` | | File download | **Implemented** | `GET /api/items/{pn}/file/{rev}` | | Approval API | **Not implemented** | DB tables exist (migration 018), no REST handlers. Tier 4 on roadmap. | | Job queue runtime | **Not implemented** | DB tables exist (migration 015), no REST endpoints or queue backend. | ## In scope (this issue) ### History Viewer - **Refresh button**: Fetches via `_client.get_revisions(pn)` and replaces local snapshot - **SSE subscription**: `revision_created` signal triggers auto-refresh - **Merge strategy**: Server revisions are authoritative — replace local snapshot on refresh ### Metadata Editor - **Schema-driven fields**: Fetch `GET /api/schemas/{name}/form` for dynamic field rendering (replaces flat key-value fallback) - **Write-back on commit**: Queue changes via `PUT /api/items/{pn}/metadata` - **Lifecycle transitions**: Enable `QComboBox` when connected; calls `PATCH /api/items/{pn}/metadata/lifecycle` - **Tag sync**: Calls `PATCH /api/items/{pn}/metadata/tags` on save when connected - **Edit conflict handling**: If Metadata Editor has unsaved changes and a Silo Pull updates `metadata.json`, show a field-by-field diff dialog ### Dependency Table - **Server resolution**: Calls `GET /api/items/{pn}/dependencies/resolve` for availability status - **Download**: Calls `SiloSync.download_file(pn)` for unresolved items - **Refresh**: Re-checks resolution status after downloads complete ### All viewers - **Connection check**: On widget creation, check `_server_mode`. If offline, display "Offline — showing cached data" banner and disable server-dependent controls. - **Reconnect handling**: When connection status changes, refresh active viewers. ## Out of scope (deferred) ### Approvals Viewer server integration - No server API exists. The `SiloApprovalsViewer` will continue to display local `silo/approvals.json` snapshot only. - Deferred until Tier 4 Approval/ECO workflow is implemented on the server. ### Job Viewer server integration - No job queue runtime or REST endpoints exist despite DB tables being present. - The `SiloJobViewer` will continue as a local YAML editor only. Run button and status panel deferred. - Deferred until Tier 3 Compute infrastructure is implemented on the server. ## Files to modify | File | Change | |------|--------| | `src/Mod/Create/silo_viewers.py` | Add server fetch, SSE subscription, offline banner, and write-back logic to History, Metadata, and Dependency viewers | | `src/Mod/Create/silo_document.py` | Connect viewer refresh to SSE broker events | ## Technical notes ### Cross-module import pattern Viewers live in `src/Mod/Create/` but `_client`, `_server_mode`, and `SiloEventListener` live in `mods/silo/freecad/silo_commands.py`. Imports must be guarded: ```python try: import silo_commands _client = silo_commands._client _server_mode = silo_commands._server_mode except ImportError: _client = None ``` ### SSE event subscription pattern Each widget that needs SSE creates its own `SiloEventListener()` instance (matching existing pattern in `SiloAuthDockWidget` and `SiloStartView`). ## Acceptance criteria - [ ] History Viewer refresh button fetches live revisions from server - [ ] History Viewer auto-refreshes on `revision_created` SSE event - [ ] Metadata Editor lifecycle transitions call server API when connected - [ ] Metadata Editor tag sync calls server API when connected - [ ] Metadata Editor write-back pushes on document commit when connected - [ ] Dependency Table uses server-side resolution check when connected - [ ] Dependency Table download button fetches unresolved dependencies - [ ] All viewers show "Offline — showing cached data" banner when disconnected - [ ] All viewers re-enable server controls on reconnect ## Dependencies - Phase 1 foundation (#37) - Phase 2–5 viewer widgets (#38, #39, #40, #41) - Existing SSE broker in `silo_commands.py` (`SiloEventListener`) - Existing Silo client API methods in `silo-client` ## References - `docs/src/silo-server/SPECIFICATION.md` — API endpoint reference - `docs/src/silo-server/STATUS.md` — implementation status - `docs/src/silo-server/GAP_ANALYSIS.md` — approval/job gaps - Silo Metadata Viewport Specification §9 (Server Integration) - `docs/SILO_VIEWPORT_PLAN.md` Phase 7 - `mods/silo/freecad/silo_commands.py` — `SiloEventListener` class
forbes added the enhancement label 2026-02-18 21:17:43 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/silo-mod#43