Files
AIPortPilot/backend/scripts/seed_demo_data.py
T
selfrelease 947642919b feat(data): 完整演示种子数据脚本 — 22 张表 119 条记录
- 租户:远见资本(VC)
- 用户 7 个:admin/gp/lead/mgr/founder_a/founder_b/founder_c
- 企业 5 家:智链科技/云栈数据/深瞳智能/量子芯微/光合生物
- 覆盖全模型:财务数据/月报/健康度/风险/弱信号/任务/OKR/里程碑/
  协同/决策前哨/助推/重大事项/协议/董事会/BML假设/AAR/团队/人才/审计
- 运行:cd backend && python -m scripts.seed_demo_data
- 登录密码均为 demo123456
2026-07-19 12:05:33 +08:00

638 lines
46 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""演示种子数据 — 按 5 个业务场景生成完整示例数据。
覆盖模型:Tenant / User / Company / MonthlyReport / HealthScore / RiskEvent /
WeakSignal / Task / OKR / MilestoneTree / SynergyOpportunity / DecisionSentinel /
NudgeRecord / MajorEvent / InvestmentAgreement / BoardMeeting / FinancialData /
Hypothesis / AARRecord / TeamMember / TalentProfile / AuditLog。
运行方式:
cd backend && python -m scripts.seed_demo_data
"""
import asyncio
import json
from datetime import datetime, timedelta, timezone
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.database import async_session_factory, engine, Base
from app.core.security import hash_password
from app.models import (
AARRecord, AuditLog, BoardMeeting, Company, FinancialData, HealthScore,
Hypothesis, InvestmentAgreement, MajorEvent, MilestoneTree, MonthlyReport,
NudgeRecord, OKR, RiskEvent, SynergyOpportunity, Task, TalentProfile,
TeamMember, Tenant, User, WeakSignal, DecisionSentinel,
)
UTC = timezone.utc
# ─── 固定 ID(方便跨表引用) ──────────────────────────────────────────
TENANT_ID = "00000000-0000-0000-0000-000000000001"
ADMIN_ID = "00000000-0000-0000-0000-000000000002"
GP_ID = "00000000-0000-0000-0000-000000000003"
LEAD_ID = "00000000-0000-0000-0000-000000000004"
MGR_ID = "00000000-0000-0000-0000-000000000005"
FOUNDER_A = "00000000-0000-0000-0000-000000000006"
FOUNDER_B = "00000000-0000-0000-0000-000000000007"
FOUNDER_C = "00000000-0000-0000-0000-000000000008"
COMP_A = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaa1"
COMP_B = "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbb2"
COMP_C = "cccccccc-cccc-cccc-cccc-ccccccccccc3"
COMP_D = "dddddddd-dddd-dddd-dddd-ddddddddddd4"
COMP_E = "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeee5"
NOW = datetime.now(UTC)
D = lambda days: NOW - timedelta(days=days) # noqa: E731
async def seed() -> None:
"""生成全部演示数据。"""
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.drop_all)
await conn.run_sync(Base.metadata.create_all)
async with async_session_factory() as db:
await _seed_tenant_users(db)
await _seed_companies(db)
await _seed_financial(db)
await _seed_reports(db)
await _seed_health(db)
await _seed_risks(db)
await _seed_weak_signals(db)
await _seed_tasks(db)
await _seed_okrs(db)
await _seed_milestones(db)
await _seed_synergies(db)
await _seed_sentinels(db)
await _seed_nudges(db)
await _seed_events(db)
await _seed_agreements(db)
await _seed_boards(db)
await _seed_hypotheses(db)
await _seed_aars(db)
await _seed_team_members(db)
await _seed_talents(db)
await _seed_audit_logs(db)
await db.commit()
print("✅ 演示数据生成完成")
print(f" 租户: {TENANT_ID}")
print(f" 用户: admin/gp/lead/mgr/founder_a/founder_b/founder_c")
print(f" 企业: 智链科技/云栈数据/深瞳智能/量子芯微/光合生物")
print(" 登录密码均为: demo123456")
# ─── 租户 + 用户 ───────────────────────────────────────────────────────
async def _seed_tenant_users(db: AsyncSession) -> None:
tenant = Tenant(
id=TENANT_ID,
name="远见资本",
type="vc",
config_json={"fund_name": "远见三期", "fund_size": "5亿人民币"},
)
db.add(tenant)
users = [
User(id=ADMIN_ID, tenant_id=TENANT_ID, email="admin@demo.com", password_hash=hash_password("demo123456"), name="系统管理员", role="admin", is_active=True),
User(id=GP_ID, tenant_id=TENANT_ID, email="gp@demo.com", password_hash=hash_password("demo123456"), name="张远见", role="gp", is_active=True),
User(id=LEAD_ID, tenant_id=TENANT_ID, email="lead@demo.com", password_hash=hash_password("demo123456"), name="李投后", role="post_invest_lead", is_active=True),
User(id=MGR_ID, tenant_id=TENANT_ID, email="mgr@demo.com", password_hash=hash_password("demo123456"), name="王经理", role="investor", is_active=True),
User(id=FOUNDER_A, tenant_id=TENANT_ID, email="founder_a@demo.com", password_hash=hash_password("demo123456"), name="陈智链", role="founder", is_active=True),
User(id=FOUNDER_B, tenant_id=TENANT_ID, email="founder_b@demo.com", password_hash=hash_password("demo123456"), name="刘云栈", role="founder", is_active=True),
User(id=FOUNDER_C, tenant_id=TENANT_ID, email="founder_c@demo.com", password_hash=hash_password("demo123456"), name="赵深瞳", role="founder", is_active=True),
]
for u in users:
db.add(u)
await db.flush()
print(" ✓ 租户 + 7 用户")
# ─── 企业 ──────────────────────────────────────────────────────────────
async def _seed_companies(db: AsyncSession) -> None:
companies = [
Company(id=COMP_A, tenant_id=TENANT_ID, name="智链科技有限公司", industry="AI/供应链", stage="b",
description="利用大模型优化供应链决策,服务制造业客户。",
founded_at=datetime(2021, 3, 1, tzinfo=UTC), total_funding="1.2亿人民币", website="https://zhilian.example.com"),
Company(id=COMP_B, tenant_id=TENANT_ID, name="云栈数据科技", industry="AI/数据平台", stage="a",
description="企业级数据治理与 AI 训练数据管理平台。",
founded_at=datetime(2022, 1, 1, tzinfo=UTC), total_funding="5000万人民币", website="https://yunzhan.example.com"),
Company(id=COMP_C, tenant_id=TENANT_ID, name="深瞳智能", industry="AI/计算机视觉", stage="b",
description="工业质检视觉 AI,服务半导体和新能源行业。",
founded_at=datetime(2020, 6, 1, tzinfo=UTC), total_funding="2亿人民币", website="https://shentong.example.com"),
Company(id=COMP_D, tenant_id=TENANT_ID, name="量子芯微电子", industry="芯片/AI算力", stage="seed",
description="AI 推理芯片设计,边缘端低功耗 NPU。",
founded_at=datetime(2023, 9, 1, tzinfo=UTC), total_funding="1500万人民币", website="https://quantumchip.example.com"),
Company(id=COMP_E, tenant_id=TENANT_ID, name="光合生物医疗", industry="AI/医疗", stage="a",
description="AI 辅助药物发现,聚焦小分子靶点筛选。",
founded_at=datetime(2022, 9, 1, tzinfo=UTC), total_funding="8000万人民币", website="https://guanghe.example.com"),
]
for c in companies:
db.add(c)
await db.flush()
print(" ✓ 5 企业")
# ─── 财务数据 ──────────────────────────────────────────────────────────
async def _seed_financial(db: AsyncSession) -> None:
"""每家企业生成近 3 个月利润表 + 现金流。"""
for comp_id, revenue, burn, cash in [
(COMP_A, 800, 350, 4200), # 月营收350万, 消耗120万, 现金4200万
(COMP_B, 150, 120, 1800),
(COMP_C, 1200, 480, 6500),
(COMP_D, 0, 80, 600),
(COMP_E, 80, 200, 2400),
]:
for i in range(3):
y, m = (NOW.year, NOW.month - i) if NOW.month - i > 0 else (NOW.year - 1, 12 + NOW.month - i)
db.add(FinancialData(
company_id=comp_id, period_year=y, period_month=m,
statement_type="income",
data_json={"revenue": revenue, "cogs": int(revenue * 0.4), "gross_profit": int(revenue * 0.6), "opex": burn, "net_income": revenue - burn - int(revenue * 0.4)},
source="monthly_report", credibility_score=85.0 - i * 5,
))
db.add(FinancialData(
company_id=comp_id, period_year=y, period_month=m,
statement_type="cash_flow",
data_json={"operating_cf": revenue - burn, "investing_cf": -50, "financing_cf": 0, "net_cf": revenue - burn - 50, "cash_balance": cash - i * burn},
source="monthly_report", credibility_score=85.0 - i * 5,
))
await db.flush()
print(" ✓ 财务数据 (5 企业 x 3 月)")
# ─── 月报 ──────────────────────────────────────────────────────────────
async def _seed_reports(db: AsyncSession) -> None:
reports = [
# 智链科技 — 已提交 + AI 解析
MonthlyReport(company_id=COMP_A, period_year=NOW.year, period_month=NOW.month - 1 if NOW.month > 1 else 12,
status="ai_parsed", submitted_by=FOUNDER_A, submitted_at=D(10),
raw_content="本月营收800万,环比增长15%。新签客户3家,流失1家。团队新增5人。AI模型推理成本降低12%",
structured_data={"revenue": 800, "mom_growth": 0.15, "new_customers": 3, "churned": 1, "headcount": 45, "ai_cost_reduction": 0.12},
ai_summary="智链科技本月表现良好,营收增长15%,AI推理成本优化显著。客户净增2家,团队扩张至45人。",
ai_concerns=[{"level": "medium", "item": "客户流失率环比上升", "detail": "本月流失1家年合同客户"}, {"level": "low", "item": "现金Runway 12个月", "detail": "按当前消耗速度可维持12个月"}]),
# 云栈数据 — 已提交
MonthlyReport(company_id=COMP_B, period_year=NOW.year, period_month=NOW.month - 1 if NOW.month > 1 else 12,
status="ai_parsed", submitted_by=FOUNDER_B, submitted_at=D(8),
raw_content="本月营收150万,环比持平。完成数据治理平台v2.0发布。新签1家金融客户。",
structured_data={"revenue": 150, "mom_growth": 0.0, "new_customers": 1, "churned": 0, "headcount": 22},
ai_summary="云栈数据营收持平,产品迭代正常。金融客户拓展是亮点。",
ai_concerns=[{"level": "high", "item": "营收增长停滞", "detail": "连续2个月环比0%增长"}, {"level": "medium", "item": "现金Runway 15个月", "detail": "需关注融资节奏"}]),
# 深瞳智能 — 已提交
MonthlyReport(company_id=COMP_C, period_year=NOW.year, period_month=NOW.month - 1 if NOW.month > 1 else 12,
status="reviewed", submitted_by=FOUNDER_C, submitted_at=D(12), reviewed_by=MGR_ID, reviewed_at=D(5),
raw_content="本月营收1200万,环比增长22%。半导体客户占比提升至60%。新增专利2项。",
structured_data={"revenue": 1200, "mom_growth": 0.22, "new_customers": 2, "churned": 0, "headcount": 68, "patents": 2},
ai_summary="深瞳智能强劲增长,半导体行业渗透加深。专利积累构建技术壁垒。",
ai_concerns=[{"level": "low", "item": "客户集中度风险", "detail": "半导体行业占比60%"}]),
# 量子芯微 — 草稿
MonthlyReport(company_id=COMP_D, period_year=NOW.year, period_month=NOW.month - 1 if NOW.month > 1 else 12,
status="draft", submitted_by=None,
raw_content="", structured_data=None, ai_summary=None, ai_concerns=None),
# 光合生物 — 延迟提交
MonthlyReport(company_id=COMP_E, period_year=NOW.year, period_month=NOW.month - 2 if NOW.month > 2 else 11,
status="ai_parsed", submitted_by=FOUNDER_A, submitted_at=D(40),
raw_content="本月营收80万,来自2个合作药企里程碑付款。研发进展:3个靶点进入先导化合物阶段。",
structured_data={"revenue": 80, "milestone_payment": 80, "targets": 3, "headcount": 18},
ai_summary="光合生物收入来自里程碑付款,研发管线推进正常。",
ai_concerns=[{"level": "high", "item": "月报延迟提交", "detail": "延迟20天"}, {"level": "medium", "item": "现金消耗快", "detail": "月消耗200万,Runway 12月"}]),
]
for r in reports:
db.add(r)
await db.flush()
print(" ✓ 月报 (5 份)")
# ─── 健康度评分 ────────────────────────────────────────────────────────
async def _seed_health(db: AsyncSession) -> None:
scores = [
# 智链科技 — 良好
HealthScore(company_id=COMP_A, total_score=78.5, financial_score=82, operational_score=75, ai_commercial_score=80, ai_cost_score=85,
org_talent_score=72, product_tech_score=80, market_compete_score=78, governance_score=75, financing_score=80,
trend="up", evidence_json={"financial": "营收增长15%,现金流健康", "ai_cost": "推理成本降低12%"},
recommendations_json={"action": "关注客户流失率", "owner": MGR_ID, "review_at": D(-30).isoformat()}),
# 云栈数据 — 中等
HealthScore(company_id=COMP_B, total_score=62.0, financial_score=55, operational_score=68, ai_commercial_score=60, ai_cost_score=65,
org_talent_score=70, product_tech_score=72, market_compete_score=58, governance_score=65, financing_score=50,
trend="stable", evidence_json={"financial": "营收持平,需突破", "financing": "Runway 15月,需启动融资"},
recommendations_json={"action": "加速融资节奏", "owner": LEAD_ID, "review_at": D(-14).isoformat()}),
# 深瞳智能 — 优秀
HealthScore(company_id=COMP_C, total_score=85.5, financial_score=88, operational_score=85, ai_commercial_score=90, ai_cost_score=82,
org_talent_score=83, product_tech_score=88, market_compete_score=86, governance_score=82, financing_score=85,
trend="up", evidence_json={"financial": "营收增长22%", "market": "半导体渗透加深"},
recommendations_json={"action": "关注客户集中度", "owner": MGR_ID, "review_at": D(-30).isoformat()}),
# 量子芯微 — 早期风险
HealthScore(company_id=COMP_D, total_score=48.0, financial_score=35, operational_score=50, ai_commercial_score=45, ai_cost_score=55,
org_talent_score=52, product_tech_score=60, market_compete_score=42, governance_score=55, financing_score=40,
trend="down", evidence_json={"financial": "无营收,现金紧张", "financing": "Runway 7月"},
recommendations_json={"action": "紧急启动天使+轮融资", "owner": GP_ID, "review_at": D(-7).isoformat()}),
# 光合生物 — 中等偏上
HealthScore(company_id=COMP_E, total_score=68.5, financial_score=60, operational_score=72, ai_commercial_score=70, ai_cost_score=65,
org_talent_score=68, product_tech_score=75, market_compete_score=65, governance_score=70, financing_score=62,
trend="stable", evidence_json={"financial": "里程碑收入稳定", "product": "3靶点推进中"},
recommendations_json={"action": "月报提交及时性改善", "owner": MGR_ID, "review_at": D(-30).isoformat()}),
]
for s in scores:
s.calculated_at = D(5)
db.add(s)
await db.flush()
print(" ✓ 健康度评分 (5 企业)")
# ─── 风险事件 ──────────────────────────────────────────────────────────
async def _seed_risks(db: AsyncSession) -> None:
risks = [
RiskEvent(company_id=COMP_A, type="operational", severity="medium", status="in_progress",
title="客户流失率环比上升", description="本月流失1家年合同客户,流失率从2%升至4%",
evidence_json={"metric": "churn_rate", "current": 0.04, "previous": 0.02, "threshold": 0.03},
suggested_action="联系流失客户了解原因,加强客户成功团队", assigned_to=MGR_ID, due_at=D(-7)),
RiskEvent(company_id=COMP_B, type="financial", severity="high", status="assigned",
title="营收增长停滞", description="连续2个月环比0%增长,未达预期",
evidence_json={"metric": "revenue_growth", "current": 0.0, "expected": 0.15, "months": 2},
suggested_action="与创始人讨论增长策略,评估产品定价和市场拓展", assigned_to=LEAD_ID, due_at=D(-3)),
RiskEvent(company_id=COMP_D, type="financial", severity="critical", status="open",
title="现金Runway不足7个月", description="按当前消耗速度,现金仅可维持7个月",
evidence_json={"metric": "runway_months", "current": 7, "threshold": 9},
suggested_action="紧急启动天使+轮融资,准备BP和财务预测", assigned_to=GP_ID, due_at=D(-14)),
RiskEvent(company_id=COMP_E, type="operational", severity="medium", status="resolved",
title="月报延迟提交", description="上月月报延迟20天提交",
evidence_json={"metric": "report_delay_days", "current": 20, "threshold": 5},
suggested_action="与创始人沟通提交规范,设置自动提醒", assigned_to=MGR_ID, due_at=D(-10), closed_at=D(-3)),
RiskEvent(company_id=COMP_C, type="org", severity="low", status="open",
title="核心技术人员稳定性下降", description="CTO提及外部机会,稳定性评分从0.85降至0.65",
evidence_json={"metric": "cto_stability", "current": 0.65, "previous": 0.85},
suggested_action="了解CTO诉求,评估股权激励调整", assigned_to=LEAD_ID),
RiskEvent(company_id=COMP_A, type="ai_specific", severity="low", status="closed",
title="AI模型推理成本超标", description="上月推理成本占营收比12%,超10%阈值",
evidence_json={"metric": "ai_cost_ratio", "current": 0.12, "threshold": 0.10},
suggested_action="优化模型量化策略", assigned_to=MGR_ID, closed_at=D(-5)),
]
for r in risks:
r.identified_at = D(15)
db.add(r)
await db.flush()
print(" ✓ 风险事件 (6 条)")
# ─── 弱信号 ────────────────────────────────────────────────────────────
async def _seed_weak_signals(db: AsyncSession) -> None:
signals = [
WeakSignal(company_id=COMP_B, signal_type="market", source="行业论坛", content="竞品发布类似数据治理产品,定价低30%",
confidence=0.72, risk_probability=0.65, status="alerted",
correlation_result={"related_signals": 2, "pattern": "竞品压力增加"}),
WeakSignal(company_id=COMP_C, signal_type="org", source="LinkedIn", content="CTO 更新简历,标注'开放看机会'",
confidence=0.85, risk_probability=0.78, status="alerted",
correlation_result={"related_signals": 1, "pattern": "核心人员流失风险"}),
WeakSignal(company_id=COMP_D, signal_type="technical", source="GitHub", content="核心开源依赖库停止维护,需迁移",
confidence=0.68, risk_probability=0.45, status="correlated"),
WeakSignal(company_id=COMP_A, signal_type="sentiment", source="客户反馈", content="大客户提及预算削减计划",
confidence=0.60, risk_probability=0.55, status="new"),
WeakSignal(company_id=COMP_E, signal_type="market", source="FDA新闻", content="同类靶点药物获FDA快速审批",
confidence=0.75, risk_probability=0.30, status="new"),
]
for s in signals:
s.detected_at = D(7)
db.add(s)
await db.flush()
print(" ✓ 弱信号 (5 条)")
# ─── 任务 ──────────────────────────────────────────────────────────────
async def _seed_tasks(db: AsyncSession) -> None:
tasks = [
Task(tenant_id=TENANT_ID, company_id=COMP_A, title="联系流失客户进行回访", description="了解客户流失原因,制定挽留方案",
status="in_progress", priority="high", assigned_to=MGR_ID, source_type="risk", due_at=D(-3)),
Task(tenant_id=TENANT_ID, company_id=COMP_B, title="与云栈数据创始人讨论增长策略", description="评估产品定价和市场拓展方案",
status="todo", priority="high", assigned_to=LEAD_ID, source_type="risk", due_at=D(-1)),
Task(tenant_id=TENANT_ID, company_id=COMP_D, title="准备天使+轮BP", description="包含财务预测和产品路线图",
status="todo", priority="urgent", assigned_to=GP_ID, source_type="risk", due_at=D(-14)),
Task(tenant_id=TENANT_ID, company_id=COMP_C, title="评估CTO股权激励调整方案", description="了解CTO诉求,设计retention package",
status="todo", priority="medium", assigned_to=LEAD_ID, source_type="manual", due_at=D(-7)),
Task(tenant_id=TENANT_ID, company_id=COMP_A, title="审阅智链科技本月月报", description="关注AI成本降低和客户流失",
status="done", priority="medium", assigned_to=MGR_ID, source_type="report", completed_at=D(-3)),
Task(tenant_id=TENANT_ID, company_id=COMP_E, title="跟进光合生物月报提交及时性", description="设置自动提醒,沟通提交规范",
status="done", priority="medium", assigned_to=MGR_ID, source_type="manual", completed_at=D(-2)),
]
for t in tasks:
db.add(t)
await db.flush()
print(" ✓ 任务 (6 条)")
# ─── OKR ───────────────────────────────────────────────────────────────
async def _seed_okrs(db: AsyncSession) -> None:
okrs = [
OKR(company_id=COMP_A, quarter=f"{NOW.year}-Q{(NOW.month - 1) // 3 + 1}",
objective="实现季度营收3000万,客户净增8家",
key_results=[{"kr": "季度营收达3000万", "current": 2400, "target": 3000, "progress": 0.80},
{"kr": "新签客户8家", "current": 5, "target": 8, "progress": 0.625},
{"kr": "客户流失率<3%", "current": 0.04, "target": 0.03, "progress": 0.75}],
alignment_score=82.0, status="active",
deviation_alerts=[{"kr": "客户流失率", "current": "4%", "target": "<3%", "severity": "medium"}]),
OKR(company_id=COMP_B, quarter=f"{NOW.year}-Q{(NOW.month - 1) // 3 + 1}",
objective="完成A+轮融资,营收突破500万/月",
key_results=[{"kr": "月营收达500万", "current": 150, "target": 500, "progress": 0.30},
{"kr": "完成A+轮融资", "current": 0, "target": 1, "progress": 0.0},
{"kr": "签约3家金融客户", "current": 1, "target": 3, "progress": 0.33}],
alignment_score=55.0, status="active",
deviation_alerts=[{"kr": "月营收", "current": "150万", "target": "500万", "severity": "high"},
{"kr": "融资进度", "current": "未启动", "target": "完成", "severity": "high"}]),
OKR(company_id=COMP_C, quarter=f"{NOW.year}-Q{(NOW.month - 1) // 3 + 1}",
objective="半导体行业营收占比70%,新增专利5项",
key_results=[{"kr": "半导体营收占比70%", "current": 0.60, "target": 0.70, "progress": 0.857},
{"kr": "新增专利5项", "current": 2, "target": 5, "progress": 0.40}],
alignment_score=88.0, status="active", deviation_alerts=[]),
]
for o in okrs:
db.add(o)
await db.flush()
print(" ✓ OKR (3 条)")
# ─── 里程碑 ────────────────────────────────────────────────────────────
async def _seed_milestones(db: AsyncSession) -> None:
# 智链科技里程碑树
m1 = MilestoneTree(company_id=COMP_A, name="B轮融资", is_current=True, status="in_progress", target_date=D(-90), description="B轮1亿人民币,估值8亿")
db.add(m1); await db.flush()
m2 = MilestoneTree(company_id=COMP_A, name="产品v3.0发布", parent_id=m1.id, is_current=True, status="completed", actual_date=D(-20), description="多模态供应链决策引擎")
m3 = MilestoneTree(company_id=COMP_A, name="客户数突破50", parent_id=m1.id, is_current=True, status="in_progress", target_date=D(-60))
m4 = MilestoneTree(company_id=COMP_A, name="海外市场拓展", parent_id=m1.id, is_current=False, status="planned", target_date=D(-180), description="东南亚试点 — 备选路径",
ai_analysis={"risk": "海外合规成本高", "opportunity": "市场先发优势"})
for m in [m2, m3, m4]:
db.add(m)
# 云栈数据里程碑
m5 = MilestoneTree(company_id=COMP_B, name="A+轮融资", is_current=True, status="in_progress", target_date=D(-45), description="A+轮3000万人民币")
db.add(m5); await db.flush()
m6 = MilestoneTree(company_id=COMP_B, name="数据治理平台v2.0", parent_id=m5.id, is_current=True, status="completed", actual_date=D(-10))
m7 = MilestoneTree(company_id=COMP_B, name="金融行业突破", parent_id=m5.id, is_current=True, status="in_progress", target_date=D(-30))
for m in [m6, m7]:
db.add(m)
await db.flush()
print(" ✓ 里程碑 (7 节点)")
# ─── 协同机会 ──────────────────────────────────────────────────────────
async def _seed_synergies(db: AsyncSession) -> None:
synergies = [
SynergyOpportunity(tenant_id=TENANT_ID, type="customer", company_a_id=COMP_A, company_b_id=COMP_C,
title="智链科技 → 深瞳智能:制造业客户共享",
description="智链科技的3家制造业客户有质检需求,可引荐深瞳智能。",
match_reason="AI分析:客户行业重叠度高,需求互补",
status="confirmed", authorized=True),
SynergyOpportunity(tenant_id=TENANT_ID, type="tech", company_a_id=COMP_B, company_b_id=COMP_D,
title="云栈数据 → 量子芯微:数据平台支持芯片设计仿真",
description="云栈数据平台可处理量子芯微的仿真数据集。",
match_reason="技术栈匹配,数据平台可降低芯片仿真IT成本40%",
status="discovered", authorized=False),
SynergyOpportunity(tenant_id=TENANT_ID, type="talent", company_a_id=COMP_C, company_b_id=COMP_E,
title="深瞳智能 → 光合生物:AI算法人才推荐",
description="深瞳智能有CV算法人才储备,光合生物需AI药物筛选算法工程师。",
match_reason="技能匹配度85%,工作地点同城",
status="executing", authorized=True,
effect_result={"candidates_referred": 3, "interviewed": 2, "offered": 1}),
]
for s in synergies:
db.add(s)
await db.flush()
print(" ✓ 协同机会 (3 条)")
# ─── 决策前哨 ──────────────────────────────────────────────────────────
async def _seed_sentinels(db: AsyncSession) -> None:
sentinels = [
DecisionSentinel(company_id=COMP_B, decision_type="funding",
title="A+轮融资时机选择:现在 vs 等待产品验证",
description="营收增长停滞,但产品v2.0刚发布。是否现在融资还是等Q2数据验证后融资?",
signals=[{"source": "月报", "signal": "营收停滞2月"}, {"source": "市场", "signal": "竞品定价低30%"}],
scenarios={"A": {"name": "现在融资", "pros": "现金充裕", "cons": "估值可能偏低", "probability": 0.6},
"B": {"name": "等待Q2验证", "pros": "估值更高", "cons": "现金Runway风险", "probability": 0.4}},
status="analyzed"),
DecisionSentinel(company_id=COMP_C, decision_type="hiring",
title="CTO retention:股权激励 vs 替换",
description="CTO稳定性下降,需决定加大股权激励还是提前寻找替代者。",
signals=[{"source": "LinkedIn", "signal": "CTO更新简历"}, {"source": "弱信号", "signal": "稳定性评分0.65"}],
scenarios={"A": {"name": "加大股权激励", "pros": "保留技术连续性", "cons": "股权稀释", "probability": 0.7},
"B": {"name": "启动替换搜索", "pros": "降低单点风险", "cons": "过渡期风险", "probability": 0.3}},
status="identified"),
DecisionSentinel(company_id=COMP_D, decision_type="funding",
title="天使+轮 vs Pre-A:融资策略选择",
description="现金Runway 7月,需快速融资。天使+轮快但金额小,Pre-A慢但可支撑更长。",
signals=[{"source": "财务", "signal": "Runway 7月"}, {"source": "产品", "signal": "NPU原型流片在即"}],
scenarios={"A": {"name": "天使+轮 1500万", "pros": "3个月内close", "cons": "只够6月", "probability": 0.55},
"B": {"name": "Pre-A 5000万", "pros": "支撑18月", "cons": "需6月", "probability": 0.45}},
status="acted"),
]
for s in sentinels:
s.identified_at = D(10)
db.add(s)
await db.flush()
print(" ✓ 决策前哨 (3 条)")
# ─── 行为助推 ──────────────────────────────────────────────────────────
async def _seed_nudges(db: AsyncSession) -> None:
nudges = [
NudgeRecord(company_id=COMP_A, nudge_type="anchoring",
context="月报审阅 — 客户流失率",
message="同类AI供应链企业平均客户流失率为2.5%,智链科技本月4%高于基准。",
target_user_id=MGR_ID, accepted=True,
effect_result={"action": "联系流失客户", "result": "挽留1家"}),
NudgeRecord(company_id=COMP_B, nudge_type="loss_aversion",
context="融资时机提醒",
message="如果不启动A+轮融资,预计6个月后现金耗尽,错失产品验证窗口。",
target_user_id=LEAD_ID, accepted=True,
effect_result={"action": "约见创始人讨论融资", "result": "启动BP准备"}),
NudgeRecord(company_id=COMP_D, nudge_type="social_proof",
context="融资策略",
message="Portfolio中3家类似阶段企业选择了Pre-A路线,平均估值高于天使+轮2倍。",
target_user_id=GP_ID, accepted=False,
effect_result={"action": "选择天使+轮", "result": "快速close"}),
NudgeRecord(company_id=COMP_C, nudge_type="timing",
context="CTO稳定性",
message="融资前是关键人才挽留的最佳时机,建议在B+轮前完成CTO股权激励调整。",
target_user_id=LEAD_ID, accepted=True,
effect_result={"action": "设计retention package", "result": "进行中"}),
]
for n in nudges:
db.add(n)
await db.flush()
print(" ✓ 行为助推 (4 条)")
# ─── 重大事项 ──────────────────────────────────────────────────────────
async def _seed_events(db: AsyncSession) -> None:
events = [
MajorEvent(company_id=COMP_A, event_type="product", title="产品v3.0多模态引擎发布", severity="high",
description="支持文本+图像+时序数据的多模态供应链决策引擎上线",
source="monthly_report", status="addressed", occurred_at=D(20)),
MajorEvent(company_id=COMP_C, event_type="personnel", title="CTO更新简历", severity="high",
description="CTO在LinkedIn更新简历,标注'开放看机会'",
source="weak_signal", status="confirmed", occurred_at=D(7)),
MajorEvent(company_id=COMP_D, event_type="funding", title="天使+轮融资启动", severity="critical",
description="现金Runway不足7月,启动天使+轮融资",
source="manual", status="addressed", occurred_at=D(3)),
MajorEvent(company_id=COMP_E, event_type="product", title="3个靶点进入先导化合物阶段", severity="medium",
description="AI药物筛选管线推进,3个靶点通过虚拟筛选进入实验验证",
source="monthly_report", status="confirmed", occurred_at=D(15)),
]
for e in events:
db.add(e)
await db.flush()
print(" ✓ 重大事项 (4 条)")
# ─── 投资协议 ──────────────────────────────────────────────────────────
async def _seed_agreements(db: AsyncSession) -> None:
agreements = [
InvestmentAgreement(company_id=COMP_A, title="B轮投资协议", signed_at=datetime(2023, 6, 1, tzinfo=UTC),
key_clauses={"valuation": "8亿人民币", "investment": "1亿", "board_seat": "1席", "anti_dilution": "加权平均", "liquidation_pref": "1x非参与"},
monitoring_rules=[{"clause": "反稀释", "trigger": "下一轮估值低于8亿", "action": "通知GP"}],
status="active"),
InvestmentAgreement(company_id=COMP_B, title="A轮投资协议", signed_at=datetime(2023, 3, 1, tzinfo=UTC),
key_clauses={"valuation": "3亿", "investment": "5000万", "board_seat": "1席", "redemption_right": "5年后可要求回购"},
monitoring_rules=[{"clause": "回购权", "trigger": "2028-03-01", "action": "提前6月提醒"}],
status="active"),
InvestmentAgreement(company_id=COMP_C, title="B轮投资协议", signed_at=datetime(2022, 12, 1, tzinfo=UTC),
key_clauses={"valuation": "10亿", "investment": "2亿", "board_seat": "1席", "info_rights": "月报+季度财务"},
monitoring_rules=[{"clause": "信息权", "trigger": "月报延迟>5天", "action": "通知投后负责人"}],
status="active"),
]
for a in agreements:
db.add(a)
await db.flush()
print(" ✓ 投资协议 (3 份)")
# ─── 董事会 ────────────────────────────────────────────────────────────
async def _seed_boards(db: AsyncSession) -> None:
boards = [
BoardMeeting(company_id=COMP_A, title="2025年Q2董事会", meeting_at=D(-7), status="scheduled",
agenda=[{"item": "Q2经营汇报", "duration": "30min"}, {"item": "B轮融资进展", "duration": "20min"}, {"item": "客户流失分析", "duration": "15min"}],
materials_summary="AI摘要:Q2营收2400万(完成80%),客户净增5家但流失率上升,B轮估值预期8-10亿。",
questions=[{"q": "客户流失率上升的原因是什么?", "priority": "high"}, {"q": "B轮预计何时close", "priority": "medium"}]),
BoardMeeting(company_id=COMP_C, title="2025年Q2董事会", meeting_at=D(-14), status="completed",
agenda=[{"item": "Q2经营汇报", "duration": "30min"}, {"item": "半导体行业拓展", "duration": "20min"}],
minutes="Q2营收3600万超预期,半导体占比60%。专利新增2项。CTO稳定性需关注。",
resolutions=[{"item": "批准CTO股权激励调整方案", "status": "执行中"}, {"item": "Q3启动半导体行业专项销售", "status": "已启动"}]),
]
for b in boards:
db.add(b)
await db.flush()
print(" ✓ 董事会 (2 场)")
# ─── BML 假设 ──────────────────────────────────────────────────────────
async def _seed_hypotheses(db: AsyncSession) -> None:
hypotheses = [
Hypothesis(company_id=COMP_A, hypothesis="降低定价10%可提升客户签约率30%",
experiment="对3家潜在客户提供10%折扣试用",
data={"customers_tested": 3, "signed": 2, "conversion_rate": 0.67},
conclusion="部分验证:签约率提升67%(超预期30%),但需观察折扣结束后续约率",
status="validated"),
Hypothesis(company_id=COMP_B, hypothesis="金融行业客户愿意为数据合规功能支付20%溢价",
experiment="向2家金融客户展示合规模块并报价溢价20%",
data={"customers_tested": 2, "interested": 1, "signed": 0},
conclusion="待验证:1家表示感兴趣但需内部审批,尚未签约",
status="measuring"),
Hypothesis(company_id=COMP_C, hypothesis="半导体客户对边缘端质检需求年增长50%",
experiment="调研5家半导体客户未来12月质检预算",
data={"surveyed": 3, "budget_increase_avg": 0.35},
conclusion="未达预期:平均预算增长35%低于50%假设,但基础需求强劲",
status="learning"),
]
for h in hypotheses:
db.add(h)
await db.flush()
print(" ✓ BML 假设 (3 条)")
# ─── AAR 复盘 ──────────────────────────────────────────────────────────
async def _seed_aars(db: AsyncSession) -> None:
aars = [
AARRecord(company_id=COMP_A, trigger_event="Q1客户流失率升至4%",
original_plan="Q1客户流失率控制在2%以内",
actual_result="Q1流失率4%,流失2家年合同客户",
gap_analysis="客户成功团队响应延迟,流失客户反馈'技术支持不够及时'。竞品以低价策略抢客。",
lessons={"what_expected": "流失率2%", "what_happened": "4%", "why_gap": "客户成功人手不足+竞品低价", "what_learned": "需主动客户健康度监控", "what_to_change": "增加客户成功HC,建立预警机制"},
improvements=[{"action": "增加2名客户成功经理", "status": "已完成", "owner": "创始人"}, {"action": "建立客户健康度周报", "status": "进行中", "owner": "投资经理"}]),
AARRecord(company_id=COMP_C, trigger_event="CTO稳定性下降",
original_plan="核心技术团队稳定,无关键人员流失",
actual_result="CTO更新简历,稳定性评分0.65",
gap_analysis="CTO反馈股权激励不足,技术路线存在分歧。",
lessons={"what_expected": "CTO长期稳定", "what_happened": "稳定性下降", "why_gap": "股权激励未随估值增长调整", "what_learned": "关键人才激励需动态调整", "what_to_change": "建立定期激励review机制"},
improvements=[{"action": "CTO股权激励调整方案", "status": "设计中", "owner": "投后负责人"}]),
]
for a in aars:
db.add(a)
await db.flush()
print(" ✓ AAR 复盘 (2 条)")
# ─── 团队成员 ──────────────────────────────────────────────────────────
async def _seed_team_members(db: AsyncSession) -> None:
members = [
TeamMember(company_id=COMP_A, name="陈智链", role="CEO/创始人", is_key_person=True, joined_at=datetime(2021, 3, 1, tzinfo=UTC), stability_score=0.92),
TeamMember(company_id=COMP_A, name="张技术", role="CTO", is_key_person=True, joined_at=datetime(2021, 4, 1, tzinfo=UTC), stability_score=0.85),
TeamMember(company_id=COMP_A, name="李销售", role="VP销售", is_key_person=True, joined_at=datetime(2022, 1, 1, tzinfo=UTC), stability_score=0.80),
TeamMember(company_id=COMP_C, name="赵深瞳", role="CEO/创始人", is_key_person=True, joined_at=datetime(2020, 6, 1, tzinfo=UTC), stability_score=0.90),
TeamMember(company_id=COMP_C, name="孙算法", role="CTO", is_key_person=True, joined_at=datetime(2020, 7, 1, tzinfo=UTC), stability_score=0.65),
TeamMember(company_id=COMP_C, name="周产品", role="产品总监", is_key_person=False, joined_at=datetime(2021, 3, 1, tzinfo=UTC), stability_score=0.78),
TeamMember(company_id=COMP_B, name="刘云栈", role="CEO/创始人", is_key_person=True, joined_at=datetime(2022, 1, 1, tzinfo=UTC), stability_score=0.88),
]
for m in members:
db.add(m)
await db.flush()
print(" ✓ 团队成员 (7 人)")
# ─── 人才画像 ──────────────────────────────────────────────────────────
async def _seed_talents(db: AsyncSession) -> None:
talents = [
TalentProfile(tenant_id=TENANT_ID, name="孙算法", current_role="CTO", current_company="深瞳智能",
skills=["计算机视觉", "PyTorch", "团队管理", "边缘计算"], experience_years=12,
performance_rating=4.5, potential_rating=4.0, nine_box="star",
flow_prediction={"probability": 0.65, "timeline": "3-6月", "triggers": ["股权激励不足", "技术路线分歧"]},
status="active"),
TalentProfile(tenant_id=TENANT_ID, name="李销售", current_role="VP销售", current_company="智链科技",
skills=["B2B销售", "制造业客户", "团队管理"], experience_years=10,
performance_rating=4.2, potential_rating=3.8, nine_box="high_potential",
flow_prediction={"probability": 0.20, "timeline": "12月+", "triggers": []},
status="active"),
TalentProfile(tenant_id=TENANT_ID, name="吴架构", current_role="首席架构师", current_company="云栈数据",
skills=["分布式系统", "数据治理", "Kubernetes"], experience_years=15,
performance_rating=4.8, potential_rating=4.5, nine_box="star",
flow_prediction={"probability": 0.15, "timeline": "稳定", "triggers": []},
status="active"),
]
for t in talents:
db.add(t)
await db.flush()
print(" ✓ 人才画像 (3 人)")
# ─── 审计日志 ──────────────────────────────────────────────────────────
async def _seed_audit_logs(db: AsyncSession) -> None:
logs = [
AuditLog(tenant_id=TENANT_ID, user_id=MGR_ID, action="login", resource_type="auth", ip="192.168.1.100", created_at=D(0)),
AuditLog(tenant_id=TENANT_ID, user_id=MGR_ID, action="view", resource_type="company", resource_id=COMP_A, ip="192.168.1.100", created_at=D(0)),
AuditLog(tenant_id=TENANT_ID, user_id=MGR_ID, action="view", resource_type="report", resource_id="report_001", ip="192.168.1.100", created_at=D(0)),
AuditLog(tenant_id=TENANT_ID, user_id=LEAD_ID, action="view", resource_type="risk", resource_id="risk_001", ip="192.168.1.101", created_at=D(1)),
AuditLog(tenant_id=TENANT_ID, user_id=LEAD_ID, action="update", resource_type="risk", resource_id="risk_001", detail_json={"field": "status", "old": "open", "new": "assigned"}, ip="192.168.1.101", created_at=D(1)),
AuditLog(tenant_id=TENANT_ID, user_id=GP_ID, action="view", resource_type="dashboard", ip="192.168.1.102", created_at=D(2)),
AuditLog(tenant_id=TENANT_ID, user_id=GP_ID, action="ai_call", resource_type="weekly_brief", detail_json={"tokens": 3500, "model": "qwen-max"}, ip="192.168.1.102", created_at=D(2)),
AuditLog(tenant_id=TENANT_ID, user_id=ADMIN_ID, action="view", resource_type="audit_logs", ip="192.168.1.103", created_at=D(3)),
AuditLog(tenant_id=TENANT_ID, user_id=FOUNDER_A, action="create", resource_type="monthly_report", detail_json={"company": "智链科技", "period": f"{NOW.year}-{NOW.month-1}"}, ip="10.0.0.50", created_at=D(10)),
AuditLog(tenant_id=TENANT_ID, user_id=FOUNDER_B, action="create", resource_type="monthly_report", detail_json={"company": "云栈数据", "period": f"{NOW.year}-{NOW.month-1}"}, ip="10.0.0.51", created_at=D(8)),
]
for l in logs:
db.add(l)
await db.flush()
print(" ✓ 审计日志 (10 条)")
if __name__ == "__main__":
asyncio.run(seed())