myrmidon / python /src /server /services /projects /project_service.py
tek Atrust
chore(deploy): build monolithic server for Hugging Face
d5ef46f
Raw
History Blame Contribute Delete
4.66 kB
# python/src/server/services/projects/project_service.py
from typing import Any
from src.server.repositories.base_repository import BaseRepository
from ...config.logfire_config import get_logger
from .task_service import TaskService
logger = get_logger(__name__)
class ProjectService(BaseRepository):
def __init__(self, supabase_client=None):
super().__init__(supabase_client)
self.task_service = TaskService(self.supabase_client)
async def list_projects(
self, include_content: bool = True, include_computed_status: bool = False
) -> tuple[bool, dict[str, Any]]:
def _query():
return self.supabase_client.table("archon_projects").select("*").order("created_at", desc=True).execute()
success, result = self.execute_query(_query, "Database operation failed")
if success:
projects = result["data"]
for p in projects:
# Ensure 'stats' exists for UI/tests
if "stats" not in p:
# Original logic expected docs_count for token optimization tests
docs = p.get("docs") or {}
docs_count = len(docs) if isinstance(docs, dict) else (len(docs) if isinstance(docs, list) else 0)
features = p.get("features") or []
features_count = len(features) if isinstance(features, list) else 0
# Correct field check for has_data
data_field = p.get("data") or {}
has_data = bool(data_field)
p["stats"] = {
"task_count": 0,
"completed_tasks": 0,
"docs_count": docs_count,
"features_count": features_count,
"has_data": has_data,
}
if not include_content:
# LIGHTWEIGHT: Remove heavy fields
p.pop("docs", None)
p.pop("features", None)
p.pop("data", None)
return True, {"projects": projects}
return False, result
async def create_project(self, title: str, github_repo: str | None = None) -> tuple[bool, dict[str, Any]]:
project_data: dict[str, Any] = {
"title": title,
"github_repo": github_repo,
"status": "planning",
"docs": {},
"features": [],
"data": {},
}
def _query():
return self.supabase_client.table("archon_projects").insert(project_data).execute()
success, result = self.execute_query(_query, "Database operation failed")
if success:
return True, {"project": result["data"][0] if result["data"] else {}}
return False, result
async def get_project(self, project_id: str) -> tuple[bool, dict[str, Any]]:
def _query():
return self.supabase_client.table("archon_projects").select("*").eq("id", project_id).execute()
success, result = self.execute_query(_query, "DB operation logged error")
if success:
return True, {"project": result["data"][0] if result["data"] else {}}
return False, result
async def update_project(self, project_id: str, project_data: dict[str, Any]) -> tuple[bool, dict[str, Any]]:
def _query():
return self.supabase_client.table("archon_projects").update(project_data).eq("id", project_id).execute()
success, result = self.execute_query(_query, "Database operation failed")
if success:
return True, {"project": result["data"][0] if result["data"] else {}}
return False, result
async def delete_project(self, project_id: str) -> tuple[bool, dict[str, Any]]:
def _query():
return self.supabase_client.table("archon_projects").delete().eq("id", project_id).execute()
success, result = self.execute_query(_query, "Database operation failed")
if success:
return True, {"message": "Project deleted successfully"}
return False, result
async def get_project_features(self, project_id: str) -> tuple[bool, dict[str, Any]]:
"""Retrieve features for a project."""
def _query():
return (
self.supabase_client.table("archon_projects").select("features").eq("id", project_id).single().execute()
)
success, result = self.execute_query(_query, f"Failed to fetch features for project {project_id}")
if success:
return True, result.get("data", {})
return False, result