TestDefinitionListItem:
  type: object
  properties:
    TestSiteID:
      type: integer
    TestSiteCode:
      type: string
    TestSiteName:
      type: string
    TestType:
      type: string
      enum: [TEST, PARAM, CALC, GROUP, TITLE]
    SeqScr:
      type: integer
    SeqRpt:
      type: integer
    isVisibleScr:
      type: integer
      enum: [0, 1]
    isVisibleRpt:
      type: integer
      enum: [0, 1]
    isCountStat:
      type: integer
    StartDate:
      type: string
      format: date-time
    EndDate:
      type: string
      format: date-time
      nullable: true
    DisciplineID:
      type: integer
      nullable: true
    DepartmentID:
      type: integer
      nullable: true
    DisciplineName:
      type: string
      nullable: true
    DepartmentName:
      type: string
      nullable: true

TestDefinition:
  type: object
  properties:
    TestSiteID:
      type: integer
    SiteID:
      type: integer
    TestSiteCode:
      type: string
    TestSiteName:
      type: string
    TestType:
      type: string
      enum: [TEST, PARAM, CALC, GROUP, TITLE]
      description: |
        TEST: Technical test
        PARAM: Parameter
        CALC: Calculated
        GROUP: Panel/Profile
        TITLE: Section header
    Description:
      type: string
    DisciplineID:
      type: integer
    DisciplineName:
      type: string
    DepartmentID:
      type: integer
    DepartmentName:
      type: string
    ResultType:
      type: string
      enum: [NMRIC, RANGE, TEXT, VSET, NORES]
      description: |
        Result type determines the format of test results:
        - NMRIC: Single numeric value
        - RANGE: Numeric range (min-max)
        - TEXT: Free text result
        - VSET: Value set/enum result
        - NORES: No result (for GROUP and TITLE types)
        
        TestType to ResultType mapping:
        - TEST: NMRIC | RANGE | TEXT | VSET
        - PARAM: NMRIC | RANGE | TEXT | VSET
        - CALC: NMRIC (calculated result is always numeric)
        - GROUP: NORES (no result, container only)
        - TITLE: NORES (no result, header only)
    RefType:
      type: string
      enum: [RANGE, THOLD, VSET, TEXT, NOREF]
      description: |
        Reference type determines which reference range table to use:
        - RANGE: Numeric reference range
        - THOLD: Threshold/panic range
        - VSET: Value set reference
        - TEXT: Free text reference
        - NOREF: No reference (for NORES result type)
        
        ResultType to RefType mapping:
        - NMRIC: RANGE | THOLD → refnum table
        - RANGE: RANGE | THOLD → refnum table
        - VSET: VSET → reftxt table
        - TEXT: TEXT → reftxt table
        - NORES: NOREF → (no reference table)
    VSet:
      type: integer
      description: Value set ID for VSET result type
    ReqQty:
      type: number
      format: decimal
      description: Required sample quantity
    ReqQtyUnit:
      type: string
      description: Unit for required quantity
    Unit1:
      type: string
      description: Primary unit
    Factor:
      type: number
      format: decimal
      description: Conversion factor
    Unit2:
      type: string
      description: Secondary unit (after conversion)
    Decimal:
      type: integer
      description: Number of decimal places
    CollReq:
      type: string
      description: Collection requirements
    Method:
      type: string
      description: Test method
    ExpectedTAT:
      type: integer
      description: Expected turnaround time
    SeqScr:
      type: integer
      description: Screen sequence
    SeqRpt:
      type: integer
      description: Report sequence
    IndentLeft:
      type: integer
      default: 0
    FontStyle:
      type: string
    isVisibleScr:
      type: integer
      default: 1
      description: Screen visibility (0=hidden, 1=visible)
    isVisibleRpt:
      type: integer
      default: 1
      description: Report visibility (0=hidden, 1=visible)
    isCountStat:
      type: integer
      default: 1
    Level:
      type: integer
    isRequestable:
      type: integer
      default: 1
      description: Flag indicating if test can be requested (1=yes, 0=no)
    CreateDate:
      type: string
      format: date-time
    StartDate:
      type: string
      format: date-time
    EndDate:
      type: string
      format: date-time
    FormulaCode:
      type: string
      description: Formula expression for calculated tests
    testdefcal:
      type: array
      description: Calculated test details (only for CALC type)
      items:
        type: object
    testdefgrp:
      type: object
      description: Group definition payload for GROUP and CALC types.
      properties:
        members:
          type: array
          description: |
            Group members (for GROUP and CALC types).
            When creating or updating, provide members in testdefgrp.members with TestSiteID field.
            Do NOT use Member, SeqScr, or Members fields when creating/updating.
          items:
            type: object
            properties:
              TestGrpID:
                type: integer
                description: Group membership record ID
              TestSiteID:
                type: integer
                description: Parent group TestSiteID
              Member:
                type: integer
                description: |
                  Member TestSiteID (foreign key to testdefsite).
                  **Note**: This field is in the response. When creating/updating, use TestSiteID in testdefgrp.members instead.
              TestSiteCode:
                type: string
                description: Member test code
              TestSiteName:
                type: string
                description: Member test name
              TestType:
                type: string
                description: Member test type
              CreateDate:
                type: string
                format: date-time
              EndDate:
                type: string
                format: date-time
    testmap:
      type: array
      description: Flat test mapping payload for /api/test create/update
      items:
        type: object
        properties:
          HostType:
            type: string
          HostID:
            type: string
          HostTestCode:
            type: string
          HostTestName:
            type: string
          ClientType:
            type: string
          ClientID:
            type: string
          ClientTestCode:
            type: string
          ClientTestName:
            type: string
          ConDefID:
            type: integer
            nullable: true
    refnum:
      type: array
      description: Numeric reference ranges (optional). Mutually exclusive with reftxt - a test can only have ONE reference type.
      items:
        type: object
        properties:
          RefNumID:
            type: integer
          NumRefType:
            type: string
            enum: [NMRC, THOLD]
            description: NMRC=Numeric range, THOLD=Threshold
          NumRefTypeLabel:
            type: string
          RangeType:
            type: string
          RangeTypeLabel:
            type: string
          SpcType:
            type: string
            description: Specimen type code (e.g., GEN, EDTA)
          Sex:
            type: string
          SexLabel:
            type: string
          LowSign:
            type: string
          LowSignLabel:
            type: string
          HighSign:
            type: string
          HighSignLabel:
            type: string
          High:
            type: number
            format: float
          Low:
            type: number
            format: float
          AgeStart:
            type: integer
            description: Minimum patient age in days
          AgeEnd:
            type: integer
            description: Maximum patient age in days
          Flag:
            type: string
          Interpretation:
            type: string
          Notes:
            type: string
            description: Optional note attached to the numeric reference range
    reftxt:
      type: array
      description: Text reference ranges (optional). Mutually exclusive with refnum - a test can only have ONE reference type.
      items:
        type: object
        properties:
          RefTxtID:
            type: integer
          TxtRefType:
            type: string
            enum: [TEXT, VSET]
            description: TEXT=Free text, VSET=Value set
          TxtRefTypeLabel:
            type: string
          Sex:
            type: string
          SexLabel:
            type: string
          AgeStart:
            type: integer
            description: Minimum patient age in days
          AgeEnd:
            type: integer
            description: Maximum patient age in days
          RefTxt:
            type: string
          Flag:
            type: string
  examples:
    TEST_numeric:
      summary: Technical test with numeric reference
      value:
        TestSiteID: 1
        SiteID: 1
        TestSiteCode: GLU
        TestSiteName: Glucose
        TestType: TEST
        DisciplineID: 2
        DepartmentID: 2
        ResultType: NMRIC
        RefType: NMRC
        Unit1: mg/dL
        ReqQty: 300
        ReqQtyUnit: uL
        Decimal: 0
        Method: Hexokinase
        SeqScr: 11
        SeqRpt: 11
        isVisibleScr: 1
        isVisibleRpt: 1
        isCountStat: 1
        refnum:
          - RefNumID: 1
            NumRefType: NMRC
            NumRefTypeLabel: Numeric
            RangeType: REF
            RangeTypeLabel: Reference Range
            Sex: '2'
            SexLabel: Male
            LowSign: GE
            LowSignLabel: ">="
            HighSign: LE
            HighSignLabel: "<="
            Low: 70
            High: 100
            AgeStart: 6570
            AgeEnd: 36135
            Flag: N
            Interpretation: Normal
    TEST_threshold:
      summary: Technical test with threshold reference (panic)
      value:
        TestSiteID: 2
        SiteID: 1
        TestSiteCode: GLU
        TestSiteName: Glucose
        TestType: TEST
        DisciplineID: 2
        DepartmentID: 2
        ResultType: NMRIC
        RefType: THOLD
        Unit1: mg/dL
        Decimal: 0
        Method: Hexokinase
        SeqScr: 11
        SeqRpt: 11
        isVisibleScr: 1
        isVisibleRpt: 1
        isCountStat: 1
        refnum:
          - RefNumID: 2
            NumRefType: THOLD
            NumRefTypeLabel: Threshold
            RangeType: PANIC
            RangeTypeLabel: Panic Range
            Sex: '1'
            SexLabel: Female
            LowSign: LT
            LowSignLabel: "<"
            High: 40
            AgeStart: 0
            AgeEnd: 43800
            Flag: L
            Interpretation: Critical Low
    TEST_text:
      summary: Technical test with text reference
      value:
        TestSiteID: 3
        SiteID: 1
        TestSiteCode: STAGE
        TestSiteName: Disease Stage
        TestType: TEST
        DisciplineID: 1
        DepartmentID: 1
        ResultType: VSET
        RefType: TEXT
        SeqScr: 50
        SeqRpt: 50
        isVisibleScr: 1
        isVisibleRpt: 1
        isCountStat: 1
        reftxt:
          - RefTxtID: 1
            TxtRefType: TEXT
            TxtRefTypeLabel: Text
            Sex: '2'
            SexLabel: Male
            AgeStart: 6570
            AgeEnd: 36135
            RefTxt: 'NORM=Normal;HYPO=Hypochromic;MACRO=Macrocytic'
            Flag: N
    PARAM:
      summary: Parameter test
      value:
        TestSiteID: 4
        SiteID: 1
        TestSiteCode: HEIGHT
        TestSiteName: Height
        TestType: PARAM
        DisciplineID: 10
        ResultType: NMRIC
        Unit1: cm
        Decimal: 0
        SeqScr: 40
        SeqRpt: 40
        isVisibleScr: 1
        isVisibleRpt: 0
        isCountStat: 0
    CALC:
      summary: Calculated test with reference
      value:
        TestSiteID: 5
        SiteID: 1
        TestSiteCode: EGFR
        TestSiteName: eGFR
        TestType: CALC
        DisciplineID: 2
        DepartmentID: 2
        Unit1: mL/min/1.73m2
        Decimal: 0
        SeqScr: 20
        SeqRpt: 20
        isVisibleScr: 1
        isVisibleRpt: 1
        isCountStat: 0
        testdefcal:
          - TestCalID: 1
            DisciplineID: 2
            DepartmentID: 2
            FormulaCode: CKD_EPI(CREA,AGE,GENDER)
            Unit1: mL/min/1.73m2
            Decimal: 0
        testdefgrp:
          members:
            - TestSiteID: 21
              TestSiteCode: CREA
              TestSiteName: Creatinine
              TestType: TEST
            - TestSiteID: 51
              TestSiteCode: AGE
              TestSiteName: Age
              TestType: PARAM
        refnum:
          - RefNumID: 5
            NumRefType: NMRC
            NumRefTypeLabel: Numeric
            RangeType: REF
            RangeTypeLabel: Reference Range
            Sex: '1'
            SexLabel: Female
            LowSign: GE
            LowSignLabel: ">="
            HighSign: LE
            HighSignLabel: "<="
            Low: 10
            High: 20
            AgeStart: 6570
            AgeEnd: 43800
            Flag: N
            Interpretation: Normal
    GROUP:
      summary: Panel/Profile test
      value:
        TestSiteID: 6
        SiteID: 1
        TestSiteCode: LIPID
        TestSiteName: Lipid Panel
        TestType: GROUP
        DisciplineID: 2
        DepartmentID: 2
        SeqScr: 51
        SeqRpt: 51
        isVisibleScr: 1
        isVisibleRpt: 1
        isCountStat: 1
        testdefgrp:
          members:
            - TestGrpID: 1
              TestSiteID: 6
              Member: 100
              MemberTestSiteID: 100
              TestSiteCode: CHOL
              TestSiteName: Total Cholesterol
              TestType: TEST
            - TestGrpID: 2
              TestSiteID: 6
              Member: 101
              MemberTestSiteID: 101
              TestSiteCode: TG
              TestSiteName: Triglycerides
              TestType: TEST
    TITLE:
      summary: Section header
      value:
        TestSiteID: 7
        SiteID: 1
        TestSiteCode: CHEM_HEADER
        TestSiteName: '--- CHEMISTRY ---'
        TestType: TITLE
        DisciplineID: 2
        DepartmentID: 2
        SeqScr: 100
        SeqRpt: 100
        isVisibleScr: 1
        isVisibleRpt: 1
        isCountStat: 0

