@ai-content-space/loopx 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +7 -8
- package/README.md +22 -10
- package/README.zh-CN.md +22 -10
- package/docs/loopx/design/loopx-skill-suite-v1-design.md +14 -7
- package/docs/loopx/plans/loopx-skill-suite-v1-implementation.md +7 -3
- package/package.json +3 -2
- package/plugins/loopx/.codex-plugin/plugin.json +1 -1
- package/plugins/loopx/skills/clarify/SKILL.md +4 -4
- package/plugins/loopx/skills/debug/SKILL.md +1 -1
- package/plugins/loopx/skills/exec/SKILL.md +1 -1
- package/plugins/loopx/skills/finish/SKILL.md +103 -8
- package/plugins/loopx/skills/fix-review/SKILL.md +1 -1
- package/plugins/loopx/skills/go-style/SKILL.md +2 -2
- package/plugins/loopx/skills/kratos/SKILL.md +1 -1
- package/plugins/loopx/skills/plan/SKILL.md +2 -2
- package/plugins/loopx/skills/refactor-plan/SKILL.md +1 -1
- package/plugins/loopx/skills/review/SKILL.md +1 -1
- package/plugins/loopx/skills/spec/DESIGN_SPEC_TEMPLATE.md +2 -2
- package/plugins/loopx/skills/spec/SKILL.md +2 -2
- package/plugins/loopx/skills/subagent-exec/SKILL.md +1 -1
- package/plugins/loopx/skills/tdd/SKILL.md +1 -1
- package/plugins/loopx/skills/verify/SKILL.md +1 -1
- package/scripts/verify-skills.mjs +2 -1
- package/skills/RESOLVER.md +0 -4
- package/skills/clarify/SKILL.md +4 -4
- package/skills/debug/SKILL.md +1 -1
- package/skills/exec/SKILL.md +1 -1
- package/skills/finish/SKILL.md +103 -8
- package/skills/fix-review/SKILL.md +1 -1
- package/skills/go-style/SKILL.md +2 -2
- package/skills/kratos/SKILL.md +1 -1
- package/skills/plan/SKILL.md +2 -2
- package/skills/refactor-plan/SKILL.md +1 -1
- package/skills/review/SKILL.md +1 -1
- package/skills/spec/DESIGN_SPEC_TEMPLATE.md +2 -2
- package/skills/spec/SKILL.md +2 -2
- package/skills/subagent-exec/SKILL.md +1 -1
- package/skills/tdd/SKILL.md +1 -1
- package/skills/verify/SKILL.md +1 -1
- package/src/cli.mjs +1 -2
- package/src/plan-runtime.mjs +0 -352
- package/src/workflow.mjs +5 -124
- package/plugins/loopx/scripts/plugin-install.test.mjs +0 -125
- package/skills/ai-slop-cleaner/SKILL.md +0 -114
- package/skills/autoresearch/SKILL.md +0 -68
- package/skills/deep-interview/SKILL.md +0 -461
- package/skills/ralph/SKILL.md +0 -271
- package/skills/ralplan/SKILL.md +0 -49
package/src/plan-runtime.mjs
CHANGED
|
@@ -73,359 +73,7 @@ function mdTable(headers, rows) {
|
|
|
73
73
|
].join('\n');
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
function isCorporateActionSource(sourceText) {
|
|
77
|
-
return /公司行动|Corporate Action|corporate-actions|OCC|分红派息|拆股|合股|退市|摘牌|代码\s*\/\s*名称变更/i.test(String(sourceText || ''));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function corporateActionPlannerDraft({ slug, sourceText }) {
|
|
81
|
-
const eventRows = [
|
|
82
|
-
['总览', '展示当前任务、今日新增、今日需处理、未来生效、异常/超时', '读取任务/异常/下游状态聚合,不执行任何业务动作', 'seed 后 8 类样例均可进入详情'],
|
|
83
|
-
['分红派息', '普通现金分红、特殊分红、主体扣税、税费分摊、客户净额', '生成客户分红明细;确认主体税费和分摊后才允许模拟入账/扣款', '多头入账、空头扣款、待确认客户进入差异处理'],
|
|
84
|
-
['拆股', '正股数量增加、单位成本同比降低、OCC 合约调整', '生成正股持仓调整和期权调整明细;未确认 OCC 时不得执行下发', '客户持仓、订单处理、保证金重算、展示下发均有 mock 状态'],
|
|
85
|
-
['合股', '正股数量减少、碎股现金替代、非标准期权', '生成整数股、碎股现金替代和期权非标调整;碎股金额差异进入异常', '碎股现金替代、订单处理、期权非标展示均可验收'],
|
|
86
|
-
['退市/摘牌', '最后交易日、清算/失效日、持仓和订单保护', '生成客户影响、订单保护和期权 OCC 待监控;缺结果时停在待复核或差异待处理', '不自动迁移资产账本,不改历史账单'],
|
|
87
|
-
['期权退市 OCC', 'OCC Memo、原合约、调整后合约、乘数、行权价、交割物', '按 memo_no + underlying_security_id + adjustment_type 匹配;正股任务可关联但不可互相替代', 'OCC 字段缺失、合约映射失败、保证金未重算均进入异常'],
|
|
88
|
-
['代码/名称变更', '新旧 symbol/name/security_id 映射、生效日、确认来源', '确认映射后模拟下发展示、订单和期权链影响;不改历史账单', '缺新代码映射时创建事件异常,不允许执行'],
|
|
89
|
-
['事件异常处理', '金额、数量、客户范围、合约映射、下游回写、超时', '异常独立落库并关联 task/detail/option_adjustment/downstream_status', '处理后回到待确认或待执行;处理动作写 OperationLog'],
|
|
90
|
-
];
|
|
91
|
-
const stateRows = [
|
|
92
|
-
['生成明细', '待生成', '事件已入库且未有有效明细版本', '待复核', '差异待处理', '写客户明细/期权调整/操作日志;重复请求返回已有有效版本'],
|
|
93
|
-
['重算', '待复核、待确认、差异待处理', '任务未执行且存在明细或异常修正', '待复核', '差异待处理', '废弃旧明细版本,生成新版本;已完成/执行中禁止重算'],
|
|
94
|
-
['复核', '待复核', '明细完整且无阻断异常', '待确认', '差异待处理', '仅人工触发;记录 operator_id/operator_name/remark'],
|
|
95
|
-
['确认', '待确认', '税费、数量、OCC、客户范围均已复核', '待执行', '差异待处理', '确认后冻结当前有效明细版本'],
|
|
96
|
-
['执行', '待执行', '动作类型为现金/持仓处理且无阻断异常', '执行中', '差异待处理', '只调用 mock ExecutionProvider,不触达真实资产/交易/清算'],
|
|
97
|
-
['下发', '待执行', '动作类型为展示/订单/期权链/柜台下发且无阻断异常', '执行中', '差异待处理', '写 DownstreamStatus;mock 回写成功后归档'],
|
|
98
|
-
['mock 回写成功', '执行中', '全部目标系统返回 success', '已完成', '差异待处理', '系统回调只允许推进执行中任务'],
|
|
99
|
-
['mock 回写失败', '执行中', '任一目标系统返回 failed/timeout', '差异待处理', '差异待处理', '创建 Discrepancy 并保留 DownstreamStatus 失败原因'],
|
|
100
|
-
['重试', '差异待处理、执行中', '失败原因已处理或超时可补偿查询', '执行中', '差异待处理', '重试次数和目标系统写入 DownstreamStatus'],
|
|
101
|
-
['录入人工结果', '待复核、待确认、差异待处理', '运营输入确认值和说明', '待确认', '差异待处理', '只修改平台确认字段,不写真实下游'],
|
|
102
|
-
['标记无需处理', '待生成、待复核、待确认、待执行、差异待处理', '确认该事件对客户/平台无动作', '无需处理', '原状态不变', '必须填写原因;终态禁止再执行'],
|
|
103
|
-
['标记人工完成', '待执行、差异待处理', '外部已人工处理且上传凭证/备注', '已完成', '原状态不变', '必须写 OperationLog;不触发 mock 执行'],
|
|
104
|
-
];
|
|
105
|
-
const entityRows = [
|
|
106
|
-
['CorporateActionEvent', 'id, corporate_action_event_id(unique), source, source_event_id, event_type, market, asset_type, security_id, underlying_security_id, symbol, key_date, version, event_status, raw_snapshot_id, event_payload', '事件去重、版本修订、取消/更正追溯', 'corporate_action_event_id + version;同版本重复不建新任务'],
|
|
107
|
-
['CorporateActionTask', 'task_id(unique), event_id, event_type, task_status, asset_scope, security_id, symbol, key_date, affected_customer_count, affected_order_count, risk_flags, current_detail_version, detail_payload', '运营主任务和状态机载体', 'event_id 一对一或一对多;任务状态由 usecase 集中推进'],
|
|
108
|
-
['CorporateActionCustomerDetail', 'task_id, detail_version, user_id, trade_account_id, security_id, asset_type, position_qty, cash_amount, tax_amount, net_amount, order_action, margin_status, process_status, detail_payload', '客户级影响明细', 'task_id + detail_version + user_id + trade_account_id + security_id'],
|
|
109
|
-
['CorporateActionOptionAdjustment', 'task_id, memo_no, underlying_security_id, option_security_id, original_contract, adjusted_contract, old_strike, new_strike, old_multiplier, new_multiplier, deliverable, review_status, adjustment_payload', 'OCC 和期权调整', 'memo_no + underlying_security_id + option_security_id + adjustment_type'],
|
|
110
|
-
['CorporateActionDiscrepancy', 'task_id, detail_id, option_adjustment_id, downstream_status_id, discrepancy_type, field_name, estimated_value, confirmed_value, status, resolution_note', '差异和事件异常', '处理后写 confirmed_value/status/resolution_note 并回推任务状态'],
|
|
111
|
-
['CorporateActionDownstreamStatus', 'task_id, target_system, action_type, status, request_payload, response_payload, failure_reason, retry_count', 'mock 执行/下发回写', 'target_system + action_type 可多条;禁止真实 client 写入'],
|
|
112
|
-
['CorporateActionOperationLog', 'task_id, operator_id, operator_name, action_type, before_status, after_status, remark, created_at', '人工动作和系统回写审计', '所有人工动作、mock 回写、异常处理必须落日志'],
|
|
113
|
-
];
|
|
114
|
-
const providerRows = [
|
|
115
|
-
['EventSourceProvider', 'FetchMockEvents(ctx) ([]EventInput, error)', '行情/RIC、OCC、清算结果的本地样例输入', '首期仅 local mock;不接 Reuters、OCC PDF、清算接口'],
|
|
116
|
-
['ImpactProvider', 'BuildDetails(ctx, task) (ImpactResult, error)', '客户、持仓、订单、保证金、展示影响明细', '返回结构化明细和异常;不得读真实资产/交易系统'],
|
|
117
|
-
['ExecutionProvider', 'Execute(ctx, task, action) (ExecutionResult, error)', '模拟现金入账/扣款、持仓调整、展示/订单/期权链下发', '只写 DownstreamStatus 和 OperationLog;无真实外部副作用'],
|
|
118
|
-
['ExceptionProvider', 'Resolve(ctx, discrepancy, input) (ResolutionResult, error)', '人工确认金额/数量/客户范围/合约映射/回写失败', '处理结果只影响平台任务和明细确认字段'],
|
|
119
|
-
];
|
|
120
|
-
const apiRows = [
|
|
121
|
-
['GET', '/admin/v1/corporate-actions/overview', '总览统计、风险提示、异常/超时', 'admin.corporate_action.view'],
|
|
122
|
-
['POST', '/admin/v1/corporate-actions/mock/seed', '生成 8 类 mock 样例', 'admin.corporate_action.seed'],
|
|
123
|
-
['GET', '/admin/v1/corporate-actions/tasks', '按 event_type/status/symbol/task_id/key_date 查询任务', 'admin.corporate_action.view'],
|
|
124
|
-
['GET', '/admin/v1/corporate-actions/tasks/{task_id}', '任务详情、客户明细、期权调整、异常、日志、下游状态', 'admin.corporate_action.view'],
|
|
125
|
-
['POST', '/admin/v1/corporate-actions/tasks/{task_id}/details/generate', '生成或重算明细', 'admin.corporate_action.operate'],
|
|
126
|
-
['POST', '/admin/v1/corporate-actions/tasks/{task_id}/actions/{action}', '复核、确认、执行、下发、重试、无需处理、人工完成', 'admin.corporate_action.operate'],
|
|
127
|
-
['GET', '/admin/v1/corporate-actions/discrepancies', '异常列表和跨任务筛选', 'admin.corporate_action.view'],
|
|
128
|
-
['POST', '/admin/v1/corporate-actions/discrepancies/{id}/resolve', '处理异常并回写任务状态', 'admin.corporate_action.operate'],
|
|
129
|
-
];
|
|
130
|
-
const sliceRows = [
|
|
131
|
-
['1', 'HITL', '领域/数据/状态底座', 'Ent schema、枚举、状态机、repository 接口、usecase 骨架', '状态矩阵单测、事件去重单测、schema 生成可重复'],
|
|
132
|
-
['2', 'AFK', 'Mock 数据与任务闭环', '8 类 mock 事件、明细生成、异常创建、mock 回写', '每类事件可 seed、可生成任务、可查详情'],
|
|
133
|
-
['3', 'HITL', '管理 API 与权限', 'overview/tasks/detail/action/discrepancy 接口和 permission_mark', '接口测试覆盖权限、参数、非法动作和响应结构'],
|
|
134
|
-
['4', 'HITL', '后台前端', 'web/admin 总览、共享任务页、详情、操作区、异常页', 'npm build 通过;页面字段与原型样例一致'],
|
|
135
|
-
['5', 'HITL', '端到端验收', '8 类工作流逐项演示、异常处理、mock 无真实副作用证明', 'go test ./...、前端 build、浏览器人工验收记录'],
|
|
136
|
-
];
|
|
137
|
-
const testRows = eventRows.map(([eventType, scope, rule]) => [
|
|
138
|
-
eventType,
|
|
139
|
-
`验证 ${scope}`,
|
|
140
|
-
`${eventType === '总览' ? 'overview API + seed 统计' : 'usecase mock workflow + API detail/action 测试'}`,
|
|
141
|
-
`${rule};浏览器中从列表进入详情并完成允许动作`,
|
|
142
|
-
]);
|
|
143
|
-
|
|
144
|
-
const planText = [
|
|
145
|
-
`# 计划:${slug}`,
|
|
146
|
-
'',
|
|
147
|
-
'## 需求摘要',
|
|
148
|
-
'',
|
|
149
|
-
'在 Account 服务内实现美股公司行动任务处理平台。首期覆盖总览、分红派息、拆股、合股、退市/摘牌、期权退市 OCC、代码/名称变更和事件异常处理。后端提供固定 `/admin/v1/corporate-actions/*` 管理接口;前端新建 `web/admin` 并由现有 `/account/admin/` 静态托管;事件、任务、明细、期权调整、异常、操作日志和 mock 下游状态必须持久化;外部系统和下游回写全部 mock;通知不做。',
|
|
150
|
-
'',
|
|
151
|
-
'## 原始需求清单',
|
|
152
|
-
'',
|
|
153
|
-
...eventRows.map((row, index) => `${index + 1}. ${row[0]}:${row[1]}。`),
|
|
154
|
-
'',
|
|
155
|
-
'## 方案选择/ADR',
|
|
156
|
-
'',
|
|
157
|
-
mdTable(['方案', '结论', '理由', '代价'], [
|
|
158
|
-
['统一任务底座 + 事件类型扩展 + mock provider', '采用', '状态机、日志、异常、权限、页面 shell 可复用,能覆盖全量原型并控制真实副作用', '必须把事件差异写成明确字段/子表/受控 payload,避免 JSON 失控'],
|
|
159
|
-
['每类公司行动独立实现', '拒绝', '重复状态机、日志、异常和页面,首期实现和回归成本过高', '虽然领域表达更细,但不适合当前 mock 闭环目标'],
|
|
160
|
-
['仅静态前端或内存 mock', '拒绝', '不能满足持久化、回放、审计和 build 后验收', '交付快但后续实现必然重写'],
|
|
161
|
-
]),
|
|
162
|
-
'',
|
|
163
|
-
'## 架构边界',
|
|
164
|
-
'',
|
|
165
|
-
'- API 前缀唯一确定为 `/admin/v1/corporate-actions/*`;`/account/admin/` 只负责后台静态页面托管,不作为 API 前缀。',
|
|
166
|
-
'- 真实行情、OCC、清算、资产、交易、风控、展示、柜台、通知系统均不接入;首期只允许 local mock provider。',
|
|
167
|
-
'- 后端状态机是唯一真相;前端只展示后端返回的可用动作,不自行推导状态。',
|
|
168
|
-
'- 通知、OCC PDF 解析、非美股市场、真实客户资产/订单自动修改均为非目标。',
|
|
169
|
-
'',
|
|
170
|
-
'## 事件处理规则',
|
|
171
|
-
'',
|
|
172
|
-
mdTable(['工作流', '覆盖内容', '处理规则', '验收样例'], eventRows),
|
|
173
|
-
'',
|
|
174
|
-
'## 开发切片',
|
|
175
|
-
'',
|
|
176
|
-
mdTable(['Slice', '模式', '名称', '交付物', '验收信号'], sliceRows),
|
|
177
|
-
'',
|
|
178
|
-
'## 测试矩阵',
|
|
179
|
-
'',
|
|
180
|
-
mdTable(['工作流', '业务断言', '自动化验证', '人工验收'], testRows),
|
|
181
|
-
'',
|
|
182
|
-
'## 风险与非目标',
|
|
183
|
-
'',
|
|
184
|
-
'- 高风险:资金、资产、订单、期权合约、保证金和展示下发均只能 mock;任何真实 client 注入都必须被测试或代码结构阻断。',
|
|
185
|
-
'- 高风险:状态机必须拒绝未确认执行、已完成后继续动作、执行中重算、存在阻断异常时确认/执行。',
|
|
186
|
-
'- 非目标:真实外部接口容错、通知发送、OCC PDF 解析、非美股市场、真实资产账本迁移。',
|
|
187
|
-
'',
|
|
188
|
-
'## 人工确认点',
|
|
189
|
-
'',
|
|
190
|
-
'- plan 产物需要人工确认后才允许 build。',
|
|
191
|
-
'- Slice 1 状态机和 Ent schema 属于 HITL,必须人工确认字段和状态含义。',
|
|
192
|
-
'- Slice 4/5 前端页面和端到端演示必须人工确认原型覆盖度。',
|
|
193
|
-
'',
|
|
194
|
-
'## Build Handoff',
|
|
195
|
-
'',
|
|
196
|
-
'- build 输入以本计划、架构方案、开发计划、详细设计、测试计划为准。',
|
|
197
|
-
'- build 阶段如果发现产品文档、原型说明和代码事实冲突,先停止对应高风险分支并回到 plan 修订。',
|
|
198
|
-
].join('\n');
|
|
199
|
-
|
|
200
|
-
const architectureText = [
|
|
201
|
-
`# 架构方案:${slug}`,
|
|
202
|
-
'',
|
|
203
|
-
'## 文档定位',
|
|
204
|
-
'',
|
|
205
|
-
'架构方案回答系统边界、模块职责、数据/状态模型、接口集成、关键流程和架构取舍;不负责逐文件排期,也不替代字段级详细设计。',
|
|
206
|
-
'',
|
|
207
|
-
'## 架构目标与非目标',
|
|
208
|
-
'',
|
|
209
|
-
'- 目标:在 Account 服务内新增独立公司行动任务域,完成 8 类工作流的 mock 闭环。',
|
|
210
|
-
'- 目标:通过统一状态机、结构化持久化、操作日志和 mock provider 控制金融副作用风险。',
|
|
211
|
-
'- 非目标:真实外部系统、通知、OCC PDF 解析、非美股市场、真实资产/订单自动变更。',
|
|
212
|
-
'',
|
|
213
|
-
'## 上下文与系统边界',
|
|
214
|
-
'',
|
|
215
|
-
'- 静态页面入口:`/account/admin/`,加载 `web/admin/dist/index.html`。',
|
|
216
|
-
'- 管理 API 入口:固定 `/admin/v1/corporate-actions/*`。',
|
|
217
|
-
'- 服务内模块:`internal/api/open/admin` 负责 HTTP 适配;`internal/biz/corporateaction` 负责状态机和 usecase;`internal/data/ent/schema` 负责持久化;`internal/service` 聚合 usecase;`internal/server` 注册路由和权限。',
|
|
218
|
-
'- 外部依赖边界:EventSourceProvider、ImpactProvider、ExecutionProvider、ExceptionProvider 首期全部 local mock。',
|
|
219
|
-
'',
|
|
220
|
-
'## 组件与职责',
|
|
221
|
-
'',
|
|
222
|
-
mdTable(['组件', '职责', '禁止事项'], [
|
|
223
|
-
['Admin Handler', '参数解析、权限校验、响应映射、调用 usecase', '不得写业务状态机,不得直接访问真实外部系统'],
|
|
224
|
-
['CorporateAction Usecase', '事件入库、任务生成、状态推进、明细生成、异常处理、日志记录', '不得绕过 repository 写库,不得调用未声明真实 client'],
|
|
225
|
-
['Repository/Data', 'Ent schema、事务、唯一键、查询、版本链、日志落库', '不得在 data 层决定业务动作是否合法'],
|
|
226
|
-
['Mock Providers', '生成事件、客户影响、OCC/清算确认、mock 执行和回写', '不得连接真实行情/OCC/资产/交易/通知'],
|
|
227
|
-
['Admin Web', '总览、任务列表、详情、明细、操作区、异常页', '不得自行推进状态,不得隐藏后端阻断异常'],
|
|
228
|
-
]),
|
|
229
|
-
'',
|
|
230
|
-
'## 数据与状态模型',
|
|
231
|
-
'',
|
|
232
|
-
mdTable(['实体', '关键字段', '职责', '主键/幂等/关系'], entityRows),
|
|
233
|
-
'',
|
|
234
|
-
'## 状态机',
|
|
235
|
-
'',
|
|
236
|
-
'主状态固定为:待生成、待复核、待确认、待执行、执行中、差异待处理、无需处理、已完成。终态为无需处理、已完成。任务级状态优先级:差异待处理 > 执行中 > 待执行 > 待确认 > 待复核 > 待生成;明细级阻断异常会把任务拉回差异待处理。',
|
|
237
|
-
'',
|
|
238
|
-
mdTable(['动作', '允许起始状态', '前置条件', '成功状态', '失败/阻断状态', '审计和副作用'], stateRows),
|
|
239
|
-
'',
|
|
240
|
-
'## 接口与集成契约',
|
|
241
|
-
'',
|
|
242
|
-
mdTable(['方法', '路径', '用途', '权限标识'], apiRows),
|
|
243
|
-
'',
|
|
244
|
-
'## Provider 契约',
|
|
245
|
-
'',
|
|
246
|
-
mdTable(['Provider', '方法', '输入/输出', '边界'], providerRows),
|
|
247
|
-
'',
|
|
248
|
-
'## 关键流程',
|
|
249
|
-
'',
|
|
250
|
-
'1. mock seed 拉取 EventInput,按 `corporate_action_event_id + version` 去重入库 CorporateActionEvent。',
|
|
251
|
-
'2. usecase 根据 event_type 生成 CorporateActionTask,初始状态为待生成;取消/修订事件写新版本并使旧任务进入无需处理或差异待处理。',
|
|
252
|
-
'3. 运营点击生成明细,ImpactProvider 生成客户明细、期权调整和初始异常;状态进入待复核。',
|
|
253
|
-
'4. 运营复核/确认后,任务进入待执行;存在阻断异常时只能处理异常或标记无需处理。',
|
|
254
|
-
'5. 运营点击执行/下发,ExecutionProvider 只写 mock DownstreamStatus;全部成功后已完成,失败或超时进入差异待处理。',
|
|
255
|
-
'6. 异常处理写 Discrepancy、OperationLog,并按处理结果回到待确认或待执行。',
|
|
256
|
-
'',
|
|
257
|
-
'## 迁移、发布与回滚',
|
|
258
|
-
'',
|
|
259
|
-
'- 上线顺序:先合入 Ent schema 和生成代码,再接 usecase/repository,再注册 API/权限,最后发布 `web/admin`。',
|
|
260
|
-
'- 数据兼容:新增表为 additive,不修改开户、入金、通知和真实 SDK 表;无历史公司行动数据需要回填。',
|
|
261
|
-
'- 前后端错位:前端对 404/空数据展示空态;后端 API 在权限未注册前不暴露菜单入口。',
|
|
262
|
-
'- 回滚:关闭菜单/路由即可停止入口;mock seed 不再运行;已创建的新表可保留为无入口数据,生产迁移回滚需单独 DBA 审批。',
|
|
263
|
-
'',
|
|
264
|
-
'## 质量属性与风险',
|
|
265
|
-
'',
|
|
266
|
-
'- 可测试性:状态机、去重、provider mock、API、前端 build 和端到端样例均有独立验证。',
|
|
267
|
-
'- 可观测性:每个人工动作、mock 回写、异常处理都写 OperationLog/DownstreamStatus。',
|
|
268
|
-
'- 安全性:真实外部系统不注入到公司行动模块;ExecutionProvider 只有 mock 实现。',
|
|
269
|
-
'',
|
|
270
|
-
'## 架构决策记录',
|
|
271
|
-
'',
|
|
272
|
-
mdTable(['决策', '结论', '理由', '后续影响'], [
|
|
273
|
-
['API 前缀', '固定 `/admin/v1/corporate-actions/*`', '复用 Account 现有后台 API 风格,避免 `/account/admin/v1` 二义性', '前端 API client baseURL 固定为空或同源 `/admin/v1`'],
|
|
274
|
-
['状态机', '后端集中定义转换矩阵', '金融动作不能由前端或分散 handler 推进', '所有非法动作写单测'],
|
|
275
|
-
['数据模型', '公共字段结构化落列,事件差异放受控 payload', '兼顾查询、审计和事件差异', '真实接入前可逐步收敛 payload 字段'],
|
|
276
|
-
['外部系统', '首期 local mock provider', '需求明确不接真实外部系统', '真实 adapter 必须另走 clarify/plan'],
|
|
277
|
-
]),
|
|
278
|
-
].join('\n');
|
|
279
|
-
|
|
280
|
-
const developmentPlanText = [
|
|
281
|
-
`# 开发计划:${slug}`,
|
|
282
|
-
'',
|
|
283
|
-
'## 文档定位',
|
|
284
|
-
'',
|
|
285
|
-
'开发计划回答按什么顺序交付、每个切片的完成边界、依赖、验证、人工确认点和回滚策略;不重新选择架构,不替代详细设计。',
|
|
286
|
-
'',
|
|
287
|
-
'## 交付切片',
|
|
288
|
-
'',
|
|
289
|
-
mdTable(['Slice', '模式', '目标', '主要文件', '完成定义'], [
|
|
290
|
-
['1', 'HITL', '领域/数据/状态底座', '`internal/biz/corporateaction/*`, `internal/data/ent/schema/corporate_action_*.go`, `internal/service/service.go`', 'Ent 生成通过;状态机合法/非法动作单测通过;事件去重单测通过'],
|
|
291
|
-
['2', 'AFK', 'Mock 数据与任务闭环', '`mock_provider.go`, usecase 明细生成/执行/异常处理测试', '8 类 mock 事件可 seed;任务、明细、日志、下游状态落库;无真实 client'],
|
|
292
|
-
['3', 'HITL', '管理 API 与权限', '`internal/api/open/admin/corporate_action.go`, `internal/server/server.go`', 'overview/list/detail/action/discrepancy 测试通过;permission_mark 注册明确'],
|
|
293
|
-
['4', 'HITL', '后台前端', '`web/admin/*`', '总览、共享任务页、异常页可构建;字段与原型样例一致;动作后刷新状态'],
|
|
294
|
-
['5', 'HITL', '端到端验收', '测试与验收记录', '8 类工作流各跑一条样例;异常可处理;无真实外部副作用证据完整'],
|
|
295
|
-
]),
|
|
296
|
-
'',
|
|
297
|
-
'## 实施顺序与依赖',
|
|
298
|
-
'',
|
|
299
|
-
'1. 先做 Slice 1,锁定 Ent schema、状态机和 provider 接口;未确认前不做页面动作。',
|
|
300
|
-
'2. Slice 2 只依赖 Slice 1,先完成 mock seed 和 usecase 测试,让业务闭环可在后端跑通。',
|
|
301
|
-
'3. Slice 3 在 Slice 2 后暴露 API;handler 不补业务规则,只调用 usecase。',
|
|
302
|
-
'4. Slice 4 在 API contract 稳定后接前端;共享任务 shell 通过 event_type 配置列、详情字段和动作。',
|
|
303
|
-
'5. Slice 5 做全量回归和人工浏览器验收。',
|
|
304
|
-
'',
|
|
305
|
-
'## 需求到开发切片',
|
|
306
|
-
'',
|
|
307
|
-
mdTable(['需求', '切片', '交付物', '验证'], testRows.map(([workflow, assertion, auto, manual]) => [workflow, workflow === '总览' ? 'Slice 3/4/5' : 'Slice 2/3/4/5', assertion, `${auto};${manual}`])),
|
|
308
|
-
'',
|
|
309
|
-
'## 文件级变更清单',
|
|
310
|
-
'',
|
|
311
|
-
mdTable(['路径', '变更', '说明'], [
|
|
312
|
-
['internal/biz/corporateaction/enums.go', '新增', '事件类型、状态、动作、异常类型、下游系统枚举'],
|
|
313
|
-
['internal/biz/corporateaction/state_machine.go', '新增', '动作到状态的集中转换表和校验函数'],
|
|
314
|
-
['internal/biz/corporateaction/usecase.go', '新增', 'overview/list/detail/generate/action/resolve 编排'],
|
|
315
|
-
['internal/biz/corporateaction/mock_provider.go', '新增', '8 类 mock 事件、影响明细、mock 执行/回写'],
|
|
316
|
-
['internal/data/ent/schema/corporate_action_*.go', '新增', '7 张公司行动核心表'],
|
|
317
|
-
['internal/api/open/admin/corporate_action.go', '新增', '管理 API handler'],
|
|
318
|
-
['internal/server/server.go', '修改', '注册 `/admin/v1/corporate-actions/*` 和权限标识'],
|
|
319
|
-
['web/admin/*', '新增', 'Vue/Vite 或仓库确认的前端工程,总览/任务/异常页面'],
|
|
320
|
-
['internal/tests/corporate_action_*_test.go', '新增', '状态机、mock workflow、API、回归测试'],
|
|
321
|
-
]),
|
|
322
|
-
'',
|
|
323
|
-
'## 验证计划',
|
|
324
|
-
'',
|
|
325
|
-
'- `go test ./internal/biz/corporateaction -run StateMachine`:状态转换和非法动作。',
|
|
326
|
-
'- `go test ./internal/biz/corporateaction -run MockWorkflow`:8 类 mock 样例闭环。',
|
|
327
|
-
'- `go test ./internal/api/open/admin ./internal/server -run CorporateAction`:API、权限和路由。',
|
|
328
|
-
'- `go test ./...`:仓库级回归。',
|
|
329
|
-
'- `cd web/admin && npm install && npm run build`:前端构建。',
|
|
330
|
-
'- 浏览器访问 `/account/admin/`:人工验收总览、任务详情、明细、操作、异常处理。',
|
|
331
|
-
'',
|
|
332
|
-
'## 人工确认点',
|
|
333
|
-
'',
|
|
334
|
-
'- Ent schema、状态机矩阵和 API 前缀在 Slice 1/3 前必须人工确认。',
|
|
335
|
-
'- 前端字段与原型样例在 Slice 4 完成后人工确认。',
|
|
336
|
-
'- 端到端演示前确认 mock-only 边界,没有真实资产、交易、通知副作用。',
|
|
337
|
-
'',
|
|
338
|
-
'## 回滚/降级策略',
|
|
339
|
-
'',
|
|
340
|
-
'- 若后端未完成,前端菜单不开放;静态托管可保持无入口。',
|
|
341
|
-
'- 若前端失败,保留 API 和 mock 测试,build 记录前端 remaining scope。',
|
|
342
|
-
'- 若迁移有风险,先不执行生产迁移;新增表为 additive,回滚入口优先于删表。',
|
|
343
|
-
'',
|
|
344
|
-
'## 完成定义',
|
|
345
|
-
'',
|
|
346
|
-
'- 8 类工作流全部有 mock 样例、API 详情、明细、日志和可验收动作。',
|
|
347
|
-
'- 状态机、去重、异常、mock 执行和权限测试通过。',
|
|
348
|
-
'- HTML/Markdown plan 产物可由人工直接审阅,不依赖 runtime 状态页。',
|
|
349
|
-
].join('\n');
|
|
350
|
-
|
|
351
|
-
const testPlanText = [
|
|
352
|
-
`# 测试计划:${slug}`,
|
|
353
|
-
'',
|
|
354
|
-
'## 需求到测试矩阵',
|
|
355
|
-
'',
|
|
356
|
-
mdTable(['工作流', '自动化测试', '人工验收', '必须断言'], testRows.map(([workflow, assertion, auto, manual]) => [workflow, auto, manual, assertion])),
|
|
357
|
-
'',
|
|
358
|
-
'## 状态机测试',
|
|
359
|
-
'',
|
|
360
|
-
mdTable(['动作', '正向断言', '反向断言'], stateRows.map(([action, from, guard, success]) => [action, `${from} 满足 ${guard} 时进入 ${success}`, `不满足前置条件、终态、执行中重算、存在阻断异常时必须拒绝并保持原状态`])),
|
|
361
|
-
'',
|
|
362
|
-
'## 数据与持久化测试',
|
|
363
|
-
'',
|
|
364
|
-
'- `corporate_action_event_id + version` 重复入库不重复建任务;版本修订保留追溯。',
|
|
365
|
-
'- 任务详情返回 Event、Task、CustomerDetail、OptionAdjustment、Discrepancy、DownstreamStatus、OperationLog。',
|
|
366
|
-
'- 服务重启后任务、明细、异常、日志仍可查询。',
|
|
367
|
-
'',
|
|
368
|
-
'## API 与权限测试',
|
|
369
|
-
'',
|
|
370
|
-
mdTable(['接口', '测试重点'], apiRows.map(([method, path, purpose, permission]) => [`${method} ${path}`, `${purpose};校验 ${permission};非法参数和越权返回明确错误`])),
|
|
371
|
-
'',
|
|
372
|
-
'## Mock 边界测试',
|
|
373
|
-
'',
|
|
374
|
-
'- ExecutionProvider 测试注入 only mock 实现;执行/下发只写 DownstreamStatus,不调用真实资产、交易、通知 client。',
|
|
375
|
-
'- 下游失败/超时创建 Discrepancy,任务进入差异待处理。',
|
|
376
|
-
'- 通知功能没有真实发送记录,只允许 mock 或空状态。',
|
|
377
|
-
'',
|
|
378
|
-
'## 人工验收',
|
|
379
|
-
'',
|
|
380
|
-
'- 打开 `/account/admin/`,seed 后总览展示 8 类样例和异常/超时提示。',
|
|
381
|
-
'- 每类工作流从列表进入详情,核对原型字段、客户明细、期权明细、操作日志。',
|
|
382
|
-
'- 每类至少完成一次生成明细、复核、确认、执行或下发;异常页至少处理一条差异。',
|
|
383
|
-
'',
|
|
384
|
-
'## 回归门禁',
|
|
385
|
-
'',
|
|
386
|
-
'- build 结束前必须保留命令输出、浏览器截图或人工验收记录。',
|
|
387
|
-
'- 任何未覆盖工作流必须进入 remaining scope,不能声明已完成。',
|
|
388
|
-
].join('\n');
|
|
389
|
-
|
|
390
|
-
return {
|
|
391
|
-
principles: [
|
|
392
|
-
'公司行动平台首期只做 mock 闭环,不触达真实资金、资产、交易、清算、展示或通知系统。',
|
|
393
|
-
'API 前缀、状态机、数据模型、provider 契约和验收矩阵必须在 plan 阶段定死。',
|
|
394
|
-
'8 类工作流不能只枚举名称,必须分别给出处理规则、异常路径和验证信号。',
|
|
395
|
-
'人工确认动作是状态推进边界,前端不得绕过后端状态机。',
|
|
396
|
-
'Markdown 是可编辑沟通源,HTML 是完整可读方案视图。',
|
|
397
|
-
],
|
|
398
|
-
decisionDrivers: [
|
|
399
|
-
'产品和原型要求覆盖全量公司行动后台工作流。',
|
|
400
|
-
'Account 服务内实现必须控制现有开户、入金、通知和真实外部 SDK 的影响面。',
|
|
401
|
-
'后续 build 需要明确字段、状态、API、mock 边界和验收路径。',
|
|
402
|
-
],
|
|
403
|
-
options: [
|
|
404
|
-
{ name: '统一任务底座 + 事件类型扩展', pros: ['集中状态机、日志、异常、权限和页面 shell', '实现量可控', '便于后续真实 adapter 替换 mock'], cons: ['必须约束扩展 payload,避免字段失控'] },
|
|
405
|
-
{ name: '每类事件独立系统', pros: ['领域表达细'], cons: ['重复状态机/日志/页面,首期风险过高'] },
|
|
406
|
-
{ name: '静态原型或内存 mock', pros: ['最快'], cons: ['不满足持久化、审计、内部闭环和 build 验收'] },
|
|
407
|
-
],
|
|
408
|
-
planText,
|
|
409
|
-
architectureText,
|
|
410
|
-
developmentPlanText,
|
|
411
|
-
testPlanText,
|
|
412
|
-
preMortem: [
|
|
413
|
-
'若 API 前缀再次出现 `/account/admin/v1` 与 `/admin/v1` 双口径,必须阻断 build。',
|
|
414
|
-
'若状态机矩阵未被实现为集中表和单测,执行/下发会存在误推进风险。',
|
|
415
|
-
'若 mock provider 与真实 client 混放,必须停止实现并拆分边界。',
|
|
416
|
-
],
|
|
417
|
-
principlesResolved: true,
|
|
418
|
-
optionsReviewed: true,
|
|
419
|
-
acceptanceCriteriaTestable: true,
|
|
420
|
-
verificationStepsResolved: true,
|
|
421
|
-
executionInputsResolved: true,
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
|
|
425
76
|
function plannerDraftFromSource({ slug, sourceText, deliberateMode }) {
|
|
426
|
-
if (isCorporateActionSource(sourceText)) {
|
|
427
|
-
return corporateActionPlannerDraft({ slug, sourceText, deliberateMode });
|
|
428
|
-
}
|
|
429
77
|
const summary = buildSourceSummary(sourceText);
|
|
430
78
|
const executionInputs = bulletsFromSection(extractSection(sourceText, 'Execution Inputs'), []);
|
|
431
79
|
const executionInputsResolved = executionInputs.length > 0 && executionInputs.every((item) => !/\b(TBD|待定|unknown|later)\b/i.test(item));
|
package/src/workflow.mjs
CHANGED
|
@@ -296,7 +296,7 @@ function compactPlanningText(text, { html = false } = {}) {
|
|
|
296
296
|
|| trimmed.startsWith('|')
|
|
297
297
|
|| /^[-*]\s+/.test(trimmed)
|
|
298
298
|
|| /^\d+[.)]\s+/.test(trimmed)
|
|
299
|
-
|| /MUST|SHALL|必须|不得|不能|不自动|人工|确认|复核|执行|下发|任务|字段|状态|流程|规则|范围|来源|验收|示例|异常|差异|
|
|
299
|
+
|| /MUST|SHALL|必须|不得|不能|不自动|人工|确认|复核|执行|下发|任务|字段|状态|流程|规则|范围|来源|验收|示例|异常|差异|mock|API|接口|持久化|页面|明细|日志|权限/i.test(trimmed);
|
|
300
300
|
};
|
|
301
301
|
|
|
302
302
|
for (const line of source.split('\n')) {
|
|
@@ -854,8 +854,8 @@ function markdownTableCoverageItems(sourceText) {
|
|
|
854
854
|
continue;
|
|
855
855
|
}
|
|
856
856
|
if (
|
|
857
|
-
|
|
858
|
-
|| cells.some((cell) => /SHALL|MUST|
|
|
857
|
+
/事件|字段|处理模式|标准化|范围|任务|确认|复核|审批|审计|权限|资源|下发|source|event|field|coverage|requirement/i.test(currentHeading)
|
|
858
|
+
|| cells.some((cell) => /SHALL|MUST|manual_|raw_snapshot|event_|处理|确认|复核|审批|补偿|回滚|下发|不自动/i.test(cell))
|
|
859
859
|
) {
|
|
860
860
|
items.push(first);
|
|
861
861
|
}
|
|
@@ -872,7 +872,7 @@ function requirementHeadingCoverageItems(sourceText) {
|
|
|
872
872
|
function relevantHeadingCoverageItems(sourceText) {
|
|
873
873
|
return [...String(sourceText || '').matchAll(/^#{2,4}\s+(.+?)\s*$/gm)]
|
|
874
874
|
.map((match) => match[1].replace(/`/g, '').trim())
|
|
875
|
-
.filter((title) =>
|
|
875
|
+
.filter((title) => /需求|范围|验收|页面|任务|事件|流程|规则|字段|接口|架构|设计|计划|处理|异常|差异|复核|审批|审计|权限|资源|mock/i.test(title))
|
|
876
876
|
.filter((title) => !/^(审阅说明|门禁|source|context|inference)$/i.test(title));
|
|
877
877
|
}
|
|
878
878
|
|
|
@@ -1103,126 +1103,7 @@ function enrichDevelopmentPlanTextForReview(text, items) {
|
|
|
1103
1103
|
return next;
|
|
1104
1104
|
}
|
|
1105
1105
|
|
|
1106
|
-
function isCorporateActionDesignDraft(items, plannerDraft) {
|
|
1107
|
-
return /公司行动|corporate-actions|OCC|分红派息|拆股|合股|退市|摘牌/.test([
|
|
1108
|
-
...items,
|
|
1109
|
-
plannerDraft?.planText,
|
|
1110
|
-
plannerDraft?.architectureText,
|
|
1111
|
-
plannerDraft?.developmentPlanText,
|
|
1112
|
-
].join('\n'));
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
function corporateActionDetailedDesignTextForChange({ changeId, slug }) {
|
|
1116
|
-
const stateRows = [
|
|
1117
|
-
['生成明细', '待生成', '待复核', '事件已入库且未生成有效明细版本', '写 CustomerDetail/OptionAdjustment/Discrepancy/OperationLog'],
|
|
1118
|
-
['重算', '待复核、待确认、差异待处理', '待复核', '任务未执行且存在修正输入', '废弃旧 detail_version,生成新版本'],
|
|
1119
|
-
['复核', '待复核', '待确认', '明细完整且无阻断异常', '仅人工触发,写 OperationLog'],
|
|
1120
|
-
['确认', '待确认', '待执行', '税费、数量、客户范围、OCC 字段均已复核', '冻结当前有效明细版本'],
|
|
1121
|
-
['执行', '待执行', '执行中', '现金/持仓类动作且无阻断异常', '调用 mock ExecutionProvider,写 DownstreamStatus'],
|
|
1122
|
-
['下发', '待执行', '执行中', '展示/订单/期权链/柜台类动作且无阻断异常', '调用 mock ExecutionProvider,写 DownstreamStatus'],
|
|
1123
|
-
['mock 回写成功', '执行中', '已完成', '全部目标系统 success', '系统回写日志,不允许从非执行中推进'],
|
|
1124
|
-
['mock 回写失败', '执行中', '差异待处理', '任一目标系统 failed/timeout', '创建 Discrepancy,保留 failure_reason'],
|
|
1125
|
-
['重试', '差异待处理、执行中', '执行中', '失败原因已处理或允许补偿查询', 'retry_count + 1 并写日志'],
|
|
1126
|
-
['标记无需处理', '非终态', '无需处理', '人工确认无客户/平台动作', '必须填写原因,终态禁止再执行'],
|
|
1127
|
-
['标记人工完成', '待执行、差异待处理', '已完成', '外部已人工处理且有备注/凭证', '不触发 mock 执行,只写日志'],
|
|
1128
|
-
];
|
|
1129
|
-
return [
|
|
1130
|
-
`# 详细设计:${changeId}`,
|
|
1131
|
-
'',
|
|
1132
|
-
'## 文档定位',
|
|
1133
|
-
'',
|
|
1134
|
-
'本文档给 build 阶段提供字段、接口、函数、组件、状态机和边界条件级别的实现输入。架构文档决定边界,开发计划决定顺序,本文决定具体怎么落地。',
|
|
1135
|
-
'',
|
|
1136
|
-
'## 需求到设计映射',
|
|
1137
|
-
'',
|
|
1138
|
-
requirementMappingTable(['总览', '分红派息', '拆股', '合股', '退市/摘牌', '期权退市 OCC', '代码/名称变更', '事件异常处理'], [
|
|
1139
|
-
['需求', (item) => item],
|
|
1140
|
-
['后端落点', () => 'CorporateActionUsecase + Ent repository + mock provider'],
|
|
1141
|
-
['前端落点', () => 'web/admin 共享任务 shell,按 event_type 配置列表列、详情字段、动作按钮'],
|
|
1142
|
-
['验证证据', () => 'usecase/API 测试 + 浏览器人工验收'],
|
|
1143
|
-
]),
|
|
1144
|
-
'',
|
|
1145
|
-
'## 数据结构与字段',
|
|
1146
|
-
'',
|
|
1147
|
-
'| 实体 | 字段 | 索引/关系 | 说明 |',
|
|
1148
|
-
'| --- | --- | --- | --- |',
|
|
1149
|
-
'| CorporateActionEvent | corporate_action_event_id, source, source_event_id, event_type, market, asset_type, security_id, underlying_security_id, symbol, key_date, version, event_status, raw_snapshot_id, event_payload | unique(corporate_action_event_id, version) | 事件快照和修订追溯;同版本重复不建任务 |',
|
|
1150
|
-
'| CorporateActionTask | task_id, event_id, event_type, task_status, asset_scope, security_id, symbol, key_date, affected_customer_count, affected_order_count, risk_flags, current_detail_version, detail_payload | unique(task_id), index(event_id,status,type) | 运营主任务和状态机载体 |',
|
|
1151
|
-
'| CorporateActionCustomerDetail | task_id, detail_version, user_id, trade_account_id, security_id, asset_type, position_qty, cash_amount, tax_amount, net_amount, order_action, margin_status, process_status, detail_payload | index(task_id,detail_version,user_id) | 客户级明细;支持多版本重算 |',
|
|
1152
|
-
'| CorporateActionOptionAdjustment | task_id, memo_no, underlying_security_id, option_security_id, original_contract, adjusted_contract, old_strike, new_strike, old_multiplier, new_multiplier, deliverable, review_status, adjustment_payload | index(task_id,memo_no,underlying_security_id) | OCC 和期权调整明细 |',
|
|
1153
|
-
'| CorporateActionDiscrepancy | task_id, detail_id, option_adjustment_id, downstream_status_id, discrepancy_type, field_name, estimated_value, confirmed_value, status, resolution_note | index(task_id,status,type) | 金额、数量、客户范围、合约映射、下游回写差异 |',
|
|
1154
|
-
'| CorporateActionDownstreamStatus | task_id, target_system, action_type, status, request_payload, response_payload, failure_reason, retry_count | index(task_id,target_system,status) | mock 执行/下发状态;禁止真实 client 写入 |',
|
|
1155
|
-
'| CorporateActionOperationLog | task_id, operator_id, operator_name, action_type, before_status, after_status, remark, created_at | index(task_id,created_at) | 所有人工动作和系统回写留痕 |',
|
|
1156
|
-
'',
|
|
1157
|
-
'## 接口、函数与组件契约',
|
|
1158
|
-
'',
|
|
1159
|
-
'| 契约 | 输入 | 输出 | 错误/权限 |',
|
|
1160
|
-
'| --- | --- | --- | --- |',
|
|
1161
|
-
'| GET /admin/v1/corporate-actions/overview | status/date range | 统计卡片、风险提示、异常/超时 | admin.corporate_action.view |',
|
|
1162
|
-
'| POST /admin/v1/corporate-actions/mock/seed | seed profile | 8 类 mock 任务数量 | admin.corporate_action.seed;重复 seed 按 event id 去重 |',
|
|
1163
|
-
'| GET /admin/v1/corporate-actions/tasks | event_type/status/symbol/task_id/key_date/page | 任务列表和分页 | admin.corporate_action.view |',
|
|
1164
|
-
'| GET /admin/v1/corporate-actions/tasks/{task_id} | task_id/detail_version | event/task/details/options/discrepancies/downstream/logs/available_actions | admin.corporate_action.view |',
|
|
1165
|
-
'| POST /tasks/{task_id}/details/generate | task_id, force_recalc, remark | 新 detail_version 和状态 | admin.corporate_action.operate;非法状态拒绝 |',
|
|
1166
|
-
'| POST /tasks/{task_id}/actions/{action} | action, remark, optional resolution payload | 新状态、日志、下游状态 | admin.corporate_action.operate;状态机统一校验 |',
|
|
1167
|
-
'| GET /discrepancies | status/type/task_id/symbol/page | 异常列表 | admin.corporate_action.view |',
|
|
1168
|
-
'| POST /discrepancies/{id}/resolve | confirmed_value/resolution_note/next_status | 异常处理结果和任务状态 | admin.corporate_action.operate |',
|
|
1169
|
-
'',
|
|
1170
|
-
'Provider 接口固定为:`EventSourceProvider.FetchMockEvents`、`ImpactProvider.BuildDetails`、`ExecutionProvider.Execute`、`ExceptionProvider.Resolve`。首期只提供 local mock 实现;真实 adapter 不在本次范围。',
|
|
1171
|
-
'',
|
|
1172
|
-
'## 状态机与流程细节',
|
|
1173
|
-
'',
|
|
1174
|
-
requirementMappingTable(stateRows, [
|
|
1175
|
-
['动作', (row) => row[0]],
|
|
1176
|
-
['起始状态', (row) => row[1]],
|
|
1177
|
-
['成功状态', (row) => row[2]],
|
|
1178
|
-
['前置条件', (row) => row[3]],
|
|
1179
|
-
['副作用', (row) => row[4]],
|
|
1180
|
-
]),
|
|
1181
|
-
'',
|
|
1182
|
-
'任务级状态优先级为:差异待处理 > 执行中 > 待执行 > 待确认 > 待复核 > 待生成。明细级阻断异常优先于任务级普通状态;只要存在未处理阻断异常,确认、执行、下发必须拒绝。',
|
|
1183
|
-
'',
|
|
1184
|
-
'## 错误处理与边界条件',
|
|
1185
|
-
'',
|
|
1186
|
-
'- 重复事件:同 `corporate_action_event_id + version` 返回已有事件,不重复建任务。',
|
|
1187
|
-
'- 事件修订:新 version 建立新事件快照;旧任务未完成时进入差异待处理或无需处理,保留日志。',
|
|
1188
|
-
'- 缺证券映射:创建事件异常,任务停在待复核,不允许执行。',
|
|
1189
|
-
'- OCC 字段缺失或合约匹配失败:写 OptionAdjustment + Discrepancy,任务差异待处理。',
|
|
1190
|
-
'- mock 下游失败/超时:写 DownstreamStatus failure_reason,任务差异待处理。',
|
|
1191
|
-
'- 真实副作用防线:公司行动模块不得注入真实资产、交易、清算、通知 client;测试需要断言执行/下发只写 mock 表。',
|
|
1192
|
-
'',
|
|
1193
|
-
'## 前端设计',
|
|
1194
|
-
'',
|
|
1195
|
-
'- `web/admin` 提供总览、任务页、异常页;总览首屏直接展示公司行动任务数据,不做营销页。',
|
|
1196
|
-
'- 任务页使用共享 shell:左侧筛选/列表,中间客户明细和期权明细,右侧任务详情、可用动作、操作日志。',
|
|
1197
|
-
'- `event_type` 配置列表列、详情字段、明细表列和动作按钮;按钮只使用后端 `available_actions`。',
|
|
1198
|
-
'- API base 固定同源 `/admin/v1/corporate-actions`,不要出现 `/account/admin/v1`。',
|
|
1199
|
-
'',
|
|
1200
|
-
'## 测试设计',
|
|
1201
|
-
'',
|
|
1202
|
-
'- 状态机:覆盖每个动作的合法/非法状态,尤其未确认执行、执行中重算、终态继续动作、存在阻断异常时确认/执行。',
|
|
1203
|
-
'- 数据:事件去重、版本修订、任务详情聚合、服务重启后查询。',
|
|
1204
|
-
'- 业务:8 类 mock 工作流各至少一条闭环样例。',
|
|
1205
|
-
'- API:overview/list/detail/action/discrepancy、权限标识、非法参数。',
|
|
1206
|
-
'- 前端:`npm run build`、浏览器检查总览/任务/异常、最长字段不重叠。',
|
|
1207
|
-
'- 副作用:执行/下发不调用真实 client,不发送通知。',
|
|
1208
|
-
'',
|
|
1209
|
-
'## 实现注意事项',
|
|
1210
|
-
'',
|
|
1211
|
-
'- 先实现状态机单测,再写 handler 和页面动作。',
|
|
1212
|
-
'- Ent schema 为 additive;生产回滚优先关闭菜单/路由,不直接删表。',
|
|
1213
|
-
'- build 阶段如果发现源文档和原型冲突,停止对应切片并回 plan 修订。',
|
|
1214
|
-
'',
|
|
1215
|
-
'## Source',
|
|
1216
|
-
'',
|
|
1217
|
-
`- workflow slug: ${slug}`,
|
|
1218
|
-
`- change id: ${changeId}`,
|
|
1219
|
-
].join('\n');
|
|
1220
|
-
}
|
|
1221
|
-
|
|
1222
1106
|
function detailedDesignTextForChange({ changeId, slug, items, plannerDraft }) {
|
|
1223
|
-
if (isCorporateActionDesignDraft(items, plannerDraft)) {
|
|
1224
|
-
return corporateActionDetailedDesignTextForChange({ changeId, slug });
|
|
1225
|
-
}
|
|
1226
1107
|
return [
|
|
1227
1108
|
`# loopx Detailed Design: ${changeId}`,
|
|
1228
1109
|
'',
|
|
@@ -2335,7 +2216,7 @@ function deriveSlugFromSpecPath(path, text) {
|
|
|
2335
2216
|
return normalizeSlug(meta.workflow_id);
|
|
2336
2217
|
}
|
|
2337
2218
|
const name = basename(path).replace(/\.md$/i, '');
|
|
2338
|
-
return normalizeSlug(name.replace(/^
|
|
2219
|
+
return normalizeSlug(name.replace(/^clarify-/, ''));
|
|
2339
2220
|
}
|
|
2340
2221
|
|
|
2341
2222
|
function containsChineseText(text) {
|