B2D-agentic-ai / backend /routers /projects.py
AMRYB's picture
Upload 91 files
287f3d3 verified
Raw
History Blame Contribute Delete
3.2 kB
"""Projects management and state CRUD router."""
from __future__ import annotations
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field
from agentic_core.agents import known_info_snapshot
from agentic_core.schemas import ProjectContext
from ..deps import services
router = APIRouter(prefix="/api/projects", tags=["Projects"])
class CreateProjectRequest(BaseModel):
business_idea: str = Field(min_length=1)
def load_project(project_id: str) -> ProjectContext:
context = services.project_store.load(project_id)
if context is None:
raise HTTPException(status_code=404, detail=f"Project {project_id!r} not found")
return context
def save_project(context: ProjectContext) -> None:
services.project_store.save(context)
def project_response(context: ProjectContext, discovery: dict | None = None) -> dict:
return {
"project_id": context.project_id,
"status": context.status,
"business_idea": context.business_idea,
"summary": project_summary(context),
"known_information": known_info_snapshot(context),
"transcript": [turn.model_dump() for turn in context.transcript],
"discovery": discovery,
}
def project_summary(context: ProjectContext) -> dict:
return {
"problem": context.problem,
"target_users": context.target_users,
"user_roles": context.user_roles,
"business_goals": context.business_goals,
"core_features": context.core_features,
"constraints": context.constraints,
"integrations": context.integrations,
"technology_preferences": context.technology_preferences,
}
@router.get("")
async def list_projects():
"""List all project IDs stored in the system."""
return {"projects": services.project_store.list_ids()}
@router.post("", status_code=201)
async def create_project(request: CreateProjectRequest):
"""Create a project and run the first discovery turn."""
context = services.project_store.create(request.business_idea)
output = await services.orchestrator.discovery_turn(context, request.business_idea)
save_project(context)
return project_response(context, output.model_dump())
@router.get("/{project_id}")
async def get_project(project_id: str):
"""Fetch full project state, context, and summary."""
context = load_project(project_id)
return project_response(context)
@router.delete("/{project_id}")
async def delete_project(project_id: str):
"""Delete a project state from persistent SQLite store."""
deleted = services.project_store.delete(project_id)
if not deleted:
raise HTTPException(status_code=404, detail=f"Project {project_id!r} not found")
return {"status": "deleted", "project_id": project_id}
@router.get("/{project_id}/runs")
async def get_project_runs(project_id: str):
"""Fetch per-agent execution logs and telemetry records for a project."""
load_project(project_id)
records = services.tracker.list(project_id)
return {"project_id": project_id, "runs": [r.model_dump() for r in records]}