WangKang преди 2 седмици
родител
ревизия
173f236037

+ 1 - 0
.gitignore

@@ -75,3 +75,4 @@ video
 .cursor
 .codegraph
 .worktrees/
+.scratch

+ 0 - 12
.run/ruoyi-monitor-admin.run.xml

@@ -1,12 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="emoon-monitor-admin/Dockerfile: Compose 部署" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
-    <deployment type="dockerfile">
-      <settings>
-        <option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.4.1" />
-        <option name="buildOnly" value="true" />
-        <option name="sourceFilePath" value="emoon-extend/emoon-monitor-admin/Dockerfile" />
-      </settings>
-    </deployment>
-    <method v="2" />
-  </configuration>
-</component>

+ 0 - 11
.run/ruoyi-server.run.xml

@@ -1,11 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="emoon-admin/Dockerfile: Compose 部署" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
-    <deployment type="dockerfile">
-      <settings>
-        <option name="imageTag" value="ruoyi/ruoyi-server:5.4.1" />
-        <option name="sourceFilePath" value="emoon-admin/Dockerfile" />
-      </settings>
-    </deployment>
-    <method v="2" />
-  </configuration>
-</component>

+ 0 - 12
.run/ruoyi-snailjob-server.run.xml

@@ -1,12 +0,0 @@
-<component name="ProjectRunConfigurationManager">
-  <configuration default="false" name="emoon-snailjob-server/Dockerfile: Compose 部署" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
-    <deployment type="dockerfile">
-      <settings>
-        <option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.4.1" />
-        <option name="buildOnly" value="true" />
-        <option name="sourceFilePath" value="emoon-extend/emoon-snailjob-server/Dockerfile" />
-      </settings>
-    </deployment>
-    <method v="2" />
-  </configuration>
-</component>

+ 0 - 106
.superpowers/brainstorm/86383-1780383912/content/final-web-demo-design-v2.html

@@ -1,106 +0,0 @@
-<h2>修订版:品牌配色 + 对话优先</h2>
-<p class="subtitle">主题色使用浅色 #3ad4d8、深色 #2b1f99。左侧不再做功能按钮,改为助手上下文与可说示例。</p>
-
-<div class="mockup">
-  <div class="mockup-header">主界面结构 v2</div>
-  <div class="mockup-body">
-    <div style="height:540px;border:1px solid #dfe7f7;border-radius:18px;background:#f7fbff;overflow:hidden;font-family:Inter,Arial,sans-serif;color:#16133a">
-      <div style="height:58px;background:white;border-bottom:1px solid #e7ebf5;display:flex;align-items:center;justify-content:space-between;padding:0 22px">
-        <div style="display:flex;align-items:center;gap:12px">
-          <div style="width:34px;height:34px;border-radius:10px;background:#2b1f99;color:white;display:grid;place-items:center;font-weight:900">医</div>
-          <div style="font-weight:900">医梦门诊助手</div>
-        </div>
-        <div style="font-size:13px;color:#69708a">Web Demo · 门诊大厅 · 联调演示</div>
-      </div>
-
-      <div style="display:grid;grid-template-columns:280px 1fr 390px;gap:16px;padding:16px;height:482px">
-        <aside style="background:linear-gradient(180deg,#ffffff,#f1fbff);border:1px solid #dfe7f7;border-radius:16px;padding:18px;display:flex;flex-direction:column">
-          <div style="display:flex;gap:12px;align-items:center;margin-bottom:18px">
-            <div style="width:70px;height:70px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#ffffff,#3ad4d8 45%,#2b1f99);display:grid;place-items:center;font-size:24px;font-weight:900;color:white;box-shadow:0 12px 30px rgba(43,31,153,.18)">AI</div>
-            <div>
-              <div style="font-weight:900;font-size:18px">你好,我在</div>
-              <div style="font-size:12px;color:#68708c;margin-top:4px">说出需求,我来判断下一步</div>
-            </div>
-          </div>
-
-          <div style="border:1px solid #dce7f8;border-radius:14px;background:white;padding:14px;margin-bottom:14px">
-            <div style="font-size:12px;color:#69708a;margin-bottom:8px">可以这样说</div>
-            <div style="display:grid;gap:8px;font-size:13px">
-              <div style="background:#f4fbff;border-radius:10px;padding:9px">“我头疼三天,想挂号”</div>
-              <div style="background:#f4fbff;border-radius:10px;padding:9px">“明天上午有神经内科的号吗”</div>
-              <div style="background:#f4fbff;border-radius:10px;padding:9px">“我想找李明医生”</div>
-            </div>
-          </div>
-
-          <div style="border:1px solid #dce7f8;border-radius:14px;background:white;padding:14px">
-            <div style="font-size:12px;color:#69708a;margin-bottom:8px">当前可办理</div>
-            <div style="display:flex;flex-wrap:wrap;gap:8px">
-              <span style="border:1px solid #cceff1;color:#156e83;border-radius:999px;padding:6px 9px;font-size:12px">挂号</span>
-              <span style="border:1px solid #e2e5f2;color:#5d5a82;border-radius:999px;padding:6px 9px;font-size:12px">导诊</span>
-              <span style="border:1px solid #e2e5f2;color:#5d5a82;border-radius:999px;padding:6px 9px;font-size:12px">医生查询</span>
-            </div>
-          </div>
-
-          <div style="margin-top:auto;background:#fff8e8;border:1px solid #f0d89c;border-radius:12px;padding:12px;font-size:12px;color:#735b14">
-            后端返回 mock:true 时展示“联调演示”,不伪装成真实业务。
-          </div>
-        </aside>
-
-        <main style="background:white;border:1px solid #dfe7f7;border-radius:16px;display:flex;flex-direction:column;overflow:hidden">
-          <div style="padding:16px;border-bottom:1px solid #edf1f7;display:flex;justify-content:space-between;align-items:center">
-            <div>
-              <div style="font-size:22px;font-weight:900">对话入口</div>
-              <div style="font-size:13px;color:#69708a;margin-top:4px">系统会识别意图并进入对应流程</div>
-            </div>
-            <div style="background:#f1f0ff;color:#2b1f99;border-radius:999px;padding:7px 11px;font-size:12px;font-weight:800">REGISTRATION</div>
-          </div>
-          <div style="flex:1;padding:16px;display:flex;flex-direction:column;gap:12px;background:#fbfdff">
-            <div style="max-width:72%;background:white;border:1px solid #e1e8f5;border-radius:14px;padding:12px">请直接告诉我你想办理什么,也可以描述症状。</div>
-            <div style="max-width:76%;align-self:flex-end;background:#2b1f99;color:white;border-radius:14px;padding:12px">我头疼三天,还有点恶心,想挂号。</div>
-            <div style="max-width:80%;background:white;border:1px solid #e1e8f5;border-radius:14px;padding:12px">已识别为挂号需求。根据描述,建议优先选择神经内科。</div>
-          </div>
-          <div style="padding:14px;border-top:1px solid #edf1f7;display:flex;gap:10px;background:white">
-            <div style="flex:1;border:1px solid #dce7f7;border-radius:999px;padding:12px 14px;color:#98a1b8">继续输入症状、科室、医生或时间...</div>
-            <div style="background:#3ad4d8;color:#10144a;border-radius:999px;padding:12px 18px;font-weight:900">语音</div>
-            <div style="background:#2b1f99;color:white;border-radius:999px;padding:12px 20px;font-weight:900">发送</div>
-          </div>
-        </main>
-
-        <section style="display:grid;grid-template-rows:auto 1fr;gap:12px">
-          <div style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:14px">
-            <div style="display:flex;justify-content:space-between;align-items:center">
-              <strong>挂号进度</strong>
-              <span style="font-size:12px;color:#69708a">科室推荐</span>
-            </div>
-            <div style="display:grid;grid-template-columns:repeat(5,1fr);gap:5px;margin-top:12px">
-              <div style="height:8px;border-radius:99px;background:#2b1f99"></div>
-              <div style="height:8px;border-radius:99px;background:#3ad4d8"></div>
-              <div style="height:8px;border-radius:99px;background:#dfe7f7"></div>
-              <div style="height:8px;border-radius:99px;background:#dfe7f7"></div>
-              <div style="height:8px;border-radius:99px;background:#dfe7f7"></div>
-            </div>
-          </div>
-
-          <div style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:16px;overflow:hidden">
-            <div style="font-weight:900;font-size:18px;margin-bottom:12px">推荐科室</div>
-            <div style="border:2px solid #3ad4d8;border-radius:14px;padding:12px;margin-bottom:10px;background:#f4fdff">
-              <div style="font-weight:900;color:#2b1f99">神经内科</div>
-              <div style="font-size:12px;color:#68708c;margin-top:6px">头痛伴恶心,建议优先排查神经系统相关问题。</div>
-              <div style="margin-top:12px;background:#2b1f99;color:white;border-radius:999px;text-align:center;padding:9px;font-weight:900">选择神经内科</div>
-            </div>
-            <div style="border:1px solid #dfe7f7;border-radius:14px;padding:12px">
-              <div style="font-weight:900">普通内科</div>
-              <div style="font-size:12px;color:#68708c;margin-top:6px">可作为综合初筛科室。</div>
-              <div style="margin-top:12px;border:1px solid #c8d2ea;border-radius:999px;text-align:center;padding:9px;font-weight:900;color:#2b1f99">选择普通内科</div>
-            </div>
-          </div>
-        </section>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="section">
-  <h3>修订原则</h3>
-  <p>左侧不再是功能菜单,而是“智能体说明 + 可说示例 + 能力范围”。患者仍然可以看到系统能做什么,但不会被要求先点菜单。真正的任务入口来自对话与后端意图识别。</p>
-</div>

