mirror of
https://github.com/velocitatem/cvfs.git
synced 2026-05-31 16:53:38 +00:00
feat: add mobile support, delete CV/branch, and fix DOCX export with patches
Agent-Logs-Url: https://github.com/velocitatem/cvfs/sessions/4d754ed6-7f63-44e0-8689-123d7a70595f Co-authored-by: velocitatem <60182044+velocitatem@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
300a577fbe
commit
5d815cd24d
@@ -6,9 +6,10 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.api.deps import get_current_user, get_db
|
||||
from app.schemas import DocumentListResponse, DocumentResponse
|
||||
from app.services.documents import create_document, get_document, list_documents
|
||||
from app.services.documents import create_document, delete_document, get_document, list_documents
|
||||
from app.services.storage import storage_client
|
||||
from dlib.auth import AuthenticatedUser
|
||||
from dlib.cv import generate_patched_docx
|
||||
|
||||
|
||||
router = APIRouter(prefix="/documents", tags=["documents"])
|
||||
@@ -49,7 +50,8 @@ async def download_version_docx(
|
||||
version = next((v for v in document.versions if v.id == version_id), None)
|
||||
if not version or not version.artifact_docx_key:
|
||||
raise HTTPException(status_code=404, detail="Version artifact not found")
|
||||
data = storage_client.download_bytes(key=version.artifact_docx_key)
|
||||
original = storage_client.download_bytes(key=version.artifact_docx_key)
|
||||
data = generate_patched_docx(original, version.structured_blocks or [])
|
||||
slug = f"{document.title.replace(' ', '-')}-{version.branch_name}.docx"
|
||||
return Response(
|
||||
content=data,
|
||||
@@ -74,3 +76,14 @@ async def upload_document(
|
||||
upload=file,
|
||||
)
|
||||
return DocumentResponse.model_validate(document)
|
||||
|
||||
|
||||
@router.delete("/{document_id}", status_code=204)
|
||||
async def delete_user_document(
|
||||
document_id: str,
|
||||
session: AsyncSession = Depends(get_db),
|
||||
user: AuthenticatedUser = Depends(get_current_user),
|
||||
):
|
||||
deleted = await delete_document(session, owner_id=user.sub, document_id=document_id)
|
||||
if not deleted:
|
||||
raise HTTPException(status_code=404, detail="Document not found")
|
||||
|
||||
@@ -5,7 +5,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.api.deps import get_current_user, get_db
|
||||
from app.schemas import BranchCreateRequest, VersionResponse
|
||||
from app.services.versions import create_branch
|
||||
from app.services.versions import create_branch, delete_version
|
||||
from dlib.auth import AuthenticatedUser
|
||||
|
||||
|
||||
@@ -29,3 +29,18 @@ async def create_version_branch(
|
||||
if not version:
|
||||
raise HTTPException(status_code=404, detail="Parent version not found")
|
||||
return VersionResponse.model_validate(version)
|
||||
|
||||
|
||||
@router.delete("/{version_id}", status_code=204)
|
||||
async def delete_version_branch(
|
||||
version_id: str,
|
||||
session: AsyncSession = Depends(get_db),
|
||||
user: AuthenticatedUser = Depends(get_current_user),
|
||||
):
|
||||
result = await delete_version(session, owner_id=user.sub, version_id=version_id)
|
||||
if result is False:
|
||||
raise HTTPException(status_code=404, detail="Version not found")
|
||||
if result == "root":
|
||||
raise HTTPException(status_code=400, detail="Cannot delete root version")
|
||||
if result == "has_children":
|
||||
raise HTTPException(status_code=409, detail="Delete child branches first")
|
||||
|
||||
@@ -68,3 +68,14 @@ async def get_document(
|
||||
)
|
||||
result = await session.execute(stmt)
|
||||
return result.scalars().unique().one_or_none()
|
||||
|
||||
|
||||
async def delete_document(
|
||||
session: AsyncSession, owner_id: str, document_id: str
|
||||
) -> bool:
|
||||
doc = await get_document(session, owner_id, document_id)
|
||||
if not doc:
|
||||
return False
|
||||
await session.delete(doc)
|
||||
await session.commit()
|
||||
return True
|
||||
|
||||
@@ -82,3 +82,28 @@ async def create_branch(
|
||||
)
|
||||
result = await session.execute(stmt_refresh)
|
||||
return result.scalars().one()
|
||||
|
||||
|
||||
async def delete_version(
|
||||
session: AsyncSession, owner_id: str, version_id: str
|
||||
) -> bool | str:
|
||||
"""Delete a non-root branch. Returns False if not found, 'root' if root, True on success."""
|
||||
stmt = (
|
||||
select(CvVersion)
|
||||
.join(CvVersion.document)
|
||||
.where(CvVersion.id == version_id, CvDocument.owner_id == owner_id)
|
||||
)
|
||||
result = await session.execute(stmt)
|
||||
version = result.scalars().one_or_none()
|
||||
if not version:
|
||||
return False
|
||||
if not version.parent_version_id:
|
||||
return "root"
|
||||
# Refuse if child branches exist
|
||||
child_stmt = select(CvVersion.id).where(CvVersion.parent_version_id == version_id).limit(1)
|
||||
child_result = await session.execute(child_stmt)
|
||||
if child_result.scalar_one_or_none():
|
||||
return "has_children"
|
||||
await session.delete(version)
|
||||
await session.commit()
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user