learning_ai_common_plat/docs/ecosystem-after-refactor.drawio
saravanakumardb1 a874a4332b docs: add common platform analysis, ecosystem architecture, and drawio diagram
- COMMON_PLATFORM_ANALYSIS.md: identifies 8 shared packages to extract from LysnrAI and MindLyst repos (~1,580 LOC duplication eliminated)
- ECOSYSTEM_ARCHITECTURE.md: detailed post-refactor architecture with components, services, migration plan, advantages, cautions, versioning, testing, and CI/CD impact
- ecosystem-after-refactor.drawio: 4-layer architecture diagram (clients, repos, common platform, Azure infra)
2026-02-12 10:40:28 -08:00

479 lines
44 KiB
Plaintext

<mxfile host="app.diagrams.net" modified="2026-02-12T18:00:00.000Z" agent="Cascade" version="24.0.0" etag="common-plat-ecosystem" type="device">
<diagram id="main" name="Ecosystem After Refactor">
<mxGraphModel dx="3400" dy="2800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="4000" pageHeight="3200" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- TITLE -->
<!-- ═══════════════════════════════════════════════════════════ -->
<mxCell id="title" value="&lt;b&gt;ByteLyst Ecosystem — Post-Refactor Architecture&lt;/b&gt;&lt;br&gt;&lt;i&gt;3-Repo Monorepo Ecosystem with Shared Common Platform&lt;/i&gt;&lt;br&gt;v1.0 · Feb 2026" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;fontSize=22;fontFamily=Helvetica;" vertex="1" parent="1">
<mxGeometry x="900" y="-60" width="700" height="70" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- LEGEND -->
<!-- ═══════════════════════════════════════════════════════════ -->
<mxCell id="legend_box" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;dashed=1;opacity=80;" vertex="1" parent="1">
<mxGeometry x="1780" y="-60" width="360" height="200" as="geometry" />
</mxCell>
<mxCell id="legend_title" value="&lt;b&gt;LEGEND&lt;/b&gt;" style="text;html=1;align=left;fontSize=12;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1800" y="-50" width="80" height="20" as="geometry" />
</mxCell>
<mxCell id="leg1" value="" style="rounded=1;whiteSpace=wrap;fillColor=#FF6E6E;strokeColor=#b85450;opacity=40;" vertex="1" parent="1">
<mxGeometry x="1800" y="-20" width="18" height="18" as="geometry" />
</mxCell>
<mxCell id="leg1t" value="LysnrAI Repo (learning_voice_ai_agent)" style="text;html=1;align=left;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1826" y="-22" width="290" height="20" as="geometry" />
</mxCell>
<mxCell id="leg2" value="" style="rounded=1;whiteSpace=wrap;fillColor=#5A8CFF;strokeColor=#6c8ebf;opacity=40;" vertex="1" parent="1">
<mxGeometry x="1800" y="4" width="18" height="18" as="geometry" />
</mxCell>
<mxCell id="leg2t" value="MindLyst Repo (learning_multimodal_memory_agents)" style="text;html=1;align=left;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1826" y="2" width="310" height="20" as="geometry" />
</mxCell>
<mxCell id="leg3" value="" style="rounded=1;whiteSpace=wrap;fillColor=#34D399;strokeColor=#82b366;opacity=40;" vertex="1" parent="1">
<mxGeometry x="1800" y="28" width="18" height="18" as="geometry" />
</mxCell>
<mxCell id="leg3t" value="Common Platform (learning_ai_common_plat)" style="text;html=1;align=left;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1826" y="26" width="290" height="20" as="geometry" />
</mxCell>
<mxCell id="leg4" value="" style="rounded=1;whiteSpace=wrap;fillColor=#2EE6D6;strokeColor=#0097a7;opacity=40;" vertex="1" parent="1">
<mxGeometry x="1800" y="52" width="18" height="18" as="geometry" />
</mxCell>
<mxCell id="leg4t" value="Azure Cloud Infrastructure" style="text;html=1;align=left;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1826" y="50" width="200" height="20" as="geometry" />
</mxCell>
<mxCell id="leg5" value="" style="rounded=1;whiteSpace=wrap;fillColor=#FFD166;strokeColor=#d6b656;opacity=40;" vertex="1" parent="1">
<mxGeometry x="1800" y="76" width="18" height="18" as="geometry" />
</mxCell>
<mxCell id="leg5t" value="Client Applications (End User)" style="text;html=1;align=left;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1826" y="74" width="200" height="20" as="geometry" />
</mxCell>
<mxCell id="leg6_line" value="" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=2;dashed=1;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1800" y="110" as="sourcePoint" />
<mxPoint x="1860" y="110" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="leg6t" value="Depends on (npm/file: reference)" style="text;html=1;align=left;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1870" y="100" width="220" height="20" as="geometry" />
</mxCell>
<mxCell id="leg7_line" value="" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=2;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1800" y="132" as="sourcePoint" />
<mxPoint x="1860" y="132" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="leg7t" value="Network call (HTTP/REST)" style="text;html=1;align=left;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1870" y="122" width="200" height="20" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- LAYER 0: CLIENT APPLICATIONS (Top) -->
<!-- ═══════════════════════════════════════════════════════════ -->
<mxCell id="clients_group" value="&lt;b&gt;LAYER 0 — CLIENT APPLICATIONS&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFD166;strokeColor=#d6b656;opacity=15;verticalAlign=top;fontSize=13;fontStyle=1;align=left;spacingLeft=10;" vertex="1" parent="1">
<mxGeometry x="40" y="40" width="2400" height="160" as="geometry" />
</mxCell>
<!-- LysnrAI Clients -->
<mxCell id="client_desktop" value="&lt;b&gt;LysnrAI Desktop&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:10px'&gt;Python 3.12 + tkinter&lt;br&gt;macOS / Windows&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="60" y="80" width="160" height="60" as="geometry" />
</mxCell>
<mxCell id="client_lysnr_ios" value="&lt;b&gt;LysnrAI iOS&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:10px'&gt;Swift + SwiftUI&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="240" y="80" width="130" height="60" as="geometry" />
</mxCell>
<mxCell id="client_lysnr_android" value="&lt;b&gt;LysnrAI Android&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:10px'&gt;Kotlin + Compose&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="390" y="80" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="client_admin" value="&lt;b&gt;Admin Dashboard&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:10px'&gt;Next.js 16 :3001&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="550" y="80" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="client_user" value="&lt;b&gt;User Portal&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:10px'&gt;Next.js 16 :3002&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="710" y="80" width="130" height="60" as="geometry" />
</mxCell>
<mxCell id="client_tracker" value="&lt;b&gt;Tracker Dashboard&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:10px'&gt;Next.js :3003&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="860" y="80" width="140" height="60" as="geometry" />
</mxCell>
<!-- MindLyst Clients -->
<mxCell id="client_ml_ios" value="&lt;b&gt;MindLyst iOS&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:10px'&gt;SwiftUI + KMP&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="1680" y="80" width="130" height="60" as="geometry" />
</mxCell>
<mxCell id="client_ml_android" value="&lt;b&gt;MindLyst Android&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:10px'&gt;Compose + KMP&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="1830" y="80" width="140" height="60" as="geometry" />
</mxCell>
<mxCell id="client_ml_web" value="&lt;b&gt;MindLyst Web&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:10px'&gt;Next.js 14 :3050&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="1990" y="80" width="130" height="60" as="geometry" />
</mxCell>
<!-- Separator label -->
<mxCell id="sep_lysnr_clients" value="&lt;font color='#FF6E6E'&gt;&lt;b&gt;LysnrAI Clients&lt;/b&gt;&lt;/font&gt;" style="text;html=1;align=center;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="380" y="155" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="sep_ml_clients" value="&lt;font color='#5A8CFF'&gt;&lt;b&gt;MindLyst Clients&lt;/b&gt;&lt;/font&gt;" style="text;html=1;align=center;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1830" y="155" width="120" height="20" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- LAYER 1: LYSNRAI REPO — SERVICES (Left) -->
<!-- ═══════════════════════════════════════════════════════════ -->
<mxCell id="lysnr_repo" value="&lt;b&gt;LAYER 1 — learning_voice_ai_agent (LysnrAI)&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FF6E6E;strokeColor=#b85450;opacity=12;verticalAlign=top;fontSize=13;fontStyle=1;align=left;spacingLeft=10;" vertex="1" parent="1">
<mxGeometry x="40" y="240" width="960" height="620" as="geometry" />
</mxCell>
<!-- Python Backend -->
<mxCell id="python_backend" value="&lt;b&gt;FastAPI Backend&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Python 3.12 :8000&lt;br&gt;auth · config · cloud&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=11;" vertex="1" parent="1">
<mxGeometry x="60" y="280" width="180" height="65" as="geometry" />
</mxCell>
<!-- Fastify Services -->
<mxCell id="svc_group" value="&lt;b&gt;Fastify Microservices (TypeScript)&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#999999;dashed=1;verticalAlign=top;fontSize=11;fontStyle=1;align=left;spacingLeft=8;" vertex="1" parent="1">
<mxGeometry x="60" y="370" width="920" height="200" as="geometry" />
</mxCell>
<mxCell id="svc_platform" value="&lt;b&gt;platform-service&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;:4003&lt;br&gt;Auth · Audit · Flags&lt;br&gt;Notifications · Blob&lt;br&gt;Rate Limiting&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="80" y="410" width="150" height="90" as="geometry" />
</mxCell>
<mxCell id="svc_billing" value="&lt;b&gt;billing-service&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;:4002&lt;br&gt;Subscriptions · Plans&lt;br&gt;Usage · Licenses&lt;br&gt;Stripe Webhooks&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="250" y="410" width="150" height="90" as="geometry" />
</mxCell>
<mxCell id="svc_growth" value="&lt;b&gt;growth-service&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;:4001&lt;br&gt;Invitations&lt;br&gt;Referrals · Promos&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="420" y="410" width="140" height="90" as="geometry" />
</mxCell>
<mxCell id="svc_tracker" value="&lt;b&gt;tracker-service&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;:4004&lt;br&gt;Items · Comments&lt;br&gt;Votes · Public API&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="580" y="410" width="140" height="90" as="geometry" />
</mxCell>
<!-- Service internal lib — BEFORE (crossed out) -->
<mxCell id="svc_old_lib" value="&lt;font color='#999999'&gt;&lt;s&gt;src/lib/ (per-service duplicate)&lt;/s&gt;&lt;br&gt;&lt;s&gt;cosmos.ts · errors.ts · config.ts&lt;/s&gt;&lt;br&gt;&lt;s&gt;auth.ts · product-config.ts&lt;/s&gt;&lt;/font&gt;&lt;br&gt;&lt;font color='#34D399'&gt;&lt;b&gt;→ NOW: @bytelyst/* packages&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=none;fontSize=10;align=left;" vertex="1" parent="1">
<mxGeometry x="740" y="400" width="220" height="70" as="geometry" />
</mxCell>
<!-- Dashboards internal lib — BEFORE (crossed out) -->
<mxCell id="dash_group" value="&lt;b&gt;Next.js Dashboards (TypeScript)&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#999999;dashed=1;verticalAlign=top;fontSize=11;fontStyle=1;align=left;spacingLeft=8;" vertex="1" parent="1">
<mxGeometry x="60" y="595" width="920" height="120" as="geometry" />
</mxCell>
<mxCell id="dash_admin" value="&lt;b&gt;admin-dashboard-web&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;:3001 · Next.js 16&lt;br&gt;Users · Tokens · Audit&lt;br&gt;Usage · Invitations · Themes&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="80" y="630" width="180" height="70" as="geometry" />
</mxCell>
<mxCell id="dash_user" value="&lt;b&gt;user-dashboard-web&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;:3002 · Next.js 16&lt;br&gt;Profile · Billing&lt;br&gt;Settings · SSO&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="280" y="630" width="160" height="70" as="geometry" />
</mxCell>
<mxCell id="dash_tracker" value="&lt;b&gt;tracker-dashboard-web&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;:3003 · Next.js&lt;br&gt;Board · Roadmap&lt;br&gt;Public Voting&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="460" y="630" width="160" height="70" as="geometry" />
</mxCell>
<mxCell id="dash_old_lib" value="&lt;font color='#999999'&gt;&lt;s&gt;src/lib/ (per-dashboard duplicate)&lt;/s&gt;&lt;br&gt;&lt;s&gt;cosmos.ts · auth-server.ts · auth-context.tsx&lt;/s&gt;&lt;br&gt;&lt;s&gt;api.ts · utils.ts&lt;/s&gt;&lt;/font&gt;&lt;br&gt;&lt;font color='#34D399'&gt;&lt;b&gt;→ NOW: @bytelyst/* packages&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=none;fontSize=10;align=left;" vertex="1" parent="1">
<mxGeometry x="640" y="630" width="320" height="70" as="geometry" />
</mxCell>
<!-- Monitoring -->
<mxCell id="monitoring" value="&lt;b&gt;Monitoring&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Loki · Grafana&lt;br&gt;Health Checks&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="260" y="280" width="130" height="65" as="geometry" />
</mxCell>
<!-- Shared JSON -->
<mxCell id="lysnr_product_json" value="&lt;b&gt;shared/product.json&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Product Identity&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="410" y="280" width="140" height="45" as="geometry" />
</mxCell>
<!-- Desktop app -->
<mxCell id="desktop_app" value="&lt;b&gt;Desktop App&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Python 3.12 · tkinter&lt;br&gt;Audio · STT · LLM · Paste&lt;br&gt;Hotkey · Cloud Sync&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="570" y="270" width="180" height="80" as="geometry" />
</mxCell>
<!-- Mobile apps -->
<mxCell id="lysnr_mobile" value="&lt;b&gt;Mobile Apps&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;iOS (Swift) + Android (Kotlin)&lt;br&gt;Fully native (no KMP)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="770" y="280" width="180" height="60" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- LAYER 1: MINDLYST REPO (Right) -->
<!-- ═══════════════════════════════════════════════════════════ -->
<mxCell id="ml_repo" value="&lt;b&gt;LAYER 1 — learning_multimodal_memory_agents (MindLyst)&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#5A8CFF;strokeColor=#6c8ebf;opacity=12;verticalAlign=top;fontSize=13;fontStyle=1;align=left;spacingLeft=10;" vertex="1" parent="1">
<mxGeometry x="1560" y="240" width="580" height="620" as="geometry" />
</mxCell>
<!-- KMP Shared -->
<mxCell id="kmp_shared" value="&lt;b&gt;KMP Shared Module&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;commonMain/ (Kotlin)&lt;br&gt;Models · Repositories&lt;br&gt;DI · Triage Pipeline&lt;br&gt;OpenAI + Whisper Client&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1580" y="290" width="180" height="90" as="geometry" />
</mxCell>
<!-- MindLyst Design Tokens -->
<mxCell id="ml_tokens_old" value="&lt;font color='#999999'&gt;&lt;s&gt;MindLystTokens.kt&lt;/s&gt;&lt;br&gt;&lt;s&gt;MindLystTheme.swift&lt;/s&gt;&lt;br&gt;&lt;s&gt;globals.css&lt;/s&gt;&lt;/font&gt;&lt;br&gt;&lt;font color='#34D399'&gt;&lt;b&gt;→ NOW: @bytelyst/design-tokens&lt;/b&gt;&lt;/font&gt;" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;strokeColor=none;fontSize=10;align=left;" vertex="1" parent="1">
<mxGeometry x="1780" y="290" width="220" height="70" as="geometry" />
</mxCell>
<!-- MindLyst iOS -->
<mxCell id="ml_ios" value="&lt;b&gt;iOS App&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;SwiftUI&lt;br&gt;MindLystTheme.swift&lt;br&gt;HomeScreen · CaptureOrb&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1580" y="420" width="160" height="80" as="geometry" />
</mxCell>
<!-- MindLyst Android -->
<mxCell id="ml_android" value="&lt;b&gt;Android App&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Jetpack Compose&lt;br&gt;MindLystTheme.kt&lt;br&gt;HomeScreen · CaptureOrb&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1760" y="420" width="160" height="80" as="geometry" />
</mxCell>
<!-- MindLyst Web -->
<mxCell id="ml_web" value="&lt;b&gt;Web Dashboard&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Next.js 14 :3050&lt;br&gt;Pages Router · CSS vars&lt;br&gt;Landing · Dashboard&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1580" y="530" width="160" height="80" as="geometry" />
</mxCell>
<!-- MindLyst Design System -->
<mxCell id="ml_design_sys" value="&lt;b&gt;design-system/&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;tokens/ (JSON source)&lt;br&gt;web/ (mindlyst.css)&lt;br&gt;components/ (specs)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1760" y="530" width="160" height="80" as="geometry" />
</mxCell>
<!-- Future MindLyst services -->
<mxCell id="ml_future" value="&lt;font color='#999999'&gt;&lt;b&gt;Future: MindLyst Backend Services&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Will also use @bytelyst/cosmos,&lt;br&gt;@bytelyst/auth, @bytelyst/fastify-core&lt;/font&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#6c8ebf;dashed=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="1580" y="650" width="340" height="55" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- LAYER 2: COMMON PLATFORM (Center) -->
<!-- ═══════════════════════════════════════════════════════════ -->
<mxCell id="common_repo" value="&lt;b&gt;LAYER 2 — learning_ai_common_plat (@bytelyst/*)&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#34D399;strokeColor=#82b366;opacity=15;verticalAlign=top;fontSize=14;fontStyle=1;align=center;" vertex="1" parent="1">
<mxGeometry x="1040" y="240" width="480" height="620" as="geometry" />
</mxCell>
<!-- P0 packages -->
<mxCell id="p0_label" value="&lt;font color='#dc2626'&gt;&lt;b&gt;P0 — Drop-in (do first)&lt;/b&gt;&lt;/font&gt;" style="text;html=1;align=left;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1060" y="270" width="180" height="18" as="geometry" />
</mxCell>
<mxCell id="pkg_errors" value="&lt;b&gt;@bytelyst/errors&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;ServiceError base class&lt;br&gt;NotFound · BadRequest&lt;br&gt;Unauthorized · Forbidden&lt;br&gt;Conflict · TooManyRequests&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1060" y="295" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="pkg_cosmos" value="&lt;b&gt;@bytelyst/cosmos&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;CosmosClient singleton&lt;br&gt;getContainer(name)&lt;br&gt;Container registry + TTL&lt;br&gt;initializeAllContainers()&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1280" y="295" width="200" height="80" as="geometry" />
</mxCell>
<!-- P1 packages -->
<mxCell id="p1_label" value="&lt;font color='#ea580c'&gt;&lt;b&gt;P1 — High impact&lt;/b&gt;&lt;/font&gt;" style="text;html=1;align=left;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1060" y="390" width="180" height="18" as="geometry" />
</mxCell>
<mxCell id="pkg_config" value="&lt;b&gt;@bytelyst/config&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Zod base env schema&lt;br&gt;(PORT, HOST, NODE_ENV,&lt;br&gt;COSMOS_*, SERVICE_NAME)&lt;br&gt;Product identity loader&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1060" y="415" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="pkg_auth" value="&lt;b&gt;@bytelyst/auth&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;JWT create/verify (jose)&lt;br&gt;Fastify extractAuth hook&lt;br&gt;Next.js getCurrentUser&lt;br&gt;bcrypt password hashing&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1280" y="415" width="200" height="80" as="geometry" />
</mxCell>
<mxCell id="pkg_fastify" value="&lt;b&gt;@bytelyst/fastify-core&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;createServiceApp() factory&lt;br&gt;CORS · Swagger · Metrics&lt;br&gt;x-request-id hook&lt;br&gt;/health · Error handler&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1060" y="510" width="200" height="80" as="geometry" />
</mxCell>
<!-- P2 packages -->
<mxCell id="p2_label" value="&lt;font color='#ca8a04'&gt;&lt;b&gt;P2 — Medium impact&lt;/b&gt;&lt;/font&gt;" style="text;html=1;align=left;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1280" y="510" width="180" height="18" as="geometry" />
</mxCell>
<mxCell id="pkg_api_client" value="&lt;b&gt;@bytelyst/api-client&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;createApiClient() factory&lt;br&gt;Typed fetch + auth headers&lt;br&gt;{ data, error } or throw&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1280" y="535" width="200" height="70" as="geometry" />
</mxCell>
<mxCell id="pkg_react_auth" value="&lt;b&gt;@bytelyst/react-auth&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;AuthProvider&amp;lt;TUser&amp;gt;&lt;br&gt;useAuth() hook&lt;br&gt;localStorage token mgmt&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1060" y="610" width="200" height="70" as="geometry" />
</mxCell>
<!-- P3 package -->
<mxCell id="p3_label" value="&lt;font color='#4f46e5'&gt;&lt;b&gt;P3 — Cross-platform&lt;/b&gt;&lt;/font&gt;" style="text;html=1;align=left;fontSize=10;fontStyle=1;" vertex="1" parent="1">
<mxGeometry x="1280" y="620" width="180" height="18" as="geometry" />
</mxCell>
<mxCell id="pkg_tokens" value="&lt;b&gt;@bytelyst/design-tokens&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Canonical JSON source&lt;br&gt;→ CSS vars (--ml-*)&lt;br&gt;→ TypeScript constants&lt;br&gt;→ Kotlin object&lt;br&gt;→ Swift structs&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1280" y="645" width="200" height="85" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- LAYER 3: AZURE INFRASTRUCTURE (Bottom) -->
<!-- ═══════════════════════════════════════════════════════════ -->
<mxCell id="azure_layer" value="&lt;b&gt;LAYER 3 — Azure Cloud Infrastructure&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#2EE6D6;strokeColor=#0097a7;opacity=12;verticalAlign=top;fontSize=13;fontStyle=1;align=center;" vertex="1" parent="1">
<mxGeometry x="40" y="920" width="2100" height="180" as="geometry" />
</mxCell>
<mxCell id="az_cosmos" value="&lt;b&gt;Azure Cosmos DB&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;cosmos-mywisprai&lt;br&gt;Serverless · NoSQL&lt;br&gt;DB: lysnrai&lt;br&gt;13+ containers&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f7fa;strokeColor=#0097a7;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="80" y="960" width="170" height="90" as="geometry" />
</mxCell>
<mxCell id="az_blob" value="&lt;b&gt;Azure Blob Storage&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;bytelystblobs&lt;br&gt;6 containers: audio,&lt;br&gt;transcripts, attachments,&lt;br&gt;avatars, releases, backups&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f7fa;strokeColor=#0097a7;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="280" y="960" width="180" height="90" as="geometry" />
</mxCell>
<mxCell id="az_keyvault" value="&lt;b&gt;Azure Key Vault&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;kv-mywisprai&lt;br&gt;Secrets management&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f7fa;strokeColor=#0097a7;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="490" y="960" width="150" height="70" as="geometry" />
</mxCell>
<mxCell id="az_speech" value="&lt;b&gt;Azure Speech&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;mywisprai-speech&lt;br&gt;STT (F0 tier)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f7fa;strokeColor=#0097a7;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="670" y="960" width="140" height="70" as="geometry" />
</mxCell>
<mxCell id="az_openai" value="&lt;b&gt;Azure OpenAI&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;mywisprai-openai-sweden&lt;br&gt;swedencentral · S0&lt;br&gt;gpt-4o-mini&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f7fa;strokeColor=#0097a7;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="840" y="960" width="170" height="80" as="geometry" />
</mxCell>
<mxCell id="az_stripe" value="&lt;b&gt;Stripe&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Payments · Webhooks&lt;br&gt;Subscriptions&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f7fa;strokeColor=#0097a7;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1040" y="960" width="140" height="70" as="geometry" />
</mxCell>
<mxCell id="az_openai_public" value="&lt;b&gt;OpenAI API&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;api.openai.com&lt;br&gt;gpt-4o-mini · Whisper&lt;br&gt;(MindLyst triage)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f7fa;strokeColor=#0097a7;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1210" y="960" width="150" height="80" as="geometry" />
</mxCell>
<mxCell id="az_docker" value="&lt;b&gt;Docker Compose&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;Traefik · Loki · Grafana&lt;br&gt;All services&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f7fa;strokeColor=#0097a7;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1390" y="960" width="150" height="70" as="geometry" />
</mxCell>
<mxCell id="az_gh_actions" value="&lt;b&gt;GitHub Actions&lt;/b&gt;&lt;br&gt;&lt;font style='font-size:9px'&gt;CI pipelines&lt;br&gt;9 workflows (LysnrAI)&lt;br&gt;1 workflow (MindLyst)&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0f7fa;strokeColor=#0097a7;fontSize=10;shadow=1;" vertex="1" parent="1">
<mxGeometry x="1570" y="960" width="160" height="80" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- DEPENDENCY ARROWS: Services → Common Platform -->
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- Platform service → errors -->
<mxCell id="arr_plat_err" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=2;dashed=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="svc_platform" target="pkg_errors">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Billing service → errors -->
<mxCell id="arr_bill_err" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=1.5;dashed=1;exitX=1;exitY=0.3;exitDx=0;exitDy=0;entryX=0;entryY=0.7;entryDx=0;entryDy=0;" edge="1" parent="1" source="svc_billing" target="pkg_errors">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Growth service → fastify-core -->
<mxCell id="arr_grow_fc" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=1.5;dashed=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.3;entryDx=0;entryDy=0;" edge="1" parent="1" source="svc_growth" target="pkg_fastify">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Tracker service → auth -->
<mxCell id="arr_trk_auth" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=1.5;dashed=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="svc_tracker" target="pkg_auth">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Admin dashboard → cosmos -->
<mxCell id="arr_admin_cos" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=1.5;dashed=1;exitX=1;exitY=0.3;exitDx=0;exitDy=0;entryX=0;entryY=0.9;entryDx=0;entryDy=0;" edge="1" parent="1" source="dash_admin" target="pkg_cosmos">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- User dashboard → react-auth -->
<mxCell id="arr_user_ra" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=1.5;dashed=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="dash_user" target="pkg_react_auth">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Tracker dashboard → api-client -->
<mxCell id="arr_trkd_api" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=1.5;dashed=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="dash_tracker" target="pkg_api_client">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- DEPENDENCY ARROWS: MindLyst → Common Platform -->
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- MindLyst web → design-tokens -->
<mxCell id="arr_mlweb_tok" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=2;dashed=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="ml_web" target="pkg_tokens">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- MindLyst design-system → design-tokens -->
<mxCell id="arr_mlds_tok" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=1.5;dashed=1;exitX=0;exitY=0.7;exitDx=0;exitDy=0;entryX=1;entryY=0.8;entryDx=0;entryDy=0;" edge="1" parent="1" source="ml_design_sys" target="pkg_tokens">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- MindLyst future services → fastify-core -->
<mxCell id="arr_mlfut_fc" style="endArrow=classic;html=1;strokeColor=#34D399;strokeWidth=1.5;dashed=1;dashPattern=8 4;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.7;entryDx=0;entryDy=0;" edge="1" parent="1" source="ml_future" target="pkg_fastify">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- NETWORK ARROWS: Services → Azure -->
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- Services → Cosmos -->
<mxCell id="arr_svc_cosmos" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=1.5;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="svc_group" target="az_cosmos">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Desktop → Azure Speech -->
<mxCell id="arr_desk_speech" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="desktop_app" target="az_speech">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Dashboards → Cosmos -->
<mxCell id="arr_dash_cosmos" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=1.5;exitX=0.3;exitY=1;exitDx=0;exitDy=0;entryX=0.7;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="dash_group" target="az_cosmos">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Billing → Stripe -->
<mxCell id="arr_bill_stripe" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="svc_billing" target="az_stripe">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- KMP → OpenAI public -->
<mxCell id="arr_kmp_openai" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="kmp_shared" target="az_openai_public">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- CLIENT → SERVICE ARROWS -->
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- Desktop client → Desktop app -->
<mxCell id="arr_c_desk" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.3;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="client_desktop" target="desktop_app">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Admin client → admin dashboard -->
<mxCell id="arr_c_admin" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="client_admin" target="dash_admin">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- User client → user dashboard -->
<mxCell id="arr_c_user" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="client_user" target="dash_user">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- MindLyst clients → KMP -->
<mxCell id="arr_c_ml_ios" style="endArrow=classic;html=1;strokeColor=#666666;strokeWidth=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.3;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="client_ml_ios" target="kmp_shared">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- INTRA-PACKAGE DEPENDENCY ARROWS (within common plat) -->
<!-- ═══════════════════════════════════════════════════════════ -->
<!-- fastify-core → errors -->
<mxCell id="arr_fc_err" style="endArrow=classic;html=1;strokeColor=#22c55e;strokeWidth=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="pkg_fastify" target="pkg_errors">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- fastify-core → config -->
<mxCell id="arr_fc_cfg" style="endArrow=classic;html=1;strokeColor=#22c55e;strokeWidth=1;exitX=0.3;exitY=0;exitDx=0;exitDy=0;entryX=0.3;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="pkg_fastify" target="pkg_config">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- auth → config -->
<mxCell id="arr_auth_cfg" style="endArrow=classic;html=1;strokeColor=#22c55e;strokeWidth=1;exitX=0.3;exitY=0;exitDx=0;exitDy=0;entryX=0.7;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="pkg_auth" target="pkg_config">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- api-client → auth -->
<mxCell id="arr_apic_auth" style="endArrow=classic;html=1;strokeColor=#22c55e;strokeWidth=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="pkg_api_client" target="pkg_auth">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- react-auth → api-client -->
<mxCell id="arr_ra_apic" style="endArrow=classic;html=1;strokeColor=#22c55e;strokeWidth=1;exitX=1;exitY=0.3;exitDx=0;exitDy=0;entryX=0;entryY=0.7;entryDx=0;entryDy=0;" edge="1" parent="1" source="pkg_react_auth" target="pkg_api_client">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>