+ 0 - 87
.superpowers/brainstorm/86383-1780383912/content/final-web-demo-design-v3.html

@@ -1,87 +0,0 @@
-<h2>最终修订:右侧上下文面板</h2>
-<p class="subtitle">右侧不是固定卡片列表,而是 Context Panel:无卡片时展示静态医生助手形象;有任务卡片时切换为卡片专区。</p>
-
-<div class="split">
-  <div class="mockup">
-    <div class="mockup-header">空闲 / 普通问答状态</div>
-    <div class="mockup-body">
-      <div style="height:420px;border:1px solid #dfe7f7;border-radius:18px;background:#f7fbff;padding:16px;font-family:Inter,Arial,sans-serif;color:#16133a">
-        <div style="display:grid;grid-template-columns:260px 1fr 360px;gap:14px;height:100%">
-          <div style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:16px">
-            <div style="width:62px;height:62px;border-radius:50%;background:radial-gradient(circle,#fff,#3ad4d8 50%,#2b1f99);color:white;display:grid;place-items:center;font-weight:900;margin-bottom:14px">AI</div>
-            <strong>医梦门诊助手</strong>
-            <p style="font-size:12px;color:#69708a">直接说出需求,我来识别。</p>
-          </div>
-          <div style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:16px;display:flex;flex-direction:column">
-            <strong style="font-size:20px">对话入口</strong>
-            <div style="margin-top:18px;background:#f5f9ff;border-radius:14px;padding:12px">你好,我可以帮你完成挂号、导诊、医生查询。</div>
-            <div style="margin-top:auto;border:1px solid #dce7f7;border-radius:999px;padding:12px;color:#98a1b8">说出你的需求...</div>
-          </div>
-          <div style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:18px;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center">
-            <div style="width:150px;height:170px;border-radius:42% 42% 28% 28%;background:linear-gradient(180deg,#f9fbff,#e8f6ff);border:2px solid #dce7f7;position:relative;margin-bottom:18px">
-              <div style="position:absolute;left:45px;top:34px;width:60px;height:60px;border-radius:50%;background:#ffe7d6;border:2px solid #ead2bf"></div>
-              <div style="position:absolute;left:57px;top:54px;width:8px;height:8px;border-radius:50%;background:#2b1f99;box-shadow:28px 0 #2b1f99"></div>
-              <div style="position:absolute;left:66px;top:76px;width:28px;height:10px;border-bottom:3px solid #2b1f99;border-radius:0 0 20px 20px"></div>
-              <div style="position:absolute;left:34px;top:96px;width:82px;height:70px;border-radius:26px 26px 18px 18px;background:#2b1f99"></div>
-              <div style="position:absolute;left:48px;top:106px;width:54px;height:18px;border-radius:999px;background:#3ad4d8"></div>
-            </div>
-            <div style="font-weight:900;font-size:18px">医生助手待命中</div>
-            <div style="font-size:12px;color:#69708a;margin-top:8px">后续可接入 TTS / STT,展示正在听、正在说等状态。</div>
-            <div style="margin-top:16px;display:flex;gap:8px">
-              <span style="background:#f1f0ff;color:#2b1f99;border-radius:999px;padding:7px 10px;font-size:12px">可听</span>
-              <span style="background:#e9fbfc;color:#146f82;border-radius:999px;padding:7px 10px;font-size:12px">可说</span>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-
-  <div class="mockup">
-    <div class="mockup-header">挂号任务 / 卡片状态</div>
-    <div class="mockup-body">
-      <div style="height:420px;border:1px solid #dfe7f7;border-radius:18px;background:#f7fbff;padding:16px;font-family:Inter,Arial,sans-serif;color:#16133a">
-        <div style="display:grid;grid-template-columns:260px 1fr 360px;gap:14px;height:100%">
-          <div style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:16px">
-            <div style="width:62px;height:62px;border-radius:50%;background:radial-gradient(circle,#fff,#3ad4d8 50%,#2b1f99);color:white;display:grid;place-items:center;font-weight:900;margin-bottom:14px">AI</div>
-            <strong>医梦门诊助手</strong>
-            <p style="font-size:12px;color:#69708a">当前已识别:挂号。</p>
-          </div>
-          <div style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:16px;display:flex;flex-direction:column">
-            <strong style="font-size:20px">挂号对话</strong>
-            <div style="margin-top:18px;background:#2b1f99;color:white;border-radius:14px;padding:12px;align-self:flex-end">我头疼三天,想挂号。</div>
-            <div style="margin-top:12px;background:#f5f9ff;border-radius:14px;padding:12px">建议优先选择神经内科。</div>
-            <div style="margin-top:auto;border:1px solid #dce7f7;border-radius:999px;padding:12px;color:#98a1b8">继续输入...</div>
-          </div>
-          <div style="display:grid;grid-template-rows:auto 1fr;gap:12px">
-            <div style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:14px">
-              <strong>挂号进度</strong>
-              <div style="display:grid;grid-template-columns:repeat(5,1fr);gap:5px;margin-top:12px">
-                <div style="height:8px;border-radius:99px;background:#2b1f99"></div>
-                <div style="height:8px;border-radius:99px;background:#3ad4d8"></div>
-                <div style="height:8px;border-radius:99px;background:#dfe7f7"></div>
-                <div style="height:8px;border-radius:99px;background:#dfe7f7"></div>
-                <div style="height:8px;border-radius:99px;background:#dfe7f7"></div>
-              </div>
-            </div>
-            <div style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:16px">
-              <div style="font-weight:900;font-size:18px;margin-bottom:12px">推荐科室</div>
-              <div style="border:2px solid #3ad4d8;border-radius:14px;padding:12px;background:#f4fdff">
-                <div style="font-weight:900;color:#2b1f99">神经内科</div>
-                <div style="font-size:12px;color:#68708c;margin-top:6px">头痛伴恶心,建议优先排查神经系统相关问题。</div>
-                <div style="margin-top:12px;background:#2b1f99;color:white;border-radius:999px;text-align:center;padding:9px;font-weight:900">选择神经内科</div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="section">
-  <h3>状态切换规则</h3>
-  <p><strong>无 activeTask / 无 card_created:</strong>右侧展示医生助手形象。<br>
-  <strong>有 task_updated 或 card_created:</strong>右侧切换为任务进度 + 卡片专区。<br>
-  <strong>流程完成:</strong>展示挂号成功卡片,用户点击“完成”后回到医生助手形象。</p>
-</div>

+ 0 - 74
.superpowers/brainstorm/86383-1780383912/content/final-web-demo-design-v4.html

