docs(claude): record the deep-module principle for future development
This commit is contained in:
21
CLAUDE.md
21
CLAUDE.md
@@ -113,6 +113,27 @@ MinIO/Qdrant/SQLAlchemy client-construction code. Use ports only for
|
||||
external side effects/persistence — not around pure local functions.
|
||||
(ADR-0015)
|
||||
|
||||
### Prefer deep modules over shallow ones
|
||||
|
||||
When a package exposes several small pure functions that a caller must
|
||||
compose correctly every time (right dispatch, right order, right
|
||||
thread/async offload), give it one entry point that owns that composition,
|
||||
and keep the small functions internal — exported only where their own unit
|
||||
tests need them. A shallow interface (one whose surface is nearly as complex
|
||||
as its implementation) pushes a correctness obligation onto every call site;
|
||||
a deep one absorbs it once. Apply the deletion test when unsure: if deleting
|
||||
the wrapper would concentrate the composition logic back into every caller
|
||||
rather than just relocate it, the wrapper is worth having.
|
||||
|
||||
Worked example: `src/application/ingestion/` exposes `parse_and_chunk_document`
|
||||
as its only caller-facing entry point. It dispatches on source type and owns
|
||||
the `anyio.to_thread.run_sync` + `CapacityLimiter` offload ADR-0017 requires;
|
||||
`parse_docx`/`parse_csv`/`parse_xlsx`/`chunk_document` stay in the package,
|
||||
exported mainly for their own tests, not for outside callers to reach for
|
||||
directly. Follow this pattern in `application/` as new packages are added
|
||||
there — `points/`, `retrieval/`, `threads/` — rather than exposing their
|
||||
internals as the primary surface.
|
||||
|
||||
### Resource lifetime rules (ADR-0012)
|
||||
|
||||
- Application-lifetime objects (SQLAlchemy engine/sessionmaker, Qdrant client,
|
||||
|
||||
Reference in New Issue
Block a user