152 lines
5.0 KiB
Python
152 lines
5.0 KiB
Python
from typing import Any, Dict, List, Optional
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from models.document import DocumentNode
|
|
from models.user import User
|
|
from pydantic import BaseModel
|
|
from services.document_service import document_service
|
|
|
|
from routers.auth import get_current_user
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class CreateDocumentRequest(BaseModel):
|
|
title: str
|
|
type: str # "book", "chapter", "scene"
|
|
parent_id: Optional[str] = None
|
|
content: str = ""
|
|
|
|
|
|
class UpdateDocumentRequest(BaseModel):
|
|
title: Optional[str] = None
|
|
content: Optional[str] = None
|
|
parent_id: Optional[str] = None # Для переноса
|
|
order: Optional[int] = None
|
|
|
|
|
|
def _get_user_project(project_id: str, current_user: User) -> None:
|
|
"""Проверить что проект принадлежит пользователю"""
|
|
from services.project_service import project_service
|
|
|
|
project = project_service.get_project(project_id)
|
|
if not project:
|
|
raise HTTPException(status_code=404, detail="Project not found")
|
|
if project.user_id != current_user.id:
|
|
raise HTTPException(status_code=403, detail="Access denied")
|
|
|
|
|
|
@router.get(
|
|
"/projects/{project_id}/documents/tree", response_model=List[Dict[str, Any]]
|
|
)
|
|
async def get_documents_tree(
|
|
project_id: str, current_user: User = Depends(get_current_user)
|
|
):
|
|
"""Получить документы в виде дерева"""
|
|
_get_user_project(project_id, current_user)
|
|
return document_service.get_documents_tree(project_id, current_user.id)
|
|
|
|
|
|
@router.get("/projects/{project_id}/documents", response_model=List[DocumentNode])
|
|
async def get_all_documents(
|
|
project_id: str, current_user: User = Depends(get_current_user)
|
|
):
|
|
"""Получить все документы (плоский список)"""
|
|
_get_user_project(project_id, current_user)
|
|
return document_service.get_all_documents(project_id, current_user.id)
|
|
|
|
|
|
@router.get(
|
|
"/projects/{project_id}/documents/{document_id}", response_model=DocumentNode
|
|
)
|
|
async def get_document(
|
|
project_id: str,
|
|
document_id: str,
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Получить документ по ID"""
|
|
_get_user_project(project_id, current_user)
|
|
document = document_service.get_document(project_id, document_id, current_user.id)
|
|
if not document:
|
|
raise HTTPException(status_code=404, detail="Document not found")
|
|
return document
|
|
|
|
|
|
@router.post(
|
|
"/projects/{project_id}/documents", response_model=DocumentNode, status_code=201
|
|
)
|
|
async def create_document(
|
|
project_id: str,
|
|
request: CreateDocumentRequest,
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Создать новый документ"""
|
|
_get_user_project(project_id, current_user)
|
|
try:
|
|
return document_service.create_document(
|
|
project_id=project_id,
|
|
title=request.title,
|
|
doc_type=request.type,
|
|
user_id=current_user.id,
|
|
parent_id=request.parent_id,
|
|
content=request.content,
|
|
)
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
|
|
|
|
@router.put(
|
|
"/projects/{project_id}/documents/{document_id}", response_model=DocumentNode
|
|
)
|
|
async def update_document(
|
|
project_id: str,
|
|
document_id: str,
|
|
request: UpdateDocumentRequest,
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Обновить документ (включая перенос)"""
|
|
_get_user_project(project_id, current_user)
|
|
try:
|
|
document = document_service.update_document(
|
|
project_id=project_id,
|
|
document_id=document_id,
|
|
user_id=current_user.id,
|
|
title=request.title,
|
|
content=request.content,
|
|
parent_id=request.parent_id,
|
|
order=request.order,
|
|
)
|
|
if not document:
|
|
raise HTTPException(status_code=404, detail="Document not found")
|
|
return document
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
|
|
|
|
@router.delete("/projects/{project_id}/documents/{document_id}")
|
|
async def delete_document(
|
|
project_id: str,
|
|
document_id: str,
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Удалить документ с каскадом"""
|
|
_get_user_project(project_id, current_user)
|
|
success = document_service.delete_document(project_id, document_id, current_user.id)
|
|
if not success:
|
|
raise HTTPException(status_code=404, detail="Document not found")
|
|
return {"status": "deleted", "document_id": document_id}
|
|
|
|
|
|
@router.get(
|
|
"/projects/{project_id}/documents/{parent_id}/children",
|
|
response_model=List[DocumentNode],
|
|
)
|
|
async def get_children(
|
|
project_id: str,
|
|
parent_id: str,
|
|
current_user: User = Depends(get_current_user),
|
|
):
|
|
"""Получить прямых детей узла"""
|
|
_get_user_project(project_id, current_user)
|
|
return document_service.get_children(project_id, parent_id, current_user.id)
|