@@ -1,74 +0,0 @@
-<h2>最终版交互定稿:医生形象仅展示</h2>
-<p class="subtitle">右侧空闲态只放静态医生形象;语音与发送按钮保留在中间对话输入区。</p>
-
-<div class="mockup">
-  <div class="mockup-header">空闲态:右侧只展示形象,不承载输入操作</div>
-  <div class="mockup-body">
-    <div style="height:520px;border:1px solid #dfe7f7;border-radius:18px;background:#f7fbff;overflow:hidden;font-family:Inter,Arial,sans-serif;color:#16133a">
-      <div style="height:58px;background:white;border-bottom:1px solid #e7ebf5;display:flex;align-items:center;justify-content:space-between;padding:0 22px">
-        <div style="display:flex;align-items:center;gap:12px">
-          <div style="width:34px;height:34px;border-radius:10px;background:#2b1f99;color:white;display:grid;place-items:center;font-weight:900">医</div>
-          <div style="font-weight:900">医梦门诊助手</div>
-        </div>
-        <div style="font-size:13px;color:#69708a">Web Demo · 门诊大厅 · 联调演示</div>
-      </div>
-
-      <div style="display:grid;grid-template-columns:280px 1fr 390px;gap:16px;padding:16px;height:462px">
-        <aside style="background:linear-gradient(180deg,#ffffff,#f1fbff);border:1px solid #dfe7f7;border-radius:16px;padding:18px;display:flex;flex-direction:column">
-          <div style="display:flex;gap:12px;align-items:center;margin-bottom:18px">
-            <div style="width:70px;height:70px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#ffffff,#3ad4d8 45%,#2b1f99);display:grid;place-items:center;font-size:24px;font-weight:900;color:white">AI</div>
-            <div>
-              <div style="font-weight:900;font-size:18px">你好,我在</div>
-              <div style="font-size:12px;color:#68708c;margin-top:4px">说出需求,我来判断下一步</div>
-            </div>
-          </div>
-          <div style="border:1px solid #dce7f8;border-radius:14px;background:white;padding:14px">
-            <div style="font-size:12px;color:#69708a;margin-bottom:8px">可以这样说</div>
-            <div style="display:grid;gap:8px;font-size:13px">
-              <div style="background:#f4fbff;border-radius:10px;padding:9px">“我头疼三天,想挂号”</div>
-              <div style="background:#f4fbff;border-radius:10px;padding:9px">“明天上午有神经内科的号吗”</div>
-              <div style="background:#f4fbff;border-radius:10px;padding:9px">“我想找李明医生”</div>
-            </div>
-          </div>
-          <div style="margin-top:auto;background:#fff8e8;border:1px solid #f0d89c;border-radius:12px;padding:12px;font-size:12px;color:#735b14">
-            Mock 结果显示“联调演示”,不伪装成真实业务。
-          </div>
-        </aside>
-
-        <main style="background:white;border:1px solid #dfe7f7;border-radius:16px;display:flex;flex-direction:column;overflow:hidden">
-          <div style="padding:16px;border-bottom:1px solid #edf1f7">
-            <div style="font-size:22px;font-weight:900">对话入口</div>
-            <div style="font-size:13px;color:#69708a;margin-top:4px">系统会识别意图并进入对应流程</div>
-          </div>
-          <div style="flex:1;padding:16px;display:flex;flex-direction:column;gap:12px;background:#fbfdff">
-            <div style="max-width:72%;background:white;border:1px solid #e1e8f5;border-radius:14px;padding:12px">请直接告诉我你想办理什么,也可以描述症状。</div>
-            <div style="max-width:76%;align-self:flex-end;background:#2b1f99;color:white;border-radius:14px;padding:12px">我头疼三天,还有点恶心,想挂号。</div>
-            <div style="max-width:80%;background:white;border:1px solid #e1e8f5;border-radius:14px;padding:12px">已识别为挂号需求。根据描述,建议优先选择神经内科。</div>
-          </div>
-          <div style="padding:14px;border-top:1px solid #edf1f7;display:flex;gap:10px;background:white">
-            <div style="flex:1;border:1px solid #dce7f7;border-radius:999px;padding:12px 14px;color:#98a1b8">继续输入症状、科室、医生或时间...</div>
-            <div style="background:#3ad4d8;color:#10144a;border-radius:999px;padding:12px 18px;font-weight:900">语音</div>
-            <div style="background:#2b1f99;color:white;border-radius:999px;padding:12px 20px;font-weight:900">发送</div>
-          </div>
-        </main>
-
-        <section style="background:white;border:1px solid #dfe7f7;border-radius:16px;padding:18px;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center">
-          <div style="width:180px;height:210px;border-radius:42% 42% 28% 28%;background:linear-gradient(180deg,#f9fbff,#e8f6ff);border:2px solid #dce7f7;position:relative;margin-bottom:18px;box-shadow:0 20px 48px rgba(43,31,153,.12)">
-            <div style="position:absolute;left:55px;top:40px;width:70px;height:70px;border-radius:50%;background:#ffe7d6;border:2px solid #ead2bf"></div>
-            <div style="position:absolute;left:70px;top:64px;width:8px;height:8px;border-radius:50%;background:#2b1f99;box-shadow:32px 0 #2b1f99"></div>
-            <div style="position:absolute;left:79px;top:88px;width:32px;height:10px;border-bottom:3px solid #2b1f99;border-radius:0 0 20px 20px"></div>
-            <div style="position:absolute;left:44px;top:116px;width:92px;height:86px;border-radius:28px 28px 18px 18px;background:#2b1f99"></div>
-            <div style="position:absolute;left:58px;top:128px;width:64px;height:20px;border-radius:999px;background:#3ad4d8"></div>
-          </div>
-          <div style="font-weight:900;font-size:20px">医生助手</div>
-          <div style="font-size:13px;color:#69708a;margin-top:8px;max-width:260px">当前仅作为静态形象展示。语音与发送操作仍在中间输入区完成。</div>
-        </section>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="section">
-  <h3>定稿规则</h3>
-  <p>右侧空闲态只展示静态医生形象和一句说明;不放语音按钮、不放发送按钮、不放可听/可说标签。只有收到 `task_updated` 或 `card_created` 后,右侧才切换为任务进度和业务卡片。</p>
-</div>

+ 0 - 89
.superpowers/brainstorm/86383-1780383912/content/final-web-demo-design.html

