You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

78 lines
2.4 KiB

"""
routers/documents.py — Document CRUD and graph endpoints.
"""
from __future__ import annotations
from typing import Optional
from fastapi import APIRouter, HTTPException, Depends
import asyncpg
from core.database import get_pool
from core.settings import Settings
from models.responses import DocumentResponse, GraphResponse, GraphNode, GraphEdge, RelatedDocument, TagCount
from services.retriever import get_related
router = APIRouter(prefix='/document', tags=['documents'])
def _get_settings() -> Settings:
from main import app_settings
return app_settings
@router.get('/{document_id}', response_model=DocumentResponse)
async def get_document(document_id: str):
pool = await get_pool()
async with pool.acquire() as conn:
row = await conn.fetchrow(
'SELECT * FROM documents WHERE id = $1::uuid', document_id
)
if not row:
raise HTTPException(status_code=404, detail='Document not found')
return _row_to_doc(row)
@router.get('/path/{path:path}', response_model=DocumentResponse)
async def get_document_by_path(path: str):
pool = await get_pool()
async with pool.acquire() as conn:
row = await conn.fetchrow('SELECT * FROM documents WHERE path = $1', path)
if not row:
raise HTTPException(status_code=404, detail='Document not found')
return _row_to_doc(row)
@router.get('/{document_id}/related', response_model=list[RelatedDocument])
async def related_documents(document_id: str, limit: int = 5):
pool = await get_pool()
async with pool.acquire() as conn:
related = await get_related(conn, document_id, limit=limit)
return [RelatedDocument(**r) for r in related]
def _row_to_doc(row: asyncpg.Record) -> DocumentResponse:
# Handle frontmatter - asyncpg returns JSONB as dict directly
fm = row['frontmatter']
if fm is None:
frontmatter = {}
elif isinstance(fm, dict):
frontmatter = fm
else:
# Fallback for unexpected types
frontmatter = {}
return DocumentResponse(
id=str(row['id']),
path=row['path'],
title=row['title'] or '',
content=row['content'],
frontmatter=frontmatter,
tags=list(row['tags'] or []),
aliases=list(row['aliases'] or []),
word_count=row['word_count'],
created_at=row['created_at'],
updated_at=row['updated_at'],
indexed_at=row['indexed_at'],
)

Powered by TurnKey Linux.