import logging from fastapi import APIRouter, BackgroundTasks, HTTPException from pydantic import BaseModel from typing import Dict, List, Optional from app.services.note_store import create_note, get_note from app.models.enums import NoteType, NoteStatus from app.utils.time import now_ts router = APIRouter(prefix="/internal/notes", tags=["internal"]) logger = logging.getLogger(__name__) class CreateAudioNoteRequest(BaseModel): note_id: str raw_text: str metadata: Dict generate: List[str] = [] @router.post("/audio") async def create_audio_note(req: CreateAudioNoteRequest, bg: BackgroundTasks): """ Idempotent create: - Nếu note đã tồn tại → return luôn - KHÔNG throw 500 vì duplicate """ now = now_ts() allowed = {"normalize", "keywords", "summary", "mindmap"} if not set(req.generate).issubset(allowed): raise HTTPException(400, "Invalid generate task") # 🔒 IDEMPOTENT CHECK existing = get_note(req.note_id) if existing: logger.info("Note already exists, skip create note_id=%s", req.note_id) return { "note_id": req.note_id, "status": existing.get("status"), } note = { "note_id": req.note_id, "type": NoteType.audio, "raw_text": req.raw_text, "metadata": req.metadata, # 🔥 PLACEHOLDER → CREATED "status": NoteStatus.created, "created_at": now, "updated_at": now, } # Chuẩn bị field cho enrich (nhưng CHƯA chạy) if req.generate: note.update({ "normalized_text": None, "title": None, "keywords": [], "summary": None, "mindmap": None, }) try: create_note(note) except ValueError: # double-safe (race condition) logger.warning("Race create_note, ignore note_id=%s", req.note_id) # ❌ KHÔNG chạy enrich ở đây # enrich CHỈ được trigger sau ASR xong (transcribed) return { "note_id": req.note_id, "status": note["status"], }