跳转到主要内容

FSD M11 · 评估与工具

← 总则 | 附录 → | 上游:PRD §4 M11 实现落点:backend/internal/domain/evaluation/(model/service〔workbench+watchVideo〕/service_eval〔评估流水线〕/service_review〔审片双入口〕/service_viral/repo)+ cmd/server/workbench_handlers.go + cmd/server/evaluation_handlers.go + cmd/server/routes.go:239-267(挂载,审片 4 条 :264-267 物理居中)。事实基准=Go 代码;冻结版 qmtv/server/workbench.js/evaluation.js/index.js:490-513(viral)仅差异对拍参照。 域内要点:评估冻结-结算是全站唯一 TypeReserve 台账面(总则 §1 词条的展开落点);审片双入口 404 文案分叉(classic ’task not found’ vs director ’not found’);审片面零 SSE 零通知;watchVideo 状态丢失不 emit;wire 全蛇形;PRD §4 M11 已登记差异 ①~⑭(prd-qmtv-v1.md:216)引用不重立。上传档位 up80(工作台)/up10(评估)。

M11 评估与工具

14 端点全量(workbench 2+审片 4+eval 6+viral 2)。三扣费面三制式:工作台 TOOLS 固定价、审片 10(空分镜先退后拒)、评估 TypeReserve 冻结-结算、viral 5——四制式互不同源(quirk 富矿域)。

F11.01 工作台工具提交(workbench/tasks POST)

对应 PRD:§4 M11 · POST /api/workbench/tasks | 状态:实现 | 实现落点:workbench_handlers.go:18-54、service.go:141-221 | UI:WorkbenchView(E2E-GEN-02 已实现——toast「去字幕完成」;confirm 仅 repaint 空描述分支)

1 功能定义

视频工作台三工具(一键转绘 20/去字幕 10/转高清 15)提交:扣费→异步处理→SSE workbench done。

2 触发条件与前置状态

登录态;tool key 白名单(TOOLS map);余额不足 402;双载荷(multipart 视频/JSON 文本,PRD ⑩)。

3 输入与校验

{tool, video_id?/描述}——repaint 需描述(前端 confirm 分支对应);taskId 无=空串(台账「工作台·X(-N)」service.go:176-178 逐字,冻结 workbench.js:52)。

4 处理流程

TryDeduct(固定价,settings 无此键)→ INSERT workbench_tasks(status=‘processing’)→ 异步 goroutine(提交段同步返回)→ watchVideo 编排(F11.02)。

5 输出与结果状态

{id, status:'processing'}(wb_ 行投影);列表窄投影不含 params 全文(model.go json:"-" 面:OutPath/VideoStatus JOIN 伴列)。

6 状态流转

processing→done(SSE workbench done 帧)/failed(视频链失败联动);「任务状态丢失」为终态旁支(不 emit,F11.02 §7)。

7 边界与异常
条件系统行为提示/码
tool 非三值400TOOLS 键校验
余额不足402统一信封
提交后进程重启RecoverStuck 回队(PRD ⑨,F11.02 §4)—
8 权限与数据规则

authed + amw 属主面;up80 档(workbench.js:12 multer 80MB 对齐,handler 单文件双保险 500「File too large」:35-37)。

F11.02 工作台列表/轮询/启动恢复(workbench/tasks GET)

对应 PRD:§4 M11 · GET /api/workbench/tasks | 状态:实现 | 实现落点:workbench_handlers.go:57-66、service.go:225-304 | UI:WorkbenchView 列表+轮询 | 场景挂钩:E2E-GEN-02(间接)

1 功能定义

本人工作台任务列表 + watchVideo 轮询状态机 + 服务重启悬挂恢复。

2 触发条件与前置状态

列表登录态(按 user_id);watchVideo 由 F11.01 提交后 goroutine 内启动(非 HTTP 端点)。

3 输入与校验

无参数(全量本人任务,无分页——照冻结 :78-123)。

4 处理流程

