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:
191
pitch-deck/migrations/000_pitch_data_tables.sql
Normal file
191
pitch-deck/migrations/000_pitch_data_tables.sql
Normal file
@@ -0,0 +1,191 @@
|
||||
-- =========================================================
|
||||
-- Pitch Deck: Core data tables + Financial Model
|
||||
-- Run BEFORE 001_investor_auth.sql
|
||||
-- =========================================================
|
||||
|
||||
-- Company info
|
||||
CREATE TABLE IF NOT EXISTS pitch_company (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT,
|
||||
legal_form TEXT,
|
||||
founding_date TEXT,
|
||||
tagline_de TEXT,
|
||||
tagline_en TEXT,
|
||||
mission_de TEXT,
|
||||
mission_en TEXT,
|
||||
website TEXT,
|
||||
hq_city TEXT
|
||||
);
|
||||
|
||||
-- Team members
|
||||
CREATE TABLE IF NOT EXISTS pitch_team (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT,
|
||||
role_de TEXT,
|
||||
role_en TEXT,
|
||||
bio_de TEXT,
|
||||
bio_en TEXT,
|
||||
equity_pct NUMERIC,
|
||||
expertise TEXT[],
|
||||
linkedin_url TEXT,
|
||||
photo_url TEXT,
|
||||
sort_order INT DEFAULT 0
|
||||
);
|
||||
|
||||
-- Historical financials
|
||||
CREATE TABLE IF NOT EXISTS pitch_financials (
|
||||
id SERIAL PRIMARY KEY,
|
||||
year INT,
|
||||
revenue_eur BIGINT,
|
||||
costs_eur BIGINT,
|
||||
mrr_eur BIGINT,
|
||||
burn_rate_eur BIGINT,
|
||||
customers_count INT,
|
||||
employees_count INT,
|
||||
arr_eur BIGINT
|
||||
);
|
||||
|
||||
-- Market segments (TAM/SAM/SOM)
|
||||
CREATE TABLE IF NOT EXISTS pitch_market (
|
||||
id SERIAL PRIMARY KEY,
|
||||
market_segment TEXT,
|
||||
label TEXT,
|
||||
value_eur BIGINT,
|
||||
growth_rate_pct NUMERIC,
|
||||
source TEXT
|
||||
);
|
||||
|
||||
-- Competitors
|
||||
CREATE TABLE IF NOT EXISTS pitch_competitors (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT,
|
||||
customers_count INT,
|
||||
pricing_range TEXT,
|
||||
strengths TEXT[],
|
||||
weaknesses TEXT[],
|
||||
website TEXT
|
||||
);
|
||||
|
||||
-- Feature comparison matrix
|
||||
CREATE TABLE IF NOT EXISTS pitch_features (
|
||||
id SERIAL PRIMARY KEY,
|
||||
feature_name_de TEXT,
|
||||
feature_name_en TEXT,
|
||||
category TEXT,
|
||||
breakpilot BOOLEAN,
|
||||
proliance BOOLEAN,
|
||||
dataguard BOOLEAN,
|
||||
heydata BOOLEAN,
|
||||
is_differentiator BOOLEAN,
|
||||
sort_order INT DEFAULT 0
|
||||
);
|
||||
|
||||
-- Milestones / timeline
|
||||
CREATE TABLE IF NOT EXISTS pitch_milestones (
|
||||
id SERIAL PRIMARY KEY,
|
||||
milestone_date TEXT,
|
||||
title_de TEXT,
|
||||
title_en TEXT,
|
||||
description_de TEXT,
|
||||
description_en TEXT,
|
||||
status TEXT,
|
||||
category TEXT,
|
||||
sort_order INT DEFAULT 0
|
||||
);
|
||||
|
||||
-- Key metrics
|
||||
CREATE TABLE IF NOT EXISTS pitch_metrics (
|
||||
id SERIAL PRIMARY KEY,
|
||||
metric_name TEXT,
|
||||
label_de TEXT,
|
||||
label_en TEXT,
|
||||
value TEXT,
|
||||
unit TEXT,
|
||||
is_live BOOLEAN
|
||||
);
|
||||
|
||||
-- Funding round
|
||||
CREATE TABLE IF NOT EXISTS pitch_funding (
|
||||
id SERIAL PRIMARY KEY,
|
||||
round_name TEXT,
|
||||
amount_eur BIGINT,
|
||||
use_of_funds JSONB,
|
||||
instrument TEXT,
|
||||
target_date TEXT,
|
||||
status TEXT
|
||||
);
|
||||
|
||||
-- Products / tiers
|
||||
CREATE TABLE IF NOT EXISTS pitch_products (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT,
|
||||
hardware TEXT,
|
||||
hardware_cost_eur NUMERIC,
|
||||
monthly_price_eur NUMERIC,
|
||||
llm_model TEXT,
|
||||
llm_size TEXT,
|
||||
llm_capability_de TEXT,
|
||||
llm_capability_en TEXT,
|
||||
features_de TEXT[],
|
||||
features_en TEXT[],
|
||||
is_popular BOOLEAN,
|
||||
operating_cost_eur NUMERIC,
|
||||
sort_order INT DEFAULT 0
|
||||
);
|
||||
|
||||
-- =========================================================
|
||||
-- Financial Model
|
||||
-- =========================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pitch_fm_scenarios (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT,
|
||||
description TEXT,
|
||||
is_default BOOLEAN DEFAULT false,
|
||||
color TEXT DEFAULT '#6366f1',
|
||||
sort_order INT DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pitch_fm_assumptions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
scenario_id UUID REFERENCES pitch_fm_scenarios(id) ON DELETE CASCADE,
|
||||
key TEXT,
|
||||
label_de TEXT,
|
||||
label_en TEXT,
|
||||
value JSONB,
|
||||
value_type TEXT DEFAULT 'scalar',
|
||||
unit TEXT,
|
||||
min_value NUMERIC,
|
||||
max_value NUMERIC,
|
||||
step_size NUMERIC,
|
||||
category TEXT,
|
||||
sort_order INT DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pitch_fm_results (
|
||||
id SERIAL PRIMARY KEY,
|
||||
scenario_id UUID REFERENCES pitch_fm_scenarios(id) ON DELETE CASCADE,
|
||||
month INT,
|
||||
year INT,
|
||||
month_in_year INT,
|
||||
new_customers INT,
|
||||
churned_customers INT,
|
||||
total_customers INT,
|
||||
mrr_eur NUMERIC,
|
||||
arr_eur NUMERIC,
|
||||
revenue_eur NUMERIC,
|
||||
cogs_eur NUMERIC,
|
||||
personnel_eur NUMERIC,
|
||||
infra_eur NUMERIC,
|
||||
marketing_eur NUMERIC,
|
||||
total_costs_eur NUMERIC,
|
||||
employees_count INT,
|
||||
gross_margin_pct NUMERIC,
|
||||
burn_rate_eur NUMERIC,
|
||||
runway_months NUMERIC,
|
||||
cac_eur NUMERIC,
|
||||
ltv_eur NUMERIC,
|
||||
ltv_cac_ratio NUMERIC,
|
||||
cash_balance_eur NUMERIC,
|
||||
cumulative_revenue_eur NUMERIC
|
||||
);
|
||||
36
pitch-deck/migrations/003_pitch_versions.sql
Normal file
36
pitch-deck/migrations/003_pitch_versions.sql
Normal file
@@ -0,0 +1,36 @@
|
||||
-- =========================================================
|
||||
-- Pitch Deck: Version Management (Git-Style History)
|
||||
-- =========================================================
|
||||
|
||||
-- Version metadata: each version points to its parent (git-style DAG)
|
||||
CREATE TABLE IF NOT EXISTS pitch_versions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
parent_id UUID REFERENCES pitch_versions(id) ON DELETE SET NULL,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'draft'
|
||||
CHECK (status IN ('draft', 'committed')),
|
||||
created_by UUID REFERENCES pitch_admins(id) ON DELETE SET NULL,
|
||||
committed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_pitch_versions_parent ON pitch_versions(parent_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_pitch_versions_status ON pitch_versions(status);
|
||||
|
||||
-- Version content: one row per data table per version (fully materialized)
|
||||
-- table_name values: company, team, financials, market, competitors, features,
|
||||
-- milestones, metrics, funding, products, fm_scenarios, fm_assumptions
|
||||
CREATE TABLE IF NOT EXISTS pitch_version_data (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
version_id UUID NOT NULL REFERENCES pitch_versions(id) ON DELETE CASCADE,
|
||||
table_name TEXT NOT NULL,
|
||||
data JSONB NOT NULL,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_by UUID REFERENCES pitch_admins(id) ON DELETE SET NULL,
|
||||
UNIQUE(version_id, table_name)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_pitch_version_data_version ON pitch_version_data(version_id);
|
||||
|
||||
-- Per-investor version assignment (NULL = use base tables)
|
||||
ALTER TABLE pitch_investors
|
||||
ADD COLUMN IF NOT EXISTS assigned_version_id UUID REFERENCES pitch_versions(id) ON DELETE SET NULL;
|
||||
Reference in New Issue
Block a user