feat(pitch-deck): data room — file sharing and investor uploads
Build pitch-deck / build-push-deploy (push) Successful in 1m21s
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 31s
CI / test-python-voice (push) Successful in 33s
CI / test-bqas (push) Successful in 32s

- lib/dataroom-storage.ts: local volume storage (DATAROOM_PATH env var,
  default /data/dataroom) replacing NextCloud WebDAV
- Admin API: upload documents, rename, delete, manage per-investor releases
- Investor API: list released documents, stream download with audit log,
  upload own documents (max DATAROOM_MAX_UPLOAD_MB, default 50MB)
- /pitch-admin/dataroom: document list + release toggles + investor uploads tab
- /dataroom: investor-facing document library + upload section
- All reads and writes logged to pitch_audit_logs
- Migration 005: dataroom_documents, dataroom_releases, dataroom_investor_uploads
- AdminShell: Data Room nav link (FolderOpen icon)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-05-01 15:38:21 +02:00
parent 1bf1411c66
commit 9888b1b5d7
13 changed files with 930 additions and 0 deletions
+33
View File
@@ -122,6 +122,39 @@ export async function POST(request: NextRequest) {
`CREATE INDEX IF NOT EXISTS idx_fp_liquid_scenario ON fp_liquiditaet(scenario_id)`,
`CREATE INDEX IF NOT EXISTS idx_fp_guv_scenario ON fp_guv(scenario_id)`,
`CREATE INDEX IF NOT EXISTS idx_fp_overrides_lookup ON fp_cell_overrides(scenario_id, sheet_name, row_id)`,
// 005 — data room
`CREATE TABLE IF NOT EXISTS dataroom_documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
filename TEXT NOT NULL,
file_path TEXT NOT NULL,
display_name TEXT,
mime_type TEXT,
file_size BIGINT,
uploaded_by TEXT NOT NULL DEFAULT 'admin',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
)`,
`CREATE TABLE IF NOT EXISTS dataroom_releases (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
document_id UUID REFERENCES dataroom_documents(id) ON DELETE CASCADE,
investor_id UUID REFERENCES pitch_investors(id) ON DELETE CASCADE,
released_by TEXT NOT NULL,
released_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(document_id, investor_id)
)`,
`CREATE TABLE IF NOT EXISTS dataroom_investor_uploads (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
investor_id UUID REFERENCES pitch_investors(id) ON DELETE CASCADE,
filename TEXT NOT NULL,
file_path TEXT NOT NULL,
display_name TEXT,
mime_type TEXT,
file_size BIGINT,
created_at TIMESTAMPTZ DEFAULT NOW()
)`,
`CREATE INDEX IF NOT EXISTS idx_dataroom_releases_investor ON dataroom_releases(investor_id)`,
`CREATE INDEX IF NOT EXISTS idx_dataroom_releases_document ON dataroom_releases(document_id)`,
`CREATE INDEX IF NOT EXISTS idx_dataroom_uploads_investor ON dataroom_investor_uploads(investor_id)`,
]
for (const sql of statements) {