Question Hierarchy Diagrams¶
Overview¶
This document provides visual representations of the annotation question hierarchies, data flow, and architectural concepts in SyRF.
Related Documentation¶
- Annotation Questions Business Logic - Core business rules
- Formal Specification - Precise rule definitions and terminology
- Architecture Analysis - Where logic should live
- Category Question Structure - Detailed category rules
Terminology: See the Terminology Glossary for precise definitions of terms like Unit, Label Question, Control Question, and Lookup Question.
1. Category Hierarchy Overview¶
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ANNOTATION CATEGORY HIERARCHY │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┐ │
│ │ Study │ ◄── Flat structure │
│ │ (Category) │ No units, no label Q │
│ └───────┬────────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Disease │ │ Treatment │ │ Outcome │ ◄── Unit-based │
│ │ Model │ │ │ │ Assessment │ Categories │
│ │ Induction │ │ │ │ │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ │ HAS CONTROL Q │ HAS CONTROL Q │ NO CONTROL Q │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Model │ │ Treatment │ │ Average, │ │
│ │ Control │ │ Control │ │ Error Type │ │
│ │ (Bool) │ │ (Bool) │ │ Units, etc │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ Cohort │ ◄── Aggregates DM, T, O │
│ │ (Category) │ via lookup questions │
│ └───────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ Experiment │ ◄── Aggregates Cohorts │
│ │ (Category) │ via lookup questions │
│ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
2. Question Type Classification¶
┌─────────────────────────────────────────────────────────────────────────────────┐
│ QUESTION TYPE MATRIX │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ BY DATA FUNCTION │ │
│ ├───────────────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ LABEL QUESTIONS │ │CONTROL QUESTIONS│ │ LOOKUP QUESTIONS │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ Creates named │ │ Is this unit a │ │ References labels from │ │ │
│ │ │ instances │ │ control proc? │ │ other categories │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ labelQuestion: │ │ questionType: │ │ annotationLookup: │ │ │
│ │ │ true │ │ boolean │ │ true │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ Examples: │ │ Examples: │ │ Examples: │ │ │
│ │ │ - DM Label │ │ - Model Ctrl │ │ - Cohort DMs │ │ │
│ │ │ - Treatment L │ │ - Treatment C │ │ - Cohort Treatments │ │ │
│ │ │ - Outcome L │ │ │ │ - Experiment Cohorts │ │ │
│ │ │ - Cohort L │ │ │ │ │ │ │
│ │ │ - Experiment L │ │ │ │ │ │ │
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ BY INPUT TYPE │ │
│ ├───────────────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ TEXTBOX │ │ DROPDOWN │ │ CHECKBOX │ │ CHECKLIST │ │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ │ │ string │ │ string │ │ boolean │ │ string[] │ │ │
│ │ │ integer │ │ (options) │ │ (single) │ │ (multi-select) │ │ │
│ │ │ decimal │ │ │ │ │ │ │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ RADIO │ │ AUTOCOMPLETE │ │ │
│ │ │ │ │ │ │ │
│ │ │ string │ │ string │ │ │
│ │ │ (single │ │ (searchable │ │ │
│ │ │ select) │ │ dropdown) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
3. Parent-Child Relationship Patterns¶
Pattern A: Root Questions (Study Category)¶
┌─────────────────────────────────────────────────────────────────────────────────┐
│ PATTERN A: ROOT QUESTIONS (STUDY CATEGORY) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ Study Category │
│ ══════════════ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ ││
│ │ ┌─────────────────────┐ ┌─────────────────────┐ ││
│ │ │ Custom Question A │ │ Custom Question B │ ││
│ │ │ ───────────────── │ │ ───────────────── │ ││
│ │ │ root: true │ │ root: true │ ││
│ │ │ target: null │ │ target: null │ ││
│ │ │ │ │ │ ││
│ │ │ ┌───────────────┐ │ │ ┌───────────────┐ │ ││
│ │ │ │ Child A.1 │ │ │ │ Child B.1 │ │ ││
│ │ │ │ target: │ │ │ │ target: │ │ ││
│ │ │ │ parentId: A │ │ │ │ parentId: B │ │ ││
│ │ │ └───────────────┘ │ │ └───────────────┘ │ ││
│ │ │ │ │ │ ││
│ │ │ ┌───────────────┐ │ │ │ ││
│ │ │ │ Child A.2 │ │ │ │ ││
│ │ │ │ (conditional) │ │ │ │ ││
│ │ │ └───────────────┘ │ │ │ ││
│ │ └─────────────────────┘ └─────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
│ KEY: Custom questions can be at root level. Children target their parent. │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Pattern B: Control-Based (Treatment/Disease Model)¶
┌─────────────────────────────────────────────────────────────────────────────────┐
│ PATTERN B: CONTROL-BASED (TREATMENT / DISEASE MODEL) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ Treatment / Disease Model Category │
│ ══════════════════════════════════ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ ││
│ │ ┌─────────────────────────────────────────────────────────────────────┐ ││
│ │ │ Label Question [SYSTEM] │ ││
│ │ │ root: true, labelQuestion: true │ ││
│ │ │ │ ││
│ │ │ ┌───────────────────────────────────────────────────────────────┐ │ ││
│ │ │ │ Control Question [SYSTEM] │ │ ││
│ │ │ │ questionType: boolean, controlType: checkbox │ │ ││
│ │ │ │ │ │ ││
│ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ ││
│ │ │ │ │ WHEN CONTROL = TRUE (Control Procedure) │ │ │ ││
│ │ │ │ │ ───────────────────────────────────── │ │ │ ││
│ │ │ │ │ │ │ │ ││
│ │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ ││
│ │ │ │ │ │ Custom Q1 │ │ Custom Q2 │ │ Custom Q3 │ │ │ │ ││
│ │ │ │ │ │ control: │ │ control: │ │ control: │ │ │ │ ││
│ │ │ │ │ │ true │ │ true │ │ true │ │ │ │ ││
│ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ ││
│ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ ││
│ │ │ │ │ │ ││
│ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ ││
│ │ │ │ │ WHEN CONTROL = FALSE (Active/Test Procedure) │ │ │ ││
│ │ │ │ │ ─────────────────────────────────────────── │ │ │ ││
│ │ │ │ │ │ │ │ ││
│ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ ││
│ │ │ │ │ │ Custom Q4 │ │ Custom Q5 │ │ │ │ ││
│ │ │ │ │ │ control: │ │ control: │ │ │ │ ││
│ │ │ │ │ │ false │ │ false │ │ │ │ ││
│ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ ││
│ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ ││
│ │ │ │ │ │ ││
│ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ ││
│ │ │ │ │ ALWAYS VISIBLE (control: null) │ │ │ ││
│ │ │ │ │ ───────────────────────────── │ │ │ ││
│ │ │ │ │ ┌─────────────┐ │ │ │ ││
│ │ │ │ │ │ Custom Q6 │ Questions visible regardless │ │ │ ││
│ │ │ │ │ │ control: │ of control value │ │ │ ││
│ │ │ │ │ │ null │ │ │ │ ││
│ │ │ │ │ └─────────────┘ │ │ │ ││
│ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ ││
│ │ │ └───────────────────────────────────────────────────────────────┘ │ ││
│ │ └─────────────────────────────────────────────────────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
│ KEY: FIRST-LEVEL custom questions MUST target Control Question, with │
│ conditionalParent set to true, false, or null. │
│ NESTED questions can target other custom questions in the same category. │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Pattern C: Label-Based (Cohort/Outcome/Experiment)¶
┌─────────────────────────────────────────────────────────────────────────────────┐
│ PATTERN C: LABEL-BASED (COHORT/OUTCOME/EXPERIMENT) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ Cohort / Outcome Assessment / Experiment Category │
│ ═════════════════════════════════════════════════ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ ││
│ │ ┌─────────────────────────────────────────────────────────────────────┐ ││
│ │ │ Label Question [SYSTEM] │ ││
│ │ │ root: true, labelQuestion: true │ ││
│ │ │ │ ││
│ │ │ ┌─────────────────────────────────────────────────────────────┐ │ ││
│ │ │ │ SYSTEM QUESTIONS │ │ ││
│ │ │ │ ──────────────── │ │ ││
│ │ │ │ │ │ ││
│ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ ││
│ │ │ │ │ Lookup Q1 │ │ Lookup Q2 │ │ System Q3 │ │ │ ││
│ │ │ │ │ (DMs/Treats │ │ (Outcomes │ │ (Special │ │ │ ││
│ │ │ │ │ /Cohorts) │ │ /etc) │ │ metadata) │ │ │ ││
│ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ ││
│ │ │ └─────────────────────────────────────────────────────────────┘ │ ││
│ │ │ │ ││
│ │ │ ┌─────────────────────────────────────────────────────────────┐ │ ││
│ │ │ │ CUSTOM QUESTIONS │ │ ││
│ │ │ │ ──────────────── │ │ ││
│ │ │ │ │ │ ││
│ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ ││
│ │ │ │ │ Custom Q1 │ │ Custom Q2 │ │ │ ││
│ │ │ │ │ target: │ │ target: │ │ │ ││
│ │ │ │ │ parentId: │ │ parentId: │ All custom questions │ │ ││
│ │ │ │ │ labelGuid │ │ labelGuid │ parent to Label Q │ │ ││
│ │ │ │ └─────────────┘ └─────────────┘ │ │ ││
│ │ │ └─────────────────────────────────────────────────────────────┘ │ ││
│ │ └─────────────────────────────────────────────────────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
│ KEY: FIRST-LEVEL custom questions MUST target Label Question. No control param.│
│ NESTED questions can target other custom questions in the same category. │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
4. Lookup Question Data Flow¶
┌─────────────────────────────────────────────────────────────────────────────────┐
│ LOOKUP QUESTION DATA FLOW │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ STEP 1: User Creates Label Annotations │
│ ═══════════════════════════════════════ │
│ │
│ Disease Model Induction Treatment Outcome Assessment │
│ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Label: "MCAO" │ │ Label: "Aspirin" │ │ Label: "Infarct │ │
│ │ ID: guid-mcao │ │ ID: guid-aspirin │ │ Volume" │ │
│ └─────────────────────┘ └─────────────────────┘ │ ID: guid-infarct │ │
│ ┌─────────────────────┐ ┌─────────────────────┐ └─────────────────────┘ │
│ │ Label: "Sham" │ │ Label: "Saline" │ ┌─────────────────────┐ │
│ │ ID: guid-sham │ │ ID: guid-saline │ │ Label: "Neuro │ │
│ └─────────────────────┘ └─────────────────────┘ │ Score" │ │
│ │ ID: guid-neuro │ │
│ └─────────────────────┘ │
│ │
│ │ │
│ │ AGGREGATES │
│ ▼ │
│ │
│ STEP 2: Cohort Lookups Display Available Labels │
│ ═══════════════════════════════════════════════ │
│ │
│ Cohort Category │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Cohort Label: "Experimental Group 1" │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Disease Models [LOOKUP CHECKLIST] │ │ │
│ │ │ ───────────────────────────────── │ │ │
│ │ │ │ │ │
│ │ │ ☑ MCAO ◄── Displays label, stores guid-mcao │ │ │
│ │ │ ☐ Sham ◄── Displays label, stores guid-sham │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Treatments [LOOKUP CHECKLIST] │ │ │
│ │ │ ──────────────────────────── │ │ │
│ │ │ │ │ │
│ │ │ ☑ Aspirin ◄── Displays label, stores guid-aspirin │ │ │
│ │ │ ☐ Saline ◄── Displays label, stores guid-saline │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Outcomes [LOOKUP CHECKLIST] │ │ │
│ │ │ ────────────────────────── │ │ │
│ │ │ │ │ │
│ │ │ ☑ Infarct Volume ◄── Displays label, stores guid-infarct │ │ │
│ │ │ ☑ Neuro Score ◄── Displays label, stores guid-neuro │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
│ │
│ │ │
│ │ AGGREGATES │
│ ▼ │
│ │
│ STEP 3: Experiment Lookups Display Available Cohorts │
│ ════════════════════════════════════════════════════ │
│ │
│ Experiment Category │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Experiment Label: "Aspirin vs Control Study" │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Cohorts [LOOKUP CHECKLIST] │ │ │
│ │ │ ────────────────────────── │ │ │
│ │ │ │ │ │
│ │ │ ☑ Experimental Group 1 ◄── Displays cohort label │ │ │
│ │ │ ☐ Control Group 1 ◄── Displays cohort label │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
5. Conditional Display Logic¶
┌─────────────────────────────────────────────────────────────────────────────────┐
│ CONDITIONAL DISPLAY LOGIC │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ TYPE 1: Boolean Conditional │
│ ═══════════════════════════ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ Parent Question: "Is Control Procedure?" ☐ ││
│ │ ││
│ │ ┌──────────────────────────────────────┐ ││
│ │ CHECKED (true) ──►│ Child Questions with │ ││
│ │ │ conditionalParentAnswers: │ ││
│ │ │ conditionType: Boolean (0) │ ││
│ │ │ targetParentBoolean: true │ ││
│ │ └──────────────────────────────────────┘ ││
│ │ ││
│ │ ┌──────────────────────────────────────┐ ││
│ │ UNCHECKED (false)►│ Child Questions with │ ││
│ │ │ conditionalParentAnswers: │ ││
│ │ │ conditionType: Boolean (0) │ ││
│ │ │ targetParentBoolean: false │ ││
│ │ └──────────────────────────────────────┘ ││
│ │ ││
│ │ ┌──────────────────────────────────────┐ ││
│ │ ANY VALUE ───────►│ Child Questions with │ ││
│ │ │ conditionalParentAnswers: null │ ││
│ │ └──────────────────────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
│ │
│ TYPE 2: Option Conditional │
│ ══════════════════════════ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ Parent Question: "Average Type" [▼ Mean] ││
│ │ ││
│ │ OPTIONS: Mean, Median ││
│ │ ││
│ │ ┌──────────────────────────────────────┐ ││
│ │ Mean SELECTED ───►│ Child: "Error Type" │ ││
│ │ │ Shows options: SD, SEM │ ││
│ │ │ │ ││
│ │ │ Option filter: │ ││
│ │ │ filterType: Option (1) │ ││
│ │ │ value: ["Mean"] │ ││
│ │ └──────────────────────────────────────┘ ││
│ │ ││
│ │ ┌──────────────────────────────────────┐ ││
│ │ Median SELECTED ─►│ Child: "Error Type" │ ││
│ │ │ Shows options: IQR │ ││
│ │ │ │ ││
│ │ │ Option filter: │ ││
│ │ │ filterType: Option (1) │ ││
│ │ │ value: ["Median"] │ ││
│ │ └──────────────────────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
│ │
│ TYPE 3: Multi-Option Conditional (V1 Schema Only) │
│ ═════════════════════════════════════════════════ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ Parent Question: "Species" [▼ Rat] ││
│ │ ││
│ │ OPTIONS: Mouse, Rat, Hamster, Rabbit, Other ││
│ │ ││
│ │ ┌──────────────────────────────────────┐ ││
│ │ Rat OR Mouse ────►│ Child: "Strain Details" │ ││
│ │ │ │ ││
│ │ │ conditionalParentAnswers: │ ││
│ │ │ conditionType: Option (1) │ ││
│ │ │ targetParentOptions: ["Rat", │ ││
│ │ │ "Mouse"] │ ││
│ │ └──────────────────────────────────────┘ ││
│ │ ││
│ │ ⚠️ NOTE: V0 schema only allows single option; V1+ allows multiple ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
6. Frontend vs Backend Rule Enforcement¶
┌─────────────────────────────────────────────────────────────────────────────────┐
│ RULE ENFORCEMENT COMPARISON │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ FRONTEND ENFORCEMENT ││
│ │ ════════════════════ ││
│ │ ││
│ │ User creates question ││
│ │ │ ││
│ │ ▼ ││
│ │ ┌───────────────────┐ ││
│ │ │ CreateQuestion │ ││
│ │ │ Component │ ││
│ │ │ ─────────────── │ ││
│ │ │ • Checks category │ ││
│ │ │ • Sets parent │ ││
│ │ │ • Sets control │ ││
│ │ └─────────┬─────────┘ ││
│ │ │ ││
│ │ │ RULES ENFORCED ││
│ │ │ ✓ Category parent ││
│ │ │ ✓ Control parameter ││
│ │ │ ││
│ │ ▼ ││
│ │ ┌───────────────────┐ ┌───────────────────┐ ┌─────────────────┐ ││
│ │ │ API Call │─────►│ Backend API │─────►│ Database │ ││
│ │ └───────────────────┘ └───────────────────┘ │ ─────────── │ ││
│ │ (minimal validation) │ ✓ Valid data │ ││
│ │ └─────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ DATABASE SEEDING PATH ││
│ │ ═════════════════════ ││
│ │ ││
│ │ Seeding script ││
│ │ │ ││
│ │ │ NO FRONTEND INVOLVED ││
│ │ │ ││
│ │ ▼ ││
│ │ ┌───────────────────┐ ││
│ │ │ Domain Methods │ ││
│ │ │ ─────────────── │ ││
│ │ │ • Limited checks │ ││
│ │ └─────────┬─────────┘ ││
│ │ │ ││
│ │ │ RULES NOT ENFORCED ││
│ │ │ ✗ Category parent ││
│ │ │ ✗ Control parameter ││
│ │ │ ││
│ │ ▼ ││
│ │ ┌───────────────────────────────────────────────────────────────────────┐ ││
│ │ │ Database │ ││
│ │ │ ──────── │ ││
│ │ │ ✗ INVALID DATA │ ││
│ │ │ - Treatment question without Control parent │ ││
│ │ │ - Missing conditional answers │ ││
│ │ │ - Orphaned child questions │ ││
│ │ └───────────────────────────────────────────────────────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ PROPOSED: DOMAIN ENFORCEMENT ││
│ │ ════════════════════════════ ││
│ │ ││
│ │ Any data entry path ││
│ │ │ ││
│ │ ▼ ││
│ │ ┌───────────────────┐ ││
│ │ │ Domain Layer │ ││
│ │ │ (Single Source │ ││
│ │ │ of Truth) │ ││
│ │ │ ─────────────── │ ││
│ │ │ • Category rules │ ││
│ │ │ • Parent rules │ ││
│ │ │ • Control rules │ ││
│ │ └─────────┬─────────┘ ││
│ │ │ ││
│ │ │ ALL RULES ENFORCED ││
│ │ │ ✓ Throws DomainException ││
│ │ │ for violations ││
│ │ │ ││
│ │ ▼ ││
│ │ ┌───────────────────────────────────────────────────────────────────────┐ ││
│ │ │ Database │ ││
│ │ │ ──────── │ ││
│ │ │ ✓ ALWAYS VALID DATA │ ││
│ │ └───────────────────────────────────────────────────────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
7. System Question GUID Reference Diagram¶
┌─────────────────────────────────────────────────────────────────────────────────┐
│ SYSTEM QUESTION GUID MAP │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ LABEL QUESTIONS (Create Instances) │
│ ═══════════════════════════════════ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────────┐ │
│ │ Category │ GUID │ Type │ │
│ ├────────────────────────────────────────────────────────────────────────────┤ │
│ │ Disease Model Induction │ bdb6e257-5a08-42ef-aad0-829668679b0e │ Text │ │
│ │ Treatment │ b02e3072-74f0-44e0-a468-f472b3b09991 │ Text │ │
│ │ Outcome Assessment │ dbe2720c-2e08-4f47-bcd0-3fe4ae8b8c7f │ Text │ │
│ │ Cohort │ 62c852ad-3390-48a4-ac13-439bf6b6587f │ Text │ │
│ │ Experiment │ 7c555b6e-1fb6-4036-9982-c09a5db82ace │ Text │ │
│ │ Hidden (PDF Refs) │ 7ee21ff9-e309-4387-8d30-719201497682 │ Text │ │
│ └────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ CONTROL QUESTIONS (Is Control Procedure?) │
│ ═════════════════════════════════════════ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────────┐ │
│ │ Category │ GUID │ Type │ │
│ ├────────────────────────────────────────────────────────────────────────────┤ │
│ │ Disease Model Induction │ b18aa936-a4c6-446b-ac98-88ac38930878 │ Bool │ │
│ │ Treatment │ d04ec2d7-3e10-4847-9999-befe7ee4c454 │ Bool │ │
│ └────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ LOOKUP QUESTIONS (Cross-Reference) │
│ ═══════════════════════════════════ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────────┐ │
│ │ Question │ GUID │ Refs │ │
│ ├────────────────────────────────────────────────────────────────────────────┤ │
│ │ Cohort Disease Models │ ecb550a5-ed95-473f-84bf-262c9faa7541 │ DM Lbl │ │
│ │ Cohort Treatments │ a3f2e5bb-3ade-4830-bb66-b5550a3cc85b │ Tx Lbl │ │
│ │ Cohort Outcomes │ 12ecd826-85a4-499a-844c-bd35ea6624ad │ OA Lbl │ │
│ │ Experiment Cohorts │ e7a84ba2-4ef2-4a14-83cb-7decf469d1a2 │ Co Lbl │ │
│ │ Outcome PDF Graphs │ 016278e8-7e60-40d4-9568-d7fa42670c32 │ PDFRef │ │
│ └────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ OUTCOME METADATA QUESTIONS │
│ ═══════════════════════════ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────────┐ │
│ │ Question │ GUID │ Type │ │
│ ├────────────────────────────────────────────────────────────────────────────┤ │
│ │ Average Type │ 3a287115-5000-4d3f-8c41-7c46fae9adcf │ Drop │ │
│ │ Error Type │ 8dbea59f-54d2-4e41-87e7-fde9e73a72d5 │ Drop │ │
│ │ Greater Is Worse │ 45351e04-47b2-4785-9a72-713284e917b8 │ Bool │ │
│ │ Units │ 66eb1736-a838-4692-a78b-96b0671a377c │ Text │ │
│ └────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ OTHER SYSTEM QUESTIONS │
│ ═══════════════════════ │
│ │
│ ┌────────────────────────────────────────────────────────────────────────────┐ │
│ │ Question │ GUID │ Type │ │
│ ├────────────────────────────────────────────────────────────────────────────┤ │
│ │ Cohort Number of Animals │ 83caa64f-86a1-4f6e-a278-ebbd25297677 │ Int │ │
│ └────────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
8. Stage Configuration to Question Visibility¶
This diagram shows how the Stage.Extraction boolean controls which questions are visible in the annotation form.
┌─────────────────────────────────────────────────────────────────────────────────┐
│ STAGE CONFIGURATION → QUESTION VISIBILITY │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ PROJECT CONFIGURATION │
│ ════════════════════ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ Stage Entity │ │
│ │ ───────────── │ │
│ │ • Name: "Data Extraction" │ │
│ │ • Extraction: true/false ◄── THE MASTER SWITCH │ │
│ │ • AnnotationQuestions: [custom question IDs] │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ QUESTION RESOLUTION LOGIC │ │
│ ├───────────────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ BACKEND (Stage.cs:93-96): │ │
│ │ ───────────────────────── │ │
│ │ public ImmutableHashSet<Guid> AllStageAnnotationQuestions => │ │
│ │ AnnotationQuestions.Union(Extraction │ │
│ │ ? SystemQuestionIds ◄── 18 system questions │ │
│ │ : Empty); │ │
│ │ │ │
│ │ FRONTEND (annotation-question.selectors.ts:150-152): │ │
│ │ ──────────────────────────────────────────────── │ │
│ │ return stage.extraction │ │
│ │ ? _.union(sysAnnotationQuestions, stageQuestions) │ │
│ │ : stageQuestions; │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────┴────────────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ extraction=false │ │ extraction=true │ │
│ ├─────────────────────┤ ├─────────────────────┤ │
│ │ │ │ │ │
│ │ Available: │ │ Available: │ │
│ │ ───────── │ │ ───────── │ │
│ │ • Study (custom) │ │ • ALL CATEGORIES │ │
│ │ │ │ - Study │ │
│ │ Hidden: │ │ - Disease Model │ │
│ │ ─────── │ │ - Treatment │ │
│ │ • Disease Model │ │ - Outcome │ │
│ │ • Treatment │ │ - Cohort │ │
│ │ • Outcome │ │ - Experiment │ │
│ │ • Cohort │ │ │ │
│ │ • Experiment │ │ System Qs: 18 │ │
│ │ │ │ Custom Qs: varied │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │ │ │
│ └────────────────┬────────────────┘ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ ANNOTATION FORM DISPLAY │ │
│ ├───────────────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Study │ │ Disease │ │Treatment│ │ Outcome │ │ Cohort │ │Expermt │ │ │
│ │ │ TAB │ │ Model │ │ TAB │ │ TAB │ │ TAB │ │ TAB │ │ │
│ │ │ │ │ TAB │ │ │ │ │ │ │ │ │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │ │ │ │ │ │
│ │ ▼ ▼ ▼ ▼ ▼ ▼ │ │
│ │ Questions Questions Questions Questions Questions Questions │ │
│ │ grouped by grouped by grouped by grouped by grouped by grouped by │ │
│ │ category category category category category category │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────────────────┐ │
│ │ ANNOTATION STORAGE │ │
│ ├───────────────────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ Study.ExtractionInfo │ │
│ │ ──────────────────── │ │
│ │ ├── Annotations[] ◄── Each links back to QuestionId │ │
│ │ ├── Sessions[] ◄── Tracks annotator work │ │
│ │ └── OutcomeData[] ◄── Quantitative extraction (when enabled) │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Key Insight: The Stage.Extraction boolean is the master switch that determines:
- Form structure: Whether unit-based categories (with their complex hierarchies) are available
- Question visibility: Whether the 18 system questions appear in the form
- Data storage: Whether
OutcomeDatais collected alongside annotations
9. Data Extraction Workflow¶
This diagram shows the complete workflow for data extraction, from enabling the feature to entering OutcomeData.
┌─────────────────────────────────────────────────────────────────────────────────┐
│ DATA EXTRACTION WORKFLOW │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ STEP 1: ENABLE DATA EXTRACTION │
│ ══════════════════════════════ │
│ │
│ Stage Settings → Check "Data Extraction" checkbox │
│ (Sets stage.extraction = true) │
│ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ STEP 2: CREATE UNITS (in any order, but BEFORE linking) ││
│ ├─────────────────────────────────────────────────────────────────────────────┤│
│ │ ││
│ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────────┐ ││
│ │ │ Disease Model │ │ Treatment │ │ Outcome Assessment │ ││
│ │ │ Tab │ │ Tab │ │ Tab │ ││
│ │ ├──────────────────┤ ├──────────────────┤ ├──────────────────────┤ ││
│ │ │ • Create labels │ │ • Create labels │ │ • Create labels │ ││
│ │ │ (e.g., "MCAO") │ │ (e.g.,"Aspirin")│ │ (e.g., "Infarct │ ││
│ │ │ • Mark control │ │ • Mark control │ │ Volume") │ ││
│ │ │ (Sham=true) │ │ (Vehicle=true) │ │ • Set Average Type │ ││
│ │ │ │ │ │ │ • Set Error Type │ ││
│ │ │ │ │ │ │ • Set Units │ ││
│ │ │ │ │ │ │ • Set Greater Is │ ││
│ │ │ │ │ │ │ Worse │ ││
│ │ └──────────────────┘ └──────────────────┘ └──────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ STEP 3: LINK UNITS VIA COHORT ││
│ ├─────────────────────────────────────────────────────────────────────────────┤│
│ │ ││
│ │ Cohort Tab ││
│ │ ────────── ││
│ │ ┌─────────────────────────────────────────────────────────────────┐ ││
│ │ │ Cohort Label: "Treatment Group A" │ ││
│ │ │ │ ││
│ │ │ Disease Models: [LOOKUP - select from DM units created above] │ ││
│ │ │ ☑ MCAO │ ││
│ │ │ │ ││
│ │ │ Treatments: [LOOKUP - select from Treatment units] │ ││
│ │ │ ☑ Aspirin │ ││
│ │ │ │ ││
│ │ │ Outcomes: [LOOKUP - select from Outcome units] │ ││
│ │ │ ☑ Infarct Volume │ ││
│ │ │ │ ││
│ │ │ Number of Animals: 10 │ ││
│ │ └─────────────────────────────────────────────────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ STEP 4: LINK COHORTS TO EXPERIMENT ││
│ ├─────────────────────────────────────────────────────────────────────────────┤│
│ │ ││
│ │ Experiment Tab ││
│ │ ────────────── ││
│ │ ┌─────────────────────────────────────────────────────────────────┐ ││
│ │ │ Experiment Label: "Aspirin Study" │ ││
│ │ │ │ ││
│ │ │ Cohorts: [LOOKUP - select from Cohort units] │ ││
│ │ │ ☑ Treatment Group A │ ││
│ │ │ ☑ Control Group │ ││
│ │ └─────────────────────────────────────────────────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ STEP 5: ENTER OUTCOMEDATA ││
│ ├─────────────────────────────────────────────────────────────────────────────┤│
│ │ ││
│ │ OutcomeData UI appears for EACH: Experiment → Cohort → Outcome combination ││
│ │ ││
│ │ ┌─────────────────────────────────────────────────────────────────┐ ││
│ │ │ Experiment: "Aspirin Study" │ ││
│ │ │ └── Cohort: "Treatment Group A" │ ││
│ │ │ └── Outcome: "Infarct Volume" │ ││
│ │ │ │ ││
│ │ │ TimePoints: │ ││
│ │ │ ┌─────────────────────────────────────────────┐ │ ││
│ │ │ │ Time │ Average (Mean/Median) │ Error (SD) │ │ ││
│ │ │ ├─────────────────────────────────────────────┤ │ ││
│ │ │ │ 24h │ 45.3 │ 12.1 │ │ ││
│ │ │ │ 48h │ 38.7 │ 10.5 │ │ ││
│ │ │ │ 72h │ 32.1 │ 8.2 │ │ ││
│ │ │ └─────────────────────────────────────────────┘ │ ││
│ │ │ │ ││
│ │ │ [Optional: Link to PDF Graph] │ ││
│ │ └─────────────────────────────────────────────────────────────────┘ ││
│ │ ││
│ │ NOTE: OutcomeData inherits metadata from system questions: ││
│ │ • units, averageType, errorType, greaterIsWorse ← from Outcome ││
│ │ • numberOfAnimals ← from Cohort ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐│
│ │ STORAGE ││
│ ├─────────────────────────────────────────────────────────────────────────────┤│
│ │ ││
│ │ Study.ExtractionInfo.OutcomeData[] ││
│ │ ┌─────────────────────────────────────────────────────────────────┐ ││
│ │ │ OutcomeData { │ ││
│ │ │ stageId: guid, │ ││
│ │ │ experimentId: guid, // Links to Experiment unit │ ││
│ │ │ cohortId: guid, // Links to Cohort unit │ ││
│ │ │ outcomeId: guid, // Links to Outcome unit │ ││
│ │ │ timePoints: [...], │ ││
│ │ │ units: "mm³", // From Outcome Assessment │ ││
│ │ │ averageType: "Mean", // From Outcome Assessment │ ││
│ │ │ errorType: "SD", // From Outcome Assessment │ ││
│ │ │ greaterIsWorse: true, // From Outcome Assessment │ ││
│ │ │ numberOfAnimals: 10, // From Cohort │ ││
│ │ │ graphId: guid | null // Optional PDF reference │ ││
│ │ │ } │ ││
│ │ └─────────────────────────────────────────────────────────────────┘ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
Key Insight: Units are created first, then linked via lookup questions. OutcomeData is the final step, only available once the full Experiment → Cohort → Outcome chain is established through linking.
Summary¶
These diagrams illustrate:
- Category Hierarchy - How categories relate to each other
- Question Types - Classification by function and input type
- Parent-Child Patterns - Three distinct patterns (Root, Control-based, Label-based)
- Lookup Flow - How data flows between categories via lookups
- Conditional Logic - Boolean and option-based display conditions
- Enforcement Gap - The problem with frontend-only rule enforcement
- GUID Reference - Quick lookup for all system question identifiers
- Stage Configuration - How
Stage.Extractioncontrols question visibility - Data Extraction Workflow - Complete workflow from enabling extraction to entering OutcomeData
For implementation details and code references, see the Business Logic README and Architecture Analysis.