fix(pitch-deck): all financial slides now read from fp_* tables via useFpKPIs
All checks were successful
Build pitch-deck / build-push-deploy (push) Successful in 1m18s
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 34s
CI / test-python-voice (push) Successful in 32s
CI / test-bqas (push) Successful in 32s

New shared hook: useFpKPIs — loads annual KPIs from fp_guv/liquiditaet/personal/kunden.
Replaces useFinancialModel (simplified model) for KPI display on all slides.

Slides updated:
- CompetitionSlide: "110 Gesetze" → "380+ Regularien & Normen"
- BusinessModelSlide: ACV + Gross Margin from fp_* (was useFinancialModel)
- ExecutiveSummarySlide: Unternehmensentwicklung from fp_* (was useFinancialModel)
- FinancialsSlide: KPI cards from fp_* (ARR, Customers, Break-Even, EBIT 2030)

All slides now show consistent numbers from the same source of truth (fp_* tables).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-19 17:00:27 +02:00
parent de308b7397
commit f66f32ee9d
6 changed files with 141 additions and 40 deletions

View File

@@ -5,6 +5,7 @@ import { Language } from '@/lib/types'
import { t } from '@/lib/i18n'
import ProjectionFooter from '../ui/ProjectionFooter'
import { useFinancialModel } from '@/lib/hooks/useFinancialModel'
import { useFpKPIs } from '@/lib/hooks/useFpKPIs'
import GradientText from '../ui/GradientText'
import FadeInView from '../ui/FadeInView'
import FinancialChart from '../ui/FinancialChart'
@@ -23,9 +24,10 @@ interface FinancialsSlideProps {
lang: Language
investorId: string | null
preferredScenarioId?: string | null
isWandeldarlehen?: boolean
}
export default function FinancialsSlide({ lang, investorId, preferredScenarioId }: FinancialsSlideProps) {
export default function FinancialsSlide({ lang, investorId, preferredScenarioId, isWandeldarlehen }: FinancialsSlideProps) {
const i = t(lang)
const fm = useFinancialModel(investorId, preferredScenarioId)
const [activeTab, setActiveTab] = useState<FinTab>('overview')
@@ -35,6 +37,18 @@ export default function FinancialsSlide({ lang, investorId, preferredScenarioId
const summary = activeResults?.summary
const lastResult = activeResults?.results[activeResults.results.length - 1]
// KPI cards from fp_* tables (source of truth)
const { last: fpLast, kpis: fpKPIs } = useFpKPIs(isWandeldarlehen)
const kpiArr = fpLast?.arr || summary?.final_arr || 0
const kpiCustomers = fpLast?.customers || summary?.final_customers || 0
const kpiEbit = fpKPIs?.y2029?.ebit // First profitable year
const kpiBreakEven = (() => {
for (const y of [2026, 2027, 2028, 2029, 2030]) {
if ((fpKPIs[`y${y}`]?.ebit || 0) > 0) return y
}
return 0
})()
// Build scenario color map
const scenarioColors: Record<string, string> = {}
fm.scenarios.forEach(s => { scenarioColors[s.id] = s.color })
@@ -74,9 +88,9 @@ export default function FinancialsSlide({ lang, investorId, preferredScenarioId
<div className="grid grid-cols-2 md:grid-cols-4 gap-2 mb-3">
<KPICard
label={`ARR 2030`}
value={summary ? Math.round(summary.final_arr / 1_000_000 * 10) / 10 : 0}
suffix=" Mio."
decimals={1}
value={kpiArr >= 1_000_000 ? Math.round(kpiArr / 1_000_000 * 10) / 10 : Math.round(kpiArr / 1000)}
suffix={kpiArr >= 1_000_000 ? ' Mio.' : 'k'}
decimals={kpiArr >= 1_000_000 ? 1 : 0}
trend="up"
color="#6366f1"
delay={0.1}
@@ -84,28 +98,28 @@ export default function FinancialsSlide({ lang, investorId, preferredScenarioId
/>
<KPICard
label={de ? 'Kunden 2030' : 'Customers 2030'}
value={summary?.final_customers || 0}
value={kpiCustomers}
trend="up"
color="#22c55e"
delay={0.15}
/>
<KPICard
label="Break-Even"
value={summary?.break_even_month || 0}
suffix={de ? ' Mo.' : ' mo.'}
trend={summary?.break_even_month && summary.break_even_month <= 24 ? 'up' : 'down'}
value={kpiBreakEven || 0}
trend={kpiBreakEven && kpiBreakEven <= 2029 ? 'up' : 'down'}
color="#eab308"
delay={0.2}
subLabel={summary?.break_even_month ? `~${Math.ceil((summary.break_even_month) / 12) + 2025}` : ''}
subLabel=""
/>
<KPICard
label="LTV/CAC"
value={summary?.final_ltv_cac || 0}
suffix="x"
label="EBIT 2030"
value={fpLast?.ebit ? Math.round(fpLast.ebit / 1_000_000 * 10) / 10 : 0}
suffix=" Mio."
decimals={1}
trend={(summary?.final_ltv_cac || 0) >= 3 ? 'up' : 'down'}
trend={(fpLast?.ebit || 0) > 0 ? 'up' : 'down'}
color="#a855f7"
delay={0.25}
subLabel="EUR"
/>
</div>