mirror of
https://github.com/zvx-echo6/central.git
synced 2026-08-26 17:31:39 +00:00
refactor: decouple adapter class-identity (kind) from instance-identity (name)
Adds a `kind` TEXT column to `config.adapters` (migration 043) so one adapter
class can later back many operator-created instances. Every built-in adapter
row is back-filled with `kind = name`, keeping all 23 adapters working
unchanged.
- Migration 043: ADD COLUMN IF NOT EXISTS kind, back-fill, SET NOT NULL.
- AdapterConfig gains `kind: str | None` with a model_validator that falls
back to `name` when the column is NULL/absent (pre-043 rows).
- config_store.get_adapter / list_adapters: add `kind` to SELECT.
- supervisor._create_adapter AND _start_adapter (api-key precondition):
resolve the class by config.kind (class key) not config.name (instance key);
runtime state keying stays on config.name.
- routes.py GET/POST /adapters/{name} and adapters_list: add `kind` to SELECT,
resolve the adapter class by row["kind"].
- adapter_discovery.py: comment clarifying .name is the kind (class identity).
- Out of scope, left as-is (built-ins only, name==kind): setup wizard paths in
routes.py (~750/~891/~1109) and gui/__init__.py.
- Tests: 17 new pure-unit tests (migration SQL shape, AdapterConfig back-compat,
_create_adapter + _start_adapter kind dispatch). Existing test mock rows
updated to include the `kind` field.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9450696fe9
commit
ff97faea0d
12 changed files with 370 additions and 26 deletions
|
|
@ -42,9 +42,9 @@ class TestAdaptersListAuthenticated:
|
|||
|
||||
mock_conn = AsyncMock()
|
||||
mock_conn.fetch.return_value = [
|
||||
{"name": "firms", "enabled": True, "cadence_s": 300, "settings": {"api_key_alias": "firms"}, "paused_at": None, "updated_at": None, "last_error": None},
|
||||
{"name": "nws", "enabled": True, "cadence_s": 60, "settings": {"contact_email": "test@test.com"}, "paused_at": None, "updated_at": None, "last_error": None},
|
||||
{"name": "usgs_quake", "enabled": True, "cadence_s": 120, "settings": {"feed": "all_hour"}, "paused_at": None, "updated_at": None, "last_error": None},
|
||||
{"name": "firms", "kind": "firms", "enabled": True, "cadence_s": 300, "settings": {"api_key_alias": "firms"}, "paused_at": None, "updated_at": None, "last_error": None},
|
||||
{"name": "nws", "kind": "nws", "enabled": True, "cadence_s": 60, "settings": {"contact_email": "test@test.com"}, "paused_at": None, "updated_at": None, "last_error": None},
|
||||
{"name": "usgs_quake", "kind": "usgs_quake", "enabled": True, "cadence_s": 120, "settings": {"feed": "all_hour"}, "paused_at": None, "updated_at": None, "last_error": None},
|
||||
]
|
||||
|
||||
mock_pool = MagicMock()
|
||||
|
|
@ -97,6 +97,7 @@ class TestAdaptersEditForm:
|
|||
mock_conn.fetchrow.side_effect = [
|
||||
{
|
||||
"name": "nws",
|
||||
"kind": "nws",
|
||||
"enabled": True,
|
||||
"cadence_s": 60,
|
||||
"settings": {"contact_email": "test@example.com", "region": {"north": 49, "south": 24, "east": -66, "west": -125}},
|
||||
|
|
@ -178,6 +179,7 @@ class TestAdaptersEditSubmit:
|
|||
mock_conn = AsyncMock()
|
||||
mock_conn.fetchrow.return_value = {
|
||||
"name": "nws",
|
||||
"kind": "nws",
|
||||
"enabled": True,
|
||||
"cadence_s": 60,
|
||||
"settings": {"contact_email": "old@example.com", "region": {"north": 49, "south": 24, "east": -66, "west": -125}},
|
||||
|
|
@ -227,6 +229,7 @@ class TestAdaptersEditSubmit:
|
|||
mock_conn.fetchrow.side_effect = [
|
||||
{
|
||||
"name": "nws",
|
||||
"kind": "nws",
|
||||
"enabled": True,
|
||||
"cadence_s": 60,
|
||||
"settings": {"contact_email": "test@example.com", "region": {"north": 49, "south": 24, "east": -66, "west": -125}},
|
||||
|
|
@ -286,6 +289,7 @@ class TestAdaptersAudit:
|
|||
mock_conn = AsyncMock()
|
||||
mock_conn.fetchrow.return_value = {
|
||||
"name": "nws",
|
||||
"kind": "nws",
|
||||
"enabled": True,
|
||||
"cadence_s": 60,
|
||||
"settings": {"contact_email": "old@example.com", "region": {"north": 49, "south": 24, "east": -66, "west": -125}},
|
||||
|
|
@ -350,6 +354,7 @@ class TestAdaptersJsonbRegression:
|
|||
mock_conn = AsyncMock()
|
||||
mock_conn.fetchrow.return_value = {
|
||||
"name": "nws",
|
||||
"kind": "nws",
|
||||
"enabled": True,
|
||||
"cadence_s": 60,
|
||||
"settings": {"contact_email": "old@example.com", "region": {"north": 49, "south": 24, "east": -66, "west": -125}}, # dict, as asyncpg returns
|
||||
|
|
@ -402,6 +407,7 @@ class TestAdaptersJsonbRegression:
|
|||
mock_conn = AsyncMock()
|
||||
mock_conn.fetchrow.return_value = {
|
||||
"name": "nws",
|
||||
"kind": "nws",
|
||||
"enabled": True,
|
||||
"cadence_s": 60,
|
||||
"settings": {"contact_email": "old@example.com", "region": {"north": 49, "south": 24, "east": -66, "west": -125}}, # dict
|
||||
|
|
@ -443,7 +449,7 @@ class TestAdaptersJsonbRegression:
|
|||
mock_conn = MagicMock()
|
||||
mock_conn.fetchrow = AsyncMock(side_effect=[
|
||||
# Adapter row
|
||||
{"name": "firms", "enabled": True, "cadence_s": 300, "settings": {},
|
||||
{"name": "firms", "kind": "firms", "enabled": True, "cadence_s": 300, "settings": {},
|
||||
"paused_at": None, "updated_at": None, "last_error": None},
|
||||
# System row
|
||||
{"map_tile_url": "https://tile.example.com", "map_attribution": "Test"},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue