docs(arch-atlas): 完整性补图16张——新人据图通读全系统
9 opus 子代理新人视角审查→补 16 图(P0+P1+P2),目标=读图即懂整个系统: - 00: 端到端跨域全链泳道(8泳道15步+钱流并联,旗舰)+ 系统上下文外部依赖边界(C4 L1) - 01 B端客户旅程 / 02 逻辑→单体物理拓扑+契约跨域接缝+模块状态热力图 / 03 postMessage信封数据模型 - 04 核心对象生命周期状态机+两套身份 / 05 对话式创作闭环+生成任务UI闭环+feed交互 - 06 运营状态机合集+IP授权锁风来源+短信vs邀请码 / 07 端到端trace贯穿 5 新 SVG 经脚本核(良构/零溢出/脚注/转义)+ 11 Mermaid 配平;8 篇纯追加(既有图零改)。 子代理忠于源码/设计档纠偏:B端P-BIZ编号/feed第四互动=举报/BIZ五态按设计档真态/契约命名漂移诚实标。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1b3e375a68
commit
bb7c2baf7b
@ -1,13 +1,13 @@
|
||||
---
|
||||
date: 2026-06-22
|
||||
topic: 系统总览图说——绘境AI 架构图集的总图 + 目录(系统级 7 图 + 下钻各域)
|
||||
status: 现行为主(系统级 7 图)· 架构图集入口 · 通用图例与按角色路径在此
|
||||
topic: 系统总览图说——绘境AI 架构图集的总图 + 目录(系统级 9 图 + 下钻各域)
|
||||
status: 现行为主(系统级 9 图)· 架构图集入口 · 通用图例与按角色路径在此
|
||||
---
|
||||
|
||||
# 00 · 系统总览图说
|
||||
|
||||
> **这是什么**:绘境AI **架构图集**的**总图 + 目录**——整套图集按领域拆成 8 篇(本篇 00 系统总览 + 01–07 各域,每篇一个文档、各含该域全部图与讲解)。本篇是入口:先读下面七张**系统级跨域图**建立全局轮廓,再按目录下钻到某个领域那一篇。
|
||||
> **怎么读**:先看「系统级 7 图」(系统怎么分层、两条生成轨现行 vs 远期、数据怎么回流、钱怎么转、失败怎么兜、鉴权边界在哪),再按你的角色或任务选某领域下钻(见文末「按角色读」)。所有 SVG 仍在各子目录 `assets/` 下,各篇经相对路径引用、inline 渲染。
|
||||
> **这是什么**:绘境AI **架构图集**的**总图 + 目录**——整套图集按领域拆成 8 篇(本篇 00 系统总览 + 01–07 各域,每篇一个文档、各含该域全部图与讲解)。本篇是入口:先读下面九张**系统级跨域图**建立全局轮廓,再按目录下钻到某个领域那一篇。
|
||||
> **怎么读**:先看「系统级 9 图」(系统怎么分层、两条生成轨现行 vs 远期、数据怎么回流、钱怎么转、失败怎么兜、鉴权边界在哪、端到端全链怎么串、系统边界与外部依赖在哪),再按你的角色或任务选某领域下钻(见文末「按角色读」)。所有 SVG 仍在各子目录 `assets/` 下,各篇经相对路径引用、inline 渲染。
|
||||
|
||||
---
|
||||
|
||||
@ -26,7 +26,7 @@ status: 现行为主(系统级 7 图)· 架构图集入口 · 通用图例与按
|
||||
|
||||
## 0. 怎么读 + 全图通用图例
|
||||
|
||||
**这份主档的形态,是「先定向、再下钻」。** 它分功能段:第一篇是**系统定向图集**,用七张系统级大图把整个系统的轮廓自顶向下讲清楚;第二到第八篇是**七个领域的全部图说**,把各域的每一张图与每一段讲解都搬进来 inline。建议的读法是:**先把第一篇七张图连讲解读完**(建立全局轮廓),**再按你的角色或当前任务,选某一两个领域的篇章下钻**(文末给了按角色推荐的路径)。读完第一篇,你应该能回答「这是个什么系统、分几层、两条生成轨现行 vs 远期怎么切、数据怎么回流、钱怎么转」;读完某领域那一篇,你应该知道「这块的图在哪、它的命门是哪条缝」。
|
||||
**这份主档的形态,是「先定向、再下钻」。** 它分功能段:第一篇是**系统定向图集**,用九张系统级大图把整个系统的轮廓自顶向下讲清楚;第二到第八篇是**七个领域的全部图说**,把各域的每一张图与每一段讲解都搬进来 inline。建议的读法是:**先把第一篇九张图连讲解读完**(建立全局轮廓),**再按你的角色或当前任务,选某一两个领域的篇章下钻**(文末给了按角色推荐的路径)。读完第一篇,你应该能回答「这是个什么系统、分几层、两条生成轨现行 vs 远期怎么切、数据怎么回流、钱怎么转」;读完某领域那一篇,你应该知道「这块的图在哪、它的命门是哪条缝」。
|
||||
|
||||
**单源纪律(本图集的硬约束)。** 这份图集要消灭的就是「同一张图存两处、改一处漏一处」的漂移面。在原来的多文件形态下,本图集靠「系统级图内联、领域图只链接」来守这条纪律。**本主档是单一全量主档,定位就是把所有图说 inline 在一篇**——所以原各域图说里那种「单源引用、不复制 README 的图,只给链接」的声明,在本文里改成**直接内联该 README 对应节的 Mermaid 块**(让它真渲染),并在图下注明图源;原「单源不复制」的声明段相应删去。系统级图与领域图仍是**互补、不重复**:领域图回答「这一块内部长什么样」,系统级图回答「这些块如何跨域串成一个整体」;本文不会把同一张图在不同篇章各画一份。
|
||||
|
||||
@ -58,18 +58,18 @@ status: 现行为主(系统级 7 图)· 架构图集入口 · 通用图例与按
|
||||
|
||||
**状态码**(贯穿全图集):**现** = 现行已建 / 已实测 · **接** = 现行待接线(设计已出、代码未接) · **建** = 待建 · **缓** = 缓做(排在 W-G1 之后) · **F / future** = future-state(框架自带未部署 / 远期轨) · **废** = 决策史对照(被推翻的旧方案)。全文凡远期 / 待接 / 缓做 / 已废的元素一律虚线框 + 小标,绝不画成现行。
|
||||
|
||||
> **各域特有的状态分布**(各篇沿用本图例,这里把各域整体状态分布先汇总一句,各篇开头再展开):**第一篇系统级**=现 ×5、现 + F ×2;**产品**=九图整体「现」(定义层,两处元素级 future-state);**架构**=现 ×10 + 现+史 ×1 + 现+废 ×1;**产物执行沙箱**=现 ×7(机制全建成,四处现状债元素级标注);**后端**=现 ×8(若干设计缝与桩元素级标注);**前端**=现 ×8 + 建 ×1(tier2 承载);**运营**=11 图整体「现」(元素级 mock / 待建 / 待律所诚实区分);**运维**=现 ×6 + 接 ×2(观测) + 缓 ×1(k3s)。
|
||||
> **各域特有的状态分布**(各篇沿用本图例,这里把各域整体状态分布先汇总一句,各篇开头再展开):**第一篇系统级**=现 ×5、现 + F ×3、现 + 接 ×1(共 9 图);**产品**=九图整体「现」(定义层,两处元素级 future-state);**架构**=现 ×10 + 现+史 ×1 + 现+废 ×1;**产物执行沙箱**=现 ×7(机制全建成,四处现状债元素级标注);**后端**=现 ×8(若干设计缝与桩元素级标注);**前端**=现 ×8 + 建 ×1(tier2 承载);**运营**=11 图整体「现」(元素级 mock / 待建 / 待律所诚实区分);**运维**=现 ×6 + 接 ×2(观测) + 缓 ×1(k3s)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 第一篇 · 系统总览(7 张系统级图)
|
||||
## 第一篇 · 系统总览(9 张系统级图)
|
||||
|
||||
下面七张图是这份主档的核心。它们都是**跨域才画得出、没有任何单个领域拥有**的系统级图。按「先看全局形状、再看两条生成轨、再看数据与钱与可靠性与边界」的顺序读下来,就能自顶向下建立对整个系统的认知。
|
||||
下面九张图是这份主档的核心。它们都是**跨域才画得出、没有任何单个领域拥有**的系统级图。按「先看全局形状、再看两条生成轨、再看数据与钱与可靠性与边界、最后把全链串起来并钉清系统边界」的顺序读下来,就能自顶向下建立对整个系统的认知。
|
||||
|
||||
> 本篇内联的图 1–6 是顶层 `docs/architecture/assets/` 下的系统级 SVG(路径保持 `assets/xxx.svg`);图 7 是 Mermaid,直接内联。
|
||||
> 本篇内联的图 1–6 与图 8–9 是顶层 `docs/architecture/assets/` 下的系统级 SVG(路径保持 `assets/xxx.svg`);图 7 是 Mermaid,直接内联。
|
||||
|
||||
### 图 1 · 六域生命周期全景〔SVG·架·现〕
|
||||
|
||||
@ -155,7 +155,23 @@ flowchart TB
|
||||
|
||||
这张图最该让人看出的,是**两条跨角色的转化回路**:一条是玩家「发起同款」跳转工作坊变成创作者(P-FED-12)——它把「玩游戏的人」转化成「做游戏的人」,是网络效应护城河的产品载体;另一条是 B 端客户的询单经商务 / BD 流转成定制单据。还有一处系统级衔接:运营对内容的审核 / 降权处置会联动 feed 曝光(影响玩家看到什么),管理员对创作者的白名单置位(set-creator)决定一个 C 端用户能不能创作——这两条「B 端动作影响 C 端体验」的链路,正是图 6 那条「权限在后端强制」与图 4 那条「feed 重排」的人侧投影。这张图没有现行 / 远期的灰度,它是当前的角色与端的真相;每个角色的完整旅程(创作者旅程、玩家旅程)在产品篇,每个端的视图地图在前端篇。
|
||||
|
||||
> **第一篇状态分布**:现 ×5、现 + F ×2(图 2 含 future-state 中间件与「接」可观测、图 3 含远期 tier2 轨)。系统级图与领域图**互补不重复**:本 7 图都是跨域才画得出、无单域拥有的图。**远期/已废标注**:tier2 轨(图 3,= AgentScope+Phaser)= 远期·待 spike 虚线、远期可能与左轨收敛为一条;Nacos/RocketMQ(图 2)= future-state 未部署;观测(图 2)= 接;收益回流语料(图 4)= 远期·待建;打款 mock(图 5)= 现状桩;网关双校验(图 6)= 未来态;Dify/OpenGame/玩法填参模板/15KB = 已废;gameDefinition JSON 数据壳 = 中间脚手架·正迁移成直接生成 `src/` 源项目;均不画成现行终态。
|
||||
### 图 8 · 端到端跨域全链泳道〔SVG·流·现 + F〕
|
||||
|
||||

|
||||
|
||||
这张图是整本图集里**最该第一个读**的一张:它把前面那些分门别类的领域图,拼成了一条从「创作者敲下一句话」一直跑到「数据回流让 feed 重排」的完整系统链。它用八条横向泳道——创作者、game-studio、aigc + SAA、compliance、project + feed、玩家、telemetry、ad + trade——各占一条道,让你能顺着一个编号(①到⑮,外加钱流的 Ⓐ 到 Ⓓ)从头走到尾,看清每一步落在哪个域、交给谁、产出什么。主链是这样跑的:创作者一句话(①)经 studio 提交(②),aigc 建任务(③)进入 SAA 十六节点编排(④),九门验收通过后 emit 出包(⑤)回写成 project 草稿(⑥);创作者提交发布(⑦)触发 compliance 锁风门裁决(⑧),只有 pass 才让游戏 PUBLISHED 入 feed(⑨);玩家在竖屏游戏流里刷到(⑩)、即点即玩并互动(⑪);这些行为经埋点上报进 telemetry 聚合(⑬)、算出 0–100 的质量分(⑭),再把 feed 重新排序(⑮),把更好的游戏推回到玩家眼前——这条绿色的回流箭头,正是把一条线性的价值链弯成飞轮的地方。下半部还叠了一条与主链并联的钱流:玩家试玩时触发游戏内广告曝光(Ⓐ),经 ad 模块计费落账(Ⓑ),由 trade 按 `source_ref` 对账分账(Ⓒ),最终结进创作者钱包(Ⓓ)。
|
||||
|
||||
新人能从这张图看出几件单看任何一张领域图都看不全的事。其一,**判断「系统有没有缝」,就是看相邻泳道的交接处对不对得上**——出包能不能落成草稿、草稿能不能提审、裁决能不能控制入流、互动能不能回流成排序,任何一处接不上,闭环就断了;这张图把所有交接点都画在了一条线上,据图就能逐个核对。其二,**合规门是整条链的上线总闸**:图上那条红线写着「pass 才入流」,游戏造得再好,过不了锁风门也进不了 feed,这是平台不碰红线的硬约束。其三,**现状必须诚实地读**,不能因为画出来了就当全是实的:图里用橙色虚线小标点出了两处现状桩——feed 的游标分页现在恒返第一页、Redis 候选集还是增长期形态,广告侧的 `provider` 还是 mock、真广告 SDK 要等渠道落地才接;提现打款那一格更标了红线,缺渠道时必须 fail-fast、绝不发假钱。其四,右上角那个紫色虚线框是 **tier2 富游戏轨**——它走的是 AgentScope 自治加 Phaser 无头的另一套范式,目前只有设计、待 0 号 spike,**不在这条现行链上**;它换的只是「游戏内容怎么造出来」,造出来之后仍旧汇进同一条上线与发行的公共件。把这些边界一眼标清,正是为了让据图做评审的人,既能顺着主链确认闭环跑得通,又不会把桩和远期误当成已经建好的现行。
|
||||
|
||||
### 图 9 · 系统上下文与外部依赖边界〔SVG·架·现 + 接〕
|
||||
|
||||

