v0.4.0 - merge from claude/dev-015sto5mf2MpPCE57TbNKtaF #1
60
CHANGELOG.md
60
CHANGELOG.md
@@ -5,6 +5,65 @@ All notable changes to Seismo Fleet Manager will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.3.0] - 2025-12-09
|
||||
|
||||
### Added
|
||||
- **Series 4 (Micromate) Support**: New `/api/series4/heartbeat` endpoint for receiving telemetry from Series 4 Micromate units
|
||||
- Auto-detection of Series 4 units via UM##### ID pattern
|
||||
- Stores project hints from emitter payload in unit notes
|
||||
- Automatic unit type classification across both Series 3 and Series 4 endpoints
|
||||
- **Development Environment Labels**: Visual indicators to distinguish dev from production deployments
|
||||
- Yellow "DEV" badge in sidebar navigation
|
||||
- "[DEV]" prefix in browser title
|
||||
- Yellow banner on dashboard when running in development mode
|
||||
- Environment variable support in docker-compose.yml (ENVIRONMENT=production|development)
|
||||
- **Quality of Life Improvements**:
|
||||
- Human-readable relative timestamps (e.g., "2h 15m ago", "3d ago") with full date in tooltips
|
||||
- "Last Updated" timestamp indicator on dashboard
|
||||
- Status icons for colorblind accessibility (checkmark for OK, clock for Pending, X for Missing)
|
||||
- Breadcrumb navigation on unit detail pages
|
||||
- Copy-to-clipboard buttons for unit IDs
|
||||
- Search/filter functionality for fleet roster table
|
||||
- Improved empty state messages with icons
|
||||
- **Timezone Support**: Comprehensive timezone handling across the application
|
||||
- Timezone selector in Settings (defaults to America/New_York EST)
|
||||
- Human-readable timestamp format (e.g., "9/10/2020 8:00 AM EST")
|
||||
- Timezone-aware display for all timestamps site-wide
|
||||
- Settings stored in localStorage for immediate effect
|
||||
- **Settings Page Redesign**: Complete overhaul with tabbed interface and persistent preferences
|
||||
- **General Tab**: Display preferences (timezone, theme, auto-refresh interval)
|
||||
- **Data Management Tab**: Safe operations (CSV export, merge import, roster table)
|
||||
- **Advanced Tab**: Power user settings (replace mode import, calibration defaults, status thresholds)
|
||||
- **Danger Zone Tab**: Destructive operations isolated with enhanced warnings
|
||||
- Backend preferences storage via new UserPreferences model
|
||||
- Tab state persistence in localStorage
|
||||
- Smooth animations and consistent styling with existing pages
|
||||
- **User Preferences API**: New backend endpoints for persistent settings storage
|
||||
- `GET /api/settings/preferences` - Retrieve all user preferences
|
||||
- `PUT /api/settings/preferences` - Update preferences (supports partial updates)
|
||||
- Database-backed storage for cross-device preference sync
|
||||
- Migration script: `backend/migrate_add_user_preferences.py`
|
||||
|
||||
### Changed
|
||||
- Timestamps now display in user-selected timezone with human-readable format throughout the application
|
||||
- Settings page reorganized from 644-line flat layout to clean 4-tab interface
|
||||
- CSV Replace Mode moved from Data Management to Advanced tab with additional warnings
|
||||
- Import operations separated: safe merge in Data Management tab, destructive replace in Advanced tab
|
||||
- Page title changed from "Roster Manager" to "Settings" for better clarity
|
||||
- All preferences now persist to backend database instead of relying solely on localStorage
|
||||
|
||||
### Fixed
|
||||
- Unit type classification now consistent across Series 3 and Series 4 heartbeat endpoints
|
||||
- Auto-correction of misclassified unit types when they report to wrong endpoint
|
||||
|
||||
### Technical Details
|
||||
- New `detect_unit_type()` helper function for pattern-based unit classification
|
||||
- UserPreferences model with single-row table pattern (id=1) for global settings
|
||||
- Series 4 units identified by UM prefix followed by digits (e.g., UM11719)
|
||||
- JavaScript Intl API used for client-side timezone conversion
|
||||
- Pydantic schema for partial preference updates (PreferencesUpdate model)
|
||||
- Environment context injection via custom FastAPI template response wrapper
|
||||
|
||||
## [0.2.1] - 2025-12-03
|
||||
|
||||
### Added
|
||||
@@ -92,6 +151,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Photo management per unit
|
||||
- Automated status categorization (OK/Pending/Missing)
|
||||
|
||||
[0.3.0]: https://github.com/serversdwn/seismo-fleet-manager/compare/v0.2.1...v0.3.0
|
||||
[0.2.1]: https://github.com/serversdwn/seismo-fleet-manager/compare/v0.2.0...v0.2.1
|
||||
[0.2.0]: https://github.com/serversdwn/seismo-fleet-manager/compare/v0.1.1...v0.2.0
|
||||
[0.1.1]: https://github.com/serversdwn/seismo-fleet-manager/compare/v0.1.0...v0.1.1
|
||||
|
||||
77
README.md
77
README.md
@@ -1,4 +1,4 @@
|
||||
# Seismo Fleet Manager v0.2.1
|
||||
# Seismo Fleet Manager v0.3.0
|
||||
|
||||
Backend API and HTMX-powered web interface for managing a mixed fleet of seismographs and field modems. Track deployments, monitor health in real time, merge roster intent with incoming telemetry, and control your fleet through a unified database and dashboard.
|
||||
|
||||
@@ -100,15 +100,27 @@ cp /tmp/sfm_test.db data/seismo_fleet.db
|
||||
|
||||
The helper script creates a modem/seismograph mix so you can exercise the dashboard, roster tabs, and unit detail screens immediately.
|
||||
|
||||
## Upgrading from v0.1.x
|
||||
## Upgrading from Previous Versions
|
||||
|
||||
Versions ≥0.2 introduce new roster columns (device_type, calibration dates, modem metadata, addresses, etc.). Run the migration once per database file before starting the app:
|
||||
### From v0.2.x to v0.3.0
|
||||
|
||||
Version 0.3.0 introduces user preferences storage. Run the migration once per database file:
|
||||
|
||||
```bash
|
||||
python backend/migrate_add_user_preferences.py
|
||||
```
|
||||
|
||||
This creates the `user_preferences` table for persistent settings storage (timezone, theme, auto-refresh interval, calibration defaults, status thresholds).
|
||||
|
||||
### From v0.1.x to v0.2.x or later
|
||||
|
||||
Versions ≥0.2 introduce new roster columns (device_type, calibration dates, modem metadata, addresses, etc.). Run the migration once per database file:
|
||||
|
||||
```bash
|
||||
python backend/migrate_add_device_types.py
|
||||
```
|
||||
|
||||
The script is idempotent—if the new columns already exist it simply exits.
|
||||
Both migration scripts are idempotent—if the columns/tables already exist, they simply exit.
|
||||
|
||||
## API Endpoints
|
||||
|
||||
@@ -156,6 +168,8 @@ The script is idempotent—if the new columns already exist it simply exits.
|
||||
- **GET** `/api/settings/stats` - Counts for roster, emitters, and ignored tables
|
||||
- **GET** `/api/settings/roster-units` - Raw roster dump for the settings data grid
|
||||
- **POST** `/api/settings/import-csv-replace` - Replace the entire roster in one atomic transaction
|
||||
- **GET** `/api/settings/preferences` - Get user preferences (timezone, theme, calibration defaults, etc.)
|
||||
- **PUT** `/api/settings/preferences` - Update user preferences (supports partial updates)
|
||||
- **POST** `/api/settings/clear-all` - Danger-zone action that wipes roster, emitters, and ignored tables
|
||||
- **POST** `/api/settings/clear-roster` - Delete only roster entries
|
||||
- **POST** `/api/settings/clear-emitters` - Delete auto-discovered emitters
|
||||
@@ -183,6 +197,7 @@ See [sample_roster.csv](sample_roster.csv) for a minimal working example.
|
||||
### Emitter Reporting
|
||||
- **POST** `/emitters/report` - Submit status report from a seismograph unit
|
||||
- **POST** `/api/series3/heartbeat` - Series 3 multi-unit telemetry payload
|
||||
- **POST** `/api/series4/heartbeat` - Series 4 (Micromate) multi-unit telemetry payload
|
||||
- **GET** `/fleet/status` - Retrieve status of all seismograph units (legacy)
|
||||
|
||||
### Photo Management
|
||||
@@ -314,6 +329,22 @@ print(response.json())
|
||||
| reason | string | Optional context for ignoring |
|
||||
| ignored_at | datetime | When the ignore action occurred |
|
||||
|
||||
### UserPreferences Table (Settings Storage)
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| id | integer | Always 1 (single-row table) |
|
||||
| timezone | string | Display timezone (default: America/New_York) |
|
||||
| theme | string | UI theme: auto, light, or dark |
|
||||
| auto_refresh_interval | integer | Dashboard refresh interval in seconds |
|
||||
| date_format | string | Date format preference |
|
||||
| table_rows_per_page | integer | Default pagination size |
|
||||
| calibration_interval_days | integer | Default days between calibrations |
|
||||
| calibration_warning_days | integer | Warning threshold before calibration due |
|
||||
| status_ok_threshold_hours | integer | Hours for OK status threshold |
|
||||
| status_pending_threshold_hours | integer | Hours for Pending status threshold |
|
||||
| updated_at | datetime | Last preference update timestamp |
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
@@ -321,8 +352,8 @@ seismo-fleet-manager/
|
||||
├── backend/
|
||||
│ ├── main.py # FastAPI app entry point
|
||||
│ ├── database.py # SQLAlchemy database configuration
|
||||
│ ├── models.py # Database models (RosterUnit, Emitter, IgnoredUnit)
|
||||
│ ├── routes.py # Legacy API endpoints
|
||||
│ ├── models.py # Database models (RosterUnit, Emitter, IgnoredUnit, UserPreferences)
|
||||
│ ├── routes.py # Legacy API endpoints + Series 3/4 heartbeat endpoints
|
||||
│ ├── routers/ # Modular API routers
|
||||
│ │ ├── roster.py # Fleet status endpoints
|
||||
│ │ ├── roster_edit.py # Roster management & CSV import
|
||||
@@ -330,10 +361,11 @@ seismo-fleet-manager/
|
||||
│ │ ├── photos.py # Photo management
|
||||
│ │ ├── dashboard.py # Dashboard partials
|
||||
│ │ ├── dashboard_tabs.py # Dashboard tab endpoints
|
||||
│ │ └── settings.py # Roster manager/data operations
|
||||
│ │ └── settings.py # Settings, preferences, and data management
|
||||
│ ├── services/
|
||||
│ │ └── snapshot.py # Fleet status snapshot logic
|
||||
│ ├── migrate_add_device_types.py # SQLite migration for v0.2 schema
|
||||
│ ├── migrate_add_user_preferences.py # SQLite migration for v0.3 schema
|
||||
│ └── static/ # Static assets (CSS, etc.)
|
||||
├── create_test_db.py # Generate a sample SQLite DB with mixed devices
|
||||
├── templates/ # Jinja2 HTML templates
|
||||
@@ -400,24 +432,31 @@ docker compose down -v
|
||||
|
||||
## Release Highlights
|
||||
|
||||
### v0.3.0 — 2025-12-09
|
||||
- **Series 4 Support**: New `/api/series4/heartbeat` endpoint with auto-detection for Micromate units (UM##### pattern)
|
||||
- **Settings Redesign**: Completely redesigned Settings page with 4-tab interface (General, Data Management, Advanced, Danger Zone)
|
||||
- **User Preferences**: Backend storage for timezone, theme, auto-refresh interval, calibration defaults, and status thresholds
|
||||
- **Development Labels**: Visual indicators to distinguish dev from production environments
|
||||
- **Timezone Support**: Comprehensive timezone handling with human-readable timestamps site-wide
|
||||
- **Quality of Life**: Relative timestamps, status icons for accessibility, breadcrumb navigation, copy-to-clipboard, search functionality
|
||||
|
||||
### v0.2.1 — 2025-12-03
|
||||
- Added the `/settings` roster manager with CSV export/import, live stats, and danger-zone table reset actions.
|
||||
- Deployed/Benched/Retired/Ignored tabs now have dedicated HTMX partials, sorting, and inline actions (edit, deploy toggle, ignore, delete).
|
||||
- Unit detail pages expose device-type specific metadata (calibration windows, modem pairing, IP/phone fields) with a refreshed editing experience.
|
||||
- Snapshot summary and dashboard counts now focus on deployed units and include address/coordinate data for mapping widgets.
|
||||
- Added the `/settings` roster manager with CSV export/import, live stats, and danger-zone table reset actions
|
||||
- Deployed/Benched/Retired/Ignored tabs now have dedicated HTMX partials, sorting, and inline actions
|
||||
- Unit detail pages expose device-type specific metadata (calibration windows, modem pairing, IP/phone fields)
|
||||
- Snapshot summary and dashboard counts now focus on deployed units and include address/coordinate data
|
||||
|
||||
### v0.2.0 — 2025-12-03
|
||||
- Introduced device-type aware roster schema (seismograph vs modem) plus migration + `create_test_db.py` helper for new installs.
|
||||
- Added Ignore list model/endpoints to quarantine noisy emitters directly from the roster.
|
||||
- Roster page gained Add Unit + CSV Import modals, HTMX-driven updates, and unknown emitter callouts.
|
||||
- Snapshot service now returns active/benched/retired/unknown buckets containing richer metadata for the dashboard and roster tabs.
|
||||
- Introduced device-type aware roster schema (seismograph vs modem) plus migration + `create_test_db.py` helper
|
||||
- Added Ignore list model/endpoints to quarantine noisy emitters directly from the roster
|
||||
- Roster page gained Add Unit + CSV Import modals, HTMX-driven updates, and unknown emitter callouts
|
||||
- Snapshot service now returns active/benched/retired/unknown buckets containing richer metadata
|
||||
|
||||
### v0.1.1 — 2025-12-02
|
||||
- **Roster Editing API**: Full CRUD operations for managing your fleet roster
|
||||
- **CSV Import**: Bulk upload roster data from CSV files
|
||||
- **Enhanced Data Model**: Added project_id and location fields to roster
|
||||
- **Bug Fixes**: Improved database session management and error handling
|
||||
- **Dashboard Improvements**: Separate views for Active, Benched, and Retired units
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md) for the full release notes.
|
||||
|
||||
@@ -437,9 +476,11 @@ MIT
|
||||
|
||||
## Version
|
||||
|
||||
**Current: 0.2.1** — Settings & roster manager refresh (2025-12-03)
|
||||
**Current: 0.3.0** — Series 4 support, settings redesign, user preferences (2025-12-09)
|
||||
|
||||
Previous: 0.2.0 — Device-type aware roster + ignore list (2025-12-03)
|
||||
Previous: 0.2.1 — Settings & roster manager refresh (2025-12-03)
|
||||
|
||||
0.2.0 — Device-type aware roster + ignore list (2025-12-03)
|
||||
|
||||
0.1.1 — Roster Management & CSV Import (2025-12-02)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Base.metadata.create_all(bind=engine)
|
||||
ENVIRONMENT = os.getenv("ENVIRONMENT", "production")
|
||||
|
||||
# Initialize FastAPI app
|
||||
VERSION = "0.2.3"
|
||||
VERSION = "0.3.0"
|
||||
app = FastAPI(
|
||||
title="Seismo Fleet Manager",
|
||||
description="Backend API for managing seismograph fleet status",
|
||||
@@ -258,9 +258,9 @@ async def unknown_emitters_partial(request: Request):
|
||||
def health_check():
|
||||
"""Health check endpoint"""
|
||||
return {
|
||||
"message": "Seismo Fleet Manager v0.1.1",
|
||||
"message": f"Seismo Fleet Manager v{VERSION}",
|
||||
"status": "running",
|
||||
"version": "0.1.1"
|
||||
"version": VERSION
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user