Files
john a400130c67
CI / api-test (push) Has been cancelled
CI / web-build (push) Has been cancelled
Sprint 6: report review workflow, CI/K8s, and client tabs.
Add coach review APIs, pose calibration thresholds, Gitea CI, Kubernetes skeleton, H5 practice page, and mini program tab bar.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 11:44:11 +08:00

83 lines
2.4 KiB
Python

"""Report review workflow for staff."""
from datetime import datetime, timezone
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.db.models import Child, Report
def report_admin_dict(report: Report, child: Child | None = None) -> dict:
return {
"id": report.id,
"childId": report.child_id,
"childName": child.name if child else None,
"taskId": report.task_id,
"reportType": report.report_type,
"riskLevel": report.risk_level,
"summary": report.summary,
"status": report.status,
"reviewedBy": report.reviewed_by,
"createdAt": report.created_at.isoformat() if report.created_at else None,
}
def list_pending_reports(db: Session, tenant_id: int | None = None) -> list[dict]:
query = (
select(Report, Child)
.join(Child, Child.id == Report.child_id)
.where(Report.status == "pending_review")
.order_by(Report.id.desc())
)
if tenant_id:
query = query.where(Child.tenant_id == tenant_id)
rows = db.execute(query).all()
return [report_admin_dict(report, child) for report, child in rows]
def get_report_for_review(db: Session, report_id: int, tenant_id: int | None = None) -> Report | None:
report = db.get(Report, report_id)
if not report:
return None
child = db.get(Child, report.child_id)
if not child:
return None
if tenant_id and child.tenant_id != tenant_id:
return None
return report
def review_report(
db: Session,
reviewer_id: int,
report_id: int,
action: str,
tenant_id: int | None = None,
note: str | None = None,
) -> tuple[Report | None, str | None]:
report = get_report_for_review(db, report_id, tenant_id)
if not report:
return None, "report_not_found"
if report.status != "pending_review":
return None, "invalid_status"
if action == "approve":
report.status = "published"
elif action == "reject":
report.status = "rejected"
else:
return None, "invalid_action"
report.reviewed_by = reviewer_id
report.updated_at = datetime.now(timezone.utc)
if note:
recommendations = list(report.recommendations or [])
recommendations.append(f"复核备注:{note}")
report.recommendations = recommendations
db.commit()
db.refresh(report)
return report, None