architecture.dot (2733B)
1 digraph corpus { 2 rankdir=LR 3 compound=true 4 splines=ortho 5 concentrate=true 6 nodesep=0.7 7 ranksep=1.6 8 bgcolor=transparent 9 10 node [fontname="Atkinson Hyperlegible Mono", fontsize=11, shape=box, style="rounded,filled", fontcolor=white] 11 edge [fontname="Atkinson Hyperlegible Mono", fontsize=9, color="#aaaaaa", fontcolor="#aaaaaa", arrowhead=vee, arrowsize=0.8, penwidth=1.4] 12 13 subgraph cluster_frontend { 14 label="Frontend" 15 style="rounded,filled" 16 fillcolor="#1e1533" 17 color="#9b7de8" 18 fontcolor=white 19 fontname="Atkinson Hyperlegible Mono" 20 UI [label="Elm SPA\n?user=slug", fillcolor="#2d2050"] 21 Client [label="Scrobble Client\n(LB-compatible)", fillcolor="#2d2050"] 22 } 23 24 subgraph cluster_server { 25 label="Corpus Server" 26 style="rounded,filled" 27 fillcolor="#112611" 28 color="#5aaa5a" 29 fontcolor=white 30 fontname="Atkinson Hyperlegible Mono" 31 API [label="Web API", fillcolor="#1c3e1c"] 32 Proxy [label="Cover Proxy", fillcolor="#1c3e1c"] 33 LBSync [label="ListenBrainz Sync", fillcolor="#1c3e1c"] 34 LFSync [label="Last.fm Sync", fillcolor="#1c3e1c"] 35 Enrich [label="Enrichment Task", fillcolor="#1c3e1c"] 36 } 37 38 subgraph cluster_storage { 39 label="Storage" 40 style="rounded,filled" 41 fillcolor="#272000" 42 color="#d4a80c" 43 fontcolor=white 44 fontname="Atkinson Hyperlegible Mono" 45 DB [label="DuckDB", shape=cylinder, fillcolor="#3d3100"] 46 S3 [label="S3 Bucket", shape=box3d, fillcolor="#3d3100"] 47 } 48 49 subgraph cluster_external { 50 label="External APIs" 51 style="rounded,filled" 52 fillcolor="#0e1e38" 53 color="#5a8de0" 54 fontcolor=white 55 fontname="Atkinson Hyperlegible Mono" 56 LB [label="ListenBrainz", fillcolor="#162d52"] 57 LF [label="Last.fm", fillcolor="#162d52"] 58 MB [label="MusicBrainz", fillcolor="#162d52"] 59 DC [label="Discogs", fillcolor="#162d52"] 60 CAA [label="Cover Art Archive", fillcolor="#162d52"] 61 } 62 63 // Scrobble Sync 64 LB -> LBSync 65 LF -> LFSync 66 LBSync -> DB 67 LFSync -> DB 68 69 // Enrichment 70 DB -> Enrich 71 Enrich -> MB 72 Enrich -> LF 73 Enrich -> DC 74 Enrich -> DB [constraint=false] 75 76 // Scrobble Submission 77 Client -> API [label="POST /1/submit-listens\n(token auth)"] 78 API -> DB [constraint=false] 79 80 // Web UI 81 UI -> API 82 API -> DB 83 84 // Cover Art 85 UI -> Proxy 86 Proxy -> S3 87 Proxy -> CAA 88 Proxy -> LF 89 Proxy -> DC 90 Proxy -> S3 [constraint=false] 91 }