Slice 50 - Index Read Views
Date: 2026-06-29
Scope#
Split read-only SQLite index queries out of the projection store.
Decisions#
- Keep
IndexStoreas the facade used byIndexService. - Keep projection ownership in
services/index/store.py: schema migration, source loading, freshness signatures, and writes intoindex.db. - Move read-only query/view construction into
services/index/views.py. - Return the same Pydantic models from reads:
SearchPageResult,PageView,TopicSummary,TopicDetail, andHealthReport. - Do not optimize refresh cost in this slice.
ensure_freshstill parses source markdown to compute the source signature.
Cosmic Python Transfer#
Cosmic Python chapter 12 recommends splitting read-only views from
state-changing command/event handlers even without full CQRS machinery.
CodeAlmanac's index.db is a derived read model, so the same smaller pattern
fits here:
class IndexStore:
def refresh(self, root):
...
def search(self, root, request):
with connect_index(index_db_path(root)) as connection:
return search_pages(connection, request)views.py reads the projection and maps rows into typed Pydantic models. It
does not load markdown, apply migrations, or run write SQL.
Files#
src/codealmanac/services/index/store.pysrc/codealmanac/services/index/views.pytests/test_architecture.py
Verification#
- Focused read-model, topic health, viewer service, CLI read, and architecture tests.
- Focused ruff over index services and related tests.
- Temp-repo CLI dogfood for
search,search --mentions,show --backlinks,topics show, andhealth. - Full pytest, full ruff, diff check, package build, and wheel inspection.