Files
claudia-docs-api/app/main.py
Motoko 07f9ac91fc Phase 3: Graph view, backlinks, quick switcher, export
- Add outgoing_links (JSON) and backlinks_count to Document model
- POST /documents/{id}/detect-links — detect [[uuid]] patterns in content
- GET /documents/{id}/backlinks — documents referencing this doc
- GET /documents/{id}/outgoing-links — documents this doc references
- GET /documents/{id}/links — combined incoming + outgoing
- GET /projects/{id}/graph — full project relationship graph
- GET /search/quick — fuzzy search (Quick Switcher Cmd+K)
- GET /projects/{id}/documents/search — project-scoped search
- GET /documents/{id}/export — markdown|json export
- GET /projects/{id}/export — json|zip export
- 27 new tests
2026-03-30 23:46:45 +00:00

66 lines
1.7 KiB
Python

import asyncio
from contextlib import asynccontextmanager
from datetime import datetime
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from app.config import settings
from app.database import init_db, get_db, async_engine
from app.routers import auth, projects, folders, documents, tags, search, links, export
from app.services.auth import cleanup_expired_blocklist
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup: init database
await init_db()
yield
# Shutdown
await async_engine.dispose()
app = FastAPI(
title="Claudia Docs API",
description="Gestor documental para agentes de IA",
version="1.0.0",
lifespan=lifespan,
)
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=settings.cors_origins_list,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Include routers
app.include_router(auth.router)
app.include_router(projects.router)
app.include_router(folders.router)
app.include_router(documents.router)
app.include_router(tags.router)
app.include_router(search.router)
app.include_router(links.router)
app.include_router(export.router)
@app.get("/api/v1/health")
async def health():
return {"status": "ok", "timestamp": datetime.utcnow().isoformat()}
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
import logging
logger = logging.getLogger(__name__)
logger.error(f"Unhandled exception: {exc}", exc_info=True)
return JSONResponse(
status_code=500,
content={"detail": "Internal server error"},
)