feat(research): add research study management functionality
- Implemented models for ResearchStudy, ResearchStudyArm, and ResearchParticipant. - Created views for listing, creating, updating, and exporting research studies. - Added bulk participant generation feature with CSV and JSON support. - Developed templates for study management, participant entry, and bulk generation. - Introduced URL routing for research study operations. - Added utility functions for randomisation and participant assignment. - Implemented participant intake process with demographic data collection. - Ensured proper handling of participant CIDs and assignment methods.
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Research Platform Extension - Implementation Summary</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #0f1720;
|
||||
--panel: #162130;
|
||||
--text: #e6edf3;
|
||||
--muted: #9fb0c3;
|
||||
--accent: #57a6ff;
|
||||
--ok: #3fb950;
|
||||
--warn: #d29922;
|
||||
--border: #2d3a4f;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
|
||||
background: radial-gradient(circle at 20% 10%, #1b2a40, var(--bg));
|
||||
color: var(--text);
|
||||
line-height: 1.5;
|
||||
}
|
||||
.wrap {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
}
|
||||
.card {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
padding: 18px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
h1, h2, h3 { margin-top: 0; }
|
||||
h1 { font-size: 1.6rem; }
|
||||
h2 { font-size: 1.2rem; border-bottom: 1px solid var(--border); padding-bottom: 6px; }
|
||||
code { color: var(--accent); }
|
||||
.muted { color: var(--muted); }
|
||||
.tag { display: inline-block; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border); margin-right: 6px; }
|
||||
.ok { color: var(--ok); }
|
||||
.warn { color: var(--warn); }
|
||||
ul { margin-top: 8px; }
|
||||
.grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
th, td { border: 1px solid var(--border); padding: 8px; text-align: left; }
|
||||
th { background: #1a2738; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<div class="card">
|
||||
<h1>Research Platform Extension</h1>
|
||||
<p class="muted">Generated: 12 May 2026</p>
|
||||
<p>
|
||||
The Atlas app was extended to support multi-study research workflows that randomise participants
|
||||
to packeted case collections while reusing existing collection-taking, timing, marking, and attempt models.
|
||||
</p>
|
||||
<div>
|
||||
<span class="tag">Randomisation on site</span>
|
||||
<span class="tag">Pseudo-ID workflow</span>
|
||||
<span class="tag">Per-packet marking config</span>
|
||||
<span class="tag">CSV/JSON export</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Implemented Data Model</h2>
|
||||
<ul>
|
||||
<li><code>ResearchStudy</code>: study container with slug, active flag, demographic collection toggle, and randomisation mode.</li>
|
||||
<li><code>ResearchStudyArm</code>: packet definition linked to existing <code>CaseCollection</code>, including weighting and marking scheme metadata.</li>
|
||||
<li><code>ResearchParticipant</code>: pseudo-ID keyed participant with demographic fields, consent flag, assigned arm, and generated CID credential link.</li>
|
||||
</ul>
|
||||
<p>Migration generated: <code>atlas/migrations/0103_researchstudy_researchstudyarm_researchparticipant.py</code>.</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Participant Flow</h2>
|
||||
<ul>
|
||||
<li>Participant visits: <code>/atlas/research/run/<study_slug>/<pseudo_id>/</code>.</li>
|
||||
<li>Site captures consent and simple demographics (configurable per study).</li>
|
||||
<li>Participant is randomised to a packet (study arm) by configured strategy.</li>
|
||||
<li>A dedicated <code>CidUser</code> credential is created and attached to the participant if needed.</li>
|
||||
<li>Assigned packet <code>CaseCollection</code> is launched via existing candidate collection routes.</li>
|
||||
</ul>
|
||||
<p class="ok">This reuses current Atlas taking/timing/marking behavior and avoids changes to candidate-facing scoring internals.</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Randomisation Logic</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Mode</th><th>Behavior</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>Completely random</td><td>Weighted random choice over active arms using <code>allocation_weight</code>.</td></tr>
|
||||
<tr><td>Balanced (equal-fill)</td><td>Assigns to least-filled active arm; tie broken randomly.</td></tr>
|
||||
<tr><td>Balanced within group</td><td>If enabled, balancing is applied within <code>candidate_group</code> strata.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Marking and Scoring</h2>
|
||||
<ul>
|
||||
<li>Existing answer models remain in use: <code>CidReportAnswer</code> / <code>UserReportAnswer</code>.</li>
|
||||
<li>Existing collection mark views remain functional for non-technical markers.</li>
|
||||
<li>Per-packet configuration fields added on study arm:
|
||||
<ul>
|
||||
<li><code>marking_scheme_name</code></li>
|
||||
<li><code>marking_guidance</code></li>
|
||||
<li><code>scoring_mode</code> and <code>max_case_score</code> for normalised exports</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="warn">Current marker UI itself is unchanged; packet-specific configuration is reflected in study management and exports.</p>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Management and Export</h2>
|
||||
<div class="grid">
|
||||
<div>
|
||||
<h3>Management Views</h3>
|
||||
<ul>
|
||||
<li><code>/atlas/research/</code> list studies</li>
|
||||
<li><code>/atlas/research/create/</code> create study</li>
|
||||
<li><code>/atlas/research/<pk>/</code> study detail + packets + participants</li>
|
||||
<li><code>/atlas/research/<pk>/update/</code> update study</li>
|
||||
<li><code>/atlas/research/<pk>/arm/<arm_id>/update/</code> update packet</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Exports</h3>
|
||||
<ul>
|
||||
<li><code>/atlas/research/<pk>/export.csv</code></li>
|
||||
<li><code>/atlas/research/<pk>/export.json</code></li>
|
||||
</ul>
|
||||
<p>Export rows include demographics, assignment metadata, credential ID, attempt status, and raw/normalised scores.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Files Added/Updated</h2>
|
||||
<ul>
|
||||
<li>Updated: <code>atlas/models.py</code>, <code>atlas/forms.py</code>, <code>atlas/views.py</code>, <code>atlas/urls.py</code>, <code>atlas/admin.py</code></li>
|
||||
<li>Added templates:
|
||||
<ul>
|
||||
<li><code>atlas/templates/atlas/research_study_list.html</code></li>
|
||||
<li><code>atlas/templates/atlas/research_study_form.html</code></li>
|
||||
<li><code>atlas/templates/atlas/research_study_detail.html</code></li>
|
||||
<li><code>atlas/templates/atlas/research_study_arm_form.html</code></li>
|
||||
<li><code>atlas/templates/atlas/research_participant_entry.html</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Added migration: <code>atlas/migrations/0103_researchstudy_researchstudyarm_researchparticipant.py</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Compatibility Notes</h2>
|
||||
<ul>
|
||||
<li>No existing collection, case, or answer model behavior was removed.</li>
|
||||
<li>Randomisation and participant routing are additive and isolated to new research URLs.</li>
|
||||
<li>Author/editor permission pattern is respected for study management views.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user