Typed pydantic-settings config, structlog JSON logging with request/trace id propagation and redaction of phone numbers, tokens and face keys, the unified response envelope and error-code table from 架构文档 §9.2, async SQLAlchemy session management, ORM models for the eight foundation tables, and the OpenTelemetry/Prometheus wiring. packages/domain stays pure logic -- snowflake ids, the quota three-phase protocol and the tk_task state machine -- so it can be tested without a database and is held to mypy strict.
40 lines
1.5 KiB
Markdown
Executable File
40 lines
1.5 KiB
Markdown
Executable File
# `packages/domain/` — 纯领域逻辑
|
||
|
||
架构 §3.2 硬性规则 2:**领域逻辑放在这里,不依赖 FastAPI、不依赖数据库会话,
|
||
可纯单元测试。**
|
||
|
||
## 能放什么
|
||
|
||
- 数据类与值对象(配额状态、任务状态、诊断维度…)
|
||
- 判定与计算(配额是否够、状态能否流转、置信度冲突消解、色差计算…)
|
||
- 纯函数、不可变数据结构
|
||
|
||
## 绝对不能放什么
|
||
|
||
- `import fastapi` / `sqlalchemy` / `httpx` / `redis` / `celery`
|
||
- `import packages.shared`(连日志和配置都不行)
|
||
- 任何 IO:读文件、发请求、查库、读环境变量
|
||
- `async def` 里真的 await 了 IO 的东西
|
||
|
||
违反会被 import-linter 的 `packages.domain is pure` 契约在 CI 拦下。
|
||
|
||
## 为什么这么严
|
||
|
||
这是 AI 大量写代码时唯一还能快速验证正确性的地方 —— 没有 mock、没有
|
||
fixture、没有容器,几毫秒跑完几百个用例。一旦让 IO 渗进来,这个性质就没了,
|
||
后面所有业务规则的测试都会退化成集成测试。
|
||
|
||
## mypy strict
|
||
|
||
本目录与 `packages/llm/` 一起,是 mypy **strict** 模式覆盖的范围
|
||
(架构 §16.2)。所有函数必须有完整类型注解。
|
||
|
||
## 现有内容
|
||
|
||
| 模块 | 内容 |
|
||
| --- | --- |
|
||
| `ids.py` | 雪花 ID 生成(§6.1 原则 2) |
|
||
| `errors.py` | 纯领域异常,适配层负责翻译成 `AppError` |
|
||
| `billing/quota.py` | 配额三段式的算术与周期键(§7.4) |
|
||
| `task/state.py` | `tk_task` 状态机(§6.2) |
|