Mobile operators were never seeing the inline PDF preview, .TXT
download, or Review form that v0.13.0 added — every feature was
working on desktop browsers but invisible in the PWA.
Root cause: backend/static/sw.js had CACHE_VERSION = 'v1', unchanged
since v0.12.x. The activate handler deletes any cache not matching
CACHE_VERSION, so without a bump the stale sfm-static-v1 cache (with
the pre-v0.13.0 event-modal.js) stayed authoritative. cacheFirst
strategy served it forever; mobile users effectively saw the v0.12.x
modal regardless of how many times we rebuilt the image.
Fix:
- CACHE_VERSION bumped to 'v0.13.2' (matches backend/main.py VERSION).
Comment in sw.js documents the convention: any release touching a
static asset must bump this string.
- event-modal.js added to the precache list so its lifecycle is
explicitly tied to the SW version bump (installed fresh on activate
rather than landing via the cacheFirst-then-cached pattern).
Mobile users get the new modal on next page nav: SW update check
picks up the bumped sw.js, skipWaiting installs it, activate evicts
the v1 caches, controllerchange fires, page reloads, fresh
event-modal.js loads. Worst case ~1h delay from
registration.update() interval; operators can force-refresh by
closing + reopening the PWA.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.13.0 shipped the mic_unit_pref default as "dBL", which made the
website chart's mic axis inconsistent with the PDF report (which
renders psi). Original brief was always "psi on charts, dBL on
peaks" — I implemented the default backwards. Operator caught it
within an hour of rollout.
Same-day patch:
- backend/models.py: default "dBL" → "psi"
- migrate_add_mic_unit_pref.py: idempotent across both fresh DB
("add column with psi default") and v0.13.0 upgrade ("flip dBL
rows to psi"). One-row table, freshness assumed.
- backend/routers/settings.py: GET/PUT fallback "dBL" → "psi"
- templates/settings.html: dropdown's `selected` flag moves to psi
+ reorders options + relabels with "(matches PDF report)" hint
- backend/static/event-modal.js: module-level fallback + branch
conditions flip to make psi the unset/error default
Includes the "Captured at" → "Time received" relabel from earlier
in the day (already-shipped commit 43c804d) rolled into the
release notes.
Migration is idempotent + safe to re-run; rolled out on the dev
container during this commit's smoke test.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Phase 1 closes the read-only gap between Terra-View and the
standalone SFM webapp on port 8200. Operators no longer need to
bounce between the two for routine event review.
Wraps up four commits shipped this iteration:
db8d666 settings: add mic_unit_pref for event-report chart
1d9fd00 event-modal: port 4-channel Chart.js waveform/histogram
panels + docker-compose mount fix for SFM container
4b2bb9a event-modal: inline PDF preview + .TXT link + review form
2905a32 admin_events: wire shared event-detail modal into the page
Highlights:
- Inline PDF preview via iframe (lazy-loaded; browser-native zoom)
- Chart.js 4-channel waveform/histogram in the modal
- Review form persisted to sidecar via PATCH
- /admin/events row click opens the modal (was port-8200-only)
- mic_unit_pref setting (dBL default, psi alternate; chart only)
- Cross-modal CustomEvent so host tables refresh on save
Phase 2 (device control: start/stop monitoring, push compliance,
erase) deferred pending SFM auth layer — see seismo-relay roadmap.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CHANGELOG entry for the five commits that landed after the v0.12.0 tag:
two features (Unit Swap wizard at /tools/unit-swap, editable deployment
timeline on /unit/{id}) and two correctness fixes (RosterUnit.deployed
now flips on swap/unassign/promote; deployment timeline now respects
user timezone for both display and edits). No schema migrations.
README bumped to v0.12.1 with new bullets for the post-v0.12.0 features
and several already-shipped items that were missing from the list (SFM
Event DB Manager, Deployment-History calendar + Gantt tabs, reusable
location-map partial). backend/main.py VERSION constant bumped too.
Version bumped in backend/main.py, README header/highlights/history,
and CHANGELOG.md with a comprehensive 0.10.0 entry covering the SFM
integration work shipped on this branch.
Highlights:
- SFM event store is now the authoritative vibration data source
- SFM-primary seismograph status with heartbeat fallback
- Dashboard rework (top-row reorder, schedule moved, SFM-sourced
Recent Call-Ins)
- Event detail modal + sortable events tables across all event
surfaces
- Events attribution engine + metadata-backfill tool
- /admin/sfm + /admin/slmm diagnostic pages under Developer settings
- Tools workflow hub at /tools (Pair Devices, Project Tidy, Backfill)
- Sidebar reorganization (single Devices entry w/ tabs, new Events
+ Tools entries)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Updated all instances of device_type from "sound_level_meter" to "slm" across the codebase.
- Enhanced documentation to reflect the new device type standardization.
- Added migration script to convert legacy device types in the database.
- Updated relevant API endpoints, models, and frontend templates to use the new device type.
- Ensured backward compatibility by deprecating the old device type without data loss.
Added Docker support for easy deployment:
- Dockerfile: Python 3.11 slim image with FastAPI app
- docker-compose.yml: Service definition with volume mounting for data persistence
- .dockerignore: Exclude unnecessary files from Docker build
- database.py: Updated to store SQLite DB in ./data directory for volume persistence
- .gitignore: Added entries for database files and data directory
- README.md: Comprehensive documentation with Docker and local setup instructions
The application can now be run with: docker compose up -d
Database persists in ./data directory mounted as a volume