a400130c67
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>
83 lines
2.4 KiB
Python
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
|