feat(domains): identity, billing, task services and domain placeholders

Billing implements reserve -> commit -> refund against bl_quota and bl_ledger
with row-level locking and idempotency keys; the refund commits on its own
transaction so a failed request cannot silently keep a user's quota. Task
implements the unified task centre over the state machine. Identity issues and
resolves users. Remaining domains are placeholders whose READMEs state what
belongs there and what must not.
This commit is contained in:
xsl
2026-08-14 00:26:39 +08:00
parent 54dc741811
commit 7c67506474
36 changed files with 1213 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
"""统一合规出口 — interface only (架构文档 §7.5, CR-05, CR-06).
**所有对外生成物必须经过 ``publish_asset()``,没有例外。** The signature is
fixed here so that business code written against it does not have to change when
the implementation lands (T-P1-22 / T-P1-23).
Nothing in this package may import a business domain — it must be safe to call
from anywhere (架构文档 §4.2 禁止的依赖). import-linter enforces that.
Not implemented on purpose; implementing it half-way is worse than not having
it, because a half-working moderation call looks like a working one:
1. 内容审核 (fail-close: 审核服务不可用则拒绝发布) — 腾讯云 IMS/TMS
2. 27 位内容编号生成与 ``cp_content_registry`` 登记
3. 显式标识: 图片可见「AI 生成」水印 / 文本提示语
4. 隐式标识: 文件元数据 (属性信息 + 服务提供者编码 + 内容编号)
5. 上传目标 COS 桶并返回签名地址
必须专门测试的点 (§7.5): 图片经 CDN、缩略图处理、客户端保存与再次分享后,
元数据是否仍然存在。很多图片处理链路会剥离 EXIF/XMP。
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Literal
ContentType = Literal["image", "text", "pdf"]
ModerationSuggestion = Literal["pass", "review", "block"]
_NOT_IMPLEMENTED = (
"compliance is a structural placeholder (T-P1-22 / T-P1-23). "
"No generated content may be released to users until 审核 + 水印 + 元数据 + "
"内容编号登记 are all in place — CR-05/CR-06 are 不可裁剪."
)
@dataclass(frozen=True, slots=True)
class ContentRef:
ref_type: str
ref_id: str
@dataclass(frozen=True, slots=True)
class ModelInfo:
provider: str
model: str
prompt_id: str | None = None
prompt_version: str | None = None
@dataclass(frozen=True, slots=True)
class PublishedAsset:
content_code: str
url: str
moderation: ModerationSuggestion
async def moderate(text: str) -> ModerationSuggestion:
"""审核不可降级:服务不可用时按拦截处理 (fail-close, 架构文档 §11.4)."""
raise NotImplementedError(_NOT_IMPLEMENTED)
async def publish_asset(
raw: bytes | str,
content_type: ContentType,
ref: ContentRef,
model_info: ModelInfo,
) -> PublishedAsset:
raise NotImplementedError(_NOT_IMPLEMENTED)