Repository navigation
feat(api): serve field lists from the resource-state read model - #333
Open
AlexAxthelm wants to merge 3 commits into
Open
AlexAxthelm wants to merge 3 commits into
AlexAxthelm wants to merge 3 commits into
Conversation
…-766) List and filter-options now read precomputed rows when the caller's licensed sources exactly match a permission profile and the read model is ready (built by this commit); otherwise they answer live, unchanged. At 50K resources list requests drop from ~2-3 s to under 10 ms. Each process caches readiness for up to 5 s, so most requests skip the lookup. Operators can switch the fast path off with a new `disabled` flag that rebuilds never clear, so a deploy's rebuild can't undo it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CD summary
|
| service | url | fqdn |
|---|---|---|
| api | open | pr-0333-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io |
| frontend | https://witty-mushroom-017a3dc1e-333.westus2.1.azurestaticapps.net | |
| stitch-llm | open | pr-0333-llm.purplegrass-c07d0a94.westus2.azurecontainerapps.io |
Database (1)
| db_name | postgres_host | postgres_port | postgres_db |
|---|---|---|---|
| pr_0333 | stitch-dev.postgres.database.azure.com |
5432 |
pr_0333 |
Jobs (2)
| job | image | postgres_db | api_url | auth_mode |
|---|---|---|---|---|
| db-migrations | ghcr.io/rmi/stitch-api:pr-0333@sha256:bace2c260dd0f56725148d0f001d91da340414dc729324414c0d7c4906551354 |
pr_0333 |
||
| seed | ghcr.io/rmi/stitch-seed:pr-0333@sha256:c78a579670b8320a6699326c1d2a676e72cba2cf43713b3a7ea4c9ae1eb25d43 |
https://pr-0333-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io/api/v1 |
stitch-client-bearer-token |
Images (3)
| build_time | commit_time | git_sha | image | image_digest |
|---|---|---|---|---|
| 2026-10-15T15:58:50Z | 2026-10-15T15:58:30Z | 8984d7a | ghcr.io/rmi/stitch-api:pr-0333 |
ghcr.io/rmi/stitch-api:pr-0333@sha256:bace2c260dd0f56725148d0f001d91da340414dc729324414c0d7c4906551354 |
| 2026-10-15T15:58:47Z | 2026-10-15T15:58:30Z | 8984d7a | ghcr.io/rmi/stitch-seed:pr-0333 |
ghcr.io/rmi/stitch-seed:pr-0333@sha256:c78a579670b8320a6699326c1d2a676e72cba2cf43713b3a7ea4c9ae1eb25d43 |
| 2026-10-15T15:58:50Z | 2026-10-15T15:58:30Z | 8984d7a | ghcr.io/rmi/stitch-stitch-llm:pr-0333 |
ghcr.io/rmi/stitch-stitch-llm:pr-0333@sha256:a196e5ec31933ca473730e0bb09ecb86446fd0be0bae9e4f78dcf5e771bbd9d3 |
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Cross-version repairs can leave mixed-version rows marked current, and cached readiness can expose incompatible replacements.
2 open findings
What changed in this PR
Builds on #332 by routing field lists and filter options through the precomputed read model when permissions and readiness allow, with live fallback.
Changes:
- Adds cached list and filter-options queries.
- Introduces a five-second readiness cache and persistent operator off switch.
- Adds parity, fallback, concurrency, and observability tests plus rollout documentation.
| File | Description |
|---|---|
| HACKING.md | Documents local rebuilds. |
| deployments/api/tests/observability/test_query_name_actions.py | Checks fast-path query labels. |
| deployments/api/tests/db/read_model/test_state.py | Tests disabled-state and validation behavior. |
| deployments/api/tests/db/read_model/test_read_path.py | Tests parity, fallback, caching, and HTTP responses. |
| deployments/api/tests/db/read_model/test_read_path_postgres.py | Tests PostgreSQL parity and page consistency. |
| deployments/api/tests/db/read_model/test_concurrency_postgres.py | Extends rebuild concurrency coverage. |
| deployments/api/tests/db/read_model/scenarios.py | Checks reads during rebuilds. |
| deployments/api/tests/conftest.py | Resets readiness caching between tests. |
| deployments/api/src/stitch/api/db/read_model/state.py | Adds readiness caching and invalidation. |
| deployments/api/src/stitch/api/db/read_model/rebuild.py | Adds disabled-state handling for rebuilds and repairs. |
| deployments/api/src/stitch/api/db/queries.py | Adds stored-state query builders. |
| deployments/api/src/stitch/api/db/og_field_resource_actions.py | Routes eligible reads through stored state. |
| deployments/api/src/stitch/api/db/model/og_field_resource_state.py | Adds the disabled flag. |
| deployments/api/README.md | Links the rollout runbook. |
| deployments/api/READ_MODEL.md | Documents operation, verification, and performance. |
| deployments/api/alembic/versions/2f2fb644b180_resource_state_disabled_flag.py | Migrates the disabled flag. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
A switched-off table built by commit A accepted a repair from commit B, leaving B's rows in a table still marked ready as built by A. --if-stale from A then saw nothing to redo, and switching the table back on served B's rows under A indefinitely. Apply the version guard whether or not the table is switched off: repair it from the image that built it, or rebuild it from the new one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An API process that cached "ready" in the last 5 seconds keeps reading the table, so a rebuild by other code during that window can hand it rows the new code just rewrote. Deploys already wait for the previous revision to stop serving first; say so where rebuilds are documented and where the cache is defined. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CD summary
|
| service | url | fqdn |
|---|---|---|
| api | open | pr-0333-api.purplegrass-c07d0a94.westus2.azurecontainerapps.io |
| frontend | https://witty-mushroom-017a3dc1e-333.westus2.1.azurestaticapps.net | |
| stitch-llm | open | pr-0333-llm.purplegrass-c07d0a94.westus2.azurecontainerapps.io |
Database (1)
| db_name | postgres_host | postgres_port | postgres_db |
|---|---|---|---|
| pr_0333 | stitch-dev.postgres.database.azure.com |
5432 |
pr_0333 |
Jobs (1)
| job | image | postgres_db |
|---|---|---|
| db-migrations | ghcr.io/rmi/stitch-api:pr-0333@sha256:a15bb99b2363b15ce64955371a39c359164a6b79504f0c227a43624633dcba60 |
pr_0333 |
Images (3)
| build_time | commit_time | git_sha | image | image_digest |
|---|---|---|---|---|
| 2026-10-16T09:49:13Z | 2026-10-16T09:48:57Z | 2552d4b | ghcr.io/rmi/stitch-api:pr-0333 |
ghcr.io/rmi/stitch-api:pr-0333@sha256:a15bb99b2363b15ce64955371a39c359164a6b79504f0c227a43624633dcba60 |
| 2026-10-16T09:49:11Z | 2026-10-16T09:48:57Z | 2552d4b | ghcr.io/rmi/stitch-seed:pr-0333 |
ghcr.io/rmi/stitch-seed:pr-0333@sha256:c03e1bf56f6817b03956b4c3333cbce24b732bf979c92e316eb2a33291639445 |
| 2026-10-16T09:49:15Z | 2026-10-16T09:48:57Z | 2552d4b | ghcr.io/rmi/stitch-stitch-llm:pr-0333 |
ghcr.io/rmi/stitch-stitch-llm:pr-0333@sha256:88aecc360245898097242584378cfa823e2494b39b46b9150638f3c331262d8d |
This was referenced Oct 16, 2026
Closed
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Fourth PR of splitting #324 into smaller PRs for ease of review. Builds on #332: this is the one where we actually see faster results, because we're wiring it into the read paths.
The list and filter-options endpoints start reading from the precomputed table (when it's ready, and the caller's permissions match one of the stored profiles), falling back to the existing live path otherwise.
It also adds an operator's "off switch" (
disabled) and a short per-process readiness cache, so the safety switch ships alongside the fast path. These are useful for comparison to the live coalescer for validity or performance testing, and settingdisabledin the DB should start returning results from the live path after a ~5s timeout (part of machinery to prevent needing to check read-state readiness on every request)Summary
Fourth PR in the STIT-766 read-model stack (builds on #332). List and filter-options now read precomputed rows when they can, taking typical list requests at ~50K resources from ~2–3 s to under 10 ms. Answers are identical either way.
When the fast path is used
All three must hold; otherwise the request is answered live, exactly as before:
disabled, below).The detail endpoint and per-field source listings are unchanged; they always compute live.
Read path (
og_field_resource_actions.py,queries.py)_query_live/_filter_options_live, whichqueryandfilter_optionscall when the fast path doesn't apply.ORDER BY.DISTINCTper field, each answered from its(permission_mask, field)index.resources.count+resources.list_page;resources.count+resources.list_ids+resources.list_hydrate;resources.filter_optionseither way.Readiness cache (
state.py)Operator switch-off (new migration
2f2fb644b180)UPDATE og_field_resource_state_status SET disabled = true;sends reads back to live within ~5 s.ready = falsealone would be undone by the next rebuild.SET disabled = false.--idsrepairs are allowed on a switched-off table, since nothing is served from it.Docs
READ_MODEL.md:--if-stalefrom the deployed image; feat(auth): add stitch-auth package (STIT-333, STIT-335) #5 automates this);HACKING.md: "Fast list reads locally".deployments/api/README.md: a pointer to the runbook.The stack
Until #5 lands, a deployed environment reads live until someone runs the rebuild by hand. That's safe, just slower.
Related issues
Part of: STIT-766
Replaces: #324 (split for review)
Testing
tests/db/read_model/test_read_path.py:q=search;tests/db/read_model/test_read_path_postgres.py(Postgres only): parity on real Postgres, including JSONB provenance key order, and that a page is picked and read in one statement.tests/db/read_model/test_state.py:--if-staledoesn't rebuild a current, switched-off table; the CLI warns;--idsis allowed;tests/observability/test_query_name_actions.py: the read-model list and filter-options labels.make checkpasses.alembicreports no differences from the models.Checklist
AI use: Claude Code split this out of #324 and wrote most of the code, tests and docs. I reviewed it before committing. Verified by the tests, migration checks and deliberate breakage check above.
🤖 Generated with Claude Code