fix: finanzplan scenario selector — load from API, no hardcoded UUID
All checks were successful
Build pitch-deck / build-push-deploy (push) Successful in 1m4s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 29s
CI / test-python-voice (push) Successful in 27s
CI / test-bqas (push) Successful in 28s

Replaces the FM-name-based 'wandeldarlehen' hack with a proper scenario
picker. Scenarios are fetched from /api/finanzplan, default is selected
automatically. Dropdown appears when multiple scenarios exist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-04-17 10:56:52 +02:00
parent 27ef21a4f0
commit 11fa490599

View File

@@ -61,8 +61,12 @@ function formatCell(v: number | undefined): string {
return Math.round(v).toLocaleString('de-DE', { maximumFractionDigits: 0 })
}
interface FpScenario { id: string; name: string; is_default: boolean }
export default function FinanzplanSlide({ lang, investorId, preferredScenarioId }: FinanzplanSlideProps) {
const [sheets, setSheets] = useState<SheetMeta[]>([])
const [scenarios, setScenarios] = useState<FpScenario[]>([])
const [selectedScenarioId, setSelectedScenarioId] = useState<string>('')
const [activeSheet, setActiveSheet] = useState<string>('personalkosten')
const [rows, setRows] = useState<SheetRow[]>([])
const [loading, setLoading] = useState(false)
@@ -77,19 +81,26 @@ export default function FinanzplanSlide({ lang, investorId, preferredScenarioId
[fm.activeResults],
)
// Determine fp_scenario_id from the active FM scenario name
const fpScenarioParam = fm.activeScenario?.name?.toLowerCase().includes('wandeldarlehen')
? '?scenarioId=c0000000-0000-0000-0000-000000000200'
: ''
// Load sheet list
// Load sheet list + scenarios
useEffect(() => {
fetch('/api/finanzplan', { cache: 'no-store' })
.then(r => r.json())
.then(data => setSheets(data.sheets || []))
.then(data => {
setSheets(data.sheets || [])
const scens: FpScenario[] = data.scenarios || []
setScenarios(scens)
// Pick default scenario on first load
if (!selectedScenarioId) {
const def = scens.find(s => s.is_default) ?? scens[0]
if (def) setSelectedScenarioId(def.id)
}
})
.catch(() => {})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const scenarioParam = selectedScenarioId ? `?scenarioId=${selectedScenarioId}` : ''
// Load sheet data
const loadSheet = useCallback(async (name: string) => {
if (name === 'kpis' || name === 'charts') {
@@ -99,12 +110,12 @@ export default function FinanzplanSlide({ lang, investorId, preferredScenarioId
}
setLoading(true)
try {
const r = await fetch(`/api/finanzplan/${name}${fpScenarioParam}`, { cache: 'no-store' })
const r = await fetch(`/api/finanzplan/${name}${scenarioParam}`, { cache: 'no-store' })
const data = await r.json()
setRows(data.rows || [])
} catch { /* ignore */ }
setLoading(false)
}, [fpScenarioParam])
}, [scenarioParam])
useEffect(() => { loadSheet(activeSheet) }, [activeSheet, loadSheet])
@@ -112,7 +123,7 @@ export default function FinanzplanSlide({ lang, investorId, preferredScenarioId
const handleCompute = async () => {
setComputing(true)
try {
await fetch('/api/finanzplan/compute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' })
await fetch('/api/finanzplan/compute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ scenarioId: selectedScenarioId || undefined }) })
await loadSheet(activeSheet)
} catch { /* ignore */ }
setComputing(false)
@@ -182,6 +193,17 @@ export default function FinanzplanSlide({ lang, investorId, preferredScenarioId
</button>
))}
<div className="flex-1" />
{scenarios.length > 1 && (
<select
value={selectedScenarioId}
onChange={e => setSelectedScenarioId(e.target.value)}
className="text-[10px] bg-white/[0.06] text-white/60 border border-white/10 rounded-lg px-2 py-1.5 mr-2"
>
{scenarios.map(s => (
<option key={s.id} value={s.id}>{s.name}{s.is_default ? ' ★' : ''}</option>
))}
</select>
)}
<button
onClick={handleCompute}
disabled={computing}