Appearance
agreement — 协议发布(1 端点)
前缀:
/api/v1/admin/agreement/权限:CONFIG_WRITE(super + it)—— 协议归系统配置类,走 config 权限位 代码:src/app/agreement/interface/api/agreement_api.py+application/usecase.py公开读侧(C 端契约)见 frontend · agreement
3.13.1 update —— 发布协议(更新内容)
PATCH /api/v1/admin/agreement/{type} · 权限 CONFIG_WRITE
一句话:更新用户协议/隐私政策正文并发布 —— version 服务端自增(审计锚点), html 格式入库前经服务端白名单 sanitize(唯一通道)。
Path 参数:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | ✔ | user_agreement(用户协议)| privacy(隐私政策)—— 白名单外 → 400「type 必须为 […]」 |
Body:
| 字段 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
title | string | ✔ | — | 协议标题(≤128 字符;空白 → 400) |
content | string | ✔ | — | 正文(空白 → 400) |
content_format | string | ⬜ | "plain" | plain(纯文本 \n\n 分段 — 存量口径)| html(富文本 — 保存前自动 sanitize)。枚举外 → 400 |
响应(data = 更新后的现行版):
jsonc
{
"type": "user_agreement",
"title": "沐禾健康用户服务协议",
"content": "<h2>…</h2><p>…</p>", // html 格式时为已 sanitize 的 HTML
"version": 5, // 服务端自增(每次发布 +1)
"updated_at": "2026-09-24T05:26:26",// snake_case(全项目唯一 — 见公开读侧说明)
"content_format": "html"
}curl
bash
curl -s -X PATCH "$BASE_URL/api/v1/admin/agreement/user_agreement" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "X-Env: Prd" \
-H 'Content-Type: application/json' \
-d '{"title":"用户协议","content":"<p>正文</p>","content_format":"html"}'⚠️ 三条纪律
- X-Env 双库:不带
X-Env时缺省落 dev 库 —— 后台发布正式版必须带X-Env: Prd(或经 admin Web 的切换器操作)。 - sanitize 白名单(
content_format=html时,服务端强制):- 允许标签:
h1-h4 / p / br / hr / strong / b / em / i / u / s / sub / sup / span / ul / ol / li / blockquote / table 族 / a / img - 属性逐标签白名单:
a→href/target/title;img→src/alt/width/height;th/td→colspan/rowspan href/src仅放http(s):///#/mailto:(javascript:拒)script/style/iframe/object/embed/svg/math连内容整块丢弃;style属性一律剥
- 允许标签:
- plain 直存不清洗(存量语义);html 才过清洗 —— 前端(admin Web)保存恒以 html 提交。
发布后的可见性
公开读端点(免登录)立即返回新版本 —— C 端按 content_format 分支渲染 (plain 按段 / html 走 rich-text 组件)—— 详见 frontend · agreement。