PMFlow/backend/app/seed_projects_helpers.py

173 lines
5.2 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.

"""Helpers for seed project creation and SSTC recovery."""
from __future__ import annotations
import json
from typing import Optional
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models import Signal, Task, TruthNode, User
from app.services.auth import AuthService
PIXELLE_SIGNAL_CONTENTS = [
(
"HackerNews",
"Pixelle-Video: An AI-powered automated short video generation platform with script-to-video automation",
9.2,
"critical",
),
(
"ProductHunt",
"Pixelle-Video launches API for programmatic video content generation",
8.5,
"high",
),
(
"TechCrunch",
"Pixelle-Video raises Series A funding to scale AI video infrastructure",
7.8,
"high",
),
]
PIXELLE_TASK_BLUEPRINT = [
{"title": "Integrate Pixelle-Video API", "priority": "high", "hours": 8.0},
{"title": "Design Video Workflow UI", "priority": "medium", "hours": 12.0},
{"title": "Optimize Video Pipeline", "priority": "medium", "hours": 16.0},
]
def _build_signal_payload(impact_score: float) -> tuple[str, str]:
strategic_analysis = json.dumps(
{
"decision_proposal": {
"is_strategic": True,
"threat_level": "HIGH",
"lead_time_days": 14,
"impact_score": impact_score,
"recommendation": "立即集成 Pixelle-Video API 到主平台",
},
"competitiveness_radar": {
"innovation": 85,
"market_potential": 90,
"technical_complexity": 75,
"resource_intensity": 70,
},
"detected_tech_stacks": ["AI/ML", "Video Processing", "REST API"],
"related_knowledge_nodes": [],
"rag_context_used": 0,
}
)
tasks_generated = json.dumps(
[
{"task_name": "Integrate Pixelle-Video API", "type": "backend", "estimated_hours": 8.0},
{"task_name": "Design Video Workflow UI", "type": "frontend", "estimated_hours": 12.0},
{"task_name": "Optimize Video Pipeline", "type": "ai_engineer", "estimated_hours": 16.0},
]
)
return strategic_analysis, tasks_generated
def build_pixelle_signals() -> list[Signal]:
signals: list[Signal] = []
for source, content, impact_score, priority in PIXELLE_SIGNAL_CONTENTS:
signal = Signal(
source=source,
content=content,
impact_score=impact_score,
priority=priority,
processed=True,
)
strategic_analysis, tasks_generated = _build_signal_payload(impact_score)
signal.strategic_analysis = strategic_analysis
signal.tasks_generated = tasks_generated
signals.append(signal)
return signals
async def ensure_seed_user(session: AsyncSession) -> User:
user_result = await session.execute(select(User).limit(1))
seed_user = user_result.scalar_one_or_none()
if seed_user:
return seed_user
seed_user = User(
username="boss",
email="boss@pmflow.local",
password_hash=AuthService.hash_password("boss123"),
name="负责人",
role="BOSS",
status="active",
)
session.add(seed_user)
await session.flush()
return seed_user
async def create_pixelle_charter_and_tasks(
session: AsyncSession,
*,
project_id: int,
created_by: int,
signal_ids: list[int],
) -> TruthNode:
charter = TruthNode(
node_type="charter",
parent_id=None,
project_id=project_id,
created_by=created_by,
title="Pixelle-Video 集成需求宪章",
content={
"rationale": "基于 HackerNews/ProductHunt/TechCrunch 信号,决定集成 Pixelle-Video API 到主平台",
"signal_ids": signal_ids,
"decision": "立即集成 Pixelle-Video API,支持脚本到视频的自动化生成",
},
version=1,
status="aligned",
)
session.add(charter)
await session.flush()
for task_item in PIXELLE_TASK_BLUEPRINT:
task = Task(
truth_node_id=charter.id,
project_id=project_id,
title=task_item["title"],
required_skill_tag_ids=[],
status="todo",
priority=task_item["priority"],
estimated_hours=task_item["hours"],
)
session.add(task)
return charter
def build_ai_signal() -> Signal:
signal = Signal(
source="ArXiv",
content="New paper: Multi-Agent LLM Voting System improves accuracy by 23%",
impact_score=7.5,
priority="medium",
processed=True,
)
signal.strategic_analysis = json.dumps(
{
"decision_proposal": {
"is_strategic": True,
"threat_level": "MEDIUM",
"lead_time_days": 30,
"impact_score": 7.5,
"recommendation": "实现多模型投票机制提升 AI 分析准确性",
},
"detected_tech_stacks": ["LLM", "Voting", "Multi-Agent"],
}
)
return signal
def pick_signal_ids(signals: Optional[list[Signal]]) -> list[int]:
return [signal.id for signal in (signals or []) if signal.id is not None]