mirror of
https://git.victorphan.net/basketballcantho/ten-project.git
synced 2026-08-05 13:13:11 +07:00
Hoàn thành chức năng collaborative
This commit is contained in:
@@ -18,6 +18,14 @@ def _verify_pdf_ownership(db: Session, pdf_id: int, user_id: int) -> PDF:
|
||||
return pdf
|
||||
|
||||
|
||||
def _any_pdf_or_404(db: Session, pdf_id: int) -> PDF:
|
||||
"""Return PDF regardless of owner — any authenticated user may read annotations."""
|
||||
pdf = db.get(PDF, pdf_id)
|
||||
if not pdf:
|
||||
raise HTTPException(status_code=404, detail="PDF not found.")
|
||||
return pdf
|
||||
|
||||
|
||||
# ── GET /api/annotations/{pdf_id}/{page_number} ───────────────────────────────
|
||||
|
||||
@router.get("/{pdf_id}/{page_number}", response_model=AnnotationOut)
|
||||
@@ -27,7 +35,7 @@ def get_annotation(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
_verify_pdf_ownership(db, pdf_id, current_user.id)
|
||||
_any_pdf_or_404(db, pdf_id)
|
||||
|
||||
ann = (
|
||||
db.query(Annotation)
|
||||
@@ -52,6 +60,59 @@ def get_annotation(
|
||||
return ann
|
||||
|
||||
|
||||
# ── GET /api/annotations/{pdf_id}/{page_number}/all ───────────────────────────
|
||||
# Returns a merged canvas_data whose "objects" array contains annotations from
|
||||
# ALL users for the given page. Any authenticated user may call this.
|
||||
|
||||
@router.get("/{pdf_id}/{page_number}/all", response_model=AnnotationOut)
|
||||
def get_all_annotations(
|
||||
pdf_id: int,
|
||||
page_number: int,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
_any_pdf_or_404(db, pdf_id)
|
||||
|
||||
rows = (
|
||||
db.query(Annotation)
|
||||
.filter(
|
||||
Annotation.pdf_id == pdf_id,
|
||||
Annotation.page_number == page_number,
|
||||
)
|
||||
.all()
|
||||
)
|
||||
|
||||
if not rows:
|
||||
return AnnotationOut(
|
||||
id=0,
|
||||
pdf_id=pdf_id,
|
||||
page_number=page_number,
|
||||
canvas_data={},
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
)
|
||||
|
||||
# Merge all objects arrays; use canvas metadata (background etc.) from latest record
|
||||
latest = max(rows, key=lambda r: r.updated_at)
|
||||
base: dict = dict(latest.canvas_data) if latest.canvas_data else {}
|
||||
merged_objects: list = []
|
||||
for row in rows:
|
||||
for obj in (row.canvas_data or {}).get("objects", []):
|
||||
# Tag each object with its owner so the frontend can avoid re-saving
|
||||
# other users' objects under the current user's record (prevents duplicates).
|
||||
obj_copy = dict(obj)
|
||||
obj_copy["_owner_id"] = row.user_id
|
||||
merged_objects.append(obj_copy)
|
||||
base["objects"] = merged_objects
|
||||
|
||||
return AnnotationOut(
|
||||
id=latest.id,
|
||||
pdf_id=pdf_id,
|
||||
page_number=page_number,
|
||||
canvas_data=base,
|
||||
updated_at=latest.updated_at,
|
||||
)
|
||||
|
||||
|
||||
# ── PUT /api/annotations/{pdf_id}/{page_number} ───────────────────────────────
|
||||
|
||||
@router.put("/{pdf_id}/{page_number}", response_model=AnnotationOut)
|
||||
@@ -62,7 +123,7 @@ def upsert_annotation(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
_verify_pdf_ownership(db, pdf_id, current_user.id)
|
||||
_any_pdf_or_404(db, pdf_id)
|
||||
|
||||
ann = (
|
||||
db.query(Annotation)
|
||||
|
||||
Reference in New Issue
Block a user