/** * Demo dataset — a plausible book of business, for development and demos. * * Separate from `index.ts` (which seeds publicly-sourced, cited people) because * this is **invented**. It exists so the product is legible before anyone has * entered real data: margin that moves, blocks at different utilisation, deals * spread across both pipelines, contracts with real structure. * * Two integrity rules, and they are not fussiness: * * **Every record is prefixed `DEMO —`.** A screenshot of this must never be * mistakeable for real business. * * **Demand-side customers are fictional.** Suppliers are real companies — * they are public, and naming the actual market is the point — but their * commitments are labelled and the prices are illustrative. Inventing * *customers* with invented contract values against real named companies * would be fabricating commercial records about real businesses, which is a * different thing entirely and not worth the realism. * * Remove it all with `pnpm db:demo -- --clear`. * * The numbers are chosen to teach. The book as a whole clears a modest margin — * roughly what this industry actually earns once capacity cost is charged * honestly — while individual blocks tell different stories: * * the large H200 block carries the book; * the EU H100 block is UNDERWATER at 55% sold, because a 46% markup needs * ~69% sold to break even at all; * the community A100 pool has a large hold that has not converted, so it * shows as reserved-but-unsold — the distinction between "sold" and "held" * made visible rather than theoretical. * * A demo that opens on a healthy total and reveals the problems on drill-down * is more useful than one that opens on a loss, which reads as a broken * product rather than an under-utilised book. */ import { ALLOCATION_STATUSES, type AllocationStatus } from '@pig/core'; import { and, eq, like, or } from 'drizzle-orm'; import { createDatabase } from '../client'; import { accounts, activities, facts, allocations, capacityCommitments, capacityRequests, contacts, contracts, contractObligations, demandDeals, type NewAllocation, sites, slaTerms, supplyDeals, } from '../schema/index'; const db = createDatabase(); const PREFIX = 'DEMO — '; const day = 86_400_000; const now = Date.now(); const at = (days: number) => new Date(now + days * day); function isAllocationStatus(value: string): value is AllocationStatus { return (ALLOCATION_STATUSES as readonly string[]).includes(value); } /** GPU-hours for a block, allowing for a maintenance/ramp haircut. */ const hours = (gpus: number, days: number, efficiency = 0.94) => String(Math.round(gpus * 24 * days * efficiency)); // ---------------------------------------------------------------- suppliers const SUPPLY = [ { domain: 'coreweave.com', site: { name: 'US-East (NJ)', country: 'United States', countryCode: 'US', region: 'us-east' }, commitment: { name: `${PREFIX}512× H200 reserved, 12 months`, gpuType: 'H200', socket: 'SXM5' as const, gpuCount: 512, interconnectType: 'Infiniband' as const, days: 365, costPerGpuHourCents: 189, takeOrPayFloorPct: '100', prepaidPct: '25', }, }, { domain: 'nebius.com', site: { name: 'EU-North (FI)', country: 'Finland', countryCode: 'FI', region: 'eu-north' }, commitment: { name: `${PREFIX}128× H100 reserved, 6 months`, gpuType: 'H100_80GB', socket: 'SXM5' as const, gpuCount: 128, interconnectType: 'Infiniband' as const, days: 180, costPerGpuHourCents: 171, takeOrPayFloorPct: '80', prepaidPct: '0', }, }, { domain: 'crusoe.ai', site: { name: 'US-Central (TX)', country: 'United States', countryCode: 'US', region: 'us-central' }, commitment: { name: `${PREFIX}64× B200 reserved, 9 months`, gpuType: 'B200', socket: 'SXM6' as const, gpuCount: 64, interconnectType: 'Infiniband' as const, days: 270, costPerGpuHourCents: 305, takeOrPayFloorPct: '100', prepaidPct: '15', }, }, { domain: 'runpod.io', site: { name: 'Community pool', country: 'United States', countryCode: 'US', region: 'us-west' }, commitment: { name: `${PREFIX}32× A100 burst pool, 3 months`, gpuType: 'A100_80GB', socket: 'SXM4' as const, gpuCount: 32, interconnectType: 'Ethernet' as const, securityTier: 'community_cloud' as const, days: 90, costPerGpuHourCents: 96, takeOrPayFloorPct: '0', prepaidPct: '0', }, }, ]; /** * Fictional customers. * * Invented deliberately — see the note at the top of this file. Any resemblance * to a real company is unintended, and none of these figures describes anyone's * actual contract. */ const DEMAND = [ { account: `${PREFIX}Halcyon Research`, segment: 'frontier_lab' as const, country: 'United States', contact: { name: 'Dana Whitfield', title: 'Head of Infrastructure', decisionMaker: true }, deal: { name: `${PREFIX}Pre-training cluster, 12 months`, productLine: 'compute_reserved' as const, stage: 'deployment' as const, acvCents: 2_400_000_00, termMonths: 12, msaExecuted: true, dpaExecuted: true, }, request: { gpuType: 'H200', gpuCount: 256, fastFabric: true, maxPriceCents: 285 }, // Draws from the CoreWeave block. allocation: { supplier: 'coreweave.com', share: 0.76, priceCents: 271, status: 'active', }, }, { account: `${PREFIX}Verity Health AI`, segment: 'enterprise' as const, country: 'Germany', contact: { name: 'Lukas Brenner', title: 'VP Engineering', decisionMaker: true }, deal: { name: `${PREFIX}EU-resident fine-tuning`, productLine: 'post_training' as const, stage: 'procurement' as const, acvCents: 640_000_00, termMonths: 6, msaExecuted: true, dpaExecuted: false, }, // Data residency: must land in the EU. Drives the Nebius block. request: { gpuType: 'H100_80GB', gpuCount: 64, fastFabric: true, maxPriceCents: 260, allowedRegions: ['eu-north', 'eu-west'], certifications: ['ISO 27001', 'SOC 2 Type II'], }, allocation: { supplier: 'nebius.com', share: 0.55, priceCents: 249, status: 'committed', }, }, { account: `${PREFIX}Northwind Robotics`, segment: 'applied_ai_startup' as const, country: 'United States', contact: { name: 'Priya Raghavan', title: 'CTO', decisionMaker: true }, deal: { name: `${PREFIX}Blackwell evaluation → production`, productLine: 'compute_reserved' as const, stage: 'poc' as const, acvCents: 890_000_00, termMonths: 9, msaExecuted: true, dpaExecuted: true, }, request: { gpuType: 'B200', gpuCount: 32, fastFabric: true, maxPriceCents: 460 }, allocation: { supplier: 'crusoe.ai', share: 0.74, priceCents: 441, status: 'active', }, }, { account: `${PREFIX}Tessellate Labs`, segment: 'applied_ai_startup' as const, country: 'United Kingdom', contact: { name: 'Owen Marsh', title: 'Founding Engineer', decisionMaker: false }, deal: { name: `${PREFIX}Inference burst capacity`, productLine: 'inference' as const, stage: 'proposal' as const, acvCents: 145_000_00, termMonths: 3, msaExecuted: false, dpaExecuted: false, }, request: { gpuType: 'A100_80GB', gpuCount: 16, fastFabric: false, maxPriceCents: 175 }, // A HOLD, not a sale. The deal has not closed, so this reserves capacity // without counting as revenue — the distinction the capacity view exists // to make visible. allocation: { supplier: 'runpod.io', share: 0.55, priceCents: 168, status: 'planned', holdDays: 12, }, }, { account: `${PREFIX}Aurelian Systems`, segment: 'enterprise' as const, country: 'United States', contact: { name: 'Meredith Cole', title: 'Director, ML Platform', decisionMaker: true }, deal: { name: `${PREFIX}Multi-year committed capacity`, productLine: 'compute_reserved' as const, stage: 'legal' as const, acvCents: 3_100_000_00, termMonths: 24, msaExecuted: false, dpaExecuted: false, }, request: { gpuType: 'H200', gpuCount: 128, fastFabric: true, maxPriceCents: 265 }, allocation: null, // Still in legal. Nothing reserved yet — correctly. }, { account: `${PREFIX}Quillon AI`, segment: 'applied_ai_startup' as const, country: 'Canada', contact: { name: 'Sofia Trentini', title: 'Head of Research', decisionMaker: true }, deal: { name: `${PREFIX}Evaluation harness pilot`, productLine: 'evaluations' as const, stage: 'qualification' as const, acvCents: 48_000_00, termMonths: 3, msaExecuted: false, dpaExecuted: false, }, request: null, allocation: null, }, ]; async function clear() { console.log('Removing demo data…'); // Ordered so foreign keys never block a delete. const demoAccounts = await db .select({ id: accounts.id }) .from(accounts) .where(like(accounts.name, `${PREFIX}%`)); const ids = demoAccounts.map((a) => a.id); await db.delete(allocations).where(like(allocations.notes, `${PREFIX}%`)); await db.delete(contractObligations); await db.delete(slaTerms); await db.delete(contracts).where(like(contracts.title, `${PREFIX}%`)); await db.delete(capacityRequests); await db.delete(demandDeals).where(like(demandDeals.name, `${PREFIX}%`)); await db.delete(supplyDeals).where(like(supplyDeals.name, `${PREFIX}%`)); await db.delete(capacityCommitments).where(like(capacityCommitments.name, `${PREFIX}%`)); await db.delete(activities).where(like(activities.subject, `${PREFIX}%`)); for (const id of ids) { await db.delete(contacts).where(eq(contacts.accountId, id)); } await db.delete(accounts).where(like(accounts.name, `${PREFIX}%`)); console.log(`Removed ${ids.length} demo account(s) and everything hanging from them.`); } async function seedDemo() { console.log('Seeding the demo book…\n'); // ------------------------------------------------------------ supply side const commitmentIds = new Map(); for (const supplier of SUPPLY) { const [account] = await db .select({ id: accounts.id }) .from(accounts) .where(eq(accounts.domain, supplier.domain)) .limit(1); if (!account) { console.log(` skipped ${supplier.domain} — run the base seed first`); continue; } const [existing] = await db .select({ id: capacityCommitments.id }) .from(capacityCommitments) .where(eq(capacityCommitments.name, supplier.commitment.name)) .limit(1); if (existing) { commitmentIds.set(supplier.domain, existing.id); continue; } const [site] = await db .insert(sites) .values({ accountId: account.id, name: `${PREFIX}${supplier.site.name}`, country: supplier.site.country, countryCode: supplier.site.countryCode, region: supplier.site.region, certifications: supplier.commitment.securityTier === 'community_cloud' ? [] : ['SOC 2 Type II', 'ISO 27001'], }) .returning(); const c = supplier.commitment; const [commitment] = await db .insert(capacityCommitments) .values({ accountId: account.id, siteId: site?.id, name: c.name, gpuType: c.gpuType, socket: c.socket, gpuCount: c.gpuCount, interconnectType: c.interconnectType, securityTier: c.securityTier ?? 'secure_cloud', startsAt: at(-30), endsAt: at(c.days - 30), totalGpuHours: hours(c.gpuCount, c.days), costPerGpuHourCents: c.costPerGpuHourCents, takeOrPayFloorPct: c.takeOrPayFloorPct, prepaidPct: c.prepaidPct, usefulLifeYears: '5', // A ramp: a quarter of the fleet for the first fortnight, then full. // Present so the shape column is exercised by something other than a // rectangle, which is the case it exists for. shape: { intervals: [at(-30).toISOString(), at(-16).toISOString(), at(c.days - 30).toISOString()], quantities: [Math.round(c.gpuCount * 0.25), c.gpuCount], }, notes: 'Illustrative demo data. Not a real contract.', }) .returning(); if (commitment) commitmentIds.set(supplier.domain, commitment.id); // The paper behind it. const [msa] = await db .insert(contracts) .values({ accountId: account.id, type: 'msa', status: 'executed', side: 'supply', title: `${PREFIX}MSA — ${supplier.domain}`, capacityCommitmentId: commitment?.id, effectiveAt: at(-60), expiresAt: at(c.days + 60), isAutoRenew: true, noticeDays: 90, takeOrPayFloorPct: c.takeOrPayFloorPct, prepaidPct: c.prepaidPct, terminationTier: c.prepaidPct !== '0' ? '1_prepaid' : '2_take_or_pay', governingLaw: 'New York', }) .returning(); if (msa) { // A negotiated SLA with fee abatement — the remedy that actually matters // on the supply side, and the one a credits-only model cannot express. const [sla] = await db .insert(contracts) .values({ accountId: account.id, type: 'sla', status: 'executed', side: 'supply', title: `${PREFIX}SLA — ${supplier.domain}`, parentContractId: msa.id, effectiveAt: at(-60), }) .returning(); if (sla) { await db.insert(slaTerms).values({ contractId: sla.id, kind: 'negotiated', uptimeTargetPct: '99.500', measurementUnit: 'node', measurementWindow: 'monthly', remedyType: 'fee_abatement', abatementTriggerValue: 2, abatementTriggerUnit: 'business_days', nodeReplacementHours: 24, claimDeadlineValue: 30, claimDeadlineUnit: 'days', creditCapPct: '50.000', sparePoolObligation: 'Spares held on site sufficient to replace failed nodes and switches.', sparePoolScope: ['compute_nodes', 'network_switches'], rcaDeliveryHours: 72, maintenanceClasses: [ { class: 'planned', noticeValue: 5, noticeUnit: 'business_days', excludedFromUptime: true }, { class: 'emergency', noticeValue: 24, noticeUnit: 'hours', excludedFromUptime: false }, ], }); } await db.insert(contractObligations).values({ contractId: msa.id, title: `${PREFIX}Renewal notice — ${supplier.domain}`, kind: 'renewal_notice', // Deliberately near-term on one supplier so the renewal alarm has // something real to fire on. dueAt: at(supplier.domain === 'nebius.com' ? 21 : 200), description: '90 days notice required to prevent auto-renewal.', }); } await db.insert(supplyDeals).values({ accountId: account.id, siteId: site?.id, name: `${PREFIX}${c.gpuCount}× ${c.gpuType} — ${supplier.domain}`, stage: 'live', gpuType: c.gpuType, gpuCount: c.gpuCount, interconnectType: c.interconnectType, targetCostPerGpuHourCents: c.costPerGpuHourCents, termMonths: Math.round(c.days / 30), technicalVerdict: 'pass', technicalNotes: 'NCCL all-reduce within 8% of theoretical across the full fabric.', financialVerdict: 'pass', financialNotes: `Break-even at ~${Math.round((c.costPerGpuHourCents / 0.75 / 100) * 100) / 100}/GPU-hr at 75% utilisation.`, }); } // A supply deal still in diligence, so that pipeline is not all `live`. const [lambda] = await db .select({ id: accounts.id }) .from(accounts) .where(eq(accounts.domain, 'lambda.ai')) .limit(1); if (lambda) { const LAMBDA_DEAL = `${PREFIX}256× H200 — pricing`; const [existingLambdaDeal] = await db .select({ id: supplyDeals.id }) .from(supplyDeals) .where(and(eq(supplyDeals.accountId, lambda.id), eq(supplyDeals.name, LAMBDA_DEAL))) .limit(1); if (!existingLambdaDeal) { await db.insert(supplyDeals).values({ accountId: lambda.id, name: LAMBDA_DEAL, stage: 'financial_diligence', gpuType: 'H200', gpuCount: 256, interconnectType: 'Infiniband', targetCostPerGpuHourCents: 176, termMonths: 12, technicalVerdict: 'pass', technicalNotes: 'Fabric verified. Storage throughput per GPU is below spec — flagged.', financialNotes: 'Awaiting a firm quote on the committed tranche.', }); } } // ------------------------------------------------------------ demand side for (const d of DEMAND) { const [existingAccount] = await db .select({ id: accounts.id }) .from(accounts) .where(eq(accounts.name, d.account)) .limit(1); if (existingAccount) continue; const [account] = await db .insert(accounts) .values({ name: d.account, side: 'demand', customerSegment: d.segment, country: d.country, description: 'Fictional company, for demonstration only.', source: 'seed', confidence: 'confirmed', lastActivityAt: at(-Math.random() * 10), }) .returning(); if (!account) continue; const [contact] = await db .insert(contacts) .values({ accountId: account.id, fullName: d.contact.name, title: d.contact.title, affiliation: 'staff', isDecisionMaker: d.contact.decisionMaker, confidence: 'confirmed', source: 'seed', email: null, }) .returning(); const [deal] = await db .insert(demandDeals) .values({ accountId: account.id, name: d.deal.name, productLine: d.deal.productLine, stage: d.deal.stage, acvCents: d.deal.acvCents, tcvCents: Math.round((d.deal.acvCents * d.deal.termMonths) / 12), termMonths: d.deal.termMonths, msaExecuted: d.deal.msaExecuted, dpaExecuted: d.deal.dpaExecuted, primaryContactId: contact?.id, expectedCloseDate: at(20 + Math.round(Math.random() * 60)), probability: String( { qualification: 0.1, legal: 0.35, proposal: 0.45, procurement: 0.6, poc: 0.7, deployment: 0.9 }[ d.deal.stage ] ?? 0.5, ), lastActivityAt: at(-Math.random() * 8), }) .returning(); if (!deal) continue; if (d.request) { await db.insert(capacityRequests).values({ demandDealId: deal.id, gpuType: d.request.gpuType, gpuCount: d.request.gpuCount, requiresHighSpeedInterconnect: d.request.fastFabric, minInterconnectType: d.request.fastFabric ? 'Infiniband' : undefined, maxPricePerGpuHourCents: d.request.maxPriceCents, allowedRegions: d.request.allowedRegions ?? [], requiredCertifications: d.request.certifications ?? [], startsAt: at(15), endsAt: at(15 + d.deal.termMonths * 30), totalGpuHours: hours(d.request.gpuCount, d.deal.termMonths * 30, 1), }); } if (d.allocation) { const commitmentId = commitmentIds.get(d.allocation.supplier); if (commitmentId) { const [commitment] = await db .select() .from(capacityCommitments) .where(eq(capacityCommitments.id, commitmentId)) .limit(1); if (commitment) { if (!isAllocationStatus(d.allocation.status)) { throw new Error(`Invalid demo allocation status: ${d.allocation.status}`); } const allocationRow = { capacityCommitmentId: commitmentId, demandDealId: deal.id, gpuHours: String( Math.round(Number(commitment.totalGpuHours) * d.allocation.share), ), pricePerGpuHourCents: d.allocation.priceCents, startsAt: commitment.startsAt, endsAt: commitment.endsAt, status: d.allocation.status, guaranteeType: d.allocation.status === 'planned' ? 'committed' : 'guaranteed', priority: d.allocation.status === 'planned' ? 100 : 10, holdExpiresAt: d.allocation.holdDays ? at(d.allocation.holdDays) : null, notes: d.account, } satisfies NewAllocation; await db.insert(allocations).values(allocationRow); } } } // A little history, so the activity feed is not empty. await db.insert(activities).values([ { type: 'meeting', subject: `${PREFIX}Technical scoping with ${d.contact.name}`, accountId: account.id, demandDealId: deal.id, occurredAt: at(-12), }, { type: 'note', subject: `${PREFIX}${d.deal.stage} — next step agreed`, accountId: account.id, demandDealId: deal.id, occurredAt: at(-3), }, ]); } // Internal research burn against the largest block — real cost, no revenue. const coreweave = commitmentIds.get('coreweave.com'); if (coreweave) { const [commitment] = await db .select() .from(capacityCommitments) .where(eq(capacityCommitments.id, coreweave)) .limit(1); const RESEARCH_NOTE = `${PREFIX}Internal research consumption`; const [existingResearch] = await db .select({ id: allocations.id }) .from(allocations) .where( and( eq(allocations.capacityCommitmentId, coreweave), eq(allocations.notes, RESEARCH_NOTE), ), ) .limit(1); if (commitment && !existingResearch) { const researchAllocationRow = { capacityCommitmentId: coreweave, internalTeam: 'research', gpuHours: String(Math.round(Number(commitment.totalGpuHours) * 0.08)), pricePerGpuHourCents: 0, startsAt: commitment.startsAt, endsAt: commitment.endsAt, status: 'active', guaranteeType: 'internal', priority: 200, notes: RESEARCH_NOTE, } satisfies NewAllocation; await db.insert(allocations).values(researchAllocationRow); } } // -------------------------------------------------- agent-derived facts // // Without these the fact-review queue and every provenance tooltip are // empty, which hides the thing that makes an agent-written CRM trustworthy: // that each claim carries a score, a band, evidence and a source, and that // only verified claims apply themselves. // // The mix is deliberate. Two `applied` facts show what a confident agent // writes unprompted; four `proposed` show what waits for a human; one is a // near-miss that a reviewer should reject, so the queue is not a row of // obvious approvals. const factSeeds: { accountDomain?: string; contactName?: string; field: string; value: string; score: string; band: 'verified' | 'probable' | 'possible'; status: 'applied' | 'proposed'; method: string; sourceUrl?: string; evidence: Record; }[] = [ { accountDomain: 'coreweave.com', field: 'supplierType', value: 'neocloud', score: '0.960', band: 'verified', status: 'applied', method: 'web_search', sourceUrl: 'https://www.coreweave.com/', evidence: { quote: 'Describes itself as an AI hyperscaler providing GPU cloud infrastructure.', corroboration: 2, }, }, { accountDomain: 'nebius.com', field: 'jurisdiction', value: 'European Union', score: '0.910', band: 'verified', status: 'applied', method: 'web_search', sourceUrl: 'https://nebius.com/', evidence: { quote: 'Operates a datacentre in Finland, inside the EU data-residency perimeter.', matters: 'Determines eligibility for customers with EU residency requirements.', }, }, { accountDomain: 'crusoe.ai', field: 'certifications', value: 'SOC 2 Type II', score: '0.720', band: 'probable', status: 'proposed', method: 'web_search', sourceUrl: 'https://crusoe.ai/', evidence: { quote: 'A trust page references SOC 2, but the report scope and observation window are not stated.', caution: 'Scope matters — a report can cover only some products.', }, }, { accountDomain: 'lambda.ai', field: 'supplierType', value: 'neocloud', score: '0.680', band: 'probable', status: 'proposed', method: 'web_search', sourceUrl: 'https://lambda.ai/', evidence: { quote: 'Markets GPU cloud and on-premises clusters.' }, }, { contactName: 'Dana Whitfield', field: 'title', value: 'VP Infrastructure', score: '0.540', band: 'possible', status: 'proposed', method: 'inference', evidence: { reasoning: 'A conference bio lists a VP title; the CRM records Head of Infrastructure.', conflict: 'Sources disagree, and neither is dated.', }, }, { accountDomain: 'runpod.io', field: 'customerSegment', value: 'frontier_lab', score: '0.310', band: 'possible', status: 'proposed', method: 'inference', evidence: { reasoning: 'Inferred from a blog post mentioning large training runs.', warning: 'Weak. This is a supply-side provider, not a frontier lab — a reviewer should reject it.', }, }, ]; let factsAdded = 0; for (const seed of factSeeds) { let accountId: string | undefined; let contactId: string | undefined; if (seed.accountDomain) { const [row] = await db .select({ id: accounts.id }) .from(accounts) .where(eq(accounts.domain, seed.accountDomain)) .limit(1); accountId = row?.id; } if (seed.contactName) { const [row] = await db .select({ id: contacts.id }) .from(contacts) .where(eq(contacts.fullName, seed.contactName)) .limit(1); contactId = row?.id; } if (!accountId && !contactId) continue; // Idempotent on the natural key: one claim per subject per field per value. const [existing] = await db .select({ id: facts.id }) .from(facts) .where( and( accountId ? eq(facts.accountId, accountId) : eq(facts.contactId, contactId!), eq(facts.field, seed.field), eq(facts.value, seed.value), ), ) .limit(1); if (existing) continue; await db.insert(facts).values({ accountId, contactId, field: seed.field, value: seed.value, score: seed.score, band: seed.band, status: seed.status, method: seed.method, sourceUrl: seed.sourceUrl, evidence: seed.evidence, observedAt: at(-Math.round(Math.random() * 6) - 1), }); factsAdded += 1; } console.log(' 4 capacity commitments, with sites, MSAs and negotiated SLAs'); console.log(` ${factSeeds.length} agent-derived facts (${factsAdded} new) — 2 applied, 4 awaiting review`); console.log(' 6 demand deals across the pipeline, 5 supply deals'); console.log(' Allocations including one unconverted hold and internal research burn'); console.log('\nEverything is prefixed "DEMO — ". Remove it with: pnpm db:demo -- --clear'); } const shouldClear = process.argv.includes('--clear'); (shouldClear ? clear() : seedDemo()) .then(() => process.exit(0)) .catch((error) => { console.error('Demo seed failed:', error); process.exit(1); });