""" 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)}")