This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
just --list (or read the Justfile) is the source of truth for recipes; all run via uv. Do not call pytest/ruff directly — use just.
just test [args]runs pytest without coverage; extra args pass through (e.g.just test tests/test_routes.py -k test_name).- The 100% coverage gate lives in
just test-ci(line) andjust test-branch(branch) — not injust test. just lintauto-fixes;just lint-ciis the non-fixing CI check (also validates planning changes).just check-planningvalidates planning changes;just indexprints the change listing.
Authoritative, code-current capability prose lives in
architecture/— one file per capability. When a change alters a capability's behavior, update the matchingarchitecture/<capability>.mdin the same PR — that promotion is what keepsarchitecture/true. The summary below is quick orientation only.
This is a single-module library (modern_di_litestar/main.py) that integrates modern-di with Litestar.
Key concepts:
ModernDIPlugin— a LitestarInitPluginthat wires amodern_di.Containerinto Litestar's lifecycle. Accepts an optionalautowired_groupslist ofmodern_di.Groupsubclasses; their providers are auto-registered as app-level Litestar dependencies keyed by attribute name.FromDI(provider)— returns a LitestarProvidethat resolves a provider from the request-scoped DI container. Accepts either anAbstractProviderinstance or a type.build_di_container— a Litestar dependency that creates a childContainerper request/websocket, scoped toREQUESTorSESSIONrespectively, and tears it down after the response.litestar_request_provider/litestar_websocket_provider—ContextProviderinstances that make the raw LitestarRequest/WebSocketobjects resolvable via DI.fetch_di_container(app)— retrieves the app-level container fromapp.state.
Data flow: App startup → ModernDIPlugin.on_app_init stores the root container in app.state → each request, build_di_container creates a child container with the request/websocket bound → FromDI callables resolve from that child container → child container closed on response teardown.
Type annotation: Use ty: ignore for type suppression (not # type: ignore).
Planning uses a portable two-axis convention — architecture/ (repo root) is
the living truth home and promotion target; planning/changes/ holds the
flat per-change files. Start at the
Quick path in planning/README.md
to choose a lane, create a change file, and ship — that file is the authoritative
spec. Run just check-planning to validate changes and just index to print
the change listing.