Phase 1 MVP - Complete implementation

- Auth: register, login, JWT with refresh tokens, blocklist
- Projects/Folders/Documents CRUD with soft deletes
- Tags CRUD and assignment
- FTS5 search with highlights and tag filtering
- ADR-001, ADR-002, ADR-003 compliant
- Security fixes applied (JWT_SECRET_KEY, exception handler, cookie secure)
- 25 tests passing
This commit is contained in:
Motoko
2026-03-30 15:17:27 +00:00
parent 33f19e02f8
commit 7f3e8a8f53
41 changed files with 2858 additions and 0 deletions

36
app/routers/search.py Normal file
View File

@@ -0,0 +1,36 @@
from fastapi import APIRouter, Depends, Query, Request
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.routers.auth import get_current_agent
from app.schemas.search import SearchResponse
from app.services.search import search_documents
router = APIRouter(prefix="/api/v1/search", tags=["search"])
@router.get("", response_model=SearchResponse)
async def search(
request: Request,
q: str = Query(..., min_length=1),
project_id: str | None = Query(None),
tags: str | None = Query(None),
limit: int = Query(20, ge=1, le=100),
offset: int = Query(0, ge=0),
db: AsyncSession = Depends(get_db),
):
agent = await get_current_agent(request, db)
tag_list = None
if tags:
tag_list = [t.strip() for t in tags.split(",") if t.strip()]
return await search_documents(
db=db,
query=q,
agent_id=agent.id,
project_id=project_id,
tags=tag_list,
limit=limit,
offset=offset,
)