feat(ECR-041): OpsCMS Banner 薄写面(Write-Wave 首刀)
Admin POST/PUT + admin.cms.write/审计;C 端 GET /home/banners;首页投影回退静态 homeFeeds;migration 000051;不碰 FeedSlot/支付/UGC。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -238,7 +238,7 @@ UI **不出现「塔罗」**。禁止神谕吉凶、恐吓话术。
|
||||
| Phase D `[Ops]` | 商业加深:订单筛选 · 展示价 · 退款只读(**ECR-009** · Spec `ops-commerce.md`) |
|
||||
| Phase E `[Ops]` | 系统:RBAC · 封禁 · 推送占位(**ECR-010** · Spec `ops-system.md`) |
|
||||
| Phase D+ Contract | **Contract-First** 扩展目录:**ECR-013A…040**(RBAC/兑换码/问答运营/安全/危机/CMS/ExploreConfig 等)。见 `docs/WAVE0/` |
|
||||
| Phase F+ | 封禁细策略 · 真推送通道 · 更细权限矩阵;**UGC 仍 `[No]`**;真支付最后 |
|
||||
| Phase F+ / Write-Wave | **写面加深**(首刀 **ECR-041 Banner** · `docs/WAVE0/WRITE_WAVE_AUTHORIZATION.md`);封禁细策略 · 真推送;**UGC 仍 `[No]`**;**真支付最后** |
|
||||
|
||||
不计入 P1 Complete;不进入五 Tab。
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
| [ops-ai-core-config.md](ops-ai-core-config.md) | AI 核心配置 AICoreConfig | §7 | `admin-h5` `/ai` | Ops · **ECR-021** |
|
||||
| [ops-crisis-care.md](ops-crisis-care.md) | 危机关怀 CrisisCare | §7 | `admin-h5` `/crisis` | Ops · **ECR-022** |
|
||||
| [ops-knowledge-source.md](ops-knowledge-source.md) | AI 知识源 KnowledgeSource | §7 | `admin-h5` `/ai` | Ops · **ECR-023** |
|
||||
| [ops-banner.md](ops-banner.md) | OpsCMS Banner | §7 | `admin-h5` `/cms` | Ops · **ECR-024** |
|
||||
| [ops-banner.md](ops-banner.md) | OpsCMS Banner(只读基线) | §7 | `admin-h5` `/cms` | Ops · **ECR-024** |
|
||||
| [ops-banner-write.md](ops-banner-write.md) | OpsCMS Banner **写面** | §7 | admin CMS 写 · `GET /home/banners` | Write-Wave · **ECR-041** |
|
||||
| [ops-feed-slot.md](ops-feed-slot.md) | OpsCMS FeedSlot | §7 | `admin-h5` `/cms` | Ops · **ECR-025** |
|
||||
| [ops-scheduled-publication.md](ops-scheduled-publication.md) | OpsCMS ScheduledPublication | §7 | `/admin/cms/publications*` | Ops · **ECR-026** |
|
||||
| [ops-knowledge-chunk.md](ops-knowledge-chunk.md) | AICoreConfig KnowledgeChunk | §7 | `/admin/ai/knowledge-chunks*` | Ops · **ECR-027** |
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
# Feature Spec: OpsCMS · Banner 写面(Ops · ECR-041)
|
||||
|
||||
> Status: `Active`(**ECR-041 Closed** · Feature Complete)
|
||||
> Map: `§7 运营后台` · Capability: `OpsCMS` · BC: `Ops_CMS_NoUGC`
|
||||
> Parent: WAVE0-FROZEN · Write-Wave: `docs/WAVE0/WRITE_WAVE_AUTHORIZATION.md`
|
||||
> Predecessor: ECR-024 Closed(Banner 只读)
|
||||
> 关联:[ops-banner.md](ops-banner.md)(只读基线)· [ops-content.md](ops-content.md) · [home.md](home.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标
|
||||
|
||||
让运营可 **创建 / 更新 / 上下架** Banner;C 端首页对 `placement=home` 的 active Banner **生效**;写操作鉴权 + 审计;失败可回退静态。
|
||||
|
||||
验证 Write-Wave 首刀闭环,**不**做 FeedSlot、真支付、UGC。
|
||||
|
||||
## 2. In / Out
|
||||
|
||||
| In | Out |
|
||||
|----|-----|
|
||||
| Admin:Banner create / update / 设 `active` | **FeedSlot** 一切写与 API |
|
||||
| 加法权限 `admin.cms.write`(既有 RBAC) | soft-delete 物理删行(`system=true` 禁止删) |
|
||||
| C 端:`GET` active banners(至少 `placement=home`) | ScheduledPublication 写 · 外链任意 URL |
|
||||
| 首页推荐区:API Banner 投影优先,空则回退静态 `homeFeeds` | 把 FeedSlot 与 Banner 合并为一 ECR |
|
||||
| `admin_audit_logs` 记录写操作 | Crisis / Handoff / ContentSafety 写 · 真支付 · UGC |
|
||||
| OpenAPI · contract_diff · integration | 新权限子系统 · 改引擎分层 |
|
||||
|
||||
### 与 `homeFeeds` 的关系(诚实边界)
|
||||
|
||||
- ECR-008 将「首页 Feeds CMS」后置;表意信息流位属 **FeedSlot**(ECR-025 只读,写面另 ECR)。
|
||||
- **本切片**:用 **Banner(placement=home)** 驱动首页推荐区展示(投影字段见下);**不**写 `ops_feed_slots`。
|
||||
- 完整 Feeds 槽位运营(多 slot、排期)→ 后续 FeedSlot 写面 ECR。
|
||||
|
||||
## 3. Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `Banner` | `code` 唯一;`placement` ∈ {home,explore,ask};`active`;`system` |
|
||||
| 写语义 | upsert 字段;`active=false` = 下架;禁止 soft-delete 列/物理删 system 行 |
|
||||
| C 端投影 | 仅 `active=true`;按 `sort_order` 升序 |
|
||||
|
||||
### 首页投影映射(Banner → 原 homeFeeds 卡)
|
||||
|
||||
| homeFeeds 字段 | 来源 |
|
||||
|----------------|------|
|
||||
| `to` | `link_path`(须站内 `/` 相对路径) |
|
||||
| `title` | `title` |
|
||||
| `meta` | 可选:无则空串或固定「运营推荐」 |
|
||||
| `icon` / `tone` / `stat` / `tag` | 本切片可用缺省;**不**扩表除非 migration 明确(默认缺省,避免 scope creep) |
|
||||
|
||||
## 4. API
|
||||
|
||||
### Admin(既有前缀 `/api/v1/admin/cms`)
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/banners` · `/banners/{id}` | `admin.cms.read` | 保持 ECR-024 |
|
||||
| POST | `/banners` | `admin.cms.write` | 创建(code 唯一) |
|
||||
| PUT | `/banners/{id}` | `admin.cms.write` | 更新 title/placement/image_url/link_path/sort_order/active |
|
||||
| — | DELETE | — | **不做**(下架用 `active=false`) |
|
||||
|
||||
校验:`link_path` 若非空须以 `/` 开头、禁 `http(s):`;`placement` 枚举;`system=true` 行不可改 `code`、不可删。
|
||||
|
||||
### C 端
|
||||
|
||||
| Method | Path | Auth | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/api/v1/home/banners` | DeviceAuth(与 `/home/tools` 同级) | 仅 `active`;query `placement` 默认 `home` |
|
||||
|
||||
## 5. Permission / Audit
|
||||
|
||||
- Migration 授予 `super_admin`:`admin.cms.write`(加法码,非新 RBAC 模型)。
|
||||
- 每次 POST/PUT 写 `admin_audit_logs`(actor · action · target id/code · diff 摘要)。
|
||||
|
||||
## 6. Migration
|
||||
|
||||
- 若仅需权限种子:`000051_ops_banner_write`(以 TRACEABILITY Max+1 为准,编码时再锁)。
|
||||
- **表结构**:默认复用 `ops_banners`;本切片 **不**为 FeedSlot 改表。若投影缺省不够且 Human 未扩 scope,不得私自加列。
|
||||
|
||||
## 7. UI
|
||||
|
||||
| 端 | 行为 |
|
||||
|----|------|
|
||||
| admin-h5 `/cms` | Banner 列表 + 新建/编辑/上下架(只动 Banner;FeedSlot 仍只读展示可保留) |
|
||||
| user-h5 首页 | `GET /home/banners` → 推荐区;失败或空 → 静态 `homeFeeds` |
|
||||
|
||||
## 8. AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | POST 合法 Banner → list/get 可见 |
|
||||
| AC-F-02 | PUT `active=false` → C 端 list 不含 |
|
||||
| AC-F-03 | PUT `active=true` + placement=home → `GET /home/banners` 含该项 |
|
||||
| AC-F-04 | 重复 `code` → 4xx |
|
||||
| AC-F-05 | 非法 `link_path`(外链)→ 4xx |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 仅 read 无 write → POST/PUT 403 |
|
||||
| AC-A-01 | 写操作产生审计行 |
|
||||
| AC-C-01 | H5 首页:有 active home Banner 时推荐区非纯静态 |
|
||||
| AC-C-02 | API 失败时首页不白屏(回退静态) |
|
||||
| AC-O-01 | 不触碰 FeedSlot 写路径 · 无 soft-delete · 无支付 |
|
||||
|
||||
## 9. Non-goals(STOP 对齐)
|
||||
|
||||
FeedSlot 写 · ScheduledPublication 写 · UGC · 真支付 · soft-delete · Crisis/Handoff/ContentSafety 写 · 扩大为本 ECR 合并多概念。
|
||||
|
||||
## 10. Trace
|
||||
|
||||
- ECR: `docs/ECR/ECR-041-banner-write.md`
|
||||
- BD: `docs/BACKEND_DESIGN/BD-2026-041-banner-write.md`
|
||||
- PRODUCT_SPEC · CONTRACT_DIFF · TEST_REPORT · CODE_REVIEW(实现阶段)
|
||||
- Auth: `docs/WAVE0/WRITE_WAVE_AUTHORIZATION.md`
|
||||
@@ -1,13 +1,14 @@
|
||||
# Feature Spec: OpsCMS · Banner(Ops · ECR-024)
|
||||
# Feature Spec: OpsCMS · Banner(Ops · ECR-024 只读基线)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-024 Closed**)
|
||||
> Status: `Active`(**ECR-024 Closed** · 只读)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-023 Closed
|
||||
> Capability: `OpsCMS` · BC: `Ops_CMS_NoUGC`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
> 授权(只读队列):`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
> **写面:** [ops-banner-write.md](ops-banner-write.md)(**ECR-041** · Write-Wave)
|
||||
|
||||
## Non-goals
|
||||
## Non-goals(本只读 Spec)
|
||||
|
||||
Banner 写发布 · FeedSlot · ScheduledPublication · UGC · 真支付
|
||||
Banner 写发布(见 ECR-041)· FeedSlot · ScheduledPublication · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| 首页宫格 CRUD(最多约 24 项;默认 12) | 首页 Feeds 信息流 CMS(本 ECR 后置,仍用静态 `homeFeeds`) |
|
||||
| 首页宫格 CRUD(最多约 24 项;默认 12) | 首页 Feeds/推荐区运营:ECR-008 后置;**Banner 写面见 ECR-041**;完整 FeedSlot 写另 ECR |
|
||||
| 工具 path / icon 白名单校验 | 任意外链、自定义 SVG 上传 |
|
||||
| scales 列表 + 上架/下架 + 审计 | 新建量表题目编辑器 · 探索目录全量 CMS |
|
||||
| Admin「内容」页 | RBAC / 封禁 / 推送(Ops-E) |
|
||||
|
||||
Reference in New Issue
Block a user