R1: Dashboard 500 fix, Phase 2/7 uncommitted changes

- Fix dashboard 500 when deps disconnected — _gather_state() now returns
  full defaults instead of bare {'connected': False}
- Phase 2: FX param schemas aligned with DSP implementations
- Phase 7: Pipeline routing, preset manager improvements
- Factory presets: cleanup and normalization

Fixes dashboard crash on disconnected state (dogfood issue #1)
This commit is contained in:
2026-06-12 14:02:13 -04:00
parent 1301a8a128
commit 77a757cee6
62 changed files with 24166 additions and 20 deletions
+145
View File
@@ -0,0 +1,145 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 480 320" font-family="Inter, -apple-system, sans-serif">
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#1a1a2e"/>
<stop offset="100%" stop-color="#16213e"/>
</linearGradient>
<linearGradient id="led-off" x1="0" y1="1" x2="0" y2="0">
<stop offset="0%" stop-color="#2a2a3a"/>
<stop offset="100%" stop-color="#3a3a4a"/>
</linearGradient>
<linearGradient id="led-on" x1="0" y1="1" x2="0" y2="0">
<stop offset="0%" stop-color="#00b894"/>
<stop offset="100%" stop-color="#55efc4"/>
</linearGradient>
<linearGradient id="knob" x1="0" y1="1" x2="0" y2="0">
<stop offset="0%" stop-color="#2d3436"/>
<stop offset="100%" stop-color="#636e72"/>
</linearGradient>
</defs>
<!-- Background -->
<rect width="480" height="320" rx="12" fill="url(#bg)" stroke="#2d3436" stroke-width="2"/>
<!-- ═══ Status Bar ═══ -->
<rect x="0" y="0" width="480" height="36" rx="12" fill="#0a0a1a" opacity="0.6"/>
<rect x="0" y="24" width="480" height="12" fill="#0a0a1a" opacity="0.6"/>
<!-- Status dots (FX chain indicator) -->
<circle cx="28" cy="18" r="4" fill="#55efc4"/>
<circle cx="44" cy="18" r="4" fill="#55efc4"/>
<circle cx="60" cy="18" r="4" fill="#55efc4"/>
<circle cx="76" cy="18" r="4" fill="#e17055"/>
<circle cx="92" cy="18" r="4" fill="#636e72"/>
<circle cx="108" cy="18" r="4" fill="#636e72"/>
<!-- Status labels -->
<text x="140" y="23" fill="#636e72" font-size="10">GN Ch Dr ◇ Dly Rvb</text>
<!-- Tuner / Tempo / CPU -->
<text x="320" y="23" fill="#55efc4" font-size="11" font-weight="bold">♩ 120</text>
<text x="380" y="23" fill="#636e72" font-size="10">CPU 23%</text>
<text x="440" y="23" fill="#636e72" font-size="10">▣ 89%</text>
<!-- ═══ Main Content Area ═══ -->
<!-- Preset name badge -->
<rect x="12" y="44" width="456" height="32" rx="6" fill="#0a0a1a" opacity="0.5"/>
<text x="24" y="65" fill="#dfe6e9" font-size="14" font-weight="bold">Bank 1 / 03 — Edge of Breakup</text>
<text x="380" y="65" fill="#636e72" font-size="11">4CM ◇ BYPASS</text>
<!-- ═══ FX Block Cards ═══ -->
<!-- Row 1 -->
<g transform="translate(12, 84)">
<rect width="108" height="56" rx="6" fill="#2d3436" opacity="0.9"/>
<text x="54" y="22" fill="#dfe6e9" font-size="11" font-weight="bold" text-anchor="middle">NOISE GATE</text>
<text x="54" y="38" fill="#636e72" font-size="9" text-anchor="middle">Thresh: -56dB</text>
<circle cx="90" cy="12" r="4" fill="#55efc4"/>
</g>
<g transform="translate(128, 84)">
<rect width="108" height="56" rx="6" fill="#2d3436" opacity="0.9"/>
<text x="54" y="22" fill="#dfe6e9" font-size="11" font-weight="bold" text-anchor="middle">COMPRESSOR</text>
<text x="54" y="38" fill="#636e72" font-size="9" text-anchor="middle">Ratio: 3:1</text>
<circle cx="90" cy="12" r="4" fill="#55efc4"/>
</g>
<g transform="translate(244, 84)">
<rect width="108" height="56" rx="6" fill="#2d3436" opacity="0.9"/>
<text x="54" y="22" fill="#dfe6e9" font-size="11" font-weight="bold" text-anchor="middle">OVERDRIVE</text>
<text x="54" y="38" fill="#636e72" font-size="9" text-anchor="middle">Drive: 68%</text>
<circle cx="90" cy="12" r="4" fill="#55efc4"/>
</g>
<g transform="translate(360, 84)">
<rect width="108" height="56" rx="6" fill="#2d3436" opacity="0.9"/>
<text x="54" y="22" fill="#dfe6e9" font-size="11" font-weight="bold" text-anchor="middle">EQ</text>
<text x="54" y="38" fill="#636e72" font-size="9" text-anchor="middle">Bass: +2 Mid: 0</text>
<circle cx="90" cy="12" r="4" fill="#55efc4"/>
</g>
<!-- Row 2 -->
<g transform="translate(12, 148)">
<rect width="108" height="56" rx="6" fill="#2d3436" opacity="0.9"/>
<text x="54" y="22" fill="#dfe6e9" font-size="11" font-weight="bold" text-anchor="middle">NAM AMP</text>
<text x="54" y="38" fill="#e17055" font-size="9" text-anchor="middle">Matchless Chime</text>
<circle cx="90" cy="12" r="4" fill="#55efc4"/>
</g>
<g transform="translate(128, 148)">
<rect width="108" height="56" rx="6" fill="#2d3436" opacity="0.9"/>
<text x="54" y="22" fill="#dfe6e9" font-size="11" font-weight="bold" text-anchor="middle">CAB IR</text>
<text x="54" y="38" fill="#e17055" font-size="9" text-anchor="middle">Vox AC30 Blue</text>
<circle cx="90" cy="12" r="4" fill="#55efc4"/>
</g>
<g transform="translate(244, 148)">
<rect width="108" height="56" rx="6" fill="#2d3436" opacity="0.9"/>
<text x="54" y="22" fill="#dfe6e9" font-size="11" font-weight="bold" text-anchor="middle">CHORUS</text>
<text x="54" y="38" fill="#636e72" font-size="9" text-anchor="middle">Rate: 0.4 Depth: 55</text>
<circle cx="90" cy="12" r="4" fill="#55efc4"/>
</g>
<g transform="translate(360, 148)">
<rect width="108" height="56" rx="6" fill="#2d3436" opacity="0.8"/>
<text x="54" y="22" fill="#636e72" font-size="11" font-weight="bold" text-anchor="middle">DELAY</text>
<text x="54" y="38" fill="#636e72" font-size="9" text-anchor="middle">Time: 420ms</text>
<circle cx="90" cy="12" r="4" fill="#636e72"/>
</g>
<!-- ═══ Footer ═══ -->
<!-- VU Meters -->
<rect x="12" y="212" width="456" height="36" rx="6" fill="#0a0a1a" opacity="0.5"/>
<text x="24" y="234" fill="#636e72" font-size="9">L</text>
<rect x="36" y="220" width="200" height="20" rx="3" fill="#1a1a2e"/>
<rect x="36" y="220" width="120" height="20" rx="3" fill="#55efc4"/>
<rect x="36" y="220" width="160" height="20" rx="3" fill="#00b894" opacity="0.3"/>
<text x="256" y="234" fill="#636e72" font-size="9">R</text>
<rect x="268" y="220" width="200" height="20" rx="3" fill="#1a1a2e"/>
<rect x="268" y="220" width="80" height="20" rx="3" fill="#55efc4"/>
<rect x="268" y="220" width="140" height="20" rx="3" fill="#00b894" opacity="0.3"/>
<!-- Knobs row -->
<g transform="translate(40, 260)">
<circle cx="0" cy="0" r="18" fill="url(#knob)" stroke="#636e72" stroke-width="1"/>
<line x1="0" y1="-14" x2="0" y2="-6" stroke="#55efc4" stroke-width="2" stroke-linecap="round"/>
<text x="0" y="28" fill="#636e72" font-size="9" text-anchor="middle">MASTER</text>
</g>
<g transform="translate(140, 260)">
<circle cx="0" cy="0" r="18" fill="url(#knob)" stroke="#636e72" stroke-width="1"/>
<line x1="0" y1="-14" x2="8" y2="-8" stroke="#55efc4" stroke-width="2" stroke-linecap="round"/>
<text x="0" y="28" fill="#636e72" font-size="9" text-anchor="middle">GAIN</text>
</g>
<g transform="translate(240, 260)">
<circle cx="0" cy="0" r="18" fill="url(#knob)" stroke="#636e72" stroke-width="1"/>
<line x1="0" y1="-14" x2="-8" y2="-8" stroke="#55efc4" stroke-width="2" stroke-linecap="round"/>
<text x="0" y="28" fill="#636e72" font-size="9" text-anchor="middle">TONE</text>
</g>
<g transform="translate(340, 260)">
<circle cx="0" cy="0" r="18" fill="url(#knob)" stroke="#636e72" stroke-width="1"/>
<line x1="0" y1="-14" x2="4" y2="-12" stroke="#55efc4" stroke-width="2" stroke-linecap="round"/>
<text x="0" y="28" fill="#636e72" font-size="9" text-anchor="middle">VOLUME</text>
</g>
<!-- Bottom nav dots -->
<circle cx="190" cy="305" r="3" fill="#55efc4"/>
<circle cx="210" cy="305" r="3" fill="#636e72"/>
<circle cx="230" cy="305" r="3" fill="#636e72"/>
<circle cx="250" cy="305" r="3" fill="#636e72"/>
<circle cx="270" cy="305" r="3" fill="#636e72"/>
<circle cx="290" cy="305" r="3" fill="#636e72"/>
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB