Update README and tech-selection documents for clarity and accuracy

- Revised the README.md to clarify the purpose of the tech-selection documents, distinguishing between external and internal materials.
- Added a new internal document, Flutter-vs-UniApp-Speaker.md, summarizing key points from the presentation deck.
- Updated Flutter-vs-UniApp-deck.standalone.html to enhance descriptions of HarmonyOS support and installation package sizes.
This commit is contained in:
Guangfei.Zhao
2026-09-02 09:49:29 +08:00
parent 68284ae3cc
commit cc0b00fd4f
6 changed files with 965 additions and 459 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

@@ -1,453 +1,610 @@
<mxfile host="Electron" agent="Codex" compressed="false" pages="2">
<mxfile host="65bd71144e" compressed="false" pages="2">
<diagram id="network-architecture" name="Network Architecture">
<mxGraphModel dx="1182" dy="661" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1800" pageHeight="1100" math="0" shadow="0">
<mxGraphModel dx="898" dy="770" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1800" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="2" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=28;fontStyle=1;fontColor=#1f2937;" value="Continental Retail APP Network Architecture" vertex="1">
<mxGeometry height="40" width="620" x="60" y="28" as="geometry" />
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="2" value="Continental Retail APP Network Architecture" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=28;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="60" y="28" width="620" height="40" as="geometry"/>
</mxCell>
<mxCell id="3" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#4b5563;" value="Primary route: Mobile App -&gt; App Backend. F6 API access is backend-only, F6 H5 is embedded-only, and Mini direct access is retained only for limited legacy compatibility." vertex="1">
<mxGeometry height="24" width="980" x="60" y="68" as="geometry" />
<mxCell id="3" value="Primary route: Mobile App -&gt; App Backend. F6 API access is backend-only, F6 H5 is embedded-only, and Mini direct access is retained only for limited legacy compatibility." style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#4b5563;" parent="1" vertex="1">
<mxGeometry x="60" y="68" width="980" height="24" as="geometry"/>
</mxCell>
<mxCell id="4" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d1d5db;strokeWidth=1.5;" value="" vertex="1">
<mxGeometry height="74" width="240" x="1490" y="26" as="geometry" />
<mxCell id="4" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d1d5db;strokeWidth=1.5;" parent="1" vertex="1">
<mxGeometry x="1490" y="26" width="240" height="74" as="geometry"/>
</mxCell>
<mxCell id="5" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontSize=12;fontColor=#374151;spacingTop=8;spacingLeft=10;" value="Version: v0.9&lt;br&gt;Date: 2026-06-16&lt;div&gt;Page: Network Architecture&lt;/div&gt;" vertex="1">
<mxGeometry height="56" width="220" x="1500" y="34" as="geometry" />
<mxCell id="5" value="Version: v1.0&lt;br&gt;Date: 2026-08-31&lt;div&gt;Page: Network Architecture&lt;/div&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontSize=12;fontColor=#374151;spacingTop=8;spacingLeft=10;" parent="1" vertex="1">
<mxGeometry x="1500" y="34" width="220" height="56" as="geometry"/>
</mxCell>
<mxCell id="6" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dbeafe;strokeColor=#2563eb;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#1e3a8a;" value="Mobile App" vertex="1">
<mxGeometry height="70" width="250" x="770" y="120" as="geometry" />
<mxCell id="6" value="Mobile App" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dbeafe;strokeColor=#2563eb;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#1e3a8a;" parent="1" vertex="1">
<mxGeometry x="770" y="120" width="250" height="70" as="geometry"/>
</mxCell>
<mxCell id="7" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#eff6ff;strokeColor=#93c5fd;fontSize=13;fontColor=#1f2937;" value="Native Shell + WebView&lt;br&gt;Scan / Camera / Upload / JSBridge" vertex="1">
<mxGeometry height="62" width="300" x="1060" y="124" as="geometry" />
<mxCell id="7" value="Native Shell + WebView&lt;br&gt;Scan / Camera / Upload / JSBridge" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#eff6ff;strokeColor=#93c5fd;fontSize=13;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1060" y="124" width="300" height="62" as="geometry"/>
</mxCell>
<mxCell id="8" parent="1" style="shape=cloud;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#94a3b8;strokeWidth=1.8;fontSize=16;fontStyle=1;fontColor=#1f2937;" value="Internet" vertex="1">
<mxGeometry height="80" width="150" x="820" y="220" as="geometry" />
<mxCell id="8" value="Internet" style="shape=cloud;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#94a3b8;strokeWidth=1.8;fontSize=16;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="820" y="220" width="150" height="80" as="geometry"/>
</mxCell>
<mxCell id="9" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#eef6ff;strokeColor=#2563eb;strokeWidth=2;" value="" vertex="1">
<mxGeometry height="530" width="580" x="610" y="340" as="geometry" />
<mxCell id="9" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#eef6ff;strokeColor=#2563eb;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="610" y="340" width="580" height="530" as="geometry"/>
</mxCell>
<mxCell id="10" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=22;fontStyle=1;fontColor=#1e3a8a;" value="Primary App Backend Domain (Azure China)" vertex="1">
<mxGeometry height="30" width="460" x="670" y="360" as="geometry" />
<mxCell id="10" value="Primary App Backend Domain (Azure China)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=22;fontStyle=1;fontColor=#1e3a8a;" parent="1" vertex="1">
<mxGeometry x="670" y="360" width="460" height="30" as="geometry"/>
</mxCell>
<mxCell id="11" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#f59e0b;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Public Ingress Zone" vertex="1">
<mxGeometry height="130" width="520" x="640" y="410" as="geometry" />
<mxCell id="11" value="Public Ingress Zone" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#f59e0b;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="640" y="410" width="520" height="130" as="geometry"/>
</mxCell>
<mxCell id="12" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="WAF / Application Gateway" vertex="1">
<mxGeometry height="58" width="190" x="680" y="460" as="geometry" />
<mxCell id="12" value="WAF / Application Gateway" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="680" y="460" width="190" height="58" as="geometry"/>
</mxCell>
<mxCell id="13" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="Public Load Balancer" vertex="1">
<mxGeometry height="58" width="180" x="930" y="460" as="geometry" />
<mxCell id="13" value="Public Load Balancer" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="930" y="460" width="180" height="58" as="geometry"/>
</mxCell>
<mxCell id="14" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f2fe;strokeColor=#38bdf8;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Private Application Zone" vertex="1">
<mxGeometry height="270" width="520" x="640" y="570" as="geometry" />
<mxCell id="14" value="Private Application Zone" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f2fe;strokeColor=#38bdf8;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="640" y="570" width="520" height="270" as="geometry"/>
</mxCell>
<mxCell id="15" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f3ff;strokeColor=#a78bfa;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="NSG / Access Control" vertex="1">
<mxGeometry height="42" width="420" x="690" y="610" as="geometry" />
<mxCell id="15" value="NSG / Access Control" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f3ff;strokeColor=#a78bfa;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="690" y="610" width="420" height="42" as="geometry"/>
</mxCell>
<mxCell id="16" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#60a5fa;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="App Backend BFF / Unified APIs" vertex="1">
<mxGeometry height="80" width="180" x="680" y="700" as="geometry" />
<mxCell id="16" value="App Backend BFF / Unified APIs" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#60a5fa;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="680" y="700" width="180" height="80" as="geometry"/>
</mxCell>
<mxCell id="17" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#60a5fa;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="Business Aggregation / Orchestration" vertex="1">
<mxGeometry height="80" width="200" x="900" y="700" as="geometry" />
<mxCell id="17" value="Business Aggregation / Orchestration" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#60a5fa;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="900" y="700" width="200" height="80" as="geometry"/>
</mxCell>
<mxCell id="18" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#60a5fa;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="F6 Integration Adapter" vertex="1">
<mxGeometry height="38" width="200" x="790" y="790" as="geometry" />
<mxCell id="18" value="F6 Integration Adapter" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#60a5fa;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="790" y="790" width="200" height="38" as="geometry"/>
</mxCell>
<mxCell id="19" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8fafc;strokeColor=#cbd5e1;strokeWidth=1;fontSize=12;fontColor=#374151;" value="Identity / Store Context&lt;br&gt;Menu / Config / WebView Ticket" vertex="1">
<mxGeometry height="40" width="180" x="680" y="660" as="geometry" />
<mxCell id="19" value="Identity / Store Context&lt;br&gt;Menu / Config / WebView Ticket" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8fafc;strokeColor=#cbd5e1;strokeWidth=1;fontSize=12;fontColor=#374151;" parent="1" vertex="1">
<mxGeometry x="680" y="660" width="180" height="40" as="geometry"/>
</mxCell>
<mxCell id="20" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8fafc;strokeColor=#cbd5e1;strokeWidth=1;fontSize=12;fontColor=#374151;" value="Unified Error / Audit&#xa;Logging / Security / Trace ID" vertex="1">
<mxGeometry height="40" width="200" x="900" y="660" as="geometry" />
<mxCell id="20" value="Unified Error / Audit&#xa;Logging / Security / Trace ID" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8fafc;strokeColor=#cbd5e1;strokeWidth=1;fontSize=12;fontColor=#374151;" parent="1" vertex="1">
<mxGeometry x="900" y="660" width="200" height="40" as="geometry"/>
</mxCell>
<mxCell id="21" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f0fdf4;strokeColor=#16a34a;strokeWidth=2;" value="" vertex="1">
<mxGeometry height="530" width="460" x="60" y="340" as="geometry" />
<mxCell id="21" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f0fdf4;strokeColor=#16a34a;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="60" y="340" width="460" height="530" as="geometry"/>
</mxCell>
<mxCell id="22" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=22;fontStyle=1;fontColor=#166534;" value="Mini Program Backend VPC" vertex="1">
<mxGeometry height="30" width="380" x="100" y="360" as="geometry" />
<mxCell id="22" value="Mini Program Backend VPC" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=22;fontStyle=1;fontColor=#166534;" parent="1" vertex="1">
<mxGeometry x="100" y="360" width="380" height="30" as="geometry"/>
</mxCell>
<mxCell id="78" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dcfce7;strokeColor=#86efac;strokeWidth=1;fontSize=12;fontColor=#166534;" value="Independent VPC / network boundary" vertex="1">
<mxGeometry height="28" width="250" x="165" y="390" as="geometry" />
<mxCell id="78" value="Independent VPC / network boundary" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dcfce7;strokeColor=#86efac;strokeWidth=1;fontSize=12;fontColor=#166534;" parent="1" vertex="1">
<mxGeometry x="165" y="390" width="250" height="28" as="geometry"/>
</mxCell>
<mxCell id="23" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ecfdf5;strokeColor=#4ade80;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Public Ingress Zone" vertex="1">
<mxGeometry height="120" width="400" x="90" y="410" as="geometry" />
<mxCell id="23" value="Public Ingress Zone" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ecfdf5;strokeColor=#4ade80;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="90" y="410" width="400" height="120" as="geometry"/>
</mxCell>
<mxCell id="24" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#4ade80;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="Mini Gateway / Firewall" vertex="1">
<mxGeometry height="56" width="180" x="200" y="458" as="geometry" />
<mxCell id="24" value="Mini Gateway / Firewall" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#4ade80;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="200" y="458" width="180" height="56" as="geometry"/>
</mxCell>
<mxCell id="26" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ecfdf5;strokeColor=#4ade80;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Independent Mini Services" vertex="1">
<mxGeometry height="188" width="400" x="90" y="585" as="geometry" />
<mxCell id="26" value="Independent Mini Services" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ecfdf5;strokeColor=#4ade80;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="90" y="585" width="400" height="188" as="geometry"/>
</mxCell>
<mxCell id="33" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#4ade80;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="O2O / Warranty / 马上下单 / ROOS&lt;br&gt;Shared Capabilities" vertex="1">
<mxGeometry height="80" width="270" x="155" y="655" as="geometry" />
<mxCell id="33" value="O2O / Warranty / 马上下单 / ROOS&lt;br&gt;Shared Capabilities" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#4ade80;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="155" y="655" width="270" height="80" as="geometry"/>
</mxCell>
<mxCell id="77" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f0fdf4;strokeColor=#86efac;fontSize=13;fontColor=#166534;" value="Independent domain retained. App-facing flows should converge through App Backend. Only selected legacy modules may still direct-connect." vertex="1">
<mxGeometry height="42" width="370" x="105" y="792" as="geometry" />
<mxCell id="77" value="Independent domain retained. App-facing flows should converge through App Backend. Only selected legacy modules may still direct-connect." style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f0fdf4;strokeColor=#86efac;fontSize=13;fontColor=#166534;" parent="1" vertex="1">
<mxGeometry x="105" y="792" width="370" height="42" as="geometry"/>
</mxCell>
<mxCell id="34" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#ea580c;strokeWidth=2;" value="" vertex="1">
<mxGeometry height="530" width="450" x="1280" y="340" as="geometry" />
<mxCell id="34" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#ea580c;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="1280" y="340" width="450" height="530" as="geometry"/>
</mxCell>
<mxCell id="35" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=21;fontStyle=1;fontColor=#c2410c;" value="F6 Supplier VPC (Alibaba Cloud)" vertex="1">
<mxGeometry height="30" width="390" x="1310" y="360" as="geometry" />
<mxCell id="35" value="F6 Supplier VPC (Alibaba Cloud)" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=21;fontStyle=1;fontColor=#c2410c;" parent="1" vertex="1">
<mxGeometry x="1310" y="360" width="390" height="30" as="geometry"/>
</mxCell>
<mxCell id="79" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffedd5;strokeColor=#fdba74;strokeWidth=1;fontSize=12;fontColor=#9a3412;" value="Supplier-managed VPC / network boundary" vertex="1">
<mxGeometry height="28" width="285" x="1362" y="390" as="geometry" />
<mxCell id="79" value="Supplier-managed VPC / network boundary" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffedd5;strokeColor=#fdba74;strokeWidth=1;fontSize=12;fontColor=#9a3412;" parent="1" vertex="1">
<mxGeometry x="1362" y="390" width="285" height="28" as="geometry"/>
</mxCell>
<mxCell id="36" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#fb923c;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Public Access Zone" vertex="1">
<mxGeometry height="130" width="390" x="1310" y="410" as="geometry" />
<mxCell id="36" value="Public Access Zone" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#fb923c;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1310" y="410" width="390" height="130" as="geometry"/>
</mxCell>
<mxCell id="37" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="Access Gateway / WAF" vertex="1">
<mxGeometry height="58" width="160" x="1340" y="460" as="geometry" />
<mxCell id="37" value="Access Gateway / WAF" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1340" y="460" width="160" height="58" as="geometry"/>
</mxCell>
<mxCell id="38" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="Load Balancer" vertex="1">
<mxGeometry height="58" width="140" x="1530" y="460" as="geometry" />
<mxCell id="38" value="Load Balancer" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1530" y="460" width="140" height="58" as="geometry"/>
</mxCell>
<mxCell id="39" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" value="Allowlisted B2B API Gateway" vertex="1">
<mxGeometry height="34" width="210" x="1400" y="418" as="geometry" />
<mxCell id="39" value="Allowlisted B2B API Gateway" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fb923c;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1400" y="418" width="210" height="34" as="geometry"/>
</mxCell>
<mxCell id="40" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#fb923c;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Private Service Zone" vertex="1">
<mxGeometry height="240" width="390" x="1310" y="565" as="geometry" />
<mxCell id="40" value="Private Service Zone" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#fb923c;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1310" y="565" width="390" height="240" as="geometry"/>
</mxCell>
<mxCell id="41" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f3ff;strokeColor=#a78bfa;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="Security Group / Access Policy" vertex="1">
<mxGeometry height="42" width="330" x="1340" y="603" as="geometry" />
<mxCell id="41" value="Security Group / Access Policy" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f3ff;strokeColor=#a78bfa;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1340" y="603" width="330" height="42" as="geometry"/>
</mxCell>
<mxCell id="42" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fdba74;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="F6 WebView Pages" vertex="1">
<mxGeometry height="78" width="150" x="1340" y="690" as="geometry" />
<mxCell id="42" value="F6 WebView Pages" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fdba74;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1340" y="690" width="150" height="78" as="geometry"/>
</mxCell>
<mxCell id="43" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fdba74;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" value="F6 Capability APIs&#xa;(Backend Only)" vertex="1">
<mxGeometry height="78" width="150" x="1520" y="690" as="geometry" />
<mxCell id="43" value="F6 Capability APIs&#xa;(Backend Only)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#fdba74;strokeWidth=1.4;fontSize=14;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1520" y="690" width="150" height="78" as="geometry"/>
</mxCell>
<mxCell id="44" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#fdba74;fontSize=13;fontColor=#92400e;" value="Procurement / Promotion / ERP capabilities are consumed through backend integration. App direct access is allowed only for embedded F6 H5 pages." vertex="1">
<mxGeometry height="48" width="330" x="1340" y="792" as="geometry" />
<mxCell id="44" value="Procurement / Promotion / ERP capabilities are consumed through backend integration. App direct access is allowed only for embedded F6 H5 pages." style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff7ed;strokeColor=#fdba74;fontSize=13;fontColor=#92400e;" parent="1" vertex="1">
<mxGeometry x="1340" y="792" width="330" height="48" as="geometry"/>
</mxCell>
<mxCell id="45" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8fafc;strokeColor=#d1d5db;strokeWidth=1.2;" value="" vertex="1">
<mxGeometry height="150" width="1670" x="60" y="910" as="geometry" />
<mxCell id="45" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8fafc;strokeColor=#d1d5db;strokeWidth=1.2;" parent="1" vertex="1">
<mxGeometry x="60" y="910" width="1670" height="150" as="geometry"/>
</mxCell>
<mxCell id="46" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" value="Architecture Principles" vertex="1">
<mxGeometry height="24" width="220" x="86" y="930" as="geometry" />
<mxCell id="46" value="Architecture Principles" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" parent="1" vertex="1">
<mxGeometry x="86" y="930" width="220" height="24" as="geometry"/>
</mxCell>
<mxCell id="47" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontSize=14;fontColor=#374151;spacingTop=4;" value="1. `Mobile App -&amp;gt; App Backend` is the only primary route.&lt;br&gt;2. `App -&amp;gt; F6` appears only in the Embedded H5 scenario.&lt;br&gt;3. `App Backend -&amp;gt; F6 API` must pass through `F6 Integration Adapter`.&lt;br&gt;4. `Mini Program Backend` remains an independent domain.&lt;br&gt;5. Unified controls include HTTPS/TLS, Trace ID, audit logging, config switches, and normalized error handling." vertex="1">
<mxGeometry height="84" width="980" x="86" y="966" as="geometry" />
<mxCell id="47" value="1. `Mobile App &amp;lt;-&amp;gt; App Backend` uses bidirectional HTTPS / REST API traffic.&lt;br&gt;2. `App -&amp;gt; F6` appears only in the Embedded H5 scenario.&lt;br&gt;3. `App Backend &amp;lt;-&amp;gt; F6 API` uses HTTPS / B2B API through `F6 Integration Adapter`.&lt;br&gt;4. `Mini Program Backend` remains an independent domain and integrates through HTTPS / Internal API.&lt;br&gt;5. Unified controls include HTTPS/TLS, Trace ID, audit logging, config switches, and normalized error handling." style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontSize=14;fontColor=#374151;spacingTop=4;" parent="1" vertex="1">
<mxGeometry x="86" y="966" width="980" height="84" as="geometry"/>
</mxCell>
<mxCell id="48" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" value="Legend" vertex="1">
<mxGeometry height="24" width="80" x="1160" y="930" as="geometry" />
<mxCell id="48" value="Legend" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" parent="1" vertex="1">
<mxGeometry x="1160" y="930" width="80" height="24" as="geometry"/>
</mxCell>
<mxCell id="49" parent="1" style="shape=line;html=1;strokeColor=#2563eb;strokeWidth=2;" value="" vertex="1">
<mxGeometry height="10" width="72" x="1168" y="974" as="geometry" />
<mxCell id="49" value="" style="shape=line;html=1;strokeColor=#2563eb;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="1168" y="974" width="72" height="10" as="geometry"/>
</mxCell>
<mxCell id="50" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" value="Primary route" vertex="1">
<mxGeometry height="24" width="120" x="1250" y="965" as="geometry" />
<mxCell id="50" value="Primary route" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1250" y="965" width="120" height="24" as="geometry"/>
</mxCell>
<mxCell id="51" parent="1" style="shape=line;html=1;strokeColor=#16a34a;strokeWidth=2;" value="" vertex="1">
<mxGeometry height="10" width="72" x="1168" y="1008" as="geometry" />
<mxCell id="51" value="" style="shape=line;html=1;strokeColor=#16a34a;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="1168" y="1008" width="72" height="10" as="geometry"/>
</mxCell>
<mxCell id="52" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" value="VPC backend integration" vertex="1">
<mxGeometry height="24" width="140" x="1250" y="999" as="geometry" />
<mxCell id="52" value="VPC backend integration" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1250" y="999" width="140" height="24" as="geometry"/>
</mxCell>
<mxCell id="53" parent="1" style="shape=line;html=1;strokeColor=#f97316;strokeWidth=2;" value="" vertex="1">
<mxGeometry height="10" width="72" x="1420" y="974" as="geometry" />
<mxCell id="53" value="" style="shape=line;html=1;strokeColor=#f97316;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="1420" y="974" width="72" height="10" as="geometry"/>
</mxCell>
<mxCell id="54" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" value="F6 H5 route" vertex="1">
<mxGeometry height="24" width="110" x="1502" y="965" as="geometry" />
<mxCell id="54" value="F6 H5 route" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1502" y="965" width="110" height="24" as="geometry"/>
</mxCell>
<mxCell id="55" parent="1" style="shape=line;html=1;strokeColor=#6b7280;strokeWidth=2;dashed=1;dashPattern=8 8;" value="" vertex="1">
<mxGeometry height="10" width="72" x="1420" y="1008" as="geometry" />
<mxCell id="55" value="" style="shape=line;html=1;strokeColor=#6b7280;strokeWidth=2;dashed=1;dashPattern=8 8;" parent="1" vertex="1">
<mxGeometry x="1420" y="1008" width="72" height="10" as="geometry"/>
</mxCell>
<mxCell id="56" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" value="Legacy compatibility" vertex="1">
<mxGeometry height="24" width="150" x="1502" y="999" as="geometry" />
<mxCell id="56" value="Legacy compatibility" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1502" y="999" width="150" height="24" as="geometry"/>
</mxCell>
<mxCell id="57" edge="1" parent="1" source="6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.2;fontSize=12;fontColor=#1e3a8a;" target="7" value="">
<mxGeometry relative="1" as="geometry" />
<mxCell id="57" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.2;fontSize=12;fontColor=#1e3a8a;" parent="1" source="6" target="7" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="58" edge="1" parent="1" source="6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.4;" target="8">
<mxGeometry relative="1" as="geometry" />
<mxCell id="58" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.4;" parent="1" source="6" target="8" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="59" edge="1" parent="1" source="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.5;fontSize=12;fontColor=#1e3a8a;" target="12" value="">
<mxCell id="59" value="HTTPS / REST API" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.5;fontSize=12;fontColor=#1e3a8a;labelBackgroundColor=#ffffff;" parent="1" source="8" target="12" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="900" y="350" />
<mxPoint x="775" y="350" />
<mxPoint x="900" y="350"/>
<mxPoint x="775" y="350"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="60" edge="1" parent="1" source="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#f97316;strokeWidth=1.5;fontSize=12;fontColor=#c2410c;" target="37" value="">
<mxCell id="60" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#f97316;strokeWidth=1.5;fontSize=12;fontColor=#c2410c;" parent="1" source="8" target="37" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1420" y="260" />
<mxPoint x="1420" y="260"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="61" edge="1" parent="1" source="12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.2;" target="13">
<mxGeometry relative="1" as="geometry" />
<mxCell id="61" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.2;" parent="1" source="12" target="13" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="62" edge="1" parent="1" source="13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.2;" target="16">
<mxCell id="62" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.2;" parent="1" source="13" target="16" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1020" y="600" />
<mxPoint x="770" y="600" />
<mxPoint x="1020" y="600"/>
<mxPoint x="770" y="600"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="63" edge="1" parent="1" source="16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.4;" target="17">
<mxGeometry relative="1" as="geometry" />
<mxCell id="63" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.4;" parent="1" source="16" target="17" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="64" edge="1" parent="1" source="17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#16a34a;strokeWidth=1.4;fontSize=12;fontColor=#166534;exitX=0;exitY=0.75;exitDx=0;exitDy=0;" target="18" value="">
<mxCell id="64" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#16a34a;strokeWidth=1.4;fontSize=12;fontColor=#166534;exitX=0;exitY=0.75;exitDx=0;exitDy=0;" parent="1" source="17" target="18" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="880" y="760" />
<mxPoint x="880" y="760"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="65" edge="1" parent="1" source="18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#16a34a;strokeWidth=1.4;fontSize=12;fontColor=#166534;" target="39" value="">
<mxCell id="65" value="HTTPS / B2B API" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#16a34a;strokeWidth=1.4;fontSize=12;fontColor=#166534;labelBackgroundColor=#ffffff;" parent="1" source="18" target="39" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1240" y="810" />
<mxPoint x="1240" y="435" />
<mxPoint x="1240" y="810"/>
<mxPoint x="1240" y="435"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="66" edge="1" parent="1" source="39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#16a34a;strokeWidth=1.4;" target="43">
<mxCell id="66" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#16a34a;strokeWidth=1.4;" parent="1" source="39" target="43" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1505" y="571" />
<mxPoint x="1595" y="571" />
<mxPoint x="1505" y="571"/>
<mxPoint x="1595" y="571"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="67" edge="1" parent="1" source="17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#16a34a;strokeWidth=1.4;fontSize=12;fontColor=#166534;startSize=6;" target="24" value="">
<mxCell id="67" value="HTTPS / Internal API" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#16a34a;strokeWidth=1.4;fontSize=12;fontColor=#166534;labelBackgroundColor=#ffffff;startSize=6;" parent="1" source="17" target="24" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1060" y="850" />
<mxPoint x="580" y="850" />
<mxPoint x="580" y="610" />
<mxPoint x="290" y="610" />
<mxPoint x="1060" y="850"/>
<mxPoint x="580" y="850"/>
<mxPoint x="580" y="610"/>
<mxPoint x="290" y="610"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="74" edge="1" parent="1" source="37" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#f97316;strokeWidth=1.2;" target="38">
<mxGeometry relative="1" as="geometry" />
<mxCell id="74" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#f97316;strokeWidth=1.2;" parent="1" source="37" target="38" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="75" edge="1" parent="1" source="38" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#f97316;strokeWidth=1.2;" target="42">
<mxCell id="75" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#f97316;strokeWidth=1.2;" parent="1" source="38" target="42" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1690" y="489" />
<mxPoint x="1690" y="660" />
<mxPoint x="1415" y="660" />
<mxPoint x="1690" y="489"/>
<mxPoint x="1690" y="660"/>
<mxPoint x="1415" y="660"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="76" edge="1" parent="1" source="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;dashed=1;dashPattern=8 8;strokeColor=#6b7280;strokeWidth=1.2;fontSize=12;fontColor=#4b5563;labelBackgroundColor=#ffffff;" target="24" value="Legacy only">
<mxCell id="76" value="Legacy only" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;dashed=1;dashPattern=8 8;strokeColor=#6b7280;strokeWidth=1.2;fontSize=12;fontColor=#4b5563;labelBackgroundColor=#ffffff;" parent="1" source="8" target="24" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="320" y="300" />
<mxPoint x="290" y="300" />
<mxPoint x="290" y="486" />
<mxPoint x="320" y="300"/>
<mxPoint x="290" y="300"/>
<mxPoint x="290" y="486"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="cXHFUXgN8kNcZhofBCdT-80" edge="1" parent="1" source="33" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.63;entryY=1.012;entryDx=0;entryDy=0;entryPerimeter=0;" target="33">
<mxGeometry relative="1" as="geometry" />
<mxCell id="cXHFUXgN8kNcZhofBCdT-80" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.63;entryY=1.012;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="33" target="33" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="network-topology" name="Network Topology">
<mxGraphModel dx="1436" dy="803" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1800" pageHeight="1100" math="0" shadow="0">
<mxGraphModel dx="898" dy="770" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1800" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="nt-title" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=28;fontStyle=1;fontColor=#1f2937;" value="Continental Retail APP Network Topology" vertex="1">
<mxGeometry height="40" width="700" x="60" y="28" as="geometry" />
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="nt-title" value="Continental Retail APP Network Topology" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=28;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="60" y="28" width="700" height="40" as="geometry"/>
</mxCell>
<mxCell id="nt-subtitle" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#4b5563;" value="Topology view focused on network boundaries, public ingress points, and allowed cross-domain connectivity." vertex="1">
<mxGeometry height="24" width="940" x="60" y="68" as="geometry" />
<mxCell id="nt-subtitle" value="Topology view focused on network boundaries, public ingress points, and allowed cross-domain connectivity." style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#4b5563;" parent="1" vertex="1">
<mxGeometry x="60" y="68" width="940" height="24" as="geometry"/>
</mxCell>
<mxCell id="nt-version-box" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#9ca3af;strokeWidth=1.5;" value="" vertex="1">
<mxGeometry height="74" width="240" x="1490" y="26" as="geometry" />
<mxCell id="nt-version-box" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#9ca3af;strokeWidth=1.5;" parent="1" vertex="1">
<mxGeometry x="1490" y="26" width="240" height="74" as="geometry"/>
</mxCell>
<mxCell id="nt-version-text" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontSize=12;fontColor=#374151;spacingTop=8;spacingLeft=10;" value="Version: v0.9&lt;br&gt;Date: 2026-06-16&lt;br&gt;Page: Network Topology" vertex="1">
<mxGeometry height="62" width="220" x="1500" y="32" as="geometry" />
<mxCell id="nt-version-text" value="Version: v1.0&lt;br&gt;Date: 2026-08-31&lt;br&gt;Page: Network Topology" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontSize=12;fontColor=#374151;spacingTop=8;spacingLeft=10;" parent="1" vertex="1">
<mxGeometry x="1500" y="32" width="220" height="62" as="geometry"/>
</mxCell>
<mxCell id="nt-public-zone" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f9fafb;strokeColor=#9ca3af;strokeWidth=1.5;dashed=1;dashPattern=8 8;" value="" vertex="1">
<mxGeometry height="650" width="440" x="680" y="145" as="geometry" />
<mxCell id="nt-public-zone" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f9fafb;strokeColor=#9ca3af;strokeWidth=1.5;dashed=1;dashPattern=8 8;" parent="1" vertex="1">
<mxGeometry x="680" y="145" width="440" height="650" as="geometry"/>
</mxCell>
<mxCell id="nt-public-zone-title" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" value="Public Network" vertex="1">
<mxGeometry height="28" width="180" x="810" y="165" as="geometry" />
<mxCell id="nt-public-zone-title" value="Public Network" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" parent="1" vertex="1">
<mxGeometry x="810" y="165" width="180" height="28" as="geometry"/>
</mxCell>
<mxCell id="nt-mobile" parent="1" style="shape=mxgraph.aws4.mobile_client;html=1;fillColor=#f3f4f6;strokeColor=#111827;strokeWidth=2;fontSize=16;fontStyle=1;fontColor=#111827;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=8;" value="Mobile App" vertex="1">
<mxGeometry height="95" width="72" x="864" y="215" as="geometry" />
<mxCell id="nt-mobile" value="Mobile App" style="shape=mxgraph.aws4.mobile_client;html=1;fillColor=#f3f4f6;strokeColor=#111827;strokeWidth=2;fontSize=16;fontStyle=1;fontColor=#111827;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=8;" parent="1" vertex="1">
<mxGeometry x="864" y="215" width="72" height="95" as="geometry"/>
</mxCell>
<mxCell id="nt-internet" parent="1" style="shape=cloud;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#1f2937;" value="Internet" vertex="1">
<mxGeometry height="110" width="210" x="795" y="365" as="geometry" />
<mxCell id="nt-internet" value="Internet" style="shape=cloud;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="795" y="365" width="210" height="110" as="geometry"/>
</mxCell>
<mxCell id="nt-dns" parent="1" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;fillColor=#ffffff;strokeColor=#6b7280;strokeWidth=1.4;fontSize=13;fontStyle=1;fontColor=#111827;" value="Public DNS / Domain" vertex="1">
<mxGeometry height="74" width="150" x="825" y="535" as="geometry" />
<mxCell id="nt-dns" value="Public DNS / Domain" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;fillColor=#ffffff;strokeColor=#6b7280;strokeWidth=1.4;fontSize=13;fontStyle=1;fontColor=#111827;" parent="1" vertex="1">
<mxGeometry x="825" y="535" width="150" height="74" as="geometry"/>
</mxCell>
<mxCell id="nt-azure" parent="1" style="shape=mxgraph.azure.cloud;html=1;fillColor=#ffffff;strokeColor=#111827;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#111827;verticalAlign=top;spacingTop=18;" value="Azure China&lt;br&gt;Primary App Backend VNet" vertex="1">
<mxGeometry height="470" width="520" x="80" y="255" as="geometry" />
<mxCell id="nt-azure" value="Azure China&lt;br&gt;Primary App Backend VNet" style="shape=mxgraph.azure.cloud;html=1;fillColor=#ffffff;strokeColor=#111827;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#111827;verticalAlign=top;spacingTop=18;" parent="1" vertex="1">
<mxGeometry x="80" y="255" width="520" height="470" as="geometry"/>
</mxCell>
<mxCell id="nt-azure-boundary" parent="1" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#111827;strokeWidth=1.8;dashed=1;dashPattern=6 6;fontSize=13;fontColor=#111827;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;" value="VNet boundary" vertex="1">
<mxGeometry height="330" width="430" x="125" y="345" as="geometry" />
<mxCell id="nt-azure-boundary" value="VNet boundary" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#111827;strokeWidth=1.8;dashed=1;dashPattern=6 6;fontSize=13;fontColor=#111827;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;" parent="1" vertex="1">
<mxGeometry x="125" y="345" width="430" height="330" as="geometry"/>
</mxCell>
<mxCell id="nt-azure-dmz" parent="1" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=#f9fafb;strokeColor=#374151;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Public DMZ Subnet" vertex="1">
<mxGeometry height="98" width="360" x="160" y="380" as="geometry" />
<mxCell id="nt-azure-dmz" value="Public DMZ Subnet" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=#f9fafb;strokeColor=#374151;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="160" y="380" width="360" height="98" as="geometry"/>
</mxCell>
<mxCell id="nt-azure-ingress" parent="1" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" value="WAF / App Gateway&lt;br&gt;+ Public LB" vertex="1">
<mxGeometry height="58" width="210" x="235" y="412" as="geometry" />
<mxCell id="nt-azure-ingress" value="WAF / App Gateway&lt;br&gt;+ Public LB" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="235" y="412" width="210" height="58" as="geometry"/>
</mxCell>
<mxCell id="nt-azure-private" parent="1" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=#f3f4f6;strokeColor=#6b7280;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Private Application Subnet" vertex="1">
<mxGeometry height="150" width="360" x="160" y="505" as="geometry" />
<mxCell id="nt-azure-private" value="Private Application Subnet" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=#f3f4f6;strokeColor=#6b7280;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="160" y="505" width="360" height="150" as="geometry"/>
</mxCell>
<mxCell id="nt-app-backend" parent="1" style="shape=mxgraph.azure.app_services;html=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=6;" value="" vertex="1">
<mxGeometry height="74" width="110" x="230" y="556" as="geometry" />
<mxCell id="nt-app-backend" value="" style="shape=mxgraph.azure.app_services;html=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=6;" parent="1" vertex="1">
<mxGeometry x="230" y="556" width="110" height="74" as="geometry"/>
</mxCell>
<mxCell id="nt-f6-adapter" parent="1" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" value="F6 Integration&lt;br&gt;Adapter" vertex="1">
<mxGeometry height="58" width="130" x="370" y="556" as="geometry" />
<mxCell id="nt-f6-adapter" value="F6 Integration&lt;br&gt;Adapter" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="370" y="556" width="130" height="58" as="geometry"/>
</mxCell>
<mxCell id="nt-nsg" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f3f4f6;strokeColor=#6b7280;strokeWidth=1.3;fontSize=12;fontStyle=1;fontColor=#111827;" value="NSG / Access Rules" vertex="1">
<mxGeometry height="32" width="220" x="230" y="505" as="geometry" />
<mxCell id="nt-nsg" value="NSG / Access Rules" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f3f4f6;strokeColor=#6b7280;strokeWidth=1.3;fontSize=12;fontStyle=1;fontColor=#111827;" parent="1" vertex="1">
<mxGeometry x="230" y="505" width="220" height="32" as="geometry"/>
</mxCell>
<mxCell id="nt-mini" parent="1" style="shape=mxgraph.azure.cloud;html=1;fillColor=#ffffff;strokeColor=#111827;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#111827;verticalAlign=top;spacingTop=18;" value="Mini Program Backend&lt;br&gt;Independent VPC" vertex="1">
<mxGeometry height="360" width="430" x="80" y="720" as="geometry" />
<mxCell id="nt-mini" value="Mini Program Backend&lt;br&gt;Independent VPC" style="shape=mxgraph.azure.cloud;html=1;fillColor=#ffffff;strokeColor=#111827;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#111827;verticalAlign=top;spacingTop=18;" parent="1" vertex="1">
<mxGeometry x="80" y="720" width="430" height="360" as="geometry"/>
</mxCell>
<mxCell id="nt-mini-boundary" parent="1" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#111827;strokeWidth=1.8;dashed=1;dashPattern=6 6;fontSize=13;fontColor=#111827;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;" value="VPC boundary" vertex="1">
<mxGeometry height="225" width="340" x="125" y="820" as="geometry" />
<mxCell id="nt-mini-boundary" value="VPC boundary" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#111827;strokeWidth=1.8;dashed=1;dashPattern=6 6;fontSize=13;fontColor=#111827;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;" parent="1" vertex="1">
<mxGeometry x="125" y="820" width="340" height="225" as="geometry"/>
</mxCell>
<mxCell id="nt-mini-gw" parent="1" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" value="Mini Gateway&lt;br&gt;/ Firewall" vertex="1">
<mxGeometry height="58" width="150" x="160" y="875" as="geometry" />
<mxCell id="nt-mini-gw" value="Mini Gateway&lt;br&gt;/ Firewall" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="160" y="875" width="150" height="58" as="geometry"/>
</mxCell>
<mxCell id="nt-mini-svc" parent="1" style="shape=datastore;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" value="Mini Services&lt;br&gt;O2O / Warranty&lt;br&gt;马上下单 / ROOS" vertex="1">
<mxGeometry height="92" width="150" x="285" y="935" as="geometry" />
<mxCell id="nt-mini-svc" value="Mini Services&lt;br&gt;O2O / Warranty&lt;br&gt;马上下单 / ROOS" style="shape=datastore;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="285" y="935" width="150" height="92" as="geometry"/>
</mxCell>
<mxCell id="nt-f6" parent="1" style="shape=mxgraph.azure.cloud;html=1;fillColor=#f9fafb;strokeColor=#111827;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#111827;verticalAlign=top;spacingTop=18;" value="F6 Supplier VPC&lt;br&gt;Alibaba Cloud" vertex="1">
<mxGeometry height="540" width="520" x="1200" y="255" as="geometry" />
<mxCell id="nt-f6" value="F6 Supplier VPC&lt;br&gt;Alibaba Cloud" style="shape=mxgraph.azure.cloud;html=1;fillColor=#f9fafb;strokeColor=#111827;strokeWidth=2;fontSize=18;fontStyle=1;fontColor=#111827;verticalAlign=top;spacingTop=18;" parent="1" vertex="1">
<mxGeometry x="1200" y="255" width="520" height="540" as="geometry"/>
</mxCell>
<mxCell id="nt-f6-boundary" parent="1" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#111827;strokeWidth=1.8;dashed=1;dashPattern=6 6;fontSize=13;fontColor=#111827;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;" value="Supplier-managed VPC boundary" vertex="1">
<mxGeometry height="390" width="430" x="1245" y="345" as="geometry" />
<mxCell id="nt-f6-boundary" value="Supplier-managed VPC boundary" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#111827;strokeWidth=1.8;dashed=1;dashPattern=6 6;fontSize=13;fontColor=#111827;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;" parent="1" vertex="1">
<mxGeometry x="1245" y="345" width="430" height="390" as="geometry"/>
</mxCell>
<mxCell id="nt-f6-public" parent="1" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=#f9fafb;strokeColor=#374151;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Public Access Subnet" vertex="1">
<mxGeometry height="130" width="360" x="1280" y="380" as="geometry" />
<mxCell id="nt-f6-public" value="Public Access Subnet" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=#f9fafb;strokeColor=#374151;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1280" y="380" width="360" height="130" as="geometry"/>
</mxCell>
<mxCell id="nt-f6-h5-ingress" parent="1" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" value="Access Gateway / WAF&lt;br&gt;+ Load Balancer" vertex="1">
<mxGeometry height="58" width="190" x="1305" y="425" as="geometry" />
<mxCell id="nt-f6-h5-ingress" value="Access Gateway / WAF&lt;br&gt;+ Load Balancer" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1305" y="425" width="190" height="58" as="geometry"/>
</mxCell>
<mxCell id="nt-f6-api-gw" parent="1" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" value="Allowlisted&lt;br&gt;B2B API Gateway" vertex="1">
<mxGeometry height="58" width="150" x="1510" y="425" as="geometry" />
<mxCell id="nt-f6-api-gw" value="Allowlisted&lt;br&gt;B2B API Gateway" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#374151;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1510" y="425" width="150" height="58" as="geometry"/>
</mxCell>
<mxCell id="nt-f6-private" parent="1" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=#f3f4f6;strokeColor=#6b7280;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" value="Private Service Subnet" vertex="1">
<mxGeometry height="165" width="360" x="1280" y="540" as="geometry" />
<mxCell id="nt-f6-private" value="Private Service Subnet" style="shape=rect;rounded=0;whiteSpace=wrap;html=1;fillColor=#f3f4f6;strokeColor=#6b7280;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1280" y="540" width="360" height="165" as="geometry"/>
</mxCell>
<mxCell id="nt-f6-h5" parent="1" style="shape=mxgraph.aws4.client;html=1;fillColor=#ffffff;strokeColor=#6b7280;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=6;" value="F6 WebView&lt;br&gt;Pages" vertex="1">
<mxGeometry height="74" width="92" x="1325" y="595" as="geometry" />
<mxCell id="nt-f6-h5" value="F6 WebView&lt;br&gt;Pages" style="shape=mxgraph.aws4.client;html=1;fillColor=#ffffff;strokeColor=#6b7280;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacingTop=6;" parent="1" vertex="1">
<mxGeometry x="1325" y="595" width="92" height="74" as="geometry"/>
</mxCell>
<mxCell id="nt-f6-api" parent="1" style="shape=datastore;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#6b7280;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" value="F6 Capability APIs&lt;br&gt;Backend Only" vertex="1">
<mxGeometry height="74" width="150" x="1490" y="595" as="geometry" />
<mxCell id="nt-f6-api" value="F6 Capability APIs&lt;br&gt;Backend Only" style="shape=datastore;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;fillColor=#ffffff;strokeColor=#6b7280;strokeWidth=1.5;fontSize=13;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="1490" y="595" width="150" height="74" as="geometry"/>
</mxCell>
<mxCell id="nt-notes-box" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f9fafb;strokeColor=#9ca3af;strokeWidth=1.2;" value="" vertex="1">
<mxGeometry height="155" width="720" x="1000" y="875" as="geometry" />
<mxCell id="nt-notes-box" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f9fafb;strokeColor=#9ca3af;strokeWidth=1.2;" parent="1" vertex="1">
<mxGeometry x="1000" y="875" width="720" height="155" as="geometry"/>
</mxCell>
<mxCell id="nt-notes-title" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" value="Topology Reading" vertex="1">
<mxGeometry height="24" width="180" x="1030" y="895" as="geometry" />
<mxCell id="nt-notes-title" value="Topology Reading" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" parent="1" vertex="1">
<mxGeometry x="1030" y="895" width="180" height="24" as="geometry"/>
</mxCell>
<mxCell id="nt-notes-text" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontSize=14;fontColor=#374151;spacingTop=4;" value="1. This page is network-centric: VNet/VPC boundaries are the main objects.&lt;br&gt;2. Public traffic enters only through exposed ingress nodes.&lt;br&gt;3. Backend integration crosses network boundaries through controlled gateways.&lt;br&gt;4. Mini direct access is shown as a legacy exception, not a target route." vertex="1">
<mxGeometry height="88" width="650" x="1030" y="930" as="geometry" />
<mxCell id="nt-notes-text" value="1. This page is network-centric: VNet/VPC boundaries are the main objects.&lt;br&gt;2. Public traffic enters only through exposed ingress nodes.&lt;br&gt;3. Backend integration crosses network boundaries through controlled gateways.&lt;br&gt;4. Mini direct access is shown as a legacy exception, not a target route." style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontSize=14;fontColor=#374151;spacingTop=4;" parent="1" vertex="1">
<mxGeometry x="1030" y="930" width="650" height="88" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-box" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#9ca3af;strokeWidth=1.2;" value="" vertex="1">
<mxGeometry height="180" width="320" x="640" y="877" as="geometry" />
<mxCell id="nt-legend-box" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#9ca3af;strokeWidth=1.2;" parent="1" vertex="1">
<mxGeometry x="640" y="877" width="320" height="180" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-title" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" value="Legend" vertex="1">
<mxGeometry height="24" width="90" x="670" y="885" as="geometry" />
<mxCell id="nt-legend-title" value="Legend" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=18;fontStyle=1;fontColor=#111827;" parent="1" vertex="1">
<mxGeometry x="670" y="885" width="90" height="24" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-primary-line" parent="1" style="shape=line;html=1;strokeColor=#111827;strokeWidth=2;" value="" vertex="1">
<mxGeometry height="10" width="70" x="675" y="928" as="geometry" />
<mxCell id="nt-legend-primary-line" value="" style="shape=line;html=1;strokeColor=#111827;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="675" y="928" width="70" height="10" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-primary-text" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" value="Primary App route" vertex="1">
<mxGeometry height="24" width="150" x="760" y="919" as="geometry" />
<mxCell id="nt-legend-primary-text" value="Primary App route" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="760" y="919" width="150" height="24" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-backend-line" parent="1" style="shape=line;html=1;strokeColor=#111827;strokeWidth=2;" value="" vertex="1">
<mxGeometry height="10" width="70" x="675" y="962" as="geometry" />
<mxCell id="nt-legend-backend-line" value="" style="shape=line;html=1;strokeColor=#111827;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="675" y="962" width="70" height="10" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-backend-text" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" value="Backend integration" vertex="1">
<mxGeometry height="24" width="160" x="760" y="953" as="geometry" />
<mxCell id="nt-legend-backend-text" value="Backend integration" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="760" y="953" width="160" height="24" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-h5-line" parent="1" style="shape=line;html=1;strokeColor=#111827;strokeWidth=2;dashed=1;dashPattern=2 4;" value="" vertex="1">
<mxGeometry height="10" width="70" x="675" y="996" as="geometry" />
<mxCell id="nt-legend-h5-line" value="" style="shape=line;html=1;strokeColor=#111827;strokeWidth=2;dashed=1;dashPattern=2 4;" parent="1" vertex="1">
<mxGeometry x="675" y="996" width="70" height="10" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-h5-text" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" value="F6 WebView route" vertex="1">
<mxGeometry height="24" width="160" x="760" y="987" as="geometry" />
<mxCell id="nt-legend-h5-text" value="F6 WebView route" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="760" y="987" width="160" height="24" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-legacy-line" parent="1" style="shape=line;html=1;strokeColor=#6b7280;strokeWidth=2;dashed=1;dashPattern=8 8;" value="" vertex="1">
<mxGeometry height="10" width="70" x="675" y="1030" as="geometry" />
<mxCell id="nt-legend-legacy-line" value="" style="shape=line;html=1;strokeColor=#6b7280;strokeWidth=2;dashed=1;dashPattern=8 8;" parent="1" vertex="1">
<mxGeometry x="675" y="1030" width="70" height="10" as="geometry"/>
</mxCell>
<mxCell id="nt-legend-legacy-text" parent="1" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" value="Legacy compatibility" vertex="1">
<mxGeometry height="24" width="170" x="760" y="1021" as="geometry" />
<mxCell id="nt-legend-legacy-text" value="Legacy compatibility" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="760" y="1021" width="170" height="24" as="geometry"/>
</mxCell>
<mxCell id="nt-e-mobile-internet" edge="1" parent="1" source="nt-mobile" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.5;" target="nt-internet">
<mxGeometry relative="1" as="geometry" />
<mxCell id="nt-e-mobile-internet" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.5;" parent="1" source="nt-mobile" target="nt-internet" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="nt-e-internet-dns" edge="1" parent="1" source="nt-internet" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.2;" target="nt-dns">
<mxGeometry relative="1" as="geometry" />
<mxCell id="nt-e-internet-dns" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.2;" parent="1" source="nt-internet" target="nt-dns" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="nt-e-dns-azure" edge="1" parent="1" source="nt-dns" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.5;fontSize=12;fontColor=#111827;labelBackgroundColor=#ffffff;" target="nt-azure-ingress" value="primary HTTPS">
<mxCell id="nt-e-dns-azure" value="HTTPS / REST API" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.5;fontSize=12;fontColor=#111827;labelBackgroundColor=#ffffff;" parent="1" source="nt-dns" target="nt-azure-ingress" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="600" y="572" />
<mxPoint x="600" y="441" />
<mxPoint x="600" y="572"/>
<mxPoint x="600" y="441"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="nt-e-azure-ingress-app" edge="1" parent="1" source="nt-azure-ingress" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.3;" target="nt-app-backend">
<mxGeometry relative="1" as="geometry" />
<mxCell id="nt-e-azure-ingress-app" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.3;" parent="1" source="nt-azure-ingress" target="nt-app-backend" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="nt-e-app-adapter" edge="1" parent="1" source="nt-app-backend" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.4;" target="nt-f6-adapter">
<mxGeometry relative="1" as="geometry" />
<mxCell id="nt-e-app-adapter" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.4;" parent="1" source="nt-app-backend" target="nt-f6-adapter" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="nt-e-adapter-f6-api-gw" edge="1" parent="1" source="nt-f6-adapter" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1;fontSize=12;fontColor=#111827;labelBackgroundColor=#ffffff;" target="nt-f6-api-gw" value="allowlisted B2B API">
<mxCell id="nt-e-adapter-f6-api-gw" value="HTTPS / allowlisted B2B API" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1;fontSize=12;fontColor=#111827;labelBackgroundColor=#ffffff;" parent="1" source="nt-f6-adapter" target="nt-f6-api-gw" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="435" y="640" />
<mxPoint x="1160" y="640" />
<mxPoint x="1160" y="500" />
<mxPoint x="1585" y="500" />
<mxPoint x="435" y="640"/>
<mxPoint x="1160" y="640"/>
<mxPoint x="1160" y="500"/>
<mxPoint x="1585" y="500"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="nt-e-f6-api-gw-api" edge="1" parent="1" source="nt-f6-api-gw" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.3;" target="nt-f6-api">
<mxGeometry relative="1" as="geometry" />
<mxCell id="nt-e-f6-api-gw-api" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.3;" parent="1" source="nt-f6-api-gw" target="nt-f6-api" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="nt-e-app-mini" edge="1" parent="1" source="nt-app-backend" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.8;fontSize=12;fontColor=#111827;labelBackgroundColor=#ffffff;" target="nt-mini-gw" value="backend aggregation">
<mxCell id="nt-e-app-mini" value="HTTPS / Internal API" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.8;fontSize=12;fontColor=#111827;labelBackgroundColor=#ffffff;" parent="1" source="nt-app-backend" target="nt-mini-gw" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="285" y="690" />
<mxPoint x="235" y="690" />
<mxPoint x="285" y="690"/>
<mxPoint x="235" y="690"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="nt-e-mini-gw-svc" edge="1" parent="1" source="nt-mini-gw" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.3;" target="nt-mini-svc">
<mxGeometry relative="1" as="geometry" />
<mxCell id="nt-e-mini-gw-svc" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.3;" parent="1" source="nt-mini-gw" target="nt-mini-svc" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="nt-e-dns-f6-h5" edge="1" parent="1" source="nt-dns" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.4;fontSize=12;fontColor=#111827;labelBackgroundColor=#ffffff;dashed=1;dashPattern=2 4;" target="nt-f6-h5-ingress" value="embedded WebView">
<mxCell id="nt-e-dns-f6-h5" value="HTTPS / embedded WebView" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.4;fontSize=12;fontColor=#111827;labelBackgroundColor=#ffffff;dashed=1;dashPattern=2 4;" parent="1" source="nt-dns" target="nt-f6-h5-ingress" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1080" y="572" />
<mxPoint x="1080" y="454" />
<mxPoint x="1080" y="572"/>
<mxPoint x="1080" y="454"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="nt-e-f6-h5-ingress-h5" edge="1" parent="1" source="nt-f6-h5-ingress" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.2;dashed=1;dashPattern=2 4;" target="nt-f6-h5">
<mxGeometry relative="1" as="geometry" />
<mxCell id="nt-e-f6-h5-ingress-h5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#111827;strokeWidth=1.2;dashed=1;dashPattern=2 4;" parent="1" source="nt-f6-h5-ingress" target="nt-f6-h5" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="nt-e-legacy-mini" edge="1" parent="1" source="nt-dns" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;dashed=1;dashPattern=8 8;strokeColor=#6b7280;strokeWidth=1.3;fontSize=12;fontColor=#4b5563;labelBackgroundColor=#ffffff;" target="nt-mini-gw" value="legacy only">
<mxCell id="nt-e-legacy-mini" value="legacy only" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;dashed=1;dashPattern=8 8;strokeColor=#6b7280;strokeWidth=1.3;fontSize=12;fontColor=#4b5563;labelBackgroundColor=#ffffff;" parent="1" source="nt-dns" target="nt-mini-gw" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="640" y="572" />
<mxPoint x="640" y="904" />
<mxPoint x="640" y="572"/>
<mxPoint x="640" y="904"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="OBjgTYgMnUBFrRI9yGty-1" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontSize=10;" value="&lt;span style=&quot;color: rgb(31, 41, 55); font-weight: 700; white-space: nowrap;&quot;&gt;App Backend&lt;/span&gt;&lt;br style=&quot;color: rgb(31, 41, 55); font-weight: 700; white-space: nowrap;&quot;&gt;&lt;span style=&quot;color: rgb(31, 41, 55); font-weight: 700; white-space: nowrap;&quot;&gt;BFF + Orchestration&lt;/span&gt;" vertex="1">
<mxGeometry height="73" width="110" x="230" y="557" as="geometry" />
<mxCell id="OBjgTYgMnUBFrRI9yGty-1" value="&lt;span style=&quot;color: rgb(31, 41, 55); font-weight: 700; white-space: nowrap;&quot;&gt;App Backend&lt;/span&gt;&lt;br style=&quot;color: rgb(31, 41, 55); font-weight: 700; white-space: nowrap;&quot;&gt;&lt;span style=&quot;color: rgb(31, 41, 55); font-weight: 700; white-space: nowrap;&quot;&gt;BFF + Orchestration&lt;/span&gt;" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="230" y="557" width="110" height="73" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="environment-segmentation" name="Environment Segmentation">
<mxGraphModel dx="898" dy="770" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1800" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="es-title" value="Continental Retail APP Environment Segmentation" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=28;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="60" y="28" width="760" height="40" as="geometry"/>
</mxCell>
<mxCell id="es-subtitle" value="DEV, UAT, and PROD are isolated network environments. App-facing APIs use controlled public ingress; application and data services remain private." style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;fontSize=13;fontColor=#4b5563;" parent="1" vertex="1">
<mxGeometry x="60" y="68" width="1180" height="24" as="geometry"/>
</mxCell>
<mxCell id="es-version-box" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#9ca3af;strokeWidth=1.5;" parent="1" vertex="1">
<mxGeometry x="1490" y="26" width="240" height="74" as="geometry"/>
</mxCell>
<mxCell id="es-version-text" value="Version: v1.0&lt;br&gt;Date: 2026-08-31&lt;br&gt;Page: Environment Segmentation" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;fontSize=12;fontColor=#374151;spacingTop=8;spacingLeft=10;" parent="1" vertex="1">
<mxGeometry x="1500" y="32" width="220" height="62" as="geometry"/>
</mxCell>
<mxCell id="es-mobile" value="Mobile App" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dbeafe;strokeColor=#2563eb;strokeWidth=2;fontSize=16;fontStyle=1;fontColor=#1e3a8a;" parent="1" vertex="1">
<mxGeometry x="805" y="125" width="190" height="55" as="geometry"/>
</mxCell>
<mxCell id="es-internet" value="Internet" style="shape=cloud;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#94a3b8;strokeWidth=1.8;fontSize=15;fontStyle=1;fontColor=#1f2937;" parent="1" vertex="1">
<mxGeometry x="830" y="215" width="140" height="58" as="geometry"/>
</mxCell>
<mxCell id="es-dev" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#14532d;strokeColor=#14532d;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="60" y="310" width="510" height="650" as="geometry"/>
</mxCell>
<mxCell id="es-dev-title" value="DEV Environment - Isolated VNet / VPC" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=21;fontStyle=1;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="80" y="325" width="470" height="30" as="geometry"/>
</mxCell>
<mxCell id="es-dev-cidr" value="VNet / VPC CIDR: [DEV CIDR TBD]" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#bbf7d0;strokeColor=#4ade80;fontSize=12;fontColor=#14532d;" parent="1" vertex="1">
<mxGeometry x="188" y="360" width="255" height="26" as="geometry"/>
</mxCell>
<mxCell id="es-dev-public" value="Public App API Ingress Subnet [CIDR TBD]" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dcfce7;strokeColor=#22c55e;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#14532d;" parent="1" vertex="1">
<mxGeometry x="90" y="405" width="450" height="120" as="geometry"/>
</mxCell>
<mxCell id="es-dev-ingress" value="WAF / Application Gateway&lt;br&gt;Public App API Endpoint" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#22c55e;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#14532d;" parent="1" vertex="1">
<mxGeometry x="193" y="445" width="245" height="58" as="geometry"/>
</mxCell>
<mxCell id="es-dev-app" value="Private Application Subnet [CIDR TBD] - No public IP" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dcfce7;strokeColor=#22c55e;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#14532d;" parent="1" vertex="1">
<mxGeometry x="90" y="550" width="450" height="150" as="geometry"/>
</mxCell>
<mxCell id="es-dev-services" value="BFF / Orchestration&lt;br&gt;Integration Adapters / Internal Services" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#22c55e;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#14532d;" parent="1" vertex="1">
<mxGeometry x="170" y="600" width="290" height="64" as="geometry"/>
</mxCell>
<mxCell id="es-dev-data" value="Private Data / Private Endpoint Subnet [CIDR TBD]" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#bbf7d0;strokeColor=#4ade80;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#14532d;" parent="1" vertex="1">
<mxGeometry x="90" y="725" width="450" height="105" as="geometry"/>
</mxCell>
<mxCell id="es-dev-data-service" value="Database / Cache / Secrets / Logging" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#4ade80;strokeWidth=1.4;fontSize=13;fontStyle=1;fontColor=#14532d;" parent="1" vertex="1">
<mxGeometry x="175" y="770" width="280" height="42" as="geometry"/>
</mxCell>
<mxCell id="es-dev-admin" value="Approved remote admin IP ranges&lt;br&gt;VPN / White List" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#22c55e;strokeWidth=1.5;fontSize=12;fontStyle=1;fontColor=#14532d;" parent="1" vertex="1">
<mxGeometry x="210" y="865" width="210" height="55" as="geometry"/>
</mxCell>
<mxCell id="es-uat" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ede9fe;strokeColor=#7e22ce;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="645" y="310" width="510" height="650" as="geometry"/>
</mxCell>
<mxCell id="es-uat-title" value="UAT Environment - Isolated VNet / VPC" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=21;fontStyle=1;fontColor=#6b21a8;" parent="1" vertex="1">
<mxGeometry x="665" y="325" width="470" height="30" as="geometry"/>
</mxCell>
<mxCell id="es-uat-cidr" value="VNet / VPC CIDR: [UAT CIDR TBD]" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ddd6fe;strokeColor=#a78bfa;fontSize=12;fontColor=#6b21a8;" parent="1" vertex="1">
<mxGeometry x="773" y="360" width="255" height="26" as="geometry"/>
</mxCell>
<mxCell id="es-uat-public" value="Public App API Ingress Subnet [CIDR TBD]" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f3ff;strokeColor=#8b5cf6;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#6b21a8;" parent="1" vertex="1">
<mxGeometry x="675" y="405" width="450" height="120" as="geometry"/>
</mxCell>
<mxCell id="es-uat-ingress" value="WAF / Application Gateway&lt;br&gt;Public App API Endpoint Only" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#8b5cf6;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#6b21a8;" parent="1" vertex="1">
<mxGeometry x="778" y="445" width="245" height="58" as="geometry"/>
</mxCell>
<mxCell id="es-uat-app" value="Private Application Subnet [CIDR TBD] - Internal only" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f3ff;strokeColor=#8b5cf6;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#6b21a8;" parent="1" vertex="1">
<mxGeometry x="675" y="550" width="450" height="150" as="geometry"/>
</mxCell>
<mxCell id="es-uat-services" value="BFF / Orchestration&lt;br&gt;Integration Adapters / Internal Services" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#8b5cf6;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#6b21a8;" parent="1" vertex="1">
<mxGeometry x="755" y="600" width="290" height="64" as="geometry"/>
</mxCell>
<mxCell id="es-uat-data" value="Private Data / Private Endpoint Subnet [CIDR TBD]" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ede9fe;strokeColor=#a78bfa;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#6b21a8;" parent="1" vertex="1">
<mxGeometry x="675" y="725" width="450" height="105" as="geometry"/>
</mxCell>
<mxCell id="es-uat-data-service" value="Database / Cache / Secrets / Logging" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#a78bfa;strokeWidth=1.4;fontSize=13;fontStyle=1;fontColor=#6b21a8;" parent="1" vertex="1">
<mxGeometry x="760" y="770" width="280" height="42" as="geometry"/>
</mxCell>
<mxCell id="es-prod" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#7f1d1d;strokeColor=#7f1d1d;strokeWidth=2;" parent="1" vertex="1">
<mxGeometry x="1230" y="310" width="510" height="650" as="geometry"/>
</mxCell>
<mxCell id="es-prod-title" value="PROD Environment - Isolated VNet / VPC" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=21;fontStyle=1;fontColor=#ffffff;" parent="1" vertex="1">
<mxGeometry x="1250" y="325" width="470" height="30" as="geometry"/>
</mxCell>
<mxCell id="es-prod-cidr" value="VNet / VPC CIDR: [PROD CIDR TBD]" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fecaca;strokeColor=#f87171;fontSize=12;fontColor=#7f1d1d;" parent="1" vertex="1">
<mxGeometry x="1352" y="360" width="265" height="26" as="geometry"/>
</mxCell>
<mxCell id="es-prod-public" value="Public App API Ingress Subnet [CIDR TBD]" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fef2f2;strokeColor=#ef4444;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#7f1d1d;" parent="1" vertex="1">
<mxGeometry x="1260" y="405" width="450" height="120" as="geometry"/>
</mxCell>
<mxCell id="es-prod-ingress" value="WAF / Application Gateway&lt;br&gt;Public App API Endpoint Only" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#ef4444;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#7f1d1d;" parent="1" vertex="1">
<mxGeometry x="1363" y="445" width="245" height="58" as="geometry"/>
</mxCell>
<mxCell id="es-prod-app" value="Private Application Subnet [CIDR TBD] - Internal only" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fef2f2;strokeColor=#ef4444;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#7f1d1d;" parent="1" vertex="1">
<mxGeometry x="1260" y="550" width="450" height="150" as="geometry"/>
</mxCell>
<mxCell id="es-prod-services" value="BFF / Orchestration&lt;br&gt;Integration Adapters / Internal Services" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#ef4444;strokeWidth=1.5;fontSize=14;fontStyle=1;fontColor=#7f1d1d;" parent="1" vertex="1">
<mxGeometry x="1340" y="600" width="290" height="64" as="geometry"/>
</mxCell>
<mxCell id="es-prod-data" value="Private Data / Private Endpoint Subnet [CIDR TBD]" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fee2e2;strokeColor=#f87171;strokeWidth=1.4;fontStyle=1;verticalAlign=top;align=left;spacingTop=8;spacingLeft=10;fontColor=#7f1d1d;" parent="1" vertex="1">
<mxGeometry x="1260" y="725" width="450" height="105" as="geometry"/>
</mxCell>
<mxCell id="es-prod-data-service" value="Database / Cache / Secrets / Logging" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#f87171;strokeWidth=1.4;fontSize=13;fontStyle=1;fontColor=#7f1d1d;" parent="1" vertex="1">
<mxGeometry x="1345" y="770" width="280" height="42" as="geometry"/>
</mxCell>
<mxCell id="es-notes" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8fafc;strokeColor=#d1d5db;strokeWidth=1.2;" parent="1" vertex="1">
<mxGeometry x="60" y="990" width="1680" height="80" as="geometry"/>
</mxCell>
<mxCell id="es-notes-text" value="Isolation: separate subscription/account and VNet/VPC per environment; no cross-environment routing. DEV remote admin: approved IP ranges via VPN / Bastion only.&lt;br&gt;Public ingress: bidirectional HTTPS / REST API to App-facing endpoints only; private application and data subnets have no public IP and accept approved same-environment traffic only." style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;fontSize=13;fontColor=#374151;" parent="1" vertex="1">
<mxGeometry x="72" y="995" width="1645" height="70" as="geometry"/>
</mxCell>
<mxCell id="es-e-mobile-internet" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#2563eb;strokeWidth=1.5;" parent="1" source="es-mobile" target="es-internet" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="es-e-internet-dev" value="HTTPS / REST API" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#166534;strokeWidth=1.4;fontSize=12;fontColor=#14532d;labelBackgroundColor=#ffffff;" parent="1" source="es-internet" target="es-dev-ingress" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="315" y="285"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="es-e-internet-uat" value="HTTPS / REST API" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#7e22ce;strokeWidth=1.4;fontSize=12;fontColor=#6b21a8;labelBackgroundColor=#ffffff;" parent="1" source="es-internet" target="es-uat-ingress" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="es-e-internet-prod" value="HTTPS / REST API" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=block;startFill=1;endArrow=block;endFill=1;strokeColor=#b91c1c;strokeWidth=1.4;fontSize=12;fontColor=#7f1d1d;labelBackgroundColor=#ffffff;" parent="1" source="es-internet" target="es-prod-ingress" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1485" y="285"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="es-e-dev-ingress-app" value="private TLS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#166534;strokeWidth=1.3;fontSize=11;fontColor=#14532d;labelBackgroundColor=#ffffff;" parent="1" source="es-dev-ingress" target="es-dev-services" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="es-e-uat-ingress-app" value="private TLS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#7e22ce;strokeWidth=1.3;fontSize=11;fontColor=#6b21a8;labelBackgroundColor=#ffffff;" parent="1" source="es-uat-ingress" target="es-uat-services" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="es-e-prod-ingress-app" value="private TLS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#b91c1c;strokeWidth=1.3;fontSize=11;fontColor=#7f1d1d;labelBackgroundColor=#ffffff;" parent="1" source="es-prod-ingress" target="es-prod-services" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="es-e-dev-app-data" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#166534;strokeWidth=1.2;" parent="1" source="es-dev-services" target="es-dev-data-service" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="es-e-uat-app-data" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#7e22ce;strokeWidth=1.2;" parent="1" source="es-uat-services" target="es-uat-data-service" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="es-e-prod-app-data" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=#b91c1c;strokeWidth=1.2;" parent="1" source="es-prod-services" target="es-prod-data-service" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="es-e-dev-admin" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;dashed=1;dashPattern=8 8;strokeColor=#166534;strokeWidth=1.2;" parent="1" source="es-dev-admin" target="es-dev-services" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
+4 -2
View File
@@ -109,11 +109,13 @@ V1.1 相对 V1.0 的主要变化:第 4 章拆分到 [`prd/modules/`](./prd/mod
### tech-selection/
对外的技术选型说明材料,写给客户方,可直接作为会议材料使用:
技术选型说明材料。**前两份对外**,写给客户方,可直接作为会议材料使用;**第三份是内部讲稿,不外发**:
| 文档 | 内容 |
| --- | --- |
| [tech-selection/前端技术路线评估-Flutter-vs-UniApp.md](./tech-selection/前端技术路线评估-Flutter-vs-UniApp.md) | Flutter / uni-app / uni-app x 三条路线对比,结论**推荐 Flutter**。六章:① 市面跨端方案清单与四条架构路线 ② 三者定位与架构对比 ③ 结合本项目业务的技术评估 ④ 生态、社区、落地规模与 AI 工具链 ⑤ 构建发布与可扩展性 ⑥ 结论(含成本口径:首版 ±10% 基本持平,差异在五年周期)。附录 A 来源清单、附录 B 术语表、**附录 C 对 DCloud 官方对比材料的逐条核验**(含热更新、包体、内存这几条对我方不利项的主动列出)。含非技术读者可读的通俗解释 |
| [tech-selection/Flutter-vs-UniApp.md](./tech-selection/Flutter-vs-UniApp.md) | Flutter / uni-app / uni-app x 三条路线对比,结论**推荐 Flutter**。六章:① 市面跨端方案清单与四条架构路线 ② 三者定位与架构对比 ③ 结合本项目业务的技术评估 ④ 生态、社区、落地规模与 AI 工具链 ⑤ 构建发布与可扩展性 ⑥ 结论(含成本口径:首版 ±10% 基本持平,差异在五年周期)。附录 A 来源清单、附录 B 术语表、**附录 C 对 DCloud 官方对比材料的逐条核验**(含热更新、包体、内存这几条对我方不利项的主动列出)。含非技术读者可读的通俗解释 |
| [tech-selection/Flutter-vs-UniApp-deck.standalone.html](./tech-selection/Flutter-vs-UniApp-deck.standalone.html) | 上一份材料提炼成的 27 页演示稿,单文件、无外部依赖,浏览器直接打开即可放映(方向键/空格翻页、`F` 全屏、`O` 总览、`#12` 直达某页)。语气比 md 更克制,证据标 A/B/C 三档。同目录的 `-deck.html` 是同一份的非独立版本,图片走外链 |
| tech-selection/Flutter-vs-UniApp-Speaker.md | ⛔ **内部使用,不外发。** 上面 deck 的 27 页内容摘要:每页的落点、关键数字与页脚口径,附 30 分钟配时与超时取舍、数字速查表、问答速查、三条只可口头引用的材料。含「不写进书面材料」的内容,**不要连同前两份一起发给客户**(故意不做成链接,避免误点误发) |
与 `flutter-app/` 的分工:**技术结论仍以 `flutter-app/01-14` 为准**,本目录只做对外解释与论证,不产生新的技术决策。文中所有对 uni-app x 的判断都在附录 A 给出了来源链接,其中仅 5.4 节的安卓小组件交付清单取自社区实战记录(已就地标注),其余均为官方文档,便于客户自行复核(核验日期 2026-08-25,日后引用前建议重新抽查)。
+347
View File
@@ -0,0 +1,347 @@
# Flutter vs uni-app x — 27 页内容摘要
配 `Flutter-vs-UniApp-deck.standalone.html`。数据核验 2026-08-25,出处见 `Flutter-vs-UniApp.md` 附录 A。
30 分钟配时写在每页标题后。对表点:**第 12 页 ≈ 12:00 · 第 17 页 ≈ 18:40 · 第 22 页 ≈ 24:40**。
---
## 事实校正
以下六条**在材料里没有依据**,是早期版本里被推翻的说法:
| 错 | 对 |
| --- | --- |
| uni-app x 不支持 iOS / 鸿蒙 / AI 工具 | 三条 2026 年都支持;鸿蒙它更强 |
| uni-app x 只有文档开源 | 组件与 API 是 Apache-2.0 开源;闭的是 Runtime、原生 SDK、HBuilderX |
| 提交量差几十倍 | 8.1 倍(91,171 / 11,216) |
| UVue 是改过的 Weex | nvue 才是 |
| 小组件 / Siri 做不到 | 做得到,代价是开 Xcode 写 Swift + 多绕一层 DCloud 打包规则 |
| 离线打包 = 原生工程完全可定制 | 围着闭源 AAR 的壳工程;壳外可加,壳内不可改 |
三个措辞口径:uni-app x 大厂案例是**「未检索到」不是「没有」**;成本是**「基本持平」不是「Flutter 更便宜」**;ID. UNYX 的依据是**大众安徽官网合规披露那条公开链接**。
---
## 逐页
### 1 · 封面 — 0:30
App 技术栈介绍 · T-Systems · 2026 年 8 月。
### 2 · 目录 — 0:30
五部分:跨端技术路线 / 三框架定位 / 生态与落地 / 产品能力与工程链路 / 结论。
### 3 · 结论摘要 · 推荐 Flutter — 2:00
**落点**:四条理由,且明确不做优劣评判。
- **界面两端完全一致** — 自绘引擎,不用系统控件、不依赖各机型浏览器内核。对本项目 = 六套来源不同的小程序整合后,同一业务概念在各页面长得一样
- **系统能力无额外限制** — 原生侧就是标准 Xcode / Android Studio 工程;小组件、Siri、系统推送按常规原生做,不必学第二套插件规则
- **大型 App 先例充分** — BMW、大众安徽、字节、阿里、腾讯、美团、京东、贝壳、携程;引擎到框架全部开源
- **技术栈稳定** — Flutter 2015 至今同一主线;uni-app 系同期换过两代 App 方案(5+ App、nvue),两代已于 2024 年停止官方维护
- 页脚原文:不做优劣评判,只对照与本项目形态的匹配度;uni-app x 更优三项在第 24 页
### 4 · 三个框架核心对照 — 1:30
10 行表。**前 7 行 Flutter 占优,后 3 行 uni-app x 占优**(鸿蒙 / 包体内存 / 成本)。
值得停的四行:
- **嵌 F6 网页** — Flutter 侧 F6 零改动;uni-app x 侧需 F6 引入 `uni.webview.1.5.5.js`
- **原生能力开发** — Flutter 支持命令行;uni-app x 插件只能经 HBuilderX
- **开源程度** — 差别在开到哪一层,见第 13 页
- **成本** — ±10% 以内,基本持平
### 5 · 分隔 01 — 0:10
跨端开发的技术路线。
### 6 · 市面方案按原理只有四类 — 1:20
11 个方案归四类:① 原生双端 ② 网页套壳(uni-app、Cordova、Capacitor、Taro)③ 编译到系统控件(uni-app x、RN、Kuikly、MAUI)④ 自绘引擎(**只有 Flutter**)。
- `5+ App`、`nvue` 标灰 = DCloud 上一代方案,已停止维护
- 未展开的:RN 前提是团队已有 React 栈;Taro / Cordova / Capacitor 重心仍是网页路线;KMP 只共享逻辑层;Kuikly 2025 年开源,对外生态尚早
### 7 · 四条路线,从代码到屏幕 — 2:00
四根柱子的分层图。落点在页脚:**路线 ② ③ 的界面最终交给别人画**(一个交给浏览器内核,一个交给系统控件),**路线 ④ 把这层拿回框架自己手里**——是控制权归属,不是好坏。
装修类比(md 1.2 已有):② 贴壁纸,墙有多平壁纸就有多平 · ③ 翻译图纸,词典没有的词做不出来、得自己补 · ④ 自带施工队,进哪套房子装出来都一样。
### 8 · 「界面由谁绘制」影响三件事 — 1:10
三行:两端一致性 / 做设计稿上的特殊效果 / 用一个新的系统能力。
落点在右下两张卡:本项目要嵌 F6 网页、要用扫码定位推送相机等一批系统能力、两端要保持一致品牌体验 → **一致性和系统能力两列同时重要,而路线 ④ 在这两列都不受第三方约束。**
### 9 · 分隔 02 — 0:10
三个框架的定位。
### 10 · 三者各走哪条路线 — 1:10
- **Flutter** — Dart 编译成机器码,无 JS 解释器,引擎自绘
- **uni-app** — Vue 代码,App 端跑在 WebView 里
- **uni-app x** — UTS 编译成 Kotlin / Swift,界面用系统控件;柱子第三层标着 **DCloud Runtime(闭源)**
页脚:**uni-app x 与 uni-app 是两套独立技术栈,不是版本升级关系**。佐证——uni-app x 不支持传统 uni-app 的原生插件,旧插件已停止新增上架,自家体系内迁移插件也要重写。
### 11 · 三个框架各自为谁设计 — 1:20
四行表,重点是「最初要解决的问题」这行:Flutter = 一套代码做体验接近原生的独立 App;uni-app = 一套 Vue 同时发小程序 / H5 / App;uni-app x = 让 Vue 团队产出真正的原生 App。
落点在两张卡:**首版只发 iOS / Android,不发小程序也不要 H5,且目标之一就是关停现有六套小程序** → uni-app 系最值钱的多端复用能力在本项目没有买家,要承担它的架构代价却收不到最大那份好处。
> ⚠️ 屏幕上能力清单列了「蓝牙」,但 `Flutter-vs-UniApp.md` 的原生能力表没有这一项。
### 12 · 分隔 03 — 0:10 📍 ≈ 12:00
生态与落地规模。
### 13 · 开源到哪一层,社区多大 — 1:30
**上半(重点)**:Flutter 三层全开——业务框架层 / 渲染引擎 / CLI 与构建工具。uni-app x 业务框架层开源(Apache-2.0),**下两层闭源**——Runtime 与原生 SDK、HBuilderX 与打包服务。
含义:渲染层或运行时的 bug,Flutter 侧可读源码定位、必要时自改;uni-app x 侧只能提工单等厂商。
**下半(快过)**:提交数 91,171 / 11,216(8.1 倍),star 178,643 / 41,600(4.3 倍)。
两条口径要自己先说破:① star 反映全球开源关注度,**不等于国内商业落地量**,uni-app 在国内企业与政企项目落地量很大,数据体现不出来;② 但 Flutter 那 9 万次**含渲染引擎**,DCloud 那 1 万次是框架层的,Runtime 与 SDK 闭源无任何公开提交历史。
### 14 · 谁在主力 App 上用 Flutter — 1:30
证据分档:**甲 = 框架方官方收录,乙 = 使用方公开披露,丙 = 第三方扫包统计**。丙档只看趋势不下结论。
表中:字节 90+ 款、BMW、大众安徽、闲鱼、腾讯、美团商家端、京东、贝壳、携程。
落点在左下卡:**这些团队没有一个是把整个 App 用跨端框架重写的,全是原生工程为主体 + Flutter 承载业务页面 + 系统能力走原生** —— 和本项目规划完全一致,不是要自己趟的新形态。
右下丙档卡:新上架应用 Flutter 11.07% / RN 6.75%(2024 年 1–10 月,2022 年为 10.15% / 4.73%)。该口径扫不到 uni-app 系(主要落地在小程序和 H5,不经应用商店分发),不可比。
### 15 · 案例 A · BMW — 2:00
挑这类的原因:远程车控、实时车况回传、找车、充电桩地图全落到系统 API 和车联网长连接上,**是「原生能力密集」的极端形态**,还要在多品牌多市场维持同一套体验。
- 起点:iOS / Android 各一套 BMW Connected + MINI Connected,两端功能与设计逐渐分叉,2018 年大到必须收敛
- 选型时**为体验明确排除了基于浏览器的方案**
- 2019-10 慕尼黑定案 → 2020-07 My BMW App 上线,不到一年
- 覆盖 **47 个国家、五大洲**,双端合一,同时服务 BMW 与 MINI
**这页真正的落点是那个 96**:内部 Mobile 2.0 平台每天出多个构建,**每个构建自动生成、测试并部署 96 个变体**;到 2021-10 每个变体累计构建超 10,000 个版本 → 证明 Flutter 产物在 CI 里可批量、可自动化、可长期滚动,直接接第 20 页。
### 16 · 案例 B · 大众汽车(安徽)ID. UNYX — 1:30
购车定制 / 车联车控 / 社区 / 商城。
证据类型与 BMW 不同:**大众安徽官网《第三方个人信息共享清单》**列明 Flutter SDK、供应方 Google LLC,使用情形写作**「App 所有的 L1、L2、L3 页面开发语言」**(即全部主干界面)。合规披露是法定义务、内容须与实际一致,可信度高于任何技术文章转述。
同站另一份 SDK 说明另列有 React Native SDK → 混合形态,材料里主动注明了。这不削弱结论,反而印证第 14 页:**问题不是能不能只用一个框架写完,是主干页面交给谁。**
本章收口回答三个疑问:重原生能力是不是禁区(不是,车控密度更高)· 多变体长周期扛不扛得住(那个 96 是上限参考)· 是否必须整个重写(不是,两例都是混合底座)。
### 17 · 分隔 04 — 0:10 📍 ≈ 18:40
产品能力与工程链路。
### 18 · App 的形态不止「页面 + 接口」 — 1:20
迟早会碰到:桌面/锁屏小组件、系统语音助手、系统级进度通知、各类 App Extension(如门店当日待办、库存预警上桌面)。
表中两行:
- **改一次要重来多少** — Flutter 一次增量编译;uni-app x 按官方教程**每次修改这些文件后须重制自定义基座**
- **取资源 ID 的方式** — uni-app x 侧不能直接引用 `R` 类,须运行时按字符串查找,**编译期类型检查失效**
页脚原文:**两条路线都做得到,区别在做的方式**——Flutter 侧就是开 Xcode / Android Studio 写原生;uni-app x 侧同样写原生,还要额外走一遍 DCloud 的插件与打包规则。
来源等级:uni-app x 栏出自官方文档,仅安卓小组件那份清单取自 2026-05 社区实战教程(已标注)。
### 19 · 两项官方限制,同时满足不了 — 2:30
**全场最硬的单点。** 两条均出自 DCloud 官方文档:
- **情形 A** 要用插件市场加密付费插件 → 原文「uts 加密插件只支持云端传统打包,不支持离线打包,也不支持安心打包」→ **只能云端打包**
- **情形 B** 要做 Siri 快捷指令类扩展 → 官方路径是在**离线打包**的原生工程里实现 `AppShortcutsProvider`,再用 UTS 插件衔接 → **要求离线打包**
**两个要求互斥。** 同时需要时无解,只剩三个选择:放弃扩展能力 / 重新购买非加密授权(若厂商提供)/ 整体迁走。
下半澄清「离线打包 = 原生工程完全可控」这个误解:拿到的是 Android Studio 工程,但核心是 DCloud 已编译好的闭源 AAR(`lib.5plus.base-release.aar`、`uniapp-v8-release.aar`、`utsplugin-release.aar`),无源码。
**能改**:包名、版本号、图标、Gradle 依赖、权限清单,以及在壳外加自己的原生模块。**改不了**:页面怎么渲染、页面容器与生命周期、UTS 与原生的通信机制、运行时任何行为。
连壳本身也被规定死:**自定义 `Application` 必须继承 `DCloudApplication`**,默认 `MainActivity` 节点须移除 → 宿主工程入口不归你。**不是把 uni-app 集成进自己的 App,是在它的 App 里放自己的东西。**
右卡:Flutter 侧没有这个分支,只有一种构建方式,`ios/` `android/` 就是两个完整原生工程,加不加插件、上不上 Siri 都不影响出包方式。
> 若被问云端打包费用:每次 2 元、最高档几十元,相对项目总投入可忽略——**这页的问题不是钱,是构建方式被约束后的连锁限制。**
### 20 · 发版链路能不能全自动 — 1:10
已定链路:GitLab CI/CD(lint、格式化、测试卡点)· dev/uat/prod 三套环境 · iOS 由远程 Mac 出包 · 内测分发安卓走托管 OTA 页、iOS 走 TestFlight。核心诉求是**全自动、可追溯、可复现**——任一版本能从一次 git 提交自动构建,不依赖任何人本机环境。
关键第二行:uni-app x 的原生插件与 UTS 插件编译需经 HBuilderX,**图形化 IDE 无法在流水线中自动执行**——与全自动流水线是结构性错配。本项目原生插件是十几个,不是一两个。
页脚口径:**比的不是「能不能出包」(两者都能),是出包能否放进自动化流水线。** 对照第 15 页 BMW 的 96 变体 / 上万次构建。
### 21 · AI 编程工具 — 0:50
**两边都有官方 AI 工具**,uni-app x 有 `uni-agent`、`uni-app-x-mcp`。真实差别两条:
- **开放 vs 内置** — Flutter 的 skills 是独立开源仓库(`flutter/agent-plugins`、`dart-lang/skills`),一行命令装进任意 AI 编程工具,可 fork 可加自有 skill;uni-app x 的 AI 能力主要绑在官方助手和自家 IDE
- **公开语料** — Dart / Flutter 是近十年全球公开代码;UTS / UVue 是新语言,语料以中文官方文档为主,且**插件市场付费插件加密分发,不会进入任何公开语料**
### 22 · 分隔 05 — 0:10 📍 ≈ 24:40
结论。
### 23 · 首版投入构成 — 1:50
**先给结论:两条路线基本持平,±10% 以内。成本不是推荐 Flutter 的理由。**
| 构成 | 占比 | uni-app x |
| --- | --- | --- |
| 业务逻辑与外围系统集成、联调 | 45–55% | 无差异(与框架无关) |
| UI 实现 | 20–25% | **略省**(Vue 熟悉度) |
| 原生能力与桥接 | 10–15% | 明显更贵 |
| 工程、CI、发布、可观测 | 10–15% | 明显更贵 |
**它的效率优势作用在占比第二小的那块,额外成本作用在另外两块,一加一减基本持平。**
边界:占比区间基于本项目形态估算,不同团队有出入但量级关系稳定;不含后续运维迭代。
### 24 · uni-app x 强于 Flutter 的三项 — 1:30
**不要快讲。** 讲完对方优势是下一页结论可信的前提。
**① 鸿蒙** — uni-app x 官方直接支持,一等公民;Google 明确**不在 Flutter 主线支持鸿蒙**(issue #150536,Closed as not planned,不是「还没做」是「不打算做」)。
但:鸿蒙适配由 OpenHarmony-SIG 社区分支承接,**2026-01 成立 Flutter SIG 做治理**,按季度跟进主线,3.41 鸿蒙版已发布、**3.44 鸿蒙版预计 2026-09**,不是无人维护的野生 fork。而本项目基线正是 **3.44.9**,鸿蒙不在首版范围,停在 3.44.9 不追新本就是为接鸿蒙留窗口 → 本项目时间线内可控,**但若鸿蒙变硬需求,这项它确实更省事,应如实计入。**
**② 包体与内存更小** — DCloud 官方实测 8.5M vs 18M、103MB vs 138MB。**这两个数可信**——自绘引擎必须把渲染引擎打进包,是路线本身的代价。
**③ 热更新** — uni-app 系方案成熟,线上问题不等商店审核直接下发。
页脚原文:**这三项是真实的技术差异,是否构成决定性因素取决于产品对鸿蒙、包体和热更新的实际要求。**
时间够可补:鸿蒙首版不在范围、基线已留窗口 · 门店内部业务 App,企业分发/商店安装,**无包体 KPI**,35MB 内存差在现代机型无可感知影响 · 发版链路已定为 OTA 页 + TestFlight + App Store,**热更新这条优势在已定发版模式下用不上**,发版策略变了应重新计入。
### 25 · 推荐方案 — 1:20
标题原文:**技术栈采用 Flutter,原生工程为主体,业务页面由 Flutter 承载,系统能力走原生。**
—— 推荐的不是「整个 App 用 Flutter 重写」,是第 14 页那批团队验证了五六年的形态。
四行:**界面一致性**(自绘,不依赖系统控件与浏览器内核)· **系统能力**(原生工程完全开放,没有第二套规则要学)· **工程链路**(CLI 完整,可接 CI 无人值守,与已定 GitLab 流水线天然契合)· **先例充分**(BMW、大众安徽同类形态长期运行)。
基线 **Flutter 3.44.9**,首版 iOS + Android。
### 26 · 数据与事实来源 — 0:20
完整清单在书面材料附录 A,37 条。**除三处已就地标注的非官方来源外,其余全部来自厂商官方文档**,可自行复核。
### 27 · 收口 — 0:50
两句:**成本基本持平;真正差异在五年周期里能力天花板归谁**——Flutter 的天花板是自己的工程能力,uni-app x 的天花板是厂商的插件市场与打包体系。
若仍倾向 uni-app x,md 6.6 的六项前提(前四项任一落不实即应重新评估):
1. **F6 书面同意**在其页面引入 `uni.webview.js`,并承诺配合联调排期
2. **神策提供**与我方后端版本匹配的 uni-app x SDK,明确后续支持与升级责任
3. **Bugly 的 UTS 封装完成并验证**,含 iOS 侧崩溃符号化
4. **DCloud 明确 CLI / CI 可行路径**;若无,须接受构建链路存在人工用 HBuilderX 出包的环节并据此调整发布流程
5. 确认云端 / 离线打包取舍(是否用加密付费插件、是否有需离线打包的扩展需求,互斥时以哪个为准),并知悉离线工程仍是围着闭源二进制的壳
6. 接受首版拿不到多端复用收益——那六个小程序正被这个项目关掉
---
## 超时取舍(30 → 20 分钟)
按序砍。**▲ 不可砍:3 / 4 / 7 / 15 / 16 / 19 / 23 / 24 / 25。**
| 砍 | 省 |
| --- | --- |
| 26 页附录 | 0:20 |
| 21 页 AI | 0:50 |
| 8 页并进 7 页 | 1:10 |
| 10 页并进 11 页 | 1:10 |
| 14 页只念字节 / BMW / 大众安徽 | 0:45 |
| 6 页只讲第 ④ 行 | 0:40 |
| 13 页只讲开源层次图 | 0:40 |
| 20 页并进 19 页尾 | 1:10 |
砍满 ≈ 6:45 → 23:45;再并 18 页进 19 页 → 22:25。
---
## 数字速查
| 数 | 含义 |
| --- | --- |
| 91,171 / 11,216 | 主仓库提交数,**8.1 倍**;前者含渲染引擎,后者仅框架层 |
| 178,643 / 41,600 | star,4.3 倍 |
| 31,002 / 3,709 | fork |
| 18M / 8.5M | 安装包(DCloud 官方实测) |
| 138MB / 103MB | 运行内存(同上) |
| 8.7MB / 8.1MB | uni-app x 离线或嵌入的包体增量,iOS / Android arm64-v8a |
| 47 / 96 / 10,000 | BMW:国家数 / 每构建变体数 / 每变体累计构建版本 |
| 90+ / 800+ | 字节:线上 Flutter 应用数 / Flutter 开发者数 |
| 11.07% / 6.75% | 2024 年 1–10 月新上架应用 Flutter / RN(2022 年 10.15% / 4.73%),**丙档** |
| 1,350 / 1,184 | Top 10,000 非游戏 iOS 应用中 RN / Flutter 检出数(2025-12),**存量口径,RN 早三年开源** |
| 853 / 3,413 / 300 | Kuikly 仓库提交 / star / fork,建于 2025-04-24 |
| 45–55 / 20–25 / 10–15 / 10–15 | 成本四块占比 |
| ±10% | 首版总投入差异 |
| 3.44.9 | Flutter 版本基线 |
| 2 元 | uni-app x 云打包单次计费,60MB 以下不额外收费 |
---
## 问答速查
**限制会不会随版本解决** — 小的会(CLI、SDK 覆盖)。三条不会:Runtime 与原生 SDK 闭源是商业模式;多端复用在本项目没有买家是项目形态;能力天花板取决于厂商生态是路线 ③ 的结构。
**UTS 编译成 Kotlin/Swift,不是比 Dart 更接近原生** — 承认,方向正确,比传统「字符串方法名 + 弱类型参数」的桥接干净得多。保留意见在外面那层工具链和打包体系,不在语言。
**自绘在低端安卓机卡不卡** — 表单/列表/报表为主的业务 App,两边都够用。**性能在材料里标为非决定项,不作论据。**
**不用系统控件会不会不像原生** — Flutter 有 Material 与 Cupertino 两套。更重要的是本项目要的是「整个 App 看起来是一个东西」,不是「在苹果上像苹果」。
**为什么不选 RN** — 与 uni-app x 同属路线 ③,路线分析同样适用;选它最大理由是复用已有 React 人力,本项目无此前提。用 RN 的多是 2015–2018 就大规模投入的存量团队。
**Kuikly 更新更好** — 三条,均非「它不好」:① 对外开源仅一年多,853 提交 / 3,413 star,体系外生产案例、第三方组件、招聘、AI 语料都没起来;② License 非标准开源,加了「未经腾讯书面同意不得为增加或启用动态代码下发能力制作衍生作品」;③ 面向 Kotlin/KMP 团队,与我方人力结构不匹配。
**Flutter 会不会被 Google 砍** — 风险存在,不说「绝对不会」。区别在退路:BSD-3-Clause,引擎到框架全开源,社区可 fork 接手;uni-app x 的 Runtime 与原生 SDK 闭源,**没有第二个可接手的主体**。
**uni-app 几百万开发者,生态怎么会小** — 先认:国内企业应用、政企落地量很大,star 数体现不出来,材料已主动写明口径。比的是两件不同的事:可见工程投入(含引擎 vs 仅框架层),以及同等形态的落地先例。
**招人:Vue 遍地、Dart 没人** — Dart 对有 Java/Kotlin/TS 背景的人一两周进入正常产出;项目最大一块成本(45–55%)与框架无关;真正稀缺的是写原生桥接的人,换 uni-app x 一件不少还要多学 UTS 和 DCloud 插件规则;字节一家 800+ Flutter 开发者。
**以后又要小程序怎么办** — 承认这是 uni-app 系客观长处。但本项目方向相反,目标之一是关停六套小程序;真到那天 H5 或小程序端可单独做,不必反过来约束主力 App 底座。
**DCloud 官网那页对比 Flutter** — 已逐条核验,结论在附录 C。安装包 18M/8.5M **属实**;内存 138/103MB **属实**;「dart 与原生 API 通信损耗非常明显」未附实测数据与测试条件,定性表述;「原生渲染与自渲染并存问题很多」未附数据,但混排确是业界已知难点,提醒成立;「dart 生态」与公开数据相反,**但「嵌套写法」这条是真实体验问题,不辩解**,不影响能力上限;热更新属实。
**通信损耗对我们有影响吗** — 扫码/拍照/上传是用户触发的低频调用,不在渲染热路径;接口由 Pigeon 从一份定义生成三端强类型代码。真正吃紧的是嵌 F6 那条链路,而那恰是 uni-app x 更弱处。
**BMW 那 96 跟我们什么关系** — 我们要的是 dev/uat/prod 三套环境 + 多渠道包 + 每次提交自动出包。96 证明的是产物可完全无人值守、长期规模化地跑。对照 uni-app x 的云端打包与「改一次原生文件重制基座」。
**BMW 是大公司,跟我们不一样** — 不是比资源。它在原生密度、可靠性、变体数、周期四个维度都比本项目极端,那种条件下成立则本项目风险可控。另一个信号:选型时明确排除了浏览器方案。
**怎么确认 ID. UNYX 是 Flutter** — 只指大众安徽官网《第三方个人信息共享清单》那条链接(`www.id.unyx.com/subp-YH20240626002`),使用情形写「App 所有的 L1、L2、L3 页面开发语言」。**依据是使用方的法定披露,不是任何其他来源。**
**清单里还有 RN,算不算 Flutter 案例** — 是混合形态,材料主动注明了。大型 App 几乎都是混合的;问题是主干页面交给谁,那份披露写的是「所有 L1、L2、L3 页面」。
**字节省 1/3,选 Flutter 是不是也省 1/3** — 不能这么推。**原话对照组是「原生双端开发」,不是 uni-app。** 成本结论仍是基本持平。引它只说明:有能力自研全套基建的团队,做过 90+ 个 App 后仍继续投入 Flutter。deck 上没放这个数。
**携程为什么用 RN** — 存量投入,2015–2018 已大规模投 RN。现在是原生 + RN + Flutter 混合,Flutter 用在火车票、酒店等十多个核心业务的列表页与主流程,他们自己文章标题就是「Native/RN 内嵌 Flutter UI 混合开发实践」。
**uni-app x 有没有大厂案例** — **未检索到**大厂主力 App 上的公开落地案例。DCloud 公布的是 uni-app 全系开发者与应用总量,统计主体是小程序和 H5,无法拆出「用 uni-app x 做的独立 App」,口径不可比。
**包体大 10MB、内存多 35MB 有影响吗** — 数字属实且认,是路线代价。门店员工内部业务 App,企业分发/商店安装,**无包体 KPI**;设备是门店配发的作业终端。且 uni-app x 走离线/嵌入同样有增量(iOS 8.7MB、Android arm64-v8a 8.1MB)。
**鸿蒙** — 三层,见第 24 页。
**没有热更新,线上出 bug 怎么办** — 先认这是它的真优势。三点补充:苹果对「绕过商店下发可执行逻辑」长期处于灰色地带,规模化使用有下架风险敞口;本项目发版链路已定为 OTA 页 + TestFlight + App Store;企业安全与合规评审通常也不倾向接受可绕开商店下发代码的能力。**准确说法是这条优势客观存在,但在已定发版模式下用不上。**
**F6 到底要不要改** — Flutter 侧通道由 App 在页面加载完成时自动注入,单一双向通道,**F6 零改动**。uni-app x 侧按官方 `web-view` 文档,网页向 App 发消息**需引入 `uni.webview.1.5.5.js`**,App 向网页走 `evalJS()`(执行 JS 字符串),是两条不对称的单向通道 → **需要 F6 这家第三方改他们的页面**,是排期风险。不要说它做不出 JSBridge——做得出,但要在两条单向通道上自己封装请求 ID、超时、就绪信号、错误处理、方法白名单。
**CI 和那台远程 Mac 靠谱吗** — 现阶段先手工跑仓库内脚本,后续注册成带 `macos` tag 的 GitLab Runner 变成流水线节点。核心诉求是任一版本能从一次 git 提交自动构建、不依赖任何人本机环境——这也正是判断 HBuilderX 依赖的标准。
**神策和 Bugly 接得上吗** — 神策:Flutter 侧有官方插件,在公开包管理平台、有认证发布者与版本号;uni-app x 侧**不在插件市场**(官方说明因缺 UTS 压缩混淆方案暂未提供市场包),需联系技术顾问索取 zip 源码包,另有后端版本下限。Bugly:只有原生 SDK,Flutter 侧自建原生桥(几十行 Kotlin/Swift),uni-app x 侧未见官方支持,需完全自行用 UTS 封装。落点:两边都有工作量,但一边可版本化追溯,另一边脱离公开分发渠道,升级与责任归属只能靠人对人沟通。
**扫码/车牌/VIN/蓝牙有现成的吗** — 十几项原生能力(扫码、VIN、车牌、相机、相册多选、带进度上传、图片压缩、拨号、定位、运行时权限、弱网离线暂存、崩溃桥、埋点 SDK、安卓返回键拦截、WebView 文件选择器、iOS 隐私清单)**两条路线都要自己实现并两端验证**。Flutter 侧两个具体优势:Pigeon 从一份定义生成三端强类型代码,改接口忘同步实现编译期就报错;扫码一份原生实现同时服务 App 内扫码页与嵌入网页的通道调用。车牌 OCR 拍照上传走云端、**客户端不直连由后端代理**,VIN 在端上解。**蓝牙不在材料的能力清单里,被追问具体用途不要现编。**
**弱网怎么办** — 地下车库、仓库、施工区网络差,而恰是这些场景要传大文件(检测报告、装车视频、鉴定证据)。硬要求:上传前压缩、断网本地暂存恢复后幂等重传、上传带进度。两条路线都要自己实现,区别只在实现方式。
**AI 工具对哪个更友好** — 见第 21 页。**不能说 uni-app x 没有 AI 工具。**
**成本差多少** — 见第 23 页。**不暗示 Flutter 更便宜**,说完持平就引到五年天花板。
**哪个更快出第一版** — 差不多。瓶颈在外围系统集成(F6、后台、神策、Bugly、云端 OCR)与十几项原生能力的实现与两端验证,都与框架无关(原生那块 uni-app x 还更贵)。真要说风险,uni-app x 那条路上有一个我方控制不了的排期项:需 F6 配合改造页面。
**你们会 Flutter 吗** — 答能力与学习曲线,**不举己方具体项目名**。
**做到一半能不能换** — 退出成本不对称。Flutter 侧原生工程、原生能力、F6 通道都是标准原生实现,换掉的只是业务页面层,原生资产留得下。uni-app x 侧宿主入口归 DCloud(`Application` 须继承 `DCloudApplication`)、运行时闭源、插件是 UTS 写的,要换就是整体迁移、原生插件全部重写;且 uni-app x 不支持传统 uni-app 原生插件,自家体系内迁移也要重写。
**五年后谁维护** — 技术栈层:Flutter BSD 开源可自行 fork,uni-app x 无第二个可接手主体。工程层:Melos monorepo 21 个包,依赖规则由 Dart 包机制**在编译期物理强制**,业务模块 A 根本 import 不到 B 的符号,不靠规范约束——19 个业务模块多人长期并行,模块边界是最容易烂的地方。人力层:可招聘面与 AI 辅助成熟度。
**是不是被 Google 绑死** — 对 Flutter 诚实:确实依赖其路线决策,鸿蒙就是具体例子。但依赖性质不同:Flutter 代码在手、社区可接手;uni-app x 是三重绑定——Runtime 闭源不可改、插件工具链绑 HBuilderX、云打包在厂商服务器。另有商务侧:付费插件授权绑定唯一 appid 和包名,换其一需重新购买。
**开源协议有无法律风险** — BSD-3-Clause / Apache-2.0 均为宽松协议,不要求开源自身代码,商业使用无附加义务。对比:Kuikly 的 License 非标准开源,附加条款在合规评审时要单走流程。
**代码要上传第三方云编译吗** — Flutter 不需要,`flutter build` 命令行完整,构建全在自有构建机、产物可完整留档。uni-app x 的**云端打包由 DCloud 服务完成**,且加密付费插件只支持云端打包。对有正式安全评审流程的企业是需要走流程回答的问题。(陈述事实,不引申成「有安全风险」。)
**我们需要做什么** — 定 Flutter 则基线 3.44.9、首版双端,架构决策已就绪可直接排期;倾向 uni-app x 则先落实第 27 页那六项前提。
**你们是不是就想用自己熟的** — 熟悉度确实是因素,不回避。但材料写法是为了可被独立验证:每条负面判断都给了 DCloud 官方文档链接,事实与推论分行写。两点佐证非单边论证:主动列出 uni-app x 更优三项(第 24 页);把 DCloud 官网对比页逐条核验、属实的直接认下。且成本结论给的是「基本持平」不是「Flutter 更省钱」。
---
## 三条不进书面材料
只在被追问时口头用,进任何书面材料都会失去溯源。
1. **DCloud 问答区开发者原话**(「坑无敌多 / 暂时放弃 uvue 转 nvue」)—— 单条匿名发言,被追问「谁、什么项目、什么版本」答不上,会连累全文溯源可信度。
2. **插件数量对比**(DCloud 近千款 / 插件市场约 290 / pub.dev 76,378)—— 三个口径互不可比,会被当场拆掉。用提交数和开源层次说,不用插件数说。
3. **字节「省 1/3 工时」** —— 对照组是原生双端,不能用于成本论证;只能作社会证明。
@@ -389,8 +389,8 @@ table.tiny th,table.tiny td{padding:5.5px 11px;font-size:12.5px}
<tr><td class="k">原生能力开发</td><td class="col-f">强类型代码生成,支持命令行</td><td class="col-u">原生插件已停止新增上架</td><td class="col-u">只能经 HBuilderX,不支持命令行</td></tr>
<tr><td class="k">开源程度</td><td class="col-f mark">引擎 + 框架全开源(BSD)</td><td class="col-u">框架层开源(Apache-2.0)</td><td class="col-u">框架层开源,Runtime / SDK 闭源</td></tr>
<tr><td class="k">大型 App 案例</td><td class="col-f">字节 90+ 款、闲鱼、美团、京东、贝壳、携程、BMW、大众安徽 ID. UNYX</td><td class="col-u">—</td><td class="col-u">未检索到同等量级公开案例</td></tr>
<tr><td class="k">鸿蒙</td><td class="col-u">社区分支,3.41 已发布</td><td class="col-u">支持</td><td style="color:var(--tk-success);font-weight:700">一等公民 ✓</td></tr>
<tr><td class="k">安装包与内存</td><td class="col-u">约多 10 MB / 35 MB</td><td class="col-u">—</td><td style="color:var(--tk-success);font-weight:700">更小 ✓</td></tr>
<tr><td class="k">鸿蒙</td><td class="col-u">社区分支,3.41 已发布</td><td class="col-u">支持</td><td style="color:var(--tk-success);font-weight:700">一等公民(文档用词)</td></tr>
<tr><td class="k">安装包与内存</td><td class="col-u">约多 10 MB / 35 MB</td><td class="col-u">—</td><td style="color:var(--tk-success);font-weight:700">体积更小</td></tr>
<tr><td class="k">首版投入</td><td class="col-f">基准</td><td class="col-u">—</td><td class="col-u">差异在 ±10% 以内</td></tr>
</tbody>
</table>