Files
ST-Amily2-Chat-Optimisation/DPS.drawio

155 lines
13 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<mxfile host="65bd71144e" modified="2026-04-29T00:00:00.000Z" agent="Claude" version="22.0.0" type="device">
<diagram id="dps" name="Domain-Pipeline-Service">
<mxGraphModel dx="1422" dy="900" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1200" pageHeight="900" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="title" value="表格模块 — Domain → Operation → Pipeline → Service 五层架构" style="text;html=1;align=center;fontSize=20;fontStyle=1" vertex="1" parent="1">
<mxGeometry x="180" y="20" width="840" height="30" as="geometry" />
</mxCell>
<mxCell id="subtitle" value="自下而上Domain(纯逻辑) → Operation(动作) → Pipeline(三模式) → Service(门面) → UI(订阅)" style="text;html=1;align=center;fontSize=12;fontStyle=2;fontColor=#666666" vertex="1" parent="1">
<mxGeometry x="160" y="50" width="880" height="20" as="geometry" />
</mxCell>
<mxCell id="uiLayer" value="UI Layer — 现有,不动;通过订阅事件刷新" style="swimlane;fontStyle=1;fillColor=#e1d5e7;strokeColor=#9673a6;startSize=30" vertex="1" parent="1">
<mxGeometry x="40" y="80" width="1120" height="80" as="geometry" />
</mxCell>
<mxCell id="ui1" value="ui/table-bindings.js" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6" vertex="1" parent="uiLayer">
<mxGeometry x="320" y="32" width="220" height="36" as="geometry" />
</mxCell>
<mxCell id="ui2" value="ui/message-table-renderer.js" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6" vertex="1" parent="uiLayer">
<mxGeometry x="580" y="32" width="220" height="36" as="geometry" />
</mxCell>
<mxCell id="serviceLayer" value="Service Layer — 顶层门面,组合下层" style="swimlane;fontStyle=1;fillColor=#dae8fc;strokeColor=#6c8ebf;startSize=30" vertex="1" parent="1">
<mxGeometry x="40" y="190" width="1120" height="80" as="geometry" />
</mxCell>
<mxCell id="svc" value="TableSystemService&#xa;processMessageUpdate / fillSecondary / fillBatch / reorganize / rollback" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=11" vertex="1" parent="serviceLayer">
<mxGeometry x="280" y="20" width="560" height="50" as="geometry" />
</mxCell>
<mxCell id="pipelineLayer" value="Pipeline Layer — 三模式落地formatter 可插拔" style="swimlane;fontStyle=1;fillColor=#d5e8d4;strokeColor=#82b366;startSize=30" vertex="1" parent="1">
<mxGeometry x="40" y="300" width="1120" height="200" as="geometry" />
</mxCell>
<mxCell id="formattersGroup" value="formatters/" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#82b366;dashed=1;verticalAlign=top;fontStyle=1" vertex="1" parent="pipelineLayer">
<mxGeometry x="20" y="40" width="500" height="140" as="geometry" />
</mxCell>
<mxCell id="fmtIdx" value="index.js&#xa;按 settings 分发" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10" vertex="1" parent="formattersGroup">
<mxGeometry x="160" y="30" width="180" height="40" as="geometry" />
</mxCell>
<mxCell id="fmtLeg" value="legacy.js&#xa;&lt;Amily2Edit&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10" vertex="1" parent="formattersGroup">
<mxGeometry x="20" y="85" width="140" height="44" as="geometry" />
</mxCell>
<mxCell id="fmtJson" value="json.js&#xa;{operations}" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10" vertex="1" parent="formattersGroup">
<mxGeometry x="180" y="85" width="140" height="44" as="geometry" />
</mxCell>
<mxCell id="fmtTC" value="toolcall.js&#xa;Bus tools" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10" vertex="1" parent="formattersGroup">
<mxGeometry x="340" y="85" width="140" height="44" as="geometry" />
</mxCell>
<mxCell id="fillerGroup" value="filler/" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#82b366;dashed=1;verticalAlign=top;fontStyle=1" vertex="1" parent="pipelineLayer">
<mxGeometry x="560" y="40" width="540" height="140" as="geometry" />
</mxCell>
<mxCell id="fillShared" value="shared.js&#xa;worldbook + history + buildMessages + callModel" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10" vertex="1" parent="fillerGroup">
<mxGeometry x="60" y="30" width="420" height="40" as="geometry" />
</mxCell>
<mxCell id="fillSec" value="secondary.js&#xa;触发条件 + 楼层扫描" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10" vertex="1" parent="fillerGroup">
<mxGeometry x="20" y="85" width="160" height="44" as="geometry" />
</mxCell>
<mxCell id="fillBatch" value="batch.js&#xa;批次循环" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10" vertex="1" parent="fillerGroup">
<mxGeometry x="200" y="85" width="160" height="44" as="geometry" />
</mxCell>
<mxCell id="fillReorg" value="reorganize.js" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10" vertex="1" parent="fillerGroup">
<mxGeometry x="380" y="85" width="140" height="44" as="geometry" />
</mxCell>
<mxCell id="opLayer" value="Operation Layer — 统一动作;从 executor.js 抽出" style="swimlane;fontStyle=1;fillColor=#fff2cc;strokeColor=#d6b656;startSize=30" vertex="1" parent="1">
<mxGeometry x="40" y="530" width="1120" height="80" as="geometry" />
</mxCell>
<mxCell id="op1" value="operations.js&#xa;applyOperations(state, ops) → { state, changes }&#xa;含 insertRow / updateRow / deleteRow 三内部函数" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11" vertex="1" parent="opLayer">
<mxGeometry x="320" y="10" width="480" height="60" as="geometry" />
</mxCell>
<mxCell id="domainLayer" value="Domain Layer — 拆自 manager.js禁止 import UI" style="swimlane;fontStyle=1;fillColor=#f8cecc;strokeColor=#b85450;startSize=30" vertex="1" parent="1">
<mxGeometry x="40" y="640" width="1120" height="120" as="geometry" />
</mxCell>
<mxCell id="dm1" value="store.js&#xa;currentTablesState&#xa;独占所有权" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10" vertex="1" parent="domainLayer">
<mxGeometry x="20" y="40" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="dm2" value="persist.js&#xa;commitToLastMessage&#xa;封装 16 处样板" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10" vertex="1" parent="domainLayer">
<mxGeometry x="200" y="40" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="dm3" value="mutations.js&#xa;addRow / addCol / ...&#xa;(16 个 UI 突变)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10" vertex="1" parent="domainLayer">
<mxGeometry x="380" y="40" width="180" height="60" as="geometry" />
</mxCell>
<mxCell id="dm4" value="rendering.js&#xa;toCsv * 3&#xa;(纯函数)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10" vertex="1" parent="domainLayer">
<mxGeometry x="580" y="40" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="dm5" value="templates.js&#xa;getter/setter" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10" vertex="1" parent="domainLayer">
<mxGeometry x="760" y="40" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="dm6" value="preset.js&#xa;import/export" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10" vertex="1" parent="domainLayer">
<mxGeometry x="940" y="40" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="e_svc_fillSec" style="endArrow=classic;html=1" edge="1" parent="1" source="svc" target="fillSec">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_svc_fillBatch" style="endArrow=classic;html=1" edge="1" parent="1" source="svc" target="fillBatch">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_svc_fillReorg" style="endArrow=classic;html=1" edge="1" parent="1" source="svc" target="fillReorg">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_svc_op" value="apply Op[]" style="endArrow=classic;html=1;fontSize=9" edge="1" parent="1" source="svc" target="op1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_fillSec_shared" style="endArrow=classic;html=1" edge="1" parent="1" source="fillSec" target="fillShared">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_fillBatch_shared" style="endArrow=classic;html=1" edge="1" parent="1" source="fillBatch" target="fillShared">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_fillReorg_shared" style="endArrow=classic;html=1" edge="1" parent="1" source="fillReorg" target="fillShared">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_shared_fmtIdx" value="dispatch" style="endArrow=classic;html=1;fontSize=9" edge="1" parent="1" source="fillShared" target="fmtIdx">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_fmtIdx_leg" style="endArrow=open;html=1;dashed=1;endFill=0" edge="1" parent="1" source="fmtIdx" target="fmtLeg">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_fmtIdx_json" style="endArrow=open;html=1;dashed=1;endFill=0" edge="1" parent="1" source="fmtIdx" target="fmtJson">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_fmtIdx_tc" style="endArrow=open;html=1;dashed=1;endFill=0" edge="1" parent="1" source="fmtIdx" target="fmtTC">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_leg_op" value="Op[]" style="endArrow=classic;html=1;dashed=1;fontSize=9" edge="1" parent="1" source="fmtLeg" target="op1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_json_op" value="Op[]" style="endArrow=classic;html=1;dashed=1;fontSize=9" edge="1" parent="1" source="fmtJson" target="op1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_tc_op" value="Op[]" style="endArrow=classic;html=1;dashed=1;fontSize=9" edge="1" parent="1" source="fmtTC" target="op1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_op_dm1" value="state" style="endArrow=classic;html=1;fontSize=9" edge="1" parent="1" source="op1" target="dm1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_svc_dm2" value="commit" style="endArrow=classic;html=1;dashed=1;fontSize=9" edge="1" parent="1" source="svc" target="dm2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_dm3_dm1" value="mutates" style="endArrow=classic;html=1;dashed=1;fontSize=9" edge="1" parent="1" source="dm3" target="dm1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_dm3_dm2" value="commit" style="endArrow=classic;html=1;dashed=1;fontSize=9" edge="1" parent="1" source="dm3" target="dm2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e_dm1_ui" value="subscribe / events" style="endArrow=classic;html=1;dashed=1;strokeColor=#9673a6;fontSize=9" edge="1" parent="1" source="dm1" target="ui1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="legend" value="实线箭头 → 直接调用(自顶而下)&#10;虚线箭头 → 数据流向 / 跨层订阅&#10;红色 Domain 层最严格:禁止 import UI" style="text;html=1;align=left;fontSize=11;fillColor=#ffffff;strokeColor=#cccccc;rounded=0" vertex="1" parent="1">
<mxGeometry x="40" y="780" width="380" height="60" as="geometry" />
</mxCell>
<mxCell id="note1" value="特点:&#10;• 五层洋葱模型,依赖单向自顶而下&#10;• 文件少(~14manager.js 拆出后立即清晰&#10;• Domain 是纯逻辑岛,可独立测试&#10;• 无显式 DTO 层shape 散在 JSDoc 注释里" style="text;html=1;align=left;fontSize=11;fillColor=#fff8e1;strokeColor=#ffb300;rounded=0" vertex="1" parent="1">
<mxGeometry x="450" y="770" width="380" height="80" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>