feat(halacha): review-queue triage — defer + batch group actions + quality-flag badges (#84)
Make the chair's pending-halacha review faster and less exhausting. Backend: - New 'deferred' review_status (snooze): stays out of the active library AND out of the default pending queue, without the finality of 'rejected'. update_halacha stamps reviewer+reviewed_at on defer; HALACHA_REVIEW_STATUSES is the single source of valid statuses (PATCH validation now uses it). - db.update_halachot_batch(ids, status, reviewer) — one atomic UPDATE for a whole group; invalid status / empty ids are a no-op. - POST /api/halachot/batch (HalachaBatchReviewRequest) wraps it. - update_halacha now RETURNs quality_flags too (parity with list_halachot). Frontend (halacha-review-panel): - Quality-flag badges (#81: non_decision / truncated_quote / thin_restatement / quote_unverified) so the chair sees WHY an item was held back. - Defer action — button + keyboard 'D' — to snooze without rejecting (fixes the 'leave in pending forever' anti-pattern; reject stays the junk verb). - Per-precedent batch bar: 'אשר הכל' / 'דחה הכל' via useBatchReviewHalachot (one request, one refetch) with confirm guards. - Halacha/HalachaPatch types gain quality_flags + 'deferred'. Verified: mcp-server suite 156 passed; web build green; end-to-end integration against dev DB (batch approve/reject, defer sets status+timestamp, pending excludes approved+deferred, deferred queryable, invalid status no-op). Note: api:types regen deferred until deploy (the batch hook is hand-typed, not dependent on generated types). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
28
web/app.py
28
web/app.py
@@ -5177,6 +5177,13 @@ class HalachaUpdateRequest(BaseModel):
|
||||
practice_areas: list[str] | None = None
|
||||
|
||||
|
||||
class HalachaBatchReviewRequest(BaseModel):
|
||||
"""#84 — apply one review status to many halachot at once (group action)."""
|
||||
halacha_ids: list[str]
|
||||
review_status: str
|
||||
reviewer: str | None = "דפנה"
|
||||
|
||||
|
||||
@app.post("/api/precedent-library/upload")
|
||||
async def precedent_library_upload(
|
||||
file: UploadFile = File(...),
|
||||
@@ -5712,9 +5719,7 @@ async def halacha_update(halacha_id: str, req: HalachaUpdateRequest):
|
||||
hid = UUID(halacha_id)
|
||||
except ValueError:
|
||||
raise HTTPException(400, "halacha_id לא תקין")
|
||||
if req.review_status and req.review_status not in {
|
||||
"pending_review", "approved", "rejected", "published",
|
||||
}:
|
||||
if req.review_status and req.review_status not in db.HALACHA_REVIEW_STATUSES:
|
||||
raise HTTPException(400, "review_status לא תקין")
|
||||
row = await db.update_halacha(
|
||||
halacha_id=hid,
|
||||
@@ -5730,6 +5735,23 @@ async def halacha_update(halacha_id: str, req: HalachaUpdateRequest):
|
||||
return row
|
||||
|
||||
|
||||
@app.post("/api/halachot/batch")
|
||||
async def halacha_batch_review(req: HalachaBatchReviewRequest):
|
||||
"""Apply one review status to many halachot at once (#84 group action)."""
|
||||
if req.review_status not in db.HALACHA_REVIEW_STATUSES:
|
||||
raise HTTPException(400, "review_status לא תקין")
|
||||
if not req.halacha_ids:
|
||||
return {"updated": 0}
|
||||
try:
|
||||
ids = [str(UUID(i)) for i in req.halacha_ids]
|
||||
except ValueError:
|
||||
raise HTTPException(400, "halacha_id לא תקין ברשימה")
|
||||
updated = await db.update_halachot_batch(
|
||||
ids, review_status=req.review_status, reviewer=req.reviewer or "",
|
||||
)
|
||||
return {"updated": updated}
|
||||
|
||||
|
||||
# ── Missing Precedents (TaskMaster #35) ────────────────────────────
|
||||
# Track citations from party briefs that aren't yet in the precedent
|
||||
# corpus. Researcher logs gaps; chair closes them by uploading the
|
||||
|
||||
Reference in New Issue
Block a user