Skip to content

server: define async Store protocol (#306)#325

Merged
peteski22 merged 1 commit intomozilla-ai:mainfrom
nissessenap:issue-306-store-protocol
Apr 24, 2026
Merged

server: define async Store protocol (#306)#325
peteski22 merged 1 commit intomozilla-ai:mainfrom
nissessenap:issue-306-store-protocol

Conversation

@nissessenap
Copy link
Copy Markdown
Contributor

Summary

Defines the async Store protocol that both SqliteStore (#308) and the eventual PostgresStore will conform to. Pure interface — no implementations, no runtime wiring. Part of #257 / RFC #275, Phase 1 step (3).

Changes

  • Added server/backend/src/cq_server/store/_protocol.pyStore(typing.Protocol) with async def signatures covering every public method on RemoteStore today.
  • Moved store.pystore/__init__.py to make store a package (prep for Implement SqliteStore against Store protocol via Core helpers #308, which re-exports SqliteStore from the same package root). Pure rename: only change is .scoring/.tables..scoring/..tables relative-import fix.
  • Re-exported Store from cq_server.store so callers don't reach into the private _protocol module.
  • Added tests/test_store_protocol.py — structural TDD check that RemoteStore satisfies Store via @runtime_checkable + issubclass. The test docstring calls out the known limitation (runtime_checkable only checks attribute names, not sync-vs-async); once SqliteStore lands in Implement SqliteStore against Store protocol via Core helpers #308 the same test continues to pass against a genuinely async impl.

Scope deviation worth flagging

The issue said "No changes to existing `store.py`." The branch renames it to `store/init.py`. This is deliberate — #308 explicitly requires the `store/` package layout, and doing the move now avoids a churny second rename. Rename is behavior-preserving (99% similarity; only import paths adjusted).

Out of scope (intentionally deferred)

🤖 Generated with Claude Code

@nissessenap
Copy link
Copy Markdown
Contributor Author

Small note about the current _protocol.
Should we tighten some of the returns from list[dict[str, Any]] to TypedDicts to make the interface a bit stricter?
I kept the current scope of not chaging anything in this PR.

ending_queue/list_units share a uniform shape, get_user is stable.

The API-key methods are trickier because create_api_key, get_api_key_for_user, get_api_key_by_hash, and list_api_keys_for_user, each project a different subset of columns (plus get_api_key_by_hash joins in username), so that needs a design call: one TypedDict with NotRequired fields, or separate types per method?
Similarly, recent_activity is a discriminated union on type.

@peteski22 peteski22 self-assigned this Apr 24, 2026
Phase 1 step (3) of the RFC mozilla-ai#275 PostgreSQL-backend effort (epic mozilla-ai#257).
Pure interface definition: new `cq_server.store._protocol.Store` with
`async def` signatures covering every public method on today's
`RemoteStore`. No implementations, no runtime callers touched.

Because a subpackage and a module can't share a name, `store.py` moves
to `store/__init__.py` (rename preserves history; only the two
same-package relative imports change, `.scoring` -> `..scoring` and
`.tables` -> `..tables`). The RemoteStore class is otherwise untouched.
`@runtime_checkable` plus an `issubclass(RemoteStore, Store)` assertion
covers the structural acceptance criterion — Python's runtime Protocol
check inspects attribute names only, so sync RemoteStore satisfies the
async protocol today and future async `SqliteStore` (mozilla-ai#308) will keep
satisfying it.

Deliberately out of scope: `db_path` (SQLite-specific property) and
`__enter__`/`__exit__` (sync dunders; async `__aenter__`/`__aexit__`
land with the real async `SqliteStore` in mozilla-ai#308).

Closes mozilla-ai#306.
@peteski22 peteski22 force-pushed the issue-306-store-protocol branch from 5754294 to 7959031 Compare April 24, 2026 12:06
Copy link
Copy Markdown
Collaborator

@peteski22 peteski22 left a comment

Choose a reason for hiding this comment

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

LGTM 🙏🏼

@peteski22 peteski22 merged commit 10a4b80 into mozilla-ai:main Apr 24, 2026
5 checks passed
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