CASTAD-v0.1/docs/images/architecture-distributed.svg

168 lines
10 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 800" font-family="Arial, sans-serif">
<defs>
<linearGradient id="lbGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#667eea;stop-opacity:1" />
<stop offset="100%" style="stop-color:#764ba2;stop-opacity:1" />
</linearGradient>
<linearGradient id="apiGradD" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#11998e;stop-opacity:1" />
<stop offset="100%" style="stop-color:#38ef7d;stop-opacity:1" />
</linearGradient>
<linearGradient id="redisGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#dc2626;stop-opacity:1" />
<stop offset="100%" style="stop-color:#ef4444;stop-opacity:1" />
</linearGradient>
<linearGradient id="pgGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#336791;stop-opacity:1" />
<stop offset="100%" style="stop-color:#4a90c2;stop-opacity:1" />
</linearGradient>
<linearGradient id="s3Grad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#ff9900;stop-opacity:1" />
<stop offset="100%" style="stop-color:#ffb84d;stop-opacity:1" />
</linearGradient>
<linearGradient id="workerGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#8b5cf6;stop-opacity:1" />
<stop offset="100%" style="stop-color:#a78bfa;stop-opacity:1" />
</linearGradient>
<linearGradient id="uploadGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#ec4899;stop-opacity:1" />
<stop offset="100%" style="stop-color:#f472b6;stop-opacity:1" />
</linearGradient>
<filter id="shadowD" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="2" dy="2" stdDeviation="3" flood-opacity="0.3"/>
</filter>
<marker id="arrowD" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#666"/>
</marker>
</defs>
<!-- Title -->
<text x="450" y="30" text-anchor="middle" font-size="20" font-weight="bold" fill="#333">
CaStAD Distributed Architecture (Scale-Out)
</text>
<!-- Load Balancer -->
<rect x="325" y="50" width="250" height="60" rx="10" fill="url(#lbGrad)" filter="url(#shadowD)"/>
<text x="450" y="78" text-anchor="middle" font-size="14" font-weight="bold" fill="white">Load Balancer</text>
<text x="450" y="98" text-anchor="middle" font-size="11" fill="white">nginx / AWS ALB</text>
<!-- Arrows to API Servers -->
<path d="M 350 110 L 175 145" stroke="#666" stroke-width="2" marker-end="url(#arrowD)"/>
<path d="M 450 110 L 450 145" stroke="#666" stroke-width="2" marker-end="url(#arrowD)"/>
<path d="M 550 110 L 725 145" stroke="#666" stroke-width="2" marker-end="url(#arrowD)"/>
<!-- API Servers -->
<rect x="75" y="145" width="200" height="70" rx="10" fill="url(#apiGradD)" filter="url(#shadowD)"/>
<text x="175" y="175" text-anchor="middle" font-size="13" font-weight="bold" fill="white">API Server 1</text>
<text x="175" y="195" text-anchor="middle" font-size="11" fill="white">Express.js</text>
<rect x="350" y="145" width="200" height="70" rx="10" fill="url(#apiGradD)" filter="url(#shadowD)"/>
<text x="450" y="175" text-anchor="middle" font-size="13" font-weight="bold" fill="white">API Server 2</text>
<text x="450" y="195" text-anchor="middle" font-size="11" fill="white">Express.js</text>
<rect x="625" y="145" width="200" height="70" rx="10" fill="url(#apiGradD)" filter="url(#shadowD)"/>
<text x="725" y="175" text-anchor="middle" font-size="13" font-weight="bold" fill="white">API Server N</text>
<text x="725" y="195" text-anchor="middle" font-size="11" fill="white">Express.js</text>
<!-- Vertical line connecting API servers -->
<path d="M 175 215 L 175 250 L 725 250 L 725 215" stroke="#666" stroke-width="1.5" fill="none"/>
<path d="M 450 215 L 450 250" stroke="#666" stroke-width="1.5"/>
<path d="M 450 250 L 450 285" stroke="#666" stroke-width="2" marker-end="url(#arrowD)"/>
<!-- Data Layer -->
<!-- Redis -->
<rect x="50" y="300" width="220" height="120" rx="10" fill="url(#redisGrad)" filter="url(#shadowD)"/>
<text x="160" y="330" text-anchor="middle" font-size="14" font-weight="bold" fill="white">Redis</text>
<text x="160" y="350" text-anchor="middle" font-size="11" fill="white">(Cache / Queue)</text>
<text x="160" y="375" text-anchor="middle" font-size="10" fill="rgba(255,255,255,0.9)">• Session Store</text>
<text x="160" y="390" text-anchor="middle" font-size="10" fill="rgba(255,255,255,0.9)">• Job Queue (Bull)</text>
<text x="160" y="405" text-anchor="middle" font-size="10" fill="rgba(255,255,255,0.9)">• Rate Limiting</text>
<!-- PostgreSQL -->
<rect x="340" y="300" width="220" height="120" rx="10" fill="url(#pgGrad)" filter="url(#shadowD)"/>
<text x="450" y="330" text-anchor="middle" font-size="14" font-weight="bold" fill="white">PostgreSQL</text>
<text x="450" y="350" text-anchor="middle" font-size="11" fill="white">(Primary)</text>
<rect x="370" y="365" width="160" height="40" rx="5" fill="rgba(255,255,255,0.2)"/>
<text x="450" y="385" text-anchor="middle" font-size="10" fill="white">Replica (Read)</text>
<text x="450" y="400" text-anchor="middle" font-size="10" fill="rgba(255,255,255,0.8)">High Availability</text>
<!-- S3/MinIO -->
<rect x="630" y="300" width="220" height="120" rx="10" fill="url(#s3Grad)" filter="url(#shadowD)"/>
<text x="740" y="330" text-anchor="middle" font-size="14" font-weight="bold" fill="white">S3 / MinIO</text>
<text x="740" y="350" text-anchor="middle" font-size="11" fill="white">(Storage)</text>
<text x="740" y="375" text-anchor="middle" font-size="10" fill="rgba(255,255,255,0.9)">• Videos</text>
<text x="740" y="390" text-anchor="middle" font-size="10" fill="rgba(255,255,255,0.9)">• Images</text>
<text x="740" y="405" text-anchor="middle" font-size="10" fill="rgba(255,255,255,0.9)">• Assets</text>
<!-- Connecting lines from data layer -->
<path d="M 160 420 L 160 450 L 450 450 L 450 480" stroke="#666" stroke-width="1.5" fill="none"/>
<path d="M 450 420 L 450 480" stroke="#666" stroke-width="1.5"/>
<path d="M 740 420 L 740 450 L 450 450" stroke="#666" stroke-width="1.5" fill="none"/>
<path d="M 450 480 L 450 495" stroke="#666" stroke-width="2" marker-end="url(#arrowD)"/>
<!-- Render Workers -->
<rect x="75" y="510" width="180" height="70" rx="10" fill="url(#workerGrad)" filter="url(#shadowD)"/>
<text x="165" y="540" text-anchor="middle" font-size="12" font-weight="bold" fill="white">Render Worker 1</text>
<text x="165" y="560" text-anchor="middle" font-size="10" fill="white">Puppeteer + FFmpeg</text>
<rect x="310" y="510" width="180" height="70" rx="10" fill="url(#workerGrad)" filter="url(#shadowD)"/>
<text x="400" y="540" text-anchor="middle" font-size="12" font-weight="bold" fill="white">Render Worker 2</text>
<text x="400" y="560" text-anchor="middle" font-size="10" fill="white">Puppeteer + FFmpeg</text>
<rect x="545" y="510" width="180" height="70" rx="10" fill="url(#workerGrad)" filter="url(#shadowD)"/>
<text x="635" y="540" text-anchor="middle" font-size="12" font-weight="bold" fill="white">Render Worker N</text>
<text x="635" y="560" text-anchor="middle" font-size="10" fill="white">Puppeteer + FFmpeg</text>
<!-- Arrows to Render Workers -->
<path d="M 350 495 L 165 510" stroke="#666" stroke-width="1.5"/>
<path d="M 450 495 L 400 510" stroke="#666" stroke-width="1.5"/>
<path d="M 550 495 L 635 510" stroke="#666" stroke-width="1.5"/>
<!-- Connecting line to Upload Workers -->
<path d="M 165 580 L 165 610 L 635 610 L 635 580" stroke="#666" stroke-width="1.5" fill="none"/>
<path d="M 400 580 L 400 610" stroke="#666" stroke-width="1.5"/>
<path d="M 400 610 L 400 640" stroke="#666" stroke-width="2" marker-end="url(#arrowD)"/>
<!-- Upload Workers -->
<rect x="75" y="655" width="180" height="70" rx="10" fill="url(#uploadGrad)" filter="url(#shadowD)"/>
<text x="165" y="685" text-anchor="middle" font-size="12" font-weight="bold" fill="white">Upload Worker 1</text>
<text x="165" y="705" text-anchor="middle" font-size="10" fill="white">YouTube</text>
<rect x="310" y="655" width="180" height="70" rx="10" fill="url(#uploadGrad)" filter="url(#shadowD)"/>
<text x="400" y="685" text-anchor="middle" font-size="12" font-weight="bold" fill="white">Upload Worker 2</text>
<text x="400" y="705" text-anchor="middle" font-size="10" fill="white">Instagram</text>
<rect x="545" y="655" width="180" height="70" rx="10" fill="url(#uploadGrad)" filter="url(#shadowD)"/>
<text x="635" y="685" text-anchor="middle" font-size="12" font-weight="bold" fill="white">Upload Worker N</text>
<text x="635" y="705" text-anchor="middle" font-size="10" fill="white">TikTok</text>
<!-- Arrows to Upload Workers -->
<path d="M 300 640 L 165 655" stroke="#666" stroke-width="1.5"/>
<path d="M 400 640 L 400 655" stroke="#666" stroke-width="1.5"/>
<path d="M 500 640 L 635 655" stroke="#666" stroke-width="1.5"/>
<!-- External APIs label -->
<rect x="750" y="655" width="130" height="70" rx="8" fill="#f0f0f0" stroke="#ccc" stroke-width="1"/>
<text x="815" y="680" text-anchor="middle" font-size="11" font-weight="bold" fill="#666">External APIs</text>
<text x="815" y="698" text-anchor="middle" font-size="9" fill="#888">Gemini • Suno</text>
<text x="815" y="712" text-anchor="middle" font-size="9" fill="#888">YouTube • IG • TikTok</text>
<!-- Capacity Labels -->
<rect x="780" y="50" width="100" height="25" rx="5" fill="#22c55e"/>
<text x="830" y="68" text-anchor="middle" font-size="11" fill="white">50,000+ users</text>
<!-- Legend -->
<rect x="20" y="750" width="860" height="40" rx="5" fill="#f8f9fa" stroke="#e9ecef"/>
<circle cx="60" cy="770" r="8" fill="url(#apiGradD)"/>
<text x="75" y="774" font-size="10" fill="#666">API Server</text>
<circle cx="180" cy="770" r="8" fill="url(#redisGrad)"/>
<text x="195" y="774" font-size="10" fill="#666">Redis</text>
<circle cx="280" cy="770" r="8" fill="url(#pgGrad)"/>
<text x="295" y="774" font-size="10" fill="#666">PostgreSQL</text>
<circle cx="400" cy="770" r="8" fill="url(#s3Grad)"/>
<text x="415" y="774" font-size="10" fill="#666">S3/MinIO</text>
<circle cx="510" cy="770" r="8" fill="url(#workerGrad)"/>
<text x="525" y="774" font-size="10" fill="#666">Render Worker</text>
<circle cx="650" cy="770" r="8" fill="url(#uploadGrad)"/>
<text x="665" y="774" font-size="10" fill="#666">Upload Worker</text>
</svg>