Web Interface¶
Tier: 1 (Infrastructure) · Status: Planned — v0.9.0 · Port: 8000 Prototype: The
web-mockservice (since v0.2.0, Port 8001) implements the full UI shell with mock data. See web-mock README.
The Web-Interface is the local management console for the Silvasonic recording station. It provides a real-time system dashboard, device management, service configuration, and live audio monitoring — all from a browser, without SSH.
1. Architecture & Technology Stack¶
1.1 Core Philosophy — "Fast & Light"¶
The frontend follows the "Fast & Light" philosophy (ADR-0003): Server-Side Rendering (FastAPI + Jinja2), HTMX for DOM swaps, Alpine.js for client-side interactivity.
1.2 Backend Stack¶
| Layer | Technology |
|---|---|
| Framework | FastAPI + Uvicorn |
| Templating | Jinja2 |
| Database | SQLAlchemy 2.0+ (async), asyncpg |
| API Docs | Swagger / OpenAPI (auto-generated) |
1.3 Frontend Stack¶
| Layer | Technology | Version |
|---|---|---|
| CSS Framework | Tailwind CSS | 4.x |
| UI Components | DaisyUI | 5.x |
| Typography | Geist / Geist Mono | latest |
| Icons | Lucide (inline SVG) | latest |
| Data Visualization | Apache ECharts | 5.x |
| Audio Visualization | Wavesurfer.js | 7.x |
1.4 State Management & Data Flow¶
Read+Subscribe Pattern (Observability):
- Status: reads silvasonic:status:* keys for initial state, subscribes to silvasonic:status channel via SSE for live updates.
- Logs: subscribes to silvasonic:logs channel via SSE to stream container logs into the footer console (ADR-0022).
State Reconciliation Pattern (Control):
- The Web-Interface does not orchestrate containers directly.
- It writes desired state to the database, then publishes a silvasonic:nudge signal to Redis.
- The Controller picks up the nudge and performs the actual container lifecycle actions (ADR-0017).
1.5 Operational Constraints¶
- Database First, No Filesystem Scanning: Recording and detection lists come exclusively from the database.
- Media Serving: The
:rofilesystem mount serves individual known files (WAV playback, spectrogram images) by their database-recorded path only. - Stateless Container: All state lives in the database and Redis. The container is freely restartable.
2. Design System¶
- Theme: Custom DaisyUI themes (
silvadark/silvalight), each module has its own accent color token. - Typography: Geist for UI text, Geist Mono for data values and log output.
- Icons: Lucide, inline SVG in Jinja2 templates.
- Data Visualization (TO-BE): Apache ECharts for time-series, heatmaps, histograms. Wavesurfer.js v7 with Regions plugin for BirdNET/BatDetect annotation overlay, Timeline, Minimap, pre-computed peaks.
- Offline: All assets bundled in the container image. No CDN at runtime.
3. UX Concept¶
3.1 Layout & Navigation¶
Five fixed zones: Header, Sidebar Nav, Main Content, Inspector (right), Footer. Sidebar has two groups: System (Dashboard, Recorders, Processor, Uploaders) and Modules (Livesound, Birds, Bats, Weather). Settings + About pinned to bottom.
[!IMPORTANT] Conditional Module Rendering: Module sidebar entries are only visible when the corresponding module is enabled in Settings → Modules. This is DB-driven and not yet implemented in the web-mock (which shows all modules always).
3.2 Navigation Routing Rulebook¶
| Content Type | Pattern | Applies To |
|---|---|---|
| Hardware/Service instances (hard-limited) | Bento-Grid → Inspector | Recorders (max 5), Uploaders (max 3) |
| Worker results / data analyses | Horizontal Tabs | Birds, Bats, Weather |
| Admin subsections | Horizontal Tabs | Settings |
3.3 Action Risk Classification¶
| Class | Badge | Mechanism |
|---|---|---|
| Safe | ✅ | Execute immediately (export, rename, test, browse). |
| Guarded | 🟨 | Impact preview + "Apply at next safe point" or schedule. |
| Forbidden while REC | ⛔ | Button disabled + tooltip. Admin override: 2-step typed confirm. |
4. Page Blueprints¶
Implementation reference: All pages below are prototyped in
web-mock/templates/. The mock usesmock_data.py; the real interface replaces these with async DB queries route-by-route.
4.1 Dashboard¶
Bento-Grid of system function cards: Orchestration (Controller status), Data Pipeline (Processor status), SSD Storage, CPU, RAM, Uptime. Active Alerts. ECharts upload throughput chart (TO-BE).
4.2 Recorders (Bento-Grid, max 5)¶
Grid of Recorder Cards: live level bar, sample rate, channels, segment, gain, status. Detail view via click. Inspector shows Wavesurfer.js audio preview (TO-BE).
4.3 Processor¶
Single page (no tabs): Indexer file table + Retention event log. Storage & Retention configuration is managed in Settings → Storage & Retention.
4.4 Uploaders (Bento-Grid, max 3)¶
Grid of Uploader Cards: queue size, throughput, last sync, status. Detail view with target type and auth.
4.5 Birds / Bats (Tabs)¶
[ Discovery ] [ Analyzer ] [ Statistics ]
Discovery: Pokédex-style species cards. Analyzer: data table with filters, row click → Inspector (Wavesurfer.js spectrogram + annotation regions, TO-BE). Statistics: ECharts dashboards (TO-BE).
4.6 Weather (Tabs)¶
[ Overview ] [ Current ] [ Statistics ] [ Correlation ]
ECharts time-series for temperature, precipitation, humidity, pressure, wind. Correlation: dual Y-axis — detections overlaid with weather parameters (TO-BE).
4.7 Settings (Tabs)¶
[ General ] [ Modules ] [ Storage & Retention ] [ Remotes ] [ Network ] [ User ]
- Modules: Toggle per module with system reload. Module state drives sidebar visibility.
- Remotes: Per-target configuration (Nextcloud, S3). Test Connection + Save.
- Network: WLAN Hotspot + Tailscale VPN status and config.
- User: Password management for local admin.
4.8 Observability (TO-BE)¶
[ Metrics ] [ Events ]
Per-service CPU/RAM/NVMe I/O charts (ECharts). Human-readable audit trail. Logs exclusively in Footer Console.
4.9 Maintenance (TO-BE)¶
[ Updates ] [ Backup & Export ]
Updates require REC = IDLE.
5. Migration Path: Web-Mock → Web-Interface (v0.9.0)¶
The web-mock service is the clonable base for this service. Migration steps:
- Clone:
cp -r services/web-mock → services/web-interface. Rename package tosilvasonic-web-interface, update port to8000. - Delete
mock_data.py: All mock data is replaced by async DB queries. - Replace route-by-route: Each route changes one line —
mock_data.X→await db_query(session). Templates, static assets, and routing remain unchanged. - SSE Console: Replace
FAKE_LOG_LINEScycling generator with realSUBSCRIBE silvasonic:logsfrom Redis. - Conditional Sidebar: Add DB-driven module visibility (show Birds/Bats/Weather only when enabled in Settings → Modules).
- Retire web-mock: Move to
profiles: ["dev"]in compose or remove entirely.
[!NOTE] The
ServiceContextlifespan,get_station(),get_settings(), andPOST /settings/generalare already production-ready in the web-mock and can be kept as-is.
6. Scope Boundaries¶
- No Orchestration: Does not start or stop containers — that is the Controller's job.
- No Media Processing: Does not record audio, run ML inference, or process signals.
- Internal Network Only: Not a public API. Accessible locally or via Tailscale VPN.
- RBAC: Planned for v1.9.0+ (multi-user). Not in scope for v0.9.0.