@@ -1,89 +0,0 @@
-<h2>最终设计:A+B 单应用 Web Demo</h2>
-<p class="subtitle">面向 1440×900 / 1920×1080 演示视口,完整打穿挂号闭环。</p>
-
-<div class="mockup">
-  <div class="mockup-header">主界面结构</div>
-  <div class="mockup-body">
-    <div style="height:520px;border:1px solid #dfe8e5;border-radius:18px;background:#f6fbfa;overflow:hidden;font-family:Inter,Arial,sans-serif;color:#17211f">
-      <div style="height:58px;background:white;border-bottom:1px solid #e4eeeb;display:flex;align-items:center;justify-content:space-between;padding:0 22px">
-        <div style="display:flex;align-items:center;gap:12px">
-          <div style="width:34px;height:34px;border-radius:10px;background:#16a37b;color:white;display:grid;place-items:center;font-weight:900">医</div>
-          <div style="font-weight:900">医梦门诊助手</div>
-        </div>
-        <div style="font-size:13px;color:#667773">Web Demo · 门诊大厅 · 联调演示</div>
-      </div>
-
-      <div style="display:grid;grid-template-columns:260px 1fr 380px;gap:16px;padding:16px;height:462px">
-        <aside style="background:white;border:1px solid #dfe9e6;border-radius:16px;padding:16px;display:flex;flex-direction:column">
-          <div style="display:flex;gap:12px;align-items:center;margin-bottom:18px">
-            <div style="width:62px;height:62px;border-radius:50%;background:linear-gradient(145deg,#e2fbf2,#8ee0c3);display:grid;place-items:center;font-size:28px;font-weight:900;color:#0d765e">AI</div>
-            <div>
-              <div style="font-weight:900">你好</div>
-              <div style="font-size:12px;color:#697a76">我来帮你完成挂号</div>
-            </div>
-          </div>
-          <div style="display:grid;gap:10px">
-            <div style="background:#eaf8f3;border:1px solid #bfeadc;border-radius:12px;padding:12px;font-weight:900">智能挂号</div>
-            <div style="border:1px solid #e3ece9;border-radius:12px;padding:12px;color:#667773">科室导诊</div>
-            <div style="border:1px solid #e3ece9;border-radius:12px;padding:12px;color:#667773">查医生</div>
-            <div style="border:1px solid #e3ece9;border-radius:12px;padding:12px;color:#667773">路线引导</div>
-          </div>
-          <div style="margin-top:auto;background:#fff8e6;border:1px solid #f1d99c;border-radius:12px;padding:12px;font-size:12px;color:#765b12">
-            Mock 支付与 Mock HIS 结果必须标注“联调演示”。
-          </div>
-        </aside>
-
-        <main style="background:white;border:1px solid #dfe9e6;border-radius:16px;display:flex;flex-direction:column;overflow:hidden">
-          <div style="padding:16px;border-bottom:1px solid #edf3f1">
-            <div style="font-size:22px;font-weight:900">挂号对话</div>
-            <div style="font-size:13px;color:#667773;margin-top:4px">可以说症状、科室、医生或时间</div>
-          </div>
-          <div style="flex:1;padding:16px;display:flex;flex-direction:column;gap:12px">
-            <div style="max-width:70%;background:#f0f6f4;border-radius:14px;padding:12px">我可以帮你推荐科室、选择医生和预约时间。</div>
-            <div style="max-width:76%;align-self:flex-end;background:#16a37b;color:white;border-radius:14px;padding:12px">我头疼三天,还有点恶心,想挂号。</div>
-            <div style="max-width:78%;background:#f0f6f4;border-radius:14px;padding:12px">建议优先选择神经内科,也可选择普通内科。</div>
-          </div>
-          <div style="padding:14px;border-top:1px solid #edf3f1;display:flex;gap:10px">
-            <div style="flex:1;border:1px solid #dce8e5;border-radius:999px;padding:12px 14px;color:#98a7a3">输入你的需求...</div>
-            <div style="background:#16a37b;color:white;border-radius:999px;padding:12px 20px;font-weight:900">发送</div>
-          </div>
-        </main>
-
-        <section style="display:grid;grid-template-rows:auto 1fr;gap:12px">
-          <div style="background:white;border:1px solid #dfe9e6;border-radius:16px;padding:14px">
-            <div style="display:flex;justify-content:space-between;align-items:center">
-              <strong>挂号进度</strong>
-              <span style="font-size:12px;color:#667773">2 / 5</span>
-            </div>
-            <div style="display:grid;grid-template-columns:repeat(5,1fr);gap:5px;margin-top:12px">
-              <div style="height:8px;border-radius:99px;background:#16a37b"></div>
-              <div style="height:8px;border-radius:99px;background:#16a37b"></div>
-              <div style="height:8px;border-radius:99px;background:#dfe8e5"></div>
-              <div style="height:8px;border-radius:99px;background:#dfe8e5"></div>
-              <div style="height:8px;border-radius:99px;background:#dfe8e5"></div>
-            </div>
-          </div>
-
-          <div style="background:white;border:1px solid #dfe9e6;border-radius:16px;padding:16px;overflow:hidden">
-            <div style="font-weight:900;font-size:18px;margin-bottom:12px">推荐科室</div>
-            <div style="border:1px solid #dfe8e5;border-radius:14px;padding:12px;margin-bottom:10px">
-              <div style="font-weight:900">神经内科</div>
-              <div style="font-size:12px;color:#667773;margin-top:6px">头痛伴恶心,建议优先排查神经系统相关问题。</div>
-              <div style="margin-top:12px;background:#16a37b;color:white;border-radius:999px;text-align:center;padding:9px;font-weight:900">选择</div>
-            </div>
-            <div style="border:1px solid #dfe8e5;border-radius:14px;padding:12px">
-              <div style="font-weight:900">普通内科</div>
-              <div style="font-size:12px;color:#667773;margin-top:6px">可作为综合初筛科室。</div>
-              <div style="margin-top:12px;border:1px solid #b9d9cf;border-radius:999px;text-align:center;padding:9px;font-weight:900">选择</div>
-            </div>
-          </div>
-        </section>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="section">
-  <h3>设计边界</h3>
-  <p>首版只有一个 Web 应用,但目录按未来可拆包组织。核心功能只做挂号闭环;科室导诊、查医生、路线引导在侧栏可见,但点击后展示“演示暂未开放/可后续接入”。</p>
-</div>

+ 0 - 82
.superpowers/brainstorm/86383-1780383912/content/registration-flow-ab.html

@@ -1,82 +0,0 @@
-<h2>A+B 混合方案:挂号闭环交互图</h2>
-<p class="subtitle">第一屏亲和助手,进入挂号后切成“对话 + 流程进度 + 业务卡片”的工作台。</p>
-
-<div class="mockup">
-  <div class="mockup-header">推荐交互流:Web 演示优先 · 挂号闭环</div>
-  <div class="mockup-body">
-    <div style="display:grid;grid-template-columns:1fr 34px 1fr 34px 1fr;gap:10px;align-items:stretch">
-      <div style="border:1px solid #dce8e4;border-radius:14px;background:#f8fcfb;padding:16px">
-        <div style="font-size:12px;color:#6b7b78;margin-bottom:8px">01 首页</div>
-        <div style="font-weight:900;font-size:20px;margin-bottom:10px">亲和助手入口</div>
-        <div style="height:72px;border-radius:16px;background:linear-gradient(135deg,#e8fbf4,#b4ead9);display:flex;align-items:center;padding:12px;font-weight:800">你好,我来帮你挂号</div>
-        <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:12px">
-          <div style="background:white;border:1px solid #dce8e4;border-radius:10px;padding:10px">我要挂号</div>
-          <div style="background:white;border:1px solid #dce8e4;border-radius:10px;padding:10px">科室导诊</div>
-        </div>
-      </div>
-      <div style="display:grid;place-items:center;font-size:24px;color:#7b8b87">→</div>
-      <div style="border:1px solid #dce8e4;border-radius:14px;background:#ffffff;padding:16px">
-        <div style="font-size:12px;color:#6b7b78;margin-bottom:8px">02 对话启动</div>
-        <div style="font-weight:900;font-size:20px;margin-bottom:10px">症状或科室进入</div>
-        <div style="background:#f0f6f4;border-radius:12px;padding:10px;margin-bottom:8px">“我头疼三天,想挂号”</div>
-        <div style="background:#159b78;color:white;border-radius:12px;padding:10px">SSE 返回任务 + 首张卡片</div>
-      </div>
-      <div style="display:grid;place-items:center;font-size:24px;color:#7b8b87">→</div>
-      <div style="border:1px solid #dce8e4;border-radius:14px;background:#f7fafc;padding:16px">
-        <div style="font-size:12px;color:#6b7b78;margin-bottom:8px">03 工作台</div>
-        <div style="font-weight:900;font-size:20px;margin-bottom:10px">对话 + 流程 + 卡片</div>
-        <div style="display:grid;grid-template-columns:1fr 120px;gap:8px">
-          <div style="height:96px;background:white;border:1px solid #dfe8ec;border-radius:12px;padding:10px">对话消息流</div>
-          <div style="height:96px;background:white;border:1px solid #dfe8ec;border-radius:12px;padding:10px">挂号进度<br>2/5</div>
-        </div>
-      </div>
-    </div>
-
-    <div style="margin-top:22px;display:grid;grid-template-columns:repeat(5,1fr);gap:10px">
-      <div style="background:white;border:1px solid #dfe8ec;border-radius:14px;padding:12px">
-        <strong>科室</strong>
-        <p style="margin:6px 0 0;color:#65736f">推荐理由 + 选择</p>
-      </div>
-      <div style="background:white;border:1px solid #dfe8ec;border-radius:14px;padding:12px">
-        <strong>医生</strong>
-        <p style="margin:6px 0 0;color:#65736f">职称、擅长、诊室</p>
-      </div>
-      <div style="background:white;border:1px solid #dfe8ec;border-radius:14px;padding:12px">
-        <strong>时间</strong>
-        <p style="margin:6px 0 0;color:#65736f">号源剩余 + 锁号</p>
-      </div>
-      <div style="background:white;border:1px solid #dfe8ec;border-radius:14px;padding:12px">
-        <strong>Mock 支付</strong>
-        <p style="margin:6px 0 0;color:#65736f">二维码 + 模拟支付</p>
-      </div>
-      <div style="background:white;border:1px solid #dfe8ec;border-radius:14px;padding:12px">
-        <strong>成功</strong>
-        <p style="margin:6px 0 0;color:#65736f">预约号 + Mock 标识</p>
-      </div>
-    </div>
-  </div>
-</div>
-
-<div class="options">
-  <div class="option" data-choice="route-1" onclick="toggleSelect(this)">
-    <div class="letter">1</div>
-    <div class="content">
-      <h3>推荐:单应用 Web Demo</h3>
-      <p>一个 Vite/Vue 应用,固定 Web 演示视口,内置 mock/fallback 数据,同时接真实后端 API。最快产出演示效果。</p>
-    </div>
-  </div>
-  <div class="option" data-choice="route-2" onclick="toggleSelect(this)">
-    <div class="letter">2</div>
-    <div class="content">
-      <h3>Monorepo 正式版</h3>
-      <p>直接搭 `apps/kiosk-client + packages/api-client + medical-cards`。更接近长期工程,但首版搭建和测试成本更高。</p>
-    </div>
-  </div>
-  <div class="option" data-choice="route-3" onclick="toggleSelect(this)">
-    <div class="letter">3</div>
-    <div class="content">
-      <h3>纯静态原型先行</h3>
-      <p>先做 HTML/静态交互演示,再接 API。视觉最快,但很容易偏离真实后端协议,不建议作为开发计划主线。</p>
-    </div>
-  </div>
-</div>

