fix: resolve owner_id/app_key mismatch in scheduler job filters and DB recording#336
fix: resolve owner_id/app_key mismatch in scheduler job filters and DB recording#336jessica-claude[bot] wants to merge 6 commits intomainfrom
Conversation
…B recording (#335) Listener.owner and ScheduledJob.owner stored the resource's owner_id (unique_name) but were incorrectly passed as app_key to the DB registration layer, causing all job/listener filters in the web UI and API to silently return empty results. Changes: - Rename .owner to .owner_id on Listener, ScheduledJob, ListenerMetrics, and API response models for clarity - Add explicit app_key and instance_index fields to Listener and ScheduledJob, propagated from the parent App at creation time - Fix BusService/SchedulerService registration to use the correct app_key and instance_index (not owner_id and hardcoded 0) - Add guard to skip DB registration for non-App owners (e.g., RuntimeQueryService's internal Bus) - Fix 3 HTMX partial filters and 1 API endpoint to filter on j.app_key instead of j.owner - Add instance_index filtering to instance_jobs_partial - Update Jinja2 templates for the field rename
There was a problem hiding this comment.
Pull request overview
Fixes a long-standing identity mismatch where in-memory owner/owner_id values (resource unique_name) were incorrectly used as app_key for DB registration and web/API filtering, causing scheduler job and listener views to return empty results.
Changes:
- Renames
owner→owner_idonListener,ScheduledJob,ListenerMetrics, and relevant web/API response shapes. - Adds
app_keyandinstance_indextoListener/ScheduledJob, propagates these fromAppviaBus/Scheduler, and updates DB registration to persist the correctapp_key/instance_index(skipping registration whenapp_keyis empty). - Updates web UI partials/pages/templates and API filters/serialization to use the correct identity fields; expands unit/integration coverage and adds design/spec documentation.
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_scheduler_job_names.py | Updates ScheduledJob construction to use owner_id. |
| tests/unit/bus/test_metrics.py | Renames ListenerMetrics constructor/serialization assertions to owner_id. |
| tests/integration/test_web_job_filters.py | Adds integration tests covering partial and API scheduler-job filtering by app_key and instance. |
| tests/integration/test_scheduler.py | Updates ScheduledJob usage to owner_id; adds coverage for new ScheduledJob fields and DB registration guard behavior. |
| tests/integration/test_registration.py | Adds integration tests verifying DB registration uses app_key/instance_index and skips non-App owners. |
| tests/integration/test_listeners.py | Updates Listener.create calls to owner_id; adds coverage for new Listener fields. |
| tests/integration/test_bus.py | Adjusts listener-registration test to ensure app identity is present for DB registration path. |
| tests/integration/test_apps.py | Updates Listener.create calls to owner_id. |
| src/hassette/web/ui/router.py | Fixes page-level job filtering to use j.owner_id after rename. |
| src/hassette/web/ui/partials.py | Fixes HTMX job partial filtering to use j.app_key (and instance index where applicable). |
| src/hassette/web/ui/context.py | Renames job template context field to owner_id (and currently passes app identity into templates). |
| src/hassette/web/templates/partials/scheduler_jobs.html | Updates template to display owner_id instead of owner. |
| src/hassette/web/routes/scheduler.py | Fixes API job filtering by app_key and serializes owner_id. |
| src/hassette/web/models.py | Renames API response fields owner → owner_id for scheduler job / execution models. |
| src/hassette/test_utils/web_helpers.py | Updates scheduler-job fixture helper to emit owner_id, app_key, and instance_index. |
| src/hassette/scheduler/scheduler.py | Populates ScheduledJob app_key/instance_index from parent App; renames ctor arg to owner_id. |
| src/hassette/scheduler/classes.py | Renames ScheduledJob field to owner_id; adds app_key/instance_index. |
| src/hassette/core/scheduler_service.py | Registers jobs using job.app_key/job.instance_index and skips DB registration when app_key is empty; updates owner tracking to owner_id. |
| src/hassette/core/bus_service.py | Registers listeners using listener.app_key/listener.instance_index and skips DB registration when app_key is empty; updates owner tracking to owner_id. |
| src/hassette/bus/metrics.py | Renames ListenerMetrics field/key to owner_id. |
| src/hassette/bus/listeners.py | Renames Listener field/arg to owner_id; adds app_key/instance_index. |
| src/hassette/bus/bus.py | Populates Listener app_key/instance_index from parent App; renames ctor arg to owner_id. |
| design/specs/005-fix-owner-app-key-mismatch/tasks/WP01.md | Documents dataclass rename and new identity fields. |
| design/specs/005-fix-owner-app-key-mismatch/tasks/WP02.md | Documents DB registration changes and non-App guard. |
| design/specs/005-fix-owner-app-key-mismatch/tasks/WP03.md | Documents web/API filter fixes and response model rename. |
| design/specs/005-fix-owner-app-key-mismatch/tasks/WP04.md | Documents final test/pyright verification and grep cleanup steps. |
| design/specs/005-fix-owner-app-key-mismatch/spec.md | Adds feature spec describing the mismatch, goals, and acceptance criteria. |
| design/specs/005-fix-owner-app-key-mismatch/design.md | Adds design write-up describing propagation, registration guard, and filter strategy. |
| CHANGELOG.md | Notes the fix for job/listener filtering via corrected identity handling. |
💡 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 Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #336 +/- ##
==========================================
+ Coverage 80.01% 80.08% +0.06%
==========================================
Files 141 141
Lines 10034 10052 +18
Branches 985 987 +2
==========================================
+ Hits 8029 8050 +21
+ Misses 1610 1605 -5
- Partials 395 397 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…tions The job name "my_app_job" was a substring of "my_app_job_i1", making assertions like `"my_app_job" not in body` always false when i1 was present. The weak assertion on line 106 was effectively a no-op. Rename instance-0 job from "my_app_job" to "my_app_job_i0" so all substring checks are unambiguous.
There was a problem hiding this comment.
Pull request overview
This PR resolves an identity mix-up where owner (an instance-level owner_id) was incorrectly used as app_key for DB registration and web/API filtering, causing scheduler job and listener views to return empty results. It renames owner → owner_id, introduces explicit app_key/instance_index fields on in-memory dataclasses, updates registration to persist the correct identity, and adjusts web/UI/API layers plus tests accordingly.
Changes:
- Rename
ownertoowner_idacross core dataclasses (Listener, ScheduledJob, ListenerMetrics) and web response/model serialization. - Add/propagate
app_key+instance_indexto Listener/ScheduledJob; update BusService/SchedulerService DB registration to use them and skip DB registration for non-App owners (app_key == ""). - Fix web UI partials and API scheduler job filtering to compare against
app_key(and instance index where applicable); update templates and add integration tests.
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_scheduler_job_names.py | Update ScheduledJob construction to use owner_id=. |
| tests/unit/bus/test_metrics.py | Update ListenerMetrics construction + dict assertions to owner_id. |
| tests/integration/test_web_job_filters.py | New integration tests for HTMX partials + API job filtering and owner_id response field. |
| tests/integration/test_scheduler.py | Update ScheduledJob owner_id and add tests for app_key/instance_index; adjust DB registration test setup. |
| tests/integration/test_registration.py | New integration tests validating DB registrations use app_key/instance_index and empty app_key skips registration. |
| tests/integration/test_listeners.py | Update Listener.create to use owner_id=; add Listener app_key/instance_index tests. |
| tests/integration/test_bus.py | Adjust listener registration test to ensure non-empty app_key so DB registration path is exercised. |
| tests/integration/test_apps.py | Update Listener.create calls to use owner_id=. |
| src/hassette/web/ui/router.py | Update in-memory page filtering from j.owner to j.owner_id. |
| src/hassette/web/ui/partials.py | Fix partial filters to use j.app_key (and j.instance_index for instance jobs). |
| src/hassette/web/ui/context.py | Rename serialized field from owner to owner_id for template contexts. |
| src/hassette/web/templates/partials/scheduler_jobs.html | Update template to display job.owner_id instead of job.owner. |
| src/hassette/web/routes/scheduler.py | API serialization uses owner_id; API filter uses j.app_key. |
| src/hassette/web/models.py | Rename API response model fields owner → owner_id. |
| src/hassette/test_utils/web_helpers.py | Update job fixture helper to emit owner_id and add app_key/instance_index. |
| src/hassette/scheduler/scheduler.py | Populate ScheduledJob app_key/instance_index from parent; rename owner → owner_id. |
| src/hassette/scheduler/classes.py | ScheduledJob field rename to owner_id; add app_key/instance_index; update __repr__. |
| src/hassette/core/scheduler_service.py | Use job.app_key/job.instance_index for DB registration; skip registration when app_key is empty; update owner-based queue removal to owner_id. |
| src/hassette/core/bus_service.py | Use listener.app_key/listener.instance_index for DB registration; skip registration when app_key is empty; update router owner tracking to owner_id. |
| src/hassette/bus/metrics.py | ListenerMetrics field rename to owner_id; update dict serialization key. |
| src/hassette/bus/listeners.py | Listener field rename to owner_id; add app_key/instance_index; update Listener.create signature and __repr__. |
| src/hassette/bus/bus.py | Pass owner_id and propagate app_key/instance_index from parent when creating listeners. |
| design/specs/005-fix-owner-app-key-mismatch/tasks/WP04.md | Work package doc for final test+typecheck cleanup. |
| design/specs/005-fix-owner-app-key-mismatch/tasks/WP03.md | Work package doc for web/API layer filter fixes + model rename. |
| design/specs/005-fix-owner-app-key-mismatch/tasks/WP02.md | Work package doc for DB registration fixes and non-App guard. |
| design/specs/005-fix-owner-app-key-mismatch/tasks/WP01.md | Work package doc for core dataclass changes and propagation. |
| design/specs/005-fix-owner-app-key-mismatch/spec.md | Spec documenting the root cause and acceptance criteria. |
| design/specs/005-fix-owner-app-key-mismatch/design.md | Design detailing identity separation and propagation/registration strategy. |
| CHANGELOG.md | Changelog entry describing the fix for UI/API filters and DB recording mismatch. |
💡 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.
Both test_scheduler.py and test_bus.py mutate parent.app_key and parent.index before the try block but only reset app_key in finally. Add the missing parent.index = 0 reset to both.
Summary
Listener.ownerandScheduledJob.ownerstored the resource'sowner_id(unique_name like"MyApp.MyApp.0") but were incorrectly passed asapp_keyto DB registration, soTelemetryQueryServicequeries never matched. This PR adds explicitapp_keyandinstance_indexfields to both dataclasses, fixes registration inBusService/SchedulerService, and corrects all 3 HTMX partial filters + 1 API endpoint..ownerto.owner_idonListener,ScheduledJob,ListenerMetrics, and API response models to prevent future confusion between the in-memory ownership key and the DB identity key.RuntimeQueryService's internal Bus) — these internal listeners have no telemetry value.Closes #335