Compare commits
111
Commits
7ab9add5dd
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7155b8b53a | ||
|
|
db4d118f9a | ||
|
|
fc53be22f8 | ||
|
|
e7290ed726 | ||
|
|
db3669c595 | ||
|
|
580ba85b61 | ||
|
|
57687de360 | ||
|
|
f4bd57ce1b | ||
|
|
9d4fb52d29 | ||
|
|
96292d0e95 | ||
|
|
635a83fe11 | ||
|
|
ebc2d3ad80 | ||
|
|
8d856fb56c | ||
|
|
d33a25a663 | ||
|
|
c693ac4bbc | ||
|
|
e0f605558b | ||
|
|
aa197b719b | ||
|
|
580f5ea3f0 | ||
|
|
69cb99600f | ||
|
|
1db5fcc018 | ||
|
|
258deb0184 | ||
|
|
b3fe4363fd | ||
|
|
fa8b0ba963 | ||
|
|
0158036341 | ||
|
|
dc93999f9e | ||
|
|
87b463b2bb | ||
|
|
fcc7667ba3 | ||
|
|
19091bff12 | ||
|
|
77907f79ee | ||
|
|
2b295472a4 | ||
|
|
f492088237 | ||
|
|
cd3ac2c9ab | ||
|
|
ec20e9744e | ||
|
|
aff6621ff8 | ||
|
|
56f661748a | ||
|
|
655141980a | ||
|
|
9707b72808 | ||
|
|
ad45d17dff | ||
|
|
d81e8364cc | ||
|
|
b7b0b18802 | ||
|
|
0d50c0ee73 | ||
|
|
62cd8c45dd | ||
|
|
4889ff5916 | ||
|
|
89756f65b4 | ||
|
|
13860bf1ef | ||
|
|
5ceb3ce749 | ||
|
|
1026cd0596 | ||
|
|
e9c11cdf1d | ||
|
|
432c090046 | ||
|
|
e955f1e6a2 | ||
|
|
63742c1d66 | ||
|
|
5de9a7bbe5 | ||
|
|
b34b4f281f | ||
|
|
5c462ecb2a | ||
|
|
0fa6da2446 | ||
|
|
bd9e13497f | ||
|
|
57acfa6105 | ||
|
|
ebc93b6c7e | ||
|
|
09b9c4daab | ||
|
|
45e98f6872 | ||
|
|
aad6cdf7ea | ||
|
|
487bee78d1 | ||
|
|
01063208a1 | ||
|
|
447fb6da16 | ||
|
|
58eef7c02b | ||
|
|
24a115297b | ||
|
|
0d4bc5054e | ||
|
|
b904e6b04f | ||
|
|
271e312669 | ||
|
|
5846d39d97 | ||
|
|
e6740a0326 | ||
|
|
00d9ed5610 | ||
|
|
1f572c4151 | ||
|
|
c1a8a58488 | ||
|
|
78857d5510 | ||
|
|
b91806ba80 | ||
|
|
8c50b3d925 | ||
|
|
e32466357d | ||
|
|
f51b2524c5 | ||
|
|
32ac559385 | ||
|
|
ac1aec857d | ||
|
|
bf1ae8bc53 | ||
|
|
dd4d644eaa | ||
|
|
de224184a6 | ||
|
|
4b5e5bc63d | ||
|
|
140b08ca01 | ||
|
|
22f9e358ae | ||
|
|
93227d3316 | ||
|
|
e270a38393 | ||
|
|
cae3380cbf | ||
|
|
de025d72bc | ||
|
|
c81f57a7d1 | ||
|
|
37b91e51b8 | ||
|
|
00a798bd85 | ||
|
|
1c157a0e46 | ||
|
|
61ae3b0451 | ||
|
|
1afda1d389 | ||
|
|
1eeb0b00e7 | ||
|
|
0e26aabef8 | ||
|
|
882c01d81a | ||
|
|
e25cd94b0c | ||
|
|
f75b42397f | ||
|
|
b5a05941d9 | ||
|
|
85ed0901bb | ||
|
|
27f27a1cb2 | ||
|
|
d33c8fdfe9 | ||
|
|
0ee4d4f5ae | ||
|
|
31a0ec721a | ||
|
|
e58a24ddd2 | ||
|
|
d48e95d42c | ||
|
|
ca3b13554c |
@@ -0,0 +1,29 @@
|
||||
# ADR-0008 — Go 为唯一用户后台,咨询域过渡反代
|
||||
|
||||
- Status: Accepted
|
||||
- Date: 2026-09-14
|
||||
- Tags: identity, miniprogram, consult, gateway
|
||||
|
||||
## Context
|
||||
|
||||
愈心谷 C 端同时打两套后台:咨询/测评在 Java + MySQL,愈心魔方在 Go + PostgreSQL。
|
||||
`wx.login` 的 `code` 只能用一次,无法先后换两套 token。小程序需要单一身份与单一请求入口。
|
||||
|
||||
## Decision
|
||||
|
||||
1. **Go + PostgreSQL 是唯一用户身份源。** 微信 openid / 手机号写在 `users`。
|
||||
2. **Java 过渡期为被调方**:Go 用 openid/phone 调内网 `issue-mini-app` 换 Java Redis token,并反代 `/app-api`、`/admin-api`。
|
||||
3. **咨询业务表本 ADR 不迁**;支付与档期另开 ECR。
|
||||
4. **Admin 登录独立**,不走本决策。
|
||||
|
||||
## Consequences
|
||||
|
||||
- 小程序只配置 Go 域名(现网经 `/psy/api/` 反代)。
|
||||
- 下线 Java 必须另开 ECR,并先迁支付。
|
||||
- 历史魔方账密用户按手机号合并到 `wx_openid`。
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
- 只做 SSO、双库长期并存:否决(用户要求合库合服务)。
|
||||
- 以 Java 吸收魔方:否决(栈已锁定 Go + PG)。
|
||||
- 客户端双 token:否决(code 单次使用,且拖住前端统一接入)。
|
||||
@@ -180,8 +180,9 @@ Level 0 alone ≠ Backend/Frontend Done。
|
||||
| **Vertical Slice Demo** | 主路径可演示;缺测/缺态/缺功能仍可存在 |
|
||||
| **Feature Complete** | 单功能满足本文件 §1–7 |
|
||||
| **P1 Complete** | feature-map P1 必做项全部 Feature Complete + L2 三流 + 至少 1 条 L3(或书面豁免经用户同意) |
|
||||
| **P2 Complete** | feature-map P2 范围全部 Feature Complete + P2 L2 流 + 至少 1 条 P2 L3(真支付除外,见 feature-map) |
|
||||
|
||||
当前仓库默认状态见:[product/p1-status.md](product/p1-status.md)。
|
||||
当前仓库默认状态见:[product/p1-status.md](product/p1-status.md) · [product/p2-status.md](product/p2-status.md)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -3,5 +3,10 @@
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| [../domain.md](../domain.md) | Tech ↔ 用户名 |
|
||||
| [domain-map.md](domain-map.md) | Bounded contexts(冻结) |
|
||||
| [domain-map.md](domain-map.md) | Bounded contexts(P1 冻结 + Ops Wave 0 Draft) |
|
||||
| [erd.md](erd.md) | P1 表结构草案(冻结) |
|
||||
| [boundary-rules.md](boundary-rules.md) | BC owns / allowed / forbidden(**P0** · Wave 0) |
|
||||
| [glossary.yaml](glossary.yaml) | 工程/API 唯一词(与 lexicon 双轨) |
|
||||
| [entity-catalog.md](entity-catalog.md) | 概念级实体目录(无 migration) |
|
||||
|
||||
Ops Contract-First 归档:`docs/WAVE0/`。
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
# Bounded Context Boundary Rules
|
||||
|
||||
> Wave 0 · **P0 资产** · AI / Engineer 只读;变更须 Architect + Human
|
||||
> 运行时权威副本:`.ai/domain/boundary-rules.md`
|
||||
|
||||
Status: `Draft`(Human Review 后 Frozen)
|
||||
|
||||
---
|
||||
|
||||
## 如何读
|
||||
|
||||
- **owns**:该 BC **唯一写权威**(修改入口)。
|
||||
- **does_not_own**:明示禁止「顺手改」。
|
||||
- **allowed**:允许的依赖(多为读或经门面)。
|
||||
- **forbidden**:禁止的依赖(含跨 BC 写支付/会员等)。
|
||||
|
||||
违反本文件 = Reviewer **BLOCK**(架构回归)。
|
||||
|
||||
---
|
||||
|
||||
## Admin_Auth_Audit
|
||||
|
||||
```yaml
|
||||
Admin_Auth_Audit:
|
||||
owns:
|
||||
- AdminAccount
|
||||
- AdminSession
|
||||
- AuditLog
|
||||
does_not_own:
|
||||
- UserStatus
|
||||
- MembershipPlan
|
||||
- Entitlement
|
||||
allowed:
|
||||
- Admin_RBAC.read
|
||||
forbidden:
|
||||
- Payment.write
|
||||
- C端业务聚合根的隐式写入
|
||||
```
|
||||
|
||||
## Admin_RBAC
|
||||
|
||||
```yaml
|
||||
Admin_RBAC:
|
||||
owns:
|
||||
- AdminRole
|
||||
- AdminPermission
|
||||
does_not_own:
|
||||
- User
|
||||
- Profile
|
||||
- Membership
|
||||
allowed:
|
||||
- Admin_Auth_Audit.write_audit
|
||||
forbidden:
|
||||
- Payment
|
||||
- Membership.write
|
||||
- DeviceAuth.user_token_issue
|
||||
```
|
||||
|
||||
## Identity_Profile
|
||||
|
||||
```yaml
|
||||
Identity_Profile:
|
||||
owns:
|
||||
- User
|
||||
- Profile
|
||||
- DeviceIdentity
|
||||
- UserStatus
|
||||
- BehaviorSnapshot
|
||||
- PsychologicalTagSet
|
||||
does_not_own:
|
||||
- MembershipPlan
|
||||
- Entitlement
|
||||
- Order
|
||||
- Payment
|
||||
- RedemptionCode
|
||||
allowed:
|
||||
- Analytics_OpsB.read
|
||||
forbidden:
|
||||
- Payment
|
||||
- Membership.write
|
||||
```
|
||||
|
||||
## Membership_Orders
|
||||
|
||||
```yaml
|
||||
Membership_Orders:
|
||||
owns:
|
||||
- MembershipPlan
|
||||
- Entitlement
|
||||
- Membership
|
||||
- Order
|
||||
- DeepAccess
|
||||
- RedemptionCode
|
||||
- Payment # mock 今;真支付适配器后置,仍归本 BC
|
||||
does_not_own:
|
||||
- UserStatus
|
||||
- AdminRole
|
||||
- FilterRule
|
||||
allowed:
|
||||
- Identity_Profile.read
|
||||
forbidden:
|
||||
- Ask_Ops.write_prompt
|
||||
- Content_Safety.rule_mutate_via_order
|
||||
```
|
||||
|
||||
## Analytics_OpsB
|
||||
|
||||
```yaml
|
||||
Analytics_OpsB:
|
||||
owns:
|
||||
- AnalyticsSession
|
||||
- AnalyticsEvent
|
||||
does_not_own:
|
||||
- User
|
||||
- Membership
|
||||
allowed:
|
||||
- Identity_Profile.read_ids_only
|
||||
forbidden:
|
||||
- Payment
|
||||
- 采集 PII 正文(生日/问答全文等)
|
||||
```
|
||||
|
||||
## Ops_Content
|
||||
|
||||
```yaml
|
||||
Ops_Content:
|
||||
owns:
|
||||
- HomeTool
|
||||
- ScalePublishState
|
||||
does_not_own:
|
||||
- Scale 题目正文编辑器(未开 ECR 前禁止扩张)
|
||||
allowed:
|
||||
- Explore_Reports.publish_gate
|
||||
forbidden:
|
||||
- Community
|
||||
- Payment
|
||||
```
|
||||
|
||||
## Account_Risk
|
||||
|
||||
```yaml
|
||||
Account_Risk:
|
||||
owns:
|
||||
- RiskFlag
|
||||
- BanRecord
|
||||
does_not_own:
|
||||
- MembershipPlan
|
||||
allowed:
|
||||
- Identity_Profile.UserStatus.transition # 经明确应用服务
|
||||
- Admin_Auth_Audit.write_audit
|
||||
forbidden:
|
||||
- Payment.refund_silent
|
||||
```
|
||||
|
||||
## Content_Safety
|
||||
|
||||
```yaml
|
||||
Content_Safety:
|
||||
owns:
|
||||
- FilterRule
|
||||
- ModerationCase
|
||||
- BlockPolicy
|
||||
- CrisisEvent
|
||||
- CrisisPolicy
|
||||
does_not_own:
|
||||
- Membership
|
||||
- Payment
|
||||
- AdminRole
|
||||
allowed:
|
||||
- Identity_Profile.read
|
||||
- Ask_Ops.read_session_meta
|
||||
forbidden:
|
||||
- Membership.write
|
||||
- Payment
|
||||
```
|
||||
|
||||
## Ask_Ops
|
||||
|
||||
```yaml
|
||||
Ask_Ops:
|
||||
owns:
|
||||
- AskSessionView
|
||||
- QualityFeedback
|
||||
- HandoffCase
|
||||
- SystemPrompt
|
||||
- KnowledgeSource
|
||||
- KnowledgeChunk
|
||||
- ToolDefinition
|
||||
does_not_own:
|
||||
- Payment
|
||||
- MembershipPlan
|
||||
- UserStatus
|
||||
allowed:
|
||||
- Identity_Profile.read
|
||||
- Content_Safety.evaluate
|
||||
forbidden:
|
||||
- Payment
|
||||
- Membership.write
|
||||
- Admin_RBAC.write
|
||||
```
|
||||
|
||||
## Ops_CMS_NoUGC
|
||||
|
||||
```yaml
|
||||
Ops_CMS_NoUGC:
|
||||
owns:
|
||||
- Banner
|
||||
- FeedSlot
|
||||
- ScheduledPublication
|
||||
does_not_own:
|
||||
- UGC Post
|
||||
- CommentGraph
|
||||
- TrustScore
|
||||
allowed:
|
||||
- Admin_RBAC.check
|
||||
forbidden:
|
||||
- Community
|
||||
- 用户生成内容入库为主路径
|
||||
```
|
||||
|
||||
## Community
|
||||
|
||||
```yaml
|
||||
Community:
|
||||
status: Forbidden
|
||||
owns: []
|
||||
note: feature-map UGC 广场 [No];开启须 L3 ADR + 新 Capability
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 反模式(禁止)
|
||||
|
||||
```text
|
||||
AskService → load User → update Membership → charge Payment
|
||||
UserService.updateMembership()
|
||||
Content_Safety 直接改 Entitlement
|
||||
Ops_CMS 引入「用户帖子」表却声称 NoUGC
|
||||
```
|
||||
@@ -23,6 +23,26 @@
|
||||
|
||||
---
|
||||
|
||||
## Ops Platform Bounded Contexts(Wave 0 Draft)
|
||||
|
||||
> 详细 owns/forbidden:[`boundary-rules.md`](boundary-rules.md) · 词表:[`glossary.yaml`](glossary.yaml) · 实体:[`entity-catalog.md`](entity-catalog.md)
|
||||
> 归档:`docs/WAVE0/domain/` · Capability:`docs/WAVE0/capability/ops-capability-map.md`
|
||||
> **不修改**上方 P1 不变量;Ops BC 实现须独立 ECR。
|
||||
|
||||
| Context | Capability | Status |
|
||||
|---|---|---|
|
||||
| Admin_Auth_Audit | AdminGovernance | Shipped Ops-A |
|
||||
| Admin_RBAC | AdminGovernance | Draft → ECR-013A |
|
||||
| Analytics_OpsB | GrowthInsights / UserIntelligence(read) | Shipped Ops-B |
|
||||
| Ops_Content | ExploreConfig (partial) | Shipped Ops-C |
|
||||
| Account_Risk | AccountLifecycle | Spec via ECR-013B(Identity_Profile owns UserStatus) |
|
||||
| Content_Safety | ContentSafety · CrisisCare | ContentSafety **ECR-019**;CrisisCare **ECR-022**(CrisisPolicy 只读) |
|
||||
| Ask_Ops | AskOperations · AICoreConfig | AskOperations **ECR-017/020**;AICoreConfig **ECR-021**(SystemPrompt 只读) |
|
||||
| Ops_CMS_NoUGC | OpsCMS | Draft |
|
||||
| Community | — | **Forbidden** |
|
||||
|
||||
---
|
||||
|
||||
## Context diagram
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Entity Catalog(Wave 0 · 概念级)
|
||||
|
||||
> 仅登记名称、归属 BC、Capability、生命周期备注。**不建表、不写 migration。**
|
||||
> 与 [`glossary.yaml`](glossary.yaml) · [`boundary-rules.md`](boundary-rules.md) 一致。
|
||||
|
||||
Status: `Draft`
|
||||
|
||||
| Entity | BC | Capability | Notes |
|
||||
|--------|----|------------|-------|
|
||||
| AdminAccount | Admin_Auth_Audit | AdminGovernance | 已存在 Ops-A |
|
||||
| AdminSession | Admin_Auth_Audit | AdminGovernance | 已存在 |
|
||||
| AuditLog | Admin_Auth_Audit | AdminGovernance | 已存在;只追加 |
|
||||
| AdminRole | Admin_RBAC | AdminGovernance | **ECR-013A** |
|
||||
| AdminPermission | Admin_RBAC | AdminGovernance | **ECR-013A** |
|
||||
| User | Identity_Profile | AccountLifecycle | 已存在 |
|
||||
| Profile | Identity_Profile | UserIntelligence | 已存在 |
|
||||
| UserStatus | Identity_Profile | AccountLifecycle | **ECR-013B** 状态机 |
|
||||
| AccountStateTransition | Identity_Profile | AccountLifecycle | **ECR-013B** |
|
||||
| BehaviorSnapshot | Identity_Profile | UserIntelligence | **ECR-016** 读模型(analytics 聚合) |
|
||||
| PsychologicalTagSet | Identity_Profile | UserIntelligence | **ECR-016** 由报告 type 派生 |
|
||||
| MembershipPlan | Membership_Orders | CommerceEntitlement | **ECR-014 Closed** |
|
||||
| Entitlement | Membership_Orders | CommerceEntitlement | **ECR-018** 读模型(Membership∪DeepAccess) |
|
||||
| RedemptionCode | Membership_Orders | CommerceEntitlement | **ECR-015 Closed** |
|
||||
| Membership | Membership_Orders | CommerceEntitlement | 已存在 |
|
||||
| Order | Membership_Orders | CommerceEntitlement | 已存在 |
|
||||
| DeepAccess | Membership_Orders | CommerceEntitlement | 已存在 |
|
||||
| Payment | Membership_Orders | CommerceEntitlement | mock;真支付最后 |
|
||||
| HomeTool | Ops_Content | ExploreConfig | 已存在 Ops-C |
|
||||
| ScalePublishState | Ops_Content | ExploreConfig | 已存在 |
|
||||
| AnalyticsSession / Event | Analytics_OpsB | GrowthInsights | 已存在 Ops-B |
|
||||
| FilterRule | Content_Safety | ContentSafety | **ECR-019** 只读 + evaluate |
|
||||
| ModerationCase | Content_Safety | ContentSafety | 后置 |
|
||||
| CrisisEvent / CrisisPolicy | Content_Safety | CrisisCare | **ECR-022** CrisisPolicy 只读;CrisisEvent 后置 |
|
||||
| SystemPrompt / Knowledge* / ToolDefinition | Ask_Ops | AICoreConfig | **ECR-021** SystemPrompt 只读;Knowledge/Tools 后置 |
|
||||
| AskSessionView / QualityFeedback | Ask_Ops | AskOperations | **ECR-017** AskSessionView;**ECR-020** QualityFeedback |
|
||||
| Banner / FeedSlot | Ops_CMS_NoUGC | OpsCMS | 后置 |
|
||||
| UGC* | Community | — | **Forbidden** |
|
||||
|
||||
## 状态机(ECR-013B · 契约已开)
|
||||
|
||||
`UserStatus`: 见 `.ai/product/feature-spec/ops-account-lifecycle.md`。
|
||||
`deleted` soft-delete **不在 013B**(另开)。
|
||||
实现轮前:**禁止** migration / DeviceAuth 改动。
|
||||
@@ -0,0 +1,116 @@
|
||||
# domain glossary — engineering / API unique terms
|
||||
|
||||
# Wave 0 Draft. Runtime copy: .ai/domain/glossary.yaml
|
||||
# User-facing copy stays in .ai/product/lexicon.md
|
||||
# Conflict: Architect + Human resolve; do not invent synonyms in code.
|
||||
|
||||
version: "0.1.0"
|
||||
status: draft
|
||||
|
||||
terms:
|
||||
AdminRole:
|
||||
zh: 管理员角色
|
||||
bc: Admin_RBAC
|
||||
forbidden: [admin_group, privilege_group]
|
||||
|
||||
AdminPermission:
|
||||
zh: 管理员权限点
|
||||
bc: Admin_RBAC
|
||||
forbidden: [acl_flag, authz_bit]
|
||||
|
||||
AuditLog:
|
||||
zh: 操作审计日志
|
||||
bc: Admin_Auth_Audit
|
||||
forbidden: [admin_history]
|
||||
|
||||
UserStatus:
|
||||
zh: 用户账户状态
|
||||
bc: Identity_Profile
|
||||
values: [active, disabled, banned, suspended]
|
||||
forbidden: [user_flag, account_level]
|
||||
|
||||
AccountStateTransition:
|
||||
zh: 账户状态迁移
|
||||
bc: Identity_Profile
|
||||
forbidden: [status_patch_log]
|
||||
|
||||
MembershipPlan:
|
||||
zh: 会员套餐
|
||||
bc: Membership_Orders
|
||||
forbidden: [package, vip_level, 订阅档, sku_vip]
|
||||
|
||||
Entitlement:
|
||||
zh: 权益
|
||||
bc: Membership_Orders
|
||||
forbidden: [privilege_pack, benefit_bundle]
|
||||
|
||||
RedemptionCode:
|
||||
zh: 兑换码
|
||||
bc: Membership_Orders
|
||||
forbidden: [gift_card, activation_key_alias]
|
||||
|
||||
DeepAccess:
|
||||
zh: 深度版
|
||||
bc: Membership_Orders
|
||||
forbidden: [Unlock, unlock_report]
|
||||
|
||||
BehaviorSnapshot:
|
||||
zh: 行为快照
|
||||
bc: Identity_Profile
|
||||
forbidden: [user_track_dump]
|
||||
|
||||
PsychologicalTagSet:
|
||||
zh: 心理标签集
|
||||
bc: Identity_Profile
|
||||
forbidden: [psy_labels_raw]
|
||||
|
||||
FilterRule:
|
||||
zh: 过滤规则
|
||||
bc: Content_Safety
|
||||
forbidden: [badword_only]
|
||||
|
||||
ModerationCase:
|
||||
zh: 审核工单
|
||||
bc: Content_Safety
|
||||
forbidden: [review_ticket_ugc]
|
||||
|
||||
CrisisEvent:
|
||||
zh: 危机事件
|
||||
bc: Content_Safety
|
||||
forbidden: [suicide_flag_public]
|
||||
|
||||
CrisisPolicy:
|
||||
zh: 危机策略
|
||||
bc: Content_Safety
|
||||
forbidden: [kill_switch_generic]
|
||||
|
||||
SystemPrompt:
|
||||
zh: 系统提示词
|
||||
bc: Ask_Ops
|
||||
forbidden: [god_prompt]
|
||||
|
||||
KnowledgeSource:
|
||||
zh: 知识源
|
||||
bc: Ask_Ops
|
||||
forbidden: [rag_file]
|
||||
|
||||
KnowledgeChunk:
|
||||
zh: 知识块
|
||||
bc: Ask_Ops
|
||||
forbidden: [embedding_row_ui]
|
||||
|
||||
ToolDefinition:
|
||||
zh: 工具定义
|
||||
bc: Ask_Ops
|
||||
forbidden: [function_call_config_loose]
|
||||
|
||||
Banner:
|
||||
zh: 运营横幅
|
||||
bc: Ops_CMS_NoUGC
|
||||
forbidden: [story_feed_ugc]
|
||||
|
||||
Community:
|
||||
zh: (禁止能力)
|
||||
bc: Community
|
||||
status: forbidden
|
||||
forbidden: [ugc_plaza, 社区广场]
|
||||
@@ -4,6 +4,7 @@
|
||||
|---|---|
|
||||
| [ENGINEERING-FREEZE.md](ENGINEERING-FREEZE.md) | **P1 冻结清单** |
|
||||
| [p1-status.md](p1-status.md) | **P1 完成度(当前:P1 Complete)** |
|
||||
| [p2-status.md](p2-status.md) | **P2 完成度(当前:P2 Complete)** |
|
||||
| [lexicon.md](lexicon.md) | 产品语言契约(最高优先级) |
|
||||
| [feature-design.md](feature-design.md) | **Feature Spec 强制规范** |
|
||||
| [feature-spec/](feature-spec/README.md) | **功能详细设计(单功能 HOW)** |
|
||||
@@ -21,4 +22,4 @@
|
||||
|
||||
开发链路:`feature-map` →(对标时)逆向 STEP 1–18 → `feature-spec` → domain/OpenAPI → 实现 → 测试 → Review。
|
||||
|
||||
P2 探索三模块(设计):[feature-spec/P2-BACKLOG.md](feature-spec/P2-BACKLOG.md) · 星象性格 / 身心节律 / 意象卡片。
|
||||
P2 探索收口:[p2-status.md](p2-status.md) · [feature-spec/P2-BACKLOG.md](feature-spec/P2-BACKLOG.md) · 星座 / 身心节律 / 意象卡片。
|
||||
|
||||
@@ -30,11 +30,10 @@
|
||||
## 执行分期(与 feature-map 对齐)
|
||||
|
||||
1. **P1** — 档案 · 性格探索/画像 · 人格测评 · 关系理解 · 问答 · 深度版 · 会员 · 分享 · 埋点
|
||||
2. **P2** — 星象性格 · 身心节律 · 意象卡片 · 节气陪伴深化 · 心情记录 · 成长计划
|
||||
2. **P2** — 星象性格 · 身心节律 · 意象卡片 · 节气陪伴深化 · 心情记录 · 成长计划 → **P2 Complete**([p2-status.md](p2-status.md))
|
||||
3. **P3** — 长期记忆 · 成长数据库 · 真人顾问
|
||||
|
||||
P2 三模块:**设计已立项**(Spec Active);**实现前**须保持 Spec 与 OpenAPI/erd 同步,另开编码切片。
|
||||
不进入 P1 Complete 判定。
|
||||
真支付仍属部署阶段,不进入 P1/P2 Complete 判定。
|
||||
|
||||
冲突时:**lexicon + feature-map > 历史 Vision 文档中的旧命名(解码/Unlock 等)**。
|
||||
|
||||
|
||||
+14
-10
@@ -212,11 +212,11 @@ UI **不出现「塔罗」**。禁止神谕吉凶、恐吓话术。
|
||||
|
||||
**不含** 2.6–2.8;P2 三模块不计入 P1 Complete。
|
||||
|
||||
### 第二阶段 `[P2]` — **合规全量探索进行中**
|
||||
### 第二阶段 `[P2]` — **P2 Complete**
|
||||
|
||||
星象性格 · 身心节律 · 意象卡片 · 节气陪伴深化 · 心情记录 · 成长计划 · 探索三级目录 · 量表矩阵
|
||||
|
||||
设计真源:`feature-spec/star-profile.md` · `life-rhythm.md` · `image-card.md` · [P2-BACKLOG.md](feature-spec/P2-BACKLOG.md)
|
||||
状态真源:[p2-status.md](p2-status.md) · Spec:`feature-spec/star-profile.md` · `life-rhythm.md` · `image-card.md` · [P2-BACKLOG.md](feature-spec/P2-BACKLOG.md)
|
||||
排除不变:消息/达人/UGC 广场/运势 Feed;真支付部署阶段再做。
|
||||
|
||||
### 第三阶段 `[P3]`
|
||||
@@ -228,13 +228,17 @@ UI **不出现「塔罗」**。禁止神谕吉凶、恐吓话术。
|
||||
## 7. 运营后台(内部 · 非 C 端 Tab)
|
||||
|
||||
详见 Spec:[feature-spec/ops-admin.md](feature-spec/ops-admin.md) · ECR-006
|
||||
**演进规范(Wave 0):** [`docs/WAVE0/`](../../docs/WAVE0/) · Capability Map · boundary-rules · Contract-First(禁止 Feature 堆砌进实现)
|
||||
|
||||
| 分期 | 内容 |
|
||||
|---|---|
|
||||
| Phase A `[Ops]` | 登录 · 用户/订单查询 · 会员授予 · 审计 · `apps/admin-h5`(ECR-006 Closed) |
|
||||
| Phase B `[Ops]` | 行为分析:自有埋点 + 管理端「数据」看板(**ECR-007 Implemented** · Spec `ops-analytics.md`) |
|
||||
| Phase C `[Ops]` | 内容:首页宫格 CRUD · 测评上下架(**ECR-008 Implemented** · Spec `ops-content.md`) |
|
||||
| Phase D+ | 商业加深 · RBAC · 封禁 · 推送(各开独立 ECR) |
|
||||
| Phase B `[Ops]` | 行为分析:自有埋点 + 管理端「数据」看板(**ECR-007** · Spec `ops-analytics.md`) |
|
||||
| Phase C `[Ops]` | 内容:首页宫格 CRUD · 测评上下架(**ECR-008** · Spec `ops-content.md`) |
|
||||
| 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+ / Write-Wave | **写面加深**(首刀 **ECR-041 Banner** · `docs/WAVE0/WRITE_WAVE_AUTHORIZATION.md`);封禁细策略 · 真推送;**UGC 仍 `[No]`**;**真支付最后** |
|
||||
|
||||
不计入 P1 Complete;不进入五 Tab。
|
||||
|
||||
@@ -256,11 +260,11 @@ UI **不出现「塔罗」**。禁止神谕吉凶、恐吓话术。
|
||||
| `/scales/:slug` | 探索测试作答 | |
|
||||
| `/reports` | 成长报告列表 | |
|
||||
| `/reports/:id` | 成长报告详情 | |
|
||||
| `/star` | 星座 | P2 |
|
||||
| `/synastry` | 合盘 | P2 |
|
||||
| `/synastry/invite/:token` | 合盘邀请 | P2 |
|
||||
| `/rhythm` | 身心节律 | P2 draft |
|
||||
| `/cards` | 意象卡片 | P2 draft |
|
||||
| `/star` | 星座 | P2 Complete |
|
||||
| `/synastry` | 合盘 | P2 Complete |
|
||||
| `/synastry/invite/:token` | 合盘邀请 | P2 Complete |
|
||||
| `/rhythm` | 身心节律 | P2 Complete |
|
||||
| `/cards` | 意象卡片 | P2 Complete |
|
||||
|
||||
兼容重定向:`/decode` → `/portrait`(仅技术兼容,UI 不出现 decode 文案)。
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# P2 Backlog — 探索三模块 + 合规全量目录
|
||||
|
||||
**状态:** 合规全量探索进行中(Wave 0–4)
|
||||
**状态:`P2 Complete`(见 [../p2-status.md](../p2-status.md))**
|
||||
**命名决策:** 星座 / 身心节律 / 意象卡片;UI 无「塔罗」主入口、无「算命/占卜」恐吓
|
||||
**契约:** [../lexicon.md](../lexicon.md) · [../feature-map.md](../feature-map.md) · [../STRATEGY.md](../STRATEGY.md)
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
| 顺序 | 模块 | Spec | 路由 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| 0 | 探索目录 | — | `/explore` · `/explore/:category` | Done |
|
||||
| 1 | 星座 | [star-profile.md](star-profile.md) | `/star` | Done(星盘/运势/合盘对齐中) |
|
||||
| 2 | 身心节律 | [life-rhythm.md](life-rhythm.md) | `/rhythm` | Done(今日/本周) |
|
||||
| 1 | 星座 | [star-profile.md](star-profile.md) | `/star` · `/synastry` | Done |
|
||||
| 2 | 身心节律 | [life-rhythm.md](life-rhythm.md) | `/rhythm` | Done |
|
||||
| 3 | 意象卡片 | [image-card.md](image-card.md) | `/cards` | Done(≥78 牌 · ≥8 场景) |
|
||||
| 4 | 量表矩阵 | [explore-test.md](explore-test.md) | `/scales/*` | Done(≥8) |
|
||||
| 5 | 成长计划 | companion | `/growth-plan` | Done |
|
||||
| 5 | 成长计划 | companion / growth | `/growth-plan` | Done |
|
||||
| 6 | 心情轨迹 | companion | `/companion` | Done |
|
||||
|
||||
---
|
||||
@@ -28,4 +28,5 @@
|
||||
|---|---|
|
||||
| 设计三 Spec | Done |
|
||||
| 探索 catalog API | Done |
|
||||
| 真支付 | 部署阶段 |
|
||||
| L0–L3 验证 | Done(见 p2-status) |
|
||||
| 真支付 | 部署阶段(不挡 P2 Complete) |
|
||||
|
||||
@@ -15,18 +15,57 @@
|
||||
| [membership.md](membership.md) | 深度版 / 成长会员 | §6 · §5.3 | `/membership` | P1 |
|
||||
| [reports.md](reports.md) | 成长报告列表/详情 | §2.1.2 · §5.2 | `/reports` · `/reports/:id` | P1 |
|
||||
| [share.md](share.md) | 分享卡 | journey 双引擎 | `/share` | P1 |
|
||||
| [companion.md](companion.md) | 陪伴(节气壳) | §4 | `/companion` | P1 壳 / P2 |
|
||||
| [companion.md](companion.md) | 陪伴(节气+心情) | §4 | `/companion` | P2 Complete |
|
||||
| [analytics.md](analytics.md) | 增长埋点最小集 | 横切 | H5 `track` | P1 |
|
||||
| [star-profile.md](star-profile.md) | 星象性格 | §2.6 | `/star` | P2 设计 |
|
||||
| [life-rhythm.md](life-rhythm.md) | 身心节律 | §2.7 | `/rhythm` | P2 设计 |
|
||||
| [image-card.md](image-card.md) | 意象卡片 | §2.8 | `/cards` | P2 设计 |
|
||||
| [star-profile.md](star-profile.md) | 星象性格 | §2.6 | `/star` | P2 Complete |
|
||||
| [life-rhythm.md](life-rhythm.md) | 身心节律 | §2.7 | `/rhythm` | P2 Complete |
|
||||
| [image-card.md](image-card.md) | 意象卡片 | §2.8 | `/cards` | P2 Complete |
|
||||
| [ops-admin.md](ops-admin.md) | 运营后台 | §7 | `admin-h5` `/` `/users/:id` … | Ops-A |
|
||||
| [ops-analytics.md](ops-analytics.md) | 运营行为分析(埋点+数据看板) | §7 | `admin-h5` `/analytics` · H5 track | Ops-B · ECR-007 Implemented |
|
||||
| [ops-content.md](ops-content.md) | 运营内容(宫格+测评上下架) | §7 | `admin-h5` `/content` · `GET /home/tools` | Ops-C · ECR-008 Approved |
|
||||
| [ops-analytics.md](ops-analytics.md) | 运营行为分析(埋点+数据看板) | §7 | `admin-h5` `/analytics` · H5 track | Ops-B · ECR-007 |
|
||||
| [ops-content.md](ops-content.md) | 运营内容(宫格+测评上下架) | §7 | `admin-h5` `/content` · `GET /home/tools` | Ops-C · ECR-008 |
|
||||
| [ops-commerce.md](ops-commerce.md) | 运营商业加深(订单筛选+展示价+退款只读) | §7 | `admin-h5` `/orders` `/pricing` | Ops-D · ECR-009 |
|
||||
| [ops-system.md](ops-system.md) | 运营系统(RBAC+封禁+推送占位) | §7 | `admin-h5` `/push` `/admins` | Ops-E · ECR-010 |
|
||||
| [input-compliance.md](input-compliance.md) | 用户文字输入合规 | 横切 · 安全 | 各写接口 · code 40060 | P2 · ECR-012 |
|
||||
| [ops-rbac.md](ops-rbac.md) | 运营 RBAC | §7 | `admin-h5` `/me` permissions · `/admin/roles*` | Ops · **ECR-013A** |
|
||||
| [ops-redemption-code.md](ops-redemption-code.md) | 兑换码 RedemptionCode | §7 | `admin-h5` `/codes` · `POST /membership/redeem` | Ops · **ECR-015(local)** |
|
||||
| [ops-user-intelligence.md](ops-user-intelligence.md) | 用户洞察 UserIntelligence | §7 | `admin-h5` 用户详情「洞察」 | Ops · **ECR-016(local)** |
|
||||
| [ops-ask-operations.md](ops-ask-operations.md) | 问答运营 AskOperations | §7 | `admin-h5` `/ask` | Ops · **ECR-017** |
|
||||
| [ops-entitlement.md](ops-entitlement.md) | 用户权益 Entitlement | §7 | `admin-h5` 用户详情「权益」 | Ops · **ECR-018** |
|
||||
| [ops-content-safety.md](ops-content-safety.md) | 内容安全 ContentSafety | §7 | `admin-h5` `/safety` | Ops · **ECR-019** |
|
||||
| [ops-quality-feedback.md](ops-quality-feedback.md) | 问答质量反馈 QualityFeedback | §7 | `admin-h5` `/ask` | Ops · **ECR-020** |
|
||||
| [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-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-feed-slot-write.md](ops-feed-slot-write.md) | OpsCMS FeedSlot **写面** | §7 | admin CMS 写 · `GET /home/feed-slots` | Write-Wave · **ECR-042** |
|
||||
| [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** |
|
||||
| [ops-tool-definition.md](ops-tool-definition.md) | AICoreConfig ToolDefinition | §7 | `/admin/ai/tools*` | Ops · **ECR-028** |
|
||||
| [ops-block-policy.md](ops-block-policy.md) | ContentSafety BlockPolicy | §7 | `/admin/content-safety/block-policies*` | Ops · **ECR-029** |
|
||||
| [ops-moderation-case.md](ops-moderation-case.md) | ContentSafety ModerationCase | §7 | `/admin/content-safety/cases*` | Ops · **ECR-030** |
|
||||
| [ops-crisis-event.md](ops-crisis-event.md) | CrisisCare CrisisEvent | §7 | `/admin/crisis/events*` | Ops · **ECR-031** |
|
||||
| [ops-intervention-outcome.md](ops-intervention-outcome.md) | CrisisCare InterventionOutcome | §7 | `/admin/crisis/interventions*` | Ops · **ECR-032** |
|
||||
| [ops-handoff-case.md](ops-handoff-case.md) | AskOperations HandoffCase | §7 | `/admin/ask/handoffs*` | Ops · **ECR-033** |
|
||||
| [ops-privacy-request.md](ops-privacy-request.md) | AdminGovernance PrivacyRequest | §7 | `/admin/privacy/requests*` | Ops · **ECR-034** |
|
||||
| [ops-star-config.md](ops-star-config.md) | ExploreConfig StarConfig(只读) | §7 | `/admin/explore/star-configs*` | Ops · **ECR-035** |
|
||||
| [ops-star-config-write.md](ops-star-config-write.md) | StarConfig **写面** | §7 | admin 写 · `GET /star/configs` | ExploreConfig · **ECR-043** |
|
||||
| [ops-rhythm-config.md](ops-rhythm-config.md) | ExploreConfig RhythmConfig(只读) | §7 | `/admin/explore/rhythm-configs*` | Ops · **ECR-036** |
|
||||
| [ops-rhythm-config-write.md](ops-rhythm-config-write.md) | RhythmConfig **写面** | §7 | admin 写 · `GET /rhythm/configs` | ExploreConfig · **ECR-044** |
|
||||
| [ops-image-card-deck.md](ops-image-card-deck.md) | ExploreConfig ImageCardDeck(只读) | §7 | `/admin/explore/image-card-decks*` | Ops · **ECR-037** |
|
||||
| [ops-image-card-deck-write.md](ops-image-card-deck-write.md) | ImageCardDeck **写面** | §7 | admin 写 · `GET /cards/decks` | ExploreConfig · **ECR-045** |
|
||||
| [ops-report-template.md](ops-report-template.md) | GrowthInsights ReportTemplate(只读) | §7 | `/admin/growth/report-templates*` | Ops · **ECR-038** |
|
||||
| [ops-report-template-write.md](ops-report-template-write.md) | ReportTemplate **写面** | §7 | admin POST/PUT · growth.write | GrowthInsights · **ECR-048** |
|
||||
| [ops-funnel-definition.md](ops-funnel-definition.md) | GrowthInsights FunnelDefinition(只读) | §7 | `/admin/analytics/funnel-definitions*` | Ops · **ECR-039** |
|
||||
| [ops-funnel-definition-write.md](ops-funnel-definition-write.md) | FunnelDefinition **写面** | §7 | admin POST/PUT · growth.write | GrowthInsights · **ECR-047** |
|
||||
| [ops-scale-definition.md](ops-scale-definition.md) | ExploreConfig ScaleDefinition(只读) | §7 | `/admin/explore/scales*` | Ops · **ECR-040** |
|
||||
| [ops-scale-definition-write.md](ops-scale-definition-write.md) | ScaleDefinition **写面** | §7 | admin POST/PUT · status 仍 ECR-008 | ExploreConfig · **ECR-046** |
|
||||
|
||||
新功能:复制 `_TEMPLATE.md` → 填满 → 在本表登记 → 再编码。
|
||||
|
||||
**P1 全量流程走查:** [P1-PROCESS-REVIEW.md](P1-PROCESS-REVIEW.md)
|
||||
**P2 三模块队列(设计立项 / 编码另批):** [P2-BACKLOG.md](P2-BACKLOG.md)
|
||||
**P2 收口状态:** [../p2-status.md](../p2-status.md) · [P2-BACKLOG.md](P2-BACKLOG.md)
|
||||
|
||||
|
||||
**竞品逆向(测测前端全量):** [cece-frontend-re/](cece-frontend-re/README.md) · **完整设计包:** [cece-frontend-re/complete-design/](cece-frontend-re/complete-design/README.md) · 方法见 [../../design/reverse-engineering-spec.md](../../design/reverse-engineering-spec.md)
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| Name | 账号登录(手机号+密码) |
|
||||
| Name | 账号登录(小程序微信;H5 过渡账密) |
|
||||
| Purpose | 跨设备持久用户身份;未登录不可生成/查看生日衍生结果 |
|
||||
| Business Goal | 数据归属清晰;为会员与深度版付费打底 |
|
||||
| Business Goal | 数据归属清晰;咨询与魔方同一人;为会员与深度版付费打底 |
|
||||
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| 注册 / 登录 / 登出 / me | 微信 OAuth、短信 OTP(后续) |
|
||||
| 小程序微信登录 / 登出 / me | 短信 OTP |
|
||||
| 设备身份绑定到已注册账号 | 游客可看完整报告 |
|
||||
| Bearer Session | 运营 Admin 登录(独立) |
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
```text
|
||||
进入结果页或建档
|
||||
↓
|
||||
未登录? → /login 注册或登录
|
||||
未登录? → 小程序 login-pop(微信)或 H5 /login(过渡账密)
|
||||
↓
|
||||
Device 绑定到账号 User
|
||||
↓
|
||||
@@ -58,7 +58,8 @@ Device 绑定到账号 User
|
||||
|
||||
| 路由 | 页面 |
|
||||
|---|---|
|
||||
| `/login` | LoginPage(注册/登录切换) |
|
||||
| `/login` | H5 LoginPage(过渡账密;小程序已删除此页) |
|
||||
| 小程序 `login-pop` | 微信手机号授权(唯一 C 端登录) |
|
||||
| `/mine` | 展示账号手机号尾号 + 退出 |
|
||||
|
||||
---
|
||||
@@ -77,19 +78,23 @@ Device 绑定到账号 User
|
||||
|
||||
| ID | Rule |
|
||||
|---|---|
|
||||
| R1 | **临时开放:** 任意非空手机号 + 任意密码均可登录;未注册则自动建号写入 DB |
|
||||
| R2 | 登录/注册统一走 OpenLogin;不校验历史密码,仍会更新 password_hash 记录本次输入 |
|
||||
| R1 | **小程序:** 微信 `code` + 手机号授权登录;按 `wx_openid` 命中,否则按手机号合并历史账密账号;未命中则建号 |
|
||||
| R2 | **H5 过渡:** OpenLogin(任意非空手机号+密码)仍可用,避免 H5 断服;小程序不再提供账密页。正式关掉账密须另改本 Spec |
|
||||
| R3 | 登录成功后:签发 session;device_identities.user_id 改绑到账号 |
|
||||
| R4 | 生成/查看档案与报告 API 必须已注册(users.phone 非空)且有效 session 或已绑设备账号 |
|
||||
| R5 | 登出作废 session;设备可再登录其他账号 |
|
||||
| R6 | 正式环境恢复校验前须改回本 Spec |
|
||||
| R7 | 新账号未填昵称时,服务端用「意象词+场景词」词库(100×100)随机生成,如心语岛、微光谷 |
|
||||
| R8 | 账号昵称可在个人档案页修改(PATCH `/auth/me`);首页与各页「自己」展示位统一用昵称(合盘/问答/星座/档案卡) |
|
||||
| R9 | 账号头像可在「我的」页更换:相册或拍照上传;服务端持久化;GET `/auth/me` 返回 `avatar_url`;未设置时 UI 用愈心小人正面默认头像(`public/default-avatar.png`,源图 `public/logo/愈心小人1.png`) |
|
||||
|
||||
---
|
||||
|
||||
## 8. 数据模型影响
|
||||
|
||||
- `users.phone` UNIQUE · `users.password_hash` · `users.nickname`
|
||||
- `users.phone` UNIQUE · `users.wx_openid` UNIQUE · `users.wx_unionid` · `users.java_platform_user_id` · `users.password_hash` · `users.nickname` · `users.avatar_url`
|
||||
- `user_sessions(token, user_id, expires_at)`
|
||||
- 本地文件:`data/avatars/{user_id}.{jpg|png|webp}`(进程相对路径)
|
||||
|
||||
---
|
||||
|
||||
@@ -97,10 +102,14 @@ Device 绑定到账号 User
|
||||
|
||||
| Method | Path | 说明 |
|
||||
|---|---|---|
|
||||
| POST | `/api/v1/auth/register` | 注册 |
|
||||
| POST | `/api/v1/auth/login` | 登录 |
|
||||
| POST | `/api/v1/auth/wechat` | 小程序微信登录 `{ code, encryptedData, iv }` |
|
||||
| POST | `/api/v1/auth/register` | H5 过渡注册(可带 nickname) |
|
||||
| POST | `/api/v1/auth/login` | H5 过渡登录 |
|
||||
| POST | `/api/v1/auth/logout` | 登出 |
|
||||
| GET | `/api/v1/auth/me` | 当前账号 |
|
||||
| GET | `/api/v1/auth/me` | 当前账号(含 avatar_url) |
|
||||
| PATCH | `/api/v1/auth/me` | 更新昵称 `{ nickname }` |
|
||||
| POST | `/api/v1/auth/me/avatar` | multipart `file`;jpeg/png/webp;≤2MB → 更新 avatar_url |
|
||||
| GET | `/api/v1/media/avatars/:file` | 公开读头像文件 |
|
||||
|
||||
---
|
||||
|
||||
@@ -110,12 +119,30 @@ Device 绑定到账号 User
|
||||
|---|---|---|
|
||||
| register/login | ✓ | ✓ |
|
||||
| profiles / reports 写读 | ✗ | ✓ |
|
||||
| 上传头像 | ✗ | ✓ |
|
||||
| 读头像媒体 | ✓ | ✓ |
|
||||
|
||||
---
|
||||
|
||||
## 11. 埋点
|
||||
|
||||
`auth_register` · `auth_login` · `auth_logout`
|
||||
经统一 `track()`(见 [analytics.md](analytics.md) · [ops-analytics.md](ops-analytics.md))。
|
||||
**非** P1 核心漏斗 5 事件;接入后走自有 `POST /analytics/events`(及可选 GA)。
|
||||
禁止参数含手机号、明文密码、头像绝对 URL / `user_id`。
|
||||
|
||||
| Event | 触发 | 可选 params |
|
||||
|---|---|---|
|
||||
| `auth_register` | 账号新建成功(含 OpenLogin 自动建号,`is_new=true`) | `source`: login_page |
|
||||
| `auth_login` | 已有账号登录成功(`is_new=false`) | `source`: login_page |
|
||||
| `auth_logout` | 用户在「我的」点退出且本地 session 已清 | `surface`: mine |
|
||||
| `avatar_sheet_opened` | 「我的」打开更换头像 sheet | `surface`: mine |
|
||||
| `avatar_upload_succeeded` | 头像上传 API 成功且 UI 刷新为新图 | `source`: album \| camera |
|
||||
| `avatar_upload_failed` | 头像上传失败(校验/网络/服务端) | `source`: album \| camera · `reason`: too_large \| bad_type \| network \| server \| unknown |
|
||||
| `nickname_updated` | PATCH 昵称成功 | `surface`: profile |
|
||||
|
||||
`page_view` 对 `/login` · `/mine` 由路由自动采集,本 Spec 不重复定义。
|
||||
|
||||
**实现状态:** 事件名以本表为准;H5 已挂 Login / Mine / Profile(`track` → 自有 ingest + 可选 GA)。
|
||||
|
||||
---
|
||||
|
||||
@@ -126,6 +153,7 @@ Device 绑定到账号 User
|
||||
| 新设备 | 未登录 POST portrait | 401 |
|
||||
| 注册成功 | 建档 | 200 且生成报告包 |
|
||||
| 登录另一设备 | list profiles | 见同一账号数据 |
|
||||
| 已登录设备 | POST logout 后无 Bearer 再 GET /auth/me | 401(设备已解绑,刷新不再显示登录态) |
|
||||
|
||||
---
|
||||
|
||||
@@ -133,3 +161,4 @@ Device 绑定到账号 User
|
||||
|
||||
- [x] lexicon:登录/注册/账号
|
||||
- [x] 不碰 Admin Auth
|
||||
- [x] 咨询域见 Spec `consult-miniprogram`(ECR-050)
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
|
||||
```text
|
||||
/ask
|
||||
├── 愈心 AI / 顾问 Tab
|
||||
├── 顾问列表 → 顾问专属对话(?advisor=key · 顶栏返回回列表)
|
||||
├── Empty(无档案)
|
||||
├── Loading(发送中)
|
||||
├── Normal(历史 + 输入)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Feature Spec: 陪伴(节气壳)
|
||||
|
||||
> Status: `Active`(壳) · Map: `§4 陪伴 [P2 主做;P1 可占位]` · Phase: `P1 Shell / P2`
|
||||
> Status: `Active` · Map: `§4 陪伴 [P2]` · Phase: `P2 Complete`
|
||||
> 规范:[../feature-design.md](../feature-design.md)
|
||||
|
||||
---
|
||||
@@ -111,10 +111,15 @@ Tab 陪伴 → /companion
|
||||
|
||||
## 11. 埋点
|
||||
|
||||
| Event | 触发 |
|
||||
|---|---|
|
||||
| `companion_viewed` | 打开 |
|
||||
| `mood_saved` | P2 |
|
||||
| Event | 触发 | 可选 params |
|
||||
|---|---|---|
|
||||
| `companion_viewed` | 打开 `/companion` | — |
|
||||
| `mood_saved` | 心情保存成功 | `score`(整数分,非正文) |
|
||||
| `growth_plan_viewed` | 打开 `/growth-plan` 且列表加载结束 | — |
|
||||
| `growth_plan_created` | 创建计划成功 | — |
|
||||
| `growth_plan_checkin` | 今日打卡成功 | — |
|
||||
|
||||
禁止参数含计划 title/focus/note 明文。
|
||||
|
||||
---
|
||||
|
||||
@@ -142,6 +147,6 @@ Tab 陪伴 → /companion
|
||||
|---|---|
|
||||
| Packages | `CompanionPage` · `internal/companion` · moods 表 |
|
||||
| 实现 | GET `/solar-terms/today` · POST `/moods` · GET `/moods/today` · H5 心情 UI |
|
||||
| Gaps | 成长计划、推送、心情趋势 |
|
||||
| Label | 陪伴 P2 心情已接;真支付仍后置 |
|
||||
| Gaps | 推送(后置 / Ops-E) |
|
||||
| Label | Feature Complete(P2:节气 + 心情 + 近七日轨迹;成长计划见 `/growth-plan`) |
|
||||
| Process Review | 2026-08-02 [P1-PROCESS-REVIEW](P1-PROCESS-REVIEW.md) · 心情已按产品「其他先做」落地 |
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Feature Spec: 小程序咨询域(原生 Go)
|
||||
|
||||
> Status: `Active` · ECR-050
|
||||
|
||||
## 1. 功能定义
|
||||
|
||||
小程序首页/咨询/测评/订单/我的资料不再打 Java。Go 用 PostgreSQL 提供与原 `/psychic/*` 相同的字段合同。
|
||||
|
||||
## 2. Business Rules
|
||||
|
||||
| ID | Rule |
|
||||
|---|---|
|
||||
| C1 | 未登录可看 banner、资讯、测评列表、咨询师、档期、协议 |
|
||||
| C2 | 登录后才能交卷、关注、下单、改资料、反馈 |
|
||||
| C3 | 下单锁时段;取消未支付订单释放时段 |
|
||||
| C4 | 金额单位:分;支付 openid = `users.wx_openid` |
|
||||
| C5 | 测评仅单选计分,按分数区间匹配结果 |
|
||||
| C6 | 协议路径保持历史拼写 `procotol` |
|
||||
|
||||
## 3. API
|
||||
|
||||
全部挂在 `/api/v1/psychic/*`,字段与原 Java App VO 一致(见 ECR-050 BD)。
|
||||
@@ -45,9 +45,9 @@
|
||||
↓
|
||||
进入 /scales/:slug
|
||||
↓
|
||||
加载题目
|
||||
↓
|
||||
逐题作答(须全部完成)
|
||||
已有结果? → 直接展示最近结果 +「重新测试」
|
||||
↓(无结果 / 点重测)
|
||||
加载题目 · 逐题作答(须全部完成)
|
||||
↓
|
||||
无 Self? → 引导建档
|
||||
↓
|
||||
@@ -60,10 +60,13 @@ POST result → 展示丰富结果
|
||||
|
||||
| 子能力 | P1 |
|
||||
|---|---|
|
||||
| 测试入口(探索 Tab) | ✓ |
|
||||
| 测试列表 | ✓ |
|
||||
| 测试入口(探索 Tab · 首页宫格) | ✓ · 产品向 `mbti-lite`;探索主路径为 curated 题库(A 集) |
|
||||
| 测试列表 | ✓ · 探索「题库精选」宫格(每类 1~2)+「题库分类」;分类页 `/explore/bank/:key` |
|
||||
| 题库范围(A) | ✓ 人格 / 情绪能力 / 智能 / 生活与关系;**不含**抑郁焦虑强迫躁狂双相等临床筛查 |
|
||||
| 问题流程 | ✓ |
|
||||
| 答题保存(服务端结果落库) | ✓ |
|
||||
| 最近结果回看 | ✓ GET `/scales/{slug}/result`;有结果进页不重复作答 |
|
||||
| 重新测试 | ✓ 结果页按钮 → 清空草稿再答;新结果落库并覆盖展示 |
|
||||
| 中断恢复 | ✓ localStorage 草稿(`scaleDraft`);提交后清除 |
|
||||
| 结果生成(丰富结构) | ✓ |
|
||||
| 免费层 | ✓ 全量 result |
|
||||
@@ -79,8 +82,10 @@ POST result → 展示丰富结果
|
||||
|
||||
| 路由 | 页面 |
|
||||
|---|---|
|
||||
| `/explore` | ExplorePage |
|
||||
| `/scales/:slug` | ScalePage |
|
||||
| `/explore` | ExplorePage(题库精选宫格 + 题库分类 + 其它工具) |
|
||||
| `/explore/bank/:category` | ExploreBankCategoryPage · curated 题库分类列表 |
|
||||
| `/explore/:category` | ExploreCategoryPage · 产品工具分类(解码/星座等) |
|
||||
| `/scales/:slug` | ScalePage(含 bank slug) |
|
||||
|
||||
```text
|
||||
/scales/:slug
|
||||
@@ -116,6 +121,13 @@ POST result → 展示丰富结果
|
||||
| R5 | result 含 label/summary/overview/dimensions/tips/scripts/growth_plan/faq |
|
||||
| R6 | 结果「不是固定标签」需在文案中提示 |
|
||||
| R7 | 作答过程写入本地草稿(按 slug);提交成功后清除;刷新可恢复未提交答案 |
|
||||
| R8 | 同一用户同一 slug(含 curated 题库 slug)若已有 `scale_results`,再次进入直接展示**最近一次**结果,并提供「重新测试」;未点重测不得自动进入答题 |
|
||||
| R9 | `mbti-lite` 产品展示名统一为「MBTI测试」(首页宫格 / 探索入口 / 量表 title) |
|
||||
| R10 | **标准版 `mbti-lite`**:开源 OEJTS 1.2 · **32 题**(四维各 8)· 双极 1–5 Likert;按维累加,阈值判出 E/I·S/N·T/F·J/P 一侧,合成四字母类型;**免费** |
|
||||
| R11 | **完整版 `mbti-full`**:60 题(四维各 15)· 须**成长会员**;未开通时 GET 返回 `locked=true` 且无题目;提交返回 403 |
|
||||
| R12 | 禁止使用官方 MBTI® 版权题干;结果须提示「不是固定标签」;题库重大更新须 soft-delete 旧 `scale_results` |
|
||||
| R13 | curated 题库(`scalebank`)仅含 A 集非临床探索量表;文案须声明「非诊断」;临床类(抑郁/焦虑/强迫等)不得进入 C 端 |
|
||||
| R14 | curated 题库作答走同一 `/scales/:slug`;完成后再次点击入口须遵守 R8(只看结果或显式重测),不得每次从头作答 |
|
||||
|
||||
---
|
||||
|
||||
@@ -134,6 +146,7 @@ POST result → 展示丰富结果
|
||||
|---|---|---|
|
||||
| GET | `/api/v1/scales` | 列表 |
|
||||
| GET | `/api/v1/scales/{slug}` | 题目 |
|
||||
| GET | `/api/v1/scales/{slug}/result` | 当前用户该量表最近一次结果;无则 404 |
|
||||
| POST | `/api/v1/scales/{slug}/result` | 提交计分 |
|
||||
|
||||
---
|
||||
@@ -144,18 +157,27 @@ POST result → 展示丰富结果
|
||||
|---|---|---|
|
||||
| 看列表/题目 | ✓ | ✓ |
|
||||
| 提交结果 | ✗ | ✓ |
|
||||
| `mbti-full` 作答 | ✗(须成长会员) | ✓(会员 active) |
|
||||
|
||||
---
|
||||
|
||||
## 11. 埋点
|
||||
|
||||
| Event | 触发 |
|
||||
|---|---|
|
||||
| `scale_list_viewed` | 探索列表 |
|
||||
| `scale_started` | 进入作答 |
|
||||
| `scale_completed` | 出结果 |
|
||||
| `scale_share_clicked` | 分享 |
|
||||
| `scale_cta_relation` / `scale_cta_ask` | 导流 |
|
||||
经统一 `track()`;非 P1 核心 5 事件。禁止参数含题干全文、答案明文、档案 ID。
|
||||
|
||||
| Event | 触发 | 可选 params |
|
||||
|---|---|---|
|
||||
| `scale_list_viewed` | 打开 `/explore` 且题库 catalog 加载成功 | — |
|
||||
| `scale_bank_category_viewed` | 打开 `/explore/bank/:category` 且分类加载成功 | `category`(key) |
|
||||
| `scale_started` | 用户点开始进入作答(含「重新测试」后再开始) | `slug` · `access`: free\|member |
|
||||
| `scale_completed` | 提交计分成功并展示结果 | `slug` · `access`: free\|member |
|
||||
| `scale_result_reopened` | 再次进入已有结果直接展示(R8,未重测) | `slug` |
|
||||
| `scale_retake_clicked` | 点「重新测试」 | `slug` |
|
||||
| `scale_locked_viewed` | 会员锁页展示(如 mbti-full) | `slug` |
|
||||
| `scale_share_clicked` | 结果页打开分享 | `slug` |
|
||||
| `scale_cta_relation` / `scale_cta_ask` | 结果导流(若 UI 有) | `slug` |
|
||||
|
||||
`page_view` 对 `/explore` · `/explore/bank/*` · `/scales/*` 由路由自动采集。
|
||||
|
||||
---
|
||||
|
||||
@@ -165,6 +187,14 @@ POST result → 展示丰富结果
|
||||
**When** 答完提交
|
||||
**Then** 返回 label 与 overview/tips 等丰富字段
|
||||
|
||||
**Given** 已提交过结果
|
||||
**When** 再次进入 `/scales/{slug}`
|
||||
**Then** 直接展示最近结果与「重新测试」;不进入答题
|
||||
|
||||
**Given** 结果页点「重新测试」并完成提交
|
||||
**When** 再次进入
|
||||
**Then** 展示新结果
|
||||
|
||||
**Given** 未答完
|
||||
**When** 提交
|
||||
**Then** 前端拦截;不成功落库
|
||||
@@ -186,7 +216,8 @@ POST result → 展示丰富结果
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| Packages | `internal/scale` · `service/scale` · `ExplorePage` · `ScalePage` |
|
||||
| Seeds | communication-style · emotion-pattern |
|
||||
| Seeds | communication-style · emotion-pattern · **mbti-lite(OEJTS 32)** · **mbti-full(60·会员)** |
|
||||
| Gaps | 结果付费墙若要做须先改 Spec;全量 §11 埋点未挂(核心漏斗见 analytics) |
|
||||
| Tests | score/result L1;`scaleDraft.spec`;Scale 流程组件测 |
|
||||
| Process Review | 草稿恢复已实现 · P1 收口 |
|
||||
| Tests | score/result L1;`ScoreJungian`;`scaleDraft.spec`;Scale 流程组件测 |
|
||||
| Process Review | OEJTS 标准/完整双轨 · 最近结果回看 · P1 收口 |
|
||||
| Credit | OEJTS / Open Psychometrics · openjung MIT |
|
||||
|
||||
@@ -62,9 +62,10 @@
|
||||
|
||||
```text
|
||||
/
|
||||
├── Hero / 品牌
|
||||
├── 建档 CTA
|
||||
├── 功能入口
|
||||
├── 全局顶栏:透明愈心谷 Logo(AppHeader,全站)
|
||||
├── 「自己」卡片标题展示账号昵称(默认意象词+场景词;档案页可改)
|
||||
├── 穿衣指数 · 颜色搭配 · 养生推荐
|
||||
├── 功能入口(4 列固定网格 · 多行换行 · 禁止横向滑动)
|
||||
└── (可选)推荐内容
|
||||
```
|
||||
|
||||
@@ -90,27 +91,36 @@ Empty:首页本身是入口,不因无档案空白死页。
|
||||
| R2 | 不展示内部运维信息(API 连接状态等) |
|
||||
| R3 | 入口文案符合 lexicon(个人画像/关系理解/成长会员…) |
|
||||
| R4 | Tab 五名冻结:首页·探索·问答·陪伴·我的 |
|
||||
| R5 | 「自己」卡片:穿衣指数 / 颜色搭配 / 养生推荐;有 Self 生日时按生日+**本地日历**+**十二时辰**易经种子生成;**每一时辰准点切换**;无档案或 LLM 不可用则本地回退 |
|
||||
| R6 | 文案禁止占卜/算命恐吓与医疗疗效承诺;卦象仅作节律意象 |
|
||||
| R7 | 贴士按 `user × 时辰起点` 持久缓存;GET 优先读缓存**即时返回**;缓存未命中时先回退/旧值,后台异步生成写入,禁止每次打开同步等 LLM |
|
||||
| R8 | 响应含 `shichen` / `shichen_name` / `valid_until`(下一时辰起点);前端在 `valid_until` 自动静默刷新 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 数据模型影响
|
||||
|
||||
经首页建档时写 `profiles`(见 profile Spec)。
|
||||
经首页建档时写 `profiles`。`home_daily_tips(user_id, shichen_start, tips jsonb)` 缓存时辰贴士。
|
||||
|
||||
---
|
||||
|
||||
## 9. API 需求
|
||||
|
||||
复用 `POST /profiles`、`POST /reports/portrait`;无专用 home API。
|
||||
| Method | Path | 说明 |
|
||||
|---|---|---|
|
||||
| GET | `/api/v1/home/tools` | 宫格(已有) |
|
||||
| GET | `/api/v1/home/daily-tips` | 自己卡片贴士(读缓存;含 valid_until) |
|
||||
| — | 复用 | `POST /profiles`、`POST /reports/portrait` |
|
||||
|
||||
---
|
||||
|
||||
## 10. 权限设计
|
||||
|
||||
| 能力 | Visitor |
|
||||
|---|---|
|
||||
| 浏览首页 | ✓ |
|
||||
| 建档并生成画像 | ✓ |
|
||||
| 能力 | Visitor | User |
|
||||
|---|---|---|
|
||||
| 浏览首页 | ✓ | ✓ |
|
||||
| 建档并生成画像 | 需登录 | ✓ |
|
||||
| daily-tips(个性化) | 回退文案 | 有 Self 生日则 LLM |
|
||||
|
||||
---
|
||||
|
||||
@@ -134,10 +144,26 @@ Empty:首页本身是入口,不因无档案空白死页。
|
||||
**When** 提交主 CTA
|
||||
**Then** 进入画像基础结果路径
|
||||
|
||||
**Given** 已登录且有 Self 生日、该时辰已有缓存
|
||||
**When** GET `/home/daily-tips`
|
||||
**Then** 立即返回缓存(含 clothing/palette/wellness / valid_until),不阻塞 LLM
|
||||
|
||||
**Given** 时辰切换到点
|
||||
**When** 前端到达 `valid_until`
|
||||
**Then** 静默刷新;穿衣/颜色/养生随新时辰更新
|
||||
|
||||
**Given** 无档案或无 LLM
|
||||
**When** GET `/home/daily-tips`
|
||||
**Then** `source=fallback` 且页面不白屏
|
||||
|
||||
---
|
||||
|
||||
## 13. AI 开发前检查
|
||||
|
||||
- [x] lexicon
|
||||
- [x] 不恐吓 / 不算命话术
|
||||
- [x] OpenAPI 已登记 `/home/daily-tips`
|
||||
|
||||
- [x] Spec 齐全
|
||||
|
||||
---
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Feature Spec: 意象卡片
|
||||
|
||||
> Status: `Active`(设计)· Map: `2.8 意象卡片 [P2]` · Phase: `P2`
|
||||
> Status: `Active` · Map: `2.8 意象卡片 [P2]` · Phase: `P2 Complete`
|
||||
> 规范:[../feature-design.md](../feature-design.md) · 队列:[P2-BACKLOG.md](P2-BACKLOG.md)
|
||||
> 竞品对照:塔罗体系(能力同构;**UI 禁止「塔罗」入口名**)
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
|
||||
- [x] Spec 齐全 · 禁用塔罗入口已写清
|
||||
- [x] lexicon ImageCard
|
||||
- [ ] 内容库 seed 与 OpenAPI(编码时)
|
||||
- [x] 内容库 seed 与 OpenAPI(编码时)
|
||||
|
||||
---
|
||||
|
||||
@@ -181,5 +181,6 @@
|
||||
| 复用 | ShareSheet · membership/orders · Explore 入口 |
|
||||
| 工作量 | 卡面文案/视觉资产最大;宜先 22~78 张小库 MVP |
|
||||
| Packages | `internal/imagecard` · `ImageCardPage` `/cards` |
|
||||
| 实现 | scenes/quota/draw API · 报告 type=`image_card` · 日配额表 · seed 12 卡 |
|
||||
| 编码顺序 | P2-BACKLOG 切片 3 Done |
|
||||
| 实现 | scenes/quota/draw API · 报告 type=`image_card` · 日配额 · ≥78 牌(手写底稿+确定性扩容)· ≥8 场景 |
|
||||
| Gaps | 全手写美术资产;推送 |
|
||||
| Label | Feature Complete(P2) |
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
# Feature Spec: 用户文字输入合规校验
|
||||
|
||||
> Status: `Active` · Map: `横切 · 安全/合规` · Phase: `P2`
|
||||
> 关联:[lexicon.md](../lexicon.md) · [.ai/security.md](../../security.md) · account-auth / profile / ask / companion
|
||||
|
||||
---
|
||||
|
||||
## 1. 功能定义
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| Name | 文字输入合规(Text Compliance) |
|
||||
| Purpose | 所有用户提交的**自由文字**在服务端统一做合法性/合规校验;前端可做即时提示,**以后端拒绝为准** |
|
||||
| Business Goal | 降低 XSS/注入、恐吓与医疗疗效话术、垃圾刷屏进入 DB 与模型上下文的风险 |
|
||||
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| 昵称 · 档案显示名 · 问答 content · 心情/打卡 note · 成长计划 title/focus · 邀请 display_name · 意象场景自填 | 纯数字字段(生日年月日、分数、经纬度) |
|
||||
| 长度 · 格式清洗 · XSS/控制字符 · lexicon 硬禁止 · 简易刷屏特征 | 完整内容审核平台 / 人工审 / 语音 |
|
||||
| 错误码统一 | 改开放登录策略本身 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 用户价值
|
||||
|
||||
1. 避免有害/违规文案入库与进模型。
|
||||
2. 提交失败时得到可读中文原因。
|
||||
3. N/A(安全横切,非付费面)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 用户角色
|
||||
|
||||
Visitor / User / Admin 凡提交自由文字均适用(Admin 运营文案可后续加强;本 Spec **先 C 端用户 API**)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 用户流程
|
||||
|
||||
```text
|
||||
用户输入文字 →(可选)前端即时校验
|
||||
→ API Handler/Service 调用 textsafe.Check(kind, text)
|
||||
→ OK:规范化后入库/进模型
|
||||
→ 拒绝:HTTP 400 · code 40060 · message 可读原因
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5–6. 页面 / 状态
|
||||
|
||||
各既有表单;Error 态展示 `message`。无新页面。
|
||||
|
||||
---
|
||||
|
||||
## 7. Business Rules
|
||||
|
||||
| ID | Rule |
|
||||
|---|---|
|
||||
| R1 | **后端必须校验**所有用户自由文字;前端校验不得替代后端 |
|
||||
| R2 | 种类与上限(rune):`nickname` 1–16;`display_name` 1–24;`ask_content` 1–2000;`note` 0–200;`title` 1–40;`focus` 0–40;`scene` 1–80 |
|
||||
| R3 | 拒绝控制字符(允许消息内 `\n` `\t`);拒绝 HTML/脚本片段(如 `<script`、`javascript:`) |
|
||||
| R4 | 命中 lexicon 硬禁止子串(占卜/算命/改命恐吓/疗效承诺/「测测」品牌自称等)→ 拒绝 |
|
||||
| R5 | 刷屏特征:连续相同字 ≥8,或可见字符全相同且长度 ≥6 → 拒绝 |
|
||||
| R6 | 密码字段不做 lexicon,仅拒空字节;手机号走既有数字规则 |
|
||||
| R7 | 校验通过后写库的是 **Normalize** 后的文本(Trim;压缩首尾空白) |
|
||||
| R8 | 错误码:`40060`;文案过 lexicon(勿用恐吓语气) |
|
||||
|
||||
---
|
||||
|
||||
## 8. 数据模型
|
||||
|
||||
无新表。进程内可选短时计数(本版刷屏以内容特征为主,不做跨请求配额表)。
|
||||
|
||||
---
|
||||
|
||||
## 9. API
|
||||
|
||||
既有写接口;拒绝时统一:
|
||||
|
||||
```json
|
||||
{ "code": 40060, "message": "文案不合规:…", "data": null }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 权限
|
||||
|
||||
同各业务接口鉴权;校验在鉴权之后、写库之前。
|
||||
|
||||
---
|
||||
|
||||
## 11. 埋点
|
||||
|
||||
可选:`text_rejected{kind}`(本版可不接)。
|
||||
|
||||
---
|
||||
|
||||
## 12. 验收
|
||||
|
||||
| Given | When | Then |
|
||||
|---|---|---|
|
||||
| nickname 含「算命」 | PATCH /auth/me | 40060 |
|
||||
| ask content 含 `<script` | POST messages | 40060 |
|
||||
| display_name 正常「小愈」 | POST profile | 200 |
|
||||
| note=`啊啊啊啊啊啊啊啊` | POST mood | 40060 |
|
||||
|
||||
---
|
||||
|
||||
## 13. AI 检查
|
||||
|
||||
- [x] lexicon
|
||||
- [x] 后端权威
|
||||
- [x] 不扩开放登录
|
||||
|
||||
---
|
||||
|
||||
## 14. Implementation
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| Package | `apps/api/internal/textsafe` |
|
||||
| Mirror | `@yuxingu/utils` `validateUserText`(即时提示) |
|
||||
| Wire | auth · profile · ask · companion · growth · synastry accept |
|
||||
@@ -1,6 +1,6 @@
|
||||
# Feature Spec: 身心节律
|
||||
|
||||
> Status: `Active`(设计)· Map: `2.7 身心节律 [P2]`(= `2.5 身心探索` 产品化主入口)· Phase: `P2`
|
||||
> Status: `Active` · Map: `2.7 身心节律 [P2]`(= `2.5 身心探索` 产品化主入口)· Phase: `P2 Complete`
|
||||
> 规范:[../feature-design.md](../feature-design.md) · 队列:[P2-BACKLOG.md](P2-BACKLOG.md)
|
||||
> 竞品对照:命理体系之生活向(能力同构,禁止算命/流年吉凶叙事)
|
||||
|
||||
@@ -98,6 +98,10 @@ CTA:节气陪伴 / 问答「生活节奏」/ 分享
|
||||
| R5 | 推荐用语:体质倾向、生活建议、节律、平衡 |
|
||||
| R6 | 可展示五行隐喻,须标注探索/非医疗 |
|
||||
| R7 | 与星象性格、个人画像内容可互相链,不互相覆盖主路径 |
|
||||
| R8 | **体质/五行倾向**随生日确定;**今日/本周生活建议**按**自然日(CST)**刷新(本周焦点随星期变) |
|
||||
| R9 | GET `/reports/latest` 与 GET `/reports/{id}`(type=rhythm):`as_of` ≠ 当日则**原 id 原地更新**时效段并落库;同日即时返回 |
|
||||
| R10 | `summary` 含 `as_of` · `valid_until`(次日 00:00 CST);前端到点静默刷新;**不按十二时辰** |
|
||||
| R11 | `summary.wuxing` 必含五行分布 `bars`(与愈心解码同源算法)及主/辅倾向;缺字段时 GET 原地补全 |
|
||||
|
||||
---
|
||||
|
||||
@@ -108,6 +112,7 @@ CTA:节气陪伴 / 问答「生活节奏」/ 分享
|
||||
| `growth_reports.type` | `rhythm` / `life_rhythm` |
|
||||
| 或 Constitution 专用表 | 若需独立聚合,实现时 ADR |
|
||||
| 禁止 | `luck_score`、病名诊断字段 |
|
||||
| 报告 JSON | `as_of` · `valid_until` · `today_tip` · `week_focus` |
|
||||
|
||||
---
|
||||
|
||||
@@ -155,13 +160,21 @@ CTA:节气陪伴 / 问答「生活节奏」/ 分享
|
||||
**When** 扫 summary+detail
|
||||
**Then** 符合 lexicon
|
||||
|
||||
**Given** 已有 rhythm 报告且 `as_of` 为昨日
|
||||
**When** GET latest
|
||||
**Then** `today_tip` / `week_focus` 按今日更新;报告 `id` 不变
|
||||
|
||||
**Given** 用户停留在 `/rhythm` 跨自然日
|
||||
**When** 到达 `valid_until`
|
||||
**Then** 前端静默刷新建议文案
|
||||
|
||||
---
|
||||
|
||||
## 13. AI 开发前检查
|
||||
|
||||
- [x] Spec 齐全 · 与 2.5 关系已写清
|
||||
- [x] lexicon LifeRhythm
|
||||
- [ ] OpenAPI/erd(编码时)
|
||||
- [x] OpenAPI/erd(编码时)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
# Feature Spec: 账户生命周期 / UserStatus(Ops · ECR-013B)
|
||||
|
||||
> Status: `Active`(**Closed** · Feature Complete)· Map: `§7 运营后台` · Phase: `Ops-D`
|
||||
> Parent: **WAVE0-FROZEN** (`27f27a1`) · Predecessor: **ECR-013A Closed**
|
||||
> ESS: `docs/ECR/ECR-013B-account-lifecycle.md`(**Closed**)
|
||||
> Capability: `AccountLifecycle` · BC: `Identity_Profile`
|
||||
> 模板:`docs/WAVE0/contracts/OPS-CONTRACT-TEMPLATE.md`
|
||||
|
||||
---
|
||||
|
||||
## ESS 门禁
|
||||
|
||||
1. Change Level = **L2** → 已 Approved + Coding auth + Implemented + **Closed**
|
||||
2. ~~Contract Definition only~~ — 已完成
|
||||
3. 实现证据:`docs/TEST_REPORT/ECR-013B.md` · `docs/CODE_REVIEW/ECR-013B.md`
|
||||
|
||||
---
|
||||
|
||||
## L0 Capability
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|------|
|
||||
| Capability ID | `AccountLifecycle` |
|
||||
| Purpose | 以可审计状态机管理 C 端用户账户启停与封禁,阻断违规会话 |
|
||||
| Why now | `users.status` 字段已存在但无运营迁移与强制拒绝;013A 权限面就绪后可挂状态写权限 |
|
||||
| Non-goals | soft-delete / `deleted`;UGC 社区封禁;真支付;Admin 账号启停(已有 admin.status);推送通知 |
|
||||
|
||||
---
|
||||
|
||||
## L1 Bounded Context
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|------|
|
||||
| Primary BC | `Identity_Profile` |
|
||||
| owns | `User` · `UserStatus` · `AccountStateTransition` |
|
||||
| does_not_own | `AdminRole` · `Membership` · `Payment` · `BanRecord`(Account_Risk 后置加深) |
|
||||
| allowed | `Admin_Auth_Audit.write_audit`(经 admin 调用) |
|
||||
| forbidden | `Payment` · `Membership.write` · soft-delete User |
|
||||
|
||||
权威:`.ai/domain/boundary-rules.md` · `Account_Risk` 仅允许经明确服务触发 `UserStatus.transition`。
|
||||
|
||||
---
|
||||
|
||||
## 1. 功能定义
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|------|
|
||||
| Name | Account Lifecycle / UserStatus |
|
||||
| Purpose | 运营可迁移用户状态;非 active 会话在 C 端被拒绝 |
|
||||
| Business Goal | 风险处置最小闭环,不引入社区/UGC |
|
||||
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| 状态机 `active/disabled/banned/suspended` | soft-delete / GDPR 擦除 |
|
||||
| Admin 迁移 API + AuditLog + Transition 记录 | 站内推送 / 短信 |
|
||||
| DeviceAuth / Bearer 对非 active 拒绝 | AdminAccount.status(013A 外) |
|
||||
| 权限码 `admin.users.status.write` | 行级数据 ACL |
|
||||
|
||||
---
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| Entity | 不变式 / 状态机 |
|
||||
|--------|----------------|
|
||||
| `UserStatus` | 取值冻结:`active` · `disabled` · `banned` · `suspended`;非法值拒写 |
|
||||
| `User.status` | 与 `UserStatus` 同值;默认 `active`(已有列) |
|
||||
| `AccountStateTransition` | 只追加;记录 from→to · admin_id · reason · created_at |
|
||||
|
||||
### 合法迁移
|
||||
|
||||
```text
|
||||
active → disabled | banned | suspended
|
||||
disabled → active | banned
|
||||
suspended → active | banned | disabled
|
||||
banned → active | disabled
|
||||
```
|
||||
|
||||
其它边 → **400**。同状态写 → **400**(幂等拒绝,避免空审计噪音)。
|
||||
|
||||
### C 端效应
|
||||
|
||||
| Status | DeviceAuth / 已登录 Bearer |
|
||||
|--------|------------------------------|
|
||||
| `active` | 放行 |
|
||||
| `disabled` / `banned` / `suspended` | **401**(或 403 统一码,实现轮定一)+ 不可发新 session |
|
||||
|
||||
---
|
||||
|
||||
## L3 API Contract(意图 · 实现轮同步 OpenAPI)
|
||||
|
||||
前缀:`/api/v1/admin` · AdminAuth · 信封 `{code,message,data}`
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| POST | `/users/:id/status` | `admin.users.status.write` | 迁移 UserStatus;写 Transition + AuditLog |
|
||||
| GET | `/users/:id/status-transitions` | `admin.users.read` | 最近迁移列表(limit) |
|
||||
|
||||
既有 `GET /users` · `GET /users/:id` 已暴露 `status` — 保持;实现轮确认枚举文档化。
|
||||
|
||||
`contract_diff`:`docs/CONTRACT_DIFF/ECR-013B.yaml`
|
||||
|
||||
RBAC catalog **additive**:`admin.users.status.write` → 种子写入 `super_admin`(migration)。
|
||||
|
||||
---
|
||||
|
||||
## L4 Acceptance Criteria
|
||||
|
||||
### Functional
|
||||
|
||||
| ID | Given | When | Then |
|
||||
|----|-------|------|------|
|
||||
| AC-F-01 | 用户 `active` | POST status=`banned` + reason | 200;GET user.status=`banned` |
|
||||
| AC-F-02 | 用户 `banned` | POST status=`active` | 200;可再次 DeviceAuth |
|
||||
| AC-F-03 | 非法边(如 `active`→`active`) | POST | **400** |
|
||||
| AC-F-04 | GET status-transitions | — | 含最近 from/to/admin/reason |
|
||||
|
||||
### Security
|
||||
|
||||
| ID | Given | When | Then |
|
||||
|----|-------|------|------|
|
||||
| AC-S-01 | Admin 无 `admin.users.status.write` | POST status | **403** + deny audit |
|
||||
| AC-S-02 | 用户 `banned` | C 端带原 Bearer 访问受保护 API | **401/403** |
|
||||
| AC-S-03 | 仅 DeviceAuth 无 Admin | POST `/admin/users/:id/status` | **401** |
|
||||
| AC-S-04 | 无 Admin session | GET transitions | **401** |
|
||||
|
||||
### Performance
|
||||
|
||||
| ID | Given | When | Then |
|
||||
|----|-------|------|------|
|
||||
| AC-P-01 | transitions ≤1000 行/用户 | GET transitions limit=50 | 本机 P95 **< 500ms** |
|
||||
|
||||
### Observability
|
||||
|
||||
| ID | Given | When | Then |
|
||||
|----|-------|------|------|
|
||||
| AC-O-01 | 迁移成功 | — | AuditLog action=`users.status.transition` |
|
||||
| AC-O-02 | 迁移成功 | — | `account_state_transitions` 有对应行 |
|
||||
|
||||
---
|
||||
|
||||
## Forbidden(本切片)
|
||||
|
||||
- soft-delete / `deleted` 状态
|
||||
- 真支付 · UGC · Prompt · 兑换码 · Crisis 深化
|
||||
- 改 Admin RBAC 模型(仅 **additive** 一枚 permission)
|
||||
- 自动开下一 ECR
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes(实现轮才执行)
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| Migration | YES(transitions 表;permission 种子;必要时 CHECK/注释枚举) |
|
||||
| Packages | service account/lifecycle · DeviceAuth/session 拒绝 · admin handler · admin-h5 用户详情最小 CTA |
|
||||
| Depends | ECR-013A Closed(permission middleware) |
|
||||
@@ -20,9 +20,11 @@
|
||||
| 用户列表 / 详情(档案摘要) | 首页运营位 / 工具配置 CMS |
|
||||
| 订单列表 | 优惠券 · 退款工单流 |
|
||||
| 成长会员只读 + **授予/延长**(mock 履约) | 真支付渠道配置 |
|
||||
| 操作审计日志 | 细粒度 RBAC(多角色矩阵) |
|
||||
| 操作审计日志 | 真支付渠道配置 |
|
||||
| `apps/admin-h5` 桌面友好壳 | 小程序后台 |
|
||||
|
||||
> Phase E(ECR-010):RBAC / 封禁 / 推送占位见 [ops-system.md](ops-system.md)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 用户价值
|
||||
@@ -206,7 +208,19 @@ Phase A 可先 `console`/本地;不挡验收。
|
||||
| Phase | 内容 |
|
||||
|---|---|
|
||||
| **A(本 ECR)** | 登录 · 用户 · 订单 · 授予会员 · 审计 · admin-h5 壳 |
|
||||
| **B(ECR-007)** | 自有埋点 · 管理端「数据」看板 — Spec `ops-analytics.md` |
|
||||
| **C(ECR-008)** | 首页宫格 CRUD · 测评上下架 — Spec `ops-content.md`(Approved) |
|
||||
| **B(ECR-007 Closed)** | 自有埋点 · 管理端「数据」看板 — Spec `ops-analytics.md` |
|
||||
| **C(ECR-008 Closed)** | 首页宫格 CRUD · 测评上下架 — Spec `ops-content.md` |
|
||||
| **E(ECR-013A Closed)** | Admin RBAC — Spec `ops-rbac.md` · Parent WAVE0-FROZEN |
|
||||
| **F(ECR-013B Closed)** | AccountLifecycle — Spec `ops-account-lifecycle.md` |
|
||||
| **G(ECR-014 Closed)** | MembershipPlan — Spec `ops-membership-plan.md` |
|
||||
| **H(ECR-015 Closed)** | RedemptionCode — Spec `ops-redemption-code.md` |
|
||||
| **I(ECR-016 Closed)** | UserIntelligence — Spec `ops-user-intelligence.md` |
|
||||
| **J(ECR-017 Closed)** | AskOperations — Spec `ops-ask-operations.md` |
|
||||
| **K(ECR-018 Closed)** | Entitlement — Spec `ops-entitlement.md` |
|
||||
| **L(ECR-019 Closed)** | ContentSafety FilterRule — Spec `ops-content-safety.md` |
|
||||
| **M(ECR-020 Closed)** | QualityFeedback — Spec `ops-quality-feedback.md` |
|
||||
| **N(ECR-021 Closed)** | AICoreConfig SystemPrompt — Spec `ops-ai-core-config.md` |
|
||||
| **O(ECR-022 Closed)** | CrisisCare CrisisPolicy — Spec `ops-crisis-care.md` |
|
||||
| 后置 | Knowledge·Tools 写面 / CrisisEvent / 真支付(Loop 续跑) |
|
||||
| D | 订单筛选 · 展示价 · 退款只读(另开 ECR) |
|
||||
| E | RBAC · 封禁 · 推送占位(另开 ECR) |
|
||||
| 后置 | 封禁加深(Account_Risk)· 推送占位 |
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: AICoreConfig · SystemPrompt(Ops · ECR-021)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-021 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-020 Closed
|
||||
> Capability: `AICoreConfig` · BC: `Ask_Ops`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
Prompt 在线编辑/发布 · KnowledgeSource/Chunk · ToolDefinition · 切换运行时引擎 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `SystemPrompt` | code 唯一;body 为模板文本;active/system;本切片只读 |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/ai/system-prompts` | `admin.ai_config.read` | 列表 |
|
||||
| GET | `/admin/ai/system-prompts/:id` | 同上 | 详情(含 body) |
|
||||
|
||||
## Migration
|
||||
|
||||
`000022`:`system_prompts` + 种子 `ask_default` + 授予权限
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含 ask_default |
|
||||
| AC-F-02 | get 返回 body 非空 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无 ai_config.read → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-021.yaml`
|
||||
@@ -1,7 +1,7 @@
|
||||
# Feature Spec: 运营行为分析(Ops-B)
|
||||
|
||||
> Status: `Active` · Map: `§7 运营后台` · Phase: `Ops-B`
|
||||
> ESS:`docs/ECR/ECR-007-ops-analytics.md`(Approved · L2)· BD-2026-007 Approved
|
||||
> ESS:`docs/ECR/ECR-007-ops-analytics.md`(**Closed** · L2)· BD-2026-007 Approved
|
||||
> 关联:[ops-admin.md](ops-admin.md) · [analytics.md](analytics.md) · [cece-frontend-re/complete-design/40-ops-commerce.md](cece-frontend-re/complete-design/40-ops-commerce.md)
|
||||
|
||||
---
|
||||
@@ -118,7 +118,7 @@ analytics_daily_page(可选汇总)
|
||||
- 卡片:DAU、新增、会话数、人均会话时长
|
||||
- 图:日活趋势;页面均停留 TOP
|
||||
- 表:页面明细、退出页 TOP、点击 TOP
|
||||
- 漏斗:画像完成 → 深度 CTA → 支付成功
|
||||
- 漏斗:探索列表 → 开始作答 → 量表完成 → 画像完成 → 深度 CTA → 支付成功
|
||||
|
||||
视觉:愈心谷色系;品牌仅 logo,无「运营后台」字样。
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: AskOperations(Ops · ECR-017)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-017 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-016 Closed
|
||||
> Capability: `AskOperations` · BC: `Ask_Ops`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
改写/删除消息正文 · SystemPrompt/Knowledge 配置 · QualityFeedback 写回 · AICoreConfig · 真支付 · UGC
|
||||
|
||||
## L2 读模型
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `AskSessionView` | 线程元数据 + message_count(列表) |
|
||||
| 会话详情 | 只读消息序列(role/content/created_at) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/ask/threads` | `admin.ask.read` | 列表(可选 `user_id`) |
|
||||
| GET | `/admin/ask/threads/:id` | `admin.ask.read` | 会话 meta(不含原文) |
|
||||
| GET | `/admin/ask/threads/:id/messages` | `admin.ask.transcript.read` | 对话原文(审计 `ask.transcript.read`) |
|
||||
|
||||
## Migration
|
||||
|
||||
`000019`:为 `super_admin` 授予 `admin.ask.read`(无新业务表)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | 有消息线程 → list 含该 thread · message_count≥1 |
|
||||
| AC-F-02 | detail 返回 user+assistant 消息 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无 ask.read → 403 |
|
||||
| AC-P-01 | list < 500ms 本机 |
|
||||
| AC-O-01 | N/A 只读(无写审计强制) |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-017.yaml`
|
||||
@@ -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`
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: OpsCMS · Banner(Ops · ECR-024 只读基线)
|
||||
|
||||
> Status: `Active`(**ECR-024 Closed** · 只读)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-023 Closed
|
||||
> Capability: `OpsCMS` · BC: `Ops_CMS_NoUGC`
|
||||
> 授权(只读队列):`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
> **写面:** [ops-banner-write.md](ops-banner-write.md)(**ECR-041** · Write-Wave)
|
||||
|
||||
## Non-goals(本只读 Spec)
|
||||
|
||||
Banner 写发布(见 ECR-041)· FeedSlot · ScheduledPublication · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `Banner` | code 唯一;placement ∈ {home,explore,ask};active/system;本切片只读 |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/cms/banners` | `admin.cms.read` | 只读 |
|
||||
| GET | `/admin/cms/banners/{id}` | `admin.cms.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000025`:表 + 种子(若有) + 授予 admin.cms.read
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-024.yaml`
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: ContentSafety · BlockPolicy(Ops · ECR-029)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-029 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-028 Closed
|
||||
> Capability: `ContentSafety` · BC: `Content_Safety`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
策略写发布 · 用户侧硬拦截上线 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `BlockPolicy` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/content-safety/block-policies` | `admin.content_safety.read` | 只读 |
|
||||
| GET | `/admin/content-safety/block-policies/{id}` | `admin.content_safety.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000030`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-029.yaml`
|
||||
@@ -0,0 +1,48 @@
|
||||
# Feature Spec: 运营商业加深(Ops-D)
|
||||
|
||||
> Status: `Active` · Map: `§7 Phase D` · Phase: `Ops-D` · ECR: `ECR-009`
|
||||
> 规范:[../feature-design.md](../feature-design.md)
|
||||
> 上游:Ops-A/B/C(ECR-006/007/008)
|
||||
|
||||
---
|
||||
|
||||
## 1. 功能定义
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| Name | 运营商业加深 Ops-D |
|
||||
| Purpose | 订单可筛选;套餐展示价可配;退款状态只读可见 |
|
||||
| Business Goal | 运营无需改库即可查单与维护展示价 |
|
||||
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| 订单筛选:status / kind / from–to / user_id | 真支付 · 退款工单流转 |
|
||||
| `refund_status` 只读字段 | 优惠券 · 发票 |
|
||||
| 会员套餐展示价 CRUD(分) | RBAC(Ops-E) |
|
||||
|
||||
---
|
||||
|
||||
## 2. 验收
|
||||
|
||||
**Given** 库内多状态订单
|
||||
**When** `GET /api/v1/admin/orders?status=paid&kind=membership&from=&to=`
|
||||
**Then** 仅返回匹配项,且含 `refund_status`
|
||||
|
||||
**Given** Admin 配置 `monthly` 展示价
|
||||
**When** `PUT /api/v1/admin/membership/plan-prices`
|
||||
**Then** `GET` 返回新价;不改历史 `orders.amount_cents`
|
||||
|
||||
---
|
||||
|
||||
## 3. 页面
|
||||
|
||||
| 路由 | 说明 |
|
||||
|---|---|
|
||||
| `/orders` | 增加筛选条 + 退款状态列 |
|
||||
| `/pricing` | 套餐展示价表 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 非目标
|
||||
|
||||
真支付网关 · 退款执行 · Ops-E 权限矩阵 · UGC
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: ContentSafety · FilterRule(Ops · ECR-019)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-019 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-018 Closed
|
||||
> Capability: `ContentSafety` · BC: `Content_Safety`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
ModerationCase 写回 · CrisisPolicy 配置 · 真 NLP/厂商审核 · UGC · 真支付 · 用户侧硬拦截上线(本切片仅运营只读 + 试匹配)
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `FilterRule` | code 唯一;category ∈ {crisis,abuse,spam,pii};action ∈ {flag,block,escalate};system 种子不可本切片删除 |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/content-safety/filter-rules` | `admin.content_safety.read` | 列表 |
|
||||
| GET | `/admin/content-safety/filter-rules/:id` | 同上 | 详情 |
|
||||
| POST | `/admin/content-safety/evaluate` | 同上 | 试匹配(不写工单) |
|
||||
|
||||
## Migration
|
||||
|
||||
`000020`:`filter_rules` + 种子规则 + 授予 `admin.content_safety.read`
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含 system 种子 ≥1 |
|
||||
| AC-F-02 | evaluate 命中种子 pattern → matches 非空 |
|
||||
| AC-F-03 | get 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无 content_safety.read → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | evaluate 不写 Audit(只读试匹配) |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-019.yaml`
|
||||
@@ -1,7 +1,7 @@
|
||||
# Feature Spec: 运营内容配置(Ops-C)
|
||||
|
||||
> Status: `Active` · Map: `§7 运营后台` · Phase: `Ops-C`
|
||||
> ESS:`docs/ECR/ECR-008-ops-content.md`(Approved · L2)· BD-2026-008 Approved
|
||||
> ESS:`docs/ECR/ECR-008-ops-content.md`(**Closed** · L2)· BD-2026-008 Approved
|
||||
> 关联:[ops-admin.md](ops-admin.md) · [ops-analytics.md](ops-analytics.md) · [home.md](home.md) · [explore-test.md](explore-test.md)
|
||||
|
||||
---
|
||||
@@ -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) |
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: CrisisCare · CrisisPolicy(Ops · ECR-022)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-022 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-021 Closed
|
||||
> Capability: `CrisisCare` · BC: `Content_Safety`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
CrisisEvent 入库工单 · InterventionOutcome · 策略在线编辑 · 医疗诊断结论 · UGC · 真支付 · 用户侧硬熔断上线
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `CrisisPolicy` | code 唯一;severity ∈ {high,critical};action ∈ {escalate,block,show_helpline};helpline_text 可选;本切片只读 |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/crisis/policies` | `admin.crisis.read` | 列表 |
|
||||
| GET | `/admin/crisis/policies/:id` | 同上 | 详情 |
|
||||
| POST | `/admin/crisis/evaluate` | 同上 | 试匹配(不写 CrisisEvent) |
|
||||
|
||||
## Migration
|
||||
|
||||
`000023`:`crisis_policies` + 种子 + 授予权限
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含 system 种子 ≥1 |
|
||||
| AC-F-02 | evaluate 命中 pattern → matches 非空 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无 crisis.read → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | evaluate 不写 Audit/Event |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-022.yaml`
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: CrisisCare · CrisisEvent(Ops · ECR-031)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-031 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-030 Closed
|
||||
> Capability: `CrisisCare` · BC: `Content_Safety`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
事件写入工单流 · 医疗诊断 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `CrisisEvent` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/crisis/events` | `admin.crisis.read` | 只读 |
|
||||
| GET | `/admin/crisis/events/{id}` | `admin.crisis.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000032`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-031.yaml`
|
||||
@@ -0,0 +1,36 @@
|
||||
# Feature Spec: Entitlement(Ops · ECR-018)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-018 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-017 Closed
|
||||
> Capability: `CommerceEntitlement` · BC: `Membership_Orders`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
真支付 · 改订单/退款 · 新建权益矩阵表 · UGC · 改报告正文 · ask_pack SKU
|
||||
|
||||
## L2 读模型(无 migration)
|
||||
|
||||
| 概念 | 来源 |
|
||||
|------|------|
|
||||
| `Entitlement` | Membership + DeepAccess 列表 + ask_paid_quota 聚合 |
|
||||
| flags | `report_detail_via_membership` · `deep_access_count` |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/users/:id/entitlements` | `admin.users.read` | 用户权益只读视图 |
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | 授予会员后 flags.report_detail_via_membership=true |
|
||||
| AC-F-02 | 有 deep_access 时 deep_accesses 非空或 count≥1 |
|
||||
| AC-F-03 | 无会员无深度 → membership.active=false 且 count=0 仍 200 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-P-01 | GET < 500ms 本机 |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-018.yaml`
|
||||
@@ -0,0 +1,40 @@
|
||||
# Feature Spec: OpsCMS · FeedSlot 写面(Ops · ECR-042)
|
||||
|
||||
> Status: `Active`(**ECR-042 Closed**)
|
||||
> Map: `§7` · Capability: `OpsCMS` · BC: `Ops_CMS_NoUGC`
|
||||
> Write-Wave: `docs/WAVE0/WRITE_WAVE_AUTHORIZATION.md`
|
||||
> Predecessor: ECR-025 Closed · ECR-041 Closed
|
||||
|
||||
## Goal
|
||||
|
||||
运营可创建/更新/上下架 FeedSlot;C 端可读 active 槽位;首页主信息流区按 `home.main`(或 placement=home 的 active 槽)显隐;失败回退「仍展示推荐区」。
|
||||
|
||||
## In / Out
|
||||
|
||||
| In | Out |
|
||||
|----|-----|
|
||||
| Admin POST/PUT feed-slots · `admin.cms.write` | Banner 再扩 · ScheduledPublication 写 |
|
||||
| C 端 GET `/home/feed-slots` | UGC 内容流正文 CMS · soft-delete |
|
||||
| 首页:无 active home 槽 → 隐藏推荐区;API 失败 → 仍显示 | 真支付 · Crisis/Handoff · 新权限模型 |
|
||||
|
||||
## Domain
|
||||
|
||||
复用 `ops_feed_slots`:`code` 唯一 · `slot_key` · `placement` ∈ {home,explore,ask} · `active` · `system`(system 不可改 code)。
|
||||
|
||||
## API
|
||||
|
||||
| Method | Path | Perm |
|
||||
|--------|------|------|
|
||||
| GET | `/admin/cms/feed-slots*` | cms.read |
|
||||
| POST/PUT | `/admin/cms/feed-slots*` | cms.write |
|
||||
| GET | `/home/feed-slots?placement=home` | DeviceAuth |
|
||||
|
||||
无 DELETE;下架 `active=false`。
|
||||
|
||||
## AC
|
||||
|
||||
AC-F create/update/conflict/invalid · AC-S 401/403 · AC-A audit · AC-C 首页显隐与失败回退 · AC-O 无 Banner 合并 / 无 soft-delete
|
||||
|
||||
## Migration
|
||||
|
||||
无新表;权限已在 `000051`。本切片 **不新增 migration 文件**(Max 保持 `000051`)。
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: OpsCMS · FeedSlot(Ops · ECR-025)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-025 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-024 Closed
|
||||
> Capability: `OpsCMS` · BC: `Ops_CMS_NoUGC`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
FeedSlot 写发布 · ScheduledPublication · UGC · 真支付 · Banner 写
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `FeedSlot` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/cms/feed-slots` | `admin.cms.read` | 只读 |
|
||||
| GET | `/admin/cms/feed-slots/{id}` | `admin.cms.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000026`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-025.yaml`
|
||||
@@ -0,0 +1,72 @@
|
||||
# Feature Spec: GrowthInsights · FunnelDefinition 写面(Ops · ECR-047)
|
||||
|
||||
> Status: `Active`(**Implemented · ECR-047 Closed**)
|
||||
> Map: `§7` · Capability: `GrowthInsights` · BC: `Analytics_OpsB`
|
||||
> Auth: `docs/WAVE0/ECR-047_WRITE_AUTHORIZATION.md`(**仅 ECR-047**)
|
||||
> Predecessor: ECR-039 Closed(只读)· ECR-046 Closed
|
||||
> 关联:[ops-funnel-definition.md](ops-funnel-definition.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标
|
||||
|
||||
运营可 **创建 / 更新 / 上下架** `FunnelDefinition`(漏斗目录);写鉴权 + 审计;**无**新 C 端路由。
|
||||
|
||||
**Closed 后立即 STOP**,不自动 ECR-048。
|
||||
|
||||
## 2. In / Out
|
||||
|
||||
| In | Out |
|
||||
|----|-----|
|
||||
| Admin POST/PUT `/admin/analytics/funnel-definitions*` | ReportTemplate 写 |
|
||||
| 加法 `admin.growth.write` | SystemPrompt · Knowledge · Chunk |
|
||||
| 复用表 `funnel_definitions` | soft-delete · 真支付 · UGC |
|
||||
| 审计 | 题干 · Crisis/Handoff |
|
||||
| | 自动 ECR-048 · 新 C 端路由 |
|
||||
|
||||
## 3. Domain
|
||||
|
||||
| 字段 | 规则 |
|
||||
|------|------|
|
||||
| `code` | 唯一;`^[a-z][a-z0-9_]{1,62}$`;`system=true` **不可改 code** |
|
||||
| `title` | 必填 · ≤128 |
|
||||
| `active` | `false` = 下架(唯一下架手段) |
|
||||
| `system` | 种子行;禁止物理删除 |
|
||||
|
||||
## 4. API
|
||||
|
||||
| Method | Path | 权限 |
|
||||
|--------|------|------|
|
||||
| GET | `/admin/analytics/funnel-definitions` · `/{id}` | `admin.growth.read` |
|
||||
| POST | `/admin/analytics/funnel-definitions` | `admin.growth.write` |
|
||||
| PUT | `/admin/analytics/funnel-definitions/{id}` | `admin.growth.write` |
|
||||
|
||||
无 DELETE · 无新 C 端路径。
|
||||
|
||||
## 5. Permission / Migration
|
||||
|
||||
- Migration `000056_ops_funnel_definition_write`:授予 `super_admin` → `admin.growth.write`
|
||||
- 编码时占号(Max=`000055` → `000056`)
|
||||
|
||||
## 6. UI
|
||||
|
||||
admin-h5 漏斗定义页:列表 + 新建/编辑/上下架。
|
||||
|
||||
## 7. AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | POST → list/get 可见 |
|
||||
| AC-F-02 | PUT active=false → list 仍可见且 active=false |
|
||||
| AC-F-03 | 重复 code → 409 |
|
||||
| AC-S-01/02 | 401;仅 growth.read → POST 403 |
|
||||
| AC-A-01 | 写产生审计 |
|
||||
| AC-O-01 | 无 soft-delete · 无 ReportTemplate/Prompt 写路径 |
|
||||
|
||||
## 8. Closed 后
|
||||
|
||||
**立即 STOP**。ECR-048 须新 Candidate Review + Human 拍板。
|
||||
|
||||
## 9. Trace
|
||||
|
||||
ECR-047 · BD-2026-047 · CONTRACT_DIFF · ECR-047_WRITE_AUTHORIZATION
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: GrowthInsights · FunnelDefinition(Ops · ECR-039)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-039 Closed**)
|
||||
> **写面:** [ops-funnel-definition-write.md](ops-funnel-definition-write.md)(**ECR-047 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-038 Closed
|
||||
> Capability: `GrowthInsights` · BC: `Analytics_OpsB`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
漏斗写配置 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `FunnelDefinition` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/analytics/funnel-definitions` | `admin.growth.read` | 只读 |
|
||||
| GET | `/admin/analytics/funnel-definitions/{id}` | `admin.growth.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000040`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-039.yaml`
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: AskOperations · HandoffCase(Ops · ECR-033)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-033 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-032 Closed
|
||||
> Capability: `AskOperations` · BC: `Ask_Ops`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
转人工写流 · 顾问执业 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `HandoffCase` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/ask/handoffs` | `admin.ask.read` | 只读 |
|
||||
| GET | `/admin/ask/handoffs/{id}` | `admin.ask.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000034`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-033.yaml`
|
||||
@@ -0,0 +1,95 @@
|
||||
# Feature Spec: ExploreConfig · ImageCardDeck 写面(Ops · ECR-045)
|
||||
|
||||
> Status: `Active`(**Implemented · ECR-045 Closed**)
|
||||
> Map: `§7` · Capability: `ExploreConfig` · BC: `Explore_Reports`
|
||||
> Auth: `docs/WAVE0/ECR-045_WRITE_AUTHORIZATION.md`(Human 批准 · **仅 ECR-045**)
|
||||
> Predecessor: ECR-037 Closed(只读)· ECR-044 Closed(Rhythm 写)
|
||||
> 关联:[ops-image-card-deck.md](ops-image-card-deck.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标
|
||||
|
||||
运营可 **创建 / 更新 / 上下架** `ImageCardDeck`(牌组目录);写操作鉴权 + 审计;C 端可读 active deck 并影响 `/cards` 可用性;失败回退「现网可抽」。
|
||||
|
||||
**Closed 后立即 STOP**,不自动 ECR-046。
|
||||
|
||||
## 2. In / Out
|
||||
|
||||
| In | Out |
|
||||
|----|-----|
|
||||
| Admin POST/PUT `/admin/explore/image-card-decks*` | **牌面/单卡内容 CRUD** · Star / Rhythm / Scale |
|
||||
| 复用 `admin.explore.write` | SystemPrompt · Knowledge · Chunk |
|
||||
| 复用表 `image_card_decks` | soft-delete · 真支付 · UGC |
|
||||
| C 端 GET active decks | Crisis / Handoff 写 |
|
||||
| `/cards`:无 active → 空态禁抽卡 CTA;失败 → 回退可抽 | 自动 ECR-046 |
|
||||
| 审计 | 新权限子系统 |
|
||||
|
||||
## 3. Domain
|
||||
|
||||
| 字段 | 规则 |
|
||||
|------|------|
|
||||
| `code` | 唯一;`^[a-z][a-z0-9_]{1,62}$`;`system=true` 不可改 code |
|
||||
| `title` | 必填 · ≤128 |
|
||||
| `active` | `false` = 下架(唯一下架手段) |
|
||||
| `system` | 种子行;禁止物理删除 |
|
||||
|
||||
## 4. API
|
||||
|
||||
### Admin
|
||||
|
||||
| Method | Path | 权限 |
|
||||
|--------|------|------|
|
||||
| GET | `/admin/explore/image-card-decks` · `/{id}` | `admin.explore.read` |
|
||||
| POST | `/admin/explore/image-card-decks` | `admin.explore.write` |
|
||||
| PUT | `/admin/explore/image-card-decks/{id}` | `admin.explore.write` |
|
||||
|
||||
无 DELETE。
|
||||
|
||||
### C 端
|
||||
|
||||
| Method | Path | Auth | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/api/v1/cards/decks` | DeviceAuth | 仅 `active=true`;按 code 排序 |
|
||||
|
||||
## 5. C 端生效
|
||||
|
||||
| 条件 | user-h5 `/cards` |
|
||||
|------|------------------|
|
||||
| ≥1 active | 保持现网抽卡 |
|
||||
| 成功且 0 active | 「意象牌组暂未开放」空态;禁用抽卡 CTA |
|
||||
| 请求失败 | **回退**不阻断抽卡 |
|
||||
|
||||
## 6. Permission / Migration
|
||||
|
||||
- Migration `000054_ops_image_card_deck_write`:幂等确认 `super_admin` → `admin.explore.write`
|
||||
- 编码时占号(Max=`000053`)
|
||||
|
||||
## 7. UI
|
||||
|
||||
| 端 | 行为 |
|
||||
|----|------|
|
||||
| admin-h5 意象牌组页 | 列表 + 新建/编辑/上下架(仅 Deck) |
|
||||
| user-h5 `/cards` | 按 §5 |
|
||||
|
||||
## 8. AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | POST → list/get 可见 |
|
||||
| AC-F-02 | PUT active=false → C 端不含 |
|
||||
| AC-F-03 | 有 active → C 端非空 |
|
||||
| AC-F-04 | 重复 code → 409 |
|
||||
| AC-S-01/02 | 401;仅 read → POST 403 |
|
||||
| AC-A-01 | 写产生审计 |
|
||||
| AC-C-01 | 全下架后空态/禁 CTA |
|
||||
| AC-C-02 | API 失败回退可抽 |
|
||||
| AC-O-01 | 无牌面写路径 · 无 soft-delete |
|
||||
|
||||
## 9. Closed 后
|
||||
|
||||
**立即 STOP**。ECR-046 须新 Candidate Review + Human 拍板。
|
||||
|
||||
## 10. Trace
|
||||
|
||||
ECR-045 · BD-2026-045 · CONTRACT_DIFF · ECR-045_WRITE_AUTHORIZATION
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: ExploreConfig · ImageCardDeck(Ops · ECR-037)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-037 Closed**)
|
||||
> **写面:** [ops-image-card-deck-write.md](ops-image-card-deck-write.md)(**ECR-045 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-036 Closed
|
||||
> Capability: `ExploreConfig` · BC: `Explore_Reports`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
牌组写发布 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `ImageCardDeck` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/explore/image-card-decks` | `admin.explore.read` | 只读 |
|
||||
| GET | `/admin/explore/image-card-decks/{id}` | `admin.explore.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000038`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-037.yaml`
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: CrisisCare · InterventionOutcome(Ops · ECR-032)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-032 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-031 Closed
|
||||
> Capability: `CrisisCare` · BC: `Content_Safety`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
干预写回 · 医疗诊断 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `InterventionOutcome` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/crisis/interventions` | `admin.crisis.read` | 只读 |
|
||||
| GET | `/admin/crisis/interventions/{id}` | `admin.crisis.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000033`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-032.yaml`
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: AICoreConfig · KnowledgeChunk(Ops · ECR-027)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-027 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-026 Closed
|
||||
> Capability: `AICoreConfig` · BC: `Ask_Ops`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
Embedding · 上传切块 · 运行时 RAG 接线 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `KnowledgeChunk` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/ai/knowledge-chunks` | `admin.ai_config.read` | 只读 |
|
||||
| GET | `/admin/ai/knowledge-chunks/{id}` | `admin.ai_config.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000028`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-027.yaml`
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: AICoreConfig · KnowledgeSource(Ops · ECR-023)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-023 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-022 Closed
|
||||
> Capability: `AICoreConfig` · BC: `Ask_Ops`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
KnowledgeChunk / Embedding · 源文件上传 · 在线编辑发布 · ToolDefinition · 运行时 RAG 接线 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `KnowledgeSource` | code 唯一;source_kind ∈ {faq,policy,guide};active/system;本切片只读目录,不含 Chunk |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/ai/knowledge-sources` | `admin.ai_config.read` | 列表 |
|
||||
| GET | `/admin/ai/knowledge-sources/:id` | 同上 | 详情 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000024`:`knowledge_sources` + 种子 `ask_grounding`(权限已由 000022 授予)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含 ask_grounding |
|
||||
| AC-F-02 | get 返回 source_kind 合法 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无 ai_config.read → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-023.yaml`
|
||||
@@ -0,0 +1,77 @@
|
||||
# Feature Spec: 会员套餐 MembershipPlan(Ops · ECR-014)
|
||||
|
||||
> Status: `Active`(Loop continuous · Approved · coding)· Map: `§7` · Phase: `Ops-D`
|
||||
> Parent: **WAVE0-FROZEN** · Predecessor: **ECR-013B Closed**
|
||||
> ESS: `docs/ECR/ECR-014-membership-plan.md`
|
||||
> Capability: `CommerceEntitlement` · BC: `Membership_Orders`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
---
|
||||
|
||||
## ESS 门禁
|
||||
|
||||
1. L2 · Loop continuous:契约齐 → 自动 Approve + coding
|
||||
2. **不含** 真支付 · 兑换码 · Entitlement 矩阵 · ask_pack 价目表
|
||||
|
||||
---
|
||||
|
||||
## L0 Capability
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|------|
|
||||
| Capability ID | `CommerceEntitlement` |
|
||||
| Purpose | 运营可配置成长会员套餐时长与标价(mock 履约仍用既有支付) |
|
||||
| Why now | planDays/金额硬编码;013B 完成后进入 Commerce 配置面最小切片 |
|
||||
| Non-goals | 真支付网关 · RedemptionCode · Entitlement 细权 · ask_pack |
|
||||
|
||||
---
|
||||
|
||||
## L1 Bounded Context
|
||||
|
||||
| Primary BC | `Membership_Orders` |
|
||||
| owns | `MembershipPlan` |
|
||||
| does_not_own | `UserStatus` · `Payment` 适配器 · `AdminRole` |
|
||||
| allowed | `Admin_Auth_Audit.write_audit` |
|
||||
| forbidden | 真支付 · UGC |
|
||||
|
||||
---
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| Entity | 不变式 |
|
||||
|--------|--------|
|
||||
| `MembershipPlan` | `code` ∈ {month,quarter,year} 本切片冻结;`duration_days`>0;`amount_cents`≥0;`active` 布尔 |
|
||||
|
||||
---
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/membership-plans` | `admin.membership.plans.read` | 列表 |
|
||||
| GET | `/admin/membership-plans/:code` | `admin.membership.plans.read` | 详情 |
|
||||
| PUT | `/admin/membership-plans/:code` | `admin.membership.plans.write` | 更新 title/days/amount/active + AuditLog |
|
||||
|
||||
履约:`GrantMembership` / membership `CreateOrder` 读表(缺行回退旧硬编码)。
|
||||
|
||||
`contract_diff`:`docs/CONTRACT_DIFF/ECR-014.yaml`
|
||||
|
||||
---
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | GET plans 含 month/quarter/year |
|
||||
| AC-F-02 | PUT month days/amount → GET 一致 |
|
||||
| AC-F-03 | GrantMembership 使用表内 duration_days |
|
||||
| AC-S-01 | 无 write 权限 PUT → 403 |
|
||||
| AC-S-02 | 无 Admin → 401 |
|
||||
| AC-P-01 | GET list P95 < 500ms 本机 |
|
||||
| AC-O-01 | PUT 成功 → AuditLog `membership.plans.update` |
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Migration `membership_plans` + RBAC additive permissions · admin-h5 最小列表编辑页
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: ContentSafety · ModerationCase(Ops · ECR-030)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-030 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-029 Closed
|
||||
> Capability: `ContentSafety` · BC: `Content_Safety`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
审核写回 · 真 NLP 厂商 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `ModerationCase` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/content-safety/cases` | `admin.content_safety.read` | 只读 |
|
||||
| GET | `/admin/content-safety/cases/{id}` | `admin.content_safety.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000031`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-030.yaml`
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: AdminGovernance · PrivacyRequest(Ops · ECR-034)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-034 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-033 Closed
|
||||
> Capability: `AdminGovernance` · BC: `Admin_Auth_Audit`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
隐私请求履约写 · soft-delete · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `PrivacyRequest` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/privacy/requests` | `admin.privacy.read` | 只读 |
|
||||
| GET | `/admin/privacy/requests/{id}` | `admin.privacy.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000035`:表 + 种子(若有) + 授予 admin.privacy.read
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-034.yaml`
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: QualityFeedback(Ops · ECR-020)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-020 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-019 Closed
|
||||
> Capability: `AskOperations` · BC: `Ask_Ops`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
改写消息正文 · SystemPrompt/Knowledge · HandoffCase 全量 · AICoreConfig · UGC 广场 · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `QualityFeedback` | 绑定 thread(可选 message);rating 1–5;tag ∈ {helpful,off_topic,unsafe,other};source ∈ {admin,user} |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/ask/feedback` | `admin.ask.read` | 列表 |
|
||||
| POST | `/admin/ask/threads/:id/feedback` | `admin.ask.feedback.write` | 运营提交 |
|
||||
| POST | `/ask/threads/:id/feedback` | DeviceAuth 用户 | C 端评分 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000021`:`ask_quality_feedback` + 授予 `admin.ask.feedback.write`
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | admin POST feedback → 200 · list 可见 |
|
||||
| AC-F-02 | user POST feedback → 200 |
|
||||
| AC-F-03 | 无效 rating → 400 |
|
||||
| AC-S-01 | 无 Admin → admin list 401 |
|
||||
| AC-S-02 | 无 feedback.write → admin POST 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | admin 提交写 AuditLog `ask.feedback.create` |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-020.yaml`
|
||||
@@ -0,0 +1,151 @@
|
||||
# Feature Spec: 运营后台 RBAC(Ops · ECR-013A)
|
||||
|
||||
> Status: `Active`(**Closed** · Feature Complete)· Map: `§7 运营后台` · Phase: `Ops-D`
|
||||
> Parent: **WAVE0-FROZEN** (`27f27a1`)
|
||||
> ESS: `docs/ECR/ECR-013A-admin-rbac.md`(**Closed**)
|
||||
> Capability: `AdminGovernance` · BC: `Admin_RBAC`
|
||||
> 模板:`docs/WAVE0/contracts/OPS-CONTRACT-TEMPLATE.md`
|
||||
|
||||
---
|
||||
|
||||
## ESS 门禁
|
||||
|
||||
1. Change Level = **L2** → 已 Approved + Coding auth + Implemented + **Closed**
|
||||
2. ~~Contract Definition only~~ — 已完成
|
||||
3. 实现证据:`docs/TEST_REPORT/ECR-013A.md` · `docs/CODE_REVIEW/ECR-013A.md`
|
||||
|
||||
---
|
||||
|
||||
## L0 Capability
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|------|
|
||||
| Capability ID | `AdminGovernance` |
|
||||
| Purpose | 以最小权限原则约束管理员可执行的运营动作 |
|
||||
| Why now | Ops-A 全员等价权限;进入 M1+ 前必须有权限面,否则越权不可治理 |
|
||||
| Non-goals | 用户账户启停(ECR-013B);兑换码;CMS;Ask Prompt;真支付;UGC |
|
||||
|
||||
---
|
||||
|
||||
## L1 Bounded Context
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|------|
|
||||
| Primary BC | `Admin_RBAC` |
|
||||
| owns | `AdminRole` · `AdminPermission` |
|
||||
| does_not_own | `User` · `Profile` · `UserStatus` · `Membership` · `Payment` |
|
||||
| allowed | `Admin_Auth_Audit.write_audit` |
|
||||
| forbidden | `Payment` · `Membership.write` · `DeviceAuth.user_token_issue` |
|
||||
|
||||
权威:`.ai/domain/boundary-rules.md`
|
||||
|
||||
---
|
||||
|
||||
## 1. 功能定义
|
||||
|
||||
| 字段 | 内容 |
|
||||
|------|------|
|
||||
| Name | Admin RBAC |
|
||||
| Purpose | 角色与权限点绑定;API 级强制鉴权;变更可审计 |
|
||||
| Business Goal | 支撑多运营角色,而不扩大 C 端攻击面 |
|
||||
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| Role CRUD(最小:list/get/update permissions) | UserStatus / 封禁(013B) |
|
||||
| `GET /admin/me` 返回 permissions | 细粒度数据行级 ACL |
|
||||
| 既有 admin 写操作挂 permission 检查 | 新业务模块权限爆炸式新增(另 ECR) |
|
||||
|
||||
---
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| Entity | 不变式 |
|
||||
|--------|--------|
|
||||
| `AdminRole` | `name` 唯一;系统角色 `super_admin` 不可删除 |
|
||||
| `AdminPermission` | 稳定字符串码(见下表);只增不改语义 |
|
||||
| `AdminAccount.role_id` | 每个账号恰好一个角色(本切片);无角色视为拒绝写操作 |
|
||||
|
||||
### Permission catalog(本切片冻结)
|
||||
|
||||
| Code | 覆盖既有能力 |
|
||||
|------|----------------|
|
||||
| `admin.users.read` | GET users / users/:id / stats |
|
||||
| `admin.users.membership.grant` | POST membership/grant |
|
||||
| `admin.users.ask_quota.grant` | POST ask-quota/grant |
|
||||
| `admin.orders.read` | GET orders |
|
||||
| `admin.audit.read` | GET audit-logs |
|
||||
| `admin.analytics.read` | GET analytics/*(Ops-B) |
|
||||
| `admin.content.write` | home tools / scales publish(Ops-C) |
|
||||
| `admin.roles.read` | GET roles |
|
||||
| `admin.roles.write` | 变更角色权限 |
|
||||
|
||||
`super_admin` 种子拥有上表全部。
|
||||
|
||||
---
|
||||
|
||||
## L3 API Contract(意图 · 实现轮同步 OpenAPI)
|
||||
|
||||
前缀:`/api/v1/admin` · AdminAuth · 信封 `{code,message,data}`
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/roles` | `admin.roles.read` | 角色列表 |
|
||||
| GET | `/roles/:id` | `admin.roles.read` | 角色 + permissions[] |
|
||||
| PUT | `/roles/:id/permissions` | `admin.roles.write` | 全量替换权限集;写 AuditLog |
|
||||
| GET | `/me` | (已登录) | **扩展**返回 `role` + `permissions[]` |
|
||||
|
||||
既有写接口:在实现轮挂上表 permission;缺权 → **403** + AuditLog(尝试记录)。
|
||||
|
||||
`contract_diff`:`docs/CONTRACT_DIFF/ECR-013A.yaml`
|
||||
|
||||
---
|
||||
|
||||
## L4 Acceptance Criteria
|
||||
|
||||
### Functional
|
||||
|
||||
| ID | Given | When | Then |
|
||||
|----|-------|------|------|
|
||||
| AC-F-01 | super_admin 已登录 | GET `/roles` | 200,含 `super_admin` |
|
||||
| AC-F-02 | 角色存在 | PUT permissions 合法集合 | 200;再次 GET 一致 |
|
||||
| AC-F-03 | GET `/me` | — | data 含 `permissions` 数组 |
|
||||
|
||||
### Security
|
||||
|
||||
| ID | Given | When | Then |
|
||||
|----|-------|------|------|
|
||||
| AC-S-01 | Admin 无 `admin.roles.write` | PUT `/roles/:id/permissions` | **403**;AuditLog 有拒绝或尝试记录 |
|
||||
| AC-S-02 | Admin 无 `admin.users.membership.grant` | POST membership/grant | **403** |
|
||||
| AC-S-03 | 仅 DeviceAuth | 访问 `/admin/roles` | **401** |
|
||||
| AC-S-04 | 删除 `super_admin` 角色 | 任意 API | **拒绝**(4xx) |
|
||||
|
||||
### Performance
|
||||
|
||||
| ID | Given | When | Then |
|
||||
|----|-------|------|------|
|
||||
| AC-P-01 | 角色数 N≤100 | GET `/roles` | 本机 integration 环境下 P95 **< 500ms** |
|
||||
|
||||
### Observability
|
||||
|
||||
| ID | Given | When | Then |
|
||||
|----|-------|------|------|
|
||||
| AC-O-01 | PUT permissions 成功 | — | AuditLog action 含 `roles.permissions.update` |
|
||||
| AC-O-02 | AC-S-01 触发 | — | AuditLog 可追溯 admin_id + path |
|
||||
|
||||
---
|
||||
|
||||
## Forbidden(本切片)
|
||||
|
||||
- UserStatus / AccountLifecycle(**ECR-013B**)
|
||||
- 真支付 · UGC · Prompt/RAG · 兑换码 · CMS Banner 新表
|
||||
- 改 DeviceAuth / C 端五 Tab
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes(实现轮才执行)
|
||||
|
||||
| 项 | 内容 |
|
||||
|----|------|
|
||||
| Migration | YES(roles / permissions 关联;accounts.role_id;种子 super_admin) |
|
||||
| Packages | `service/admin` · repo · middleware permission check · admin-h5 只读展示权限(最小) |
|
||||
| Parent | WAVE0-FROZEN |
|
||||
@@ -0,0 +1,43 @@
|
||||
# Feature Spec: 兑换码 RedemptionCode(Ops · ECR-015)
|
||||
|
||||
> Status: `Active`(Loop continuous · Approved · coding)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-014 Closed
|
||||
> Capability: `CommerceEntitlement` · BC: `Membership_Orders`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
真支付 · Entitlement 细权 · ask_pack 兑换 · UGC
|
||||
|
||||
## L2
|
||||
|
||||
| Entity | 不变式 |
|
||||
|--------|--------|
|
||||
| `RedemptionBatch` | label · plan_code∈membership_plans · quantity 1..100 |
|
||||
| `RedemptionCode` | code 唯一;status unused→redeemed\|disabled;redeemed 不可再兑 |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | Auth | 语义 |
|
||||
|--------|------|------|------|
|
||||
| POST | `/admin/redemption-batches` | `admin.membership.codes.write` | 批量生成 |
|
||||
| GET | `/admin/redemption-batches` | `admin.membership.codes.read` | 批次列表 |
|
||||
| GET | `/admin/redemption-batches/:id/codes` | `admin.membership.codes.read` | 码列表 |
|
||||
| POST | `/admin/redemption-codes/:id/disable` | `admin.membership.codes.write` | 作废 unused |
|
||||
| POST | `/membership/redeem` | DeviceAuth+已注册 | 兑码→延长会员 |
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | POST batch quantity=3 → 3 unused codes |
|
||||
| AC-F-02 | C端 redeem → membership active;码=redeemed |
|
||||
| AC-F-03 | 再兑同一码 → 400 |
|
||||
| AC-F-04 | disable unused → status=disabled;兑 → 400 |
|
||||
| AC-S-01 | 无 write → POST batch 403 |
|
||||
| AC-S-02 | 未登录兑码 → 401 |
|
||||
| AC-P-01 | GET batches < 500ms |
|
||||
| AC-O-01 | 生成 AuditLog `redemption.batch.create` |
|
||||
| AC-O-02 | 兑换可追溯 redeemed_by |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-015.yaml`
|
||||
@@ -0,0 +1,73 @@
|
||||
# Feature Spec: GrowthInsights · ReportTemplate 写面(Ops · ECR-048)
|
||||
|
||||
> Status: `Active`(**Implemented · ECR-048 Closed**)
|
||||
> Map: `§7` · Capability: `GrowthInsights` · BC: `Explore_Reports`
|
||||
> Auth: `docs/WAVE0/ECR-048_WRITE_AUTHORIZATION.md`(**仅 ECR-048**)
|
||||
> Predecessor: ECR-038 Closed(只读)· ECR-047 Closed(Funnel 写)
|
||||
> 关联:[ops-report-template.md](ops-report-template.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标
|
||||
|
||||
运营可 **创建 / 更新 / 上下架** `ReportTemplate`(报告模板目录);写鉴权 + 审计;**无**新 C 端路由。
|
||||
|
||||
**Closed 后立即 STOP**,不自动 ECR-049。
|
||||
|
||||
## 2. In / Out
|
||||
|
||||
| In | Out |
|
||||
|----|-----|
|
||||
| Admin POST/PUT `/admin/growth/report-templates*` | Funnel 再写 |
|
||||
| 复用 `admin.growth.write` | SystemPrompt · Knowledge · Chunk |
|
||||
| 复用表 `report_templates` | soft-delete · 真支付 · UGC |
|
||||
| 审计 | 题干 · Crisis/Handoff |
|
||||
| | 自动 ECR-049 · 新 C 端路由 |
|
||||
|
||||
## 3. Domain
|
||||
|
||||
| 字段 | 规则 |
|
||||
|------|------|
|
||||
| `code` | 唯一;`^[a-z][a-z0-9_]{1,62}$`;`system=true` **不可改 code** |
|
||||
| `title` | 必填 · ≤128 |
|
||||
| `scene` | 必填;`^[a-z][a-z0-9_]{0,30}$` · ≤32 |
|
||||
| `active` | `false` = 下架 |
|
||||
| `system` | 种子行;禁止物理删除 |
|
||||
|
||||
## 4. API
|
||||
|
||||
| Method | Path | 权限 |
|
||||
|--------|------|------|
|
||||
| GET | `/admin/growth/report-templates` · `/{id}` | `admin.growth.read` |
|
||||
| POST | `/admin/growth/report-templates` | `admin.growth.write` |
|
||||
| PUT | `/admin/growth/report-templates/{id}` | `admin.growth.write` |
|
||||
|
||||
无 DELETE · 无新 C 端路径。
|
||||
|
||||
## 5. Permission / Migration
|
||||
|
||||
- Migration `000057_ops_report_template_write`:幂等确认 `super_admin` → `admin.growth.write`
|
||||
- 编码时占号(Max=`000056` → `000057`)
|
||||
|
||||
## 6. UI
|
||||
|
||||
admin-h5 报告模板页:列表 + 新建/编辑/上下架。
|
||||
|
||||
## 7. AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | POST → list/get 可见 |
|
||||
| AC-F-02 | PUT active=false → list 仍可见且 active=false |
|
||||
| AC-F-03 | 重复 code → 409 |
|
||||
| AC-S-01/02 | 401;仅 growth.read → POST 403 |
|
||||
| AC-A-01 | 写产生审计 |
|
||||
| AC-O-01 | 无 soft-delete · 无 Funnel/Prompt 写路径 |
|
||||
|
||||
## 8. Closed 后
|
||||
|
||||
**立即 STOP**。ECR-049 须新 Candidate Review + Human 拍板。
|
||||
|
||||
## 9. Trace
|
||||
|
||||
ECR-048 · BD-2026-048 · CONTRACT_DIFF · ECR-048_WRITE_AUTHORIZATION
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: GrowthInsights · ReportTemplate(Ops · ECR-038)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-038 Closed**)
|
||||
> **写面:** [ops-report-template-write.md](ops-report-template-write.md)(**ECR-048 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-037 Closed
|
||||
> Capability: `GrowthInsights` · BC: `Explore_Reports`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
模板写发布 · 广告投放 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `ReportTemplate` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/growth/report-templates` | `admin.growth.read` | 只读 |
|
||||
| GET | `/admin/growth/report-templates/{id}` | `admin.growth.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000039`:表 + 种子(若有) + 授予 admin.growth.read
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-038.yaml`
|
||||
@@ -0,0 +1,98 @@
|
||||
# Feature Spec: ExploreConfig · RhythmConfig 写面(Ops · ECR-044)
|
||||
|
||||
> Status: `Active`(**Implemented · ECR-044 Closed**)
|
||||
> Map: `§7` · Capability: `ExploreConfig` · BC: `Explore_Reports`
|
||||
> Auth: `docs/WAVE0/ECR-044_WRITE_AUTHORIZATION.md`(Human 批准 · **仅 ECR-044**)
|
||||
> Predecessor: ECR-036 Closed(只读)· ECR-043 Closed(StarConfig 写)
|
||||
> 关联:[ops-rhythm-config.md](ops-rhythm-config.md) · [life-rhythm.md](life-rhythm.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标
|
||||
|
||||
运营可 **创建 / 更新 / 上下架** `RhythmConfig`;写操作鉴权 + 审计;C 端可读 active 配置并影响节律入口可用性;失败回退「现网可生成」。
|
||||
|
||||
验证 ExploreConfig 写面同构复用;**Closed 后立即 STOP**,不自动 ECR-045。
|
||||
|
||||
## 2. In / Out
|
||||
|
||||
| In | Out |
|
||||
|----|-----|
|
||||
| Admin POST/PUT `/admin/explore/rhythm-configs*` | **StarConfig / ImageCardDeck / ScaleDefinition** 一切 |
|
||||
| 复用权限 `admin.explore.write` | SystemPrompt · KnowledgeSource · Chunk · ToolDefinition |
|
||||
| 复用表 `rhythm_configs`(code/title/active/system) | soft-delete · 改节律引擎 · 真支付 · UGC |
|
||||
| C 端 GET active rhythm configs | Crisis / Handoff / ContentSafety 写 |
|
||||
| 节律页:无 active → 温和不可用态;API 失败 → 回退可生成 | 合并多概念 · 自动开 ECR-045 |
|
||||
| 审计 `admin_audit_logs` | 新权限子系统 |
|
||||
|
||||
## 3. Domain
|
||||
|
||||
| 字段 | 规则 |
|
||||
|------|------|
|
||||
| `code` | 唯一;`^[a-z][a-z0-9_]{1,62}$`;`system=true` 不可改 code |
|
||||
| `title` | 必填 · ≤128 |
|
||||
| `active` | `false` = 下架(唯一下架手段) |
|
||||
| `system` | 种子行;禁止物理删除 |
|
||||
|
||||
## 4. API
|
||||
|
||||
### Admin
|
||||
|
||||
| Method | Path | 权限 |
|
||||
|--------|------|------|
|
||||
| GET | `/admin/explore/rhythm-configs` · `/{id}` | `admin.explore.read`(保持) |
|
||||
| POST | `/admin/explore/rhythm-configs` | `admin.explore.write` |
|
||||
| PUT | `/admin/explore/rhythm-configs/{id}` | `admin.explore.write` |
|
||||
|
||||
无 DELETE。
|
||||
|
||||
### C 端
|
||||
|
||||
| Method | Path | Auth | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/api/v1/rhythm/configs` | DeviceAuth | 仅 `active=true`;按 code 排序 |
|
||||
|
||||
## 5. C 端生效(可观察)
|
||||
|
||||
| 条件 | user-h5 `/rhythm` |
|
||||
|------|-------------------|
|
||||
| 至少 1 条 active | 保持现网生成路径 |
|
||||
| 成功且 0 条 active | 展示「节律配置暂未开放」类空态;禁用主生成 CTA |
|
||||
| 请求失败 | **回退**:不阻断现网生成 |
|
||||
|
||||
不改节律引擎、不改报告 JSON 契约。
|
||||
|
||||
## 6. Permission / Migration
|
||||
|
||||
- Migration `000053_ops_rhythm_config_write`:幂等确认 `super_admin` → `admin.explore.write`(043 已授)
|
||||
- 编码时占号(当前 Max=`000052`)
|
||||
|
||||
## 7. UI
|
||||
|
||||
| 端 | 行为 |
|
||||
|----|------|
|
||||
| admin-h5 节律配置页 | 列表 + 新建/编辑/上下架(仅 RhythmConfig) |
|
||||
| user-h5 `/rhythm` | 按 §5 显隐 CTA |
|
||||
|
||||
## 8. AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | POST 合法 → list/get 可见 |
|
||||
| AC-F-02 | PUT `active=false` → C 端 list 不含 |
|
||||
| AC-F-03 | 有 active → C 端 list 非空;节律页可生成 |
|
||||
| AC-F-04 | 重复 code → 409 |
|
||||
| AC-S-01/02 | 401;仅 read → POST 403 |
|
||||
| AC-A-01 | 写产生审计 |
|
||||
| AC-C-01 | 全下架后节律页空态/禁 CTA |
|
||||
| AC-C-02 | C 端 API 失败不白屏、仍可走回退生成 |
|
||||
| AC-O-01 | 无 Star/Card/Scale/Prompt 写路径;无 soft-delete |
|
||||
|
||||
## 9. Closed 后
|
||||
|
||||
**立即 STOP** Continuous Loop。
|
||||
ECR-045 必须重新 Candidate Review + Human 单独拍板。
|
||||
|
||||
## 10. Trace
|
||||
|
||||
ECR-044 · BD-2026-044 · PRODUCT_SPEC · CONTRACT_DIFF · ECR-044_WRITE_AUTHORIZATION
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: ExploreConfig · RhythmConfig(Ops · ECR-036)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-036 Closed**)
|
||||
> **写面:** [ops-rhythm-config-write.md](ops-rhythm-config-write.md)(**ECR-044**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-035 Closed
|
||||
> Capability: `ExploreConfig` · BC: `Explore_Reports`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
配置写发布 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `RhythmConfig` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/explore/rhythm-configs` | `admin.explore.read` | 只读 |
|
||||
| GET | `/admin/explore/rhythm-configs/{id}` | `admin.explore.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000037`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-036.yaml`
|
||||
@@ -0,0 +1,68 @@
|
||||
# Feature Spec: ExploreConfig · ScaleDefinition 写面(Ops · ECR-046)
|
||||
|
||||
> Status: `Active`(**Implemented · ECR-046 Closed**)
|
||||
> Auth: `docs/WAVE0/ECR-046_WRITE_AUTHORIZATION.md`(**仅 ECR-046**)
|
||||
> Predecessor: ECR-040 只读 · ECR-008 status PATCH · ECR-045 Closed
|
||||
> 关联:[ops-scale-definition.md](ops-scale-definition.md) · [ops-content.md](ops-content.md)
|
||||
|
||||
## 1. 目标
|
||||
|
||||
运营可在 Explore 侧 **创建/更新量表元数据**(slug/title/description);**上下架仍走 ECR-008**。Closed 后 STOP。
|
||||
|
||||
## 2. In / Out
|
||||
|
||||
| In | Out |
|
||||
|----|-----|
|
||||
| POST/PUT `/admin/explore/scales*` | **PATCH status**(ECR-008 独占) |
|
||||
| 复用 `admin.explore.write` | 题干 / scale_questions |
|
||||
| 复用表 `scales` | soft-delete · Prompt/Knowledge/Chunk |
|
||||
| 创建默认 `status=draft` | 支付 · UGC · 自动 ECR-047 |
|
||||
| 审计 | 新权限子系统 |
|
||||
|
||||
## 3. 双通道矩阵(强制)
|
||||
|
||||
| API | 权限 | 字段 |
|
||||
|-----|------|------|
|
||||
| `POST/PUT /admin/explore/scales*` | `admin.explore.write` | slug · title · description |
|
||||
| `PATCH /admin/scales/{id}` | `admin.content.write` | **仅 status**(既有) |
|
||||
|
||||
## 4. Domain
|
||||
|
||||
| 字段 | 规则 |
|
||||
|------|------|
|
||||
| `slug` | 唯一;`^[a-z][a-z0-9-]{1,62}$` |
|
||||
| `title` | 必填 · ≤128 |
|
||||
| `description` | ≤512 · 可空串 |
|
||||
| `status` | 创建固定 `draft`;本刀 PUT **不得**改 status |
|
||||
|
||||
## 5. C 端可观察
|
||||
|
||||
| 条件 | 行为 |
|
||||
|------|------|
|
||||
| 新建 draft | C 端 published list **不含** |
|
||||
| ECR-008 PATCH → published | C 端 list **含**(既有 `/scales`) |
|
||||
| 不新增 C 端路由 | — |
|
||||
|
||||
## 6. Migration
|
||||
|
||||
`000054`→`000055_ops_scale_definition_write`:幂等确认 `admin.explore.write`
|
||||
|
||||
## 7. UI
|
||||
|
||||
admin-h5:量表元数据页(新建/编辑 slug·title·description);上下架仍在「内容」页。
|
||||
|
||||
## 8. AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | POST → list/get 可见 · status=draft |
|
||||
| AC-F-02 | PUT 改 title → get 反映;status 不变 |
|
||||
| AC-F-03 | 重复 slug → 409 |
|
||||
| AC-F-04 | draft 不在 C 端 published list;PATCH published 后出现 |
|
||||
| AC-S-01/02 | 401;仅 read → POST 403 |
|
||||
| AC-A-01 | 写产生审计 |
|
||||
| AC-O-01 | explore PUT 带 status 被忽略或不接受;无题干写;无 soft-delete |
|
||||
|
||||
## 9. Closed 后
|
||||
|
||||
立即 STOP · 禁自动 ECR-047
|
||||
@@ -0,0 +1,43 @@
|
||||
# Feature Spec: ExploreConfig · ScaleDefinition(Ops · ECR-040)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-040 Closed**)
|
||||
> **写面:** [ops-scale-definition-write.md](ops-scale-definition-write.md)(**ECR-046 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-039 Closed
|
||||
> Capability: `ExploreConfig` · BC: `Explore_Reports`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
PATCH status(已有 content.write)· 题干编辑 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `ScaleDefinition` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/explore/scales` | `admin.explore.read` 或 `admin.content.write` | 只读 |
|
||||
| GET | `/admin/explore/scales/{id}` | `admin.explore.read` 或 `admin.content.write` | 只读 |
|
||||
| GET | `/admin/scales` | `admin.explore.read` 或 `admin.content.write` | 只读(与 explore 同源) |
|
||||
|
||||
## Migration
|
||||
|
||||
Migration NO:复用 `scales` 表只读投影
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-040.yaml`
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: OpsCMS · ScheduledPublication(Ops · ECR-026)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-026 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-025 Closed
|
||||
> Capability: `OpsCMS` · BC: `Ops_CMS_NoUGC`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
定时发布写操作 · UGC · 真支付 · Banner/FeedSlot 写
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `ScheduledPublication` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/cms/publications` | `admin.cms.read` | 只读 |
|
||||
| GET | `/admin/cms/publications/{id}` | `admin.cms.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000027`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-026.yaml`
|
||||
@@ -0,0 +1,99 @@
|
||||
# Feature Spec: ExploreConfig · StarConfig 写面(Ops · ECR-043)
|
||||
|
||||
> Status: `Active`(**Implemented · ECR-043 Closed**)
|
||||
> Map: `§7` · Capability: `ExploreConfig` · BC: `Explore_Reports`
|
||||
> Auth: `docs/WAVE0/EXPLORE_CONFIG_WRITE_AUTHORIZATION.md`(Human 批准 · **仅 ECR-043**)
|
||||
> Predecessor: ECR-035 Closed(只读)· CMS 041–042 Closed
|
||||
> 关联:[ops-star-config.md](ops-star-config.md) · [star-profile.md](star-profile.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标
|
||||
|
||||
运营可 **创建 / 更新 / 上下架** `StarConfig`;写操作鉴权 + 审计;C 端可读 active 配置并影响星座入口可用性;失败回退「现网可生成」。
|
||||
|
||||
验证 ExploreConfig 写面与 CMS 同类闭环;**Closed 后立即 STOP**,不自动 ECR-044。
|
||||
|
||||
## 2. In / Out
|
||||
|
||||
| In | Out |
|
||||
|----|-----|
|
||||
| Admin POST/PUT `/admin/explore/star-configs*` | **RhythmConfig / ImageCardDeck / ScaleDefinition** 一切 |
|
||||
| 加法权限 `admin.explore.write` | SystemPrompt · KnowledgeSource · Chunk · ToolDefinition |
|
||||
| 复用表 `star_configs`(code/title/active/system) | soft-delete · 改引擎/宫位制 · 真支付 · UGC |
|
||||
| C 端 GET active star configs | Crisis / Handoff / ContentSafety 写 |
|
||||
| 星座页:无 active → 温和不可用态;API 失败 → 回退可生成 | 合并多概念 · 自动开 ECR-044 |
|
||||
| 审计 `admin_audit_logs` | 新权限子系统 |
|
||||
|
||||
## 3. Domain
|
||||
|
||||
| 字段 | 规则 |
|
||||
|------|------|
|
||||
| `code` | 唯一;`^[a-z][a-z0-9_]{1,62}$`;`system=true` 不可改 code |
|
||||
| `title` | 必填 · ≤128 |
|
||||
| `active` | `false` = 下架(唯一下架手段) |
|
||||
| `system` | 种子行;禁止物理删除 |
|
||||
|
||||
## 4. API
|
||||
|
||||
### Admin
|
||||
|
||||
| Method | Path | 权限 |
|
||||
|--------|------|------|
|
||||
| GET | `/admin/explore/star-configs` · `/{id}` | `admin.explore.read`(保持) |
|
||||
| POST | `/admin/explore/star-configs` | `admin.explore.write` |
|
||||
| PUT | `/admin/explore/star-configs/{id}` | `admin.explore.write` |
|
||||
|
||||
无 DELETE。
|
||||
|
||||
### C 端
|
||||
|
||||
| Method | Path | Auth | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/api/v1/star/configs` | DeviceAuth | 仅 `active=true`;按 code 排序 |
|
||||
|
||||
## 5. C 端生效(可观察)
|
||||
|
||||
| 条件 | user-h5 `/star` |
|
||||
|------|-----------------|
|
||||
| 至少 1 条 active | 保持现网生成路径 |
|
||||
| 成功且 0 条 active | 展示「星座配置暂未开放」类空态;禁用主生成 CTA |
|
||||
| 请求失败 | **回退**:不阻断现网生成(与 Banner/FeedSlot 失败回退同哲学) |
|
||||
|
||||
不改星历引擎、不改报告 JSON 契约。
|
||||
|
||||
## 6. Permission / Migration
|
||||
|
||||
- Migration `000052_ops_star_config_write`:授予 `super_admin` → `admin.explore.write`
|
||||
- 编码时占号(当前 Max=`000051`)
|
||||
- `knownPermissions` 注册加法码
|
||||
|
||||
## 7. UI
|
||||
|
||||
| 端 | 行为 |
|
||||
|----|------|
|
||||
| admin-h5 探索/星座配置页 | 列表 + 新建/编辑/上下架(仅 StarConfig) |
|
||||
| user-h5 `/star` | 按 §5 显隐 CTA |
|
||||
|
||||
## 8. AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | POST 合法 → list/get 可见 |
|
||||
| AC-F-02 | PUT `active=false` → C 端 list 不含 |
|
||||
| AC-F-03 | 有 active → C 端 list 非空;星座页可生成 |
|
||||
| AC-F-04 | 重复 code → 409 |
|
||||
| AC-S-01/02 | 401;仅 read → POST 403 |
|
||||
| AC-A-01 | 写产生审计 |
|
||||
| AC-C-01 | 全下架后星座页空态/禁 CTA |
|
||||
| AC-C-02 | C 端 API 失败不白屏、仍可走回退生成 |
|
||||
| AC-O-01 | 无 Rhythm/Card/Scale/Prompt 写路径;无 soft-delete |
|
||||
|
||||
## 9. Closed 后
|
||||
|
||||
**立即 STOP** Continuous Loop。
|
||||
ECR-044 必须重新 Candidate Review + Human 单独拍板。
|
||||
|
||||
## 10. Trace
|
||||
|
||||
ECR-043 · BD-2026-043 · PRODUCT_SPEC · CONTRACT_DIFF(实现时)· EXPLORE_CONFIG_WRITE_AUTHORIZATION
|
||||
@@ -0,0 +1,42 @@
|
||||
# Feature Spec: ExploreConfig · StarConfig(Ops · ECR-035 只读基线)
|
||||
|
||||
> Status: `Active`(**ECR-035 Closed** · 只读)
|
||||
> **写面:** [ops-star-config-write.md](ops-star-config-write.md)(**ECR-043 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-034 Closed
|
||||
> Capability: `ExploreConfig` · BC: `Explore_Reports`
|
||||
> 授权(只读队列):`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals(本只读 Spec)
|
||||
|
||||
配置写发布(见 ECR-043)· 引擎改分层 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `StarConfig` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/explore/star-configs` | `admin.explore.read` | 只读 |
|
||||
| GET | `/admin/explore/star-configs/{id}` | `admin.explore.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000036`:表 + 种子(若有) + 授予 admin.explore.read
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-035.yaml`
|
||||
@@ -0,0 +1,170 @@
|
||||
# Feature Spec: 运营系统(Ops-E)
|
||||
|
||||
> Status: `Active` · Map: `§7 Phase E` · Phase: `Ops-E` · ECR: `ECR-010`
|
||||
> 规范:[../feature-design.md](../feature-design.md)
|
||||
> 上游:Ops-A~D(ECR-006~009)
|
||||
|
||||
---
|
||||
|
||||
## 1. 功能定义
|
||||
|
||||
| 字段 | 内容 |
|
||||
|---|---|
|
||||
| Name | 运营系统 Ops-E |
|
||||
| Purpose | 两角色 RBAC、C 端用户封禁、推送任务占位,支撑安全运维 |
|
||||
| Business Goal | 限制写权限;可处置违规账号;预留推送运营入口(不下发) |
|
||||
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| `admin_accounts.role`:`super` \| `ops` | 细粒度权限矩阵 / 动态权限表 |
|
||||
| 用户封禁 / 解封(`users.status` active↔banned) | 设备级 / IP 封禁 |
|
||||
| `push_jobs` 草稿 CRUD(draft / cancelled) | 真推送通道 · Worker · 站内信 |
|
||||
| Admin API 动作级 403 + admin-h5 导航裁剪 | UGC · 真支付 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 用户价值
|
||||
|
||||
1. **为何需要:** 全员等同 Admin 风险高;无封禁只能改库。
|
||||
2. **完成后获得:** ops 可查可封可建推送草稿;写会员/定价/内容仅 super。
|
||||
3. **为何付费:** N/A(内部工具)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 用户角色
|
||||
|
||||
| Actor | 能力 |
|
||||
|---|---|
|
||||
| Admin `super` | 全部读写;Admin 账号列表与改角色 |
|
||||
| Admin `ops` | 读全模块;封禁/解封;推送草稿;**不可**授予会员、改价、内容写、管 Admin |
|
||||
| C 端 User `banned` | DeviceAuth / 会话拒绝(40310) |
|
||||
| Guest | 无后台入口 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 用户流程
|
||||
|
||||
```text
|
||||
Admin 登录 → Me 含 role
|
||||
↓
|
||||
ops:导航隐藏「定价写 / 内容写入口仍可见只读?按表:内容写否」
|
||||
→ 用户详情 → 封禁 → C 端下次请求 40310
|
||||
→ 推送页 → 新建 draft → 可 cancelled
|
||||
super:另开「管理员」改 role
|
||||
失败:无权限 403;未登录 401
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 页面设计
|
||||
|
||||
| 路由 | 页面 | 说明 |
|
||||
|---|---|---|
|
||||
| `/users/:id` | UserDetailPage | 封禁 / 解封按钮 |
|
||||
| `/push` | PushJobsPage | 列表 + 新建草稿 |
|
||||
| `/admins` | AdminsPage | 仅 super:列表改角色 |
|
||||
|
||||
```text
|
||||
AdminShell Nav += 推送 | 管理员(super)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 状态
|
||||
|
||||
| 态 | 要求 |
|
||||
|---|---|
|
||||
| Loading | 列表/详情请求中 |
|
||||
| Empty | 无推送任务 / 无管理员(不应发生) |
|
||||
| Error | 403 提示无权限;封禁失败可感知 |
|
||||
| Normal | 状态与角色展示正确 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 业务规则
|
||||
|
||||
1. Bootstrap / 存量 admin 默认 `super`。
|
||||
2. `ops` 调用 grant / PUT plan-prices / 内容写 → HTTP 403。
|
||||
3. 封禁写 `users.status='banned'` + audit `user.ban`;解封 `active` + `user.unban`。
|
||||
4. 被封用户:Bearer 会话与 DeviceAuth 解析后均拒绝(40310);可撤销 sessions。
|
||||
5. 推送仅 `draft`/`cancelled`;创建不下发。
|
||||
6. 仅 `super` 可 `PATCH` admin role;**禁止**降级最后一个 `super`(HTTP 409 / code 40901)。
|
||||
7. 推送标题非空且 ≤128 字符(rune),否则 400。
|
||||
|
||||
---
|
||||
|
||||
## 8. 数据
|
||||
|
||||
- `admin_accounts.role` varchar CHECK (`super`,`ops`) DEFAULT `super`
|
||||
- `users.status` CHECK (`active`,`banned`)(存量补齐)
|
||||
- `push_jobs(id, title, body, audience, status, created_by, created_at, updated_at)`
|
||||
|
||||
---
|
||||
|
||||
## 9. API
|
||||
|
||||
| Method | Path | 说明 |
|
||||
|---|---|---|
|
||||
| GET | `/api/v1/admin/me` | 响应含 `role` |
|
||||
| POST | `/api/v1/admin/users/{id}/ban` | super+ops |
|
||||
| POST | `/api/v1/admin/users/{id}/unban` | super+ops |
|
||||
| GET | `/api/v1/admin/admins` | super |
|
||||
| PATCH | `/api/v1/admin/admins/{id}` | super · body `{role}` |
|
||||
| GET | `/api/v1/admin/push-jobs` | super+ops |
|
||||
| POST | `/api/v1/admin/push-jobs` | super+ops · draft |
|
||||
| PATCH | `/api/v1/admin/push-jobs/{id}` | 改文案或 cancelled |
|
||||
|
||||
既有写接口对 `ops` 返回 403。
|
||||
|
||||
---
|
||||
|
||||
## 10. 埋点
|
||||
|
||||
N/A(内部);审计日志覆盖封禁与角色变更。
|
||||
|
||||
---
|
||||
|
||||
## 11. 事件
|
||||
|
||||
| Audit action | 何时 |
|
||||
|---|---|
|
||||
| `user.ban` / `user.unban` | 封禁变更 |
|
||||
| `admin.role_update` | 改角色 |
|
||||
| `push_job.create` / `push_job.update` | 推送占位 |
|
||||
|
||||
---
|
||||
|
||||
## 12. 验收
|
||||
|
||||
**Given** ops 账号
|
||||
**When** PUT plan-prices 或 grant membership
|
||||
**Then** 403
|
||||
|
||||
**Given** 用户被 ban
|
||||
**When** C 端带该 user 的 DeviceAuth 请求
|
||||
**Then** 40310
|
||||
|
||||
**Given** 唯一 super
|
||||
**When** PATCH role=ops
|
||||
**Then** 40901,角色不变
|
||||
|
||||
**Given** push title 超 128 字
|
||||
**When** POST push-jobs
|
||||
**Then** 40055
|
||||
|
||||
---
|
||||
|
||||
## 13. AI 开发前检查
|
||||
|
||||
- [x] Spec §4/7/9/12
|
||||
- [x] ECR-010 · BD-2026-010
|
||||
|
||||
---
|
||||
|
||||
## 14. Implementation Notes
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| Packages | `middleware` · `service/admin` · `AdminRepo` · admin-h5 |
|
||||
| Migration | `000016_ops_system` |
|
||||
| Label | Feature Complete(Ops-E MVP) |
|
||||
@@ -0,0 +1,41 @@
|
||||
# Feature Spec: AICoreConfig · ToolDefinition(Ops · ECR-028)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-028 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-027 Closed
|
||||
> Capability: `AICoreConfig` · BC: `Ask_Ops`
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
工具在线编辑 · 运行时绑定 · UGC · 真支付
|
||||
|
||||
## L2 Domain
|
||||
|
||||
| 概念 | 语义 |
|
||||
|------|------|
|
||||
| `ToolDefinition` | 本切片只读目录;code 唯一(若适用) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/ai/tools` | `admin.ai_config.read` | 只读 |
|
||||
| GET | `/admin/ai/tools/{id}` | `admin.ai_config.read` | 只读 |
|
||||
|
||||
## Migration
|
||||
|
||||
`000029`:表 + 种子(若有)(权限复用)
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | list 含种子或空列表合法 |
|
||||
| AC-F-02 | 已知 id get 200 |
|
||||
| AC-F-03 | 未知 id → 404 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无权限 → 403 |
|
||||
| AC-P-01 | list < 500ms |
|
||||
| AC-O-01 | N/A 只读 |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-028.yaml`
|
||||
@@ -0,0 +1,39 @@
|
||||
# Feature Spec: 用户洞察 UserIntelligence(Ops · ECR-016)
|
||||
|
||||
> Status: `Active`(Loop continuous · **ECR-016 Closed**)
|
||||
> Parent: WAVE0-FROZEN · Predecessor: ECR-015 Closed
|
||||
> Capability: `UserIntelligence` · BC: `Identity_Profile`(读)+ `Analytics_OpsB`(读)
|
||||
> 授权:`docs/WAVE0/LOOP_AUTHORIZATION.md`
|
||||
|
||||
## Non-goals
|
||||
|
||||
写标签 · 改报告正文 · Ask 全文运营编辑 · UGC · 真支付 · 新表(本切片纯读模型聚合)
|
||||
|
||||
## L2 读模型(无 migration)
|
||||
|
||||
| 概念 | 来源 |
|
||||
|------|------|
|
||||
| `UserProfileView` | profiles 摘要(已有 detail) |
|
||||
| `InsightReport` | growth_reports 类型计数 + 最近列表 |
|
||||
| `PsychologicalTagSet` | 由报告 type 派生的稳定标签(非 NLP) |
|
||||
| `BehaviorSnapshot` | analytics_events 最近页面/事件(若有) |
|
||||
|
||||
## L3 API
|
||||
|
||||
| Method | Path | 权限 | 语义 |
|
||||
|--------|------|------|------|
|
||||
| GET | `/admin/users/:id/insight` | `admin.users.read` | 聚合洞察只读 |
|
||||
|
||||
## L4 AC
|
||||
|
||||
| ID | Then |
|
||||
|----|------|
|
||||
| AC-F-01 | 有报告用户 → insight.reports_by_type 非空或 reports 列表 |
|
||||
| AC-F-02 | tags 含报告类型映射标签 |
|
||||
| AC-F-03 | 无埋点时 behavior.events=[] 仍 200 |
|
||||
| AC-S-01 | 无 Admin → 401 |
|
||||
| AC-S-02 | 无 users.read → 403 |
|
||||
| AC-P-01 | GET insight < 500ms 本机 |
|
||||
| AC-O-01 | N/A 只读(无写审计) |
|
||||
|
||||
contract_diff: `docs/CONTRACT_DIFF/ECR-016.yaml`
|
||||
@@ -16,7 +16,7 @@
|
||||
| In | Out |
|
||||
|---|---|
|
||||
| Self / Other 档案创建与生日变更触发 | 无档案凭空出合盘 |
|
||||
| 单人:portrait · star · rhythm | 意象卡片抽牌(配额玩法,不预生成) |
|
||||
| 单人:portrait · star · rhythm(star/rhythm 运势与今日建议按自然日在 GET 时原地刷新,见各 Spec) | 意象卡片抽牌(配额玩法,不预生成) |
|
||||
| 有 Self+Other:relation + synastry 成对覆盖 | 附近的人合盘(进页再算) |
|
||||
|
||||
---
|
||||
|
||||
@@ -92,6 +92,8 @@
|
||||
| R4 | 删除策略:任务未要求硬删 PII 时按实现(软删优先);级联影响报告见服务规则 |
|
||||
| R5 | Ask / 画像 / 关系必须挂合法 profile_id |
|
||||
| R6 | 文案用「个人档案」,不用命盘 |
|
||||
| R7 | **每账号至多一条** `relation=self`(唯一索引);再建 self → 409;解码/星盘等复用或更新既有 Self,禁止重复造「我」 |
|
||||
| R8 | 合盘/匹配对象列表只展示 `other` + 附近的人;不得把多余 self 当作 TA |
|
||||
|
||||
---
|
||||
|
||||
@@ -100,6 +102,7 @@
|
||||
| 表 | 字段要点 |
|
||||
|---|---|
|
||||
| `profiles` | id, user_id, relation, display_name, birth_date, birth_time?, birth_place?, gender?, relation_type? |
|
||||
| 约束 | 部分唯一:`(user_id) WHERE relation='self' AND deleted_at IS NULL` |
|
||||
|
||||
---
|
||||
|
||||
@@ -143,10 +146,18 @@
|
||||
**When** 添加 TA
|
||||
**Then** relation=other 且可用于关系理解
|
||||
|
||||
**Given** 已有 Self
|
||||
**When** 再次 POST relation=self
|
||||
**Then** 409 conflict;列表仍仅一条 Self
|
||||
|
||||
**Given** 他人 id
|
||||
**When** PATCH
|
||||
**Then** 失败
|
||||
|
||||
**Given** 同账号多条历史 self(脏数据)
|
||||
**When** 迁移/启动
|
||||
**Then** 仅保留最新一条,其余软删;合盘 TA 侧不再出现多个「我」
|
||||
|
||||
---
|
||||
|
||||
## 13. AI 开发前检查
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Feature Spec: 星座
|
||||
|
||||
> Status: `Active` · Map: `2.6 星座 [P2]` · Phase: `P2`
|
||||
> Status: `Active` · Map: `2.6 星座 [P2]` · Phase: `P2 Complete`
|
||||
> 规范:[../feature-design.md](../feature-design.md) · 队列:[P2-BACKLOG.md](P2-BACKLOG.md)
|
||||
> 竞品对照:测测星座体系(本命排盘 · 运势大全 · 连线合盘)
|
||||
|
||||
@@ -106,6 +106,10 @@
|
||||
| R8 | 合盘与人格匹配分流:`/synastry` 盘型;`/relation` 行为风格 |
|
||||
| R9 | 附近的人默认 `geo_visible=false`;仅可见已开启位置的 self 档案 |
|
||||
| R10 | 合盘星历走 Swiss Ephemeris(默认 Moshier);宫位制 Whole Sign |
|
||||
| R11 | 合盘交叉校验:档案 A 为本账号 Self;档案 B 须为本账号 `other` 或附近可见他人 Self;拒绝 self×self / 同 id |
|
||||
| R12 | **本命层**(轮盘/行星/相位/太阳月亮上升)随生日确定,不因打开时间重算;**运势层**(日/周/月/年 outlook · 行运)按**自然日(CST)**刷新 |
|
||||
| R13 | GET `/reports/latest` 与 GET `/reports/{id}`(type=star):若 `summary.as_of` ≠ 当日则**原报告 id 原地更新**时效段并落库;同日再读即时返回;禁止为换日运新建报告 id(以免深度权益丢失) |
|
||||
| R14 | `summary` 含 `as_of`(YYYY-MM-DD)与 `valid_until`(次日 00:00 CST RFC3339);前端到点静默刷新;**不按十二时辰**切换 |
|
||||
|
||||
---
|
||||
|
||||
@@ -118,7 +122,7 @@
|
||||
| `profiles.birth_place` | 可选;常用城市表解析经纬度 |
|
||||
| `profiles.geo_lat/lng/visible` | 附近的人 |
|
||||
| `synastry_invites` | 邀请 token · host/guest · report_id |
|
||||
| 报告 JSON | `charts.*`(五主盘+推运)· `as_of` · 三指数 · fortune/transits |
|
||||
| 报告 JSON | `charts.*`(五主盘+推运)· `as_of` · `valid_until` · 三指数 · fortune/transits |
|
||||
|
||||
详见 erd;实现切片同步 OpenAPI。
|
||||
|
||||
@@ -152,7 +156,7 @@
|
||||
|
||||
| Event | 触发 |
|
||||
|---|---|
|
||||
| `star_completed` / portrait_completed source=star | 基础结果展示 |
|
||||
| `star_completed` | 基础结果展示 |
|
||||
| `star_wheel_viewed` | 点选轮盘行星 |
|
||||
| `synastry_completed` | 合盘结果展示 |
|
||||
| `synastry_invite_created` / `synastry_invite_accepted` | 邀请链路 |
|
||||
@@ -165,7 +169,7 @@
|
||||
|
||||
**Given** Self 有生日
|
||||
**When** 生成星座报告
|
||||
**Then** 展示轮盘、太阳/月亮/上升、相位速览、fortune 日运与行运;无「占卜」「算命」恐吓
|
||||
**Then** 展示轮盘、太阳/月亮/上升、相位速览、outlook 日/周/月/年/一生与行运;无「占卜」「算命」恐吓
|
||||
|
||||
**Given** 两份档案
|
||||
**When** POST synastry
|
||||
@@ -183,6 +187,14 @@
|
||||
**When** 打开 `/star`
|
||||
**Then** 页内生日表单可生成
|
||||
|
||||
**Given** 已有 star 报告且 `as_of` 为昨日
|
||||
**When** GET latest
|
||||
**Then** 日运等 outlook 按今日更新;报告 `id` 不变;响应含当日 `as_of` 与 `valid_until`
|
||||
|
||||
**Given** 用户停留在 `/star` 跨自然日
|
||||
**When** 到达 `valid_until`
|
||||
**Then** 前端静默刷新运势 Tab 内容
|
||||
|
||||
---
|
||||
|
||||
## 13. AI 开发前检查
|
||||
@@ -202,3 +214,5 @@
|
||||
| Packages | `internal/star` · `ephemeris` · `natal` · `fortune` · `synastry` |
|
||||
| 星历 | Swiss Ephemeris(CGO,默认 Moshier);热带 + Whole Sign |
|
||||
| 实现 | `POST /reports/star` · `POST /reports/synastry` · nearby/invites · H5 `/star` · `/synastry` · invite |
|
||||
| Gaps | ECR-012 收口:报告页复用 StarFortunePanel;分享 type=star;fortuneBundle 仅读 outlook 且剥离 lucky;e2e mock 含 outlook |
|
||||
| ESS | `docs/ECR/ECR-012-star-alignment.md`(**Approved** · L2)· BD-2026-012 Approved |
|
||||
|
||||
@@ -41,7 +41,7 @@ P1 必做(feature-map):用户档案 · 性格探索/个人画像 · 人格
|
||||
| 探索测试草稿恢复 | `scaleDraft` localStorage |
|
||||
| L0–L3 | 全绿(收口时) |
|
||||
|
||||
P2 设计队列:[`feature-spec/P2-BACKLOG.md`](feature-spec/P2-BACKLOG.md)
|
||||
P2 收口:[`p2-status.md`](p2-status.md)(**P2 Complete**)· [`feature-spec/P2-BACKLOG.md`](feature-spec/P2-BACKLOG.md)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# P2 Status(对照 Definition of Done)
|
||||
|
||||
**当前标签:`P2 Complete`**
|
||||
|
||||
判定依据:`.ai/definition-of-done.md` §9
|
||||
P2 范围(feature-map):星座 · 身心节律 · 意象卡片 · 探索三级目录 · 量表矩阵 · 节气陪伴深化 · 心情记录 · 成长计划
|
||||
|
||||
**不含:** 真支付网关 · 消息/达人/UGC · 独立运势 Feed · 推送 · P3 长期记忆/顾问
|
||||
|
||||
---
|
||||
|
||||
## Review Report
|
||||
|
||||
- Feature: P2 合规全量探索收口
|
||||
- Scope label: **P2 Complete**
|
||||
- Architecture: PASS — handler → service → repository;`star` / `rhythm` / `imagecard` / `companion` / `growth` 独立包
|
||||
- API: PASS — `proto/openapi.yaml` 覆盖 star / synastry / rhythm / image-cards / explore catalog / moods / growth plans
|
||||
- Security: PASS — report detail 服务端按 DeepAccess 裁剪;配额与归属校验在服务端
|
||||
- Test (L0/L1/L2/L3): PASS
|
||||
- L0: `go test ./...` · `npm run build:h5` · `npm run test:h5`
|
||||
- L1: star / synastry / rhythm / imagecard / explore
|
||||
- L2: `internal/integration` — p2_flows · synastry · explore_catalog · growth checkin
|
||||
- L3: Playwright `e2e/p2-explore-paths.spec.ts` + `e2e/portrait-main-path.spec.ts`
|
||||
- Frontend states (L/E/E/N): PASS — 主路径页具备加载/空/错/正常;深度版 Locked
|
||||
- Documentation: PASS — Spec Active + P2-BACKLOG Done + 本文件
|
||||
- Environment: PASS — `commands.md` 本机 Go/Vite + compose.dev 仅 DB
|
||||
- Known Issues:
|
||||
- 真支付仍为 mock(部署阶段)
|
||||
- 意象卡库:手写底稿 + 确定性扩至 ≥78(非全手写美术)
|
||||
- 推送未做(Ops-E / 后置)
|
||||
- Ask 无 key 时规则引擎降级
|
||||
|
||||
---
|
||||
|
||||
## 本轮收口变更
|
||||
|
||||
| 项 | 结果 |
|
||||
|---|---|
|
||||
| 生日表单生成误用 `getLatestReport` | 已改回 `createPortrait` / `createStar` / `createRhythm` |
|
||||
| H5 单测 auth 门禁 mock | PASS(38) |
|
||||
| L3 e2e auth/profiles mock | PASS(2) |
|
||||
| 状态真源对齐 | P2-BACKLOG · feature-map · Spec 头 · DoD §9 |
|
||||
|
||||
---
|
||||
|
||||
## 验收路径
|
||||
|
||||
探索目录 → `/star`(星盘/运势/合盘)→ `/rhythm` → `/cards` → `/companion`(心情+近七日)→ `/growth-plan` → 探索量表
|
||||
|
||||
```bash
|
||||
npm run test:api
|
||||
npm run test:api:integration
|
||||
npm run test:h5
|
||||
npm run build:h5 && npm run test:e2e
|
||||
```
|
||||
+2
-1
@@ -7,7 +7,8 @@
|
||||
- DB: PostgreSQL
|
||||
- Migrations: goose (or golang-migrate) under `apps/api/migrations/`
|
||||
- Log: structured (zap or slog wrapper). No `fmt.Println` in business paths.
|
||||
- Module path: `github.com/yuxingu/digital-psychology/apps/api`
|
||||
- Module path: `github.com/yuxingu/digital-psychology/apps/api`(Go import 身份;**不**表示托管在 GitHub)
|
||||
- Git host: `https://git.jackyu66.com/jack/digital-psychology.git`(唯一远程 `origin`;无 GitHub Actions)
|
||||
|
||||
## User H5
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-009",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "2026.08",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-06T18:45:32Z"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"ecr": "ECR-010",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "2026.08",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [
|
||||
"Code changed but CHANGELOG.md not modified \u2014 required for L2 Done"
|
||||
],
|
||||
"timestamp": "2026-08-11T10:20:52Z"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"ecr": "ECR-012",
|
||||
"result": "BLOCK",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": false,
|
||||
"tests": false
|
||||
},
|
||||
"violations": [
|
||||
{
|
||||
"rule": "TR-REVIEW-001",
|
||||
"description": "Backend change requires CODE_REVIEW / code-review handoff artifact",
|
||||
"fix_required": [
|
||||
"Write reviewer decision artifact",
|
||||
"Re-run gate"
|
||||
],
|
||||
"detail": "ECR-012",
|
||||
"check": "traceability-check"
|
||||
},
|
||||
{
|
||||
"rule": "TR-COMMIT-001",
|
||||
"description": "Trace chain requires implementation commit evidence",
|
||||
"fix_required": [
|
||||
"Record commit sha in TRACEABILITY or TEST_REPORT",
|
||||
"Re-run gate"
|
||||
],
|
||||
"detail": "ECR-012",
|
||||
"check": "traceability-check"
|
||||
},
|
||||
{
|
||||
"rule": "TE-MISSING-001",
|
||||
"description": "Missing TEST_REPORT for implemented change",
|
||||
"fix_required": [
|
||||
"Add docs/TEST_REPORT/ECR-xxx.md",
|
||||
"Re-run gate"
|
||||
],
|
||||
"detail": "ECR-012",
|
||||
"check": "test-evidence-check"
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
"[traceability-check] BLOCK [TR-REVIEW-001]: Backend change requires CODE_REVIEW / code-review handoff artifact \u2014 ECR-012",
|
||||
"[traceability-check] BLOCK [TR-COMMIT-001]: Trace chain requires implementation commit evidence \u2014 ECR-012",
|
||||
"[test-evidence-check] BLOCK [TE-MISSING-001]: Missing TEST_REPORT for implemented change \u2014 ECR-012"
|
||||
],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T06:51:10Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-016",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T10:30:16Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-017",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T10:39:01Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-018",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T11:26:01Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-019",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T14:13:03Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-020",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T15:01:53Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-021",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T16:26:53Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-022",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T17:28:27Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-023",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T17:48:29Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-024",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:05:41Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-025",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:08:40Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-026",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:13:36Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-027",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:14:17Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-028",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:14:30Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-029",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:14:44Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-030",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:15:00Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-031",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:15:15Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-032",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:15:30Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-033",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:15:45Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-034",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:15:59Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-035",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:16:12Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-036",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:16:26Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-037",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:16:42Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-038",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:16:57Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-039",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:17:12Z"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"ecr": "ECR-040",
|
||||
"result": "PASS",
|
||||
"ess_version": "v1.0",
|
||||
"gate_version": "0.1.2",
|
||||
"project_profile": "unknown",
|
||||
"checks": {
|
||||
"artifact": true,
|
||||
"role_boundary": true,
|
||||
"backend_boundary": true,
|
||||
"traceability": true,
|
||||
"tests": true
|
||||
},
|
||||
"violations": [],
|
||||
"errors": [],
|
||||
"warnings": [],
|
||||
"timestamp": "2026-08-07T19:20:29Z"
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
h5:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npm run build:h5
|
||||
- run: npm run test:h5
|
||||
- name: Install Playwright Chromium
|
||||
working-directory: apps/user-h5
|
||||
run: npx playwright install --with-deps chromium
|
||||
- run: npm run test:e2e -w @yuxingu/user-h5
|
||||
env:
|
||||
CI: true
|
||||
|
||||
api:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
- name: Unit tests (no integration DB)
|
||||
working-directory: apps/api
|
||||
run: go test $(go list ./... | grep -v /internal/integration) -count=1
|
||||
|
||||
ess-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: ESS artifact presence (active ECR)
|
||||
run: |
|
||||
test -f docs/ECR/ECR-005-h5-openapi-hygiene.md
|
||||
test -f docs/TASKS/TASK-20260805-ECR005.yaml
|
||||
test -f docs/TEST_REPORT/ECR-005.md
|
||||
test -f docs/STATE/ECR-005.md
|
||||
echo "ESS docs gate OK"
|
||||
- name: ess-validate when ESS_ROOT available
|
||||
env:
|
||||
ESS_ROOT: ${{ vars.ESS_ROOT }}
|
||||
run: |
|
||||
if [ -n "$ESS_ROOT" ] && [ -f "$ESS_ROOT/scripts/ess-validate.py" ]; then
|
||||
python scripts/ess-validate.py --phase coding --ecr ECR-005 --task docs/TASKS/TASK-20260805-ECR005.yaml
|
||||
else
|
||||
echo "ESS_ROOT not configured in CI — skipped full ess-validate"
|
||||
fi
|
||||
@@ -3,6 +3,7 @@ __pycache__/
|
||||
.venv/
|
||||
*.log
|
||||
.env
|
||||
deploy.env
|
||||
.DS_Store
|
||||
|
||||
# ESS — machine-local root pointer(仓库内用 scripts 包装器)
|
||||
@@ -17,6 +18,7 @@ dist/
|
||||
apps/api/bin/
|
||||
apps/api/yuxingu-api
|
||||
apps/api/tmp/
|
||||
apps/api/data/
|
||||
*.exe
|
||||
|
||||
# IDE
|
||||
@@ -40,3 +42,7 @@ Thumbs.db
|
||||
|
||||
# Local secrets (never commit)
|
||||
apps/api/config.local.yaml
|
||||
|
||||
# Playwright / Vitest artifacts
|
||||
**/test-results/
|
||||
**/playwright-report/
|
||||
|
||||
@@ -4,40 +4,62 @@ You are the software engineer for **愈心谷 (YuXinGu)**.
|
||||
|
||||
This file is for AI agents.
|
||||
|
||||
## 0. ESS Intake Bootstrap(任何改码任务最先做)
|
||||
|
||||
读 `$ESS_ROOT/governance/SESSION_BOOTSTRAP.md`,**先输出 ESS Mode 块**,再改文件或扩 Scope。
|
||||
|
||||
```text
|
||||
ESS Mode: L0 | L1 | L2 | L2-BLOCKED | L3 | RETRO
|
||||
Change: <one line>
|
||||
ECR: <id|NONE>
|
||||
Phase: <ARCHITECT|ENGINEER|REVIEWER|none>
|
||||
Execution Context: <ECR id|TASK id|NONE>
|
||||
Allowed: <...>
|
||||
Forbidden: <...>
|
||||
Action: CONTINUE | STOP
|
||||
Reason: <...>
|
||||
```
|
||||
|
||||
- `Action: STOP` 或 `L2-BLOCKED` → **禁止**改 `apps/` / `packages/` / `proto/` / `migrations/`
|
||||
- 本仓 `ess_intake: strict`(见 `docs/PROJECT_RULES.md`):Retro ECR 须四字段;新主题 OUT OF SCOPE
|
||||
- Solo multi-role 允许同 Session 串行换 Phase;**同一 review turn 禁止 Approve + Modify**
|
||||
|
||||
## Load order (every task)
|
||||
|
||||
1. `.ai/ai-contract.md`
|
||||
2. `.ai/constitution.md`
|
||||
3. `.ai/architecture.md`
|
||||
4. `.ai/domain.md` (+ product/API tasks: `domain/domain-map.md`)
|
||||
5. `.ai/forbidden.md`
|
||||
6. `.ai/definition-of-done.md` — **完成标准(强制)**;Done ≠ build 通过
|
||||
7. `.ai/environment.md` + `.ai/development.md`(本地)· 部署任务再读 `deployment.md` / `docker.md`
|
||||
8. `.ai/file-map.md` + `.ai/workflow.md`
|
||||
9. Task rules: `.ai/coding.md` / `api.md` / `database.md` / `ui.md` / `security.md` / `testing.md` …
|
||||
10. **Product scope:** `.ai/product/lexicon.md` + `feature-map.md` + **`feature-design.md`** + 对应 **`feature-spec/<id>.md`** + `user-journey.md` + `page-tree.md` · 状态 `product/p1-status.md`
|
||||
11. **Competitor parity / reverse engineering:** `.ai/design/reverse-engineering-spec.md`(强制 STEP 1–18 · Evidence First · 禁止 Demo 式省略)→ 再映射 lexicon / feature-spec
|
||||
12. **Any UI work:** `.ai/design/design-system.md` + `component-catalog.md` + matching `design/platform/*.md` (H5 default)
|
||||
13. Matching **ADR** in `.ai/adr/` before changing stack or API style
|
||||
14. Prefer **patterns/** + **examples/** + **playbooks/**(含 `feature-spec`) over inventing structure
|
||||
15. Before claiming Done: `.ai/definition-of-done.md` + `.ai/review.md` + `.ai/checklists/*` → 输出 **Review Report**
|
||||
16. Verify via `.ai/commands.md`(本地默认本机 Go/Vite + compose.dev 仅 DB)
|
||||
17. `prompts/` are optional helpers — not a substitute for rules above
|
||||
18. **ESS process (when L2+ / architecture / release):** `docs/PROJECT_PROFILE.md` → role from `$ESS_ROOT/agents/` → `docs/ECR/` · `docs/TASKS/` · `docs/HANDOFF/`;勿把 ESS 整树复制进仓
|
||||
1. **§0 ESS Mode 块**(上)→ `docs/PROJECT_PROFILE.md` · `docs/PROJECT_RULES.md`
|
||||
2. `.ai/ai-contract.md`
|
||||
3. `.ai/constitution.md`
|
||||
4. `.ai/architecture.md`
|
||||
5. `.ai/domain.md` (+ product/API tasks: `domain/domain-map.md`)
|
||||
6. `.ai/forbidden.md`
|
||||
7. `.ai/definition-of-done.md` — **完成标准(强制)**;Done ≠ build 通过
|
||||
8. `.ai/environment.md` + `.ai/development.md`(本地)· 部署任务再读 `deployment.md` / `docker.md`
|
||||
9. `.ai/file-map.md` + `.ai/workflow.md`
|
||||
10. Task rules: `.ai/coding.md` / `api.md` / `database.md` / `ui.md` / `security.md` / `testing.md` …
|
||||
11. **Product scope:** `.ai/product/lexicon.md` + `feature-map.md` + **`feature-design.md`** + 对应 **`feature-spec/<id>.md`** + `user-journey.md` + `page-tree.md` · 状态 `product/p1-status.md`
|
||||
12. **Competitor parity / reverse engineering:** `.ai/design/reverse-engineering-spec.md`(强制 STEP 1–18 · Evidence First · 禁止 Demo 式省略)→ 再映射 lexicon / feature-spec
|
||||
13. **Any UI work:** `.ai/design/design-system.md` + `component-catalog.md` + matching `design/platform/*.md` (H5 default)
|
||||
14. Matching **ADR** in `.ai/adr/` before changing stack or API style
|
||||
15. Prefer **patterns/** + **examples/** + **playbooks/**(含 `feature-spec`) over inventing structure
|
||||
16. Before claiming Done: `.ai/definition-of-done.md` + `.ai/review.md` + `.ai/checklists/*` → 输出 **Review Report**
|
||||
17. Verify via `.ai/commands.md`(本地默认本机 Go/Vite + compose.dev 仅 DB)
|
||||
18. `prompts/` are optional helpers — not a substitute for rules above
|
||||
19. **ESS process (L2+ / architecture / release):** `$ESS_ROOT/SKILL.md` · `SESSION_BOOTSTRAP` · role from `$ESS_ROOT/agents/` → `docs/ECR/` · `docs/TASKS/` · `docs/HANDOFF/`;勿把 ESS 整树复制进仓
|
||||
|
||||
## ESS dual-track
|
||||
|
||||
| Concern | Source of truth |
|
||||
|---------|-----------------|
|
||||
| Lexicon · Feature Spec · DoD · domain · architecture freeze | `.ai/` |
|
||||
| Roles · ECR · Task Contract · Handoff · validate gates | ESS + `docs/` |
|
||||
| Intake Mode · Roles · ECR · Task · Handoff · validate | ESS + `docs/` |
|
||||
|
||||
```text
|
||||
Load Agent Profile: ARCHITECT | ENGINEER | REVIEWER | RELEASE_MANAGER
|
||||
```
|
||||
|
||||
- Cursor → ARCHITECT / REVIEWER(禁改生产实现)
|
||||
- Engineer 实现前:Active Feature Spec +(L2+)Approved ECR + HANDOFF
|
||||
- Cursor Session 可 Solo 串行三角色;**当前 Phase 权限唯一**
|
||||
- ARCHITECT / REVIEWER phase:禁改生产实现;REVIEWER 禁 Approve+Modify 同 turn
|
||||
- Engineer:Active Feature Spec +(L2+)Approved ECR + HANDOFF;无 ECR → `L2-BLOCKED`
|
||||
- `python scripts/ess-validate.py --phase <phase> --ecr ECR-xxx`
|
||||
|
||||
## Hard constraints
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user