+ 0 - 132
.superpowers/brainstorm/86383-1780383912/content/ui-direction-options.html

@@ -1,132 +0,0 @@
-<h2>统一入口客户端 UI 方向</h2>
-<p class="subtitle">三种“AI 健康朋友 + 医院服务办理”的首页与对话布局。请选择最接近你想要的方向。</p>
-
-<div class="cards">
-  <div class="card" data-choice="a" onclick="toggleSelect(this)">
-    <div class="card-image">
-      <div style="height:420px;border-radius:18px;background:#f7fbfa;border:1px solid #dbe8e4;overflow:hidden;font-family:Inter,Arial,sans-serif;color:#17211f">
-        <div style="display:flex;justify-content:space-between;align-items:center;padding:18px 22px;background:white;border-bottom:1px solid #e8efed">
-          <div style="font-weight:800;font-size:18px">医梦门诊助手</div>
-          <div style="font-size:12px;color:#6c7b77">门诊大厅 · 自助服务</div>
-        </div>
-        <div style="padding:26px 26px 18px">
-          <div style="display:flex;gap:18px;align-items:center">
-            <div style="width:86px;height:86px;border-radius:50%;background:linear-gradient(145deg,#dff7ef,#8ee0c3);display:grid;place-items:center;font-size:38px">+</div>
-            <div>
-              <div style="font-size:26px;font-weight:900;line-height:1.25">你好,我来帮你挂号</div>
-              <div style="margin-top:8px;font-size:14px;color:#667773">可以说症状、科室、医生或时间</div>
-            </div>
-          </div>
-          <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:24px">
-            <div style="background:white;border:1px solid #dfecea;border-radius:14px;padding:14px;font-weight:700">我要挂号</div>
-            <div style="background:white;border:1px solid #dfecea;border-radius:14px;padding:14px;font-weight:700">科室导诊</div>
-            <div style="background:white;border:1px solid #dfecea;border-radius:14px;padding:14px;font-weight:700">查医生</div>
-            <div style="background:white;border:1px solid #dfecea;border-radius:14px;padding:14px;font-weight:700">路线引导</div>
-          </div>
-          <div style="margin-top:24px;background:white;border:1px solid #dce9e6;border-radius:18px;padding:16px">
-            <div style="font-size:13px;color:#60706c;margin-bottom:8px">你可以直接说</div>
-            <div style="font-size:20px;font-weight:800">“我头疼三天,还有点恶心,想挂号”</div>
-          </div>
-        </div>
-        <div style="margin:0 26px 24px;display:flex;background:white;border:1px solid #dce9e6;border-radius:999px;padding:10px 12px;align-items:center;gap:10px">
-          <div style="flex:1;color:#9aa6a3">输入或语音说明你的需求</div>
-          <div style="background:#16a37b;color:white;border-radius:999px;padding:9px 16px;font-weight:800">发送</div>
-        </div>
-      </div>
-    </div>
-    <div class="card-body">
-      <h3>A. 亲和陪伴式</h3>
-      <p>大助手形象 + 少量快捷入口 + 大输入框。最像“健康朋友”,适合甲方演示第一眼建立亲近感。</p>
-    </div>
-  </div>
-
-  <div class="card" data-choice="b" onclick="toggleSelect(this)">
-    <div class="card-image">
-      <div style="height:420px;border-radius:18px;background:#f5f8ff;border:1px solid #dbe4f5;overflow:hidden;font-family:Inter,Arial,sans-serif;color:#172033">
-        <div style="display:flex;height:100%">
-          <div style="width:118px;background:#ffffff;border-right:1px solid #e4ebf5;padding:18px 12px">
-            <div style="font-weight:900;margin-bottom:24px">医梦</div>
-            <div style="display:grid;gap:10px;font-size:13px">
-              <div style="background:#e9f1ff;border-radius:12px;padding:10px;font-weight:800">挂号</div>
-              <div style="padding:10px;color:#68758a">导诊</div>
-              <div style="padding:10px;color:#68758a">医生</div>
-              <div style="padding:10px;color:#68758a">路线</div>
-            </div>
-          </div>
-          <div style="flex:1;padding:18px">
-            <div style="display:flex;justify-content:space-between;margin-bottom:14px">
-              <div style="font-size:20px;font-weight:900">门诊统一入口</div>
-              <div style="font-size:12px;color:#637186">EMOON-KIOSK-001</div>
-            </div>
-            <div style="display:grid;grid-template-columns:1.1fr .9fr;gap:14px;height:335px">
-              <div style="background:white;border:1px solid #dfe7f2;border-radius:16px;padding:16px;display:flex;flex-direction:column">
-                <div style="background:#f2f6ff;border-radius:14px;padding:12px;margin-bottom:10px;font-size:14px">您好,请描述症状或选择服务。</div>
-                <div style="align-self:flex-end;background:#316ff6;color:white;border-radius:14px;padding:12px;font-size:14px">我想挂神经内科</div>
-                <div style="margin-top:auto;border:1px solid #e2e8f2;border-radius:999px;padding:10px;color:#8a96a8">继续输入...</div>
-              </div>
-              <div style="display:grid;gap:12px">
-                <div style="background:white;border:1px solid #dfe7f2;border-radius:16px;padding:14px">
-                  <div style="font-size:13px;color:#6c798c">当前流程</div>
-                  <div style="font-weight:900;margin-top:6px">挂号 · 选择科室</div>
-                  <div style="height:8px;background:#e8eef7;border-radius:99px;margin-top:14px"><div style="width:38%;height:8px;background:#316ff6;border-radius:99px"></div></div>
-                </div>
-                <div style="background:white;border:1px solid #dfe7f2;border-radius:16px;padding:14px">
-                  <div style="font-weight:900;margin-bottom:10px">推荐科室</div>
-                  <div style="border:1px solid #e4ebf5;border-radius:12px;padding:10px;margin-bottom:8px">神经内科</div>
-                  <div style="border:1px solid #e4ebf5;border-radius:12px;padding:10px">普通内科</div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="card-body">
-      <h3>B. 办理工作台式</h3>
-      <p>左侧服务导航 + 中间对话 + 右侧流程/卡片。更像自助机业务界面,现场办理效率高。</p>
-    </div>
-  </div>
-
-  <div class="card" data-choice="c" onclick="toggleSelect(this)">
-    <div class="card-image">
-      <div style="height:420px;border-radius:18px;background:#fbfbf8;border:1px solid #e7e3d8;overflow:hidden;font-family:Inter,Arial,sans-serif;color:#28251f">
-        <div style="padding:18px 22px;display:flex;justify-content:space-between;align-items:center">
-          <div>
-            <div style="font-size:13px;color:#817a6b">医梦未来医院</div>
-            <div style="font-size:24px;font-weight:900">今天想办理什么?</div>
-          </div>
-          <div style="width:54px;height:54px;border-radius:50%;background:#1f9d7a;color:white;display:grid;place-items:center;font-weight:900">AI</div>
-        </div>
-        <div style="padding:0 22px;display:grid;grid-template-columns:repeat(3,1fr);gap:12px">
-          <div style="background:white;border:1px solid #e6e0d5;border-radius:16px;padding:16px;height:86px"><b>智能挂号</b><br><span style="font-size:12px;color:#7b7468">症状导诊选医生</span></div>
-          <div style="background:white;border:1px solid #e6e0d5;border-radius:16px;padding:16px;height:86px"><b>查科室</b><br><span style="font-size:12px;color:#7b7468">位置与擅长</span></div>
-          <div style="background:white;border:1px solid #e6e0d5;border-radius:16px;padding:16px;height:86px"><b>查路线</b><br><span style="font-size:12px;color:#7b7468">楼层导航</span></div>
-        </div>
-        <div style="margin:18px 22px;background:white;border:1px solid #e6e0d5;border-radius:20px;padding:16px;height:180px">
-          <div style="display:flex;gap:12px;margin-bottom:12px">
-            <div style="width:38px;height:38px;border-radius:50%;background:#dff3ea"></div>
-            <div style="background:#f5f3ed;border-radius:14px;padding:10px 12px;flex:1">可以直接告诉我症状,我会推荐科室,再帮你选择医生和时间。</div>
-          </div>
-          <div style="display:flex;gap:8px;flex-wrap:wrap">
-            <span style="border:1px solid #ded7cb;border-radius:999px;padding:8px 10px;font-size:12px">头疼想挂号</span>
-            <span style="border:1px solid #ded7cb;border-radius:999px;padding:8px 10px;font-size:12px">明天上午有号吗</span>
-            <span style="border:1px solid #ded7cb;border-radius:999px;padding:8px 10px;font-size:12px">找李明医生</span>
-          </div>
-        </div>
-        <div style="margin:0 22px;background:#202720;color:white;border-radius:20px;padding:14px;display:flex;justify-content:space-between;align-items:center">
-          <span>按住说话或输入文字</span>
-          <span style="background:white;color:#202720;border-radius:999px;padding:8px 14px;font-weight:800">开始</span>
-        </div>
-      </div>
-    </div>
-    <div class="card-body">
-      <h3>C. 服务入口式</h3>
-      <p>先服务卡片,后对话承接。更清晰、更不容易迷路,适合大屏/自助机,但“朋友感”弱一些。</p>
-    </div>
-  </div>
-</div>
-
-<div class="section">
-  <h3>建议</h3>
-  <p>我建议用 <strong>A + B 的混合</strong>:第一屏保持 A 的亲和感,对话进入挂号后切到 B 的右侧流程卡片区。这样既像“AI 健康朋友”,又能支撑真实挂号办理。</p>
-</div>

