Commit graph

72 commits

Author SHA1 Message Date
Matt Johnson
b1ba2d1863 fix(tests): update tests for lazy app loading and 302 redirect
- test_gui_scaffold.py: use standalone router instead of importing app
  to avoid triggering settings load during test collection
- test_setup_gate.py: expect 302 (not 307) for setup gate redirect

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-17 06:14:25 +00:00
Matt Johnson
f059f982bc feat(gui): add auth core, setup gate, and first-run operator creation
- Add migrations 007-010 for system config, operators, sessions, audit_log
- Implement argon2id password hashing via argon2-cffi
- Implement session-based authentication with database-stored tokens
- Add SetupGateMiddleware to redirect to /setup until first operator created
- Add SessionMiddleware to load session from cookie and attach operator
- Create /setup, /login, /logout, /change-password routes with CSRF protection
- Add periodic session cleanup task (hourly)
- Add audit logging for auth events
- Update systemd unit with EnvironmentFile for /etc/central/central.env
- Add comprehensive tests for auth, middleware, and audit modules

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-17 05:30:49 +00:00
Matt Johnson
614312db36 feat(gui): add FastAPI + Jinja2 + HTMX scaffold
- FastAPI app with Jinja2 templates and Pico CSS + HTMX from CDN
- Routes: GET / (placeholder page), GET /health (JSON healthcheck)
- systemd unit (no Install section - manual start only)
- TestClient tests for both endpoints

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-17 04:32:39 +00:00
Matt Johnson
374a8c067f chore: normalize line endings to LF 2026-05-16 22:26:12 +00:00
Matt Johnson
aacf06499b feat(adapters): add USGS earthquake adapter
USGS Earthquake Hazards Program adapter:
- Polls GeoJSON feed (all_hour default, configurable)
- Magnitude tier classification (minor/light/moderate/strong/major/great)
- Deduplication via USGS stable event ID
- Region filter via shapely point-in-bbox
- Skips events with null magnitude (quarry blasts, etc.)

Includes comprehensive unit tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 20:51:36 +00:00
Matt Johnson
22c50d3176 fix(firms): use public is_published/mark_published methods
Match NWS adapter pattern for supervisor compatibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 20:03:34 +00:00
Matt Johnson
0097163edf feat(adapters): add FIRMS fire hotspot adapter
NASA FIRMS adapter for VIIRS satellite fire detections:
- Polls VIIRS_SNPP_NRT and VIIRS_NOAA20_NRT satellites
- Deduplication via stable ID (satellite📅time:lat:lon)
- Hot-reload support for region, satellites, and API key
- Confidence mapping: l/n/h -> low/nominal/high
- Severity: high=3, nominal=2, low=1

Includes comprehensive unit tests for:
- CSV parsing and event generation
- Deduplication logic
- URL building and config application

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 19:58:31 +00:00
Matt Johnson
5b028b38e8 test: remove ineffective hot-reload tests
These tests pass on both fixed and unfixed code, meaning they do
not actually exercise the cadence-decrease bug. The tests were
added as part of PR #4 but direct verification showed they
do not catch the issue they claim to test.

A follow-up issue should be filed for proper regression tests
that reproduce the actual bug (AsyncLimiter blocking).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 17:19:27 +00:00
Matt Johnson
35de09ea93 test: add hot-reload integration tests for cadence changes
Add tests that exercise the ACTUAL running loop with cancel_event
signaling, not just AdapterState math in isolation.

Test cases:
- Test 1: Cadence decrease (60->30) wakes loop immediately
- Test 2: Cadence increase (10->20) extends wait correctly
- Test 3: Enable/disable/enable with gap > cadence polls immediately
- Test 4: Enable/disable/enable with gap < cadence waits

These tests verify the cancel_event mechanism properly interrupts
the sleeping loop when config changes occur via _on_config_change.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 05:59:35 +00:00
Ubuntu
a362b7b93e test: remove TomlConfigSource and config_source flag tests
TOML-related tests no longer needed after Phase C retirement.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 03:42:43 +00:00
Matt Johnson
c39e3174b8 fix: preserve last_completed_poll across adapter disable/enable
Previously, _stop_adapter() used pop() to remove adapter state,
which lost last_completed_poll. On re-enable, a fresh state was
created, causing immediate poll and violating rate-limit guarantee.