watchVideo(service.go:228-260):首 tick 3s/步进 5s/上限 180 次(model.go:117-122 可注入常量)→ VideoStatusOf 查 M3 videos 行 → done:SetWorkbenchDone+hub.Emit workbench done;视频 failed:SetWorkbenchWatchFailed 联动;状态丢失(!found 或超次):置失败后直接 return 不 emit(:238-241——PRD ⑥:冻结 :84 同分支无 bus.emit)。 RecoverStuck:启动扫 processing 悬挂行→重挂 watchVideo(PRD ⑨,二十续迁移面)。

5 输出与结果状态

列表行+status(含 done/failed/「任务状态丢失」文案面)。

6 状态流转

与 F11.01 §6 同一张状态机(本节是驱动器)。

7 边界与异常
条件系统行为提示/码
轮询超 180 次置「任务状态丢失」无 SSE 帧(quirk 照抄——前端轮询兜底可见)—
超时不退款扣费不回(PRD ⑥ 已登记)—
goroutine panicrecover 吞(service.go:227——防崩保护,watchVideo 假漏覆写测试教训面)—
8 权限与数据规则

authed + amw;轮询消费 M3 videos 表跨域读(VideoStatusOf 窄投影三列)。

F11.03 智能审片·写(review 双入口 POST)

对应 PRD:§4 M11 · POST /api/tasks/:id/review、POST /api/director3d/:id/review | 状态:实现 | 实现落点:workbench_handlers.go:69-92、service_review.go:21-73 | UI:DashboardView/VideoView 审片(classic)+ Director3DView 审片(director)| 场景挂钩:无

1 功能定义

智能审片提交:按 scope 拉分镜→LLM/Mock 逐镜评审→review_reports 落行。双入口同表同逻辑、404 文案分叉。

2 触发条件与前置状态

classic:task 存在+属主,404「task not found」(service_review.go:24);director:404「not found」(:34)——两哨兵不同字(model.go:224/:227,PRD ⑦);空分镜:先退台账再 400「审片退回:无分镜(+10)」(:52-58,Refund 唯一口 nil claim)。

3 输入与校验

无 body(scope 由服务端定);审片费 10 固定(402 走统一信封)。

4 处理流程

TryDeduct「智能审片(-10)」→ 拉分镜(classic 走 shots/director 走 director_shots——跨域共表 COALESCE 可空列读,PRD ⑪ 炸点修复面)→ LLM 截 40 条(firstN :95)→ mockReview:阈值 0.22/0.5/0.7 三档 issue(high/mid/low,:140-146)+维度分 78+rand20,主体一致性 −6,clamp [55,98](:157-161)→ review_reports 落行(scope/target_id 归属)。

5 输出与结果状态

{id}(report 行 id);详情走 F11.04。

6 状态流转

同步完成(review_reports 一次落定,无 processing 态)。

7 边界与异常
条件系统行为提示/码
classic 任务不存在404「task not found」
director 项目不存在404「not found」(文案分叉勿统一)
无分镜先退 10 再 400(台账+拒绝双写)「审片退回:无分镜(+10)」
8 权限与数据规则

authed + amw 属主面;零 SSE 零通知(全文件 grep Emit/InsertNotification 零命中——PRD ⑦,唯一不发通知的写路径);扣费 type=‘review’。

F11.04 智能审片·读(review 双入口 GET)

对应 PRD:§4 M11 · GET /api/tasks/:id/review、GET /api/director3d/:id/review | 状态:实现 | 实现落点:workbench_handlers.go:81-116、service_review.go:76-88 | UI:同 F11.03 读侧 | 场景挂钩:无

1 功能定义

审片报告读取:按 target 取最新报告(含逐镜 issues/维度分/总分)。

2 触发条件与前置状态

属主校验同写侧(双 404 文案分叉同 F11.03 §2);无报告返回 null 形态(非 404——照冻结 :198-203/:220-225)。

3 输入与校验

路径 :id(classic=task id / director=project id)。

4 处理流程

review_reports 按 target_id DESC 取首行 → report JSON 反序列化下发。

5 输出与结果状态

{report: {...}|null};issues 数组键形照 mockReview 产出(shot_no/level/message)。

6 状态流转

零写面。

7 边界与异常
条件系统行为提示/码
从未审过report=null(200)—
越权404 双文案分叉同 F11.03
8 权限与数据规则

authed + amw 属主面;报告 JSON 全文下发(无脱敏)。

F11.05 评估配置与上传(evaluations/config + upload)