+ 0 - 206
scripts/demo-registration/registration-tool-flow.sh

@@ -1,206 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-# Default demo backend URL. Override with:
-#   BASE_URL=http://localhost:8080 ./scripts/demo-registration/registration-tool-flow.sh
-BASE_URL="${BASE_URL:-http://localhost:8080}"
-
-PROJECT_ID="${PROJECT_ID:-demo-registration}"
-TRACE_ID="${TRACE_ID:-trace-demo-registration-$(date +%Y%m%d%H%M%S)}"
-PATIENT_ID="${PATIENT_ID:-patient_demo_001}"
-PATIENT_PHONE="${PATIENT_PHONE:-13800000001}"
-PATIENT_ID_CARD="${PATIENT_ID_CARD:-110101199001010011}"
-PATIENT_NAME="${PATIENT_NAME:-张三}"
-DEPARTMENT_ID="${DEPARTMENT_ID:-dept_neurology}"
-DOCTOR_ID="${DOCTOR_ID:-doctor_neuro_001}"
-SCHEDULE_ID="${SCHEDULE_ID:-schedule_neuro_001_d1_am}"
-SCHEDULE_DATE="${SCHEDULE_DATE:-}"
-LOCK_ID="${LOCK_ID:-}"
-ORDER_ID="${ORDER_ID:-}"
-
-has_jq=false
-if command -v jq >/dev/null 2>&1; then
-  has_jq=true
-fi
-
-json_quote() {
-  if [ "$has_jq" = true ]; then
-    jq -Rn --arg value "$1" '$value'
-    return
-  fi
-  printf '"%s"' "$(printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g')"
-}
-
-extract_json_string() {
-  local json="$1"
-  local filter="$2"
-  if [ "$has_jq" = false ]; then
-    return 1
-  fi
-  printf '%s' "$json" | jq -er "$filter // empty"
-}
-
-request_body() {
-  local tool_call_id="$1"
-  local risk_level="$2"
-  local input_json="$3"
-
-  cat <<JSON
-{
-  "toolCallId": "$tool_call_id",
-  "context": {
-    "projectId": "$PROJECT_ID",
-    "traceId": "$TRACE_ID"
-  },
-  "input": $input_json,
-  "riskLevel": "$risk_level"
-}
-JSON
-}
-
-get_catalog() {
-  echo
-  echo "GET ${BASE_URL}/tools/catalog"
-  echo "Expected markers for invoke responses: mock=true, status=success"
-  curl -sS \
-    -H "Accept: application/json" \
-    "${BASE_URL}/tools/catalog"
-  echo
-}
-
-invoke_tool() {
-  local tool_name="$1"
-  local risk_level="$2"
-  local input_json="$3"
-  local idempotency_key="${4:-}"
-  local tool_call_id="demo-${tool_name//./-}-$(date +%s)"
-  local body
-  body="$(request_body "$tool_call_id" "$risk_level" "$input_json")"
-
-  echo >&2
-  echo "POST ${BASE_URL}/tools/${tool_name}/invoke" >&2
-  if [ -n "$idempotency_key" ]; then
-    echo "X-Emoon-Idempotency-Key: ${idempotency_key}" >&2
-  fi
-  echo "Expected markers: mock=true, status=success" >&2
-  case "$tool_name" in
-    payment.*)
-      echo "Expected payment marker: mockPayment=true" >&2
-      ;;
-  esac
-
-  if [ -n "$idempotency_key" ]; then
-    curl -sS \
-      -H "Accept: application/json" \
-      -H "Content-Type: application/json" \
-      -H "X-Emoon-Idempotency-Key: ${idempotency_key}" \
-      -d "$body" \
-      "${BASE_URL}/tools/${tool_name}/invoke"
-  else
-    curl -sS \
-      -H "Accept: application/json" \
-      -H "Content-Type: application/json" \
-      -d "$body" \
-      "${BASE_URL}/tools/${tool_name}/invoke"
-  fi
-  echo >&2
-}
-
-require_dynamic_id() {
-  local name="$1"
-  local value="$2"
-  local hint="$3"
-  if [ -n "$value" ]; then
-    return
-  fi
-
-  cat >&2 <<EOF
-
-Missing ${name}.
-Install jq to auto-extract dynamic IDs, or rerun with ${name}=... after copying it from the previous response.
-${hint}
-EOF
-  exit 1
-}
-
-echo "Demo registration tool flow"
-echo "BASE_URL=${BASE_URL}"
-echo "PROJECT_ID=${PROJECT_ID}"
-echo "TRACE_ID=${TRACE_ID}"
-echo "Seed values: patientId=${PATIENT_ID}, departmentId=${DEPARTMENT_ID}, doctorId=${DOCTOR_ID}, scheduleId=${SCHEDULE_ID}"
-if [ "$has_jq" = false ]; then
-  echo "jq not found: the script will still issue fixed-ID reads/writes, but dynamic lockId/orderId extraction requires jq or LOCK_ID/ORDER_ID env overrides."
-fi
-
-get_catalog
-
-search_patient_response="$(invoke_tool \
-  "his.searchPatient" \
-  "L2_SENSITIVE_READ" \
-  "{\"phone\":$(json_quote "$PATIENT_PHONE"),\"idCard\":$(json_quote "$PATIENT_ID_CARD")}")"
-printf '%s\n' "$search_patient_response"
-
-departments_response="$(invoke_tool \
-  "his.queryDepartments" \
-  "L1_QUERY" \
-  "{}")"
-printf '%s\n' "$departments_response"
-
-doctors_response="$(invoke_tool \
-  "his.queryDoctors" \
-  "L1_QUERY" \
-  "{\"departmentId\":$(json_quote "$DEPARTMENT_ID")}")"
-printf '%s\n' "$doctors_response"
-
-schedule_input="{\"doctorId\":$(json_quote "$DOCTOR_ID")}"
-if [ -n "$SCHEDULE_DATE" ]; then
-  schedule_input="{\"doctorId\":$(json_quote "$DOCTOR_ID"),\"date\":$(json_quote "$SCHEDULE_DATE")}"
-fi
-schedules_response="$(invoke_tool \
-  "his.querySchedules" \
-  "L1_QUERY" \
-  "$schedule_input")"
-printf '%s\n' "$schedules_response"
-
-lock_idempotency_key="demo-lock-${TRACE_ID}"
-lock_response="$(invoke_tool \
-  "his.lockSchedule" \
-  "L3_BUSINESS_WRITE" \
-  "{\"scheduleId\":$(json_quote "$SCHEDULE_ID"),\"patientId\":$(json_quote "$PATIENT_ID")}" \
-  "$lock_idempotency_key")"
-printf '%s\n' "$lock_response"
-if [ -z "$LOCK_ID" ] && [ "$has_jq" = true ]; then
-  LOCK_ID="$(extract_json_string "$lock_response" '.data.result.lock.lockId')"
-fi
-require_dynamic_id "LOCK_ID" "$LOCK_ID" "Expected path with jq: .data.result.lock.lockId"
-
-order_idempotency_key="demo-payment-order-${TRACE_ID}"
-order_response="$(invoke_tool \
-  "payment.createOrder" \
-  "L4_FINANCIAL_ACTION" \
-  "{\"lockId\":$(json_quote "$LOCK_ID")}" \
-  "$order_idempotency_key")"
-printf '%s\n' "$order_response"
-if [ -z "$ORDER_ID" ] && [ "$has_jq" = true ]; then
-  ORDER_ID="$(extract_json_string "$order_response" '.data.result.order.orderId')"
-fi
-require_dynamic_id "ORDER_ID" "$ORDER_ID" "Expected path with jq: .data.result.order.orderId"
-
-paid_idempotency_key="demo-mark-paid-${TRACE_ID}"
-paid_response="$(invoke_tool \
-  "payment.markMockPaid" \
-  "L4_FINANCIAL_ACTION" \
-  "{\"orderId\":$(json_quote "$ORDER_ID")}" \
-  "$paid_idempotency_key")"
-printf '%s\n' "$paid_response"
-
-registration_idempotency_key="demo-registration-${TRACE_ID}"
-registration_response="$(invoke_tool \
-  "his.createRegistration" \
-  "L3_BUSINESS_WRITE" \
-  "{\"lockId\":$(json_quote "$LOCK_ID"),\"orderId\":$(json_quote "$ORDER_ID"),\"patientId\":$(json_quote "$PATIENT_ID"),\"patientName\":$(json_quote "$PATIENT_NAME"),\"patientIdCard\":$(json_quote "$PATIENT_ID_CARD"),\"patientPhone\":$(json_quote "$PATIENT_PHONE"),\"departmentId\":$(json_quote "$DEPARTMENT_ID"),\"doctorId\":$(json_quote "$DOCTOR_ID"),\"slotId\":$(json_quote "$SCHEDULE_ID")}" \
-  "$registration_idempotency_key")"
-printf '%s\n' "$registration_response"
-
-echo
-echo "Flow complete. Expected final markers: mock=true, status=success"

