62 lines
1.8 KiB
Python
62 lines
1.8 KiB
Python
|
|
"""Projects router — registered git repos + work contexts from Redis."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Optional
|
||
|
|
|
||
|
|
from fastapi import APIRouter
|
||
|
|
|
||
|
|
from app.redis_client import get_redis, list_projects, list_workcontexts, PROJECT_KEY_PREFIX, WORKCONTEXT_KEY_PREFIX
|
||
|
|
|
||
|
|
router = APIRouter(prefix="/api/v1", tags=["projects"])
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/projects")
|
||
|
|
def api_list_projects(context: Optional[str] = None, q: Optional[str] = None):
|
||
|
|
r = get_redis()
|
||
|
|
projects = list_projects(r, context=context)
|
||
|
|
|
||
|
|
# Merge in work contexts (keyed by path)
|
||
|
|
wc_keys = r.keys(f"{WORKCONTEXT_KEY_PREFIX}*")
|
||
|
|
import json
|
||
|
|
work_contexts: dict = {}
|
||
|
|
for key in wc_keys:
|
||
|
|
raw = r.get(key)
|
||
|
|
if raw:
|
||
|
|
try:
|
||
|
|
path = key[len(WORKCONTEXT_KEY_PREFIX):]
|
||
|
|
work_contexts[path] = json.loads(raw)
|
||
|
|
except Exception:
|
||
|
|
pass
|
||
|
|
|
||
|
|
# Attach work context and apply search filter
|
||
|
|
result = []
|
||
|
|
for p in projects:
|
||
|
|
path = p.get("path", "")
|
||
|
|
p["work_context"] = work_contexts.get(path)
|
||
|
|
if q and q.lower() not in (p.get("name", "") + p.get("path", "") + " ".join(p.get("tags", []))).lower():
|
||
|
|
continue
|
||
|
|
result.append(p)
|
||
|
|
|
||
|
|
# Sort: projects with recent work context first
|
||
|
|
result.sort(
|
||
|
|
key=lambda p: (
|
||
|
|
p["work_context"]["saved_at"] if p.get("work_context") else "",
|
||
|
|
),
|
||
|
|
reverse=True,
|
||
|
|
)
|
||
|
|
|
||
|
|
# Context breakdown
|
||
|
|
contexts = {}
|
||
|
|
for p in result:
|
||
|
|
c = p.get("context", "unknown")
|
||
|
|
contexts[c] = contexts.get(c, 0) + 1
|
||
|
|
|
||
|
|
return {"projects": result, "total": len(result), "contexts": contexts}
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/workcontexts")
|
||
|
|
def api_list_workcontexts():
|
||
|
|
r = get_redis()
|
||
|
|
return {"contexts": list_workcontexts(r)}
|