Files
obsidian/TallyFlow/TallyFlow-Architecture-Diagram.html
T
TNB 4497fabf22 Refine TallyFlow architecture to exactly 5 components
- MongoDB nested inside Core (no longer 6th component)
- IoT → Core connection is dashed (optional)
- Print includes Print UI + Print API note
- Capture shown as native app (not Go/Vue)
- Core Web UI and Print UI as differentiated sub-boxes
- Strict focus on the 5 components: Core, Assets, Print, Capture, IoT
2026-07-07 09:22:29 -04:00

247 lines
12 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TallyFlow Architecture Diagram</title>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'JetBrains Mono', monospace;
background: #020617;
min-height: 100vh;
padding: 2rem;
color: white;
}
.container { max-width: 1200px; margin: 0 auto; }
.header { margin-bottom: 2rem; }
.header-row { display: flex; align-items: center; gap: 1rem; margin-bottom: 0.5rem; }
.pulse-dot {
width: 12px; height: 12px; background: #22d3ee;
border-radius: 50%; animation: pulse 2s infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
h1 { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.025em; }
.subtitle { color: #94a3b8; font-size: 0.875rem; margin-left: 1.75rem; }
.diagram-container {
background: rgba(15, 23, 42, 0.5);
border-radius: 1rem; border: 1px solid #1e293b;
padding: 1.5rem; overflow-x: auto;
}
svg { width: 100%; min-width: 980px; display: block; }
.cards {
display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 1rem; margin-top: 2rem;
}
.card {
background: rgba(15, 23, 42, 0.5);
border-radius: 0.75rem; border: 1px solid #1e293b;
padding: 1.25rem;
}
.card-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; }
.card-dot { width: 8px; height: 8px; border-radius: 50%; }
.card-dot.cyan { background: #22d3ee; }
.card-dot.emerald { background: #34d399; }
.card-dot.violet { background: #a78bfa; }
.card-dot.amber { background: #fbbf24; }
.card-dot.orange { background: #fb923c; }
.card h3 { font-size: 0.875rem; font-weight: 600; }
.card ul { list-style: none; color: #94a3b8; font-size: 0.75rem; }
.card li { margin-bottom: 0.375rem; }
.footer { text-align: center; margin-top: 1.5rem; color: #475569; font-size: 0.75rem; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<div class="header-row">
<div class="pulse-dot"></div>
<h1>TallyFlow Architecture</h1>
</div>
<p class="subtitle">5 Core Components • Source-verified from ~/src</p>
</div>
<div class="diagram-container">
<svg viewBox="0 0 1000 620">
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#64748b" />
</marker>
<marker id="arrowhead-dashed" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#fb923c" />
</marker>
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1e293b" stroke-width="0.5"/>
</pattern>
</defs>
<!-- Background Grid -->
<rect width="100%" height="100%" fill="url(#grid)" />
<!-- ========== CORE (Central, owns DB) ========== -->
<rect x="200" y="60" width="600" height="280" rx="14" fill="rgba(6, 78, 59, 0.1)" stroke="#34d399" stroke-width="2.5"/>
<text x="220" y="85" fill="#34d399" font-size="13" font-weight="700">TallyFlow Core (Central Hub)</text>
<!-- Core Backend (Go) -->
<rect x="230" y="105" width="200" height="70" rx="8" fill="rgba(6, 78, 59, 0.55)" stroke="#34d399" stroke-width="2"/>
<text x="330" y="132" fill="white" font-size="13" font-weight="700" text-anchor="middle">Core Backend</text>
<text x="330" y="150" fill="#94a3b8" font-size="10" text-anchor="middle">Go (Echo / gRPC)</text>
<text x="330" y="166" fill="#34d399" font-size="9" text-anchor="middle">REST + WebSocket API</text>
<!-- Core Web UI (Vue.js) - sub-box -->
<rect x="460" y="105" width="200" height="70" rx="8" fill="rgba(8, 51, 68, 0.55)" stroke="#22d3ee" stroke-width="2"/>
<text x="560" y="132" fill="white" font-size="13" font-weight="700" text-anchor="middle">Core Web UI</text>
<text x="560" y="150" fill="#94a3b8" font-size="10" text-anchor="middle">Vue.js 2</text>
<text x="560" y="166" fill="#22d3ee" font-size="9" text-anchor="middle">Asset mgmt, reporting, config</text>
<!-- MongoDB (nested inside Core) -->
<rect x="680" y="105" width="100" height="70" rx="6" fill="rgba(76, 29, 149, 0.6)" stroke="#a78bfa" stroke-width="1.5"/>
<text x="730" y="132" fill="white" font-size="11" font-weight="700" text-anchor="middle">MongoDB</text>
<text x="730" y="150" fill="#c4b5fd" font-size="8" text-anchor="middle">Assets • Tags</text>
<text x="730" y="164" fill="#c4b5fd" font-size="8" text-anchor="middle">Photos • Zones</text>
<!-- Core API label -->
<text x="500" y="200" fill="#34d399" font-size="9" text-anchor="middle" font-weight="600">Core API Layer (single integration point for all 5 components)</text>
<!-- ========== ASSETS (Mobile) ========== -->
<rect x="60" y="380" width="170" height="100" rx="10" fill="rgba(8, 51, 68, 0.5)" stroke="#22d3ee" stroke-width="2"/>
<text x="145" y="408" fill="white" font-size="13" font-weight="700" text-anchor="middle">Assets</text>
<text x="145" y="426" fill="#94a3b8" font-size="10" text-anchor="middle">(Mobile)</text>
<text x="145" y="444" fill="#22d3ee" font-size="9" text-anchor="middle">Flutter</text>
<text x="145" y="460" fill="#94a3b8" font-size="8" text-anchor="middle">Seek &amp; Find • Inventory • Enrollment</text>
<!-- ========== PRINT ========== -->
<rect x="280" y="380" width="170" height="100" rx="10" fill="rgba(120, 53, 15, 0.45)" stroke="#fbbf24" stroke-width="2"/>
<text x="365" y="408" fill="white" font-size="13" font-weight="700" text-anchor="middle">Print</text>
<text x="365" y="426" fill="#94a3b8" font-size="10" text-anchor="middle">Flutter + Rust</text>
<text x="365" y="444" fill="#fbbf24" font-size="9" text-anchor="middle">Zebra ZPL • RFID</text>
<text x="365" y="460" fill="#94a3b8" font-size="8" text-anchor="middle">Print UI + Print API</text>
<!-- ========== CAPTURE (native) ========== -->
<rect x="500" y="380" width="170" height="100" rx="10" fill="rgba(136, 19, 55, 0.45)" stroke="#fb7185" stroke-width="2"/>
<text x="585" y="408" fill="white" font-size="13" font-weight="700" text-anchor="middle">Capture</text>
<text x="585" y="426" fill="#94a3b8" font-size="10" text-anchor="middle">(PhotoTag)</text>
<text x="585" y="444" fill="#fb7185" font-size="9" text-anchor="middle">Native App</text>
<text x="585" y="460" fill="#94a3b8" font-size="8" text-anchor="middle">Photo + Barcode QC</text>
<!-- ========== IoT ========== -->
<rect x="720" y="380" width="170" height="100" rx="10" fill="rgba(251, 146, 60, 0.4)" stroke="#fb923c" stroke-width="2"/>
<text x="805" y="408" fill="white" font-size="13" font-weight="700" text-anchor="middle">IoT</text>
<text x="805" y="426" fill="#94a3b8" font-size="10" text-anchor="middle">Rust</text>
<text x="805" y="444" fill="#fb923c" font-size="9" text-anchor="middle">Fixed Readers • Sensors</text>
<text x="805" y="460" fill="#94a3b8" font-size="8" text-anchor="middle">MQTT / HTTP / BLE</text>
<!-- ========== CONNECTIONS ========== -->
<!-- Assets → Core (solid) -->
<line x1="232" y1="420" x2="280" y2="340" stroke="#22d3ee" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="240" y="375" fill="#22d3ee" font-size="9" font-weight="600">API Sync</text>
<!-- Print → Core (solid) -->
<line x1="365" y1="378" x2="365" y2="340" stroke="#fbbf24" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="380" y="362" fill="#fbbf24" font-size="9">Print Jobs / Config</text>
<!-- Capture → Core (solid) -->
<line x1="585" y1="378" x2="585" y2="340" stroke="#fb7185" stroke-width="2" marker-end="url(#arrowhead)"/>
<text x="600" y="362" fill="#fb7185" font-size="9">Photos + Metadata</text>
<!-- IoT → Core (dashed, optional) -->
<line x1="805" y1="378" x2="805" y2="340" stroke="#fb923c" stroke-width="2" stroke-dasharray="5,4" marker-end="url(#arrowhead-dashed)"/>
<text x="820" y="362" fill="#fb923c" font-size="9">Events (optional)</text>
<!-- Core Backend owns MongoDB (short solid line) -->
<line x1="432" y1="140" x2="678" y2="140" stroke="#a78bfa" stroke-width="2" marker-end="url(#arrowhead)"/>
<!-- Legend -->
<text x="60" y="530" fill="white" font-size="10" font-weight="700">Legend</text>
<rect x="60" y="542" width="18" height="11" rx="2" fill="rgba(6, 78, 59, 0.55)" stroke="#34d399" stroke-width="1"/>
<text x="85" y="551" fill="#94a3b8" font-size="8">Core (Go + Vue.js + MongoDB)</text>
<rect x="260" y="542" width="18" height="11" rx="2" fill="rgba(8, 51, 68, 0.5)" stroke="#22d3ee" stroke-width="1"/>
<text x="285" y="551" fill="#94a3b8" font-size="8">Assets (Flutter)</text>
<rect x="385" y="542" width="18" height="11" rx="2" fill="rgba(120, 53, 15, 0.45)" stroke="#fbbf24" stroke-width="1"/>
<text x="410" y="551" fill="#94a3b8" font-size="8">Print (Flutter/Rust + UI)</text>
<rect x="530" y="542" width="18" height="11" rx="2" fill="rgba(136, 19, 55, 0.45)" stroke="#fb7185" stroke-width="1"/>
<text x="555" y="551" fill="#94a3b8" font-size="8">Capture (Native)</text>
<rect x="660" y="542" width="18" height="11" rx="2" fill="rgba(251, 146, 60, 0.4)" stroke="#fb923c" stroke-width="1"/>
<text x="685" y="551" fill="#94a3b8" font-size="8">IoT (Rust)</text>
<line x1="800" y1="547" x2="818" y2="547" stroke="#fb923c" stroke-width="1.5" stroke-dasharray="4,3" marker-end="url(#arrowhead-dashed)"/>
<text x="825" y="551" fill="#94a3b8" font-size="8">Optional flow</text>
</svg>
</div>
<div class="cards">
<div class="card">
<div class="card-header">
<div class="card-dot emerald"></div>
<h3>Core (Central)</h3>
</div>
<ul>
<li>• Go backend + Vue.js Web UI</li>
<li>• Owns MongoDB (assets, tags, photos, zones)</li>
<li>• Single API integration point</li>
<li>• Configuration &amp; reporting hub</li>
</ul>
</div>
<div class="card">
<div class="card-header">
<div class="card-dot cyan"></div>
<h3>Assets (Mobile)</h3>
</div>
<ul>
<li>• Flutter native mobile app</li>
<li>• Seek &amp; find, lightweight inventory</li>
<li>• Enrollment &amp; zone management</li>
<li>• Syncs with Core API</li>
</ul>
</div>
<div class="card">
<div class="card-header">
<div class="card-dot amber"></div>
<h3>Print</h3>
</div>
<ul>
<li>• Flutter + Rust</li>
<li>• Zebra ZPL + RFID encoding</li>
<li>• Print UI for configuration</li>
<li>• Or direct Print API usage</li>
</ul>
</div>
<div class="card">
<div class="card-header">
<div class="card-dot rose"></div>
<h3>Capture</h3>
</div>
<ul>
<li>• Native mobile app (PhotoTag)</li>
<li>• Photo + barcode association</li>
<li>• QC &amp; visual documentation</li>
<li>• Feeds Core via API</li>
</ul>
</div>
<div class="card">
<div class="card-header">
<div class="card-dot orange"></div>
<h3>IoT</h3>
</div>
<ul>
<li>• Rust service</li>
<li>• Fixed readers (Impinj/Zebra)</li>
<li>• Sensors (location, temp, shock)</li>
<li>• Optional dashed flow to Core</li>
</ul>
</div>
</div>
<p class="footer">
TallyFlow • 5 components only • MongoDB nested inside Core • Verified from source • 2026
</p>
</div>
</body>
</html>