06014d57b3
Build pitch-deck / build-push-deploy (push) Successful in 1m30s
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 33s
CI / test-python-voice (push) Successful in 32s
CI / test-bqas (push) Successful in 31s
The fm_scenarios array in each pitch version snapshot already stores the fp_scenario IDs directly (same pattern 1 Mio used). Wandeldarlehen snapshots were missing Bear/Bull entries — updated in DB to add them. - /api/data: include fp_scenarios in version response (was omitted) - PitchDeck: derive fpBaseScenarioId from data.fp_scenarios - useFpKPIs: accept fpBaseScenarioId instead of isWandeldarlehen boolean - AssumptionsSlide: find Bear/Base/Bull by name from fpScenarios prop - FinanzplanSlide: initialize from fpBaseScenarioId, use version scenarios for selector - FinancialsSlide / ExecutiveSummarySlide: pass fpBaseScenarioId to hook - types: add FpScenarioRef + fp_scenarios field to PitchData No UUID hardcoded in any component. Adding a new pitch version only requires setting the correct fp_scenario IDs in its fm_scenarios snapshot. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
95 lines
3.5 KiB
TypeScript
95 lines
3.5 KiB
TypeScript
import { NextResponse } from 'next/server'
|
|
import pool from '@/lib/db'
|
|
import { getSessionFromCookie } from '@/lib/auth'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
export async function GET() {
|
|
try {
|
|
// Check if investor has an assigned version
|
|
const session = await getSessionFromCookie()
|
|
let versionId: string | null = null
|
|
|
|
if (session) {
|
|
const inv = await pool.query(
|
|
`SELECT assigned_version_id FROM pitch_investors WHERE id = $1`,
|
|
[session.sub],
|
|
)
|
|
versionId = inv.rows[0]?.assigned_version_id || null
|
|
}
|
|
|
|
// If version assigned, load from pitch_version_data
|
|
if (versionId) {
|
|
const { rows } = await pool.query(
|
|
`SELECT table_name, data FROM pitch_version_data WHERE version_id = $1`,
|
|
[versionId],
|
|
)
|
|
const map: Record<string, unknown[]> = {}
|
|
for (const row of rows) {
|
|
map[row.table_name] = typeof row.data === 'string' ? JSON.parse(row.data) : row.data
|
|
}
|
|
return NextResponse.json({
|
|
company: (map.company || [])[0] || null,
|
|
team: map.team || [],
|
|
financials: map.financials || [],
|
|
market: map.market || [],
|
|
competitors: map.competitors || [],
|
|
features: map.features || [],
|
|
milestones: map.milestones || [],
|
|
metrics: map.metrics || [],
|
|
funding: (map.funding || [])[0] || null,
|
|
products: map.products || [],
|
|
fp_scenarios: map.fm_scenarios || [],
|
|
})
|
|
}
|
|
|
|
// Fallback: read from base tables (backward compatible)
|
|
const client = await pool.connect()
|
|
try {
|
|
const [
|
|
companyRes, teamRes, financialsRes, marketRes, competitorsRes,
|
|
featuresRes, milestonesRes, metricsRes, fundingRes, productsRes,
|
|
] = await Promise.all([
|
|
client.query('SELECT * FROM pitch_company LIMIT 1'),
|
|
client.query('SELECT * FROM pitch_team ORDER BY sort_order'),
|
|
client.query('SELECT * FROM pitch_financials ORDER BY year'),
|
|
client.query('SELECT * FROM pitch_market ORDER BY id'),
|
|
client.query('SELECT * FROM pitch_competitors ORDER BY id'),
|
|
client.query('SELECT * FROM pitch_features ORDER BY sort_order'),
|
|
client.query('SELECT * FROM pitch_milestones ORDER BY sort_order'),
|
|
client.query('SELECT * FROM pitch_metrics ORDER BY id'),
|
|
client.query('SELECT * FROM pitch_funding LIMIT 1'),
|
|
client.query('SELECT * FROM pitch_products ORDER BY sort_order'),
|
|
])
|
|
|
|
return NextResponse.json({
|
|
company: companyRes.rows[0] || null,
|
|
team: teamRes.rows,
|
|
financials: financialsRes.rows,
|
|
market: marketRes.rows,
|
|
competitors: competitorsRes.rows,
|
|
features: featuresRes.rows,
|
|
milestones: milestonesRes.rows,
|
|
metrics: metricsRes.rows,
|
|
funding: fundingRes.rows[0] || null,
|
|
products: productsRes.rows,
|
|
})
|
|
} finally {
|
|
client.release()
|
|
}
|
|
} catch (error) {
|
|
console.error('Database query error:', (error as Error).message)
|
|
// Return minimal stub in dev so the pitch renders without a DB connection
|
|
if (process.env.NODE_ENV === 'development') {
|
|
return NextResponse.json({
|
|
company: { name: 'BreakPilot', tagline: '[dev mode — no DB]' },
|
|
team: [], financials: [], market: [], competitors: [],
|
|
features: [], milestones: [], metrics: [],
|
|
funding: { instrument: 'Wandeldarlehen', amount: 500000, valuation_cap: 3000000, currency: 'EUR' },
|
|
products: [],
|
|
})
|
|
}
|
|
return NextResponse.json({ error: 'Failed to load pitch data' }, { status: 500 })
|
|
}
|
|
}
|