TestMap:
  type: object
  properties:
    TestMapID:
      type: integer
    HostType:
      type: string
      description: Host type code (e.g., SITE, WORKSTATION, INSTRUMENT)
    HostID:
      type: string
      description: Host identifier
    ClientType:
      type: string
      description: Client type code (e.g., SITE, WORKSTATION, INSTRUMENT)
    ClientID:
      type: string
      description: Client identifier
    HostName:
      type: string
      description: Resolved host name (from view)
    ClientName:
      type: string
      description: Resolved client name (from view)
    details:
      type: array
      description: Test mapping detail records
      items:
        $ref: '#/TestMapDetail'
    CreateDate:
      type: string
      format: date-time
    EndDate:
      type: string
      format: date-time
      description: Soft delete timestamp

TestMapDetail:
  type: object
  properties:
    TestMapDetailID:
      type: integer
    TestMapID:
      type: integer
    HostTestCode:
      type: string
      description: Test code in host system
    HostTestName:
      type: string
      description: Test name in host system
    ConDefID:
      type: integer
      description: Container definition ID
    ClientTestCode:
      type: string
      description: Test code in client system
    ClientTestName:
      type: string
      description: Test name in client system
    CreateDate:
      type: string
      format: date-time
    EndDate:
      type: string
      format: date-time
      description: Soft delete timestamp
