Skip to content

feat: decompose DataSyncService into RuntimeQueryService and TelemetryQueryService#334

Merged
NodeJSmith merged 9 commits intomainfrom
worktree-next
Mar 15, 2026
Merged

feat: decompose DataSyncService into RuntimeQueryService and TelemetryQueryService#334
NodeJSmith merged 9 commits intomainfrom
worktree-next

Conversation

@jessica-claude
Copy link
Contributor

Summary

  • Splits the monolithic DataSyncService into RuntimeQueryService (in-memory web UI state) and TelemetryQueryService (SQLite-backed historical telemetry), resolving the mixed-responsibility design that blocked real telemetry from reaching the UI
  • TelemetryQueryService serves real listener/job telemetry from the database — invocation counts, execution counts, last error, last run — replacing the stub TODO methods that previously returned empty lists
  • Cleans up several related issues: N+1 query pattern in bus page, row_factory set per-method instead of once at connection level, unguarded state_proxy.is_ready() calls, and unused FastAPI DI parameters throughout the web routes

…yQueryService (#267)

Splits the monolithic DataSyncService into two focused services:

- RuntimeQueryService: in-memory data layer for the web UI — event buffer,
  log buffer, app status snapshot, and WebSocket broadcast. No I/O on reads.
- TelemetryQueryService: SQLite-backed historical telemetry — listener
  invocation counts, job execution counts, last error, last run. Served
  from real database queries via DatabaseService write queue.

Other changes:
- Set aiosqlite row_factory once at connection level in DatabaseService
  (eliminates per-method repetition)
- Fix N+1 query pattern in bus_page using asyncio.gather with
  return_exceptions=True
- Add session-scoped last_err subquery in get_listener_summary
- Guard state_proxy.is_ready() call in get_system_status against
  AttributeError/RuntimeError during startup
- Update FastAPI DI aliases: RuntimeDep, TelemetryDep replace DataSyncDep
- Remove DataSyncService, DataSyncDep, and related stubs from test_utils
- Update TESTING.md, web_mocks.py, and all integration test fixtures
@NodeJSmith NodeJSmith marked this pull request as ready for review March 14, 2026 16:28
Copilot AI review requested due to automatic review settings March 14, 2026 16:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR decomposes the former DataSyncService web-facing facade into two services: RuntimeQueryService for live in-memory UI/API state and TelemetryQueryService for SQLite-backed historical telemetry, and migrates the web layer/tests to the new DI aliases.

Changes:

  • Introduces RuntimeQueryService and TelemetryQueryService, wiring both into Hassette and updating DatabaseService to use aiosqlite.Row.
  • Migrates FastAPI routes, UI routers/partials, templates, and test helpers from DataSyncDep/data_sync_service to RuntimeDep/TelemetryDep/SchedulerDep.
  • Adds integration tests for TelemetryQueryService with a real SQLite database and updates/renames unit/integration/e2e tests accordingly.

Reviewed changes

Copilot reviewed 51 out of 51 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
tests/unit/core/test_web_ui_watcher.py Updates watcher tests to use runtime_query_service broadcast.
tests/unit/core/test_runtime_query_service.py Adds unit coverage for RuntimeQueryService behaviors (logs/events/ws/system status).
tests/unit/core/test_data_sync_service.py Removes obsolete DataSyncService unit tests.
tests/integration/test_ws_endpoint.py Updates WS integration tests to target RuntimeQueryService.
tests/integration/test_web_ui_watcher.py Updates integration watcher tests to use runtime_query_service.
tests/integration/test_web_ui.py Updates UI integration tests and log patch targets; adjusts bus-listener expectations for new deps.
tests/integration/test_web_api.py Updates API integration tests to use RuntimeQueryService and adjusts bus-related expectations.
tests/integration/test_telemetry_query_service.py Adds integration tests validating SQL-backed telemetry queries against SQLite.
tests/integration/test_database_service.py Updates assertions to account for aiosqlite.Row row_factory behavior.
tests/integration/test_core.py Updates core wiring assertions for new services.
tests/integration/conftest.py Renames fixture to runtime_query_service and updates FastAPI app fixture wiring.
tests/e2e/conftest.py Updates e2e wiring to RuntimeQueryService and stubs telemetry returns in new dict format.
tests/TESTING.md Updates docs for new test helpers (create_mock_runtime_query_service) and DI split.
src/hassette/web/ui/router.py Migrates full-page UI routes to new deps; introduces job serialization helper and telemetry-driven bus/app pages.
src/hassette/web/ui/partials.py Migrates HTMX partials to RuntimeDep/TelemetryDep/SchedulerDep; updates scheduler/bus partial parameter shapes.
src/hassette/web/ui/context.py Updates alert context helper to accept RuntimeQueryService.
src/hassette/web/templates/partials/scheduler_jobs.html Updates scheduler job owner links to derive from app_key/instance_index fields.
src/hassette/web/templates/partials/scheduler_history.html Updates scheduler history owner links to use app_key/instance_index when present.
src/hassette/web/templates/partials/bus_listeners.html Updates bus listener template to use telemetry schema fields (handler_method, app_key).
src/hassette/web/templates/partials/app_detail_listeners.html Removes instance-owner map rendering (template partially migrated).
src/hassette/web/templates/partials/app_detail_jobs.html Removes instance-owner map rendering (template partially migrated).
src/hassette/web/routes/ws.py Switches WS endpoint to register clients on runtime_query_service.
src/hassette/web/routes/scheduler.py Migrates scheduler routes to new deps and serializes scheduled jobs.
src/hassette/web/routes/logs.py Switches logs API route to RuntimeDep.
src/hassette/web/routes/health.py Switches health API route to RuntimeDep.
src/hassette/web/routes/events.py Switches events API route to RuntimeDep.
src/hassette/web/routes/entities.py Removes entity endpoints.
src/hassette/web/routes/bus.py Migrates bus routes to TelemetryDep and changes query parameter contract.
src/hassette/web/routes/apps.py Switches apps API routes to RuntimeDep.
src/hassette/web/dependencies.py Replaces DataSyncDep with RuntimeDep/TelemetryDep/SchedulerDep.
src/hassette/web/app.py Removes entities router registration.
src/hassette/web/CLAUDE.md Updates web-layer contributor docs for new DI aliases and responsibilities.
src/hassette/test_utils/web_mocks.py Renames mock factory to create_mock_runtime_query_service and stubs telemetry methods.
src/hassette/test_utils/web_helpers.py Updates job fixture helper to use real trigger types for _job_to_dict isinstance checks.
src/hassette/test_utils/init.py Re-exports updated test helper names.
src/hassette/logging_.py Updates docs/comments referring to RuntimeQueryService instead of DataSyncService.
src/hassette/core/web_ui_watcher.py Broadcasts dev-reload via runtime_query_service.
src/hassette/core/web_api_service.py Waits for RuntimeQueryService readiness instead of DataSyncService.
src/hassette/core/telemetry_query_service.py Implements SQLite-backed telemetry queries (listeners/jobs/errors/sessions).
src/hassette/core/scheduler_service.py Removes deprecated execution-history stub.
src/hassette/core/runtime_query_service.py Introduces renamed/slimmed runtime query service (drops telemetry/entity concerns).
src/hassette/core/database_service.py Sets SQLite connection row_factory to aiosqlite.Row.
src/hassette/core/core.py Wires RuntimeQueryService and TelemetryQueryService into the core and exposes properties.
src/hassette/core/bus_service.py Removes deprecated listener-metrics stub methods.
src/hassette/config/config.py Updates config docstring to refer to RuntimeQueryService buffer.
design/specs/004-decompose-datasyncservice/tasks/WP02.md Adds completed work package record for telemetry SQL + tests.
design/specs/004-decompose-datasyncservice/tasks/WP01b.md Adds completed work package record for web-layer migration and template updates.
design/specs/004-decompose-datasyncservice/tasks/WP01.md Adds completed work package record for core service split.
design/specs/004-decompose-datasyncservice/spec.md Adds feature spec skeleton.
design/specs/004-decompose-datasyncservice/design.md Adds design document capturing goals, architecture, and migration plan.
CHANGELOG.md Documents addition of the two new services and DB-backed telemetry.
Comments suppressed due to low confidence (1)

src/hassette/web/routes/scheduler.py:63

  • /scheduler/history declares response_model=list[JobExecutionResponse], but returns TelemetryQueryService.get_job_summary() rows (aggregate job summaries) which do not include required execution fields (started_at, duration_ms, status, etc.). This will cause response validation errors once real telemetry is returned. Return per-execution rows (or change the response model + endpoint semantics).
@router.get("/scheduler/history", response_model=list[JobExecutionResponse])
async def get_job_history(
    telemetry: TelemetryDep,
    limit: Annotated[int, Query(ge=1, le=1000)] = 50,  # noqa: ARG001
    app_key: Annotated[str | None, Query()] = None,
    instance_index: Annotated[int, Query()] = 0,
) -> list[dict]:
    if app_key is None:
        return []
    return await telemetry.get_job_summary(app_key=app_key, instance_index=instance_index)


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@codecov
Copy link

codecov bot commented Mar 14, 2026

Codecov Report

❌ Patch coverage is 82.96530% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.03%. Comparing base (85534a6) to head (4fd11dd).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/hassette/core/telemetry_query_service.py 87.37% 11 Missing and 2 partials ⚠️
src/hassette/test_utils/web_helpers.py 14.28% 12 Missing ⚠️
src/hassette/web/utils.py 52.17% 10 Missing and 1 partial ⚠️
src/hassette/core/runtime_query_service.py 45.45% 6 Missing ⚠️
src/hassette/web/routes/scheduler.py 63.63% 3 Missing and 1 partial ⚠️
src/hassette/core/core.py 77.77% 2 Missing ⚠️
src/hassette/web/ui/context.py 66.66% 2 Missing ⚠️
src/hassette/web/ui/partials.py 93.93% 1 Missing and 1 partial ⚠️
src/hassette/core/web_api_service.py 0.00% 1 Missing ⚠️
src/hassette/test_utils/web_mocks.py 96.42% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #334      +/-   ##
==========================================
- Coverage   80.15%   80.03%   -0.13%     
==========================================
  Files         140      141       +1     
  Lines        9969    10034      +65     
  Branches      981      985       +4     
==========================================
+ Hits         7991     8031      +40     
- Misses       1583     1608      +25     
  Partials      395      395              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes the split of the former DataSyncService responsibilities into two focused services: RuntimeQueryService (live/in-memory UI state + WS broadcasting) and TelemetryQueryService (SQLite-backed historical telemetry queries). It updates the FastAPI + UI layers to use the new dependency injection aliases and adds real SQL-backed telemetry queries with integration tests.

Changes:

  • Replaces DataSyncService usage across core/web/tests with RuntimeQueryService + new DI aliases (RuntimeDep, TelemetryDep, SchedulerDep).
  • Implements TelemetryQueryService with real SQL queries and adds end-to-end integration tests against SQLite.
  • Adjusts DB initialization to set row_factory once at connection time and updates affected tests.

Reviewed changes

Copilot reviewed 52 out of 52 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
tests/unit/core/test_web_ui_watcher.py Updates watcher tests to use runtime_query_service.broadcast.
tests/unit/core/test_runtime_query_service.py Adds unit coverage for RuntimeQueryService (events/logs/system status/WS).
tests/unit/core/test_data_sync_service.py Removes old DataSyncService unit tests (service deleted/renamed).
tests/integration/test_ws_endpoint.py Migrates WS endpoint tests to RuntimeQueryService.
tests/integration/test_web_ui_watcher.py Migrates integration watcher tests to RuntimeQueryService.
tests/integration/test_web_ui.py Updates UI integration tests for new DI + removes listener-metric expectations that depended on old stubs.
tests/integration/test_web_api.py Updates API integration tests for new DI; removes entity + old bus metric assertions.
tests/integration/test_telemetry_query_service.py Adds SQLite integration tests covering all telemetry query methods.
tests/integration/test_database_service.py Updates assertions to match aiosqlite.Row row factory behavior.
tests/integration/test_core.py Updates constructor wiring expectations for new services.
tests/integration/conftest.py Renames shared fixture to runtime_query_service and updates app wiring.
tests/e2e/conftest.py Updates e2e wiring/patches for runtime + telemetry stubs.
tests/TESTING.md Updates testing docs to reference runtime mocks instead of data-sync mocks.
src/hassette/web/ui/router.py Migrates full-page UI routes to new deps; uses telemetry for bus/app listener data.
src/hassette/web/ui/partials.py Migrates HTMX partial routes to new deps; routes now call telemetry/scheduler/runtime services.
src/hassette/web/ui/context.py Updates alert_context to accept RuntimeQueryService.
src/hassette/web/templates/partials/scheduler_jobs.html Switches link strategy to app_key/instance_index-based fields.
src/hassette/web/templates/partials/scheduler_history.html Switches owner link strategy to app_key/instance_index-based fields.
src/hassette/web/templates/partials/bus_listeners.html Updates template to render telemetry-format listener rows.
src/hassette/web/templates/partials/app_detail_listeners.html Removes instance-owner-map column/logic.
src/hassette/web/templates/partials/app_detail_jobs.html Removes instance-owner-map column/logic.
src/hassette/web/routes/ws.py Uses runtime_query_service for WS registration + system status.
src/hassette/web/routes/scheduler.py Reworks scheduler endpoints to use scheduler + telemetry deps.
src/hassette/web/routes/logs.py Reworks logs endpoint to use RuntimeDep.
src/hassette/web/routes/health.py Reworks health endpoint to use RuntimeDep.
src/hassette/web/routes/events.py Reworks events endpoint to use RuntimeDep.
src/hassette/web/routes/entities.py Deletes entity endpoints (no longer supported).
src/hassette/web/routes/bus.py Reworks bus endpoints to use TelemetryDep and removes old in-memory summary behavior.
src/hassette/web/routes/apps.py Reworks apps endpoints to use RuntimeDep.
src/hassette/web/dependencies.py Replaces DataSyncDep with RuntimeDep/TelemetryDep/SchedulerDep.
src/hassette/web/app.py Removes entities router registration.
src/hassette/web/CLAUDE.md Updates web-layer guidance to reference new dependency aliases.
src/hassette/test_utils/web_mocks.py Renames mock factory to create_mock_runtime_query_service and wires telemetry stubs.
src/hassette/test_utils/web_helpers.py Updates scheduler job fixture helper to use real trigger classes.
src/hassette/test_utils/init.py Re-exports updated mock factory name.
src/hassette/state_manager/state_manager.pyi Adjusts DomainStates iterator typing.
src/hassette/logging_.py Updates comments referencing runtime service as broadcaster.
src/hassette/core/web_ui_watcher.py Broadcasts dev-reload events via runtime_query_service.
src/hassette/core/web_api_service.py Waits on runtime service readiness (instead of data sync).
src/hassette/core/telemetry_query_service.py Adds real SQL-backed telemetry query service implementation.
src/hassette/core/scheduler_service.py Removes stub execution-history method.
src/hassette/core/runtime_query_service.py Renames/slims service to runtime-only functionality.
src/hassette/core/database_service.py Sets SQLite row_factory at connect time.
src/hassette/core/core.py Wires in new runtime + telemetry query services and removes data sync service.
src/hassette/core/bus_service.py Removes stub listener-metrics accessors.
src/hassette/config/config.py Updates config docs to refer to runtime event buffer.
design/specs/004-decompose-datasyncservice/tasks/WP02.md Adds completed work package documentation for telemetry queries + tests.
design/specs/004-decompose-datasyncservice/tasks/WP01b.md Adds completed work package documentation for web layer migration.
design/specs/004-decompose-datasyncservice/tasks/WP01.md Adds completed work package documentation for core service split.
design/specs/004-decompose-datasyncservice/spec.md Adds initial spec scaffold.
design/specs/004-decompose-datasyncservice/design.md Adds design doc describing split + migration plan.
CHANGELOG.md Documents the addition of runtime + telemetry services.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

…rialization

- Fix `app_detail_listeners.html` using `l.handler_name` → `l.handler_method`
- Rename `ListenerMetrics.handler_name` → `handler_method` (field + `to_dict()`) and
  `ListenerMetricsResponse.handler_name` → `handler_method` for consistency with DB column
- Add `l.id AS listener_id`, `l.app_key`, `l.instance_index` to `get_listener_summary()`
  SELECT so templates and the Pydantic model have the correct field names
- Replace `telemetry.get_job_summary()` calls in partials with live scheduler jobs
  (`scheduler_jobs_partial`, `app_detail_jobs_partial`, `instance_jobs_partial`) — the
  template expects live fields (name, next_run, cancelled) not historical aggregates
- `scheduler_history_partial` stubs with `[]` until per-execution query is available
- Extract `resolve_trigger()` into `web/utils.py` (neutral layer) and `job_to_dict()`
  into `web/ui/context.py`, eliminating the three duplicate `_job_to_dict` copies across
  `ui/router.py`, `ui/partials.py`, and `routes/scheduler.py`
- Fix test teardown: `db.close()` → `db_service.on_shutdown()` to drain write queue
- Update `make_listener_metric`, `test_metrics.py`, and `tests/TESTING.md` to use
  `handler_method` throughout
- Fix e2e conftest lambda to use `**_` instead of positional `_idx`/`_sid`,
  preventing TypeError when `get_listener_summary` is called with keyword args
- Fix job filter in `app_detail_page` and `app_instance_detail_page` to compare
  `j.owner == instance.owner_id` instead of `j.owner == app_key`; jobs now
  appear correctly in the app detail view
- Add `app_keys` context to scheduler and bus pages; rename filter `name="owner"`
  → `name="app_key"` so HTMX requests match the partial endpoints
- Replace `owner: str` with `app_key: str` + `instance_index: int = 0` in
  `ListenerMetricsResponse`, matching the shape `TelemetryQueryService` produces
- Add COALESCE defaults to duration aggregates in `get_listener_summary` and
  `get_job_summary` so NULL durations don't fail Pydantic validation
- Stub `get_job_history` to return `[]` unconditionally; `get_job_summary`
  returns per-job aggregates incompatible with `JobExecutionResponse`
- Fix `is defined` Jinja2 guards in scheduler_jobs, bus_listeners, and
  scheduler_history partials to use truthiness checks
- Update `make_listener_metric` factory to use `app_key`/`instance_index`
  instead of `owner`, aligning with production data contract
- Add TODO comments to three known-broken `j.owner == app_key` filters in
  `partials.py` (deferred to follow-up owner_id cleanup issue)
- Fix `DomainStates.__iter__` stub to use 3-param `Generator` type
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR completes the DataSyncService decomposition by introducing two focused services: RuntimeQueryService (in-memory/live UI state + WS broadcast) and TelemetryQueryService (SQLite-backed historical telemetry). It updates the web layer DI, routes, templates, and test infrastructure accordingly, and implements real SQL telemetry queries with integration coverage.

Changes:

  • Replace DataSyncService usage with RuntimeQueryService + TelemetryQueryService across core + web DI, routes, and templates.
  • Implement real SQLite queries in TelemetryQueryService and add integration tests validating all query methods.
  • Clean up related plumbing: remove old entity routes, update listener metrics naming (handler_method), and set SQLite row_factory once on connect.

Reviewed changes

Copilot reviewed 57 out of 57 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tests/unit/core/test_web_ui_watcher.py Updates watcher tests to use runtime_query_service.broadcast.
tests/unit/core/test_runtime_query_service.py New unit tests covering RuntimeQueryService retained behaviors.
tests/unit/core/test_data_sync_service.py Removes DataSyncService unit tests (service deleted/superseded).
tests/unit/bus/test_metrics.py Renames handler_namehandler_method in listener metrics tests.
tests/integration/test_ws_endpoint.py Updates WS integration tests to use RuntimeQueryService.
tests/integration/test_web_ui_watcher.py Updates integration watcher tests to use runtime_query_service.broadcast.
tests/integration/test_web_ui.py Updates UI integration tests for new deps and stubbed telemetry behavior.
tests/integration/test_web_api.py Updates API integration tests for new deps and changed bus/scheduler expectations.
tests/integration/test_telemetry_query_service.py New integration tests validating TelemetryQueryService SQL against real SQLite.
tests/integration/test_database_service.py Updates assertions to work with aiosqlite.Row row_factory.
tests/integration/test_core.py Updates core wiring expectations for new services.
tests/integration/conftest.py Switches shared fixture from data_sync_service to runtime_query_service.
tests/e2e/conftest.py Updates e2e stubs/mocks to new runtime/telemetry services and listener dict format.
tests/TESTING.md Updates testing docs to reference new mock helpers and names.
src/hassette/web/utils.py Adds shared trigger serialization helper (resolve_trigger).
src/hassette/web/ui/router.py Migrates UI pages to RuntimeDep/TelemetryDep/SchedulerDep; parallelizes telemetry fetch for bus page.
src/hassette/web/ui/partials.py Migrates HTMX partials to new deps; stubs out some telemetry/scheduler history paths.
src/hassette/web/ui/context.py Updates alert_context to runtime service; adds job_to_dict for templates.
src/hassette/web/templates/partials/scheduler_jobs.html Switches job link rendering to app_key/instance_index fields.
src/hassette/web/templates/partials/scheduler_history.html Switches history link rendering to app_key/instance_index fields.
src/hassette/web/templates/partials/bus_listeners.html Switches listener rendering to handler_method + app_key/instance_index.
src/hassette/web/templates/partials/app_detail_listeners.html Updates listener table to use handler_method and drops owner-map columns.
src/hassette/web/templates/partials/app_detail_jobs.html Drops owner-map columns and relies on serialized job fields.
src/hassette/web/templates/pages/scheduler.html Updates scheduler filter dropdown to pass app_key.
src/hassette/web/templates/pages/bus.html Updates bus filter dropdown to pass app_key.
src/hassette/web/routes/ws.py Switches WS endpoint to runtime_query_service.
src/hassette/web/routes/scheduler.py Reworks scheduler endpoints to query SchedulerService directly; stubs history.
src/hassette/web/routes/logs.py Switches logs endpoint to RuntimeDep.
src/hassette/web/routes/health.py Switches health endpoint to RuntimeDep.
src/hassette/web/routes/events.py Switches events endpoint to RuntimeDep.
src/hassette/web/routes/entities.py Removes entity routes entirely.
src/hassette/web/routes/bus.py Reworks bus endpoints to use TelemetryDep; stubs metrics summary.
src/hassette/web/routes/apps.py Switches apps endpoints to RuntimeDep.
src/hassette/web/models.py Updates listener response schema to app_key/instance_index + handler_method.
src/hassette/web/dependencies.py Replaces DataSyncDep with RuntimeDep/TelemetryDep/SchedulerDep.
src/hassette/web/app.py Removes entities router registration.
src/hassette/web/CLAUDE.md Updates web-layer guidance to new dependency aliases.
src/hassette/test_utils/web_mocks.py Renames mock factory to create_mock_runtime_query_service; wires telemetry stubs.
src/hassette/test_utils/web_helpers.py Updates listener metric helper signature; uses real trigger objects in job fixtures.
src/hassette/test_utils/init.py Re-exports updated mock helper names.
src/hassette/logging_.py Updates documentation/comments to reference RuntimeQueryService.
src/hassette/core/web_ui_watcher.py Broadcasts dev reload via runtime_query_service.
src/hassette/core/web_api_service.py Waits on RuntimeQueryService readiness instead of DataSync.
src/hassette/core/telemetry_query_service.py Adds DB-backed telemetry query service with real SQL implementations.
src/hassette/core/scheduler_service.py Removes stubbed execution history accessor.
src/hassette/core/runtime_query_service.py Renames/slims runtime UI aggregation service; adds readiness guards.
src/hassette/core/database_service.py Sets aiosqlite.Row row_factory once on connect.
src/hassette/core/core.py Wires new services as children and exposes new properties.
src/hassette/core/bus_service.py Removes stubbed in-memory listener metrics accessors.
src/hassette/config/config.py Updates docstring to reference RuntimeQueryService.
src/hassette/bus/metrics.py Renames handler_namehandler_method in metrics dataclass + serialization.
design/specs/004-decompose-datasyncservice/tasks/WP02.md Adds completed work package notes for telemetry query implementation/tests.
design/specs/004-decompose-datasyncservice/tasks/WP01b.md Adds completed work package notes for web DI/template migration.
design/specs/004-decompose-datasyncservice/tasks/WP01.md Adds completed work package notes for initial service split and cleanup.
design/specs/004-decompose-datasyncservice/spec.md Introduces spec scaffold for the feature.
design/specs/004-decompose-datasyncservice/design.md Adds the design doc capturing architecture and migration plan.
CHANGELOG.md Documents the service split and related web/telemetry changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

- get_job_summary: add `sj.id AS job_id`, `sj.app_key`, `sj.instance_index`
  to SELECT list for consistency with get_listener_summary (#334)
- bus_page: log BaseException results from asyncio.gather at WARNING instead
  of silently dropping them (#334)
- tests: assert job_id, app_key, instance_index in get_job_summary results
…uler

- Fix di_failures counter: change SQL '= DependencyError' to 'LIKE Dependency%'
  to match actual subclass names (DependencyInjectionError, DependencyResolutionError)
- Fix empty-string app_key handling: change 'is not None' to truthiness checks
  in partials.py and routes/scheduler.py so 'All Apps' dropdown works correctly
- Fix bus_listeners_partial and /api/bus/listeners returning [] when unfiltered:
  enumerate all app instances via gather pattern instead of returning empty list
- Extract gather_all_listeners() to web/utils.py, shared by bus_page, bus
  listeners partial, and bus listeners API endpoint
@NodeJSmith NodeJSmith merged commit fbc8652 into main Mar 15, 2026
10 checks passed
@NodeJSmith NodeJSmith deleted the worktree-next branch March 15, 2026 05:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants