195 lines
5.7 KiB
Python
195 lines
5.7 KiB
Python
"""Seed projects and signals, including Pixelle SSTC bootstrap."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from typing import Optional
|
|
|
|
from sqlalchemy import func, or_, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from app.models import Project, ProjectSignalLink, Signal, TruthNode
|
|
from app.seed_projects_helpers import (
|
|
build_ai_signal,
|
|
build_pixelle_signals,
|
|
create_pixelle_charter_and_tasks,
|
|
ensure_seed_user,
|
|
pick_signal_ids,
|
|
)
|
|
|
|
PIXELLE_NAME = "Pixelle-Video 集成"
|
|
|
|
|
|
async def seed_pixelle_project(db: Optional[AsyncSession] = None):
|
|
"""创建或恢复 Pixelle-Video 示例项目与 SSTC 数据。"""
|
|
from app.database import engine
|
|
|
|
if db is None:
|
|
async_session_maker = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
async with async_session_maker() as session:
|
|
await _seed_projects(session)
|
|
else:
|
|
await _seed_projects(db)
|
|
|
|
|
|
async def _ensure_pixelle_sstc_data(session: AsyncSession, pixelle_project: Project) -> bool:
|
|
"""为已有项目补齐关联信号、宪章和任务。"""
|
|
pid = pixelle_project.id
|
|
|
|
link_count = await session.execute(
|
|
select(func.count()).select_from(ProjectSignalLink).where(ProjectSignalLink.project_id == pid)
|
|
)
|
|
has_links = (link_count.scalar() or 0) > 0
|
|
|
|
charter_count = await session.execute(
|
|
select(func.count()).select_from(TruthNode).where(
|
|
TruthNode.project_id == pid,
|
|
TruthNode.node_type == "charter",
|
|
)
|
|
)
|
|
has_charters = (charter_count.scalar() or 0) > 0
|
|
if has_links and has_charters:
|
|
return False
|
|
|
|
changed = False
|
|
pixelle_signals: list[Signal] = []
|
|
|
|
if not has_links:
|
|
pixelle_signals = build_pixelle_signals()
|
|
for signal in pixelle_signals:
|
|
session.add(signal)
|
|
await session.flush()
|
|
|
|
for signal in pixelle_signals:
|
|
session.add(
|
|
ProjectSignalLink(
|
|
project_id=pid,
|
|
signal_id=signal.id,
|
|
link_type="related",
|
|
relevance_score=1.0,
|
|
)
|
|
)
|
|
|
|
pixelle_project.signal_count = len(pixelle_signals)
|
|
changed = True
|
|
await session.flush()
|
|
|
|
if not has_charters:
|
|
seed_user = await ensure_seed_user(session)
|
|
if pixelle_signals:
|
|
signal_ids = pick_signal_ids(pixelle_signals)
|
|
else:
|
|
link_rows = await session.execute(
|
|
select(ProjectSignalLink.signal_id).where(ProjectSignalLink.project_id == pid)
|
|
)
|
|
signal_ids = [row[0] for row in link_rows.fetchall()]
|
|
|
|
await create_pixelle_charter_and_tasks(
|
|
session,
|
|
project_id=pid,
|
|
created_by=seed_user.id,
|
|
signal_ids=signal_ids,
|
|
)
|
|
|
|
changed = True
|
|
print(f"[SSTC] 已为「{PIXELLE_NAME}」恢复宪章 1 个、任务 3 个")
|
|
|
|
return changed
|
|
|
|
|
|
async def _seed_projects(session: AsyncSession):
|
|
result = await session.execute(select(Project).where(or_(Project.title == PIXELLE_NAME, Project.name == PIXELLE_NAME)))
|
|
existing = result.scalar_one_or_none()
|
|
if existing:
|
|
restored = await _ensure_pixelle_sstc_data(session, existing)
|
|
if restored:
|
|
await session.commit()
|
|
else:
|
|
print("示例项目已存在且 SSTC 数据完整,跳过")
|
|
return
|
|
|
|
pixelle_signals = build_pixelle_signals()
|
|
for signal in pixelle_signals:
|
|
session.add(signal)
|
|
await session.flush()
|
|
|
|
pixelle_project = Project(
|
|
name=PIXELLE_NAME,
|
|
title=PIXELLE_NAME,
|
|
description="集成 Pixelle-Video AI 视频生成平台到主系统",
|
|
status="active",
|
|
assigned_role="backend",
|
|
signal_count=len(pixelle_signals),
|
|
)
|
|
session.add(pixelle_project)
|
|
await session.flush()
|
|
|
|
for signal in pixelle_signals:
|
|
session.add(
|
|
ProjectSignalLink(
|
|
project_id=pixelle_project.id,
|
|
signal_id=signal.id,
|
|
link_type="related",
|
|
relevance_score=1.0,
|
|
)
|
|
)
|
|
|
|
ai_analyst_project = Project(
|
|
name="AI 分析引擎优化",
|
|
title="AI 分析引擎优化",
|
|
description="优化 LLM 服务性能,实现多模型投票机制和 RAG 检索增强",
|
|
status="active",
|
|
assigned_role="ai_engineer",
|
|
signal_count=1,
|
|
)
|
|
session.add(ai_analyst_project)
|
|
await session.flush()
|
|
|
|
ai_signal = build_ai_signal()
|
|
session.add(ai_signal)
|
|
await session.flush()
|
|
|
|
session.add(
|
|
ProjectSignalLink(
|
|
project_id=ai_analyst_project.id,
|
|
signal_id=ai_signal.id,
|
|
link_type="related",
|
|
relevance_score=0.9,
|
|
)
|
|
)
|
|
|
|
seed_user = await ensure_seed_user(session)
|
|
await create_pixelle_charter_and_tasks(
|
|
session,
|
|
project_id=pixelle_project.id,
|
|
created_by=seed_user.id,
|
|
signal_ids=pick_signal_ids(pixelle_signals),
|
|
)
|
|
|
|
await session.commit()
|
|
|
|
print("创建示例项目:")
|
|
print(f" - {pixelle_project.title} ({pixelle_project.assigned_role})")
|
|
print(f" - {ai_analyst_project.title} ({ai_analyst_project.assigned_role})")
|
|
print(f"\n关联信号: {len(pixelle_signals) + 1} 条")
|
|
print("[SSTC] Pixelle-Video 宪章 1 个,任务 3 个")
|
|
|
|
|
|
async def main():
|
|
print("开始初始化示例数据...")
|
|
|
|
from app.database import engine
|
|
from app.models import Base
|
|
|
|
async with engine.begin() as conn:
|
|
await conn.run_sync(Base.metadata.create_all)
|
|
|
|
await seed_pixelle_project()
|
|
|
|
print("\n初始化完成!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|