Changes:
- Add is_running property to AdapterState
- _stop_adapter: preserve state, just cancel task
- _start_adapter: reuse existing stopped state if present
- Add _remove_adapter for full cleanup when adapter is deleted
- _on_config_change: call _remove_adapter for deleted adapters

Integration tests verify:
- Test A: gap > cadence -> immediate poll (correct)
- Test B: gap < cadence -> wait until last_poll + cadence (was broken)
- Test C: delete + re-add -> fresh state (correct)

Tests-fail-before-fix verified: Test A/B failed on unfixed code
with "State was removed on stop!", pass with fix.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 02:37:57 +00:00
Ubuntu
1abdf45375 test: add ConfigSource and hot-reload rate-limit tests
- TomlConfigSource tests: list/get adapters, watch_for_changes no-op
- DbConfigSource tests: list/get adapters with DB fixtures
- create_config_source factory tests
- NOTIFY integration test for DbConfigSource
- Rate-limit guarantee tests:
  - Cadence change respects last_poll time
  - Gap exceeding new cadence polls immediately
  - Enable/disable/enable respects rate limit
  - Multiple rapid changes no extra polls
- Bootstrap flag validation tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 01:55:47 +00:00
Ubuntu
25909b0f4d fix(tests): replace echo6 reference with central.local
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 01:36:44 +00:00
Ubuntu
826141c71a docs(tests): add README documenting CENTRAL_TEST_DB_DSN env var
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 01:36:40 +00:00
Ubuntu
b183a621bb feat(config_store): add listener reconnect with exponential backoff
Listener now automatically reconnects on connection loss with
exponential backoff (1s-30s). Cancellation propagates cleanly.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-16 01:36:35 +00:00
Ubuntu
8c5349c880 feat(config): add database-backed config store
Add ConfigStore class providing async access to config schema:

- get_adapter/list_adapters/upsert_adapter for adapter config
- pause_adapter/unpause_adapter for runtime control
- set_api_key/get_api_key with encryption via crypto.py
- listen_for_changes using Postgres LISTEN/NOTIFY

Includes Pydantic models (AdapterConfig, ApiKeyInfo) and tests
using real Postgres test database.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-15 23:07:56 +00:00
Ubuntu
fab452aa02 feat(config): add AES-256-GCM crypto primitives
Add encrypt/decrypt functions using AES-256-GCM for secret storage.
Master key loaded from file path specified in bootstrap config.

Features:
- 32-byte key from base64-encoded file
- 12-byte random nonce per encryption
- AEAD authentication (detects tampering)
- Key caching with clear_key_cache() for rotation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-15 23:07:41 +00:00
Ubuntu
e126569a4d feat(config): add bootstrap config from environment
Add pydantic-settings based Settings class for loading configuration
from environment variables or .env file. Provides early-stage config
before database-backed config store is available.

Includes:
- CENTRAL_DB_DSN, CENTRAL_NATS_URL, CENTRAL_MASTER_KEY_PATH, CENTRAL_LOG_LEVEL
- Cached loader with get_settings()
- Tests for env vars, .env file, validation, caching

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-15 23:07:33 +00:00
Matt Johnson
4a7f1a76c7 refactor: rename CloudEvents extension attributes hub* → central*
Rename extension attributes for consistency with project naming:
- hubschemaversion → centralschemaversion
- hubcategory → centralcategory
- hubseverity → centralseverity

Non-breaking change - no consumers depend on these names yet.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-15 21:47:50 +00:00
Matt Johnson
31be17430d runtime: NWS adapter, supervisor, archive consumer, systemd units
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-15 21:29:08 +00:00
Matt Johnson
714971fe99 foundation: models, adapter ABC, config, CE wire, schema
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-15 21:08:56 +00:00
Matt Johnson
36ebbcb250 scaffold: initial repository structure 2026-05-15 19:16:24 +00:00