对应 PRD:§4 M11 · GET /api/evaluations/config、POST /api/evaluations/upload(up10)| 状态:实现 | 实现落点:evaluation_handlers.go:17-53、service_eval.go:28-43/:47-90/:521-590 | UI:EvaluationView 配置区+上传 | 场景挂钩:无

1 功能定义

评估价目配置读面(quick/deep 双价)+ 剧本文件上传解析(txt/docx、GBK 回退)。

2 触发条件与前置状态

config 登录态;upload up10 档(原 studio cover 档复用)。

3 输入与校验

config 无参;upload multipart file——.txt/.docx 白名单;costOf settings 0 值回退默认(service_eval.go:38-42 err != nil || n == 0 → def,PRD ①;quick 默认 100/deep 300)。

4 处理流程
  • config:两价+引擎名——engine『规则(Mock)』字面(:48-51,与 F11.06 POST 面『规则』两字面不同源,PRD ②)。
  • upload:GBK 判定(ToValidUTF8→U+FFFD 计数>max(2, 0.2%)→GB18030 解码 :521-534,M9 同族)→ .docx 走 zip 解包+XML 五实体反转义(&/</>/"/&#N;,:537-590)→ 纯文本回传。
5 输出与结果状态

config {quick: n, deep: n, engine: str};upload {text, name, chars} 形态(rune 计数)。

6 状态流转

零写面(upload 不落库——解析产物仅回显,落库在 F11.06 create)。

7 边界与异常
条件系统行为提示/码
settings 价=0 或解析失败回默认 100/300(0 不生效 quirk,PRD ①)—
docx 损坏解包错误透传 500 族—
8 权限与数据规则

authed + amw;价键 eval_cost_quick/eval_cost_deep(管理台计费配置可调——标「可调」族)。

F11.06 评估项目与流水线(evaluations 三件+runEval)

对应 PRD:§4 M11 · POST/GET /api/evaluations、GET /api/evaluations/:id | 状态:实现 | 实现落点:evaluation_handlers.go:54-101、service_eval.go:93-153/:226-321 | UI:EvaluationView 列表+进度轮询 | 场景挂钩:无(SSE eval 三态帧:stage/done/failed)

1 功能定义

评估项目创建(TypeReserve 冻结扣费)→ 异步流水线(五 stage 推进+SSE)→ 终态结算。

2 触发条件与前置状态

create:script_text 必填;mode ∑ {quick, deep}——非法值静默归 quick 无 400(service_eval.go:97-100,PRD ③);余额不足 402。

3 输入与校验

{name, script_text, mode}——name 缺省「未命名评估」族;script_text 落库截断(与 upload 解析面衔接)。

4 处理流程

TryDeduct type='reserve'「剧本快速/深度评估冻结(-N,完成后结算)」taskID=id(:104-106 冻结 :252-253 逐字)→ INSERT eval_projects(status=‘running’)→ 异步 goRun(:226 起,注入点便于测试):五 stage 推进(解析/拆解/维度打分/汇总/出报告,SSE eval stage 帧逐发)→ Mock 确定性打分 (v*7919)%40(:398,冻结 :56 镜像)→ done:SetEvalDone(无台账动作——冻结即终态;TypeReserve 台账仅失败面全额退款消化)+SSE done;失败:全额退款「评估失败自动退回(+N)」+SSE failed+通知「评估失败:《name》…N 积分已退回」(evalFail :311-321,错误截 100)。

5 输出与结果状态

create {id};list=EvalListRow 定列七投影(model.go:173-181,Report json:"-" 不入列表);:id=全行+report(终态才有)。

6 状态流转

running→done/failed(SSE eval 帧+前端 3s 轮询双通道——E1 轮询机保留手管先例);finished_at UTC 形态(PRD ④)。

7 边界与异常
条件系统行为提示/码
mode 乱值归 quick(静默)—
流水线任一 stage 失败全额退款+SSE failed+通知「评估失败自动退回(+300)」
Mock sleep1100/1500/900ms 三段(:287-291——Mock 行为是契约)—
模板缺键<nil> 透传(PRD ⑭)—
8 权限与数据规则

authed + amw 属主面;TypeReserve 是全站唯一冻结-结算制(先冻结后按结果结算/失败全退——总则 §1 词条展开);evalLLM 通道已接线(PRD ⑤,二十一期⑦)。

F11.07 评估报告下载(evaluations/:id/report GET)

对应 PRD:§4 M11 · GET /api/evaluations/:id/report | 状态:实现 | 实现落点:evaluation_handlers.go:102-114、service_eval.go:156-222 | UI:EvaluationView「下载报告」| 场景挂钩:无

1 功能定义

评估报告 GAE 模板渲染下载(docx 兼容 HTML 容器)。

2 触发条件与前置状态

项目存在+属主;status 非 done 时 report 缺失→按冻结形态返回空/错误面。

3 输入与校验

路径 :id;无 body。

4 处理流程

report JSON → GAE 模板变量填充(七维表/总分/建议段)→ HTML 全文响应(前端 blob 下载——E1 保留 fetch+blob 先例)。

5 输出与结果状态

text/html 全文(非 JSON 信封——下载面直出);engine 字面「规则」(POST 面字面——PRD ② 双字面对照 F11.05)。

6 状态流转

零写面。

7 边界与异常
条件系统行为提示/码
未完成即取空报告形态—
越权404—
8 权限与数据规则

authed + amw 属主面;报告含全维度明文。

F11.08 爆款分析(viral-analysis 二件)

对应 PRD:§4 M11 · GET/POST /api/viral-analysis | 状态:实现 | 实现落点:evaluation_handlers.go:115-138、service_viral.go:16-67、repo.go:397 | UI:ViralAnalysisView | 场景挂钩:无

1 功能定义

爆款标题/文案四维建议生成(math/rand Mock):单次扣 5 积分,历史保留最近 20 条。

2 触发条件与前置状态

create:title 必填(空→400 族);余额不足 402。

3 输入与校验

{title};title 截 255(slice :56,PRD ⑧ 二十一期 B2 补登)。

4 处理流程

TryDeduct CostViral=5(billing.go:15)→ math/rand 四维 advice(score=60+Intn(35)、comment/emoji/duty 三键随机池,service_viral.go:44-50——math/rand 非确定性 Mock,PRD ⑧;与 eval 7919 确定性不同制)→ viral_analyses 落行(五列 INSERT)→ 响应。

5 输出与结果状态

create {id, advice:{score, comment, emoji, duty}};list=本人最近 LIMIT 20(repo.go:397),Result/Status json:"-"(model.go json:"-" 面)。

6 状态流转

零状态(同步完成落行)。

7 边界与异常
条件系统行为提示/码
title 超 255截断(不报错)—
历史超 20旧条滚出(LIMIT 查询面)—
8 权限与数据规则

authed + amw 属主面;扣费 type=‘viral’(TypeViral 独立常量——credit-records 单列归组)。


册尾端点覆盖对账(14/14)

对账 backend/cmd/server/routes.go:239-267 亲数 14 条 ↔ 本册 F11.01~F11.08(审片 4 条 :264-267 物理居 M11 段,:259-262 为 M13 spark 段——紧邻勿混):

#端点(routes.go:line)节#端点(routes.go:line)节
1POST /workbench/tasks(:247)F11.018GET /evaluations/:id/report(:255)F11.07
2GET /workbench/tasks(:248)F11.029GET /viral-analysis(:257)F11.08
3GET /evaluations/config(:250)F11.0510POST /viral-analysis(:258)F11.08
4POST /evaluations/upload(:251)F11.0511POST /tasks/:id/review(:264)F11.03
5GET /evaluations(:252)F11.0612GET /tasks/:id/review(:265)F11.04
6GET /evaluations/:id(:253)F11.0613POST /director3d/:id/review(:266)F11.03
7POST /evaluations(:254)F11.0614GET /director3d/:id/review(:267)F11.04

(:249/:256/:259-263 为注释/空行/M13 spark 段邻接行,非端点。)

差异纪律:PRD §4 M11 ①~⑭ 全引用不重立;本册零新立 DIF(goroutine recover/三注入点系测试基建形态非行为差异,节内注记);集成锚第十一链 EvaluationChain/第十二链 WorkbenchNotifyChain 在位(backend/integration_test.go)。