Files
BadNote/server/badnote_server/routers/v1_vault_router.py
Akiba So 198da00ecd
All checks were successful
CI / Windows build (push) Successful in 7m47s
feat: vault-aligned server v1 + UX polish
Redesign the optional FastAPI companion around vault files (manifest /
PUT/GET/DELETE + OCR jobs) instead of legacy strokes_json notes. Wire a
client Server settings panel for health/login. Polish shell UX: l10n for
settings/home/board, sticky-board empty state, and a narrow-screen
diagnostics FAB.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 19:04:48 +08:00

64 lines
2.0 KiB
Python

"""v1 vault sync-assist API — vault files are the source of truth."""
from __future__ import annotations
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
from fastapi.responses import Response
from ..auth import get_current_user
from .. import vault_store
router = APIRouter()
@router.get("/manifest")
async def get_manifest(user_id: str = Depends(get_current_user)) -> dict:
"""List all files in the user's vault with size/mtime/sha256."""
return vault_store.build_manifest(user_id)
@router.get("/files/{file_path:path}")
async def download_file(
file_path: str,
user_id: str = Depends(get_current_user),
) -> Response:
try:
data = vault_store.read_file(user_id, file_path)
except ValueError as exc:
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
except FileNotFoundError:
raise HTTPException(status.HTTP_404_NOT_FOUND, detail="file not found")
return Response(
content=data,
media_type="application/octet-stream",
headers={"X-Vault-Path": file_path},
)
@router.put("/files/{file_path:path}")
async def upload_file(
file_path: str,
upload: UploadFile = File(...),
user_id: str = Depends(get_current_user),
) -> dict:
try:
data = await upload.read()
entry = vault_store.write_file(user_id, file_path, data)
except ValueError as exc:
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
return entry.to_dict()
@router.delete("/files/{file_path:path}")
async def remove_file(
file_path: str,
user_id: str = Depends(get_current_user),
) -> dict:
try:
vault_store.delete_file(user_id, file_path, tombstone=True)
except ValueError as exc:
raise HTTPException(status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
except FileNotFoundError:
raise HTTPException(status.HTTP_404_NOT_FOUND, detail="file not found")
return {"deleted": file_path, "tombstone": True}