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

47 lines
2.4 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/` — 业务域与能力包
架构 §3.2:**单体不等于混乱**。这里的每个子目录都是一个边界,越界会被 CI 拦下。
## 目录含义
| 包 | 类型 | 内容 |
| --- | --- | --- |
| `domain/` | 纯逻辑层 | 领域模型与业务规则。**无 IO、无框架、可纯单测** |
| `shared/` | 基础设施 | 配置、日志、错误码、统一响应、DB、Redis、可观测 |
| `llm/` | AI 能力 | LLM 网关(已实现) |
| `retrieval/` `rules/` `memory/` | AI 能力 | 混合检索 / 规则引擎 / 记忆系统(占位) |
| `compliance/` | 业务域 | 统一合规出口(占位,CR-05/CR-06) |
| `identity/` `billing/` `task/` `agent/` | 业务域 | 已有实现 |
| `profile/` `report/` `tryon/` `kb/` `notify/` `wardrobe/` | 业务域 | 占位 |
每个业务域包的标准结构:
```
packages/<域>/
├─ __init__.py
├─ README.md 这个域负责什么、不负责什么
├─ service.py 对外唯一入口。其他域只能调这里
└─ repo.py SQL。只有本域可以 import
```
## 硬性规则(由 `make importlint` 机器校验)
1. **禁止跨域直接查表**。要用别的域的数据,调它的 `service`,不要 import 它的
`repo`,更不要在自己的 SQL 里 JOIN 别人的表。表名的域前缀(`id_` / `bl_` /
`tk_` / …)就是为将来拆库预留的边界。
2. **`packages/domain/` 必须保持纯净**。不许 import `fastapi`、`sqlalchemy`、
`httpx`、`redis`、`celery`,也不许 import `packages/shared`。放不进去说明
它不是领域逻辑,是应用逻辑,应该待在 `service.py`。
3. **`compliance` 不得依赖任何业务域**。它必须能被任何模块安全调用。
4. **`identity` 不得依赖任何其他业务域**。登录链路不能被业务拖累。
5. **AI 能力包(`llm` / `retrieval` / `rules`)不得依赖业务域**,也不得 import
`apps`。它们要能在 V2 原样拆成独立服务。
## 加一个新业务域时
1. 建目录,写 `README.md` 说明职责与不负责的事。
2. 在 `pyproject.toml` 的 `[tool.importlinter]` 契约里把它加进相应的
`layers` / `forbidden_modules` 列表 —— 新域默认没有约束,忘了加就等于没有边界。
3. 领域规则先写进 `packages/domain/<域>/` 并配单测,再写 `service.py`。
4. 表加域前缀,走 Alembic,迁移必须向后兼容(NFR-MAINT-06)。