|
||||
|
||||
这张图回答一个新人最先想问、却常常没有一张图能直接回答的问题:**绘境AI 这个系统,边界到底画到哪里、它对外又依赖谁**。它用 C4 模型最外层的「系统上下文」视角来画——正中间一个大框是绘境AI 平台本身(内网单体:game-studio 产品前端、game-admin 管理后台、game-cloud 后端十三模块,以及它自建的 MySQL / Redis),左边是站在系统边界之外、会来使用它的四类外部用户(创作者、玩家、运营 / 管理员、B 端 / IP 客户),右边则是平台要去调用、同样在边界之外的外部依赖系统。这张图刻意不画系统内部的模块怎么拆、调用怎么串(那些在架构图和泳道图里),它只回答「边界」这一件事,所以一眼就能让人建立「哪些东西是我们自己的、哪些是外面的」这个最基础的方位感。
|
||||
|
||||
这张图真正的价值,在于它给每一个外部依赖都标了**接入度三态**,而不是把它们一律画成「已经连上了」。现行真正已经联通在调用的(绿色实线框、标「已接」)只有两类:一是生成与素材这条供给线——new-api 网关后面的便宜大模型(DeepSeek / MiniMax)和 mmx-cli 的素材生成,它们是护城河运转的燃料,已经在 mini-infra 上接通;二是代码与存储的底座——Aliyun Gitea 代码仓和 MinIO 对象存储。而变现侧的几条线——广告联盟(穿山甲 CSJ / 优量汇 GDT)、微信 / 抖音小游戏渠道、支付商户、短信服务——全部是「待接」或「远期」,用橙色或紫色虚线框画出,绝不能误读成已经接好。新人看到这里应该立刻反应过来:**这恰恰是运营域那条「合规闸门是总闸」的判断,投影到依赖边界上的样子**——所有能把钱赚回来的外部线,都卡在 ICP 备案、广告资质、渠道备案锁、短信签名报备这些日历驱动的闸门后面,一秒也压不动,所以它们现在只能是桩或 mock。最后一层意思藏在边界的切法里:平台把那些「耗时但不构成差异化」的能力——后台框架、大模型、引擎、素材生成——统统用外部现成件顶上,系统边界内只留真正的护城河(生成编排、流量分发、收益闭环、数据飞轮);而且出网一律只走受控网关、上游 key 不裸暴露、游戏侧 CSP 直接禁网,这等于把「系统边界」同时当成一道「安全边界」来守。看懂这张图,你就同时知道了这个系统「大在哪、靠谁、又把哪几道门关在了外面」。
|
||||
|
||||
> **第一篇状态分布**:现 ×5、现 + F ×3、现 + 接 ×1(图 2 含 future-state 中间件与「接」可观测、图 3 含远期 tier2 轨、图 8 含桩与远期 tier2 轨、图 9 外部依赖三态)。系统级图与领域图**互补不重复**:本 9 图都是跨域才画得出、无单域拥有的图。**远期/已废标注**:tier2 轨(图 3 / 图 8,= AgentScope+Phaser)= 远期·待 spike 虚线、远期可能与左轨收敛为一条;Nacos/RocketMQ(图 2)= future-state 未部署;观测(图 2)= 接;收益回流语料(图 4)= 远期·待建;打款 mock(图 5 / 图 8 / 图 9)= 现状桩(缺渠道须 fail-fast);网关双校验(图 6)= 未来态;feed 游标分页 / 真广告 SDK(图 8)= 现状桩;广告联盟 / 微信抖音渠道 / 支付商户 / 短信(图 9 外部依赖)= 待接或远期(被 ICP / 资质 / 备案锁 / 短信报备等日历闸门阻塞)、阿里云 OSS 生产 = 远期(MinIO 内网已接);Dify/OpenGame/玩法填参模板/15KB = 已废;gameDefinition JSON 数据壳 = 中间脚手架·正迁移成直接生成 `src/` 源项目;均不画成现行终态。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -187,6 +187,40 @@ sequenceDiagram
|
||||
|
||||
整张图最该让人看清的是**底部那一栏的诚实切分**:护城河的四层(数据壁垒 / 网络效应 / 资产壁垒 / 合规壁垒)全部用紫色虚线框 + 「未来式」小标画出,因为它们是**要在窗口期(6-12 个月)里点燃的、而不是已经有的**——短期没有护城河,有的是上面那三样不公平起跑,融资就是点火的燃料钱。这层切分必须看清:如果把飞轮、网络效应、生态资产画成「已有的墙」,就违背了护城河话术的红线。要补充一处源档里的设计缝(图上未展开、读图时一并记住):对外话术与内部判断有一处**刻意的时间差**——护城河话术 B3 对外仍说「复杂引擎用 Cocos / 不自研引擎」,但内部已改判 tier2 富游戏自治轨走 AgentScope(Python 自治 ReAct)+ Phaser/Pixi 全无头引擎、Cocos 收窄到 3D / 复杂场景 / 渠道导出轴(仍是有效决策、非废弃);因为 tier2 还在 0 号 spike 待验,没验证的东西不对外背书,等 spike 过了再同步对外口径。这处「内外口径暂不一致」是有意为之、有据可查,不是漏洞。
|
||||
|
||||
### 产品图 10 · B端客户旅程〔Mer新·时·现〕
|
||||
|
||||
这张图补上前面缺的**第三条角色旅程**。图 7 画了创作者(做游戏的人)、图 8 画了玩家(玩游戏的人),但绘境其实有**三类核心角色**——还有一类是 **B 端 / 企业客户**(品牌方、文旅景区、教育机构),他们不是来自己做游戏、也不是来刷着玩,而是**带着一笔预算来下单定制**。这条线之所以重要,是因为它在商业定位里被排成「**三线变现的现金线 · 首位**」(商业定位 §4):B 端项目收费 + 分成、版号争议最小、回款最早,是 MVP 阶段最早能把真钱赚回来的一条线。所以这张旅程不只是补全角色,它画的正是「现在就能产生现金」的那条业务主线长什么样。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor B as B端客户(品牌/文旅/教育)
|
||||
participant BD as 运营即商务BD(平台侧)
|
||||
participant TPL as 分场景模板库 + demo(P-BIZ-02)
|
||||
participant FRM as 需求表单(P-BIZ-01)
|
||||
participant DSH as 定制进度看板(P-BIZ-03)
|
||||
participant ACC as 交付验收(P-BIZ-04)
|
||||
|
||||
B->>BD: 询单 / 留下线索(品牌营销 P-BIZ-08 · 文旅 P-BIZ-12 · 教育 P-BIZ-10)
|
||||
BD-->>B: 接洽 + 引导进场景模板库
|
||||
B->>TPL: 浏览分场景模板库、看可交互 demo
|
||||
Note over B,TPL: ⚠️ 现行=能浏览模板/看 demo 的最小可用面;「32 模板 / 15min 自动出案 / demo 自动生成」是愿景示意、不是产品承诺
|
||||
B->>FRM: 提交需求表单(行业/玩法/素材/交期/预算)
|
||||
FRM-->>BD: 表单进入商务工作流
|
||||
BD-->>B: 平台报价(当前=人工报价,非自动出案)
|
||||
alt 报价确认、立项
|
||||
B->>DSH: 通过定制进度看板跟进制作进度
|
||||
DSH-->>B: 进度状态推送(需求确认→制作→内测→交付)
|
||||
B->>ACC: 试玩 / 反馈 / 确认
|
||||
ACC-->>B: 签署交付验收 → 项目收费 + 分成回款
|
||||
end
|
||||
Note over B,ACC: 教育子场景另带 学生账号与防沉迷(P-BIZ-11);P-BIZ-05~07/09 等加厚服务为 P1 远期
|
||||
```
|
||||
|
||||
这张图把 B 端旅程画成「**询单 → 看模板与 demo → 提需求表单 → 平台报价 → 进度看板跟进 → 试玩验收签署**」六段,对应需求清单 BIZ 域的四条 P0 核心(P-BIZ-01 需求表单、P-BIZ-02 模板库与预览、P-BIZ-03 进度看板、P-BIZ-04 交付验收)。新人读这张图能看出三件事。其一,**这条线有两个端在协作**:左边是 B 端客户(下单方),右边那条 BD 泳道是「运营即商务BD」——也就是平台侧的商务/运营角色,他承接询单、引导进场景库、出报价、推进交付;这正好印证了图 4 里强调的「端属性」概念,B 端定制域的需求横跨「B端」与「运营」两个端,不是单端功能。其二,**子场景是分行业的**:同一套定制流程下挂着品牌营销(P-BIZ-08)、文旅景区(P-BIZ-12)、教育课程(P-BIZ-10,且教育还连着学生账号与防沉迷 P-BIZ-11)等不同垂直场景,它们共用「表单→报价→进度→验收」这条主干、只是行业内容不同。其三,它和图 7、图 8 的关系是**三条角色旅程并列又交汇**:创作者旅程和玩家旅程在「游戏进信息流」处交汇成消费闭环,而 B 端旅程是另起的一条 B2B 业务线,它不进 C 端信息流,产出的是「项目交付 + 现金回款 + 标杆案例」,反过来给整个平台供血(对应商业定位里「B 端现金线供血 → 滚成数据飞轮」的主轴)。
|
||||
|
||||
要点出的**设计缝**是这张图最该守的诚实纪律,也是它与图 9 一脉相承的地方——**愿景与现行建设度必须切开**。需求清单里 demo 那套高调呈现的「32 个分场景模板库 / 15 分钟自动出案 / 可交互 demo 自动生成」,经创始人 2026-06-22 历史回收判定明确为**愿景示意、不是产品承诺**:B 端当前真实建设度只有**轻量需求表单 + 人工报价**,离「32 模板 / 15min 自动出案」差距很大。所以图里在「看模板与 demo」和「平台报价」两处都用 Note 把现行最小可用面与那串愿景数字切开——P-BIZ-02/03/04 在产品口径上确实是 P0(B 端能选模板预览、看进度、完成验收签署这个最小面必须可用),但「32/15min 自动」那套数字不作为验收指标、不对 B 端客户承诺。读这张图时务必记住:它画的是「B 端定制这条业务线的产品形态与现金价值」,不是「自动出案能力已经做好了」;把愿景数字当成已交付,既会误导对内排期,也会在对 B 端客户做预期管理时埋雷。
|
||||
|
||||
> **产品域图清单与状态表**
|
||||
|
||||
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|
||||
@ -200,8 +234,9 @@ sequenceDiagram
|
||||
| 7 | 创作者旅程 | 时 | Mer新(内联) | 现 | 挑素材→一句话生成→预览迭代→发布→看收益;生成迭代闭环 + 外部渠道远期标注 |
|
||||
| 8 | 玩家旅程 | 时 | Mer新(内联) | 现 | 刷feed→即点即玩→点赞分享→发起同款;即点即玩差异化 + 同款回路接回创作者旅程 + 广告 SDK 待接 |
|
||||
| 9 | 商业定位与护城河一图 | 讲 | SVG新 | 现 | 一句话定位 + 差异化闭环 + 竞争格局 + 资本效率 + 四层护城河(虚线·未来式,诚实不假装有墙)|
|
||||
| 10 | B端客户旅程 | 时 | Mer新(内联) | 现 | 询单→看模板与demo→提需求表单→平台报价→进度看板→试玩验收签署;第三类核心角色(B端/企业客户)+ 现金线首位 + B端/运营双端协作 + 品牌营销/文旅/教育子场景;「32模板/15min自动出案」愿景≠承诺(诚实切分,现行=轻量表单+人工报价) |
|
||||
|
||||
> **状态分布**:九张图整体状态全为 **现**(产品定义层)。其中三处以**元素级虚线**标出 future-state、绝不画成现行 MVP 范围:图 2 / 图 5 的**第二条生成轨(tier2)与治理层**(待 0 号 spike·未落代码·尚无正式 P-id)、图 9 的**四层护城河**(要在窗口期点燃·未来式·非已有)。**产品定义 ≠ 建设进度**:本图说画的是「产品要提供什么」(55 P0 = 验收口径),不是「代码建到哪一步」。55 条 P0 各自的真实完成度(真端到端 / 半真 / 桩)以 `需求模块映射.md` 现状快照与 `docs/mvp/MVP进度总账.md` §2 矩阵为唯一 SoT。**防漂移门**:本文 frontmatter 记产品域五份源档的 commit hash(README @ 366a44b4、需求清单 @ 15b707fd、需求模块映射 @ 7ecd616e、商业定位 @ f4ee2310、护城河话术 @ 5cadf504),源档变更即比对。
|
||||
> **状态分布**:十张图整体状态全为 **现**(产品定义层)。其中三处以**元素级虚线**标出 future-state、绝不画成现行 MVP 范围:图 2 / 图 5 的**第二条生成轨(tier2)与治理层**(待 0 号 spike·未落代码·尚无正式 P-id)、图 9 的**四层护城河**(要在窗口期点燃·未来式·非已有)。**产品定义 ≠ 建设进度**:本图说画的是「产品要提供什么」(55 P0 = 验收口径),不是「代码建到哪一步」。55 条 P0 各自的真实完成度(真端到端 / 半真 / 桩)以 `需求模块映射.md` 现状快照与 `docs/mvp/MVP进度总账.md` §2 矩阵为唯一 SoT。**防漂移门**:本文 frontmatter 记产品域五份源档的 commit hash(README @ 366a44b4、需求清单 @ 15b707fd、需求模块映射 @ 7ecd616e、商业定位 @ f4ee2310、护城河话术 @ 5cadf504),源档变更即比对。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -324,6 +324,61 @@ flowchart TB
|
||||
|
||||
这张图最该让人看出的是「owner 模式怎么消灭灰色地带」:锁风门由 compliance 当 owner(因为它是全平台的内容安全与裁决中枢),但它**不自产**风格检测原子——原料来自 aigc 和 ip,裁决挂到 project,三方各司其职、没有谁越界。这正是图 5 模块依赖里那条 compliance ↔ ip ↔ aigc 环路的真实含义。要按状态读的设计缝有一处:**专区 Zone 在 MVP 阶段还没有独立的数据库实体,是用字段承载的**(有意简化),所以图里 Zone 实体那一格画的是「逻辑归属」、不是一张独立表——这是 project 模块已知的、有意为之的缺口,不是设计漏洞。锁风门则有一处真实的合规债(虽不在本概念图的范围内、但读图时该知道):compliance 的核心检测原子目前全是桩、恒返回 pass,意味着锁风门框架虽真、自动拦截能力还没硬化,这是放量/接广告/上渠道前必须补的。
|
||||
|
||||
### 架构图 13 · 13 逻辑模块 → 单体物理打包 / 运行拓扑〔SVG新·部署·现〕
|
||||
|
||||

|
||||
|
||||
这张图专门破除新人最常见的一个误解:**「13 个模块 = 13 个微服务」是错的**。前面图 4、图 5 给的是「逻辑视图」——13 个模块按领域边界各自独立、单向依赖;但它们物理上并不是 13 个进程。这张图把「逻辑独立」与「物理单体」并排画出来,中间用一条「jar 聚合」的漏斗把两者连起来,让人一眼看清三件事。第一,**逻辑视图**(左栏):每个模块是一个独立领域,且都拆成 `-api`(只声明 DTO + Feign 接口,跨模块只认它)和 `-server`(实现)两段式 jar,模块间只经对方的 `-api` 单向调用、零反向依赖。第二,**物理视图**(中栏):这 13 个 `-server` jar 连同 Huijing 基座 jar 全部编译进**同一个物理 JAR `game-server`**,由一个 main 启动、跑在**同一个 JVM 进程**里,共用同一份 `application.yaml` 和同一套 MySQL/Redis 连接池;模块间调用此时其实是进程内的方法调用、根本不走网络。第三,**Spring Profile 是这套单体的「开关板」**:哪些 `-server` 进 Spring 上下文由 profile 控制,其中 **pay 模块的启动器被显式注释排除**出装配——这正是图 4 散文里说的「pay 是 Huijing 原生模块、当前未接入单体启动器」在物理层面的样子。
|
||||
|
||||
这张图最该让人据图记住、也最容易被误读的两点:其一,**「逻辑独立」不等于「物理多进程」**——它们是同一个进程里逻辑上分得很清的几块,而不是各跑各的;正因为是单写、一份代码一份库,所以**不存在 split-brain**(那种「两套代码各跑各的、数据互不一致」的脑裂状态)。其二,右栏那条紫色虚线框是**远期愿景、不是现行架构**:模块间的单向依赖方向,就是未来从单体拆成微服务时的天然切割线——依赖边界即拆分边界,且因为每模块已是 `-api`/`-server` 两段、依赖单向无环、Nacos(注册发现)与 RocketMQ(异步解耦)框架又已自带,真到拆分那天几乎零返工。但务必看清:右栏画的四簇微服务只是「切割线长这样」的示意,**当前一个都没拆、也不预先实现**,现在仍然是中间那个单进程;拆几个、何时拆,要等流量和团队涨到单体压不住时再按当下情况定,不是越早拆越好。
|
||||
|
||||
### 架构图 14 · 契约族 × 跨域接缝:生产者 → 消费者流向〔Mer新·协议契约·现〕
|
||||
|
||||
图 11 已经把契约族「有哪几类、各落哪、各算第几」的静态清单画清了,但它没回答一个新人同样关心的问题:**每一类契约具体在 govern 哪一条跨域 handoff,谁产、谁消?** 这张图就补这个动态视角——把几条最关键的跨域交接拎出来,在每条交接线上标明「是被哪类契约钉死的」。读法是:方框是域/角色,**实线箭头是数据/产物的流向**,箭头上的 `[契约]` 标签就是这次交接所遵循的契约。沿着主链看:创作侧 **studio 产出草稿 →(GamePackage 契约)→ runtime 把它编译成可运行包 → 在 iframe 沙箱里预览 → 通过后发布**;生成链路里,**aigc / SAA 生成节点调模型时遵循 prompts 契约**(第 8 契约,Git Registry + 8 阶段);游戏跑起来后,**宿主 game-studio ↔ 游戏之间靠 SDK 契约的 postMessage 双向通信**(这是平台向游戏注入能力的唯一通道);**SDK 上报与前端埋点 →(events 契约)→ telemetry 摄取 → 喂给看板**;广告位则**由 ad-slot 契约 govern**,从 ad 模块经 SDK 的 `Plugin.Ad` 在游戏内呈现、再把曝光回流计费。
|
||||
|
||||
这张图最该让人看懂的,是**契约到底「钉」住了什么**:每一条跨域 handoff 都不是口头约定,而是被一份具体的 schema/接口契约锁死了双方的数据形状,所以 studio 不必知道 runtime 内部怎么编译、telemetry 不必知道事件从哪个前端来——大家只认中间那份契约。这正是「契约先行、并行解耦」能成立的根:契约就是跨端的数据边界。有两处状态要顺带读清:**Dify I/O 契约(图里标灰)是唯一已废的一类**(对应被推翻的蓝图原案,现行生成主线是 new-api,见图 2/3),它不再 govern 任何现行 handoff,画在这里只是为了让人知道「读到它别当现行接线面」;另外,GamePackage 契约链里有一条跨模块对齐的硬约束——**`package_url`/`checksum`/`bundle_size` 这些编译产物字段的权威写者是 runtime,aigc 只回填生成元数据、不写这些字段**,这条边界本图用小注标出,避免两个域抢写同一字段。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
STU["studio<br/>创作编排 · 产草稿"]
|
||||
RT["runtime<br/>编译 / 沙箱 / 发布"]
|
||||
PREV["iframe 沙箱预览"]
|
||||
PUB["发布上线"]
|
||||
AIGC["aigc / SAA 生成节点"]
|
||||
LLM["便宜 LLM<br/>(经 new-api)"]
|
||||
HOST["game-studio 宿主"]
|
||||
GAME["游戏(沙箱内)"]
|
||||
TEL["telemetry<br/>摄取 / 聚合"]
|
||||
DASH["数据看板"]
|
||||
AD["ad 模块<br/>植入 / 计费 / 归因"]
|
||||
SDKAD["游戏内广告位<br/>(SDK Plugin.Ad)"]
|
||||
|
||||
STU -->|"#4 GamePackage 契约<br/>(package_url 权威=runtime)"| RT
|
||||
RT --> PREV --> PUB
|
||||
AIGC -->|"#8 prompts 契约<br/>(registry + 8 阶段)"| LLM
|
||||
LLM -.->|"#6 Dify I/O 契约 = 废<br/>(现行走 new-api)"| AIGC
|
||||
HOST <-->|"#3 SDK 契约<br/>postMessage 双向"| GAME
|
||||
GAME -->|"#5 events 契约<br/>(SDK 上报)"| TEL
|
||||
HOST -->|"#5 events 契约<br/>(前端埋点)"| TEL
|
||||
TEL --> DASH
|
||||
AD -->|"#7 ad-slot 契约"| SDKAD
|
||||
SDKAD -->|"曝光回流(events)"| TEL
|
||||
|
||||
classDef act fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px;
|
||||
classDef dead fill:#fff7ed,stroke:#d97706,stroke-width:1.4px,stroke-dasharray:6 4;
|
||||
class STU,RT,PREV,PUB,AIGC,LLM,HOST,GAME,TEL,DASH,AD,SDKAD act;
|
||||
```
|
||||
|
||||
*(图源:架构/契约总览.md「契约全景」表 + 架构/README.md §2.1 跨模块对齐;契约编号取 contracts/README 主轴 #3–#8,Dify #6 已废)*
|
||||
|
||||
### 架构图 15 · 13 模块 真 / 桩 / 未建 状态热力图〔SVG新·架·现〕
|
||||
|
||||

|
||||
|
||||
这张图在图 4 那张「四簇 13 模块」的聚类底图上,叠加每个模块**当前真实建到了什么程度**:用颜色编码状态(绿 = ✅ 完成、真端到端可验收;黄 = 🟡 部分、有壳/半真/部分接线;灰虚线 = ◻ 特殊、seam 寄宿或未接单体;红 = 🔴 纯未建,当前为 0),并在每一块里都点明「它最大的那道缺口」——让人不必翻完整张状态表,就能一眼看出哪里能放心用、哪里是要还的债。当前分布是:**✅ 完成 5**(project / telemetry / ad / trade / community)、**🟡 部分 6**(aigc / runtime / feed / studio / compliance / biz)、**◻ 特殊 2**(ip seam 寄宿 / pay 未接单体)、🔴 纯未建 0。每块的最大缺口也直接标在图上,例如 compliance 的检测原子恒返回 pass、feed 的游标分页是桩、runtime 的真实编译引擎是桩、aigc 的 W-G1 worker 尚未接为默认产线。
|
||||
|
||||
读这张图必须守住一条口径铁律,图顶也专门画了一条:**本图的状态以 `docs/mvp/MVP进度总账.md` 为准,当结构 / 实现 / 状态三者冲突时,优先级是「状态 > 实现 > 结构」。** 这意味着颜色代表的是「实际状态」而非「结构权威」——图 4 给的是「应该怎么切」(结构),这张图给的是「现在建到哪」(状态),两者口径不同、不可混用。这张图最该让评审据图盯死的是两道债:其一,**compliance 的核心检测原子全是桩、恒返回 pass**,意味着发布链对违规内容目前零自动拦截、纯靠人工兜底,这是放量 / 接广告 / 上渠道前必须硬化的「合规死锁」;其二,**aigc 的 W-G1 worker 还没接为 staging 默认产线**,而 aigc 正是平台护城河的关键路径。还有一类「卡在闸门」的状态值得单独记:ad / trade / pay 卡的不是代码——它们的业务逻辑大多已是真的、有几十个单元测试——而是 ICP 备案 / 支付进件 / 广告审核这类**不可压缩的日历闸门**,策略是先把逻辑建好、闸门到位即接。最后提醒一句:这张图是某一次的状态快照,颜色和缺口会随开发推进而变,任何时刻都应以进度总账的真 / 桩 / 未建为最高口径,本图只承担「一眼可读的空间总览」这一职。
|
||||
|
||||
> **架构域图清单与状态表**
|
||||
|
||||
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|
||||
@ -340,8 +395,11 @@ flowchart TB
|
||||
| 10 | 工程治理(幂等/SLO/可观测) | 讲 | SVG新 | 现 | 幂等矩阵 + 三服务 SLO/Error Budget + 四路可观测(落地态=接)+ 三关键技术风险及应对 |
|
||||
| 11 | 8+2 类契约族总览 | 架 | SVG新 | 现 | 三落点 + 主编号轴;诚实标出 5 缝:DB 漂移/CI 门缺位/Dify#6 废/第9契约五套相撞/agent-loop+templates 漏登 |
|
||||
| 12 | 专区 Zone + 锁风门 Gate | 讲 | Mer新(内联) | 现 | 两横切概念 owner 与聚合:Gate=compliance 聚合 AGC19+IP04 挂 PRJ05;Zone=project owner;Zone 无独立实体(字段承载) |
|
||||
| 13 | 13 逻辑模块 → 单体物理打包/运行拓扑 | 架 | SVG新 | 现 | 逻辑独立(13 领域 + -api/-server 两段式)→ jar 聚合进单一 JAR game-server → 单进程;Spring Profile 控加载(pay 显式注释排除);无 split-brain;依赖方向=未来微服务切割线(远期·不做) |
|
||||
| 14 | 契约族 × 跨域接缝 生产者→消费者流向 | 协议契约 | Mer新(内联) | 现 | 补图 11 未答的「每类契约 govern 哪条 handoff」:GamePackage(studio→runtime 编译预览发布)/prompts(生成链)/SDK(宿主↔游戏 postMessage)/events(埋点→看板)/ad-slot(广告位);Dify#6 已废不 govern 现行 |
|
||||
| 15 | 13 模块 真/桩/未建 状态热力图 | 架 | SVG新 | 现 | 四簇底图叠 13模块.md §4 状态(✅5 project/telemetry/ad/trade/community · 🟡6 aigc/runtime/feed/studio/compliance/biz · ◻2 ip seam/pay 未接单体);每块标最大缺口;口径 状态>实现>结构、以 MVP进度总账.md 为准 |
|
||||
|
||||
> **状态分布**:现 ×10、现+史 ×1(图 2,决策史对照)、现+废 ×1(图 3,含废弃蓝图)。**注**:图 2/3 的「史/废」指其中**并列的决策史/废弃候选**部分(Dify/OpenGame/自研壳),现行选定部分仍是「现」;图 9/10/11 虽整体「现」,但各含一处必须按状态读的缝(候选集桩 / 可观测落地=接 / 5 处契约现实缝),已在散文与图内标清。**防漂移门**:本文 frontmatter 记架构域三份源档的 commit hash(README/契约总览 @ 38357c3d、13模块 @ 7ecd616e),源档变更即比对。
|
||||
> **状态分布**:现 ×13、现+史 ×1(图 2,决策史对照)、现+废 ×1(图 3,含废弃蓝图)。**注**:图 2/3 的「史/废」指其中**并列的决策史/废弃候选**部分(Dify/OpenGame/自研壳),现行选定部分仍是「现」;图 9/10/11/13/14/15 虽整体「现」,但各含一处必须按状态读的边界——候选集桩(图 9)/ 可观测落地=接(图 10)/ 5 处契约现实缝(图 11)/ 微服务切割线为远期不做(图 13,紫虚线)/ Dify#6 已废不 govern 现行 handoff(图 14,灰块)/ 状态以总账为准且仅为快照(图 15),均已在散文与图内标清。**防漂移门**:本文 frontmatter 记架构域三份源档的 commit hash(README/契约总览 @ 38357c3d、13模块 @ 7ecd616e),源档变更即比对。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -154,6 +154,70 @@ stateDiagram-v2
|
||||
|
||||
这张图没有现行/远期边界,它是现行 feed 容器生命周期的真实形态;唯一的过渡口径在「终态怎么来」——`watchGameEnd` 轮询 `host.state().phase` 到 `gameover` 才 latch 一个 `game_end` 代发,是因为 ref 游戏自己没有 emit 通道,等 W-G1 落地后改由各品类标准信号产出、轮询桩可下线(与图 2 同源)。
|
||||
|
||||
### 沙箱图 8 · postMessage 信封数据模型(契约#3 跨端 wire 契约)〔Mer新·数据模型·现〕
|
||||
|
||||
下面这张类图把「跨信任边界的每一条消息长什么样」从字段层面定死。前面图 2 / 图 3 讲的是消息**怎么流、怎么被校验**,这张图补的是另一个维度:消息**本身的数据结构**。它来自契约 `contracts/sdk-interface.d.ts`(第 #3 类契约 · SDK↔宿主 postMessage 协议),是宿主侧和游戏侧都必须逐字遵守的跨端 wire 契约——游戏侧组装消息、宿主侧 `validateEnvelope` 逐字段校验,两端对的就是这一份结构。把它单独画出来,是为了给安全审计一个「合法消息的字段全集」清单,也给游戏侧实现一个照着填的模板。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
direction TB
|
||||
class PostMessageEnvelope~T~ {
|
||||
+channel: 'wanxiang-game-sdk' 〔必·定值〕
|
||||
+type: PostMessageType 〔必·8枚举内〕
|
||||
+direction: MessageDirection 〔必·合法值〕
|
||||
+traceId: string 〔必·贯穿链路〕
|
||||
+payload: T 〔必·须存在〕
|
||||
+requestId?: string 〔选·配对用〕
|
||||
}
|
||||
class PostMessageType {
|
||||
«enum»
|
||||
init
|
||||
lifecycle
|
||||
telemetry
|
||||
error
|
||||
ad
|
||||
pay
|
||||
social
|
||||
storage
|
||||
}
|
||||
class MessageDirection {
|
||||
«enum»
|
||||
game_to_host
|
||||
host_to_game
|
||||
}
|
||||
class StorageSetPayload {
|
||||
+key string
|
||||
+value string_JSON
|
||||
}
|
||||
class StorageGetPayload {
|
||||
+key string
|
||||
}
|
||||
class StorageResultPayload {
|
||||
+key string
|
||||
+value object_or_null
|
||||
}
|
||||
class AdPayPayload {
|
||||
+req slotId_orderId_amount
|
||||
+resp rewarded_shown_paid
|
||||
}
|
||||
|
||||
PostMessageEnvelope~T~ *-- PostMessageType : type
|
||||
PostMessageEnvelope~T~ *-- MessageDirection : direction
|
||||
PostMessageEnvelope~T~ <|.. StorageSetPayload : payload(type=storage·写)
|
||||
PostMessageEnvelope~T~ <|.. StorageGetPayload : payload(type=storage·读请求·带requestId)
|
||||
PostMessageEnvelope~T~ <|.. StorageResultPayload : payload(type=storage·读回包)
|
||||
PostMessageEnvelope~T~ <|.. AdPayPayload : payload(type=ad/pay·带requestId)
|
||||
|
||||
note for PostMessageEnvelope~T~ "validateEnvelope 逐字段必过项(bridge.ts):\nchannel 严格等于 'wanxiang-game-sdk' · type 在 VALID_TYPES 内\ndirection 合法 · traceId 是字符串 · payload 存在(挡 undefined)\nrequestId 若带须是字符串。校验器不抛异常、只返判定(异常本身亦攻击面)。"
|
||||
note for PostMessageType "8 枚举各自方向/用途(契约注释):\ninit=host→game 初始化 · lifecycle=game→host 生命周期 · telemetry=game→host 遥测 · error=game→host 错误\nad/pay/social/storage=双向(广告/支付/分享/键值存储,iframe 外宿主侧办、按 requestId 回包)。\n⚠ 漂移:这是契约 canonical 命名(telemetry/social);运行时 bridge VALID_TYPES 实为 track/ready(见图 4)——\n命名维度契约与代码未对齐、属已知漂移,以两侧各自语义为准,别当已收口。"
|
||||
```
|
||||
|
||||
这张图分三块读。**主类 `PostMessageEnvelope<T>` 是信封本体**,六个字段里五个必填、一个可选:`channel` 是定值常量 `wanxiang-game-sdk`,宿主据它一眼滤掉非本协议的噪声或伪造消息;`type`(取 `PostMessageType` 8 枚举之一)、`direction`(取 `MessageDirection` 两值之一)、`traceId`(贯穿「生成→运行→上报」链路的字符串)、`payload`(泛型载荷、必须存在)都是必填;只有 `requestId` 是可选——它专给「请求-回包」要配对的消息(ad / pay / storage 读)用,写类的 track / lifecycle / error 是 fire-and-forget、不带它。图上每个字段都标了〔必/选〕和约束,新人对照右侧 `validateEnvelope` 那条注记,就能一眼看出「一条消息要全过哪几关才不被丢弃」。
|
||||
|
||||
**第二块是挂在信封 `payload` 下的几个 typed payload**,展示泛型 `<T>` 在实际消息里被具化成什么。storage 这一族最完整,正好演示请求-回包的三段形状:写存档用 `StorageSetPayload{key,value}`(value 是 JSON 字符串),读请求用 `StorageGetPayload{key}`(带 requestId),读回包用 `StorageResultPayload{key,value}`——这里有个契约级的关键细节,回包的 `value` 是**宿主侧已经解析好的对象**(`Record<string,unknown>|null`)、不是原始字符串,且契约语义明令数组按未命中处理(resolve null),这正是「runtime 侧零 JSON.parse、不引可抛路径」红线在数据结构上的落点。ad / pay 一族我用一个示意类 `AdPayPayload` 概括其请求字段(slotId / orderId / amount)与回包字段(rewarded / shown / paid),它们都靠 requestId 配对。
|
||||
|
||||
**第三块是必须诚实标出的一条设计缝**,画在 `PostMessageType` 的注记里:这张图严格按契约 `sdk-interface.d.ts` 画,所以 8 个枚举是契约的 canonical 命名(含 `telemetry` / `social`);但运行时桥 `bridge.ts` 的 `VALID_TYPES` 实际用的是 `track` / `ready` 这套命名(就是图 4 那张 8 type 表)。也就是说契约声明与代码实现在「type 命名」这一维度并未对齐——这是一条已知漂移,不是已收口,读图时以两侧各自语义为准、别把它当成铁板一块。除这条命名漂移外,信封的字段结构本身契约与代码是一致的、且已真跑通过,所以整图状态是「现」;它没有现行/远期边界,讲的是一个当前就成立的跨端数据契约。
|
||||
|
||||
> **产物执行沙箱图清单与状态表**
|
||||
|
||||
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|
||||
@ -165,8 +229,9 @@ stateDiagram-v2
|
||||
| 5 | 两条正交边界 | 架 | SVG新 | 现 | 沙箱边界(iframe 壳 vs 宿主,边界①)vs 受控面(游戏↔引擎,边界②)嵌套关系 + 破一条另一条仍兜 + IP/关联档/收敛三处别混 |
|
||||
| 6 | CSP / 同源红线 / 产物消毒 | 讲 | Mer新(内联) | 现 | connect-src 'none' + 'unsafe-eval' 纵深承接(漂移①以代码为准)+ allow-same-origin 同源红线过渡态(HJ-AUDIT-001)+ escapeBundle 消毒 + 收敛三件一起做 |
|
||||
| 7 | 三容器加载 / 失败 / 销毁态机 | 状 | Mer新(内联) | 现 | 当前播放 / 前一销毁 / 后一预加载 三态轮转 + dispose 防泄漏 + 加载失败降级 demo(不上抛)+ 加载超时分流 + game_end latch 过渡口径 |
|
||||
| 8 | postMessage 信封数据模型 | 数据模型 | Mer新(内联) | 现 | PostMessageEnvelope<T> 字段级结构(channel 定值 / type 8枚举 / direction / traceId / payload / requestId? 配对)+ validateEnvelope 逐字段必过项 + storage 三段 payload + ad/pay 配对 + 契约枚举 vs 运行时 VALID_TYPES 命名漂移诚实标注 |
|
||||
|
||||
> **状态分布**:现 ×7(机制全建成、真跑通过)。本域无「待接 / 待建 / 缓做 / future」整图——但**现行机制内有四处已知债**(CSP 文档口径漂移、sandbox 属性三处不一致、sandboxAttr 半孤儿、HJ-AUDIT-001 同源红线过渡态),在图 1 / 图 6 中用橙色虚线框 + 文字小标与「现行已建实心块」区分,绝不画成「已合规收口」。**防漂移门**:本文 frontmatter 记源档 `产物执行沙箱.md @ 38357c3d`(随 7fff6518 总图说提交锚定),源档变更即比对。**单源说明**:本域所有图均为新作(SVG新 / Mer新),无「引」类;源设计档 `产物执行沙箱.md` 自身在 §1/§2/§3 内嵌了三段 Mermaid(端到端时序、三重边界、桥双校验),本图说不复制它们——图 2 是把 §1 时序升保真为 SVG、图 3 的桥流程按「桥判定流」单独框选重画、图 1/4/5 则是源档没有的新视角(全景 / 类图 / 边界嵌套)。
|
||||
> **状态分布**:现 ×8(机制全建成、真跑通过)。本域无「待接 / 待建 / 缓做 / future」整图——但**现行机制内有四处已知债**(CSP 文档口径漂移、sandbox 属性三处不一致、sandboxAttr 半孤儿、HJ-AUDIT-001 同源红线过渡态),另有**一处契约 vs 代码命名漂移**(图 8:契约 type 枚举 telemetry/social 与运行时 VALID_TYPES 的 track/ready 未对齐),均在对应图(图 1 / 图 6 / 图 8)用橙色虚线框或注记与「现行已建实心块」区分,绝不画成「已合规收口」。**防漂移门**:本文 frontmatter 记源档 `产物执行沙箱.md @ 38357c3d`(随 7fff6518 总图说提交锚定),源档变更即比对;图 8 另锚契约 `contracts/sdk-interface.d.ts`(第 #3 类契约),契约字段变更即比对本图。**单源说明**:本域所有图均为新作(SVG新 / Mer新),无「引」类;源设计档 `产物执行沙箱.md` 自身在 §1/§2/§3 内嵌了三段 Mermaid(端到端时序、三重边界、桥双校验),本图说不复制它们——图 2 是把 §1 时序升保真为 SVG、图 3 的桥流程按「桥判定流」单独框选重画、图 1/4/5 则是源档没有的新视角(全景 / 类图 / 边界嵌套);图 8 是从契约 `sdk-interface.d.ts` 提取的信封字段级数据模型,与源档 §3 的桥流程(讲消息怎么流)正交互补(讲消息长什么样),不复制 §3 的流程图。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -204,6 +204,86 @@ flowchart TB
|
||||
|
||||
这张图最该让人看出的,是匿名读这一档**不是「无所谓」、而是有三条必须守的纪律**(图上用橙色虚线框单独标出,出自安全规则、P-OPN-08 已实证):只暴露公开字段、把 PII 裁剪掉;公开读靠手动 `eq` 谓词隔离,**不能假定框架的 DataPermission 会自动生效**(它只注册在 AdminUserDO 等业务表上);跨租户读要显式收敛。这三条是匿名读端点最容易踩的坑——以为放了 `@PermitAll` 就完事,结果把私有数据或 PII 漏出去。一个要记住的细节是**登录端点本身免登**:C 端的 send-sms-code / sms-login / invite-register 三个带 `@PermitAll`(不然没法登录),但 `me` 走登录态;sms-login 是「已注册即登录、未注册自动注册」一体,成功后发真 OAuth2 token。这张图没有现行/远期边界,就是当前每个端点准入的真相速查表。
|
||||
|
||||
### 后端图 9 · 核心对象生命周期状态机〔Mer新·状态机·现〕
|
||||
|
||||
这张图回答全平台**最核心的那个对象——一款游戏(`game_project`)——这辈子会经历哪些状态、是谁在推它走**。前面图 5 是数据的静态结构、图 6 是链路的动态调用,这张图是第三个视角:把 `game_project.status` 这条七态主链单独抽出来当状态机看。它之所以是「总闸」,是因为创作链、发布链、合规链都不直接互相调用,而是各自读写这一个 status 字段来协同——谁也绕不开它。新人记住这张图,就抓住了后端业务流转的主心骨。
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
direction LR
|
||||
[*] --> 草稿0: createDraft 建项目
|
||||
草稿0 --> 审核中1: submitPublish 提交发布(project 驱动)
|
||||
审核中1 --> 通过2: compliance 裁决 verdict=pass 回写
|
||||
审核中1 --> 拒绝3: compliance 裁决 verdict=block 回写
|
||||
通过2 --> 已发布4: 统一发布编排入 feed(status=4 出流)
|
||||
拒绝3 --> 草稿0: 改源重做后再提交
|
||||
已发布4 --> 下架5: 运营/创作者下架(offlineRank 出流)
|
||||
已发布4 --> 封禁6: compliance 处置(user_ban 落台账)
|
||||
下架5 --> 审核中1: 重新提交复审
|
||||
封禁6 --> [*]: 终态(申诉另走 compliance_appeal)
|
||||
通过2 --> [*]
|
||||
下架5 --> [*]
|
||||
|
||||
note right of 审核中1
|
||||
谁推 / 谁回写两分:
|
||||
project 只驱动状态机迁移(submit/offline);
|
||||
compliance 只给结论(pass/review/block),
|
||||
经 gate_result.verdict 回写 project.status,
|
||||
自己不持有这条主链。
|
||||
end note
|
||||
note left of 草稿0
|
||||
改源不改包:源(source_project.source_json)
|
||||
与产物(version.package_url)两面解耦。
|
||||
create=首次脚手架 / modify=确定性改源 /
|
||||
extend=经 base_version_id 记血缘扩展;
|
||||
任一操作都「重新 build 产新 version」、
|
||||
而非直接动旧 package。source_hash 幂等去重,
|
||||
构建失败留孤儿源(status=2)不污染产物面。
|
||||
end note
|
||||
```
|
||||
|
||||
这张图最该让人看清两件事。**其一是「谁推」与「谁回写」的两分**:status 这条主链的所有权属于 project,但驱动它前进的有两方——project 自己负责「提交发布(submitPublish)」「下架(offlineRank)」这类主动迁移,而「通过 / 拒绝 / 封禁」这三步的结论来自 compliance,compliance 不持有这条主链、只把 `gate_result.verdict` 回写进 `project.status`。这正是图 6「唯一真原子发布」和图 7「合规处置」在状态层面的落点:发布是 project 把 compliance 裁决、runtime 出包、feed 入流串成一个事务,任一步失败整体回滚、status 不留半截。**其二是状态机背后那条「改源不改包」范式**(图左侧 note):一款游戏不是一次性产物、而是长生命周期项目,`game_source_project` 存源、`game_version` 存产物,两个存储面解耦;create(首次脚手架)/ modify(确定性改源)/ extend(经 `base_version_id` 记血缘的扩展)三种操作改的都是源,然后**重新 build 出一个新 version**,而不是去动旧包——`source_hash` 做幂等去重,构建失败时留下孤儿源(`status=2`)而不污染产物面。这张图没有现行/远期的灰度,七态都是已落库、已 e2e 验证的现行真相;唯一要注意的边界是「封禁」后的申诉不在这条主链上、另走 `compliance_appeal` 台账(见图 5 合规块)。
|
||||
|
||||
### 后端图 10 · 两套身份 + 匿名→登录归因数据视图〔Mer新·数据模型·现〕(P2)
|
||||
|
||||
这张图回答一个读懂全平台数据归属的前提问题:**「谁拥有这条数据」到底怎么判定**。答案分两层:第一层是平台根本就有**两套互不相干的身份体系**——C 端的玩家兼创作者用 `game_player`、B 端的运营与管理员用 `system_users`,它们在数值空间和代码路径上都分开;第二层是 `game_*` 业务表全都**没有物理外键**,归属不靠 DB 约束、而靠 Service 可信边界在查询里强制带 `eq(userId)` 谓词。这两层一起,才是图 5「两套身份」框和图 7「C 端归属隔离」范式在数据视角的完整底座。
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
game_player {
|
||||
bigint id "= OAuth2 userId(MEMBER)· 不在13模块清单却被全模块引用"
|
||||
varchar mobile "uk_mobile 登录主键"
|
||||
tinyint creator_flag "0 玩家 / 1 创作者(A2 白名单)"
|
||||
varchar first_anon_id "匿名→登录归因衔接"
|
||||
}
|
||||
system_users {
|
||||
bigint id "= OAuth2 userId(ADMIN)· Huijing 原生"
|
||||
varchar username "B 端账号"
|
||||
}
|
||||
game_project {
|
||||
bigint id "gameId"
|
||||
bigint creator_user_id "软关联 game_player.id(无物理外键)"
|
||||
}
|
||||
game_telemetry_event {
|
||||
varchar event_id "uk_event_id 幂等真身"
|
||||
bigint player_user_id "可空·登录态归属"
|
||||
varchar anon_id "匿名态归属"
|
||||
}
|
||||
game_runtime_session {
|
||||
bigint id "试玩会话"
|
||||
bigint player_user_id "可空(V11 放宽)"
|
||||
varchar anon_id "V11 加·匿名也能试玩"
|
||||
}
|
||||
|
||||
game_player ||..o{ game_project : "creator_user_id eq 谓词(软关联·零外键)"
|
||||
game_player ||..o{ game_runtime_session : "player_user_id(登录后)"
|
||||
game_player ||..o{ game_telemetry_event : "player_user_id(登录后)"
|
||||
game_runtime_session }o..|| game_telemetry_event : "anon_id 串起匿名行为"
|
||||
system_users ||..o{ game_project : "B 端 RBAC 经 AdminUserApi(另一套人)"
|
||||
```
|
||||
|
||||
读这张图,新人最该看出三点。**一是两套身份的彻底分离**:`game_player` 物理上寄宿在 `huijing-module-system`、却不在 13 模块清单里——它是被全平台 `game_*` 表共同引用的归属起点,所有业务表里的 `creator_user_id` / `user_id` / `player_user_id` 数值上都等于 `game_player.id`(即 OAuth2 的 `userId`);而 B 端管理员是另一套人,走 Huijing 原生的 `system_users`,`ProjectServiceImpl` 引 `AdminUserApi` 就是这条线。两套人不共用一张表、不共享数值空间。**二是「零外键 + eq 谓词」这条归属强制机理**:图上 `game_player` 指向各业务表的连线全部用虚线(`..`)画,因为代码里一根物理外键都没有——归属隔离完全靠 Service/Mapper 在 WHERE 里钉 `eq(creatorUserId)`,这是图 7 C 端「黄金归属范式」在数据层的落点,也是为什么动跨模块查询时必须自己带归属谓词、不能指望 DB 帮你拦。**三是匿名→登录的归因衔接**:试玩会话(`game_runtime_session`)和遥测事件(`game_telemetry_event`)的 `player_user_id` 都是可空的(V11 放宽),匿名玩家靠 `anon_id` 占位先玩起来、产生行为数据,登录后再经 `game_player.first_anon_id` 把这段匿名轨迹归并到真实身份上——这条衔接是「先让人无门槛玩、再做转化归因」的数据基础。这张图没有现行/远期边界,是当前数据归属判定的真相底座;标注 (P2) 是因为它服务于 feed/试玩这条 P2 链路的归属语义。
|
||||
|
||||
> **后端域图清单与状态表**
|
||||
|
||||
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|
||||
@ -216,8 +296,10 @@ flowchart TB
|
||||
| 6 | 五条业务链路 | 时 | SVG新 | 现 | 创作/发布/试玩/广告收益/数据回路 跨模块调用;唯一真原子发布 + 唯一双向边 + source_ref 对账锚点;游标/联盟SDK/检测原子桩照实标 |
|
||||
| 7 | 鉴权 OAuth2/RBAC 双模型 | 类 | SVG新 | 现 | 两类用户两套权限并存:B 端 @PreAuthorize RBAC + C 端 Service 归属隔离 + 创作白名单 + 网关双重校验=未来态纠偏 + mock 后门红线 |
|
||||
| 8 | 匿名/登录准入矩阵 | 讲 | Mer新 | 现 | 四档准入(匿名/登录/RBAC/归属)速查 + 匿名读三纪律 + 登录端点本身免登 |
|
||||
| 9 | 核心对象生命周期状态机 | 状态机 | Mer新 | 现 | game_project.status 七态主链(草稿→审核→通过/拒绝→已发布→下架/封禁)+ 每迁移标谁推谁回写(project 驱动状态 / compliance 给结论)+ 改源不改包(create/modify/extend→重 build 产新 version 不动旧 package · source/version 两面解耦) |
|
||||
| 10 | 两套身份 + 匿名→登录归因数据视图 | 数据模型 | Mer新 | 现(P2) | game_player(C 端·不在13模块清单却被全模块引用)vs system_users(B 端)两套身份数值与代码路径分开 + game_* 全表零物理外键(归属靠 Service eq 谓词)+ anon_id 匿名→登录归因衔接 |
|
||||
|
||||
> **状态分布**:现 ×8(后端域全部现行已建,无接/缓/建/future)。但「现行已建的结构」里照实标出了若干**设计缝与桩**——contracts DB 镜像漂移(图 5)、compliance 检测原子恒 pass / feed 游标分页桩 / 真联盟 SDK 桩(图 6)、网关双重校验是未来态而非现状(图 7)——绝不因整体为「现」就把桩画成真。**防漂移门**:本文 frontmatter 记后端域四份源档的 commit hash(README/数据模型/鉴权与权限 @ 38357c3d、13模块 @ 7ecd616e),源档变更即比对。
|
||||
> **状态分布**:现 ×10(后端域全部现行已建,无接/缓/建/future)。但「现行已建的结构」里照实标出了若干**设计缝与桩**——contracts DB 镜像漂移(图 5)、compliance 检测原子恒 pass / feed 游标分页桩 / 真联盟 SDK 桩(图 6)、网关双重校验是未来态而非现状(图 7)——绝不因整体为「现」就把桩画成真。图 9 / 图 10 是补的两张新人视角图(对象生命周期状态机 + 身份归属数据底座),都是现行真相、无远期灰度。**防漂移门**:本文 frontmatter 记后端域四份源档的 commit hash(README/数据模型/鉴权与权限 @ 38357c3d、13模块 @ 7ecd616e),源档变更即比对。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -179,6 +179,143 @@ flowchart TB
|
||||
|
||||
这张图有一条最关键的边界要看清,它决定了前端域的工作量没有想象中大:**两条装载轨共用同一套执行沙箱**——不管哪条轨出来的 bundle,都暴露 `window.__GameBundle` 全局名、都调 `bootGameHost`、都跑在同一套 iframe + CSP + 桥里(图上用深色实心块把「执行沙箱」画成公共件,两轨都虚线指向它)。tier2 换的是「游戏内容怎么造出来」,换不掉「造出来之后怎么被关进笼子跑」。所以前端域要补的只是**运行时容器的双轨分发 + 创作入口**,装载与渲染的 how 在架构域、见 **`架构/生成引擎/引擎与运行时.md`**(其 §7.3 把「tier2 第二装载分支」列为待开项)与 `架构/生成引擎/tier2实现详设.md`。这张图的设计缝就是它的状态本身:**整套是待建**,详细前端设计要等 tier2 临近过 0 号 spike 再展开,现在只钉归属、不预先设计——绝不能因为图画出来了,就误以为第二条生成轨的前端已经建好。
|
||||
|
||||
### 前端图 10 · 对话式创作闭环全景〔Mer新·流·现+建〕
|
||||
|
||||
这张图回答「绘境AI 完整的产品形态到底长什么样」——前面图 1 到图 9 讲的是「界面靠什么撑起一致体验、生成的游戏怎么被玩起来」,而这张图把镜头拉到最上层,画出**创作者从一句话到一款不断打磨的游戏**的全过程。它的核心定调来自 README §7.3(创始人 2026-06-21 拍):绘境的产品形态**不是「一句话 + 选玩法模板 → 整包生成」一锤子买卖,而是一条对话式创作闭环**——多轮对话把游戏生成出来,之后还能对已经生成的游戏做**差量修改**(换套美术、改第 2 关的关卡参数),以及替换游戏里用到的素材。「一句话整包生成」只是**发起一次生成的若干启动点位之一**,不是终点。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph START["发起点(启动一次生成的若干入口)"]
|
||||
direction LR
|
||||
S1["一句话自然语言<br/>+ 可选玩法模板/参考图"]
|
||||
S2["feed「做同款」入口<br/>(P-FED-12 · 2026-06-22 升 P0)"]
|
||||
end
|
||||
|
||||
ANALYZE["意图解析<br/>系统理解创意 → 归一玩法/模板"]
|
||||
CONFIRM["目标确认卡<br/>把解析结果回给用户确认再生成"]
|
||||
GEN["generate 整包生成<br/>(SAA 全图 → 可玩产物 + 版本)"]
|
||||
PLAYABLE["已生成的游戏<br/>(进 feed 可玩 · 有版本)"]
|
||||
|
||||
subgraph ITER["对已生成游戏的差量迭代(只动一处、不毁全局)"]
|
||||
direction LR
|
||||
MOD["modify 差量修改<br/>换美术 / 改某关参数"]
|
||||
EXT["extend 扩展<br/>加第 2 关 / 加系统"]
|
||||
end
|
||||
|
||||
S1 --> ANALYZE
|
||||
S2 -.->|读原作血缘 → 作为生成上下文| ANALYZE
|
||||
ANALYZE --> CONFIRM --> GEN --> PLAYABLE
|
||||
PLAYABLE --> ITER
|
||||
ITER -.->|生成新版本 → 回到可玩| PLAYABLE
|
||||
|
||||
C01["前端 C01 对话框 + 六类素材当上下文"]:::todo
|
||||
C02["前端 C02 目标确认卡 UI"]:::todo
|
||||
C03["前端 C03 差量修改入口"]:::todo
|
||||
C04["前端 C04「改了哪·其余没动」差异展示"]:::todo
|
||||
C01 -.-> S1
|
||||
C02 -.-> CONFIRM
|
||||
C03 -.-> ITER
|
||||
C04 -.-> ITER
|
||||
|
||||
classDef todo fill:#faf5ff,stroke:#7c3aed,stroke-width:1.4px,stroke-dasharray:5 4;
|
||||
classDef now fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px;
|
||||
class S1,S2,ANALYZE,CONFIRM,GEN,PLAYABLE,MOD,EXT now;
|
||||
```
|
||||
|
||||
这张图最该让人看出的,是**「产品形态已经定调、但前端 UI 还要补」这条现行 / 待建的分界线**。图的主链路——发起点 → 意图解析 → 目标确认卡 → generate → 对已生成游戏 modify/extend——在**后端已经是现行真相**:`/studio/{create,modify,extend}` 三个端点都建好了(`AppStudioController` 的 `/modify`、`/extend` 实测在),SAA 的 modify 节点也在(它会按 `baseVersionId` 反查原作的源工程注入,做差量而非静默全量重生成)。所以这条创作链不是空想,后端跑得通。但**用户看得见的那层壳子还没做**:对话框、把六类素材传进去当生成上下文、系统解析意图后给用户的目标确认卡、差量修改的入口、以及「改了哪、其余没动」的差异展示——这五件事对应 README 里的前端 **C01–C04**,图上专门用紫色虚线把它们挂在主链路相应环节,一眼看清「哪几处是待补的前端」。这正是要分清的一条边界:对话式创作**不是被砍掉的范围(descope)**,而是产品形态已定、前端落点待补,别把它和图 4「勿误砍清单」里那些有意 MVP descope 的屏(首页门户、素材中心)混为一谈。
|
||||
|
||||
图上还有一处升级要看清:右侧的 **feed「做同款」入口**(P-FED-12)——玩家在信息流里看到一款喜欢的游戏,可以直接「做同款」发起一次属于自己的创作(它会读原作的血缘当生成上下文,见图 12 与数据飞轮域)。这条入口已由创始人 2026-06-22 拍板从 P1 **升为 P0**(它是数据飞轮网络效应的核心杠杆,Doc A 已改)。需要据图把握的口径是:产品形态定调讲的是**方向**,把对话式创作(P-CRT-05)、素材中心(P-MAT)定调为产品形态,不等于把它们的验收优先级一次性提到 P0——只有同款创作(P-FED-12)这一项真升了 P0,P-CRT-05 / P-MAT 的优先级调整仍另走评审,别据这张图擅自改动验收契约。
|
||||
|
||||
### 前端图 11 · 生成任务 UI 侧 失败/取消/重试/轮询闭环〔Mer新·状态机·现〕
|
||||
|
||||
这张图回答「创作者点了生成之后,前端这一侧怎么把一次生成的全过程(排队 → 跑 → 成 / 败 / 超时 / 取消)展示出来,失败了怎么读懂原因、怎么重试」。它是一张**前端视角**的状态机,刻意和后端的任务状态机区别开:后端的状态机讲「任务在服务端经历哪些状态」,这张图讲「`Task.vue` 这个生成进度页**在浏览器里**怎么轮询、怎么渲染每个状态、给用户哪些可操作的出口」。这是 studio 比 demo 多出来的一项真实能力——demo 那个「试玩」用 720ms 模拟一卡到底的 complete、**从不出现失败态**,而真实生成会排队、会超时、会因为各种原因失败,前端必须把这些都老实地接住、可读地呈现。
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
direction LR
|
||||
[*] --> 提交生成: 用户在 Create 发起 / 重试
|
||||
提交生成 --> 排队中: status 0 queued
|
||||
排队中 --> 运行中: status 1 running
|
||||
note right of 运行中
|
||||
UI 轮询 / SSE 监听 taskId
|
||||
进度色按 progress 粗分四阶段:
|
||||
理解创意 → 搭玩法 → 生素材 → 打包
|
||||
end note
|
||||
|
||||
运行中 --> 成功: status 2 succeeded
|
||||
运行中 --> 失败: status 3 failed
|
||||
运行中 --> 超时: status 4 timed_out
|
||||
运行中 --> 已取消: status 5 canceled(用户点取消)
|
||||
排队中 --> 已取消: 排队期也可取消
|
||||
|
||||
成功 --> [*]: 回填 versionId → 进预览试玩
|
||||
失败 --> 提交生成: 点「重新生成」(retryOf 指原任务)
|
||||
超时 --> 提交生成: 点「重新生成」
|
||||
已取消 --> 提交生成: 「返回创作」再发起
|
||||
|
||||
note right of 失败
|
||||
展开七种失败原因可读中文映射(对齐契约 aigc.yaml FailureReason):
|
||||
unsafe_prompt 描述含不适宜内容请换说法
|
||||
intent_unclear 没太理解意图请写具体
|
||||
no_template_match 没匹配到玩法模板
|
||||
config_invalid 玩法配置校验未过
|
||||
llm_error AI 服务开小差
|
||||
timeout 生成超时了
|
||||
asset_gen_failed 素材生成失败
|
||||
end note
|
||||
```
|
||||
|
||||
这张图最该让人看出的,是**「失败」在前端不是一个死胡同,而是一个能被读懂、能被重来的可恢复态**。它的护城河价值就在这里:后端契约 `aigc.yaml` 定了七种失败原因枚举(`unsafe_prompt` / `intent_unclear` / `no_template_match` / `config_invalid` / `llm_error` / `timeout` / `asset_gen_failed`),前端在 `Task.vue` 里把每一种都映射成一句**人话提示**(比如 `unsafe_prompt` → 「描述包含不适宜内容,请换个说法」、`intent_unclear` → 「没太理解你的意图,试试把描述写得更具体」),让创作者知道「为什么没成、下一步该怎么改」,而不是只看到一个冷冰冰的「失败」。图上把这七条原因映射直接挂在「失败」态的展开注里,因为这正是这张图区别于后端状态机的关键信息——后端只回一个枚举值,把枚举翻译成可读文案、决定展示哪个出口,是前端这一侧的活。
|
||||
|
||||
这张图还要让人看出**两个状态边界**。其一,**可取消**:不只「运行中」能点取消,「排队中」也能取消(图上两条都画了到「已取消」的边),取消后落「已取消」态、给一个「返回创作」的出口。其二,**可重试且可追溯**:失败、超时都能点「重新生成」,重试时会带上 `retryOf` 指向原任务(图上在重试边上标了),这样一次创作的多轮重试在数据上是串得起来的,不是各自孤立的新任务。需要据图把握的一处实现现状:进度的四阶段(理解创意 → 搭玩法 → 生素材 → 打包)是前端按 `progress` 百分比**粗分**出来的展示阶段(`< 30` / `< 60` / `< 90` / `>= 90`),它是给用户的进度叙事、不是后端下发的精确步骤,看图时别把它误当成后端的真实流水节点。
|
||||
|
||||
### 前端图 12 · feed 玩家消费交互模型〔Mer新·流·现〕
|
||||
|
||||
这张图回答「玩家打开游戏信息流之后,在播放器里是怎么消费、怎么互动的」——它是图 7 视图地图里「玩家消费」那条主回路的运行期放大,聚焦**玩家侧**(区别于图 8 讲的「一款游戏怎么在沙箱里跑起来」的宿主侧装载机制)。绘境的 feed 是一条**类短视频的竖屏即刷即玩流**:整屏吸附、上滑切下一款,右侧一条互动条,刷得越深越往后拉新的一批。它和短视频最大的不同是——每一屏不是一段视频,而是一款**真在跑的游戏**,所以「切换」既要丝滑、又要让下一款游戏提前就绪。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
ENTER["玩家进入 Feed<br/>(匿名 anonId 可达 · 无需登录)"]:::now
|
||||
|
||||
subgraph SWIPE["整屏吸附上滑切换(scroll-snap y mandatory)"]
|
||||
direction LR
|
||||
PREV["上一屏<br/>(已销毁/可回滑)"]:::dim
|
||||
CUR["当前屏<br/>一款真在跑的游戏"]:::now
|
||||
NEXT["下一屏 N+1<br/>三容器预取就绪"]:::now
|
||||
end
|
||||
|
||||
subgraph BAR["右侧互动条 · 四动作(贴 feed.yaml action 枚举)"]
|
||||
direction LR
|
||||
A1["赞 action=1"]:::now
|
||||
A2["藏 action=2"]:::now
|
||||
A3["分享 action=3<br/>→ 跳 /share 落地页"]:::now
|
||||
A4["举报 action=4<br/>→ 弹原因"]:::now
|
||||
end
|
||||
|
||||
PREFETCH["manifest 首帧 + 容器预取<br/>(随 feed 清单先行下发 · 先画主题底色/标题)"]:::now
|
||||
IMPRESS["曝光埋点 game_impression<br/>(去重 · 滚到底续拉下一批)"]:::now
|
||||
LOGINGATE["触发互动才弹登录<br/>(isRealLogin 前置 · 跳 /login 带回跳)"]:::gate
|
||||
|
||||
ENTER --> SWIPE
|
||||
CUR --> BAR
|
||||
CUR -.->|切换前预热| PREFETCH
|
||||
PREFETCH -.-> NEXT
|
||||
CUR -->|整屏进入| IMPRESS
|
||||
IMPRESS -.->|滚到底| ENTER
|
||||
A1 -.->|未真实登录| LOGINGATE
|
||||
A2 -.->|未真实登录| LOGINGATE
|
||||
A4 -.->|未真实登录| LOGINGATE
|
||||
A3 -->|分享落地页公开| OUT["/share 落地页<br/>(OG 元数据 · utm 归因)"]:::now
|
||||
|
||||
classDef now fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px;
|
||||
classDef dim fill:#f1f5f9,stroke:#94a3b8,stroke-width:1.2px,stroke-dasharray:4 3;
|
||||
classDef gate fill:#fee2e2,stroke:#dc2626,stroke-width:1.5px;
|
||||
```
|
||||
|
||||
这张图最该让人看出的,是 feed 玩家侧的两条体验支柱:**「切得快」和「玩得到」**。「切得快」靠的是**三容器调度 + scroll-snap 整屏吸附**:`Feed.vue` 用原生 `scroll-snap-type: y mandatory` 做整屏吸附,上滑就切到下一款;同时维护「上一屏 / 当前屏 / 下一屏」三个容器,在切换前就把 N+1 那款游戏预取就绪(图上把当前屏、下一屏画成已就绪的实心绿块,上一屏画成可回滑的灰态)。「玩得到」靠的是 **manifest 随 feed 清单先行下发**——前端拿到 manifest 后能在切换前先用它把游戏的主题底色、标题画出来(300ms 量级),消除「点了卡在等字节」的空白感,而不是干等游戏字节到齐才出画面。这两条共同兑现了体验 SLO(信息流首屏 P75 < 3 秒、点卡到可玩常态 ≤ 2 秒),而 feed 正是这套 SLO 的前端兑现处。
|
||||
|
||||
这张图还要让人看出**互动条的真实形状和准入边界**。右侧互动条是**四个动作**,严格贴后端 `feed.yaml` 的 `action` 枚举:**赞(1)/ 藏(2)/ 分享(3)/ 举报(4)**——这里要据代码纠一处口径:互动条的第四个动作是**举报**(`action=4`),不是评论;评论(P-SOC-01)当前在 Doc A 标 P1、且 feed 互动按钮真接 community / social 仍是「排期真接」的待办(部分按钮现仍是 mock),所以图上据 `InteractBar.vue` 现状画四动作=赞/藏/分享/举报,不臆造一个评论按钮。准入边界是这张图的安全主轴:**Feed 匿名可达**(`anonId` 衔接未登录态,玩家无需登录即可即刷即玩,图上用绿块画「进入」),但**互动是登录态动作**——点赞 / 收藏 / 举报这些动作在入口最前置 `isRealLogin()` 判定,未真实登录就**弹引导登录**(确认跳 `/login` 带回跳,取消则留在当前流继续刷),图上用红色门块把这条「触发互动才弹登录」单独标出。唯独**分享**例外:它跳的 `/share` 落地页是公开页(带 OG 元数据供社交平台抓取、带 utm 渠道归因),不挡登录门。需要据图把握的两处:**曝光埋点 `game_impression` 做了去重**(来回滑同一张不重复计数,是运营质量分的回灌信号源之一)、**滚到底触发续拉下一批**(图上画了 impression → 回到 Feed 的续拉环);这套消费 / 互动 / 埋点都是现行已建,整图状态为「现」。
|
||||
|
||||
> **前端域图清单与状态表**
|
||||
|
||||
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|
||||
@ -192,8 +329,11 @@ flowchart TB
|
||||
| 7 | studio 视图地图 | 架 | SVG新 | 现 | 20 路由视图按五业务域布局(玩家消费/创作/平台成长/studio 专区/B 端)+ 4 tab 导航 + 匿名可达/必须登录准入边界 + 20vs19 计数口径 |
|
||||
| 8 | 真实试玩宿主 | 时 | Mer新(内联) | 现 | 取包→sha256 校验→srcdoc 注入→iframe sandbox→桥双校验→postMessage 回流;game_end 宿主轮询 latch 代发;同源过渡态 + 三债交叉引沙箱 §8 |
|
||||
| 9 | tier2 富游戏前端承载 | 架 | Mer新(内联) | **建** | feed 双轨装载分发 + studio 第二轨创作入口(归前端域·待建);两轨共用同一套沙箱(公共件);钉归属不预先设计,等 0 号 spike |
|
||||
| 10 | 对话式创作闭环全景 | 架 | Mer新(内联) | 现+建 | 一句话/选模板 → 意图解析 → 目标确认卡 → generate → 对已生成游戏 modify/extend + feed「做同款」(P-FED-12 升 P0);后端 /studio/{create,modify,extend} 与 SAA modify 节点现行,前端 C01–C04 待补(虚线) |
|
||||
| 11 | 失败/取消/重试/轮询闭环 | 状态机 | Mer新(内联) | 现 | UI 视角任务状态机:提交→排队→运行(进度色四阶段)→成/失/超时/取消;失败展开七种 FailureReason 可读映射;排队/运行皆可取消;重试带 retryOf 可追溯(区别于后端状态机) |
|
||||
| 12 | feed 玩家消费交互模型 | 流 | Mer新(内联) | 现 | 整屏吸附上滑切换(scroll-snap·三容器预取)+ 互动条四动作(赞/藏/分享/举报·贴 feed.yaml,非评论)+ manifest 首帧预热 + 曝光去重续拉;Feed 匿名可达、触发互动才弹登录,分享落地页公开 |
|
||||
|
||||
> **状态分布**:现 ×8(图 1–8,设计体系已全量收口合入 `dev/2.0.0`)、建 ×1(图 9,tier2 富游戏前端承载归属已定但代码未建·整图虚线)。**防漂移门**:本文 frontmatter 记前端域三份源档的 commit hash(前端/README @ 15b707fd、产物执行沙箱 @ 38357c3d、引擎与运行时 @ 7ecd616e),源档变更即比对。
|
||||
> **状态分布**:现 ×10(图 1–8、11、12,设计体系与生成任务 UI / feed 消费均已建并合入 `dev/2.0.0`)、现+建 ×1(图 10,对话式创作产品形态已定调、后端主链路现行,前端 C01–C04 待补)、建 ×1(图 9,tier2 富游戏前端承载归属已定但代码未建·整图虚线)。**防漂移门**:本文 frontmatter 记前端域三份源档的 commit hash(前端/README @ 15b707fd、产物执行沙箱 @ 38357c3d、引擎与运行时 @ 7ecd616e),源档变更即比对。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -167,6 +167,79 @@ flowchart TB
|
||||
|
||||
读这张图最该守的是它把**现状与待补严格分层**的诚实。现行已建(实心绿块)只有锁风门聚合那条框架:ComplianceGateApi.evaluate 按 block > review > pass 取最严裁决、落 game_compliance_gate_result 台账、在发布前检查被真注入——但**聚合进来的原子目前都是桩、恒返回 pass**,意味着今天的发布链对违规内容零自动拦截、纯靠人工兜底。其余全是本设计要补的待建(虚线框):双层机审的两层、人审队列底座、feed 自动降权接缝、创作者信用。处置联动这一栏要看清四类处置各自的现状落差——**下架**走 feed 现有的跨模块接缝 FeedApi.offlineRank(现成可用、封禁联动下架已在走它),**降权**则因为 setExposureLimit 现在只是管理端 HTTP 端点、不在跨模块 FeedApi 上,要 contract-first 新建 feed 降权 -api(创始人 2026-06-22 定放第一期、单独做);**封禁**台账已建,但封账号联动断着(不置 player.status=DISABLE、不连带下架全部内容,validateCreator 也不查 ban 表,所以今天封号拦不住本人继续创作,是本设计要补的两条断链);**创作者信用**现在一点没有、第一期建简单扣分台账(只记不连带、保守形态、防误伤)。图上还钉了两条贯穿铁律:**审核降级朝保守**(阿里云超时 / 报错降级到 review、绝不降级到 pass,与打款 fail-fast 同理),以及**审核状态唯一权威在 compliance**(project 只接回写、不双写,避免脑裂)。这张图的设计缝几乎布满全图——它如实画出了「框架在、判定空、处置半通」的真实现状,而非假装审核台已经建好。
|
||||
|
||||
### 运营图 12 · 运营对象状态机合集〔SVG·状态机·现〕
|
||||
|
||||

|
||||
|
||||
这张图回答「运营域里到底有几台状态机、各自怎么转、谁已经真跑」。前面几张图里,状态机被压成钱流图或瀑布图里的一行散文标签——提现五态在图 10 里只是钱流终点的一个小框,B 端五态、订阅续期同样被一笔带过。这张图把运营域四个核心对象的状态机抽出来并排画在一处:提现、B 端询单、审核工单、订阅续期各占一格,让人一眼看清每台机的触发条件、各自的终态,以及哪些动作是幂等的。读它的正确方式不是逐格细看字段,而是先对比四台机的「成熟度差异」——它们恰好分布在「已建真跑」「整段不碰钱」「第一期待建」「半建半阻塞」四种状态上,正是运营域「整图是现、元素级布满设计缝」这条命门纪律的最集中体现。
|
||||
|
||||
四台机各有一处最该记住的设计点。**提现五态**(左上,trade,实线整片已真跑)最硬的纪律是「发起 ≠ 终态」:审核事务内只把单子从「待审 0」CAS 到「打款中 1」,绝不在审核里直接置「已打款」;真正的终态由打款回调驱动,成功走 1→2、失败走 1→4 退回冻结。它的终点是 mock 桩(图上右侧虚线红框标清)——只有 MockPayoutClient,真实微信/支付宝渠道被合规日历闸门阻塞,且这条线的降级口径是「绝不静默降级 mock」,因为打款降级 mock 就是吞真钱、必须 fail-fast,这一点和广告线「缺渠道降级 mock 可接受」正好相反。**B 端询单五态**(右上,biz,整条画成虚线红框)是四台机里唯一「完全不碰钱」的——待跟进→已报价→制作中→待验收→已交付单线推进,它的「终态」是交付而不是收款,在线签章/收款/分账整段留在 M4,现在唯一能标的只有 signed_offline 线下签兜底;把它整条画成虚线红框,正是要提醒读者:B 端虽是近期现金线,但工程钱流尚未建,真正的资金动作在提现线、不在这里。
|
||||
|
||||
下面两台机讲的是「待建」与「半建」。**审核工单**(左下,compliance,整台虚线)是第一期才建的——今天 compliance 只有「申诉」一种人工单,没有带认领/分派/SLA 的内容审核队列底座;它的状态机里「超时告警」是旁路态(介入后回到审核中)、不是终态,只有「已通过/已拒绝」是真终态,而人工 approve/reject 是最高权威、覆盖机审结论。把它整台画成虚线是诚实的:今天的发布链对违规内容零自动拦截、纯靠人工兜底。**订阅续期**(右下,trade,入账实线已真跑、收单虚线红框未接)有一处和其他三台都不同的终态语义——它没有「彻底结束」的吸收态,「过期」可以被下一次续期重新拉回「生效中」,是可逆回落,所以图上画成双向箭头;它被卡住的只是「自助购买收单」这一半(需接真实支付),admin 手动赋订阅那一半早已真跑、入创作者钱包恒等式。这张图的设计缝因此可以一句话收束:四台机里没有一台是凭空设想的,但它们各自被卡在不同的位置——读图时分清「实线方框=已真跑」与「虚线框+小标=被资质/波次阻塞」,就不会把待建的审核工单或被阻塞的打款 mock、订阅收单误当成已经建好。
|
||||
|
||||
### 运营图 13 · IP 库 · 素材授权与锁风档位来源 概念模型〔Mer新·概念·现〕
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph IPLIB["IP 库(ip 模块 · 现以 seam 寄宿 compliance · 授权链待建)"]
|
||||
direction TB
|
||||
OWNER["IP 所有者 / 授权方<br/>(迪士尼 / 王蓝莓 / 品牌方)"] -->|签授权| GRANT["IP 授权档<br/>授权范围 + 敏感度 + 合同约束"]
|
||||
GRANT --> IPENT["注册 IP 实体<br/>(终态:lockStrength 作为授权属性挂在这)"]
|
||||
end
|
||||
subgraph SRC["档位源(现阶段=过渡表 · 终态=IP 实体属性)"]
|
||||
POLICY["lock_strength_policy 过渡表<br/>按 ipId / 题材关键词映射档位 · admin 可配"]
|
||||
BLACK["题材黑名单兜底规则<br/>(棋牌 / 捕鱼即便纯 UGC 也强拉人工复核)"]
|
||||
end
|
||||
IPENT -. 终态收敛(IP 授权模型成熟后) .-> POLICY
|
||||
CONTENT["待审内容<br/>生成时声明 ipId(无则纯 UGC)"] --> SEL["锁风三档选档器"]
|
||||
POLICY -->|查 lockStrength| SEL
|
||||
BLACK -->|叠一层兜底拉档| SEL
|
||||
SEL -->|无 IP / 低敏| STD["标准档<br/>机审瀑布正常跑"]
|
||||
SEL -->|IP 中高敏| STRICT["严格档<br/>降低放行阈值 · review 一律转人审"]
|
||||
SEL -->|IP 最高敏 / 命中黑名单| MANUAL["人工复核档<br/>跳过机审放行 · 直接进人审队列"]
|
||||
STD --> GATE["锁风门聚合<br/>block>review>pass 取最严 · 落 game_compliance_gate_result"]
|
||||
STRICT --> GATE
|
||||
MANUAL --> GATE
|
||||
```
|
||||
|
||||
*(图源:审核台运营.md §3.3「锁风三档与 IP 库怎么绑」;选档器下游的机审瀑布见图 11)*
|
||||
|
||||
这张图回答的是图 11 没答完的一个问题:锁风门有标准/严格/人工复核三档,**但「这条内容该走哪一档」是谁、按什么决定的**?图 11 只画了锁风门聚合的 owner 与三层瀑布,把「选档」当成一个黑盒输入;这张图把那个黑盒拆开,讲清档位的来源链——它不该让运营对每条内容手动选,而该由内容的 **IP 归属**自动推导出来。读这张图,新人能看出一条从上到下的推导链:IP 所有者签下授权时,授权档里就带了这个 IP 的敏感度与合同约束;每个注册 IP 据此带一个 `lockStrength`(标准/严格/人工复核);一条内容生成时声明了用哪个 IP,选档器就拿这个 IP 去查它的档位;没声明 IP 的纯 UGC 默认走标准档,内容类型再叠一层题材黑名单兜底(棋牌/捕鱼这类即便是纯 UGC 也强制拉到人工复核档)。三档选出来后,才进入图 11 那条机审瀑布——标准档正常跑、严格档把放行阈值压低、人工复核档直接送人审。
|
||||
|
||||
这张图最该让人看清的设计缝,是「档位源」现在和将来不是同一个东西。终态设计是把 `lockStrength` 作为 IP 的一个授权属性,直接挂在 IP 实体上,录入授权时由运营按 IP 方敏感度定下来;但现状是——**IP 库目前只是个 seam,授权链还没建,根本没有承载 `lockStrength` 的 IP 实体**。所以图上把「档位源」这一簇明确标成「现阶段=过渡表 `lock_strength_policy`、终态=IP 实体属性」,中间那条从 IP 实体指向过渡表的箭头特意画成虚线、注明「终态收敛(IP 授权模型成熟后)」:现在先用一张轻量过渡表按 ipId 或题材关键词映射档位、admin 可配,等 IP 授权模型成熟了再把档位策略收敛进 IP 实体。这样三档不被 IP 库的进度卡死,又不至于产生两套并行的策略源。这条「现在用过渡表、将来收敛进 IP 实体」的迁移,正是评审最该盯住的设计意图——别把过渡表当成终态,也别因为 IP 库还是 seam 就以为三档无从落地。
|
||||
|
||||
### 运营图 14 · 短信报备闸门 vs 邀请码旁路(C方案)切换纪律〔Mer新·时·现〕(P2)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 玩家
|
||||
participant P as 绘境AI 平台
|
||||
participant S as 短信供应商
|
||||
participant G as 合规闸门(#3 短信签名报备)
|
||||
Note over G: 报备周期 1-2 周不可压缩 · 报备完成前验证码不可用
|
||||
Note over U,P: 内测期:报备未完成,但注册漏斗不能被一道审批闸门卡死
|
||||
U->>P: 用邀请码注册(C 方案旁路 · 不依赖短信验证码)
|
||||
P-->>U: 注册成功(漏斗跑通,报备未完成也不影响内测)
|
||||
Note over G,S: 依赖串联:部分短信供应商要求域名已备案(#2 ICP)<br/>→ 选不强制备案的供应商先行,或等 ICP 完成,二者择一
|
||||
G->>P: 报备完成(签名通过)→ 才允许全量切验证码
|
||||
rect rgb(255,235,235)
|
||||
Note over P: 切渠道硬规矩 = 配置切换 + 两项验证绑定(缺一不得只切配置)
|
||||
P->>P: ① 确认 huijing.captcha.enable 对发码链路真生效
|
||||
P->>P: ② 发码 IP 日/时上限已部署(Redis 计数,防短信费用黑洞)
|
||||
end
|
||||
U->>P: 输入手机号
|
||||
P->>S: 请求下发验证码(两项验证均绑定后才放开)
|
||||
S-->>U: 短信验证码
|
||||
U->>P: 提交验证码
|
||||
P-->>U: 登录成功(切到验证码全量)
|
||||
```
|
||||
|
||||
*(图源:合规闸门.md §6「短信报备这道闸门如何不卡死漏斗」+ §4 依赖串联;鉴权切渠道两项验证出自 HJ-PASSPORT-EXEC-001 §7.2)*
|
||||
|
||||
这张图回答一个很实际的运营纪律问题:有一道合规闸门(#3 短信签名报备)周期 1-2 周不可压缩、且报备完成前短信验证码根本用不了,**那内测期的玩家怎么注册**?如果硬等这道闸门,注册漏斗在内测期就被卡死了——这正是「合规闸门是日历驱动、一秒也压不动」这条铁律,撞上「产品要尽快验证」这件事时的典型冲突。图上半部分画的就是绘境AI 的解法:把「鉴权」与「短信报备」解耦,内测期玩家用**邀请码**注册(C 方案旁路),完全不依赖短信验证码,所以报备没完成也不影响内测漏斗跑通。这一旁路同时还顺带服务了另一件事——自有端按「邀请制内测、不公开注册」定性(见图 3 的双层定性),邀请码注册恰好是这个定性的落地形态。
|
||||
|
||||
这张图最该让人记住的是下半部分那条红框纪律:邀请码旁路不是永久方案,等报备完成、要切到短信验证码全量时,**不允许「只切一个配置开关就上线」**。切渠道的硬规矩是「配置切换 + 两项验证绑定,缺一不可」——既要确认 `huijing.captcha.enable` 这个开关真正对发码链路生效(配置生效是一回事),又必须先把「按 IP 的日/时发码上限」用 Redis 计数部署好(发码频率有上限是另一回事);少了后者,验证码接口会被刷爆、烧出一个短信费用黑洞。图上还钉了一条容易被忽略的依赖串联:部分短信供应商要求域名已备案(#2 ICP 回执),所以这道报备和 ICP 之间有先后约束,要么选不强制备案的供应商先行、要么等 ICP 完成,二者择一。这张图标了 (P2) ——它讲的是一个会随日历推进真实发生的切换动作的运营纪律,不是当下就要执行的开发项;在邀请码内测阶段,它是「设计已想清、待时点到了再按纪律切」的待办,评审该确认的是这条「切换前置」别被简化成「改一行配置」,而非现在就去接短信验证码。
|
||||
|
||||
> **运营域图清单与状态表**
|
||||
|
||||
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|
||||
@ -182,8 +255,11 @@ flowchart TB
|
||||
| 9 | 一壳多游 · L1 精选整包发行 | 架 | SVG新 | 现 | 固定壳 + 远程 GameConfig(禁代码·9c 红线)+ 备案锁(待律所裁)+ 引擎竞标(P1 暂停)+ 零构建生产红利 |
|
||||
| 10 | 变现端到端钱流地图 | 时 | SVG新 | 现 | 三线(广告全真 / 订阅半真 / B 端仅状态机)→ 创作者钱包(恒等式)+ 提现 mock 打款;控制平面三 job + 对账锚点链 |
|
||||
| 11 | 审核台双层审核 | 流 | SVG新 | 现 | 快检 + 阿里云兜底 + 人审 BPM + 锁风三档 + 处置联动(下架现成 / 降权·信用·封账号联动待建);锁风门框架真·原子桩 |
|
||||
| 12 | 运营对象状态机合集 | 状态机 | SVG | 现 | 四台机并排:提现五态(真跑·终点 mock)‖ B 端询单五态(不碰钱·钱留 M4)‖ 审核工单(第一期待建·超时告警为旁路态)‖ 订阅续期(入账真·收单未接·过期可逆回落);各机触发/终态/幂等键 |
|
||||
| 13 | IP 库 · 锁风档位来源概念模型 | 概念 | Mer新 | 现 | 选档器 lockStrength 来源链:IP 授权档→IP 实体属性(终态)/ 现阶段过渡表 lock_strength_policy + 题材黑名单兜底;补图 11 未答的档位来源 |
|
||||
| 14 | 短信报备闸门 vs 邀请码旁路(C方案) | 时 | Mer新 | 现(P2) | 合规闸门(日历)交注册漏斗:邀请码旁路内测不卡注册 / 报备完成才切验证码;切渠道硬规矩=配置+两项验证绑定;依赖 ICP 串联 |
|
||||
|
||||
> **状态分布**:11 张图整体状态全为「现」(讲的都是已拍板的现行设计逻辑);状态差异在**元素级**——已建真跑 / 框架真用实心块,待接线 / 待建 / mock / 钱留 M4 / 待律所 / 远期账用虚线框 + 文字小标。本域无「整图待接 / 整图缓做」的图,其纪律点是**不把现行设计里被合规日历闸门或外部资质阻塞的部分画成已建好**。**防漂移门**:本文 frontmatter 记运营域六份源档的 commit hash(README/合规闸门 @ 3e71715a、变现与单位经济 @ 7ecd616e、变现端到端 @ 38357c3d、渠道发行 @ 5cadf504、审核台运营 @ 15b707fd),源档变更即比对。
|
||||
> **状态分布**:14 张图整体状态全为「现」(讲的都是已拍板的现行设计逻辑);状态差异在**元素级**——已建真跑 / 框架真用实心块,待接线 / 待建 / mock / 钱留 M4 / 待律所 / 远期账用虚线框 + 文字小标。本域无「整图待接 / 整图缓做」的图,其纪律点是**不把现行设计里被合规日历闸门或外部资质阻塞的部分画成已建好**。**防漂移门**:本文 frontmatter 记运营域六份源档的 commit hash(README/合规闸门 @ 3e71715a、变现与单位经济 @ 7ecd616e、变现端到端 @ 38357c3d、渠道发行 @ 5cadf504、审核台运营 @ 15b707fd),源档变更即比对。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -168,6 +168,50 @@ flowchart LR
|
||||
|
||||
读这张图,最要让人看清的是「**买到什么、买不到什么**」那一栏:本阶段上 k8s 买到的是声明式部署 + `rollout undo` 一键回滚 + requests/limits 共存保护 + 观测栈编排;**买不到的是高可用**——单节点 k3s 一旦节点挂了,集群和所有 workload 一起没,这和今天裸 JAR 挂了没本质区别,反而多背了一整套 k8s 控制平面的复杂度。如果创始人的预期是「上了 k8s 就更稳了」,这里要先校准:高可用要等多节点,而多节点要等有第二台有内存余量的 x86 机器(现在没有)。技术细节上还有两个被图钉住的关键决定:后端走 `hostNetwork: true`(一举两得——既直占宿主 48080 让对外端口零变化,又能连只 bind 在 `127.0.0.1` 的库,`hostAliases` 和 host-gateway 都做不到);隔离期 Pod 用 `server.port=48092` 起(避开正被 live 裸 JAR 占着的 48080),这正是图 2/图 3 的隔离验证安全变体平移到了 k8s。
|
||||
|
||||
### 运维图 9 · 一句话生成游戏 · 端到端 trace 贯穿〔Mer新·时序·接(待接线)〕
|
||||
|
||||
这张图回答一个最具体的问题:观测体系**做好了到底能干嘛**。前面图 6 画的是观测栈的零件怎么搭、图 5 点的是「达标线画出来了但没人在度量」,而这张图把那套栈兑现成一个看得见摸得着的能力——**一个 `trace_id` 把「一句话生成游戏」这条最值钱的链,从用户在前端点下「生成」那一刻,一路串到便宜模型返回、九门放行、产物编译完成**,中途经过的每一跳都挂在同一棵 trace 树上。这正是源档《观测体系.md》§5.1 列的**头号验收判据**:发起一次生成,在 Grafana 里用同一个 trace_id 就能查到「网关入口 → SAA 各节点 → new-api 调用」的完整链路,而且**这个 trace_id 恰好等于响应头回写的那个 `trace-id`**——前端报错时把响应头里的 `trace-id` 抄下来,运营贴进 Grafana 就能直接定位这次生成卡在哪个节点、哪道门、调模型报了什么。
|
||||
|
||||
整张图的状态是**接**(待接线):它画的是观测做好之后的目标能力,而不是今天已经能做到的事。所以图上用一条贯穿的虚线把「这条 trace 链」整体标成待接线,中途凡是要新建埋点才有数据的节点(自动 span、九门指标、终态指标、成本/积压)一律虚线框 + 「待接」小标;**唯一一个实心绿块**是 SAA 各节点的 observation——它是后端目前唯一一段依赖已就位、已在以 Micrometer 标准产出的观测信号(详见图 6 正下方那条高亮),其余全靠这条链补齐才能点亮。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
U["前端点击「生成游戏」<br/>game-studio"]:::todo
|
||||
U -->|"注入 traceparent(W3C)"| GW
|
||||
|
||||
subgraph BE["huijing 后端单体(同一棵 trace 树)"]
|
||||
direction LR
|
||||
GW["网关入口 · TraceFilter<br/>起 root span<br/>响应头回写 trace-id"]:::todo
|
||||
AIGC["aigc 服务<br/>建 game_aigc_task"]:::todo
|
||||
subgraph SAA["SAA 裸图编排 · 每节点一条 observation span"]
|
||||
direction LR
|
||||
NB["node: brief<br/>需求拆解"]:::done
|
||||
NG["node: gen_source<br/>调 new-api(出网 span)"]:::done
|
||||
NN["node: nine_gates<br/>九门校验"]:::done
|
||||
NBD["node: build<br/>build-from-source"]:::done
|
||||
end
|
||||
GW --> AIGC --> SAA
|
||||
NB --> NG --> NN --> NBD
|
||||
end
|
||||
|
||||
NG -->|"OTel agent 自动 span"| NAPI["new-api 网关<br/>→ 便宜 LLM(M3/DS-V4)"]:::todo
|
||||
|
||||
AIGC -. "终态回填 status<br/>gen_task_total{status}" .-> M
|
||||
NN -. "gen_gate_fail_total{gate}" .-> M
|
||||
SAA -. "gen_duration_seconds / gen_queue_depth / llm_cost" .-> M
|
||||
M[("指标平面<br/>成功率 / 耗时 / 积压 / 成本")]:::metric
|
||||
|
||||
GW -. "同一 trace_id 关联" .-> M
|
||||
M -. "trace ↔ metrics 同 id" .-> T[("trace 平面<br/>= 响应头 trace-id")]:::tracehl
|
||||
|
||||
classDef done fill:#dcfce7,stroke:#16a34a,stroke-width:2px;
|
||||
classDef todo fill:#fff7ed,stroke:#d97706,stroke-width:1.5px,stroke-dasharray:5 4;
|
||||
classDef metric fill:#1e293b,color:#fff,stroke:#475569,stroke-width:1.5px;
|
||||
classDef tracehl fill:#0c4a6e,color:#fff,stroke:#0ea5e9,stroke-width:2px;
|
||||
```
|
||||
|
||||
读这张图要抓住三层意思。其一,**实线链是「trace 怎么连成一根」,虚线指向是「metrics 怎么和这根 trace 同 id 挂钩」**:一次生成在 trace 平面是一条完整时间轴(每个 SAA 节点一个 span、调 new-api 那一跳由 OTel agent 自动补 span),同时几个关键节点把业务指标(终态算成功率、九门算 `gen_gate_fail`、耗时/积压/成本)打到指标平面,两个平面经同一个 trace_id 对得上——所以既能看「这一次生成卡哪了」(trace 下钻),又能看「最近一千次生成的成功率趋势」(metrics 看板),这是图 6 那套栈接好后最直接的回报。其二,**绿块与虚线框的对比就是本图的状态纪律**:别因为这张图画得顺就以为链路已经通了——除了 SAA 节点 observation 这一段地基真在,前端 traceparent 注入、网关 root span 与 trace-id 对齐、自动 span、那几个业务指标的埋点,在代码里全是待新建(图 6 散文已逐件点过,五个生成指标当前零命中)。其三,这张图同时钉死了一条**最该据图 review 的设计缝**:响应头那个 `trace-id` 现在取自 SkyWalking 的 `TracerUtils`,而 OTel agent 走的是 W3C `traceparent` 自成一套——两者不打通,前端抄回来的 `trace-id` 就和 Grafana 里 OTel trace 的 id 对不上号、查不到链路。源档《观测体系.md》§6 把「trace context 头怎么对齐成一根」列为**第一期落地就要先打通的头号待核**,这张图把那条缝画在「网关 root span ↔ 响应头 trace-id ↔ 指标/ trace 同 id」这条线上;它一旦没对齐,整张图承诺的「一个 id 贯穿到底」就断在前后端边界,所以它既是观测体系的头号验收判据,也是落地时第一个要验的点。
|
||||
|
||||
> **运维域图清单与状态表**
|
||||
|
||||
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|
||||
@ -180,8 +224,9 @@ flowchart LR
|
||||
| 6 | 观测体系 OTel→Grafana/夜莺 | 架 | SVG新 | **接** | 采集→管道→存储→看板/告警全链;唯一已就位=SAA 节点 observation,其余待接线;Collector 居中/双看板分工/旁路铁律 |
|
||||
| 7 | admin 观测入口 | 流 | Mer新(内联) | **接** | 控制台一键进盘链路 + SSO 免登 + 嵌入方式/SSO 两处待核;现状=零、整套新建 |
|
||||
| 8 | k3s 单节点迁移 | 架 | SVG新 | **缓** | 单节点 k3s + staging 应用 + 观测栈,库不进集群;四阶段迁移路;裸 JAR 兜底全程保留;买到/买不到边界 |
|
||||
| 9 | 一句话生成游戏 · 端到端 trace 贯穿 | 时 | Mer新(内联) | **接** | 一个 trace_id 串前端点击→网关→aigc→SAA 各节点 observation→new-api→九门→build;trace 与 metrics 同 id 关联、= 响应头 trace-id;唯一已就位=SAA 节点 observation,余待接线;= 观测体系头号验收判据 |
|
||||
|
||||
> **状态分布**:现 ×6、接 ×2(图 6/7,观测体系待接线)、缓 ×1(图 8,k3s 收窄缓做)。**防漂移门**:本文 frontmatter 记运维域三份源档的 commit hash(README/k8s迁移 @ 15b707fd、观测体系 @ 3e71715a),源档变更即比对。
|
||||
> **状态分布**:现 ×6、接 ×3(图 6/7/9,观测体系待接线)、缓 ×1(图 8,k3s 收窄缓做)。**防漂移门**:本文 frontmatter 记运维域三份源档的 commit hash(README/k8s迁移 @ 15b707fd、观测体系 @ 3e71715a),源档变更即比对。
|
||||
|
||||
---
|
||||
|
||||
|
||||
228
docs/architecture/assets/07-端到端全链泳道.svg
Normal file
228
docs/architecture/assets/07-端到端全链泳道.svg
Normal file
@ -0,0 +1,228 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1480 952" font-family="-apple-system,'PingFang SC','Microsoft YaHei',Segoe UI,sans-serif">
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#334155"/></marker>
|
||||
<marker id="arrowB" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#64748b"/></marker>
|
||||
<marker id="arrowG" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#16a34a"/></marker>
|
||||
<marker id="arrowR" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#dc2626"/></marker>
|
||||
<marker id="arrowP" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#7c3aed"/></marker>
|
||||
<style>
|
||||
.t{fill:#0f172a}.mut{fill:#475569}.sm{font-size:12px}.xs{font-size:11px}.xxs{font-size:10px}
|
||||
.h1{font-size:24px;font-weight:700}.h2{font-size:14px;font-weight:700}.lbl{font-size:12.5px;font-weight:600}
|
||||
.flow{stroke:#334155;stroke-width:2;fill:none}
|
||||
.flowg{stroke:#16a34a;stroke-width:2;fill:none;stroke-dasharray:7 4}
|
||||
.flowr{stroke:#dc2626;stroke-width:2;fill:none}
|
||||
.flowb{stroke:#64748b;stroke-width:1.6;fill:none;stroke-dasharray:6 4}
|
||||
.flowp{stroke:#7c3aed;stroke-width:1.8;fill:none;stroke-dasharray:6 4}
|
||||
.badge{font-size:10.5px;font-weight:700}.warn{font-size:10px;font-weight:700;fill:#b45309}
|
||||
.lane{font-size:13px;font-weight:700;fill:#0f172a}
|
||||
</style>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="1480" height="952" fill="#f8fafc"/>
|
||||
<text x="40" y="38" class="t h1">图 8 · 端到端跨域全链泳道</text>
|
||||
<text x="40" y="58" class="mut sm">一句话 → 出包 → 上线 → 被玩 → 数据回流 → feed 重排,八条泳道串成一条完整系统链。下半叠一条并联钱流(广告曝光 → 计费 → 分账 → 钱包)。把碎片拼成整条系统,这是最该先读的一张。</text>
|
||||
|
||||
<!-- 状态约定条 -->
|
||||
<rect x="40" y="74" width="1400" height="34" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4" stroke-dasharray="7 5"/>
|
||||
<text x="52" y="96" class="xs t" font-weight="700">状态约定:</text>
|
||||
<text x="126" y="96" class="xs mut">实线步骤 = 现行已建(机制实测);橙虚线小标 = 现状桩(feed 游标分页恒返第一页 / 真广告 SDK 仍 mock);紫虚线 = tier2 富游戏轨(远期·待 spike,不入现行链)。整链主路 = 现 + 桩,绝不读成全实。</text>
|
||||
|
||||
<!-- ===== 泳道背景带(8 条)===== 列起点 x=160,行高约 78,从 y=120 起 -->
|
||||
<!-- 泳道标签列底 -->
|
||||
<rect x="40" y="120" width="116" height="624" rx="8" fill="#eef2f7" stroke="#cbd5e1" stroke-width="1.2"/>
|
||||
<!-- 横线分隔 8 条道 -->
|
||||
<line x1="156" y1="198" x2="1440" y2="198" stroke="#e2e8f0" stroke-width="1"/>
|
||||
<line x1="156" y1="276" x2="1440" y2="276" stroke="#e2e8f0" stroke-width="1"/>
|
||||
<line x1="156" y1="354" x2="1440" y2="354" stroke="#e2e8f0" stroke-width="1"/>
|
||||
<line x1="156" y1="432" x2="1440" y2="432" stroke="#e2e8f0" stroke-width="1"/>
|
||||
<line x1="156" y1="510" x2="1440" y2="510" stroke="#e2e8f0" stroke-width="1"/>
|
||||
<line x1="156" y1="588" x2="1440" y2="588" stroke="#e2e8f0" stroke-width="1"/>
|
||||
<line x1="156" y1="666" x2="1440" y2="666" stroke="#e2e8f0" stroke-width="1"/>
|
||||
<rect x="156" y="120" width="1284" height="624" rx="8" fill="none" stroke="#cbd5e1" stroke-width="1.2"/>
|
||||
|
||||
<!-- 泳道标签 -->
|
||||
<text x="52" y="155" class="lane">创作者</text><text x="52" y="172" class="xxs mut">C 端</text>
|
||||
<text x="52" y="233" class="lane">game-studio</text><text x="52" y="250" class="xxs mut">前端宿主</text>
|
||||
<text x="52" y="311" class="lane">aigc + SAA</text><text x="52" y="328" class="xxs mut">生成层</text>
|
||||
<text x="52" y="389" class="lane">compliance</text><text x="52" y="406" class="xxs mut">合规审核</text>
|
||||
<text x="52" y="467" class="lane">project</text><text x="52" y="484" class="xxs mut">+ feed</text>
|
||||
<text x="52" y="545" class="lane">玩家</text><text x="52" y="562" class="xxs mut">C 端</text>
|
||||
<text x="52" y="623" class="lane">telemetry</text><text x="52" y="640" class="xxs mut">遥测回路</text>
|
||||
<text x="52" y="701" class="lane">ad + trade</text><text x="52" y="718" class="xxs mut">钱流并联</text>
|
||||
|
||||
<!-- ============ 泳道 1 · 创作者 ============ -->
|
||||
<rect x="172" y="132" width="220" height="52" rx="9" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
|
||||
<text x="184" y="153" class="t lbl">① 一句话 + 选风格</text>
|
||||
<text x="184" y="172" class="xxs mut">零门槛创意输入 + 素材</text>
|
||||
|
||||
<!-- ============ 泳道 2 · studio ============ -->
|
||||
<rect x="172" y="210" width="220" height="52" rx="9" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
|
||||
<text x="184" y="231" class="t lbl">② 提交生成请求</text>
|
||||
<text x="184" y="250" class="xxs mut">POST /app-api/aigc/generate</text>
|
||||
|
||||
<rect x="1140" y="210" width="280" height="52" rx="9" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
|
||||
<text x="1152" y="231" class="t lbl">⑫ iframe 沙箱试玩</text>
|
||||
<text x="1152" y="250" class="xxs mut">CSP + sandbox · SDK 注入受控面</text>
|
||||
|
||||
<!-- ============ 泳道 3 · aigc + SAA ============ -->
|
||||
<rect x="172" y="288" width="220" height="52" rx="9" fill="#dbeafe" stroke="#2563eb" stroke-width="1.6"/>
|
||||
<text x="184" y="309" class="t lbl">③ 建生成任务</text>
|
||||
<text x="184" y="328" class="xxs mut">202 + taskId · Dispatcher 派发</text>
|
||||
|
||||
<rect x="430" y="282" width="300" height="64" rx="9" fill="#dbeafe" stroke="#2563eb" stroke-width="1.8"/>
|
||||
<text x="442" y="302" class="t lbl">④ SAA 裸图 16 节点编排</text>
|
||||
<text x="442" y="320" class="xxs mut">render→classify→design→generate→…</text>
|
||||
<text x="442" y="336" class="xxs mut">→ new-api → 便宜 LLM → 九门兜底</text>
|
||||
|
||||
<rect x="766" y="288" width="220" height="52" rx="9" fill="#dcfce7" stroke="#16a34a" stroke-width="1.7"/>
|
||||
<text x="778" y="309" class="t lbl">⑤ 九门过 → emit 出包</text>
|
||||
<text x="778" y="328" class="xxs mut">done 由确定性门定,非 LLM 自评</text>
|
||||
|
||||
<!-- ============ 泳道 5 · project + feed(先放 project 草稿 / 发布)============ -->
|
||||
<rect x="766" y="444" width="220" height="52" rx="9" fill="#fefce8" stroke="#ca8a04" stroke-width="1.6"/>
|
||||
<text x="778" y="465" class="t lbl">⑥ 回写 project 草稿</text>
|
||||
<text x="778" y="484" class="xxs mut">game_version status=0 草稿</text>
|
||||
|
||||
<rect x="430" y="444" width="300" height="52" rx="9" fill="#fefce8" stroke="#ca8a04" stroke-width="1.6"/>
|
||||
<text x="442" y="465" class="t lbl">⑦ submitPublish 提审</text>
|
||||
<text x="442" y="484" class="xxs mut">project 编排发布 · 落锁风门</text>
|
||||
|
||||
<!-- ============ 泳道 4 · compliance ============ -->
|
||||
<rect x="172" y="366" width="220" height="52" rx="9" fill="#fff1f2" stroke="#e11d48" stroke-width="1.6"/>
|
||||
<text x="184" y="387" class="t lbl">⑧ 锁风门裁决</text>
|
||||
<text x="184" y="406" class="xxs mut">pass / review / block 取 max</text>
|
||||
|
||||
<!-- ============ 泳道 5 · feed(PUBLISHED 入流)============ -->
|
||||
<rect x="172" y="444" width="220" height="52" rx="9" fill="#fef9c3" stroke="#ca8a04" stroke-width="1.7"/>
|
||||
<text x="184" y="465" class="t lbl">⑨ PUBLISHED → 入 feed</text>
|
||||
<text x="184" y="484" class="xxs mut">status=4 · game_feed_rank 排序</text>
|
||||
|
||||
<!-- ============ 泳道 6 · 玩家 ============ -->
|
||||
<rect x="172" y="522" width="220" height="52" rx="9" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
|
||||
<text x="184" y="543" class="t lbl">⑩ 竖屏 feed 刷到</text>
|
||||
<text x="184" y="562" class="xxs mut">即点即玩 · anon_id 匿名可达</text>
|
||||
|
||||
<rect x="430" y="522" width="300" height="52" rx="9" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
|
||||
<text x="442" y="543" class="t lbl">⑪ 试玩 · 互动</text>
|
||||
<text x="442" y="562" class="xxs mut">点赞 / 收藏 / 分享 / 跳过 / 举报</text>
|
||||
|
||||
<!-- ============ 泳道 7 · telemetry ============ -->
|
||||
<rect x="766" y="600" width="220" height="52" rx="9" fill="#fefce8" stroke="#ca8a04" stroke-width="1.6"/>
|
||||
<text x="778" y="621" class="t lbl">⑬ 埋点上报 + 聚合</text>
|
||||
<text x="778" y="640" class="xxs mut">uk_event_id 幂等 · 日聚合</text>
|
||||
|
||||
<rect x="1030" y="600" width="220" height="52" rx="9" fill="#fff7ed" stroke="#d97706" stroke-width="1.6"/>
|
||||
<text x="1042" y="621" class="t lbl">⑭ 算质量分 0–100</text>
|
||||
<text x="1042" y="640" class="xxs mut">error_rate 硬降权:跑不动沉底</text>
|
||||
|
||||
<!-- feed 重排回到泳道5 -->
|
||||
<rect x="430" y="600" width="300" height="52" rx="9" fill="#fef9c3" stroke="#ca8a04" stroke-width="1.7"/>
|
||||
<text x="442" y="621" class="t lbl">⑮ feed 重排</text>
|
||||
<text x="442" y="640" class="xxs mut">sort_score 降序 = quality + boost − 限曝光</text>
|
||||
|
||||
<!-- ============ 泳道 8 · ad + trade(钱流并联)============ -->
|
||||
<rect x="172" y="678" width="248" height="52" rx="9" fill="#fef9c3" stroke="#ca8a04" stroke-width="1.6"/>
|
||||
<text x="184" y="699" class="t lbl">Ⓐ 游戏内广告曝光</text>
|
||||
<text x="184" y="718" class="xxs mut">SDK Plugin.Ad · 激励 / 插屏</text>
|
||||
|
||||
<rect x="458" y="678" width="248" height="52" rx="9" fill="#fef9c3" stroke="#ca8a04" stroke-width="1.6"/>
|
||||
<text x="470" y="699" class="t lbl">Ⓑ ad 计费台账</text>
|
||||
<text x="470" y="718" class="xxs mut">game_ad_revenue · 以分计 · uk_trace 防重</text>
|
||||
|
||||
<rect x="744" y="678" width="248" height="52" rx="9" fill="#ecfdf5" stroke="#059669" stroke-width="1.6"/>
|
||||
<text x="756" y="699" class="t lbl">Ⓒ trade 分账入账</text>
|
||||
<text x="756" y="718" class="xxs mut">source_ref 对账 · net = gross × rate</text>
|
||||
|
||||
<rect x="1030" y="678" width="248" height="52" rx="9" fill="#ecfdf5" stroke="#059669" stroke-width="1.6"/>
|
||||
<text x="1042" y="699" class="t lbl">Ⓓ 创作者钱包</text>
|
||||
<text x="1042" y="718" class="xxs mut">恒等式 balance+frozen+提现=收入</text>
|
||||
|
||||
<!-- ===== 主链箭头 ===== -->
|
||||
<!-- ①→② 竖(同列 x≈282)-->
|
||||
<line x1="282" y1="184" x2="282" y2="208" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ②→③ 竖 -->
|
||||
<line x1="282" y1="262" x2="282" y2="286" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ③→④ 横 -->
|
||||
<line x1="392" y1="314" x2="428" y2="314" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ④→⑤ 横 -->
|
||||
<line x1="730" y1="314" x2="764" y2="314" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ⑤→⑥ 竖(同列 x≈876,aigc 行到 project 行,跨 compliance 行)-->
|
||||
<line x1="876" y1="340" x2="876" y2="442" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ⑥→⑦ 横(project 草稿 → submitPublish,右到左)-->
|
||||
<line x1="766" y1="470" x2="732" y2="470" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ⑦→⑧ 竖上(submitPublish 行 → compliance 行,x≈580)-->
|
||||
<line x1="580" y1="444" x2="580" y2="420" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ⑧ 裁决 → ⑨ 入流:从 compliance(282) 竖下到 feed 行 -->
|
||||
<line x1="282" y1="418" x2="282" y2="442" class="flowr" marker-end="url(#arrowR)"/>
|
||||
<text x="292" y="436" class="xxs" fill="#b91c1c">pass 才入流</text>
|
||||
<!-- ⑨→⑩ 竖(feed 行 → 玩家行,x≈282)-->
|
||||
<line x1="282" y1="496" x2="282" y2="520" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ⑩→⑪ 横 -->
|
||||
<line x1="392" y1="548" x2="428" y2="548" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ⑪→⑬ 斜下到 telemetry(x 430-700→766,y 548→626)走折线 -->
|
||||
<line x1="730" y1="548" x2="876" y2="548" class="flow"/>
|
||||
<line x1="876" y1="548" x2="876" y2="598" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ⑬→⑭ 横 -->
|
||||
<line x1="986" y1="626" x2="1028" y2="626" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- ⑭→⑮ 回排(右到左,过 telemetry 行到 feed 重排)-->
|
||||
<line x1="1030" y1="640" x2="732" y2="640" class="flowg"/>
|
||||
<line x1="732" y1="640" x2="732" y2="640" class="flowg"/>
|
||||
<line x1="734" y1="626" x2="734" y2="654" class="flowg"/>
|
||||
<!-- 用一条干净的回灌折线 ⑭→⑮ -->
|
||||
<path d="M1030 640 L740 640" class="flowg" marker-end="url(#arrowG)"/>
|
||||
<!-- ⑮ 重排 → ⑩ 玩家刷到(feed 重排行 → 玩家行,闭环回流,x≈455)-->
|
||||
<path d="M455 600 C455 588, 408 588, 408 576" class="flowg" marker-end="url(#arrowG)"/>
|
||||
<text x="470" y="592" class="xxs" fill="#15803d" font-weight="700">回流闭环:更优游戏流回到玩家眼前</text>
|
||||
|
||||
<!-- ===== 钱流并联箭头 ===== -->
|
||||
<!-- ⑪ 试玩 → Ⓐ 广告曝光(玩家互动行 → ad 行,x≈300)-->
|
||||
<line x1="300" y1="574" x2="300" y2="676" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="310" y="660" class="xxs mut">游戏内广告</text>
|
||||
<!-- Ⓐ→Ⓑ→Ⓒ→Ⓓ 横 -->
|
||||
<line x1="420" y1="704" x2="456" y2="704" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="706" y1="704" x2="742" y2="704" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="992" y1="704" x2="1028" y2="704" class="flow" marker-end="url(#arrow)"/>
|
||||
|
||||
<!-- ⑤ 出包 → ⑫ 试玩宿主(同款也可被创作者预览;走一条提示连线,右上)-->
|
||||
<path d="M986 300 C1080 300, 1090 236, 1138 236" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<text x="1014" y="280" class="xxs mut">出包即可预览试玩</text>
|
||||
|
||||
<!-- ===== 桩 / future 小标注 ===== -->
|
||||
<!-- feed 游标分页桩(贴在 ⑨/⑩ 之间)-->
|
||||
<rect x="408" y="510" width="316" height="24" rx="6" fill="#fff7ed" stroke="#d97706" stroke-width="1.3" stroke-dasharray="6 4"/>
|
||||
<text x="418" y="526" class="warn">桩:feed 游标分页恒返第一页,Redis 候选集=增长期形态</text>
|
||||
<!-- 真广告 SDK 桩(贴在 Ⓐ 下)-->
|
||||
<rect x="172" y="734" width="248" height="20" rx="5" fill="#fff7ed" stroke="#d97706" stroke-width="1.3" stroke-dasharray="6 4"/>
|
||||
<text x="182" y="749" class="warn">桩:provider=mock,真广告 SDK 待接渠道</text>
|
||||
<!-- 打款 fail-fast 红线(贴在 Ⓓ 下)-->
|
||||
<rect x="1030" y="734" width="248" height="20" rx="5" fill="#fee2e2" stroke="#dc2626" stroke-width="1.3"/>
|
||||
<text x="1040" y="749" class="xs" fill="#b91c1c" font-weight="700">提现打款桩:缺渠道须 fail-fast,绝不发假钱</text>
|
||||
|
||||
<!-- ===== tier2 远期轨(右侧紫虚框,与现行链平行另起)===== -->
|
||||
<rect x="1018" y="282" width="402" height="64" rx="10" fill="#faf5ff" stroke="#7c3aed" stroke-width="1.8" stroke-dasharray="7 5"/>
|
||||
<text x="1030" y="304" class="t lbl" fill="#6b21a8">tier2 富游戏轨(远期·待 spike,不入现行链)</text>
|
||||
<text x="1030" y="322" class="xxs mut">AgentScope 自治 ReAct + Phaser 无头 → 真 src 源工程</text>
|
||||
<text x="1030" y="338" class="xxs mut">换的是"内容怎么造",出包后仍走同一条上线 / 发行公共件</text>
|
||||
<line x1="986" y1="314" x2="1016" y2="314" class="flowp" marker-end="url(#arrowP)"/>
|
||||
|
||||
<!-- ===== 图例 ===== -->
|
||||
<text x="40" y="784" class="t h2">图例:</text>
|
||||
<line x1="116" y1="780" x2="166" y2="780" class="flow" marker-end="url(#arrow)"/><text x="174" y="784" class="t xs">现行主路(一句话→出包→上线→被玩)</text>
|
||||
<line x1="470" y1="780" x2="520" y2="780" class="flowg" marker-end="url(#arrowG)"/><text x="528" y="784" class="t xs">数据回流(把链弯成飞轮)</text>
|
||||
<line x1="770" y1="780" x2="820" y2="780" class="flowr" marker-end="url(#arrowR)"/><text x="828" y="784" class="t xs">合规总闸(pass 才入流)</text>
|
||||
<line x1="1040" y1="780" x2="1090" y2="780" class="flowp" marker-end="url(#arrowP)"/><text x="1098" y="784" class="t xs">远期 tier2 轨(不入现行链)</text>
|
||||
|
||||
<rect x="116" y="800" width="34" height="18" rx="5" fill="#fff7ed" stroke="#d97706" stroke-width="1.6" stroke-dasharray="6 4"/><text x="158" y="814" class="t xs">现状桩(feed 游标 / 真广告 SDK / 打款)</text>
|
||||
<line x1="470" y1="809" x2="520" y2="809" class="flowb" marker-end="url(#arrowB)"/><text x="528" y="814" class="t xs">旁路(出包即可预览)</text>
|
||||
<g class="badge"><rect x="770" y="801" width="56" height="18" rx="3" fill="#dc2626"/><text x="775" y="814" fill="#fff">安全</text>
|
||||
<rect x="834" y="801" width="56" height="18" rx="3" fill="#475569"/><text x="839" y="814" fill="#fff">数据</text>
|
||||
<rect x="898" y="801" width="56" height="18" rx="3" fill="#16a34a"/><text x="903" y="814" fill="#fff">可靠</text></g>
|
||||
<text x="962" y="814" class="mut xs">沙箱/打款=安全 · 回流=数据 · 幂等对账=可靠</text>
|
||||
|
||||
<!-- ===== 一眼看出(解读条)===== -->
|
||||
<rect x="40" y="834" width="1400" height="58" rx="10" fill="#f1f5f9" stroke="#475569" stroke-width="1.4"/>
|
||||
<text x="52" y="855" class="t h2">新人一眼看出:</text>
|
||||
<text x="52" y="874" class="xs mut">① 没有任何一环跨域接缝是断的——相邻泳道交接处对得上,系统才闭环;② 合规门是上线总闸(⑧),不 pass 进不了 feed;③ 数据回流(⑬⑭⑮)把线性链弯成飞轮,是"越用越聪明"的来源;</text>
|
||||
<text x="52" y="890" class="xs mut">④ 钱流(ⒶⒷⒸⒹ)与主链并联、经 source_ref 串起对账;⑤ 现状要诚实读:feed 分页 / 真广告 SDK / 打款都还是桩,tier2 富游戏轨是远期、不在这条现行链上。</text>
|
||||
|
||||
<text x="40" y="922" class="mut xs">映射:产品/README §1 闭环 + 架构/README §5 + 后端/README §3 五条业务链 + 后端/数据模型 §2 + 运营/变现与单位经济 + 运维/smoke §1.3 | 状态:现 + F(桩与远期已标)| 设计变动须同步本图</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 17 KiB |
179
docs/architecture/assets/08-系统上下文.svg
Normal file
179
docs/architecture/assets/08-系统上下文.svg
Normal file
@ -0,0 +1,179 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1480 868" font-family="-apple-system,'PingFang SC','Microsoft YaHei',Segoe UI,sans-serif">
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#334155"/></marker>
|
||||
<marker id="arrowB" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#64748b"/></marker>
|
||||
<marker id="arrowP" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#7c3aed"/></marker>
|
||||
<style>
|
||||
.t{fill:#0f172a}.mut{fill:#475569}.sm{font-size:12px}.xs{font-size:11px}.xxs{font-size:10px}
|
||||
.h1{font-size:24px;font-weight:700}.h2{font-size:14px;font-weight:700}.lbl{font-size:12.5px;font-weight:600}
|
||||
.flow{stroke:#334155;stroke-width:2;fill:none}
|
||||
.flowb{stroke:#64748b;stroke-width:1.7;fill:none;stroke-dasharray:6 4}
|
||||
.flowp{stroke:#7c3aed;stroke-width:1.8;fill:none;stroke-dasharray:6 4}
|
||||
.badge{font-size:10.5px;font-weight:700}
|
||||
.stOn{font-size:10px;font-weight:700;fill:#15803d}.stWait{font-size:10px;font-weight:700;fill:#b45309}.stFut{font-size:10px;font-weight:700;fill:#7c3aed}
|
||||
</style>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="1480" height="868" fill="#f8fafc"/>
|
||||
<text x="40" y="38" class="t h1">图 9 · 系统上下文与外部依赖边界</text>
|
||||
<text x="40" y="58" class="mut sm">C4 L1 系统上下文:中心是绘境AI 平台(单体),左边外部用户、右边外部依赖系统。一眼看清"系统边界到哪、对外依赖谁、各依赖现接还是远期"。</text>
|
||||
|
||||
<!-- 状态约定条 -->
|
||||
<rect x="40" y="74" width="1400" height="34" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4" stroke-dasharray="7 5"/>
|
||||
<text x="52" y="96" class="xs t" font-weight="700">状态约定:</text>
|
||||
<text x="126" y="96" class="xs mut">外部依赖按接入度标三态——实线框 + 绿「已接」= 现行已联通调用;橙虚线框 + 「待接」= 设计已定、被日历闸门 / 进件阻塞;紫虚线框 + 「远期」= 排期更后或竞标未决。绝不把待接 / 远期画成已接。</text>
|
||||
|
||||
<!-- ===== 中心:绘境AI 平台 ===== -->
|
||||
<rect x="500" y="150" width="480" height="470" rx="16" fill="#eef2ff" stroke="#1d4ed8" stroke-width="2.6"/>
|
||||
<text x="740" y="180" class="t h2" text-anchor="middle">绘境AI 平台(内网单体 · 系统边界内)</text>
|
||||
<text x="740" y="200" class="xs mut" text-anchor="middle">monorepo 先行 · 13 业务模块 jar 聚合进一个进程</text>
|
||||
|
||||
<!-- 前端两端 -->
|
||||
<rect x="524" y="222" width="200" height="70" rx="10" fill="#ffffff" stroke="#2563eb" stroke-width="1.6"/>
|
||||
<text x="534" y="244" class="t lbl">game-studio</text>
|
||||
<text x="534" y="262" class="xxs mut">Vue3 + Vant · 创作者 + 玩家</text>
|
||||
<text x="534" y="280" class="xxs mut">C 端产品前端 · 试玩宿主</text>
|
||||
|
||||
<rect x="756" y="222" width="200" height="70" rx="10" fill="#ffffff" stroke="#ca8a04" stroke-width="1.6"/>
|
||||
<text x="766" y="244" class="t lbl">game-admin</text>
|
||||
<text x="766" y="262" class="xxs mut">Vue3 + Element Plus</text>
|
||||
<text x="766" y="280" class="xxs mut">B 端运营 + 管理员后台</text>
|
||||
|
||||
<!-- 网关 -->
|
||||
<rect x="524" y="304" width="432" height="40" rx="9" fill="#e0e7ff" stroke="#1d4ed8" stroke-width="1.5"/>
|
||||
<text x="740" y="329" class="t lbl" text-anchor="middle">Spring Cloud Gateway · MVP 软转发(身份可信化)</text>
|
||||
|
||||
<!-- 后端单体 game-cloud -->
|
||||
<rect x="524" y="356" width="432" height="160" rx="10" fill="#ffffff" stroke="#1d4ed8" stroke-width="1.8"/>
|
||||
<text x="534" y="378" class="t lbl">game-cloud 后端单体(Huijing fork · Java 17)</text>
|
||||
<text x="534" y="396" class="xxs mut">13 模块:studio · aigc · runtime · project · feed · telemetry</text>
|
||||
<text x="534" y="412" class="xxs mut"> trade · ad · compliance · community · biz(+ ip seam · pay 原生)</text>
|
||||
<rect x="534" y="424" width="412" height="38" rx="7" fill="#dbeafe" stroke="#2563eb" stroke-width="1.3"/>
|
||||
<text x="544" y="447" class="xs t">AI 生成层:SAA 裸图编排 → 经 new-api 出网调便宜 LLM</text>
|
||||
<rect x="534" y="468" width="412" height="40" rx="7" fill="#f1f5f9" stroke="#475569" stroke-width="1.3"/>
|
||||
<text x="544" y="485" class="xxs t">中间件(系统边界内,自建):MySQL 8.0 · Redis 7</text>
|
||||
<text x="544" y="500" class="xxs mut">权限只在后端可信边界强制 · 上游 API key 不裸暴露</text>
|
||||
|
||||
<!-- 平台维度徽章 -->
|
||||
<rect x="524" y="528" width="432" height="76" rx="9" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
|
||||
<text x="534" y="548" class="xs t" font-weight="700">平台对外姿态:</text>
|
||||
<text x="534" y="566" class="xxs mut">出网只经受控网关(生成走 new-api / 素材走 mmx),不让游戏自行联网(CSP connect-src 'none')。</text>
|
||||
<text x="534" y="582" class="xxs mut">所有外部依赖均可换 mock ↔ 真实现零改业务码切换;打款例外:缺渠道 fail-fast 不发假钱。</text>
|
||||
<g class="badge"><rect x="534" y="588" width="50" height="16" rx="3" fill="#dc2626"/><text x="539" y="600" fill="#fff">安全</text>
|
||||
<rect x="590" y="588" width="50" height="16" rx="3" fill="#16a34a"/><text x="595" y="600" fill="#fff">成本</text>
|
||||
<rect x="646" y="588" width="50" height="16" rx="3" fill="#7c3aed"/><text x="651" y="600" fill="#fff">伸缩</text>
|
||||
<rect x="702" y="588" width="50" height="16" rx="3" fill="#475569"/><text x="707" y="600" fill="#fff">数据</text></g>
|
||||
|
||||
<!-- ===== 左侧:外部用户(actor)===== -->
|
||||
<text x="40" y="142" class="t h2">外部用户(系统边界外 · actor)</text>
|
||||
<rect x="40" y="156" width="200" height="60" rx="10" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
|
||||
<text x="50" y="178" class="t lbl">创作者</text>
|
||||
<text x="50" y="196" class="xxs mut">一句话生成 / 发布 / 看收益</text>
|
||||
<text x="50" y="210" class="xxs mut">studio · C 端</text>
|
||||
|
||||
<rect x="40" y="228" width="200" height="60" rx="10" fill="#eff6ff" stroke="#2563eb" stroke-width="1.6"/>
|
||||
<text x="50" y="250" class="t lbl">玩家</text>
|
||||
<text x="50" y="268" class="xxs mut">刷 feed 即点即玩 / 互动</text>
|
||||
<text x="50" y="282" class="xxs mut">studio · C 端 · anon_id 匿名可达</text>
|
||||
|
||||
<rect x="40" y="300" width="200" height="60" rx="10" fill="#fefce8" stroke="#ca8a04" stroke-width="1.6"/>
|
||||
<text x="50" y="322" class="t lbl">运营 / 管理员</text>
|
||||
<text x="50" y="340" class="xxs mut">审核 / 精选 / 封禁 / 看板</text>
|
||||
<text x="50" y="354" class="xxs mut">admin · B 端 · system_users</text>
|
||||
|
||||
<rect x="40" y="372" width="200" height="60" rx="10" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.6"/>
|
||||
<text x="50" y="394" class="t lbl">B 端 / IP 客户</text>
|
||||
<text x="50" y="412" class="xxs mut">提需求 / 看 demo / 验收</text>
|
||||
<text x="50" y="426" class="xxs mut">现金线首位 · biz 单据流</text>
|
||||
|
||||
<!-- 用户 → 平台 箭头 -->
|
||||
<line x1="240" y1="186" x2="498" y2="250" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="240" y1="258" x2="498" y2="262" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="240" y1="330" x2="498" y2="288" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="240" y1="402" x2="498" y2="320" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="300" y="232" class="xxs mut">浏览器 HTTPS</text>
|
||||
|
||||
<!-- ===== 右侧:外部依赖系统 ===== -->
|
||||
<text x="1010" y="142" class="t h2">外部依赖系统(系统边界外 · 各标接入度)</text>
|
||||
|
||||
<!-- new-api → 便宜 LLM(已接)-->
|
||||
<rect x="1010" y="156" width="430" height="58" rx="10" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.7"/>
|
||||
<text x="1020" y="176" class="t lbl">new-api 网关 → 便宜 LLM(DeepSeek / MiniMax)</text>
|
||||
<text x="1404" y="176" class="stOn" text-anchor="end">已接</text>
|
||||
<text x="1020" y="194" class="xxs mut">生成主线:SAA 经 OpenAI 兼容接口调模型 · 单 key 入计费台账</text>
|
||||
<text x="1020" y="208" class="xxs mut">部署在 mini-infra · 多通道兜底(二厂系全废已实战)</text>
|
||||
|
||||
<!-- mmx / MiniMax 素材(已接)-->
|
||||
<rect x="1010" y="222" width="430" height="52" rx="10" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.7"/>
|
||||
<text x="1020" y="242" class="t lbl">mmx-cli / MiniMax(图 / 音 / 封面素材生成)</text>
|
||||
<text x="1404" y="242" class="stOn" text-anchor="end">已接</text>
|
||||
<text x="1020" y="260" class="xxs mut">agent 造游戏直接 CLI 调 · 免 GPU 免训练 · 成本入同一台账</text>
|
||||
|
||||
<!-- OSS / CDN -->
|
||||
<rect x="1010" y="282" width="430" height="52" rx="10" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.7"/>
|
||||
<text x="1020" y="302" class="t lbl">对象存储 / CDN(MinIO 内网 · 阿里云 OSS 生产)</text>
|
||||
<text x="1404" y="302" class="stWait" text-anchor="end">MinIO 已接 · OSS 远期</text>
|
||||
<text x="1020" y="320" class="xxs mut">游戏包 / 素材 / 封面;MVP 整包内嵌 DB,无 OSS 也可跑</text>
|
||||
|
||||
<!-- Gitea(已接)-->
|
||||
<rect x="1010" y="342" width="430" height="52" rx="10" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.7"/>
|
||||
<text x="1020" y="362" class="t lbl">Gitea 代码仓(Aliyun · 101.200.34.71)</text>
|
||||
<text x="1404" y="362" class="stOn" text-anchor="end">已接</text>
|
||||
<text x="1020" y="380" class="xxs mut">代码同步中转:push :2222 / 匿名 clone :3000 → mini-desktop 重建</text>
|
||||
|
||||
<!-- 广告联盟(待接)-->
|
||||
<rect x="1010" y="402" width="430" height="52" rx="10" fill="#fff7ed" stroke="#d97706" stroke-width="1.6" stroke-dasharray="6 4"/>
|
||||
<text x="1020" y="422" class="t lbl">广告联盟(穿山甲 CSJ / 优量汇 GDT)</text>
|
||||
<text x="1404" y="422" class="stWait" text-anchor="end">待接</text>
|
||||
<text x="1020" y="440" class="xxs mut">现 provider=mock;真 SDK 接入待广告资质 + 渠道落地</text>
|
||||
|
||||
<!-- 微信/抖音渠道(远期)-->
|
||||
<rect x="1010" y="462" width="430" height="52" rx="10" fill="#faf5ff" stroke="#7c3aed" stroke-width="1.6" stroke-dasharray="6 4"/>
|
||||
<text x="1020" y="482" class="t lbl">微信 / 抖音小游戏渠道</text>
|
||||
<text x="1404" y="482" class="stFut" text-anchor="end">远期</text>
|
||||
<text x="1020" y="500" class="xxs mut">一壳多游 L1 精选整包 · 备案锁约束 · 引擎竞标未决</text>
|
||||
|
||||
<!-- 支付商户(待接)-->
|
||||
<rect x="1010" y="522" width="430" height="52" rx="10" fill="#fff7ed" stroke="#d97706" stroke-width="1.6" stroke-dasharray="6 4"/>
|
||||
<text x="1020" y="542" class="t lbl">支付商户(微信支付 / 提现打款通道)</text>
|
||||
<text x="1404" y="542" class="stWait" text-anchor="end">待接</text>
|
||||
<text x="1020" y="560" class="xxs mut">pay 模块未接入单体 · 进件待 ICP;缺渠道打款 fail-fast</text>
|
||||
|
||||
<!-- 短信(待接)-->
|
||||
<rect x="1010" y="582" width="430" height="52" rx="10" fill="#fff7ed" stroke="#d97706" stroke-width="1.6" stroke-dasharray="6 4"/>
|
||||
<text x="1020" y="602" class="t lbl">短信服务(验证码 / 通知下发)</text>
|
||||
<text x="1404" y="602" class="stWait" text-anchor="end">待接</text>
|
||||
<text x="1020" y="620" class="xxs mut">登录验证码 / 关键通知 · 待短信签名报备闸门</text>
|
||||
|
||||
<!-- 平台 → 依赖 箭头 -->
|
||||
<!-- 已接:实线 -->
|
||||
<line x1="982" y1="200" x2="1008" y2="185" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="982" y1="240" x2="1008" y2="248" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="982" y1="300" x2="1008" y2="308" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="982" y1="360" x2="1008" y2="368" class="flow" marker-end="url(#arrow)"/>
|
||||
<!-- 待接:虚线 -->
|
||||
<line x1="982" y1="420" x2="1008" y2="428" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<line x1="982" y1="540" x2="1008" y2="548" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<line x1="982" y1="600" x2="1008" y2="608" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<!-- 远期:紫虚线 -->
|
||||
<line x1="982" y1="480" x2="1008" y2="488" class="flowp" marker-end="url(#arrowP)"/>
|
||||
|
||||
<!-- ===== 图例 ===== -->
|
||||
<text x="40" y="668" class="t h2">图例:</text>
|
||||
<rect x="116" y="654" width="34" height="20" rx="5" fill="#f0fdf4" stroke="#16a34a" stroke-width="1.8"/><text x="158" y="669" class="t xs">已接(现行已联通调用)</text>
|
||||
<rect x="330" y="654" width="34" height="20" rx="5" fill="#fff7ed" stroke="#d97706" stroke-width="1.8" stroke-dasharray="6 4"/><text x="372" y="669" class="t xs">待接(设计已定 · 闸门 / 进件阻塞)</text>
|
||||
<rect x="620" y="654" width="34" height="20" rx="5" fill="#faf5ff" stroke="#7c3aed" stroke-width="1.8" stroke-dasharray="6 4"/><text x="662" y="669" class="t xs">远期(排期更后 / 竞标未决)</text>
|
||||
<rect x="900" y="654" width="34" height="20" rx="5" fill="#eef2ff" stroke="#1d4ed8" stroke-width="2"/><text x="942" y="669" class="t xs">系统边界内(绘境AI 平台单体)</text>
|
||||
|
||||
<!-- ===== 一眼看出 ===== -->
|
||||
<rect x="40" y="690" width="1400" height="76" rx="10" fill="#f1f5f9" stroke="#475569" stroke-width="1.4"/>
|
||||
<text x="52" y="711" class="t h2">新人一眼看出:</text>
|
||||
<text x="52" y="730" class="xs mut">① 系统边界 = 绘境AI 单体(含自建 MySQL / Redis);MySQL / Redis 是边界内自建组件、不是外部依赖,所以不画在右侧。</text>
|
||||
<text x="52" y="746" class="xs mut">② 对外只有两类联通是"现行已接":生成 / 素材(new-api · mmx)与代码 / 存储底座(Gitea · MinIO);变现侧的广告、渠道、支付、短信全是待接 / 远期。</text>
|
||||
<text x="52" y="762" class="xs mut">③ 这正是运营域那条"合规闸门是总闸"在依赖边界上的投影——能赚钱的几条外部线,都卡在 ICP / 资质 / 备案这些日历闸门后面,绝不能读成已接。</text>
|
||||
|
||||
<text x="40" y="800" class="t h2">为什么这样切边界:</text>
|
||||
<text x="40" y="820" class="xs mut">平台把"不差异化但耗时"的能力(后台框架 Huijing、大模型、引擎、素材)全用外部现成件,边界内只留真正的护城河(生成编排 / 流量分发 / 收益闭环 / 数据飞轮)——这就是"5 人 + ¥4,300/月"能跑起来的取舍。</text>
|
||||
<text x="40" y="838" class="xs mut">出网只走受控网关、key 不裸暴露、游戏侧 CSP 禁网,是把"系统边界"同时当成安全边界来守:不可信的游戏代码与不可信的外部头,都在边界上被换成可信形态。</text>
|
||||
|
||||
<text x="40" y="860" class="mut xs">映射:架构/README §1·§2 + 运维/README §1.1 四机 + 运营/README §2 合规闸门 + 内网凭据与端点 | 状态:现 + 接(外部依赖三态已标)| 设计变动须同步本图</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
179
docs/architecture/架构/assets/arch-13-逻辑物理拓扑.svg
Normal file
179
docs/architecture/架构/assets/arch-13-逻辑物理拓扑.svg
Normal file
@ -0,0 +1,179 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1480 900" font-family="-apple-system,'PingFang SC','Microsoft YaHei',Segoe UI,sans-serif">
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#334155"/></marker>
|
||||
<marker id="arrowF" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#7c3aed"/></marker>
|
||||
<style>
|
||||
.t{fill:#0f172a}.mut{fill:#475569}.sm{font-size:12px}.xs{font-size:11px}.xxs{font-size:10px}
|
||||
.h1{font-size:24px;font-weight:700}.h2{font-size:14px;font-weight:700}.lbl{font-size:13px;font-weight:600}
|
||||
.flow{stroke:#334155;stroke-width:2;fill:none}.flowb{stroke:#64748b;stroke-width:1.6;fill:none;stroke-dasharray:6 4}
|
||||
.flowf{stroke:#7c3aed;stroke-width:1.8;fill:none;stroke-dasharray:7 5}
|
||||
.badge{font-size:10.5px;font-weight:700}.warn{font-size:10px;font-weight:700;fill:#b91c1c}.fut{font-size:10px;font-weight:700;fill:#6d28d9}
|
||||
.mono{font-family:'SF Mono',Menlo,Consolas,monospace}
|
||||
</style>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="1480" height="900" fill="#f8fafc"/>
|
||||
<text x="40" y="38" class="t h1">图 13 · 13 逻辑模块 → 单体物理打包 / 运行拓扑</text>
|
||||
<text x="40" y="58" class="mut sm">破除「13 模块 = 13 微服务」的误解:13 个逻辑模块按领域各自独立,物理上聚合进同一个 JAR、跑成单一进程;依赖方向就是未来微服务的天然切割线。</text>
|
||||
|
||||
<!-- 状态约定条 -->
|
||||
<rect x="40" y="74" width="1400" height="32" rx="8" fill="#f1f5f9" stroke="#475569" stroke-width="1.3"/>
|
||||
<text x="52" y="95" class="xs t" font-weight="700">读图约定:</text>
|
||||
<text x="135" y="95" class="xs mut">实线绿/蓝块 = 现行已建并打进单体;橙虚线 = 当前未接入单体启动器(pay);紫虚线 + 「远期」= 未来微服务拆分形态,当前不做。本图整体状态 = 现,仅右栏拆分愿景为远期。</text>
|
||||
|
||||
<!-- 左:13 逻辑模块(领域独立) -->
|
||||
<rect x="40" y="124" width="470" height="540" rx="12" fill="#ffffff" stroke="#475569" stroke-width="2"/>
|
||||
<text x="55" y="148" class="t h2">逻辑视图 · 13 个领域模块(各自独立)</text>
|
||||
<text x="55" y="166" class="xs mut">按领域边界切分;每个模块 = 一个独立领域 + -api / -server 两段式 jar</text>
|
||||
|
||||
<!-- 两段式 jar 说明小卡 -->
|
||||
<rect x="55" y="178" width="440" height="40" rx="8" fill="#eff6ff" stroke="#2563eb" stroke-width="1.2"/>
|
||||
<text x="65" y="196" class="xs t" font-weight="700">两段式 jar:</text>
|
||||
<text x="150" y="196" class="xs mut">-api 包 = 只声明 DTO + Feign 接口(跨模块只认它)</text>
|
||||
<text x="65" y="211" class="xs mut">-server 包 = 实现;模块间只经对方 -api 单向调用,零反向依赖</text>
|
||||
|
||||
<!-- 四簇模块 -->
|
||||
<rect x="55" y="228" width="440" height="86" rx="9" fill="#f8fafc" stroke="#334155" stroke-width="1.3"/>
|
||||
<text x="65" y="247" class="t lbl">创作链路</text>
|
||||
<rect x="65" y="256" width="102" height="48" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="73" y="274" class="xs t" font-weight="700">studio</text><text x="73" y="290" class="xxs mut">创作编排</text><text x="73" y="302" class="xxs mut">STU</text>
|
||||
<rect x="173" y="256" width="102" height="48" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="181" y="274" class="xs t" font-weight="700">aigc</text><text x="181" y="290" class="xxs mut">生成原子</text><text x="181" y="302" class="xxs mut">AGC</text>
|
||||
<rect x="281" y="256" width="102" height="48" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="289" y="274" class="xs t" font-weight="700">runtime</text><text x="289" y="290" class="xxs mut">编译沙箱</text><text x="289" y="302" class="xxs mut">RT</text>
|
||||
<rect x="389" y="256" width="98" height="48" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="397" y="274" class="xs t" font-weight="700">project</text><text x="397" y="290" class="xxs mut">项目生命周期</text><text x="397" y="302" class="xxs mut">PRJ</text>
|
||||
|
||||
<rect x="55" y="324" width="440" height="62" rx="9" fill="#f8fafc" stroke="#334155" stroke-width="1.3"/>
|
||||
<text x="65" y="343" class="t lbl">分发与数据</text>
|
||||
<rect x="65" y="352" width="155" height="28" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="73" y="371" class="xs t" font-weight="700">feed · FED</text>
|
||||
<rect x="226" y="352" width="155" height="28" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="234" y="371" class="xs t" font-weight="700">telemetry · TEL</text>
|
||||
|
||||
<rect x="55" y="396" width="440" height="86" rx="9" fill="#f8fafc" stroke="#334155" stroke-width="1.3"/>
|
||||
<text x="65" y="415" class="t lbl">变现链路</text>
|
||||
<rect x="65" y="424" width="135" height="48" rx="7" fill="#fff7ed" stroke="#d97706" stroke-width="1.4" stroke-dasharray="6 4"/>
|
||||
<text x="73" y="442" class="xs t" font-weight="700">pay · PAY</text><text x="73" y="458" class="xxs warn">未接单体 ↓</text><text x="73" y="470" class="xxs mut">huijing 原生</text>
|
||||
<rect x="206" y="424" width="135" height="48" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="214" y="442" class="xs t" font-weight="700">trade · TRD</text><text x="214" y="458" class="xxs mut">分账结算</text>
|
||||
<rect x="347" y="424" width="140" height="48" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="355" y="442" class="xs t" font-weight="700">ad · AD</text><text x="355" y="458" class="xxs mut">广告计费</text>
|
||||
|
||||
<rect x="55" y="492" width="440" height="86" rx="9" fill="#f8fafc" stroke="#334155" stroke-width="1.3"/>
|
||||
<text x="65" y="511" class="t lbl">平台与合规</text>
|
||||
<rect x="65" y="520" width="100" height="48" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="73" y="538" class="xs t" font-weight="700">community</text><text x="73" y="554" class="xxs mut">社交通知</text><text x="73" y="566" class="xxs mut">CMU</text>
|
||||
<rect x="171" y="520" width="100" height="48" rx="7" fill="#eef2ff" stroke="#6366f1" stroke-width="1.4" stroke-dasharray="6 4"/>
|
||||
<text x="179" y="538" class="xs t" font-weight="700">ip · IP</text><text x="179" y="554" class="xxs fut">seam 寄宿</text><text x="179" y="566" class="xxs mut">于 compliance</text>
|
||||
<rect x="277" y="520" width="104" height="48" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="285" y="538" class="xs t" font-weight="700">compliance</text><text x="285" y="554" class="xxs mut">安全裁决</text><text x="285" y="566" class="xxs mut">CMP</text>
|
||||
<rect x="387" y="520" width="100" height="48" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="395" y="538" class="xs t" font-weight="700">biz · BIZ</text><text x="395" y="554" class="xxs mut">B/G 定制</text>
|
||||
|
||||
<text x="55" y="600" class="xs mut">这 13 个是逻辑划分:对内一件完整的事,对外只露窄接口。它们各自独立,</text>
|
||||
<text x="55" y="618" class="xs t" font-weight="700">但物理上不是 13 个进程 —— 右侧看它们怎么聚成一个。</text>
|
||||
<text x="55" y="640" class="xxs mut">注:ip 不独立建模块、以 seam 寄宿 compliance(D5 裁定);pay 是 huijing 原生模块、</text>
|
||||
<text x="55" y="654" class="xxs mut">当前在启动器里被显式注释排除。两者状态以 13模块.md §4 为准。</text>
|
||||
|
||||
<!-- 中:聚合成单体 -->
|
||||
<rect x="540" y="124" width="470" height="540" rx="12" fill="#ffffff" stroke="#475569" stroke-width="2"/>
|
||||
<text x="555" y="148" class="t h2">物理视图 · 聚合进一个 JAR、跑成一个进程</text>
|
||||
<text x="555" y="166" class="xs mut">MVP = 单体启动:所有模块编译进同一个 JAR,用 Spring Profile 控加载</text>
|
||||
|
||||
<!-- 聚合漏斗示意 -->
|
||||
<line x1="510" y1="270" x2="555" y2="330" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="510" y1="360" x2="555" y2="350" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="510" y1="450" x2="555" y2="370" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="510" y1="540" x2="555" y2="390" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="512" y="300" class="xxs mut">jar 聚合</text>
|
||||
|
||||
<!-- game-server JAR -->
|
||||
<rect x="555" y="190" width="440" height="200" rx="11" fill="#f0fdf4" stroke="#16a34a" stroke-width="2.2"/>
|
||||
<text x="570" y="214" class="t h2">单一物理 JAR:game-server</text>
|
||||
<text x="570" y="232" class="xs mut">13 个 -server jar + huijing 基座 jar 全部编译进它,一个 main 启动</text>
|
||||
<rect x="570" y="244" width="410" height="62" rx="8" fill="#dcfce7" stroke="#16a34a" stroke-width="1.3"/>
|
||||
<text x="580" y="263" class="xs t" font-weight="700">同一 JVM 进程 · 同一份 application.yaml · 同一套 MySQL/Redis 连接池</text>
|
||||
<text x="580" y="281" class="xs mut">模块间调用 = 进程内方法调用(不走网络),逻辑独立但物理共址</text>
|
||||
<text x="580" y="298" class="xs t" font-weight="700">不存在 split-brain:全仓单写、一份代码一份库,不会两套各跑各的</text>
|
||||
<rect x="570" y="314" width="410" height="62" rx="8" fill="#eff6ff" stroke="#2563eb" stroke-width="1.3"/>
|
||||
<text x="580" y="333" class="xs t" font-weight="700">Spring Profile 控各模块加载 / 排除:</text>
|
||||
<text x="580" y="350" class="xxs mut">@ComponentScan / starter 装配按 profile 决定哪些 -server 进上下文;</text>
|
||||
<text x="580" y="366" class="xxs warn">pay 的 server 启动器里被显式「注释排除」出装配 —— 故未接入单体</text>
|
||||
|
||||
<!-- 运行拓扑 -->
|
||||
<rect x="555" y="402" width="440" height="118" rx="11" fill="#f8fafc" stroke="#334155" stroke-width="1.4"/>
|
||||
<text x="570" y="424" class="t lbl">运行拓扑:单进程 + 共享中间件</text>
|
||||
<rect x="570" y="436" width="120" height="40" rx="7" fill="#dcfce7" stroke="#16a34a" stroke-width="1.2"/>
|
||||
<text x="580" y="455" class="xs t" font-weight="700">game-server</text><text x="580" y="470" class="xxs mut">单进程</text>
|
||||
<line x1="690" y1="456" x2="742" y2="456" class="flow" marker-end="url(#arrow)"/>
|
||||
<rect x="744" y="436" width="110" height="40" rx="7" fill="#f1f5f9" stroke="#475569" stroke-width="1.2"/>
|
||||
<text x="754" y="455" class="xs t" font-weight="700">MySQL 8.0</text><text x="754" y="470" class="xxs mut">单库多表</text>
|
||||
<rect x="862" y="436" width="118" height="40" rx="7" fill="#f1f5f9" stroke="#475569" stroke-width="1.2"/>
|
||||
<text x="872" y="455" class="xs t" font-weight="700">Redis 7</text><text x="872" y="470" class="xxs mut">缓存/幂等键</text>
|
||||
<text x="570" y="496" class="xxs mut">Nginx → Gateway → game-server 单进程;Nacos/RocketMQ 框架自带但 MVP</text>
|
||||
<text x="570" y="510" class="xxs mut">未启 broker/registry,故无服务注册发现、无 MQ —— 进程内调用即可。</text>
|
||||
|
||||
<text x="555" y="546" class="xs t" font-weight="700">为什么先单体:复用 Huijing 60% 后台、一个进程一套部署,团队小、成本低。</text>
|
||||
<text x="555" y="566" class="xs mut">逻辑边界已按领域切清,等流量与团队涨上来,再沿边界平滑拆出去(见右)。</text>
|
||||
<text x="555" y="588" class="xxs mut">证据:单体真启动、Flyway V1–V25 全绿、12 份契约 yaml 锁定、project 真原子跨表发布。</text>
|
||||
<text x="555" y="606" class="xxs mut">(运行实测见 docs/mvp/MVP进度总账.md;本图只画拓扑形状。)</text>
|
||||
|
||||
<!-- 右:远期微服务切割线 -->
|
||||
<rect x="1040" y="124" width="400" height="540" rx="12" fill="#faf5ff" stroke="#7c3aed" stroke-width="1.8" stroke-dasharray="7 5"/>
|
||||
<text x="1055" y="148" class="t h2" fill="#6d28d9">远期 · 沿依赖方向拆 N 个微服务</text>
|
||||
<text x="1055" y="166" class="fut">登记为演进路径 · 当前不做、不预先实现</text>
|
||||
|
||||
<text x="1055" y="192" class="xs mut">关键洞见:模块间的</text>
|
||||
<text x="1175" y="192" class="xs t" font-weight="700">单向依赖方向</text>
|
||||
<text x="1268" y="192" class="xs mut">就是未来</text>
|
||||
<text x="1055" y="208" class="xs t" font-weight="700">微服务拆分的天然切割线 —— 依赖边界 = 拆分边界。</text>
|
||||
|
||||
<line x1="1015" y1="290" x2="1055" y2="260" class="flowf" marker-end="url(#arrowF)"/>
|
||||
<text x="1018" y="280" class="xxs fut">沿边界切</text>
|
||||
|
||||
<rect x="1055" y="232" width="180" height="48" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4" stroke-dasharray="6 4"/>
|
||||
<text x="1065" y="251" class="xs t" font-weight="700">创作生成服务</text><text x="1065" y="268" class="xxs mut">studio + aigc + runtime</text>
|
||||
<rect x="1245" y="232" width="186" height="48" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4" stroke-dasharray="6 4"/>
|
||||
<text x="1255" y="251" class="xs t" font-weight="700">分发数据服务</text><text x="1255" y="268" class="xxs mut">feed + telemetry</text>
|
||||
<rect x="1055" y="288" width="180" height="48" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4" stroke-dasharray="6 4"/>
|
||||
<text x="1065" y="307" class="xs t" font-weight="700">资金变现服务</text><text x="1065" y="324" class="xxs mut">pay + trade + ad</text>
|
||||
<rect x="1245" y="288" width="186" height="48" rx="8" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4" stroke-dasharray="6 4"/>
|
||||
<text x="1255" y="307" class="xs t" font-weight="700">合规社区服务</text><text x="1255" y="324" class="xxs mut">compliance + ip + community + biz</text>
|
||||
|
||||
<rect x="1055" y="356" width="376" height="120" rx="9" fill="#ffffff" stroke="#7c3aed" stroke-width="1.3" stroke-dasharray="6 4"/>
|
||||
<text x="1065" y="376" class="xs t" font-weight="700">拆分时几乎零返工,因为已经备好:</text>
|
||||
<text x="1065" y="394" class="xxs mut">· 每模块已是 -api / -server 两段,-api 现成可变 Feign 远程契约</text>
|
||||
<text x="1065" y="410" class="xxs mut">· 依赖单向、零反向引用,按簇切不会切出环</text>
|
||||
<text x="1065" y="426" class="xxs mut">· Nacos(注册发现)+ RocketMQ(异步解耦)框架已自带,届时启用即可</text>
|
||||
<text x="1065" y="442" class="xxs mut">· 进程内方法调用 → 网络调用,调用方代码基本不动</text>
|
||||
<text x="1065" y="462" class="fut">触发时机:流量 / 团队涨上来、单体压不住时;不是越早拆越好。</text>
|
||||
|
||||
<text x="1055" y="500" class="xs mut">这四簇只是「切割线长这样」的示意分组,</text>
|
||||
<text x="1055" y="518" class="xs mut">真正拆几个、怎么拆,到那时按当下负载与组织再定。</text>
|
||||
<text x="1055" y="544" class="warn">⚠ 这一栏整体是远期愿景,不是现行架构 —— 现在仍是中间那个单进程。</text>
|
||||
|
||||
<!-- 三视图横向关系箭头 -->
|
||||
<line x1="510" y1="690" x2="540" y2="690" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="1010" y1="690" x2="1040" y2="690" class="flowf" marker-end="url(#arrowF)"/>
|
||||
<text x="250" y="686" class="xs t" font-weight="700">逻辑独立</text>
|
||||
<text x="515" y="686" class="xs mut">jar 聚合 →</text>
|
||||
<text x="760" y="686" class="xs t" font-weight="700">物理单体(现行)</text>
|
||||
<text x="1014" y="686" class="xs mut">沿边界 →</text>
|
||||
<text x="1200" y="686" class="xs t" font-weight="700" fill="#6d28d9">微服务(远期)</text>
|
||||
|
||||
<!-- 图例 -->
|
||||
<text x="40" y="730" class="t h2">图例:</text>
|
||||
<rect x="120" y="716" width="34" height="20" rx="5" fill="#dcfce7" stroke="#16a34a" stroke-width="1.3"/><text x="162" y="731" class="t xs">现行已建 · 打进单体</text>
|
||||
<rect x="320" y="716" width="34" height="20" rx="5" fill="#fff7ed" stroke="#d97706" stroke-width="1.4" stroke-dasharray="6 4"/><text x="362" y="731" class="t xs">未接单体启动器(pay)</text>
|
||||
<rect x="560" y="716" width="34" height="20" rx="5" fill="#eef2ff" stroke="#6366f1" stroke-width="1.4" stroke-dasharray="6 4"/><text x="602" y="731" class="t xs">seam 寄宿(ip)</text>
|
||||
<rect x="740" y="716" width="34" height="20" rx="5" fill="#f5f3ff" stroke="#7c3aed" stroke-width="1.4" stroke-dasharray="6 4"/><text x="782" y="731" class="t xs">远期微服务形态(不做)</text>
|
||||
<line x1="970" y1="726" x2="1016" y2="726" class="flow" marker-end="url(#arrow)"/><text x="1024" y="730" class="t xs">现行聚合/依赖</text>
|
||||
<line x1="1160" y1="726" x2="1206" y2="726" class="flowf" marker-end="url(#arrowF)"/><text x="1214" y="730" class="t xs">远期拆分</text>
|
||||
|
||||
<!-- 徽章 -->
|
||||
<g class="badge"><rect x="120" y="752" width="56" height="18" rx="3" fill="#16a34a"/><text x="125" y="765" fill="#fff">成本</text>
|
||||
<rect x="184" y="752" width="56" height="18" rx="3" fill="#7c3aed"/><text x="189" y="765" fill="#fff">伸缩</text></g>
|
||||
<text x="252" y="765" class="mut xs">单体 = 团队小 / 部署省 / 复用 Huijing(成本);逻辑边界即切割线 = 平滑长成微服务(伸缩)。</text>
|
||||
|
||||
<text x="40" y="800" class="mut xs">映射:架构/README.md §3(jar 聚合单体 / Spring Profile / pay 排除)+ 架构/13模块.md §1(逻辑独立 · 物理单体 · 无 split-brain · 状态总表) | 状态:现(右栏微服务拆分为远期) | 设计变动须同步本图</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 17 KiB |
175
docs/architecture/架构/assets/arch-14-模块状态热力.svg
Normal file
175
docs/architecture/架构/assets/arch-14-模块状态热力.svg
Normal file
@ -0,0 +1,175 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1480 880" font-family="-apple-system,'PingFang SC','Microsoft YaHei',Segoe UI,sans-serif">
|
||||
<defs>
|
||||
<style>
|
||||
.t{fill:#0f172a}.mut{fill:#475569}.sm{font-size:12px}.xs{font-size:11px}.xxs{font-size:10px}
|
||||
.h1{font-size:24px;font-weight:700}.h2{font-size:14px;font-weight:700}.lbl{font-size:13px;font-weight:600}
|
||||
.badge{font-size:10.5px;font-weight:700}.warn{font-size:10px;font-weight:700;fill:#b91c1c}
|
||||
.gap{font-size:10px;fill:#475569}
|
||||
</style>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="1480" height="880" fill="#f8fafc"/>
|
||||
<text x="40" y="38" class="t h1">图 14 · 13 模块 真 / 桩 / 未建 状态热力图</text>
|
||||
<text x="40" y="58" class="mut sm">在四簇聚类底图上按颜色叠加每个模块的真实建设状态,并在每块标出它「最大的那道缺口」—— 一眼看出哪里能用、哪里是债。</text>
|
||||
|
||||
<!-- 口径约定条 -->
|
||||
<rect x="40" y="74" width="1400" height="34" rx="8" fill="#fffbeb" stroke="#d97706" stroke-width="1.4"/>
|
||||
<text x="52" y="96" class="xs t" font-weight="700">口径铁律:</text>
|
||||
<text x="140" y="96" class="xs mut">本图状态以 docs/mvp/MVP进度总账.md 为准(实时最高口径);结构 / 实现 / 状态三者冲突时,优先级 = </text>
|
||||
<text x="1010" y="96" class="xs t" font-weight="700">状态 > 实现 > 结构</text>
|
||||
<text x="1140" y="96" class="xs mut">。颜色 = 状态,不是结构权威。</text>
|
||||
|
||||
<!-- 颜色图例(顶部,先建立解码) -->
|
||||
<rect x="40" y="120" width="1400" height="40" rx="8" fill="#ffffff" stroke="#475569" stroke-width="1.3"/>
|
||||
<text x="52" y="145" class="t lbl">颜色解码:</text>
|
||||
<rect x="150" y="130" width="22" height="22" rx="5" fill="#16a34a"/><text x="180" y="145" class="t xs" font-weight="700">✅ 完成 ×5</text><text x="270" y="145" class="xs mut">真端到端、可验收</text>
|
||||
<rect x="430" y="130" width="22" height="22" rx="5" fill="#facc15"/><text x="460" y="145" class="t xs" font-weight="700">🟡 部分 ×6</text><text x="550" y="145" class="xs mut">有壳 / 半真 / 部分接线</text>
|
||||
<rect x="760" y="130" width="22" height="22" rx="5" fill="#cbd5e1"/><text x="790" y="145" class="t xs" font-weight="700">◻ 特殊 ×2</text><text x="880" y="145" class="xs mut">seam 寄宿 / 未接单体</text>
|
||||
<rect x="1130" y="130" width="22" height="22" rx="5" fill="#f87171"/><text x="1160" y="145" class="t xs" font-weight="700">🔴 纯未建 ×0</text><text x="1280" y="145" class="xs mut">(当前为 0)</text>
|
||||
|
||||
<!-- 簇1 创作链路 -->
|
||||
<rect x="40" y="176" width="700" height="232" rx="12" fill="#ffffff" stroke="#475569" stroke-width="2"/>
|
||||
<text x="55" y="200" class="t h2">创作链路 · 把游戏做出来</text>
|
||||
|
||||
<!-- project ✅ -->
|
||||
<rect x="55" y="212" width="328" height="86" rx="9" fill="#f0fdf4" stroke="#16a34a" stroke-width="2"/>
|
||||
<rect x="55" y="212" width="8" height="86" rx="3" fill="#16a34a"/>
|
||||
<text x="72" y="232" class="t lbl">project · 项目生命周期 ✅ 完成</text>
|
||||
<text x="72" y="250" class="xxs mut">全仓最成熟:状态机 + 唯一真原子跨表发布编排 + 审核队列真查库</text>
|
||||
<text x="72" y="270" class="gap" font-weight="700">最大缺口:</text>
|
||||
<text x="135" y="270" class="gap">Zone 无独立实体(字段承载,MVP 有意简化)</text>
|
||||
<text x="72" y="288" class="xxs mut">PRJ · 创作链路的状态收口与原子发布脊柱</text>
|
||||
|
||||
<!-- aigc 🟡 -->
|
||||
<rect x="397" y="212" width="328" height="86" rx="9" fill="#fefce8" stroke="#ca8a04" stroke-width="2"/>
|
||||
<rect x="397" y="212" width="8" height="86" rx="3" fill="#facc15"/>
|
||||
<text x="414" y="232" class="t lbl">aigc · 无状态生成原子 🟡 部分</text>
|
||||
<text x="414" y="250" class="xxs mut">执行器主链真(M2 e2e:一句话 18–27s 可玩,约 80% 成功)</text>
|
||||
<text x="414" y="270" class="warn">最大缺口:</text>
|
||||
<text x="477" y="270" class="gap" font-weight="700">W-G1 worker 尚未接为 staging 默认产线</text>
|
||||
<text x="414" y="288" class="xxs mut">SAA 控制平面「建成未默认生产」;玩法模板注册未建(护城河关键路径)</text>
|
||||
|
||||
<!-- runtime 🟡 -->
|
||||
<rect x="55" y="308" width="328" height="86" rx="9" fill="#fefce8" stroke="#ca8a04" stroke-width="2"/>
|
||||
<rect x="55" y="308" width="8" height="86" rx="3" fill="#facc15"/>
|
||||
<text x="72" y="328" class="t lbl">runtime · 编译 / 沙箱 / 发布 🟡 部分</text>
|
||||
<text x="72" y="346" class="xxs mut">存包 / 取包、engineBundle 内嵌、沙箱桥接都是真的</text>
|
||||
<text x="72" y="366" class="warn">最大缺口:</text>
|
||||
<text x="135" y="366" class="gap" font-weight="700">真实编译引擎目前是桩</text>
|
||||
<text x="72" y="384" class="xxs mut">微信 / 抖音 / 快手 / TapTap 渠道转换未建;OSS 存取也是桩</text>
|
||||
|
||||
<!-- studio 🟡 -->
|
||||
<rect x="397" y="308" width="328" height="86" rx="9" fill="#fefce8" stroke="#ca8a04" stroke-width="2"/>
|
||||
<rect x="397" y="308" width="8" height="86" rx="3" fill="#facc15"/>
|
||||
<text x="414" y="328" class="t lbl">studio · 创作编排 / 编辑器域 🟡 部分</text>
|
||||
<text x="414" y="346" class="xxs mut">创作编排委托层真(草稿装配 + aigc 接缝 + 血缘追溯)</text>
|
||||
<text x="414" y="366" class="warn">最大缺口:</text>
|
||||
<text x="477" y="366" class="gap" font-weight="700">「7 步生成链」其实在 aigc SAA 图、不在 studio</text>
|
||||
<text x="414" y="384" class="xxs mut">六类资产 / 角色 rig / 对白树 / 可视化编排目前全是桩</text>
|
||||
|
||||
<!-- 簇2 分发与数据 -->
|
||||
<rect x="756" y="176" width="684" height="232" rx="12" fill="#ffffff" stroke="#475569" stroke-width="2"/>
|
||||
<text x="771" y="200" class="t h2">分发与数据 · 让游戏被玩到、被看清</text>
|
||||
|
||||
<!-- feed 🟡 -->
|
||||
<rect x="771" y="212" width="650" height="86" rx="9" fill="#fefce8" stroke="#ca8a04" stroke-width="2"/>
|
||||
<rect x="771" y="212" width="8" height="86" rx="3" fill="#facc15"/>
|
||||
<text x="788" y="232" class="t lbl">feed · 游戏流推荐 / 互动 / 分享 🟡 部分</text>
|
||||
<text x="788" y="250" class="xxs mut">互动信号、getZones、quality 排序都是真的(B2 已 e2e 实证「互动回灌翻转排序」)</text>
|
||||
<text x="788" y="270" class="warn">最大缺口:</text>
|
||||
<text x="851" y="270" class="gap" font-weight="700">游标分页是桩(永远返回第一页)</text>
|
||||
<text x="788" y="288" class="xxs mut">候选集纯查 MySQL、无 Redis;举报转 compliance 也是桩</text>
|
||||
|
||||
<!-- telemetry ✅ -->
|
||||
<rect x="771" y="308" width="650" height="86" rx="9" fill="#f0fdf4" stroke="#16a34a" stroke-width="2"/>
|
||||
<rect x="771" y="308" width="8" height="86" rx="3" fill="#16a34a"/>
|
||||
<text x="788" y="328" class="t lbl">telemetry · 事件聚合 / 质量评分 ✅ 完成</text>
|
||||
<text x="788" y="346" class="xxs mut">唯一真端到端数据底座:事件落库 + quality 真算分 + 日聚合 upsert + 创作者 stats 全打通</text>
|
||||
<text x="788" y="366" class="gap" font-weight="700">最大缺口:</text>
|
||||
<text x="851" y="366" class="gap">MQ 异步聚合 = 桩(有意);广告营收字段占位</text>
|
||||
<text x="788" y="384" class="xxs mut">TEL · 平台「越用越聪明」的数据回路源头</text>
|
||||
|
||||
<!-- 簇3 变现链路 -->
|
||||
<rect x="40" y="424" width="700" height="232" rx="12" fill="#ffffff" stroke="#475569" stroke-width="2"/>
|
||||
<text x="55" y="448" class="t h2">变现链路 · 把钱赚回来</text>
|
||||
|
||||
<!-- pay ◻ -->
|
||||
<rect x="55" y="460" width="328" height="86" rx="9" fill="#f1f5f9" stroke="#64748b" stroke-width="2" stroke-dasharray="6 4"/>
|
||||
<rect x="55" y="460" width="8" height="86" rx="3" fill="#cbd5e1"/>
|
||||
<text x="72" y="480" class="t lbl">pay · 支付收单 ◻ 未接单体</text>
|
||||
<text x="72" y="498" class="xxs mut">yudao 原生模块,server 启动器里被显式注释排除</text>
|
||||
<text x="72" y="518" class="warn">最大缺口:</text>
|
||||
<text x="135" y="518" class="gap" font-weight="700">真实支付收单全未接入</text>
|
||||
<text x="72" y="536" class="xxs mut">卡在「支付进件」这类不可压缩的日历闸门(须等监管 / 渠道审批)</text>
|
||||
|
||||
<!-- trade ✅ -->
|
||||
<rect x="397" y="460" width="328" height="86" rx="9" fill="#f0fdf4" stroke="#16a34a" stroke-width="2"/>
|
||||
<rect x="397" y="460" width="8" height="86" rx="3" fill="#16a34a"/>
|
||||
<text x="414" y="480" class="t lbl">trade · 分账 / 结算 / 对账 ✅ 完成</text>
|
||||
<text x="414" y="498" class="xxs mut">资金状态机真(逐笔入账 + 冻结 CAS + 对账补偿),41 单测;打款 fail-fast 防假钱</text>
|
||||
<text x="414" y="518" class="gap" font-weight="700">最大缺口:</text>
|
||||
<text x="477" y="518" class="gap">真 pay 对接 = 桩,受支付进件闸门 mock-gated</text>
|
||||
<text x="414" y="536" class="xxs mut">逻辑已真、卡闸门 —— 闸门到位即接</text>
|
||||
|
||||
<!-- ad ✅ -->
|
||||
<rect x="55" y="556" width="670" height="86" rx="9" fill="#f0fdf4" stroke="#16a34a" stroke-width="2"/>
|
||||
<rect x="55" y="556" width="8" height="86" rx="3" fill="#16a34a"/>
|
||||
<text x="72" y="576" class="t lbl">ad · 广告联盟 / 植入 / 曝光计费 / 归因 ✅ 完成</text>
|
||||
<text x="72" y="594" class="xxs mut">计费全链真(合规 → 幂等 → 归因 → 台账)+ 验签 fail-fast,24 单测</text>
|
||||
<text x="72" y="614" class="gap" font-weight="700">最大缺口:</text>
|
||||
<text x="135" y="614" class="gap">真联盟 SDK(穿山甲 / 优量汇)= 桩,受广告审核闸门 mock-gated</text>
|
||||
<text x="72" y="632" class="xxs mut">AD · 与 trade 一样「逻辑已真、卡在日历闸门」</text>
|
||||
|
||||
<!-- 簇4 平台与合规 -->
|
||||
<rect x="756" y="424" width="684" height="232" rx="12" fill="#ffffff" stroke="#475569" stroke-width="2"/>
|
||||
<text x="771" y="448" class="t h2">平台与合规 · 让生态转得起来、守得住</text>
|
||||
|
||||
<!-- community ✅ -->
|
||||
<rect x="771" y="460" width="328" height="86" rx="9" fill="#f0fdf4" stroke="#16a34a" stroke-width="2"/>
|
||||
<rect x="771" y="460" width="8" height="86" rx="3" fill="#16a34a"/>
|
||||
<text x="788" y="480" class="t lbl">community · 社交 / 通知底座 ✅ 完成</text>
|
||||
<text x="788" y="498" class="xxs mut">通知底座 + 等级引擎真,3 上游 notify 全通;又补评论/关注/排行 ZSET/弹幕 WS(57 单测)</text>
|
||||
<text x="788" y="518" class="gap" font-weight="700">最大缺口:</text>
|
||||
<text x="851" y="518" class="gap">成就引擎仍未建(MVP 裁剪);弹幕多实例 / 多通道未建</text>
|
||||
<text x="788" y="536" class="xxs mut">CMU · 完成度按 MVP 裁剪后的范围计</text>
|
||||
|
||||
<!-- compliance 🟡 -->
|
||||
<rect x="1105" y="460" width="316" height="86" rx="9" fill="#fefce8" stroke="#ca8a04" stroke-width="2"/>
|
||||
<rect x="1105" y="460" width="8" height="86" rx="3" fill="#facc15"/>
|
||||
<text x="1122" y="480" class="t lbl">compliance · 内容安全 / 锁风门 🟡 部分</text>
|
||||
<text x="1122" y="498" class="xxs mut">锁风门框架 + 真注入发布链 + RBAC 都是真的</text>
|
||||
<text x="1122" y="518" class="warn">最大缺口:</text>
|
||||
<text x="1185" y="518" class="gap" font-weight="700">核心检测原子全桩、恒返回 pass</text>
|
||||
<text x="1122" y="536" class="xxs mut">发布链对违规内容零自动拦截、纯人工兜底 → 放量前必须硬化的合规死锁</text>
|
||||
|
||||
<!-- ip ◻ -->
|
||||
<rect x="771" y="556" width="328" height="86" rx="9" fill="#f1f5f9" stroke="#64748b" stroke-width="2" stroke-dasharray="6 4"/>
|
||||
<rect x="771" y="556" width="8" height="86" rx="3" fill="#cbd5e1"/>
|
||||
<text x="788" y="576" class="t lbl">ip · 素材安全 / 授权 / 风格原子 ◻ seam</text>
|
||||
<text x="788" y="594" class="xxs mut">有意不独立建,以 seam 寄宿在 compliance 里(D5 裁定)</text>
|
||||
<text x="788" y="614" class="warn">最大缺口:</text>
|
||||
<text x="851" y="614" class="gap">风格原子桩;素材安全 / 授权链 / 盗用监测全未建(远期)</text>
|
||||
<text x="788" y="632" class="xxs mut">注:面向用户的素材浏览/选用/上传最小后端在 studio 域、非 ip(plan002 U6)</text>
|
||||
|
||||
<!-- biz 🟡 -->
|
||||
<rect x="1105" y="556" width="316" height="86" rx="9" fill="#fefce8" stroke="#ca8a04" stroke-width="2"/>
|
||||
<rect x="1105" y="556" width="8" height="86" rx="3" fill="#facc15"/>
|
||||
<text x="1122" y="576" class="t lbl">biz · B/G 端定制工程底座 🟡 部分</text>
|
||||
<text x="1122" y="594" class="xxs mut">lead 状态机 + 报价落库真,13 单测</text>
|
||||
<text x="1122" y="614" class="warn">最大缺口:</text>
|
||||
<text x="1185" y="614" class="gap" font-weight="700">模板硬编码 4 个(非 32 套)</text>
|
||||
<text x="1122" y="632" class="xxs mut">报价引擎 / 签章 / CRM 纯未建</text>
|
||||
|
||||
<!-- 合计与读法 -->
|
||||
<rect x="40" y="672" width="1400" height="84" rx="11" fill="#f8fafc" stroke="#334155" stroke-width="1.4"/>
|
||||
<text x="55" y="694" class="t lbl">合计 13 模块:✅ 完成 5(project / telemetry / ad / trade / community)· 🟡 部分 6(aigc / runtime / feed / studio / compliance / biz)· ◻ 特殊 2(ip / pay)· 🔴 纯未建 0。</text>
|
||||
<text x="55" y="716" class="xs mut">三类「卡在闸门」值得单记:ad / trade / pay 卡的不是代码、是 ICP 备案 / 支付进件 / 广告审核这类不可压缩的日历闸门 —— 逻辑先建好,闸门到位即接。</text>
|
||||
<text x="55" y="734" class="xs t" font-weight="700">最该据图盯的两道债:compliance 检测原子恒 pass(放量前必硬化的合规死锁)、aigc 的 W-G1 worker 未接默认产线(护城河关键路径)。</text>
|
||||
<text x="55" y="750" class="xxs mut">本图是某次快照;颜色与缺口随开发推进会变,任何时刻以 docs/mvp/MVP进度总账.md 的真 / 桩 / 未建为准,本图只给一眼可读的空间总览。</text>
|
||||
|
||||
<!-- 徽章 -->
|
||||
<g class="badge"><rect x="40" y="772" width="56" height="18" rx="3" fill="#15803d"/><text x="45" y="785" fill="#fff">质量</text>
|
||||
<rect x="104" y="772" width="56" height="18" rx="3" fill="#dc2626"/><text x="109" y="785" fill="#fff">安全</text></g>
|
||||
<text x="172" y="785" class="mut xs">真端到端 5 块 = 可验收质量底座(质量);compliance 检测原子恒 pass = 放量前真实合规风险(安全)。</text>
|
||||
|
||||
<text x="40" y="822" class="mut xs">映射:架构/13模块.md §4 状态总表(与 docs/mvp/MVP进度总账.md 同口径) | 状态:现(快照 · 实时以 MVP进度总账.md 为准,口径 状态>实现>结构) | 设计变动须同步本图</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 14 KiB |
227
docs/architecture/运营/assets/12-运营状态机合集.svg
Normal file
227
docs/architecture/运营/assets/12-运营状态机合集.svg
Normal file
@ -0,0 +1,227 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1480 880" font-family="-apple-system,'PingFang SC','Microsoft YaHei',Segoe UI,sans-serif">
|
||||
<defs>
|
||||
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#334155"/></marker>
|
||||
<marker id="arrowR" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#dc2626"/></marker>
|
||||
<marker id="arrowB" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="#64748b"/></marker>
|
||||
<style>
|
||||
.t{fill:#0f172a}.mut{fill:#475569}.sm{font-size:12px}.xs{font-size:11px}.xxs{font-size:10px}
|
||||
.h1{font-size:24px;font-weight:700}.h2{font-size:14px;font-weight:700}.lbl{font-size:13px;font-weight:600}
|
||||
.flow{stroke:#334155;stroke-width:1.8;fill:none}.flowb{stroke:#64748b;stroke-width:1.5;fill:none;stroke-dasharray:6 4}
|
||||
.lockf{stroke:#dc2626;stroke-width:1.8;fill:none}
|
||||
.badge{font-size:10.5px;font-weight:700}.term{font-size:9.5px;font-weight:700;fill:#15803d}.todo{font-size:10px;font-weight:700;fill:#b45309}
|
||||
</style>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="1480" height="880" fill="#f8fafc"/>
|
||||
<text x="40" y="38" class="t h1">图 12 · 运营对象状态机合集(提现 ‖ B 端询单 ‖ 审核工单 ‖ 订阅续期)</text>
|
||||
<text x="40" y="58" class="mut sm">运营域里四个对象各有一台状态机,分散在三条变现线、审核台、订阅会员里。把它们并排画出来,看清每台机各自的触发条件、终态、哪些动作幂等,以及谁已真跑、谁的某段被外部资质卡住。</text>
|
||||
|
||||
<!-- 状态约定条 -->
|
||||
<rect x="40" y="76" width="1400" height="34" rx="8" fill="#fffbeb" stroke="#d97706" stroke-width="1.4"/>
|
||||
<text x="52" y="98" class="xs t" font-weight="700">状态约定:</text>
|
||||
<text x="128" y="98" class="xs mut">实线方框 = 该状态/迁移已落地真跑;虚线框 + 小标 = 该段被合规日历闸门或外部资质阻塞(mock / 钱留 M4 / 收单未接)。绿色双框 = 终态。本图整体状态 = 现。</text>
|
||||
|
||||
<!-- ① 提现五态 -->
|
||||
<rect x="40" y="128" width="700" height="290" rx="12" fill="#f0fdf4" stroke="#16a34a" stroke-width="2"/>
|
||||
<text x="56" y="152" class="t h2" fill="#15803d">① 提现五态(trade · game_trade_withdraw · 已建真跑,终点 mock)</text>
|
||||
<text x="56" y="170" class="xs mut">触发:创作者点提现 applyWithdraw;幂等键 uk_biz_no;金额单位「分」。最硬纪律 = 发起 ≠ 终态。</text>
|
||||
|
||||
<!-- 待审 0 -->
|
||||
<rect x="60" y="190" width="120" height="50" rx="9" fill="#ffffff" stroke="#16a34a" stroke-width="1.6"/>
|
||||
<text x="120" y="210" class="xs t" font-weight="700" text-anchor="middle">待审 0</text>
|
||||
<text x="120" y="226" class="xxs mut" text-anchor="middle">freeze 余额→冻结</text>
|
||||
<!-- 打款中 1 -->
|
||||
<rect x="300" y="190" width="130" height="50" rx="9" fill="#ffffff" stroke="#16a34a" stroke-width="1.6"/>
|
||||
<text x="365" y="210" class="xs t" font-weight="700" text-anchor="middle">打款中 1</text>
|
||||
<text x="365" y="226" class="xxs mut" text-anchor="middle">CAS 0→1(审核内只到此)</text>
|
||||
<!-- 已打款 2(终态)-->
|
||||
<rect x="556" y="190" width="160" height="50" rx="9" fill="#dcfce7" stroke="#16a34a" stroke-width="2.4"/>
|
||||
<rect x="560" y="194" width="152" height="42" rx="7" fill="none" stroke="#16a34a" stroke-width="1"/>
|
||||
<text x="636" y="210" class="xs t" font-weight="700" text-anchor="middle">已打款 2 ✓终</text>
|
||||
<text x="636" y="226" class="xxs mut" text-anchor="middle">回调 settlePaid</text>
|
||||
<!-- 驳回 3(终态)-->
|
||||
<rect x="60" y="300" width="150" height="48" rx="9" fill="#dcfce7" stroke="#16a34a" stroke-width="2.4"/>
|
||||
<rect x="64" y="304" width="142" height="40" rx="7" fill="none" stroke="#16a34a" stroke-width="1"/>
|
||||
<text x="135" y="322" class="xs t" font-weight="700" text-anchor="middle">驳回 3 ✓终</text>
|
||||
<text x="135" y="337" class="xxs mut" text-anchor="middle">refundFrozen 退冻结</text>
|
||||
<!-- 打款失败 4(终态)-->
|
||||
<rect x="300" y="300" width="170" height="48" rx="9" fill="#dcfce7" stroke="#16a34a" stroke-width="2.4"/>
|
||||
<rect x="304" y="304" width="162" height="40" rx="7" fill="none" stroke="#16a34a" stroke-width="1"/>
|
||||
<text x="385" y="322" class="xs t" font-weight="700" text-anchor="middle">打款失败 4 ✓终</text>
|
||||
<text x="385" y="337" class="xxs mut" text-anchor="middle">CAS 1→4 退冻结</text>
|
||||
<!-- 提现连线 -->
|
||||
<line x1="180" y1="215" x2="298" y2="215" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="239" y="208" class="xxs mut" text-anchor="middle">审核通过</text>
|
||||
<line x1="430" y1="215" x2="554" y2="215" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="492" y="208" class="xxs mut" text-anchor="middle">回调成功</text>
|
||||
<line x1="120" y1="240" x2="125" y2="298" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="150" y="272" class="xxs mut">审核驳回</text>
|
||||
<line x1="365" y1="240" x2="380" y2="298" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="392" y="272" class="xxs mut">回调失败</text>
|
||||
<!-- 提现:发起≠终态 + mock 桩 -->
|
||||
<rect x="490" y="258" width="226" height="56" rx="8" fill="#fff1f2" stroke="#dc2626" stroke-width="1.3" stroke-dasharray="6 4"/>
|
||||
<text x="500" y="276" class="xxs t" font-weight="700">打款执行 = mock 桩(待真渠道)</text>
|
||||
<text x="500" y="291" class="xxs mut">仅 MockPayoutClient;真 wxpay/alipay</text>
|
||||
<text x="500" y="305" class="xxs mut">被合规闸门阻塞,找不到实现 fail-fast</text>
|
||||
<text x="56" y="372" class="xxs t" font-weight="700">幂等:申请 uk_biz_no 防重;审核 / 打款终态全走 CAS(已翻走的单二次驱动 CAS 失败、不二次发钱)。</text>
|
||||
<text x="56" y="390" class="xxs mut">卡单兜底:WithdrawPayoutCompensateJob 扫 status=1 超 15min,按单子血统渠道补驱动终态——正常路回调、异常路补偿,两路都过 CAS。</text>
|
||||
<text x="56" y="408" class="xxs mut">降级口径:打款渠道缺失绝不静默降级 mock(那是吞真钱),必须 fail-fast——与广告线「缺渠道降级 mock 可接受」正好相反。</text>
|
||||
|
||||
<!-- ② B 端询单五态 -->
|
||||
<rect x="756" y="128" width="684" height="290" rx="12" fill="#fef2f2" stroke="#dc2626" stroke-width="2" stroke-dasharray="6 4"/>
|
||||
<text x="772" y="152" class="t h2" fill="#b91c1c">② B 端询单五态(biz · game_biz_lead · 单线推进,完全不碰钱)</text>
|
||||
<text x="772" y="170" class="xs mut">触发:客户提单 → 单线性五态;本波只走业务状态机,收款 / 在线签章 / 分账整段留 M4。</text>
|
||||
|
||||
<!-- 五态横排 -->
|
||||
<rect x="772" y="192" width="120" height="50" rx="9" fill="#ffffff" stroke="#dc2626" stroke-width="1.5"/>
|
||||
<text x="832" y="212" class="xs t" font-weight="700" text-anchor="middle">待跟进 0</text>
|
||||
<text x="832" y="228" class="xxs mut" text-anchor="middle">客户提单 / 线索</text>
|
||||
<rect x="916" y="192" width="120" height="50" rx="9" fill="#ffffff" stroke="#dc2626" stroke-width="1.5"/>
|
||||
<text x="976" y="212" class="xs t" font-weight="700" text-anchor="middle">已报价 1</text>
|
||||
<text x="976" y="228" class="xxs mut" text-anchor="middle">报价(只展示)</text>
|
||||
<rect x="1060" y="192" width="120" height="50" rx="9" fill="#ffffff" stroke="#dc2626" stroke-width="1.5"/>
|
||||
<text x="1120" y="212" class="xs t" font-weight="700" text-anchor="middle">制作中 2</text>
|
||||
<text x="1120" y="228" class="xxs mut" text-anchor="middle">接单 · 进度工单</text>
|
||||
<rect x="1204" y="192" width="120" height="50" rx="9" fill="#ffffff" stroke="#dc2626" stroke-width="1.5"/>
|
||||
<text x="1264" y="212" class="xs t" font-weight="700" text-anchor="middle">待验收 3</text>
|
||||
<text x="1264" y="228" class="xxs mut" text-anchor="middle">提交验收</text>
|
||||
<rect x="1348" y="192" width="80" height="50" rx="9" fill="#fee2e2" stroke="#dc2626" stroke-width="2.4"/>
|
||||
<rect x="1352" y="196" width="72" height="42" rx="7" fill="none" stroke="#dc2626" stroke-width="1"/>
|
||||
<text x="1388" y="210" class="xxs t" font-weight="700" text-anchor="middle">已交付 4</text>
|
||||
<text x="1388" y="224" class="xxs" fill="#b91c1c" font-weight="700" text-anchor="middle">✓终</text>
|
||||
<!-- B端连线 -->
|
||||
<line x1="892" y1="217" x2="914" y2="217" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="1036" y1="217" x2="1058" y2="217" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="1047" y="210" class="xxs mut" text-anchor="middle">接单</text>
|
||||
<line x1="1180" y1="217" x2="1202" y2="217" class="flow" marker-end="url(#arrow)"/>
|
||||
<line x1="1324" y1="217" x2="1346" y2="217" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="1335" y="210" class="xxs mut" text-anchor="middle">确认</text>
|
||||
|
||||
<!-- B端四表 + 钱留 M4 -->
|
||||
<rect x="772" y="262" width="656" height="40" rx="8" fill="#fff1f2" stroke="#dc2626" stroke-width="1.2"/>
|
||||
<text x="782" y="280" class="xxs t" font-weight="700">四表:lead 询单主单 · quote 报价(只展示不收款)· progress 进度时间线 · acceptance 验收(带 signed_offline 线下签兜底)</text>
|
||||
<text x="782" y="295" class="xxs mut">状态机合法迁移由 BizLeadServiceImpl 写前校验;admin 推进 advance / 报价 quotes / 线下签 sign-offline,app 提单 / 反馈 / 确认。</text>
|
||||
<rect x="772" y="312" width="656" height="56" rx="8" fill="#fef2f2" stroke="#dc2626" stroke-width="1.4" stroke-dasharray="6 4"/>
|
||||
<text x="1240" y="330" class="todo">钱留 M4</text>
|
||||
<text x="782" y="332" class="xxs t" font-weight="700">报价 ≠ 可支付订单:在线签章 / 收款(T-BIZ-08)/ 分账整段留 M4</text>
|
||||
<text x="782" y="348" class="xxs mut">现唯一能标的是 signed_offline——线下签了合同打个兜底标记。B 端是近期现金线,但工程钱流尚未建。</text>
|
||||
<text x="782" y="362" class="xxs mut">前端 game-admin 暂无 biz/lead 视图(待建);状态机本身已真跑,被卡的只是「钱」这一段。</text>
|
||||
<text x="772" y="392" class="xxs mut">幂等:状态机以「待跟进→已报价→制作中→待验收→已交付」单线推进,非法跳转写前即拒;重复推进同一态不产生副作用。</text>
|
||||
<text x="772" y="410" class="xxs mut" font-weight="700" fill="#b91c1c">整条线虚线红框 = 唯一不碰钱的状态机:它的「终态」是交付,不是收款;真正的资金动作在 ① 提现线、不在这里。</text>
|
||||
|
||||
<!-- ③ 审核工单 -->
|
||||
<rect x="40" y="436" width="700" height="408" rx="12" fill="#eff6ff" stroke="#2563eb" stroke-width="2"/>
|
||||
<text x="56" y="460" class="t h2" fill="#1d4ed8">③ 审核工单(compliance · game_compliance_review_task · 第一期待建)</text>
|
||||
<text x="56" y="478" class="xs mut">触发:机审瀑布判 review / 锁风人工档 / 举报率超阈值事中召回;MVP 轻量状态机起步,Flowable 留远期。</text>
|
||||
|
||||
<!-- 待认领 -->
|
||||
<rect x="60" y="500" width="150" height="50" rx="9" fill="#ffffff" stroke="#2563eb" stroke-width="1.6" stroke-dasharray="6 4"/>
|
||||
<text x="135" y="520" class="xs t" font-weight="700" text-anchor="middle">待认领</text>
|
||||
<text x="135" y="536" class="xxs mut" text-anchor="middle">机审 review / 建单</text>
|
||||
<!-- 审核中 -->
|
||||
<rect x="300" y="500" width="150" height="50" rx="9" fill="#ffffff" stroke="#2563eb" stroke-width="1.6" stroke-dasharray="6 4"/>
|
||||
<text x="375" y="520" class="xs t" font-weight="700" text-anchor="middle">审核中</text>
|
||||
<text x="375" y="536" class="xxs mut" text-anchor="middle">认领 CAS 抢占</text>
|
||||
<!-- 已升级 -->
|
||||
<rect x="540" y="500" width="160" height="50" rx="9" fill="#ffffff" stroke="#2563eb" stroke-width="1.6" stroke-dasharray="6 4"/>
|
||||
<text x="620" y="520" class="xs t" font-weight="700" text-anchor="middle">已升级</text>
|
||||
<text x="620" y="536" class="xxs mut" text-anchor="middle">拿不准 → 复审/主管</text>
|
||||
<!-- 超时告警 -->
|
||||
<rect x="300" y="588" width="160" height="46" rx="9" fill="#fff7ed" stroke="#d97706" stroke-width="1.5" stroke-dasharray="6 4"/>
|
||||
<text x="380" y="606" class="xs t" font-weight="700" text-anchor="middle">超时告警</text>
|
||||
<text x="380" y="621" class="xxs mut" text-anchor="middle">超 SLA → 介入处理</text>
|
||||
<!-- 已通过(终态)-->
|
||||
<rect x="60" y="672" width="170" height="48" rx="9" fill="#dcfce7" stroke="#16a34a" stroke-width="2.4"/>
|
||||
<rect x="64" y="676" width="162" height="40" rx="7" fill="none" stroke="#16a34a" stroke-width="1"/>
|
||||
<text x="145" y="694" class="xs t" font-weight="700" text-anchor="middle">已通过 ✓终</text>
|
||||
<text x="145" y="709" class="xxs mut" text-anchor="middle">approve → 推进发布</text>
|
||||
<!-- 已拒绝(终态)-->
|
||||
<rect x="300" y="672" width="190" height="48" rx="9" fill="#dcfce7" stroke="#16a34a" stroke-width="2.4"/>
|
||||
<rect x="304" y="676" width="182" height="40" rx="7" fill="none" stroke="#16a34a" stroke-width="1"/>
|
||||
<text x="395" y="694" class="xs t" font-weight="700" text-anchor="middle">已拒绝 ✓终</text>
|
||||
<text x="395" y="709" class="xxs mut" text-anchor="middle">reject → 触发处置</text>
|
||||
<!-- 审核工单连线 -->
|
||||
<line x1="210" y1="525" x2="298" y2="525" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<text x="254" y="518" class="xxs mut" text-anchor="middle">认领</text>
|
||||
<line x1="450" y1="520" x2="538" y2="520" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<line x1="600" y1="550" x2="430" y2="555" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<text x="540" y="572" class="xxs mut" text-anchor="middle">上级接手</text>
|
||||
<line x1="375" y1="550" x2="378" y2="586" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<line x1="405" y1="588" x2="408" y2="552" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<line x1="150" y1="550" x2="148" y2="670" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<text x="100" y="612" class="xxs mut">approve</text>
|
||||
<line x1="375" y1="550" x2="392" y2="670" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<text x="430" y="640" class="xxs mut">reject</text>
|
||||
<!-- 待认领 → 超时告警 -->
|
||||
<line x1="135" y1="550" x2="300" y2="600" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<text x="180" y="585" class="xxs mut">超 SLA 未认领</text>
|
||||
|
||||
<!-- 审核工单说明 -->
|
||||
<rect x="520" y="588" width="200" height="132" rx="8" fill="#f1f5f9" stroke="#475569" stroke-width="1.2"/>
|
||||
<text x="530" y="606" class="xxs t" font-weight="700">现状(诚实分层):</text>
|
||||
<text x="530" y="622" class="xxs mut">这台机第一期才建——今天</text>
|
||||
<text x="530" y="636" class="xxs mut">compliance 只有「申诉」一种</text>
|
||||
<text x="530" y="650" class="xxs mut">人工单,没有带认领/分派/</text>
|
||||
<text x="530" y="664" class="xxs mut">SLA 的内容审核队列底座。</text>
|
||||
<text x="530" y="682" class="xxs t" font-weight="700">人审终裁 = 最高权威,</text>
|
||||
<text x="530" y="696" class="xxs mut">覆盖机审结论。审核状态</text>
|
||||
<text x="530" y="710" class="xxs mut">唯一权威在 compliance。</text>
|
||||
<text x="56" y="742" class="xxs t" font-weight="700">幂等:认领用 CAS 抢占防双审;事中召回以 gameId+窗口为幂等键,同一内容一个窗口只召回一次、不每轮重复建单。</text>
|
||||
<text x="56" y="760" class="xxs mut">为什么走 BPM 而非裸 status:认领 / 分派 / 升级 / 超时 / SLA 统计用裸字段会越写越乱,声明成流程图由引擎驱动。</text>
|
||||
<text x="56" y="778" class="xxs mut">两条人工流并存——审核工单(compliance:review:handle 新增)与申诉单(compliance:appeal:handle 已建)共用同一套将建的队列 UI 框架。</text>
|
||||
<text x="56" y="796" class="xxs mut">权威:人工 approve/reject 覆盖机审;终裁回写驱动后续(放行推进发布 / 拦截触发 §3.5 处置联动)。</text>
|
||||
<text x="56" y="814" class="xxs" fill="#1d4ed8" font-weight="700">整台机虚线 = 第一期待建(队列底座 + 状态机 + admin 审核台);今天发布链对违规内容零自动拦截、纯靠人工兜底。</text>
|
||||
<text x="56" y="832" class="xxs mut">超时告警 = 旁路态(不是终态),介入后回到审核中;只有「已通过 / 已拒绝」是真终态。</text>
|
||||
|
||||
<!-- ④ 订阅续期 -->
|
||||
<rect x="756" y="436" width="684" height="408" rx="12" fill="#fff7ed" stroke="#d97706" stroke-width="2"/>
|
||||
<text x="772" y="460" class="t h2" fill="#b45309">④ 订阅续期(trade · game_trade_subscription · 入账已建 / 收单未建)</text>
|
||||
<text x="772" y="478" class="xs mut">触发:admin 赋订阅 grant;有效性以 expire_time 为权威、无 cron 物化;自助购买那一半被支付通道阻塞。</text>
|
||||
|
||||
<!-- 无订阅 -->
|
||||
<rect x="772" y="500" width="140" height="50" rx="9" fill="#ffffff" stroke="#d97706" stroke-width="1.6"/>
|
||||
<text x="842" y="520" class="xs t" font-weight="700" text-anchor="middle">无订阅 / 已过期</text>
|
||||
<text x="842" y="536" class="xxs mut" text-anchor="middle">expire_time ≤ now</text>
|
||||
<!-- 生效中 -->
|
||||
<rect x="1000" y="500" width="150" height="50" rx="9" fill="#fff7ed" stroke="#d97706" stroke-width="1.6"/>
|
||||
<text x="1075" y="520" class="xs t" font-weight="700" text-anchor="middle">生效中 active</text>
|
||||
<text x="1075" y="536" class="xxs mut" text-anchor="middle">expire_time > now</text>
|
||||
<!-- 订阅连线:无→生效 -->
|
||||
<line x1="912" y1="518" x2="998" y2="518" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="955" y="510" class="xxs mut" text-anchor="middle">赋订阅</text>
|
||||
<!-- 生效→生效 续期自环 -->
|
||||
<path d="M1115,500 C1135,470 1075,468 1085,498" class="flow" marker-end="url(#arrow)"/>
|
||||
<text x="1120" y="476" class="xxs mut">续期 newExpire=max(now,旧)+时长</text>
|
||||
<!-- 生效→过期 到期回落 -->
|
||||
<line x1="1040" y1="550" x2="900" y2="552" class="flowb" marker-end="url(#arrowB)"/>
|
||||
<text x="970" y="572" class="xxs mut" text-anchor="middle">到期未续(实时回算,无 job)</text>
|
||||
|
||||
<!-- 订阅三表 + 半接 -->
|
||||
<rect x="772" y="588" width="656" height="56" rx="8" fill="#ffffff" stroke="#d97706" stroke-width="1.3"/>
|
||||
<text x="782" y="606" class="xxs t" font-weight="700">三表:grant 赋余额流水(uk_biz_no)· subscription 一用户一行(uk_user · plan 1月/2季/3年)· subscription_grant 幂等账本(uk_biz_no)</text>
|
||||
<text x="782" y="622" class="xxs mut">subscription_grant 是 P0 修复加的独立账本——主行 last_grant_biz_no 只挡上一次,独立账本才挡任意历史 bizNo 重放。</text>
|
||||
<text x="782" y="638" class="xxs mut">续期算法 newExpire=max(now,旧expire)+时长,没用完的时长叠加不丢;renewByCas 防并发 lost-update。</text>
|
||||
<rect x="772" y="654" width="656" height="44" rx="8" fill="#fef2f2" stroke="#dc2626" stroke-width="1.4" stroke-dasharray="6 4"/>
|
||||
<text x="1300" y="672" class="todo">收单待支付</text>
|
||||
<text x="782" y="674" class="xxs t" font-weight="700">自助购买未接:现只能 admin 手动赋(source=admin_grant),自助购买需接真实支付收单 + 回调驱动 grantSubscription</text>
|
||||
<text x="782" y="690" class="xxs mut">替代 admin 手动赋——这一半被日历闸门(支付进件)阻塞,抽象已留好接缝,补真实现即切。</text>
|
||||
<text x="772" y="722" class="xxs t" font-weight="700">幂等:每笔赋订阅落账本一行 uk_biz_no,挡任意历史 bizNo 重放;续期 renewByCas 防并发。</text>
|
||||
<text x="772" y="740" class="xxs mut">终态语义特殊:订阅没有「彻底结束」的吸收态——「过期」可被下一次续期重新拉回「生效中」,是可逆回落,故图上画双向。</text>
|
||||
<text x="772" y="758" class="xxs mut">C 端查态 mine:effectiveStatus 按 expire_time > now 实时回算,不跑 cron 物化过期——少维护一个定时任务,代价是查时算一下。</text>
|
||||
<text x="772" y="776" class="xxs mut">入账已建(admin 赋真跑、入创作者钱包恒等式);被卡的只是「自助收单」这一半,不是整条订阅线。</text>
|
||||
<text x="772" y="794" class="xxs" fill="#b45309" font-weight="700">这台机与 ① 提现共用 trade 钱包:admin 赋订阅入账 game_trade_account(已真),与广告分账汇合在同一恒等式上。</text>
|
||||
<text x="772" y="812" class="xxs mut">边界:自助购买订阅 = 日历闸门约束(支付收单)的事,MVP 非必需;当前订阅只能 admin 手动赋。</text>
|
||||
<text x="772" y="830" class="xxs mut">分层纪律:实线方框(生效中 / 赋订阅 / 续期)已真跑,仅虚线红框「收单」一段未接。</text>
|
||||
|
||||
<!-- 图例 -->
|
||||
<text x="40" y="864" class="t h2">图例:</text>
|
||||
<rect x="118" y="850" width="30" height="18" rx="5" fill="#ffffff" stroke="#334155" stroke-width="1.8"/><text x="155" y="864" class="t xs">已真跑状态</text>
|
||||
<rect x="248" y="850" width="30" height="18" rx="5" fill="#dcfce7" stroke="#16a34a" stroke-width="2.2"/><text x="285" y="864" class="t xs">终态(双框)</text>
|
||||
<rect x="392" y="850" width="30" height="18" rx="5" fill="#ffffff" stroke="#2563eb" stroke-width="1.8" stroke-dasharray="6 4"/><text x="429" y="864" class="t xs">待建状态(虚线)</text>
|
||||
<rect x="558" y="850" width="30" height="18" rx="5" fill="#fef2f2" stroke="#dc2626" stroke-width="1.8" stroke-dasharray="6 4"/><text x="595" y="864" class="t xs">被资质阻塞段(mock/钱留 M4/收单待接)</text>
|
||||
<line x1="900" y1="859" x2="940" y2="859" class="flow" marker-end="url(#arrow)"/><text x="948" y="863" class="t xs">已落地迁移</text>
|
||||
<line x1="1060" y1="859" x2="1100" y2="859" class="flowb" marker-end="url(#arrowB)"/><text x="1108" y="863" class="t xs">待建 / 可逆回落</text>
|
||||
<g class="badge"><rect x="1260" y="851" width="50" height="16" rx="3" fill="#16a34a"/><text x="1265" y="863" fill="#fff">可靠</text></g>
|
||||
<text x="1316" y="863" class="mut xs">幂等键 + CAS + 发起≠终态 + 终态可追</text>
|
||||
|
||||
<text x="40" y="878" class="mut xxs">映射:变现端到端.md §2.4/§3/§4 + 审核台运营.md §3.4(dev/2.0.0) | 状态:现(提现真跑·终点 mock ‖ B 端不碰钱·钱留 M4 ‖ 审核工单第一期待建 ‖ 订阅入账真·收单未接) | 设计变动须同步本图</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
Loading…
x
Reference in New Issue
Block a user