feat(07-04): POST /classify re-queues Celery, removes synchronous classify (D-11)
- Replace synchronous await classifier.classify_document() with extract_and_classify.delay()
- Set doc.status='processing' and commit before dispatching Celery task
- Return {'document_id': str, 'status': 'processing'} instead of assigned topics
- Promote test_reclassify_requeues_celery from xfail stub to passing test
- Add test_reclassify_cross_user_returns_404 for IDOR security invariant (T-07-10)
This commit is contained in:
@@ -714,14 +714,17 @@ async def delete_document(
|
||||
async def classify_document(
|
||||
request: Request,
|
||||
doc_id: str,
|
||||
body: dict = {},
|
||||
session: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_regular_user),
|
||||
):
|
||||
"""Reclassify a document's topics on demand.
|
||||
"""Re-queue a document for classification via Celery (D-11).
|
||||
|
||||
Sets doc.status='processing', commits, dispatches extract_and_classify.delay(),
|
||||
and returns {'document_id': str, 'status': 'processing'}.
|
||||
|
||||
D-16: requires authenticated regular user. Asserts ownership — cross-user
|
||||
classify returns 404 (not 403) to avoid information leakage (T-03-11).
|
||||
T-07-10: ownership enforced here; IDOR returns 404 per STATE.md policy.
|
||||
"""
|
||||
request.state.current_user = current_user
|
||||
try:
|
||||
@@ -733,13 +736,12 @@ async def classify_document(
|
||||
if doc is None or doc.user_id != current_user.id:
|
||||
raise HTTPException(404, "Document not found")
|
||||
|
||||
topic_names = body.get("topics") if body else None
|
||||
try:
|
||||
topics = await classifier.classify_document(session, doc_id, topic_names)
|
||||
except Exception as e:
|
||||
raise HTTPException(500, f"Classification failed: {e}")
|
||||
doc.status = "processing"
|
||||
await session.commit()
|
||||
|
||||
return {"topics": topics}
|
||||
extract_and_classify.delay(str(doc.id))
|
||||
|
||||
return {"document_id": str(doc.id), "status": "processing"}
|
||||
|
||||
|
||||
# ── Range header parsing helper ───────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user