feat(pitch-deck): full pitch versioning with git-style history (#4)
Some checks failed
Build pitch-deck / build-and-push (push) Failing after 1m8s
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 32s
CI / test-python-voice (push) Successful in 32s
CI / test-bqas (push) Successful in 32s
CI / Deploy (push) Failing after 4s
Some checks failed
Build pitch-deck / build-and-push (push) Failing after 1m8s
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 32s
CI / test-python-voice (push) Successful in 32s
CI / test-bqas (push) Successful in 32s
CI / Deploy (push) Failing after 4s
Full pitch versioning: 12 data tables versioned as JSONB snapshots, git-style parent chain (draft→commit→fork), per-investor assignment, side-by-side diff engine, version-aware /api/data + /api/financial-model. Bug fixes: FM editor [object Object] for JSONB arrays, admin scroll. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit was merged in pull request #4.
This commit is contained in:
@@ -1,32 +1,63 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import pool from '@/lib/db'
|
||||
import { getSessionFromCookie } from '@/lib/auth'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
// GET: Load all scenarios with their assumptions
|
||||
function assembleScenarios(scenarioRows: Record<string, unknown>[], assumptionRows: Record<string, unknown>[]) {
|
||||
return scenarioRows.map(s => ({
|
||||
...s,
|
||||
assumptions: assumptionRows
|
||||
.filter((a: Record<string, unknown>) => a.scenario_id === (s as Record<string, unknown>).id)
|
||||
.map((a: Record<string, unknown>) => ({
|
||||
...a,
|
||||
value: typeof a.value === 'string' ? JSON.parse(a.value as string) : a.value,
|
||||
})),
|
||||
}))
|
||||
}
|
||||
|
||||
// GET: Load all scenarios with their assumptions (version-aware)
|
||||
export async function GET() {
|
||||
try {
|
||||
// Check if investor has an assigned version with FM data
|
||||
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 (versionId) {
|
||||
const [scenarioData, assumptionData] = await Promise.all([
|
||||
pool.query(`SELECT data FROM pitch_version_data WHERE version_id = $1 AND table_name = 'fm_scenarios'`, [versionId]),
|
||||
pool.query(`SELECT data FROM pitch_version_data WHERE version_id = $1 AND table_name = 'fm_assumptions'`, [versionId]),
|
||||
])
|
||||
|
||||
if (scenarioData.rows.length > 0) {
|
||||
const scenarios = typeof scenarioData.rows[0].data === 'string'
|
||||
? JSON.parse(scenarioData.rows[0].data) : scenarioData.rows[0].data
|
||||
const assumptions = assumptionData.rows.length > 0
|
||||
? (typeof assumptionData.rows[0].data === 'string'
|
||||
? JSON.parse(assumptionData.rows[0].data) : assumptionData.rows[0].data)
|
||||
: []
|
||||
return NextResponse.json(assembleScenarios(scenarios, assumptions))
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: base tables
|
||||
const client = await pool.connect()
|
||||
try {
|
||||
const scenarios = await client.query(
|
||||
'SELECT * FROM pitch_fm_scenarios ORDER BY is_default DESC, name'
|
||||
)
|
||||
|
||||
const assumptions = await client.query(
|
||||
'SELECT * FROM pitch_fm_assumptions ORDER BY sort_order'
|
||||
)
|
||||
|
||||
const result = scenarios.rows.map(s => ({
|
||||
...s,
|
||||
assumptions: assumptions.rows
|
||||
.filter(a => a.scenario_id === s.id)
|
||||
.map(a => ({
|
||||
...a,
|
||||
value: typeof a.value === 'string' ? JSON.parse(a.value) : a.value,
|
||||
})),
|
||||
}))
|
||||
|
||||
return NextResponse.json(result)
|
||||
return NextResponse.json(assembleScenarios(scenarios.rows, assumptions.rows))
|
||||
} finally {
|
||||
client.release()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user