mindnet/app/routers/ingest.py
2025-12-11 11:11:01 +01:00

108 lines
3.2 KiB
Python

"""
app/routers/ingest.py
API-Endpunkte für WP-11 (Discovery & Persistence).
Fixed Async/Await Integration with Discovery Service.
"""
import os
import time
import logging
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import Optional, Dict, Any
from app.core.ingestion import IngestionService
# WICHTIG: Wir nutzen wieder den spezialisierten DiscoveryService
from app.services.discovery import DiscoveryService
logger = logging.getLogger(__name__)
router = APIRouter()
# --- DTOs ---
class AnalyzeRequest(BaseModel):
text: str
type: str = "concept"
class SaveRequest(BaseModel):
markdown_content: str
filename: Optional[str] = None
folder: str = "00_Inbox"
class SaveResponse(BaseModel):
status: str
file_path: str
note_id: str
stats: Dict[str, Any]
# --- Services ---
discovery_service = DiscoveryService()
# --- Endpoints ---
@router.post("/analyze")
async def analyze_draft(req: AnalyzeRequest):
"""
WP-11 Intelligence: Liefert Link-Vorschläge (Exact + Semantic).
"""
try:
# Wir delegieren an den Service, der Exact Matching, Config und Semantik beherrscht
result = await discovery_service.analyze_draft(req.text, req.type)
return result
except Exception as e:
logger.error(f"Analyze failed: {e}", exc_info=True)
raise HTTPException(status_code=500, detail=f"Analysis failed: {str(e)}")
@router.post("/save", response_model=SaveResponse)
async def save_note(req: SaveRequest):
"""
WP-11 Persistence: Speichert Markdown physisch und indiziert es sofort.
"""
try:
# 1. Pfad-Setup
vault_root = os.getenv("MINDNET_VAULT_ROOT", "./vault")
abs_vault_root = os.path.abspath(vault_root)
if not os.path.exists(abs_vault_root):
try:
os.makedirs(abs_vault_root, exist_ok=True)
except Exception:
raise HTTPException(status_code=500, detail=f"Vault root missing and cannot create: {abs_vault_root}")
# 2. Filename
final_filename = req.filename
if not final_filename:
final_filename = f"draft_{int(time.time())}.md"
# 3. Ingestion Service (Async)
ingest_service = IngestionService()
logger.info(f"Saving {final_filename} to {req.folder}")
# Async Call zum Ingestion Service
result = await ingest_service.create_from_text(
markdown_content=req.markdown_content,
filename=final_filename,
vault_root=abs_vault_root,
folder=req.folder
)
if result.get("status") == "error":
raise HTTPException(status_code=500, detail=result.get("error"))
return SaveResponse(
status="success",
file_path=result.get("path", "unknown"),
note_id=result.get("note_id", "unknown"),
stats={
"chunks": result.get("chunks_count", 0),
"edges": result.get("edges_count", 0)
}
)
except HTTPException as he:
raise he
except Exception as e:
logger.error(f"Save failed: {e}", exc_info=True)
raise HTTPException(status_code=500, detail=f"Save failed: {str(e)}")