Files
xsl 12583e9739 feat(shared): cross-cutting plumbing and pure domain layer
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.
2026-08-14 00:26:39 +08:00

41 lines
2.0 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `packages/shared/` — 横切基础设施
配置、日志、错误码、统一响应、数据库、Redis、可观测性。架构 §16.1。
| 模块 | 内容 |
| --- | --- |
| `config.py` | pydantic-settings 类型化配置,全部来自环境变量 |
| `errors.py` | 统一错误码(§9.2:4xxxx 客户端 / 5xxxx 服务端 / 6xxxx 外部依赖) |
| `response.py` | 统一响应信封 `{code, message, data, request_id, hint}` |
| `handlers.py` | FastAPI 异常处理器,保证任何异常都返回信封且不泄露堆栈 |
| `middleware.py` | 请求 ID / 追踪 ID、访问日志、HTTP 指标、`/v1` 路径别名 |
| `logging.py` | structlog JSON 日志 + **脱敏处理器** |
| `context.py` | 请求上下文(request_id / trace_id / user_id / task_id) |
| `db.py` | 异步 SQLAlchemy 引擎与会话 |
| `models.py` | ORM 表定义 |
| `redis_client.py` | Redis 连接 |
| `observability.py` | OTel tracing + Prometheus 指标注册表 |
## 能放什么
跨所有域复用、且不含任何业务判断的东西。
## 不能放什么
- **任何业务规则**。「配额够不够」属于 `packages/domain/billing`,
「任务能不能取消」属于 `packages/domain/task`。放进来就没人能纯单测了。
- 对具体业务域的 import。`shared` 在依赖层级的底部,反向依赖会立刻形成环。
## 日志脱敏不是可选项
`logging.py` 的脱敏是 structlog **处理器**,作用于每一条日志,没有 opt-in。
新增敏感字段时加进 `SENSITIVE_KEYS`,或用 `LOG_EXTRA_REDACT_KEYS` 环境变量。
NFR-SEC-03 / 架构 §11.2:手机号、UnionID、图片地址、诊断结论、令牌一律脱敏。
## 新增错误码
在 `ErrorCode` 加值,**同时**在 `ERROR_META` 加 message 和 hint。
测试 `test_every_error_code_has_metadata` 会强制这一点。
FR-BILL-07:配额相关文案里不能出现价格、购买、会员、升级字样,
`test_quota_hint_never_mentions_price_or_purchase` 会扫描全部文案。