Context
#225 fixed a 500 IntegrityError on push by resolving the store slug → store.id before the FK insert. The fix has a fallback: if `find_by_slug` returns nothing, the service tries `find_by_id` for backwards compat with older callers that may already pass a UUID.
```python
document-parser/services/chunk_service.py::push_to_store
store = await self._stores.find_by_slug(store_id)
if store is None:
# Maybe the caller already passed an id — accept that
# too for backwards compat with older callers.
store = await self._stores.find_by_id(store_id)
```
This works today because slugs are user-typed (`rh-corpus-v3`) and ids are UUIDs — they don't collide. But the fallback is implicit. A future user creating a store with slug equal to an existing store's UUID would shadow that store silently. Unlikely in practice but the contract is fuzzy.
Scope
- Either remove the `find_by_id` fallback entirely (slugs are the public API contract; passing an id is a private detail) — and update all callers to pass slugs.
- Or make the disambiguation explicit: detect UUID-shape via `uuid.UUID(store_id)` and dispatch on that.
- Update `push_to_store` docstring to spell out the chosen contract.
- Cover the chosen contract with a test (UUID-shaped slug, ambiguous string, etc.).
Out of scope
- Renaming `store_id` parameter — the wire format stays whatever the API ships.
- Slug uniqueness enforcement at the schema level (already enforced by `stores.slug UNIQUE`).
Acceptance criteria
Priority
P2 — works correctly today, the ambiguity is theoretical.
References
Context
#225 fixed a 500 IntegrityError on push by resolving the store slug → store.id before the FK insert. The fix has a fallback: if `find_by_slug` returns nothing, the service tries `find_by_id` for backwards compat with older callers that may already pass a UUID.
```python
document-parser/services/chunk_service.py::push_to_store
store = await self._stores.find_by_slug(store_id)
if store is None:
# Maybe the caller already passed an id — accept that
# too for backwards compat with older callers.
store = await self._stores.find_by_id(store_id)
```
This works today because slugs are user-typed (`rh-corpus-v3`) and ids are UUIDs — they don't collide. But the fallback is implicit. A future user creating a store with slug equal to an existing store's UUID would shadow that store silently. Unlikely in practice but the contract is fuzzy.
Scope
Out of scope
Acceptance criteria
Priority
P2 — works correctly today, the ambiguity is theoretical.
References