diff --git a/backend/app/routers/dashboard.py b/backend/app/routers/dashboard.py index 4f3590f..0c72a48 100644 --- a/backend/app/routers/dashboard.py +++ b/backend/app/routers/dashboard.py @@ -80,17 +80,28 @@ async def get_dashboard_summary( pending_result = await db.execute(pending_query) pending_reports = pending_result.scalar_one() - # 最近评分(最多 10 条) + # 最近评分 — 每家企业只取最新一条(避免历史数据导致企业重复) + subq = ( + select( + HealthScore.company_id, + func.max(HealthScore.calculated_at).label("max_at"), + ) + .join(Company, HealthScore.company_id == Company.id) + .where(Company.tenant_id == tenant_id) + .group_by(HealthScore.company_id) + ) + if company_id: + subq = subq.where(HealthScore.company_id == company_id) + subq = subq.subquery() + recent_query = ( select(HealthScore, Company.name.label("company_name")) .join(Company, HealthScore.company_id == Company.id) - .where(Company.tenant_id == tenant_id) - ) - if company_id: - recent_query = recent_query.where(HealthScore.company_id == company_id) - recent_result = await db.execute( - recent_query.order_by(HealthScore.calculated_at.desc()).limit(10) + .join(subq, (HealthScore.company_id == subq.c.company_id) & (HealthScore.calculated_at == subq.c.max_at)) + .order_by(HealthScore.calculated_at.desc()) + .limit(10) ) + recent_result = await db.execute(recent_query) recent_rows = recent_result.all() recent_scores = [] for row in recent_rows: @@ -118,16 +129,27 @@ async def list_health_scores( db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user), ): - """获取健康度评分列表。""" + """获取健康度评分列表 — 每家企业只返回最新一条。""" + subq = ( + select( + HealthScore.company_id, + func.max(HealthScore.calculated_at).label("max_at"), + ) + .join(Company, HealthScore.company_id == Company.id) + .where(Company.tenant_id == user.tenant_id) + .group_by(HealthScore.company_id) + ) + if company_id: + subq = subq.where(HealthScore.company_id == company_id) + subq = subq.subquery() + query = ( select(HealthScore, Company.name.label("company_name")) .join(Company, HealthScore.company_id == Company.id) - .where(Company.tenant_id == user.tenant_id) + .join(subq, (HealthScore.company_id == subq.c.company_id) & (HealthScore.calculated_at == subq.c.max_at)) + .order_by(HealthScore.calculated_at.desc()) + .limit(limit) ) - if company_id: - query = query.where(HealthScore.company_id == company_id) - - query = query.order_by(HealthScore.calculated_at.desc()).limit(limit) result = await db.execute(query) scores = [] for row in result.all(): diff --git a/backend/scripts/seed_demo_data.py b/backend/scripts/seed_demo_data.py index 4e6d762..6c42f49 100644 --- a/backend/scripts/seed_demo_data.py +++ b/backend/scripts/seed_demo_data.py @@ -11,6 +11,7 @@ Hypothesis / AARRecord / TeamMember / TalentProfile / AuditLog。 import asyncio import json +import random from datetime import datetime, timedelta, timezone from sqlalchemy import text @@ -19,10 +20,15 @@ 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, + AARRecord, AgentExecution, AuditLog, BoardMeeting, Company, CompanyFundLink, + CustomerAcquisitionPlan, DataSource, DecisionSentinel, DigitalTwinModel, + EvaluationTemplate, ExitPrediction, FinancialData, FirmProfile, Fund, + FundProfile, HealthScore, Hypothesis, InquiryList, InterventionEvent, + InterventionResult, InvestmentAgreement, KnowledgeChunk, KnowledgeNode, + MajorEvent, ManagerProfile, MilestoneTree, MonteCarloSimulation, MonthlyReport, + NudgeRecord, OKR, PeerLearningCircle, PortfolioRebalancing, PreMortemRecord, + ProductDiagnostic, RedTeamRecord, RiskEvent, SynergyOpportunity, Task, + TalentProfile, TeamMember, Tenant, User, WeakSignal, ) UTC = timezone.utc @@ -56,9 +62,14 @@ async def seed() -> None: async with async_session_factory() as db: await _seed_tenant_users(db) await _seed_companies(db) + await _seed_funds(db) + await _seed_profiles(db) + await _seed_evaluation_templates(db) await _seed_financial(db) await _seed_reports(db) + await _seed_inquiries(db) await _seed_health(db) + await _seed_health_history(db) await _seed_risks(db) await _seed_weak_signals(db) await _seed_tasks(db) @@ -74,6 +85,17 @@ async def seed() -> None: await _seed_aars(db) await _seed_team_members(db) await _seed_talents(db) + await _seed_agent_executions(db) + await _seed_customer_plans(db) + await _seed_exit_predictions(db) + await _seed_pre_mortems(db) + await _seed_product_diagnostics(db) + await _seed_peer_circles(db) + await _seed_digital_twins(db) + await _seed_interventions(db) + await _seed_portfolio_simulations(db) + await _seed_knowledge_graph(db) + await _seed_data_sources(db) await _seed_audit_logs(db) await db.commit() @@ -136,30 +158,32 @@ async def _seed_companies(db: AsyncSession) -> None: # ─── 财务数据 ────────────────────────────────────────────────────────── async def _seed_financial(db: AsyncSession) -> None: - """每家企业生成近 3 个月利润表 + 现金流。""" + """每家企业生成近 6 个月利润表 + 现金流。""" for comp_id, revenue, burn, cash in [ - (COMP_A, 800, 350, 4200), # 月营收350万, 消耗120万, 现金4200万 + (COMP_A, 800, 350, 4200), # 月营收800万, 消耗350万, 现金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): + for i in range(6): y, m = (NOW.year, NOW.month - i) if NOW.month - i > 0 else (NOW.year - 1, 12 + NOW.month - i) + # 营收逐月递减(历史数据),展示增长趋势 + hist_revenue = int(revenue * (1 - 0.03 * i)) if revenue > 0 else 0 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)}, + data_json={"revenue": hist_revenue, "cogs": int(hist_revenue * 0.4), "gross_profit": int(hist_revenue * 0.6), "opex": burn, "net_income": hist_revenue - burn - int(hist_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}, + data_json={"operating_cf": hist_revenue - burn, "investing_cf": -50, "financing_cf": 0, "net_cf": hist_revenue - burn - 50, "cash_balance": cash - i * burn}, source="monthly_report", credibility_score=85.0 - i * 5, )) await db.flush() - print(" ✓ 财务数据 (5 企业 x 3 月)") + print(" ✓ 财务数据 (5 企业 x 6 月)") # ─── 月报 ────────────────────────────────────────────────────────────── @@ -201,78 +225,176 @@ async def _seed_reports(db: AsyncSession) -> None: for r in reports: db.add(r) await db.flush() - print(" ✓ 月报 (5 份)") + + # 历史月报 — 每家企业再补 5 个月,展示趋势 + historical_data = [ + # (company_id, founder_id, months_ago, revenue, growth, new_cust, churned, headcount, summary, concerns) + (COMP_A, FOUNDER_A, 2, 696, 0.08, 2, 0, 40, "营收稳步增长,新签2家客户。", []), + (COMP_A, FOUNDER_A, 3, 644, 0.05, 1, 1, 38, "营收增长5%,客户流失1家。", [{"level": "low", "item": "客户流失", "detail": "流失1家小客户"}]), + (COMP_A, FOUNDER_A, 4, 613, 0.03, 1, 0, 37, "营收小幅增长,团队稳定。", []), + (COMP_A, FOUNDER_A, 5, 595, 0.02, 0, 0, 35, "营收微增,无新签客户。", [{"level": "medium", "item": "增长放缓", "detail": "环比仅2%"}]), + (COMP_A, FOUNDER_A, 6, 583, 0.01, 1, 1, 34, "基本持平,团队新增1人。", []), + (COMP_B, FOUNDER_B, 2, 150, 0.0, 0, 0, 22, "营收持平,产品迭代中。", []), + (COMP_B, FOUNDER_B, 3, 150, 0.02, 1, 0, 21, "营收微增,新签1家客户。", []), + (COMP_B, FOUNDER_B, 4, 147, -0.01, 0, 1, 21, "营收微降,流失1家小客户。", [{"level": "medium", "item": "客户流失", "detail": "流失1家"}]), + (COMP_B, FOUNDER_B, 5, 149, 0.03, 1, 0, 20, "营收回升,新签1家。", []), + (COMP_B, FOUNDER_B, 6, 145, 0.0, 0, 0, 20, "持平,团队稳定。", []), + (COMP_C, FOUNDER_C, 2, 984, 0.18, 3, 0, 62, "强劲增长,半导体客户+3。", []), + (COMP_C, FOUNDER_C, 3, 834, 0.15, 2, 0, 58, "持续增长,新增专利1项。", []), + (COMP_C, FOUNDER_C, 4, 725, 0.12, 1, 0, 55, "稳定增长,团队扩张。", []), + (COMP_C, FOUNDER_C, 5, 647, 0.10, 1, 0, 52, "增速放缓,但趋势向上。", []), + (COMP_C, FOUNDER_C, 6, 588, 0.08, 0, 0, 50, "基线月份,稳步起步。", []), + (COMP_E, FOUNDER_A, 2, 75, 0.0, 0, 0, 17, "里程碑收入稳定。", []), + (COMP_E, FOUNDER_A, 3, 80, 0.07, 0, 0, 18, "小幅增长,靶点推进。", []), + (COMP_E, FOUNDER_A, 4, 75, 0.0, 0, 0, 17, "持平,研发正常。", []), + (COMP_E, FOUNDER_A, 5, 70, -0.07, 0, 0, 16, "收入微降,无里程碑。", [{"level": "low", "item": "收入波动", "detail": "依赖里程碑付款"}]), + (COMP_E, FOUNDER_A, 6, 75, 0.04, 0, 0, 16, "基线月份,稳定。", []), + ] + for comp_id, founder_id, months_ago, revenue, growth, new_c, churned, hc, summary, concerns in historical_data: + m = NOW.month - months_ago + y = NOW.year + if m <= 0: + m += 12 + y -= 1 + db.add(MonthlyReport( + company_id=comp_id, period_year=y, period_month=m, + status="reviewed", submitted_by=founder_id, submitted_at=D(months_ago * 30 + 10), + reviewed_by=MGR_ID, reviewed_at=D(months_ago * 30 + 5), + raw_content=f"本月营收{revenue}万,环比{'增长' if growth > 0 else '持平' if growth == 0 else '下降'}{abs(growth)*100:.0f}%。", + structured_data={"revenue": revenue, "mom_growth": growth, "new_customers": new_c, "churned": churned, "headcount": hc}, + ai_summary=summary, + ai_concerns=concerns if concerns else None, + )) + await db.flush() + print(" ✓ 月报 (5 当月 + 20 历史 = 25 份)") # ─── 健康度评分 ──────────────────────────────────────────────────────── async def _seed_health(db: AsyncSession) -> None: + """最新一期健康度评分 — 14 维度完整评分。""" scores = [ # 智链科技 — 良好 - HealthScore(company_id=COMP_A, total_score=78.5, financial_score=82, operational_score=75, ai_commercial_score=80, ai_cost_score=85, + 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()}), + synergy_score=76, ai_model_product_score=82, data_compliance_score=88, team_tech_score=74, customer_success_score=68, + trend="up", evidence_json={"financial": "营收增长15%,现金流健康", "ai_cost": "推理成本降低12%", "data_compliance": "通过等保三级", "ai_poc_count": 3, "compliance_issues": 0}, + recommendations_json={"action": "关注客户流失率", "owner": MGR_ID, "review_at": D(-30).isoformat()}, + fund_type="early_vc", fund_lifecycle="investment", company_stage="b", industry="ai", strategy="growth"), # 云栈数据 — 中等 - HealthScore(company_id=COMP_B, total_score=62.0, financial_score=55, operational_score=68, ai_commercial_score=60, ai_cost_score=65, + 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()}), + synergy_score=64, ai_model_product_score=68, data_compliance_score=85, team_tech_score=72, customer_success_score=60, + trend="stable", evidence_json={"financial": "营收持平,需突破", "financing": "Runway 15月,需启动融资", "ai_poc_count": 1, "compliance_issues": 1}, + recommendations_json={"action": "加速融资节奏", "owner": LEAD_ID, "review_at": D(-14).isoformat()}, + fund_type="early_vc", fund_lifecycle="investment", company_stage="a", industry="ai", strategy="growth"), # 深瞳智能 — 优秀 - HealthScore(company_id=COMP_C, total_score=85.5, financial_score=88, operational_score=85, ai_commercial_score=90, ai_cost_score=82, + 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()}), + synergy_score=80, ai_model_product_score=86, data_compliance_score=90, team_tech_score=85, customer_success_score=82, + trend="up", evidence_json={"financial": "营收增长22%", "market": "半导体渗透加深", "ai_poc_count": 5, "compliance_issues": 0}, + recommendations_json={"action": "关注客户集中度", "owner": MGR_ID, "review_at": D(-30).isoformat()}, + fund_type="early_vc", fund_lifecycle="growth", company_stage="b", industry="ai", strategy="growth"), # 量子芯微 — 早期风险 - HealthScore(company_id=COMP_D, total_score=48.0, financial_score=35, operational_score=50, ai_commercial_score=45, ai_cost_score=55, + 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()}), + synergy_score=45, ai_model_product_score=58, data_compliance_score=65, team_tech_score=62, customer_success_score=38, + trend="down", evidence_json={"financial": "无营收,现金紧张", "financing": "Runway 7月", "ai_poc_count": 0, "compliance_issues": 2}, + recommendations_json={"action": "紧急启动天使+轮融资", "owner": GP_ID, "review_at": D(-7).isoformat()}, + fund_type="angel", fund_lifecycle="investment", company_stage="seed", industry="hardware", strategy="growth"), # 光合生物 — 中等偏上 - HealthScore(company_id=COMP_E, total_score=68.5, financial_score=60, operational_score=72, ai_commercial_score=70, ai_cost_score=65, + 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()}), + synergy_score=66, ai_model_product_score=72, data_compliance_score=80, team_tech_score=70, customer_success_score=65, + trend="stable", evidence_json={"financial": "里程碑收入稳定", "product": "3靶点推进中", "ai_poc_count": 2, "compliance_issues": 0}, + recommendations_json={"action": "月报提交及时性改善", "owner": MGR_ID, "review_at": D(-30).isoformat()}, + fund_type="early_vc", fund_lifecycle="investment", company_stage="a", industry="biotech", strategy="growth"), ] for s in scores: s.calculated_at = D(5) db.add(s) await db.flush() - print(" ✓ 健康度评分 (5 企业)") + print(" ✓ 健康度评分 (5 企业 x 14 维度)") # ─── 风险事件 ────────────────────────────────────────────────────────── async def _seed_risks(db: AsyncSession) -> None: risks = [ + # COMP_A — 智链科技 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)), + RiskEvent(company_id=COMP_A, type="market", severity="medium", status="open", + title="竞品低价策略冲击", description="杉数科技以低于我方30%的价格争夺制造业客户", + evidence_json={"competitor": "杉数科技", "price_diff": -0.30, "affected_customers": 3}, + suggested_action="强化差异化话术,加速多模态产品迭代", assigned_to=LEAD_ID), + RiskEvent(company_id=COMP_A, type="financial", severity="low", status="resolved", + title="应收账款周期延长", description="2家客户付款周期从30天延至45天", + evidence_json={"metric": "ar_days", "current": 45, "previous": 30, "threshold": 60}, + suggested_action="与客户协商缩短账期", assigned_to=MGR_ID, closed_at=D(-15)), + # COMP_B — 云栈数据 + 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_B, type="financial", severity="high", status="open", + title="现金Runway缩短至15个月", description="按当前消耗速度,现金仅可维持15个月", + evidence_json={"metric": "runway_months", "current": 15, "threshold": 18}, + suggested_action="启动A+轮融资准备,控制招聘节奏", assigned_to=GP_ID), + RiskEvent(company_id=COMP_B, type="market", severity="medium", status="open", + title="金融行业准入门槛高", description="银行客户POC周期长达6-12月,转化率低", + evidence_json={"metric": "poc_conversion", "current": 0.15, "expected": 0.30}, + suggested_action="调整目标客户画像,探索保险/证券赛道", assigned_to=MGR_ID), + # COMP_C — 深瞳智能 + RiskEvent(company_id=COMP_C, type="org", severity="medium", 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_C, type="market", severity="medium", status="in_progress", + title="客户集中度过高", description="半导体行业占比60%,周期下行风险大", + evidence_json={"metric": "customer_concentration", "current": 0.60, "threshold": 0.50, "industry": "semiconductor"}, + suggested_action="拓展新能源、消费电子等新行业客户", assigned_to=MGR_ID, due_at=D(-30)), + RiskEvent(company_id=COMP_C, type="operational", severity="low", status="closed", + title="产品交付延迟", description="1条产线视觉系统部署延迟2周", + evidence_json={"metric": "delivery_delay_days", "current": 14, "threshold": 7}, + suggested_action="增加现场实施人员", assigned_to=MGR_ID, closed_at=D(-20)), + # COMP_D — 量子芯微 + 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_D, type="technical", severity="high", status="in_progress", + title="NPU流片进度风险", description="EDA工具链兼容性问题可能导致流片延迟1-2月", + evidence_json={"metric": "tapeout_delay_risk", "risk_level": "high", "eta_impact": "1-2月"}, + suggested_action="协调备用EDA工具,增加验证人力", assigned_to=GP_ID, due_at=D(-7)), + RiskEvent(company_id=COMP_D, type="market", severity="medium", status="open", + title="边缘NPU赛道巨头入场", description="英伟达发布边缘端Jetson新品,可能挤压创业公司空间", + evidence_json={"competitor": "NVIDIA", "product": "Jetson Orin Nano", "threat_level": "medium"}, + suggested_action="强化低功耗差异化,加速客户绑定", assigned_to=LEAD_ID), + # COMP_E — 光合生物 + 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_E, type="financial", severity="medium", status="open", + title="研发投入产出周期长", description="3靶点尚处先导化合物阶段,距临床还需12-18月", + evidence_json={"metric": "time_to_clinic", "current": 18, "threshold": 12, "targets": 3}, + suggested_action="评估是否引入大药企联合开发", assigned_to=LEAD_ID), ] for r in risks: r.identified_at = D(15) db.add(r) await db.flush() - print(" ✓ 风险事件 (6 条)") + print(" ✓ 风险事件 (15 条)") # ─── 弱信号 ──────────────────────────────────────────────────────────── @@ -290,12 +412,23 @@ async def _seed_weak_signals(db: AsyncSession) -> None: 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"), + WeakSignal(company_id=COMP_C, signal_type="market", source="半导体行业协会", content="半导体周期指标连续2月下行", + confidence=0.70, risk_probability=0.62, status="correlated", + correlation_result={"related_signals": 1, "pattern": "行业周期风险"}), + WeakSignal(company_id=COMP_A, signal_type="technical", source="GitHub", content="竞品开源多模态决策引擎,star数暴涨", + confidence=0.65, risk_probability=0.40, status="new"), + WeakSignal(company_id=COMP_B, signal_type="org", source="脉脉", content="云栈数据销售总监更新简历", + confidence=0.78, risk_probability=0.60, status="alerted", + correlation_result={"related_signals": 1, "pattern": "销售负责人不稳定"}), + WeakSignal(company_id=COMP_D, signal_type="market", source="英伟达发布会", content="英伟达发布边缘端Jetson Orin Nano,价格下探", + confidence=0.82, risk_probability=0.70, status="alerted", + correlation_result={"related_signals": 2, "pattern": "巨头入场边缘AI"}), ] for s in signals: s.detected_at = D(7) db.add(s) await db.flush() - print(" ✓ 弱信号 (5 条)") + print(" ✓ 弱信号 (9 条)") # ─── 任务 ────────────────────────────────────────────────────────────── @@ -633,5 +766,512 @@ async def _seed_audit_logs(db: AsyncSession) -> None: print(" ✓ 审计日志 (10 条)") +# ─── 健康度历史趋势(近 6 个月) ────────────────────────────────────── +async def _seed_health_history(db: AsyncSession) -> None: + """每家企业近 6 个月健康度趋势,用于趋势图展示。""" + # 基线分数和月度变化趋势 + trends = [ + # (company_id, base_score, monthly_deltas) + (COMP_A, 70.0, [+1.5, +2.0, +1.5, +2.0, +1.5, +0.0]), # 上升趋势 + (COMP_B, 65.0, [-0.5, -0.5, +0.0, -0.5, -1.0, +0.0]), # 下降趋势 + (COMP_C, 75.0, [+1.5, +2.0, +2.5, +2.0, +1.5, +1.0]), # 强上升 + (COMP_D, 58.0, [-2.0, -2.0, -2.5, -1.5, -1.0, -1.0]), # 持续下降 + (COMP_E, 65.0, [+0.5, +1.0, +0.5, +1.0, +0.5, +0.0]), # 缓慢上升 + ] + for comp_id, base, deltas in trends: + score = base + for i, delta in enumerate(deltas): + score += delta + m = (NOW.month - i - 1) if (NOW.month - i - 1) > 0 else (12 + NOW.month - i - 1) + y = NOW.year if (NOW.month - i - 1) > 0 else NOW.year - 1 + db.add(HealthScore( + company_id=comp_id, total_score=round(score, 1), + financial_score=round(score * 1.05, 1), operational_score=round(score * 0.95, 1), + ai_commercial_score=round(score * 1.02, 1), ai_cost_score=round(score * 1.08, 1), + org_talent_score=round(score * 0.92, 1), product_tech_score=round(score * 1.03, 1), + market_compete_score=round(score * 0.98, 1), governance_score=round(score * 0.96, 1), + financing_score=round(score * 0.94, 1), + synergy_score=round(score * 0.97, 1), ai_model_product_score=round(score * 1.04, 1), + data_compliance_score=round(score * 1.12, 1), team_tech_score=round(score * 0.95, 1), + customer_success_score=round(score * 0.87, 1), + trend="up" if delta > 0 else "down" if delta < 0 else "stable", + evidence_json={"historical": True, "month": f"{y}-{m:02d}"}, + calculated_at=datetime(y, m, 1, tzinfo=UTC), + fund_type="early_vc", fund_lifecycle="investment", company_stage="b", industry="ai", strategy="growth", + )) + await db.flush() + print(" ✓ 健康度历史趋势 (5 企业 x 6 月)") + + +# ─── 基金 ────────────────────────────────────────────────────────────── +async def _seed_funds(db: AsyncSession) -> None: + """基金信息 + 企业-基金关联。""" + fund1 = Fund(tenant_id=TENANT_ID, name="远见三期人民币基金", fund_type="early_vc", strategy="growth", + established_date=datetime(2023, 1, 1).date(), total_lifespan_months=84, investment_period_months=48, + lp_composition_json={"government": 30, "market": 50, "corporate": 20}, primary_market="china_mainland") + fund2 = Fund(tenant_id=TENANT_ID, name="远见天使基金", fund_type="angel", strategy="growth", + established_date=datetime(2024, 1, 1).date(), total_lifespan_months=72, investment_period_months=36, + lp_composition_json={"government": 20, "market": 60, "corporate": 20}, primary_market="china_mainland") + for f in [fund1, fund2]: + db.add(f) + await db.flush() + + links = [ + CompanyFundLink(company_id=COMP_A, fund_id=fund1.id, investment_date=datetime(2023, 6, 1).date(), + investment_stage="b", round="B轮", amount=5000, ownership_pct=12.5, is_current=True), + CompanyFundLink(company_id=COMP_B, fund_id=fund1.id, investment_date=datetime(2023, 3, 1).date(), + investment_stage="a", round="A轮", amount=2000, ownership_pct=15.0, is_current=True), + CompanyFundLink(company_id=COMP_C, fund_id=fund1.id, investment_date=datetime(2022, 12, 1).date(), + investment_stage="b", round="B轮", amount=8000, ownership_pct=20.0, is_current=True), + CompanyFundLink(company_id=COMP_E, fund_id=fund1.id, investment_date=datetime(2023, 9, 1).date(), + investment_stage="a", round="A轮", amount=3000, ownership_pct=10.0, is_current=True), + CompanyFundLink(company_id=COMP_D, fund_id=fund2.id, investment_date=datetime(2024, 3, 1).date(), + investment_stage="seed", round="天使轮", amount=500, ownership_pct=8.0, is_current=True), + ] + for l in links: + db.add(l) + await db.flush() + print(" ✓ 基金 (2 支) + 关联 (5 条)") + + +# ─── 多主体画像 ──────────────────────────────────────────────────────── +async def _seed_profiles(db: AsyncSession) -> None: + """投资机构、基金、投资经理画像。""" + firm = FirmProfile(tenant_id=TENANT_ID, name="远见资本", + focus_areas={"sectors": ["AI", "硬科技", "生物医药"], "stages": ["seed", "A", "B"]}, + stage_preference="seed-B", description="专注早期科技投资,管理规模15亿人民币。") + db.add(firm) + await db.flush() + + db.add(FundProfile(firm_id=firm.id, name="远见三期人民币基金", fund_size="5亿人民币", vintage_year=2023, + strategy="早期科技,AI+硬科技为主,赋能式投后管理。")) + db.add(FundProfile(firm_id=firm.id, name="远见天使基金", fund_size="1亿人民币", vintage_year=2024, + strategy="天使阶段,聚焦AI应用和芯片设计。")) + + db.add(ManagerProfile(firm_id=firm.id, user_id=MGR_ID, name="王经理", + focus_areas={"sectors": ["AI/供应链", "AI/数据平台"], "companies": [COMP_A, COMP_B]}, + portfolio_count=2)) + db.add(ManagerProfile(firm_id=firm.id, user_id=LEAD_ID, name="李投后", + focus_areas={"sectors": ["AI/计算机视觉", "AI/医疗"], "companies": [COMP_C, COMP_E]}, + portfolio_count=2)) + await db.flush() + print(" ✓ 画像 (机构1 + 基金2 + 经理2)") + + +# ─── 评价模板 ────────────────────────────────────────────────────────── +async def _seed_evaluation_templates(db: AsyncSession) -> None: + """6 轴动态评价模板 — 覆盖常见组合。""" + templates = [ + EvaluationTemplate(tenant_id=TENANT_ID, name="早期VC-AI-B轮-成长策略", + fund_type="early_vc", fund_lifecycle="investment", company_stage="b", + industry="ai", strategy="growth", investor_type="investor", + weights_json={"financial": 0.12, "operational": 0.10, "ai_commercial": 0.12, "ai_cost": 0.08, + "org_talent": 0.10, "product_tech": 0.12, "market_compete": 0.10, "governance": 0.06, + "financing": 0.08, "synergy": 0.04, "ai_model_product": 0.04, "data_compliance": 0.02, + "team_tech": 0.01, "customer_success": 0.01}, + enabled_dimensions=["financial", "operational", "ai_commercial", "ai_cost", "org_talent", + "product_tech", "market_compete", "governance", "financing", "synergy", + "ai_model_product", "data_compliance", "team_tech", "customer_success"], + disabled_dimensions=[], + custom_metrics_json={"ai_poc_count": {"label": "AI PoC 数量", "source": "月报"}, "compliance_issues": {"label": "合规整改项", "source": "审计"}}, + is_default=True), + EvaluationTemplate(tenant_id=TENANT_ID, name="天使-硬件-种子期-成长策略", + fund_type="angel", fund_lifecycle="investment", company_stage="seed", + industry="hardware", strategy="growth", investor_type="gp", + weights_json={"financial": 0.06, "operational": 0.08, "ai_commercial": 0.08, "ai_cost": 0.06, + "org_talent": 0.15, "product_tech": 0.20, "market_compete": 0.10, "governance": 0.05, + "financing": 0.12, "synergy": 0.03, "ai_model_product": 0.04, "data_compliance": 0.01, + "team_tech": 0.02, "customer_success": 0.00}, + enabled_dimensions=["financial", "operational", "ai_commercial", "ai_cost", "org_talent", + "product_tech", "market_compete", "governance", "financing", "synergy", + "ai_model_product", "data_compliance", "team_tech"], + disabled_dimensions=["customer_success"], + is_default=True), + EvaluationTemplate(tenant_id=TENANT_ID, name="早期VC-生物医疗-A轮-成长策略", + fund_type="early_vc", fund_lifecycle="investment", company_stage="a", + industry="biotech", strategy="growth", investor_type="investor", + weights_json={"financial": 0.08, "operational": 0.10, "ai_commercial": 0.10, "ai_cost": 0.06, + "org_talent": 0.12, "product_tech": 0.18, "market_compete": 0.08, "governance": 0.08, + "financing": 0.10, "synergy": 0.03, "ai_model_product": 0.04, "data_compliance": 0.03, + "team_tech": 0.00, "customer_success": 0.00}, + enabled_dimensions=["financial", "operational", "ai_commercial", "ai_cost", "org_talent", + "product_tech", "market_compete", "governance", "financing", "synergy", + "ai_model_product", "data_compliance"], + disabled_dimensions=["team_tech", "customer_success"], + is_default=True), + ] + for t in templates: + db.add(t) + await db.flush() + print(" ✓ 评价模板 (3 套)") + + +# ─── 追问清单 ────────────────────────────────────────────────────────── +async def _seed_inquiries(db: AsyncSession) -> None: + """月报追问清单 — AI 生成补充问题。""" + inquiries = [ + InquiryList(company_id=COMP_A, + questions=[{"q": "本月流失客户的具体原因是什么?", "a": "客户反馈技术支持响应慢,竞品以低价策略抢客。"}, + {"q": "AI推理成本降低12%的具体措施?", "a": "采用模型量化+推理优化,单次调用成本从0.05元降至0.044元。"}, + {"q": "新签3家客户的年合同金额?", "a": "合计约480万/年,平均160万/家。"}], + status="answered", sent_at=D(9), answered_at=D(5)), + InquiryList(company_id=COMP_B, + questions=[{"q": "营收连续2个月持平的原因?", "a": "现有客户续约稳定,但新客户拓展速度放缓。"}, + {"q": "金融客户拓展进展?", "a": "1家银行已进POC阶段,预计Q3签约。"}, + {"q": "A+轮融资准备情况?", "a": "BP初稿完成,正在整理财务预测。"}], + status="answered", sent_at=D(7), answered_at=D(3)), + InquiryList(company_id=COMP_D, + questions=[{"q": "NPU原型流片时间表?", "a": "预计下月流片,Q4出工程样片。"}, + {"q": "天使+轮BP何时可以准备好?", "a": "正在准备中,预计2周内完成。"}], + status="sent", sent_at=D(2)), + ] + for i in inquiries: + db.add(i) + await db.flush() + print(" ✓ 追问清单 (3 条)") + + +# ─── Agent 执行记录 ──────────────────────────────────────────────────── +async def _seed_agent_executions(db: AsyncSession) -> None: + """AI Agent L1-L4 分级执行记录。""" + agents = [ + AgentExecution(tenant_id=TENANT_ID, agent_name="月报解析Agent", autonomy_level="L3", + input_summary="智链科技2025-06月报", output_summary="解析完成:营收800万(+15%),客户净增2家", + output_detail={"revenue": 800, "mom_growth": 0.15, "new_customers": 3, "churned": 1}, + review_status="auto_approved", model_version="gpt-4o-2024", duration_ms=3200), + AgentExecution(tenant_id=TENANT_ID, agent_name="风险预警Agent", autonomy_level="L2", + input_summary="量子芯微财务数据扫描", output_summary="发现1项critical风险:Runway不足7月", + output_detail={"risks_found": 1, "severity": "critical", "metric": "runway", "value": 7}, + review_status="approved", reviewer_id=MGR_ID, reviewed_at=D(3), model_version="gpt-4o-2024", duration_ms=1800), + AgentExecution(tenant_id=TENANT_ID, agent_name="弱信号监测Agent", autonomy_level="L3", + input_summary="深瞳智能外部信号扫描", output_summary="LinkedIn检测到CTO更新简历", + output_detail={"signal_type": "org", "source": "LinkedIn", "confidence": 0.85}, + review_status="auto_approved", model_version="gpt-4o-2024", duration_ms=2400), + AgentExecution(tenant_id=TENANT_ID, agent_name="协同匹配Agent", autonomy_level="L2", + input_summary="Portfolio协同分析", output_summary="发现3个协同机会", + output_detail={"matches": 3, "types": ["customer", "tech", "talent"]}, + review_status="approved", reviewer_id=LEAD_ID, reviewed_at=D(5), model_version="gpt-4o-2024", duration_ms=5600), + AgentExecution(tenant_id=TENANT_ID, agent_name="健康度计算Agent", autonomy_level="L4", + input_summary="5家企业健康度季度评估", output_summary="14维度评分完成,2家上升1家下降", + output_detail={"companies": 5, "trends": {"up": 2, "stable": 2, "down": 1}}, + review_status="auto_approved", model_version="gpt-4o-2024", duration_ms=8200), + AgentExecution(tenant_id=TENANT_ID, agent_name="月报解析Agent", autonomy_level="L3", + input_summary="云栈数据2025-06月报", output_summary="解析完成:营收150万(持平)", + output_detail={"revenue": 150, "mom_growth": 0.0}, + review_status="auto_approved", model_version="gpt-4o-2024", duration_ms=2800), + AgentExecution(tenant_id=TENANT_ID, agent_name="决策哨兵Agent", autonomy_level="L2", + input_summary="云栈数据融资时机分析", output_summary="建议现在启动A+轮融资", + output_detail={"decision": "funding", "recommendation": "now", "confidence": 0.72}, + review_status="pending", model_version="gpt-4o-2024", duration_ms=4200), + AgentExecution(tenant_id=TENANT_ID, agent_name="数据校验Agent", autonomy_level="L4", + input_summary="5家企业财务数据交叉校验", output_summary="校验通过,数据一致性98.5%", + output_detail={"checked": 30, "passed": 29, "inconsistencies": 1}, + review_status="auto_approved", model_version="gpt-4o-2024", duration_ms=1500), + ] + for idx, a in enumerate(agents): + a.created_at = D(10 - idx) + db.add(a) + await db.flush() + print(" ✓ Agent 执行记录 (8 条)") + + +# ─── 客户获取计划 ────────────────────────────────────────────────────── +async def _seed_customer_plans(db: AsyncSession) -> None: + """AI 客户增长引擎 — LP 资源匹配 + 客户获取方案。""" + plans = [ + CustomerAcquisitionPlan(company_id=COMP_A, target_customer="年营收10-50亿制造业CIO/供应链总监", + entry_angle="从供应链预测场景切入,ROI 3个月可见", + decision_chain={"roles": ["CIO", "供应链VP", "采购总监"], "influence": {"CIO": 0.4, "供应链VP": 0.4, "采购总监": 0.2}, "cycle": "3-6月"}, + pricing_strategy="SaaS订阅:年费80-200万,按模块阶梯定价", + competitive_analysis={"direct": ["杉数科技", "京东物流AI"], "advantage": "多模态决策引擎,部署快3倍", "weakness": "品牌知名度低"}, + lp_resources={"lp_company": "某制造业LP", "intro_channel": "GP引荐", "warmth": "high"}, + execution_status="executing", + result={"customers_contacted": 5, "poc_started": 2, "signed": 1, "revenue": 160}), + CustomerAcquisitionPlan(company_id=COMP_B, target_customer="金融机构数据治理负责人", + entry_angle="合规驱动+AI训练数据管理,从数据治理切入", + decision_chain={"roles": ["数据治理总监", "合规负责人", "CTO"], "influence": {"数据治理总监": 0.5, "合规负责人": 0.3, "CTO": 0.2}, "cycle": "6-12月"}, + pricing_strategy="平台授权+实施服务:首年120万+实施80万", + competitive_analysis={"direct": ["亿信华辰", "数美科技"], "advantage": "AI原生,支持大模型训练数据管理", "weakness": "金融行业案例少"}, + lp_resources={"lp_company": "某银行LP", "intro_channel": "GP引荐", "warmth": "medium"}, + execution_status="planned", + result=None), + CustomerAcquisitionPlan(company_id=COMP_C, target_customer="半导体晶圆厂质检负责人", + entry_angle="替代人工目检,从良率提升切入", + decision_chain={"roles": ["质量总监", "生产VP", "CIO"], "influence": {"质量总监": 0.5, "生产VP": 0.3, "CIO": 0.2}, "cycle": "3-6月"}, + pricing_strategy="设备+软件:单条产线200-400万", + competitive_analysis={"direct": ["康代智能", "奥普特"], "advantage": "AI算法精度99.2%,行业领先", "weakness": "硬件成本偏高"}, + lp_resources={"lp_company": "某半导体LP", "intro_channel": "LP直接引荐", "warmth": "high"}, + execution_status="completed", + result={"customers_contacted": 8, "poc_started": 5, "signed": 3, "revenue": 800}), + ] + for p in plans: + db.add(p) + await db.flush() + print(" ✓ 客户获取计划 (3 条)") + + +# ─── 退出预测 ────────────────────────────────────────────────────────── +async def _seed_exit_predictions(db: AsyncSession) -> None: + """退出时机预测 — IPO/并购/二手份额。""" + predictions = [ + ExitPrediction(company_id=COMP_C, exit_path="ipo", + timing_window={"earliest": "2027-Q1", "latest": "2028-Q3"}, + expected_return=4.2, hold_return=2.8, confidence=0.75, + signals={"positive": ["营收年增50%+", "半导体赛道热度高", "专利壁垒"], "negative": ["客户集中度60%", "CTO稳定性"]}, + recommendation="建议2027年Q1启动IPO准备,当前应解决客户集中度和CTO retention问题。"), + ExitPrediction(company_id=COMP_A, exit_path="acquisition", + timing_window={"earliest": "2026-Q3", "latest": "2027-Q4"}, + expected_return=3.5, hold_return=3.0, confidence=0.65, + signals={"positive": ["多模态技术差异化", "制造业客户基础"], "negative": ["客户流失率上升", "竞争加剧"]}, + recommendation="建议关注产业并购机会,优先接触京东物流、菜鸟等供应链平台。"), + ExitPrediction(company_id=COMP_E, exit_path="acquisition", + timing_window={"earliest": "2028-Q1", "latest": "2030-Q4"}, + expected_return=5.0, hold_return=3.5, confidence=0.55, + signals={"positive": ["AI药物发现赛道升温", "3靶点进入先导"], "negative": ["研发周期长", "现金流压力"]}, + recommendation="建议继续持有,等待靶点临床验证结果后评估并购机会。"), + ] + for p in predictions: + db.add(p) + await db.flush() + print(" ✓ 退出预测 (3 条)") + + +# ─── Pre-mortem + Red Team ───────────────────────────────────────────── +async def _seed_pre_mortems(db: AsyncSession) -> None: + """失败推演 + 对抗分析。""" + pre_mortems = [ + PreMortemRecord(company_id=COMP_D, decision_context="天使+轮融资1500万,估值8000万", + failure_paths=[{"path": "流片失败导致估值缩水", "probability": 0.25, "impact": "high"}, + {"path": "融资周期超3月,现金耗尽", "probability": 0.15, "impact": "critical"}, + {"path": "竞品发布同类NPU,差异化丧失", "probability": 0.20, "impact": "medium"}], + risk_checklist={"items": ["流片进度", "现金Runway", "竞品动态", "核心团队稳定性"], "checked": 3, "total": 4}, + mitigations={"actions": ["准备过桥贷款方案", "与2家竞品做技术对标", "CTO股权激励绑定"]}), + PreMortemRecord(company_id=COMP_B, decision_context="A+轮融资3000万 vs 等待Q2数据验证", + failure_paths=[{"path": "现在融资估值偏低,稀释过多", "probability": 0.40, "impact": "medium"}, + {"path": "等待期间现金耗尽", "probability": 0.20, "impact": "critical"}, + {"path": "Q2数据不及预期,融资更难", "probability": 0.30, "impact": "high"}], + risk_checklist={"items": ["现金Runway", "Q2营收预期", "竞品定价压力", "金融客户签约"], "checked": 2, "total": 4}, + mitigations={"actions": ["准备两套BP", "与现有股东沟通过桥", "加速金融客户POC"]}), + ] + for p in pre_mortems: + db.add(p) + + red_teams = [ + RedTeamRecord(company_id=COMP_A, perspective="competitor", + analysis="如果我是杉数科技,会以低价+行业深耕策略抢智链科技的制造业客户。智链的多模态优势在具体场景中并未形成壁垒。", + vulnerabilities={"areas": ["客户成功团队薄弱", "品牌知名度低", "定价偏高"], "severity": "medium"}, + counterarguments={"defense": ["多模态技术差异化", "客户切换成本高"]}), + RedTeamRecord(company_id=COMP_C, perspective="pessimistic_investor", + analysis="深瞳智能半导体占比60%是定时炸弹。半导体周期下行时营收将大幅缩水。CTO稳定性问题如果恶化,技术优势可能丧失。", + vulnerabilities={"areas": ["客户集中度60%", "CTO稳定性0.65", "半导体周期风险"], "severity": "high"}, + counterarguments={"defense": ["正在拓展新能源客户", "CTO激励方案设计中"]}), + RedTeamRecord(company_id=COMP_D, perspective="devils_advocate", + analysis="量子芯微的NPU在边缘端确实有需求,但巨头(英伟达/高通)一旦下沉,创业公司很难竞争。7月Runway意味着没有试错空间。", + vulnerabilities={"areas": ["巨头竞争风险", "Runway 7月", "无营收"], "severity": "critical"}, + counterarguments={"defense": ["边缘端低功耗是差异化", "已有3家潜在客户"]}), + ] + for r in red_teams: + db.add(r) + await db.flush() + print(" ✓ Pre-mortem (2) + Red Team (3)") + + +# ─── 产品竞争力诊断 ──────────────────────────────────────────────────── +async def _seed_product_diagnostics(db: AsyncSession) -> None: + """产品竞争力诊断 — 热力图 + 竞品对比。""" + diagnostics = [ + ProductDiagnostic(company_id=COMP_A, product_name="多模态供应链决策引擎", + dimensions={"技术壁垒": 82, "产品成熟度": 75, "用户体验": 70, "生态集成": 65, "定价竞争力": 60, "客户支持": 55}, + heatmap_data={"strengths": ["技术壁垒", "产品成熟度"], "weaknesses": ["客户支持", "定价竞争力"], "neutral": ["用户体验", "生态集成"]}, + competitors=[{"name": "杉数科技", "scores": {"技术壁垒": 78, "产品成熟度": 85, "用户体验": 80, "生态集成": 75, "定价竞争力": 70, "客户支持": 82}}, + {"name": "京东物流AI", "scores": {"技术壁垒": 70, "产品成熟度": 88, "用户体验": 85, "生态集成": 90, "定价竞争力": 65, "客户支持": 78}}], + roadmap_suggestions="建议优先提升客户支持能力(增加2名CSM)和优化定价策略(引入阶梯定价),同时加强生态集成(对接ERP系统)。"), + ProductDiagnostic(company_id=COMP_C, product_name="工业质检视觉AI平台", + dimensions={"技术壁垒": 88, "产品成熟度": 85, "用户体验": 78, "生态集成": 72, "定价竞争力": 65, "客户支持": 80}, + heatmap_data={"strengths": ["技术壁垒", "产品成熟度", "客户支持"], "weaknesses": ["定价竞争力", "生态集成"], "neutral": ["用户体验"]}, + competitors=[{"name": "康代智能", "scores": {"技术壁垒": 82, "产品成熟度": 90, "用户体验": 82, "生态集成": 85, "定价竞争力": 75, "客户支持": 85}}, + {"name": "奥普特", "scores": {"技术壁垒": 75, "产品成熟度": 82, "用户体验": 78, "生态集成": 80, "定价竞争力": 82, "客户支持": 80}}], + roadmap_suggestions="技术优势明显,建议降低硬件成本(考虑国产替代方案)并加强生态集成(对接MES系统)。"), + ] + for d in diagnostics: + db.add(d) + await db.flush() + print(" ✓ 产品诊断 (2 条)") + + +# ─── 同行学习圈 ──────────────────────────────────────────────────────── +async def _seed_peer_circles(db: AsyncSession) -> None: + """同行学习圈 — AI 匹配面临类似挑战的创始人。""" + circles = [ + PeerLearningCircle(tenant_id=TENANT_ID, topic="融资时机选择:现在 vs 等待验证", + description="云栈数据和量子芯微创始人均面临融资时机决策,AI匹配讨论。", + members=[{"founder_id": FOUNDER_B, "company_id": COMP_B, "name": "刘云栈"}, + {"founder_id": FOUNDER_C, "company_id": COMP_D, "name": "赵深瞳(代)"}], + discussion_framework={"steps": ["各自分享融资困境", "分析共同风险", "讨论应对策略", "制定行动承诺"]}, + conclusions="两位创始人一致认为:在营收未达预期时,应优先保证现金Runway > 12月,融资宁可早不要晚。", + action_commitments=[{"founder": "刘云栈", "action": "2周内完成BP", "deadline": "14天"}, + {"founder": "赵深瞳(代)", "action": "启动天使+轮", "deadline": "7天"}], + status="completed"), + PeerLearningCircle(tenant_id=TENANT_ID, topic="客户集中度风险管理", + description="深瞳智能和智链科技都面临客户集中度/流失问题。", + members=[{"founder_id": FOUNDER_A, "company_id": COMP_A, "name": "陈智链"}, + {"founder_id": FOUNDER_C, "company_id": COMP_C, "name": "赵深瞳"}], + discussion_framework={"steps": ["分享客户结构", "分析流失原因", "讨论多元化策略", "制定行动承诺"]}, + conclusions="深瞳:半导体占比60%需降低;智链:流失率4%需降至3%以下。共同策略:建立客户健康度预警机制。", + action_commitments=[{"founder": "陈智链", "action": "建立客户健康度周报", "deadline": "30天"}, + {"founder": "赵深瞳", "action": "启动新能源客户拓展", "deadline": "60天"}], + status="active"), + ] + for c in circles: + db.add(c) + await db.flush() + print(" ✓ 同行学习圈 (2 个)") + + +# ─── 数字孪生 ────────────────────────────────────────────────────────── +async def _seed_digital_twins(db: AsyncSession) -> None: + """数字孪生模型。""" + twins = [ + DigitalTwinModel(company_id=COMP_A, model_params={"revenue_model": "saaS_subscription", "churn_rate": 0.03, "growth_rate": 0.15, "cac": 50, "ltv": 400}, + scenarios=[{"name": "乐观", "revenue_y0": 800, "revenue_y1": 1200, "runway_months": 18}, + {"name": "基准", "revenue_y0": 800, "revenue_y1": 1000, "runway_months": 14}, + {"name": "悲观", "revenue_y0": 800, "revenue_y1": 700, "runway_months": 10}], + accuracy_score=0.82, last_calibrated_at=D(7)), + DigitalTwinModel(company_id=COMP_C, model_params={"revenue_model": "hardware+software", "semi_ratio": 0.60, "growth_rate": 0.22, "gross_margin": 0.55}, + scenarios=[{"name": "乐观", "revenue_y0": 1200, "revenue_y1": 1800, "valuation": "15亿"}, + {"name": "基准", "revenue_y0": 1200, "revenue_y1": 1500, "valuation": "12亿"}, + {"name": "悲观", "revenue_y0": 1200, "revenue_y1": 1000, "valuation": "8亿"}], + accuracy_score=0.78, last_calibrated_at=D(14)), + ] + for t in twins: + db.add(t) + await db.flush() + print(" ✓ 数字孪生 (2 个)") + + +# ─── 干预事件 + 结果(Alpha 归因) ───────────────────────────────────── +async def _seed_interventions(db: AsyncSession) -> None: + """投后管理 Alpha 归因 — 干预 → 指标变化 → 估值影响。""" + interventions = [ + InterventionEvent(company_id=COMP_A, intervention_type="customer_intro", + title="引荐LP制造业客户给智链科技", description="通过LP关系引荐3家制造业客户,加速客户拓展。", + executed_by=GP_ID, executed_at=D(30)), + InterventionEvent(company_id=COMP_C, intervention_type="strategy", + title="建议深瞳智能拓展新能源客户", description="降低半导体客户集中度,拓展新能源赛道。", + executed_by=LEAD_ID, executed_at=D(45)), + InterventionEvent(company_id=COMP_A, intervention_type="governance", + title="推动智链科技建立客户成功团队", description="增加2名CSM,建立客户健康度周报机制。", + executed_by=MGR_ID, executed_at=D(60)), + InterventionEvent(company_id=COMP_D, intervention_type="funding", + title="协助量子芯微准备天使+轮融资", description="GP直接参与BP打磨和投资人对接。", + executed_by=GP_ID, executed_at=D(10)), + ] + for i in interventions: + db.add(i) + await db.flush() + + results = [ + InterventionResult(intervention_id=interventions[0].id, + metric_changes={"customers_new": 2, "revenue_increase": 320, "sales_cycle_reduction": 30}, + valuation_impact=0.5, return_contribution=0.15, alpha_score=0.82, + evidence={"before": {"customers": 48, "revenue": 800}, "after": {"customers": 50, "revenue": 960}}), + InterventionResult(intervention_id=interventions[1].id, + metric_changes={"semi_ratio": -0.05, "new_customers": 1, "revenue_diversification": 0.10}, + valuation_impact=0.3, return_contribution=0.08, alpha_score=0.68, + evidence={"before": {"semi_ratio": 0.65, "customers": 20}, "after": {"semi_ratio": 0.60, "customers": 21}}), + InterventionResult(intervention_id=interventions[2].id, + metric_changes={"churn_rate": -0.01, "csat": 8, "response_time": -40}, + valuation_impact=0.2, return_contribution=0.06, alpha_score=0.72, + evidence={"before": {"churn_rate": 0.04, "csat": 7.2}, "after": {"churn_rate": 0.03, "csat": 8.0}}), + ] + for r in results: + db.add(r) + await db.flush() + print(" ✓ 干预事件 (4) + 结果 (3) — Alpha 归因") + + +# ─── 组合再平衡 + Monte Carlo ────────────────────────────────────────── +async def _seed_portfolio_simulations(db: AsyncSession) -> None: + """组合再平衡建议 + Monte Carlo 模拟结果。""" + db.add(PortfolioRebalancing( + tenant_id=TENANT_ID, + marginal_returns={"COMP_A": 0.25, "COMP_B": 0.08, "COMP_C": 0.35, "COMP_D": -0.05, "COMP_E": 0.15}, + reallocation_plan={"reduce": [{"company": "COMP_B", "amount": 500, "reason": "边际回报低"}], + "increase": [{"company": "COMP_C", "amount": 300, "reason": "高增长高回报"}, {"company": "COMP_A", "amount": 200, "reason": "上升趋势明确"}]}, + irr_impact=0.03, dpi_impact=0.02, status="proposed", + )) + + # Monte Carlo — 生成 IRR/DPI 概率分布 + random.seed(42) + irr_samples = [random.gauss(0.22, 0.08) for _ in range(10000)] + irr_buckets = {} + for s in irr_samples: + bucket = round(s * 2) / 2 # 0.5% 区间 + irr_buckets[str(bucket)] = irr_buckets.get(str(bucket), 0) + 1 + + dpi_samples = [max(0, random.gauss(1.8, 0.4)) for _ in range(10000)] + dpi_buckets = {} + for s in dpi_samples: + bucket = round(s * 2) / 2 + dpi_buckets[str(bucket)] = dpi_buckets.get(str(bucket), 0) + 1 + + db.add(MonteCarloSimulation( + tenant_id=TENANT_ID, iterations=10000, + irr_distribution=irr_buckets, dpi_distribution=dpi_buckets, + percentile_p5=0.08, percentile_p50=0.22, percentile_p95=0.36, + )) + await db.flush() + print(" ✓ 组合再平衡 (1) + Monte Carlo (1)") + + +# ─── 知识图谱 ────────────────────────────────────────────────────────── +async def _seed_knowledge_graph(db: AsyncSession) -> None: + """知识图谱节点 — 企业特征 + 管理动作 + 环境上下文 → 结果 → 回报影响。""" + nodes = [ + KnowledgeNode(tenant_id=TENANT_ID, entity_type="company", entity_id=COMP_A, + attributes={"name": "智链科技", "industry": "AI/供应链", "stage": "B"}, + relations=[{"target": "action_1", "type": "received"}, {"target": "context_1", "type": "in"}]), + KnowledgeNode(tenant_id=TENANT_ID, entity_type="action", entity_id="action_1", + attributes={"type": "customer_intro", "title": "引荐LP制造业客户"}, + relations=[{"target": "result_1", "type": "led_to"}]), + KnowledgeNode(tenant_id=TENANT_ID, entity_type="context", entity_id="context_1", + attributes={"type": "market", "description": "制造业数字化转型加速"}, + relations=[{"target": "result_1", "type": "influenced"}]), + KnowledgeNode(tenant_id=TENANT_ID, entity_type="result", entity_id="result_1", + attributes={"metric": "revenue", "change": "+20%", "duration": "3月"}, + relations=[{"target": "return_1", "type": "contributed_to"}]), + KnowledgeNode(tenant_id=TENANT_ID, entity_type="return", entity_id="return_1", + attributes={"irr_impact": 0.15, "alpha_score": 0.82}, + relations=[]), + ] + for n in nodes: + db.add(n) + await db.flush() + print(" ✓ 知识图谱 (5 节点)") + + +# ─── 数据源 ──────────────────────────────────────────────────────────── +async def _seed_data_sources(db: AsyncSession) -> None: + """外部数据源配置。""" + sources = [ + DataSource(tenant_id=TENANT_ID, source_type="crunchbase", name="Crunchbase API", + api_endpoint="https://api.crunchbase.com/v3.1", status="active", last_synced_at=D(1), + config={"sync_frequency": "daily"}), + DataSource(tenant_id=TENANT_ID, source_type="github", name="GitHub 活跃度监测", + api_endpoint="https://api.github.com", status="active", last_synced_at=D(1), + config={"repos": ["zhilian/ai-engine", "yunzhan/data-platform"]}), + DataSource(tenant_id=TENANT_ID, source_type="business_registry", name="工商信息同步", + api_endpoint="https://api.qcc.com/v2", status="active", last_synced_at=D(3), + config={"sync_frequency": "weekly"}), + DataSource(tenant_id=TENANT_ID, company_id=COMP_C, source_type="custom", name="半导体行业数据库", + api_endpoint="https://semi-data.example.com/api", status="active", last_synced_at=D(2), + config={"metrics": ["industry_growth", "competitor_funding"]}), + ] + for s in sources: + db.add(s) + await db.flush() + print(" ✓ 数据源 (4 个)") + + if __name__ == "__main__": asyncio.run(seed()) diff --git a/frontend/src/app/(investor)/agents/page.tsx b/frontend/src/app/(investor)/agents/page.tsx index 238f695..4c9f6ce 100644 --- a/frontend/src/app/(investor)/agents/page.tsx +++ b/frontend/src/app/(investor)/agents/page.tsx @@ -26,8 +26,14 @@ export default function AgentsPage() { const load = () => { listAgentExecutions() - .then((resp) => setItems((resp.data as AgentExecution[]) ?? [])) - .catch(() => setItems([])) + .then((resp) => { + console.log("[agents] API response:", resp); + setItems((resp.data as AgentExecution[]) ?? []); + }) + .catch((err) => { + console.error("[agents] API error:", err); + setItems([]); + }) .finally(() => setIsLoading(false)); };