+ 0 - 15
scripts/demo-registration/tools-catalog.sh

@@ -1,15 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-# Default demo backend URL. Override with:
-#   BASE_URL=http://localhost:8080 ./scripts/demo-registration/tools-catalog.sh
-BASE_URL="${BASE_URL:-http://localhost:8080}"
-
-echo "GET ${BASE_URL}/tools/catalog"
-echo "Expected markers in catalog/demo responses: mock=true, status=success"
-
-curl -sS \
-  -H "Accept: application/json" \
-  "${BASE_URL}/tools/catalog"
-
-echo

+ 0 - 273
scripts/render_ai_platform_architecture.py

@@ -1,273 +0,0 @@
-from PIL import Image, ImageDraw, ImageFont
-from pathlib import Path
-import textwrap
-
-
-ROOT = Path(__file__).resolve().parents[1]
-OUT = ROOT / "docs/assets/ai-platform-module-architecture-map.png"
-
-W, H = 5250, 3300
-BG = "#F6FAFF"
-INK = "#102A5C"
-MUTED = "#536B90"
-BLUE = "#0D63CE"
-CYAN = "#00A7C7"
-PURPLE = "#6B3FD6"
-GREEN = "#10A37F"
-ORANGE = "#F28C28"
-RED = "#D94B4B"
-LINE = "#B9D4F4"
-CARD = "#FFFFFF"
-
-
-def font(size, bold=False):
-    candidates = [
-        "/System/Library/Fonts/Hiragino Sans GB.ttc",
-        "/System/Library/Fonts/STHeiti Medium.ttc" if bold else "/System/Library/Fonts/STHeiti Light.ttc",
-        "/System/Library/Fonts/Supplemental/Arial Unicode.ttf",
-    ]
-    for p in candidates:
-        if Path(p).exists():
-            return ImageFont.truetype(p, size=size, index=0)
-    return ImageFont.load_default()
-
-
-F = {
-    "title": font(74, True),
-    "sub": font(34),
-    "h1": font(42, True),
-    "h2": font(34, True),
-    "body": font(27),
-    "small": font(23),
-    "tiny": font(20),
-    "mono": font(22),
-}
-
-
-img = Image.new("RGB", (W, H), BG)
-draw = ImageDraw.Draw(img)
-
-
-def text_size(s, ft):
-    box = draw.textbbox((0, 0), s, font=ft)
-    return box[2] - box[0], box[3] - box[1]
-
-
-def wrap_text(text, ft, max_w):
-    lines = []
-    for para in text.split("\n"):
-        current = ""
-        for ch in para:
-            if text_size(current + ch, ft)[0] <= max_w:
-                current += ch
-            else:
-                if current:
-                    lines.append(current)
-                current = ch
-        if current:
-            lines.append(current)
-    return lines
-
-
-def rounded(x, y, w, h, fill=CARD, outline=LINE, radius=28, width=3):
-    draw.rounded_rectangle([x, y, x + w, y + h], radius=radius, fill=fill, outline=outline, width=width)
-
-
-def shadow_card(x, y, w, h, fill=CARD, outline=LINE, radius=28):
-    draw.rounded_rectangle([x + 10, y + 12, x + w + 10, y + h + 12], radius=radius, fill="#D8E8FA")
-    rounded(x, y, w, h, fill, outline, radius)
-
-
-def label(text, x, y, fill=INK, ft=None, anchor=None):
-    draw.text((x, y), text, font=ft or F["body"], fill=fill, anchor=anchor)
-
-
-def pill(text, x, y, fill, fg="#FFFFFF", pad_x=22, pad_y=10, ft=None):
-    ft = ft or F["small"]
-    tw, th = text_size(text, ft)
-    draw.rounded_rectangle([x, y, x + tw + pad_x * 2, y + th + pad_y * 2], radius=22, fill=fill)
-    label(text, x + pad_x, y + pad_y - 2, fg, ft)
-    return tw + pad_x * 2
-
-
-def card(title, lines, x, y, w, h, accent=BLUE, tag=None, subtitle=None):
-    shadow_card(x, y, w, h, CARD, "#A9C8EE", 22)
-    draw.rounded_rectangle([x, y, x + w, y + 66], radius=22, fill=accent)
-    draw.rectangle([x, y + 42, x + w, y + 66], fill=accent)
-    label(title, x + 24, y + 14, "#FFFFFF", F["h2"])
-    if tag:
-        pill(tag, x + w - text_size(tag, F["tiny"])[0] - 84, y + 14, "#FFFFFF", accent, 16, 8, F["tiny"])
-    ty = y + 88
-    if subtitle:
-        label(subtitle, x + 24, ty, accent, F["small"])
-        ty += 38
-    for ln in lines:
-        for wrapped in wrap_text("• " + ln, F["small"], w - 56):
-            label(wrapped, x + 28, ty, INK, F["small"])
-            ty += 34
-        ty += 2
-
-
-def layer_band(idx, name, desc, y, h, color):
-    draw.rounded_rectangle([80, y, W - 80, y + h], radius=30, fill="#EEF6FF", outline="#C8DDF5", width=2)
-    draw.rounded_rectangle([96, y + 18, 310, y + h - 18], radius=24, fill=color)
-    label(idx, 203, y + 48, "#FFFFFF", F["h1"], "ma")
-    label(name, 340, y + 30, INK, F["h2"])
-    label(desc, 340, y + 76, MUTED, F["small"])
-
-
-def arrow(x1, y1, x2, y2, color=BLUE, width=8):
-    draw.line([x1, y1, x2, y2], fill=color, width=width)
-    import math
-    ang = math.atan2(y2 - y1, x2 - x1)
-    size = 24
-    p1 = (x2, y2)
-    p2 = (x2 - size * math.cos(ang - 0.45), y2 - size * math.sin(ang - 0.45))
-    p3 = (x2 - size * math.cos(ang + 0.45), y2 - size * math.sin(ang + 0.45))
-    draw.polygon([p1, p2, p3], fill=color)
-
-
-# Title
-label("医梦 AI 中台 Maven 模块演进与依赖关系图", W // 2, 70, INK, F["title"], "ma")
-label("现状 emoon-mcp-api 先不动代码,仅按目标拆分为 ai-agent-api / ai-card-api / ai-mcp-api 进行架构设计", W // 2, 154, MUTED, F["sub"], "ma")
-pill("大厂技术培训风", 350, 230, BLUE)
-pill("高密度强层级", 660, 230, CYAN)
-pill("现状 + 规划同屏", 965, 230, PURPLE)
-pill("初级工程师可读", 1325, 230, GREEN)
-
-shadow_card(1960, 215, 3160, 92, "#FFFFFF", "#8DB7E8", 22)
-label("依赖红线", 2000, 238, RED, F["small"])
-compact_rules = [
-    "入口层只依赖 API 契约",
-    "Card 不直连 MCP",
-    "计量先落库再入账",
-    "敏感数据不进外部日志/prompt 明文",
-    "三开发优先模块化单体",
-]
-rx = 2200
-for r in compact_rules:
-    rx += pill(r, rx, 232, "#EAF4FF", INK, 14, 7, F["tiny"]) + 18
-
-
-# L0 external touchpoints
-layer_band("L0", "业务触点层", "用户和业务系统进入 AI 中台的入口,不直接依赖底层实现模块。", 330, 310, BLUE)
-l0 = [
-    ("患者端 / 小程序", ["问诊、报告解读、随访、建档"]),
-    ("医生工作站", ["舌诊、面诊、病历生成、医嘱建议"]),
-    ("院内运营后台", ["能力配置、合同、套餐、统计报表"]),
-    ("医院系统集成", ["HIS / EMR / LIS / PACS 调用"]),
-    ("IoMT / 语音设备", ["语音陪诊、床旁设备、可穿戴数据"]),
-]
-x = 520
-for title, lines in l0:
-    card(title, lines, x, 420, 850, 150, BLUE, "外部调用")
-    x += 900
-
-
-# L1 application entry
-layer_band("L1", "应用入口层", "保持当前业务入口,向下只调用领域 API,不跨层访问具体实现。", 690, 330, CYAN)
-l1 = [
-    ("emoon-openplatform", ["开放接口、SSE 会话、院内集成入口", "当前已依赖 emoon-mcp-api"]),
-    ("emoon-admin", ["平台运营后台、租户配置、能力包管理", "三期补齐计费、统计、审计运营页"]),
-    ("emoon-app / 小程序端", ["患者问诊、报告、随访、AI 卡片交互", "只认业务 API 和 SSE 事件"]),
-    ("emoon-extend / worker", ["文件处理、异步任务、外部通道适配", "后续承接 OCR/ASR/回调类任务"]),
-]
-x = 540
-for title, lines in l1:
-    card(title, lines, x, 780, 1040, 170, CYAN, "入口")
-    x += 1140
-
-
-# L2 current maven baseline and split
-layer_band("L2", "当前 Maven 基座与目标 API 拆分", "不做微服务先行;先把 API 契约从 emoon-mcp-api 中按职责拆清楚。", 1070, 610, PURPLE)
-card("当前 emoon-infra / emoon-modules-api", [
-    "emoon-chat-api:聊天/消息领域契约",
-    "emoon-system-api:租户、用户、字典、权限基础能力",
-    "emoon-knowledge-api:知识库与文档能力契约",
-    "emoon-mcp-api:当前混放 Agent、Card、MCP、三方 SDK 依赖",
-], 520, 1180, 1250, 360, PURPLE, "现状")
-
-card("emoon-mcp-api(现状待拆)", [
-    "包含 AgentEngine / AgentRequest / AgentResponse",
-    "包含 AiConversation / AiCardInstance 等领域对象",
-    "依赖偏重:web、sse、websocket、langchain4j、pdfbox、tika 等",
-    "问题:API 契约和实现依赖混在一起,调用边界不清晰",
-], 1910, 1150, 1320, 420, RED, "不要先动代码")
-
-target_cards = [
-    ("ai-agent-api", ["统一 AI 调用契约", "会话、SSE、编排、Dify/DirectLLM 引擎抽象", "只放 DTO / SPI / 轻量接口"]),
-    ("ai-card-api", ["AI 卡片契约", "卡片定义、实例、事件、状态、渲染数据", "面向前端和业务场景复用"]),
-    ("ai-mcp-api", ["MCP 工具契约", "Tool Registry、Tool Call、权限、审计元数据", "仅表达工具协议,不承载 Agent 编排"]),
-]
-for i, (t, lines) in enumerate(target_cards):
-    card(t, lines, 3420, 1125 + i * 165, 1500, 140, [BLUE, GREEN, ORANGE][i], "目标 API")
-
-arrow(1775, 1360, 1900, 1360, RED, 10)
-arrow(3235, 1255, 3405, 1195, BLUE, 8)
-arrow(3235, 1360, 3405, 1360, GREEN, 8)
-arrow(3235, 1465, 3405, 1525, ORANGE, 8)
-label("拆分原则:API 包只定义契约;实现、持久化、三方 SDK 依赖下沉到对应业务模块", 3460, 1600, RED, F["small"])
-
-
-# L3 target implementation modules
-layer_band("L3", "目标领域实现模块", "仍保持 Maven 模块化单体优先,模块内高内聚,模块间通过 API 契约调用。", 1740, 620, GREEN)
-impl = [
-    ("ai-agent", BLUE, ["实现 ai-agent-api", "AgentEngineFactory、DifyEngine、DirectLLMEngine", "SSE 事件、幂等、降级、Outbox"]),
-    ("ai-card", GREEN, ["实现 ai-card-api", "卡片定义/实例/版本/事件流", "卡片只经 Agent 调 MCP,不直连工具"]),
-    ("ai-mcp", ORANGE, ["实现 ai-mcp-api", "工具注册、权限、调用路由、审计", "院内工具适配 HIS/EMR/LIS/PACS"]),
-    ("ai-meter", PURPLE, ["计量事件中心", "Token/次数/分钟/项目/年费统一归集", "8 状态机、重放、幂等去重"]),
-    ("ai-billing", RED, ["合同、能力值包、预扣款、结算", "pricing snapshot、special adjustment", "合理不限量与跨账户划拨"]),
-    ("ai-knowledge", CYAN, ["知识库、模板、病种规则、提示词资产", "对接现有 emoon-knowledge-api", "支撑报告、病历、质控场景"]),
-]
-x0, y0 = 520, 1850
-for i, (t, c, lines) in enumerate(impl):
-    x = x0 + (i % 3) * 1540
-    y = y0 + (i // 3) * 235
-    card(t, lines, x, y, 1420, 190, c, "实现模块")
-
-for sx, sy, tx, ty, c in [
-    (4170, 1265, 1230, 1825, BLUE),
-    (4170, 1425, 2770, 1825, GREEN),
-    (4170, 1590, 4310, 1825, ORANGE),
-    (1250, 2090, 2770, 2090, PURPLE),
-    (2770, 2090, 4310, 2090, RED),
-]:
-    arrow(sx, sy, tx, ty, c, 7)
-
-
-# L4 future independent boundaries
-layer_band("L4", "未来可独立部署边界", "三开发阶段不建议先拆微服务;当吞吐、隔离或交付责任成熟后,再按这些边界拆。", 2420, 360, ORANGE)
-future = [
-    ("MCP Tool Server", ["医院内网工具调用隔离", "工具权限、审计、限流独立"]),
-    ("AudioStreamGateway", ["电话/语音陪诊流式接入", "ASR/TTS、按分钟计量"]),
-    ("IoMTEventIngestion", ["设备事件接入与清洗", "告警、趋势、随访触发"]),
-    ("OutboundFollowup", ["随访任务、回访、消息触达", "失败重试与运营统计"]),
-    ("File/OCR/ASR Worker", ["报告、影像、病历附件异步处理", "长任务与主链路解耦"]),
-]
-x = 520
-for title, lines in future:
-    card(title, lines, x, 2510, 850, 165, ORANGE, "可拆服务")
-    x += 900
-
-
-# L5 external systems + data base
-layer_band("L5", "外部系统与数据可靠性底座", "所有调用、计量、账务、审计必须形成闭环,避免医疗场景不可追溯。", 2840, 360, BLUE)
-base = [
-    ("AI 引擎", ["Dify Workflow / DirectLLM / Vision / Mock"]),
-    ("院内系统", ["HIS / EMR / LIS / PACS / 预约挂号"]),
-    ("数据存储", ["MySQL:业务状态", "Redis:锁/限流/短期缓存"]),
-    ("可靠性", ["Outbox:异步一致性", "幂等键:API/Meter/Tool 分层"]),
-    ("账务审计", ["Credit Ledger:能力值流水", "Audit/Trace:全链路追踪"]),
-]
-x = 520
-for title, lines in base:
-    card(title, lines, x, 2930, 850, 165, BLUE, "底座")
-    x += 900
-
-
-shadow_card(80, 3180, W - 160, 82, "#EAF4FF", "#A9C8EE", 22)
-label("读图顺序:先看 L2 的 emoon-mcp-api 现状待拆,再看右侧三类目标 API,最后沿箭头进入 L3 实现模块和 L5 计量/账务/审计闭环。", W // 2, 3210, INK, F["small"], "ma")
-
-OUT.parent.mkdir(parents=True, exist_ok=True)
-img.save(OUT, "PNG", optimize=True)
-print(OUT)