feat: refine subject visits and project workflows
Add early termination visit workflow with ordering, non-applicable visit handling, visit window display, and medication adherence support. Extend monitoring visit issue template fields, site scoping, setup draft project info handling, login security UI, attachment behavior, and related tests/migrations.
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import pytest
|
||||
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
|
||||
|
||||
from app.crud import monitoring_visit_issue as issue_crud
|
||||
from app.models.monitoring_visit_issue import MonitoringVisitIssue
|
||||
from app.schemas.monitoring_visit_issue import MonitoringVisitIssueCreate
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_monitoring_visit_issue_template_fields_can_be_filtered(tmp_path):
|
||||
db_path = tmp_path / "monitoring-issues.db"
|
||||
engine = create_async_engine(f"sqlite+aiosqlite:///{db_path}", future=True)
|
||||
SessionLocal = async_sessionmaker(engine, expire_on_commit=False)
|
||||
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(MonitoringVisitIssue.__table__.create)
|
||||
|
||||
study_id = uuid.UUID("11111111-1111-1111-1111-111111111111")
|
||||
site_id = uuid.UUID("22222222-2222-2222-2222-222222222222")
|
||||
async with SessionLocal() as session:
|
||||
created = await issue_crud.create_issue(
|
||||
session,
|
||||
study_id,
|
||||
MonitoringVisitIssueCreate(
|
||||
issue_no="MV-001",
|
||||
site_id=site_id,
|
||||
category="原始记录",
|
||||
subject_code="SUBJ-001",
|
||||
status="OPEN",
|
||||
severity="严重",
|
||||
mark="SDV",
|
||||
visit_cycle="V1",
|
||||
center_query="请补充签名日期",
|
||||
center_latest_reply="待中心回复",
|
||||
rectification_completed=False,
|
||||
due_at=datetime(2026, 5, 1, tzinfo=timezone.utc),
|
||||
),
|
||||
created_by=None,
|
||||
)
|
||||
|
||||
assert created.site_id == site_id
|
||||
assert created.severity == "严重"
|
||||
assert created.mark == "SDV"
|
||||
assert created.visit_cycle == "V1"
|
||||
assert created.center_query == "请补充签名日期"
|
||||
assert created.center_latest_reply == "待中心回复"
|
||||
assert created.rectification_completed is False
|
||||
|
||||
matched = await issue_crud.list_issues(
|
||||
session,
|
||||
study_id,
|
||||
site_id=site_id,
|
||||
severity="严重",
|
||||
mark="SDV",
|
||||
visit_cycle="V1",
|
||||
rectification_completed=False,
|
||||
due_from=datetime(2026, 5, 1, tzinfo=timezone.utc).date(),
|
||||
due_to=datetime(2026, 5, 1, tzinfo=timezone.utc).date(),
|
||||
)
|
||||
unmatched = await issue_crud.list_issues(
|
||||
session,
|
||||
study_id,
|
||||
site_id=uuid.UUID("33333333-3333-3333-3333-333333333333"),
|
||||
)
|
||||
|
||||
await engine.dispose()
|
||||
|
||||
assert [item.issue_no for item in matched] == ["MV-001"]
|
||||
assert unmatched == []
|
||||
Reference in New Issue
Block a user