feat: add standards wiki, MCP registry, and app template

This commit is contained in:
2026-10-11 22:09:30 +05:30
parent 1ef2efbeda
commit 1208945e1d
155 changed files with 24512 additions and 7 deletions

View File

@@ -0,0 +1,89 @@
# Composition Root
## Summary
All wiring happens in exactly one module. It builds a **flat resource
registry** and exposes it to the HTTP layer and to scripts.
---
## The resource registry
`init.py` returns a plain `dict[str, Any]`. Keys follow two conventions:
- `<resource>_repo` — a repository adapter for a resource.
- `<resource>_svc` — a service for a resource.
Plus named infrastructure adaptors:
- `http_cache_store` — response cache backend.
- `progress_bus` — progress/event bus.
- `<vendor>_<kind>` — fetchers, clients, stores.
The API stores the dict on `app.state.resources` during lifespan startup.
Handlers read from it; nothing imports concrete adapters.
## Shape
```python
_resources: dict = {}
_initialized = False
async def init(settings=None) -> dict:
global _initialized
if _initialized:
return _resources
await setup_database(uri=settings.mongo_uri, db_name=settings.mongo_db)
# 1. leaf repositories
user_repo = create_user_repo()
# 2. dependent repositories (dependencies passed by keyword)
wallet_repo = create_wallet_repo(user_repo=user_repo)
# 3. services (build via the DI library, injecting the repo)
_resources["user_repo"] = user_repo
_resources["wallet_repo"] = wallet_repo
_resources["user_svc"] = get_user_service(user_repo)
_resources["wallet_svc"] = get_wallet_service(wallet_repo)
# 4. infrastructure adaptors (optional)
_resources["http_cache_store"] = HttpCacheStore(...)
_resources["progress_bus"] = ProgressEventBus()
_initialized = True
return _resources
async def shutdown() -> None:
global _initialized
await close_stores(_resources)
await shutdown_database()
_resources.clear()
_initialized = False
```
## Typed accessors
Expose a `get_svc(name)` helper with one `@overload` per key so scripts get
typing without importing concrete classes:
```python
@overload
def get_svc(name: Literal["user_svc"]) -> UserService: ...
@overload
def get_svc(name: Literal["wallet_svc"]) -> WalletService: ...
def get_svc(name: str):
return _resources[name]
```
Also expose `get_db()` (raw database handle) and pure helpers such as
`compute_fingerprint(payload)` (canonical hash used for deduplication).
## Rules
- `init()` is **idempotent**.
- The composition root is the only place that imports concrete adapters.
- Handlers never call `init()`; they read `request.app.state.resources`.
- Scripts call `init()` / `shutdown()` around their work.