bichnhan2701 commited on
Commit
f313630
·
1 Parent(s): dd8f00c

Add note text internal api

Browse files
app/api/notes/notes_text_internal.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from fastapi import APIRouter, BackgroundTasks, HTTPException
3
+ from pydantic import BaseModel
4
+ from typing import List, Optional, Dict
5
+ from app.services.note_store import create_note, get_note
6
+ from app.jobs.async_enrichment_job import enrich_note
7
+ from app.models.enums import NoteType, NoteStatus
8
+ from app.utils.time import now_ts
9
+
10
+
11
+ router = APIRouter(prefix="/internal/notes", tags=["internal"])
12
+ logger = logging.getLogger(__name__)
13
+
14
+
15
+ class NoteTextInternalCreateRequest(BaseModel):
16
+ note_id: str
17
+ raw_text: str
18
+ folder_id: Optional[str] = None
19
+ generate: List[str] = []
20
+
21
+
22
+ @router.post("/text")
23
+ async def create_text_note_internal(req: NoteTextInternalCreateRequest, bg: BackgroundTasks):
24
+ """
25
+ Idempotent create for text notes:
26
+ - If note exists -> return current status
27
+ - Else create note with provided `note_id` and optionally enqueue enrichment
28
+ """
29
+ now = now_ts()
30
+
31
+ allowed = {"normalize", "keywords", "summary", "mindmap"}
32
+ if not set(req.generate).issubset(allowed):
33
+ raise HTTPException(400, "Invalid generate task")
34
+
35
+ # IDEMPOTENT CHECK
36
+ existing = get_note(req.note_id)
37
+ if existing:
38
+ logger.info("Note already exists, skip create note_id=%s", req.note_id)
39
+ return {
40
+ "note_id": req.note_id,
41
+ "status": existing.get("status"),
42
+ }
43
+
44
+ has_enrichment = bool(req.generate)
45
+ note = {
46
+ "note_id": req.note_id,
47
+ "type": NoteType.text,
48
+ "raw_text": req.raw_text,
49
+ "folder_id": req.folder_id,
50
+ "status": NoteStatus.processing if has_enrichment else NoteStatus.created,
51
+ "created_at": now,
52
+ "updated_at": now,
53
+ }
54
+
55
+ # Prepare fields for enrichment if requested
56
+ if req.generate:
57
+ note.update({
58
+ "normalized_text": None,
59
+ "title": None,
60
+ "keywords": [],
61
+ "summary": None,
62
+ "mindmap": None,
63
+ "generate": req.generate,
64
+ })
65
+
66
+ try:
67
+ create_note(note)
68
+ except ValueError:
69
+ # race: another worker created it first
70
+ logger.warning("Race create_note, ignore note_id=%s", req.note_id)
71
+ existing = get_note(req.note_id)
72
+ return {
73
+ "note_id": req.note_id,
74
+ "status": existing.get("status") if existing else NoteStatus.created,
75
+ }
76
+
77
+ # enqueue enrichment if requested
78
+ if req.generate:
79
+ try:
80
+ bg.add_task(enrich_note, req.note_id, req.generate)
81
+ except Exception:
82
+ # don't fail the request if enqueue fails; log and continue
83
+ logger.exception("Failed to enqueue enrich_note for %s", req.note_id)
84
+
85
+ return {"note_id": req.note_id, "status": note["status"]}
app/main.py CHANGED
@@ -1,5 +1,5 @@
1
  from fastapi import FastAPI
2
- from app.api.notes import notes_text, notes_audio, notes_get, notes_update, notes_regenerate, notes_events, internal_notes
3
  from app.api.folders import folders_create, folders_get, folders_update, folders_delete
4
 
5
  app = FastAPI(title="Note Service API")
@@ -7,6 +7,7 @@ app = FastAPI(title="Note Service API")
7
  # Notes
8
  app.include_router(notes_text.router)
9
  app.include_router(notes_audio.router)
 
10
  app.include_router(notes_get.router)
11
  app.include_router(notes_update.router)
12
  app.include_router(notes_regenerate.router)
 
1
  from fastapi import FastAPI
2
+ from app.api.notes import notes_text, notes_audio, notes_text_internal, notes_get, notes_update, notes_regenerate, notes_events, internal_notes
3
  from app.api.folders import folders_create, folders_get, folders_update, folders_delete
4
 
5
  app = FastAPI(title="Note Service API")
 
7
  # Notes
8
  app.include_router(notes_text.router)
9
  app.include_router(notes_audio.router)
10
+ app.include_router(notes_text_internal.router)
11
  app.include_router(notes_get.router)
12
  app.include_router(notes_update.router)
13
  app.include_router(notes_regenerate.router)