feat: harden auth and study workflows

- replace plaintext login and unlock requests with RSA-OAEP/AES-GCM encrypted payloads

- add login challenge replay protection, production RSA key validation, and auth tests

- wire compose to environment-driven dev/prod settings without committing local secrets

- update setup-config smoke scripts and Postman docs for encrypted login

- add visit schedule migrations/tests and update study/subject setup workflows
This commit is contained in:
Cheng Zhou
2026-05-08 22:13:12 +08:00
parent a7bbcaa5dc
commit 74feca4467
47 changed files with 2423 additions and 534 deletions
+3 -3
View File
@@ -173,9 +173,9 @@ async def update_subject(
await _ensure_subject_active(db, subject)
old_status = subject.status
updated = await subject_crud.update_subject(db, subject, subject_in)
# auto-generate visits when enrolled
if subject_in.status and subject_in.status == "ENROLLED" and (subject_in.enrollment_date or updated.enrollment_date):
await subject_crud.generate_default_visits(db, updated)
# 基线/治疗日期是访视计划的唯一推算基准,不能用入组日期替代。
if updated.baseline_date:
await subject_crud.sync_visits_from_baseline(db, updated)
detail = None
if subject_in.status and subject_in.status != old_status:
detail = f"参与者 {updated.subject_no} 状态 {old_status} -> {subject_in.status}"