/api/test:
  get:
    tags: [Test]
    summary: List test definitions
    security:
      - bearerAuth: []
    parameters:
      - name: page
        in: query
        schema:
          type: integer
          default: 1
        description: Page number for pagination
      - name: perPage
        in: query
        schema:
          type: integer
          default: 20
        description: Number of items per page
      - name: SiteID
        in: query
        schema:
          type: integer
        description: Filter by site ID
      - name: TestType
        in: query
        schema:
          type: string
          enum: [TEST, PARAM, CALC, GROUP, TITLE]
        description: Filter by test type
      - name: isVisibleScr
        in: query
        schema:
          type: integer
          enum: [0, 1]
        description: Filter by screen visibility (0=hidden, 1=visible)
      - name: isVisibleRpt
        in: query
        schema:
          type: integer
          enum: [0, 1]
        description: Filter by report visibility (0=hidden, 1=visible)
      - name: search
        in: query
        schema:
          type: string
        description: Search by test code or name
    responses:
      '200':
        description: List of test definitions
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                message:
                  type: string
                data:
                  type: array
                  items:
                    $ref: '../components/schemas/tests.yaml#/TestDefinitionListItem'
                pagination:
                  type: object
                  properties:
                    total:
                      type: integer
                      description: Total number of records matching the query
            examples:
              list_flat:
                summary: Flat list response from testdefsite
                value:
                  status: success
                  message: Data fetched successfully
                  data:
                    - TestSiteID: 21
                      TestSiteCode: GLU
                      TestSiteName: Glucose
                      TestType: TEST
                      SeqScr: 11
                      SeqRpt: 11
                      isVisibleScr: 1
                      isVisibleRpt: 1
                      isCountStat: 1
                      StartDate: '2026-01-01 00:00:00'
                      EndDate: null
                      DisciplineID: 2
                      DepartmentID: 2
                      DisciplineName: Clinical Chemistry
                      DepartmentName: Laboratory
                    - TestSiteID: 22
                      TestSiteCode: CREA
                      TestSiteName: Creatinine
                      TestType: TEST
                      SeqScr: 12
                      SeqRpt: 12
                      isVisibleScr: 1
                      isVisibleRpt: 1
                      isCountStat: 1
                      StartDate: '2026-01-01 00:00:00'
                      EndDate: null
                      DisciplineID: 2
                      DepartmentID: 2
                      DisciplineName: Clinical Chemistry
                      DepartmentName: Laboratory

  post:
    tags: [Test]
    summary: Create test definition
    security:
      - bearerAuth: []
    requestBody:
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              SiteID:
                type: integer
                description: Site ID (required)
              TestSiteCode:
                type: string
                description: Test code (required)
              TestSiteName:
                type: string
                description: Test name (required)
              TestType:
                type: string
                enum: [TEST, PARAM, CALC, GROUP, TITLE]
                description: Test type (required)
              Description:
                type: string
              DisciplineID:
                type: integer
              DepartmentID:
                type: integer
              ResultType:
                type: string
                enum: [NMRIC, RANGE, TEXT, VSET, NORES]
              RefType:
                type: string
                enum: [RANGE, THOLD, VSET, TEXT, NOREF]
              VSet:
                type: integer
              ReqQty:
                type: number
                format: decimal
              ReqQtyUnit:
                type: string
              Unit1:
                type: string
              Factor:
                type: number
                format: decimal
              Unit2:
                type: string
              Decimal:
                type: integer
              CollReq:
                type: string
              Method:
                type: string
              ExpectedTAT:
                type: integer
              SeqScr:
                type: integer
              SeqRpt:
                type: integer
              IndentLeft:
                type: integer
              FontStyle:
                type: string
              isVisibleScr:
                type: integer
              isVisibleRpt:
                type: integer
              isCountStat:
                type: integer
              testdefcal:
                type: object
                description: Calculated test metadata persisted in the `testdefcal` table.
                properties:
                  FormulaCode:
                    type: string
                    description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
              testdefgrp:
                type: object
                description: Group definition wrapper for CALC/GROUP member assignments.
                properties:
                  members:
                    type: array
                    description: Array of member TestSiteIDs for CALC/GROUP definitions.
                    items:
                      type: object
                      properties:
                        TestSiteID:
                          type: integer
                          description: Foreign key referencing the member test's TestSiteID.
                      required:
                        - TestSiteID
              refnum:
                type: array
                items:
                  type: object
              reftxt:
                type: array
                items:
                  type: object
              testmap:
                type: array
                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
            required:
              - SiteID
              - TestSiteCode
              - TestSiteName
              - TestType
          examples:
            TEST_no_ref:
              summary: Technical test without reference or map
              value:
                SiteID: 1
                TestSiteCode: TEST_NREF
                TestSiteName: Numeric Test
                TestType: TEST
                SeqScr: 500
                SeqRpt: 500
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                DisciplineID: 2
                DepartmentID: 2
                Unit1: mg/dL
                Method: CBC Analyzer
            PARAM_no_ref:
              summary: Parameter without reference or map
              value:
                SiteID: 1
                TestSiteCode: PARAM_NRF
                TestSiteName: Clinical Parameter
                TestType: PARAM
                SeqScr: 10
                SeqRpt: 10
                isVisibleScr: 1
                isVisibleRpt: 0
                isCountStat: 0
                DisciplineID: 10
                DepartmentID: 0
                Unit1: cm
                Method: Manual entry
            TEST_range_single:
              summary: Technical test with numeric range reference (single)
              value:
                SiteID: 1
                TestSiteCode: TEST_RANGE
                TestSiteName: Glucose Range
                TestType: TEST
                SeqScr: 105
                SeqRpt: 105
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                refnum:
                  - NumRefType: NMRC
                    RangeType: REF
                    Sex: '2'
                    LowSign: GE
                    Low: 70
                    HighSign: LE
                    High: 100
                    AgeStart: 6570
                    AgeEnd: 36135
                    Flag: N
                DisciplineID: 2
                DepartmentID: 2
                ResultType: NMRIC
                RefType: RANGE
                Unit1: mg/dL
                Method: Hexokinase
            TEST_range_multiple_map:
              summary: Numeric reference with multiple ranges and test map
              value:
                SiteID: 1
                TestSiteCode: TEST_RMAP
                TestSiteName: Glucose Panic Range
                TestType: TEST
                SeqScr: 110
                SeqRpt: 110
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                refnum:
                  - NumRefType: NMRC
                    RangeType: REF
                    Sex: '2'
                    LowSign: GE
                    Low: 70
                    HighSign: LE
                    High: 100
                    AgeStart: 6570
                    AgeEnd: 36135
                    Flag: N
                  - NumRefType: NMRC
                    RangeType: REF
                    Sex: '1'
                    LowSign: '>'
                    Low: 75
                    HighSign: <
                    High: 105
                    AgeStart: 6570
                    AgeEnd: 36135
                    Flag: N
                testmap:
                  - HostType: SITE
                    HostID: '1'
                    HostTestCode: GLU
                    HostTestName: Glucose
                    ClientType: WST
                    ClientID: '1'
                    ClientTestCode: GLU_C
                    ClientTestName: Glucose Client
                    ConDefID: 1
                  - HostType: SITE
                    HostID: '1'
                    HostTestCode: CREA
                    HostTestName: Creatinine
                    ClientType: WST
                    ClientID: '1'
                    ClientTestCode: CREA_C
                    ClientTestName: Creatinine Client
                    ConDefID: 2
                  - HostType: WST
                    HostID: '3'
                    HostTestCode: HB
                    HostTestName: Hemoglobin
                    ClientType: INST
                    ClientID: '2'
                    ClientTestCode: HB_C
                    ClientTestName: Hemoglobin Client
                    ConDefID: 3
                DisciplineID: 2
                DepartmentID: 2
                ResultType: NMRIC
                RefType: RANGE
                Unit1: mg/dL
                Method: Hexokinase
            TEST_threshold:
              summary: Technical test with threshold reference
              value:
                SiteID: 1
                TestSiteCode: TEST_THLD
                TestSiteName: Sodium Threshold
                TestType: TEST
                SeqScr: 115
                SeqRpt: 115
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                refnum:
                  - NumRefType: THOLD
                    RangeType: PANIC
                    Sex: '2'
                    LowSign: LT
                    Low: 120
                    AgeStart: 0
                    AgeEnd: 45625
                    Flag: H
                DisciplineID: 2
                DepartmentID: 2
                ResultType: NMRIC
                RefType: THOLD
                Unit1: mmol/L
                Method: Auto Analyzer
            TEST_threshold_map:
              summary: Threshold reference plus test map
              value:
                SiteID: 1
                TestSiteCode: TEST_TMAP
                TestSiteName: Potassium Panic
                TestType: TEST
                SeqScr: 120
                SeqRpt: 120
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                refnum:
                  - NumRefType: THOLD
                    RangeType: PANIC
                    Sex: '2'
                    LowSign: LT
                    Low: 120
                    AgeStart: 0
                    AgeEnd: 45625
                    Flag: H
                  - NumRefType: THOLD
                    RangeType: PANIC
                    Sex: '1'
                    LowSign: <
                    Low: 121
                    AgeStart: 0
                    AgeEnd: 45625
                    Flag: H
                testmap:
                  - HostType: SITE
                    HostID: '1'
                    ClientType: WST
                    ClientID: '1'
                    details:
                      - HostTestCode: HB
                        HostTestName: Hemoglobin
                        ConDefID: 3
                        ClientTestCode: HB_C
                        ClientTestName: Hemoglobin Client
                      - HostTestCode: GLU
                        HostTestName: Glucose
                        ConDefID: 1
                        ClientTestCode: GLU_C
                        ClientTestName: Glucose Client
                DisciplineID: 2
                DepartmentID: 2
                ResultType: NMRIC
                RefType: THOLD
                Unit1: mmol/L
                Method: Auto Analyzer
            TEST_text:
              summary: Technical test with text reference
              value:
                SiteID: 1
                TestSiteCode: TEST_TEXT
                TestSiteName: Disease Stage
                TestType: TEST
                SeqScr: 130
                SeqRpt: 130
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                reftxt:
                  - SpcType: GEN
                    TxtRefType: TEXT
                    Sex: '2'
                    AgeStart: 6570
                    AgeEnd: 36135
                    RefTxt: NORM=Normal;HIGH=High
                    Flag: N
                DisciplineID: 1
                DepartmentID: 1
                ResultType: TEXT
                RefType: TEXT
                Method: Morphology
            TEST_text_map:
              summary: Text reference plus test map
              value:
                SiteID: 1
                TestSiteCode: TEST_TXM
                TestSiteName: Disease Stage (Map)
                TestType: TEST
                SeqScr: 135
                SeqRpt: 135
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                reftxt:
                  - SpcType: GEN
                    TxtRefType: TEXT
                    Sex: '2'
                    AgeStart: 6570
                    AgeEnd: 36135
                    RefTxt: NORM=Normal
                    Flag: N
                  - SpcType: GEN
                    TxtRefType: TEXT
                    Sex: '1'
                    AgeStart: 6570
                    AgeEnd: 36135
                    RefTxt: ABN=Abnormal
                    Flag: N
                testmap:
                  - HostType: SITE
                    HostID: '1'
                    ClientType: WST
                    ClientID: '1'
                    details:
                      - HostTestCode: STAGE
                        HostTestName: Disease Stage
                        ConDefID: 4
                        ClientTestCode: STAGE_C
                        ClientTestName: Disease Stage Client
                DisciplineID: 1
                DepartmentID: 1
                ResultType: TEXT
                RefType: TEXT
            TEST_valueset:
              summary: Technical test using a value set result
              value:
                SiteID: 1
                TestSiteCode: TEST_VSET
                TestSiteName: Urine Color
                TestType: TEST
                SeqScr: 140
                SeqRpt: 140
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                reftxt:
                  - SpcType: GEN
                    TxtRefType: VSET
                    Sex: '2'
                    AgeStart: 0
                    AgeEnd: 43800
                    RefTxt: NORM=Normal;MACRO=Macro
                    Flag: N
                DisciplineID: 4
                DepartmentID: 4
                ResultType: VSET
                RefType: VSET
                Method: Visual
            TEST_valueset_map:
              summary: Value set reference with test map
              value:
                SiteID: 1
                TestSiteCode: TEST_VMAP
                TestSiteName: Urine Color (Map)
                TestType: TEST
                SeqScr: 145
                SeqRpt: 145
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                reftxt:
                  - SpcType: GEN
                    TxtRefType: VSET
                    Sex: '2'
                    AgeStart: 0
                    AgeEnd: 43800
                    RefTxt: NORM=Normal;ABN=Abnormal
                    Flag: N
                testmap:
                  - HostType: SITE
                    HostID: '1'
                    ClientType: WST
                    ClientID: '8'
                    details:
                      - HostTestCode: UCOLOR
                        HostTestName: Urine Color
                        ConDefID: 12
                        ClientTestCode: UCOLOR_C
                        ClientTestName: Urine Color Client
                DisciplineID: 4
                DepartmentID: 4
                ResultType: VSET
                RefType: VSET
            TEST_valueset_map_no_reftxt:
              summary: Value set result with mapping but without explicit text reference entries
              value:
                SiteID: 1
                TestSiteCode: TEST_VSETM
                TestSiteName: Urine Result Map
                TestType: TEST
                SeqScr: 150
                SeqRpt: 150
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                testmap:
                  - HostType: SITE
                    HostID: '1'
                    ClientType: WST
                    ClientID: '8'
                    details:
                      - HostTestCode: UGLUC
                        HostTestName: Urine Glucose
                        ConDefID: 12
                        ClientTestCode: UGLUC_C
                        ClientTestName: Urine Glucose Client
                DisciplineID: 4
                DepartmentID: 4
                ResultType: VSET
                RefType: VSET
            CALC_basic:
              summary: Calculated test with members (no references)
              value:
                SiteID: 1
                TestSiteCode: CALC_BASE
                TestSiteName: Estimated GFR
                TestType: CALC
                SeqScr: 190
                SeqRpt: 190
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 0
                DisciplineID: 2
                DepartmentID: 2
                testdefcal:
                  FormulaCode: CKD_EPI(CREA,AGE,GENDER)
                testdefgrp:
                  members:
                    - TestSiteID: 21
                    - TestSiteID: 22
            CALC_full:
              summary: Calculated test with numeric reference ranges and map
              value:
                SiteID: 1
                TestSiteCode: CALC_FULL
                TestSiteName: Estimated GFR (Map)
                TestType: CALC
                SeqScr: 195
                SeqRpt: 195
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 0
                refnum:
                  - NumRefType: NMRC
                    RangeType: REF
                    Sex: '2'
                    LowSign: GE
                    Low: 10
                    HighSign: LE
                    High: 20
                    AgeStart: 6570
                    AgeEnd: 43800
                    Flag: N
                testmap:
                  - HostType: SITE
                    HostID: '1'
                    ClientType: WST
                    ClientID: '3'
                    details:
                      - HostTestCode: EGFR
                        HostTestName: eGFR
                        ConDefID: 1
                        ClientTestCode: EGFR_C
                        ClientTestName: eGFR Client
                DisciplineID: 2
                DepartmentID: 2
                testdefcal:
                  FormulaCode: CKD_EPI(CREA,AGE,GENDER)
                testdefgrp:
                  members:
                    - TestSiteID: 21
                    - TestSiteID: 22
            GROUP_with_members:
              summary: Group/profile test with members and mapping
              value:
                SiteID: 1
                TestSiteCode: GROUP_PNL
                TestSiteName: Lipid Profile
                TestType: GROUP
                SeqScr: 10
                SeqRpt: 10
                isVisibleScr: 1
                isVisibleRpt: 1
                isCountStat: 1
                testmap:
                  - HostType: SITE
                    HostID: '1'
                    ClientType: WST
                    ClientID: '3'
                    details:
                      - HostTestCode: LIPID
                        HostTestName: Lipid Profile
                        ConDefID: 1
                        ClientTestCode: LIPID_C
                        ClientTestName: Lipid Client
                testdefgrp:
                  members:
                    - TestSiteID: 169
                    - TestSiteID: 170

    responses:
      '201':
        description: Test definition created
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: created
                message:
                  type: string
                data:
                  type: object
                  properties:
                    TestSiteId:
                      type: integer
      '400':
        description: Validation error (e.g., invalid member TestSiteID)
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: failed
                message:
                  type: string
                  example: 'Invalid member TestSiteID(s): 185, 186. Make sure to use TestSiteID, not SeqScr or other values.'

/api/test/{id}:
  get:
    tags: [Test]
    summary: Get test definition by ID
    security:
      - bearerAuth: []
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Test Site ID
    responses:
      '200':
        description: Test definition details
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                message:
                  type: string
                data:
                  $ref: '../components/schemas/tests.yaml#/TestDefinition'
      '404':
        description: Test not found

  patch:
    tags: [Test]
    summary: Update test definition
    security:
      - bearerAuth: []
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Test Site ID
    requestBody:
      required: true
      content:
        application/json:
          schema:
            type: object
            properties:
              TestSiteID:
                type: integer
                description: Test Site ID (required)
              TestSiteCode:
                type: string
              TestSiteName:
                type: string
              TestType:
                type: string
                enum: [TEST, PARAM, CALC, GROUP, TITLE]
              Description:
                type: string
              DisciplineID:
                type: integer
              DepartmentID:
                type: integer
              ResultType:
                type: string
                enum: [NMRIC, RANGE, TEXT, VSET, NORES]
              RefType:
                type: string
                enum: [RANGE, THOLD, VSET, TEXT, NOREF]
              VSet:
                type: integer
              ReqQty:
                type: number
                format: decimal
              ReqQtyUnit:
                type: string
              Unit1:
                type: string
              Factor:
                type: number
                format: decimal
              Unit2:
                type: string
              Decimal:
                type: integer
              CollReq:
                type: string
              Method:
                type: string
              ExpectedTAT:
                type: integer
              SeqScr:
                type: integer
              SeqRpt:
                type: integer
              IndentLeft:
                type: integer
              FontStyle:
                type: string
              isVisibleScr:
                type: integer
              isVisibleRpt:
                type: integer
              isCountStat:
                type: integer
              testdefcal:
                type: object
                description: Calculated test metadata persisted in the `testdefcal` table.
                properties:
                  FormulaCode:
                    type: string
                    description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
              testdefgrp:
                type: object
                description: Group definition wrapper for CALC/GROUP member assignments.
                properties:
                  members:
                    type: array
                    description: Array of member TestSiteIDs for CALC/GROUP definitions.
                    items:
                      type: object
                      properties:
                        TestSiteID:
                          type: integer
                          description: Foreign key referencing the member test's TestSiteID.
                      required:
                        - TestSiteID
              refnum:
                type: array
                items:
                  type: object
              reftxt:
                type: array
                items:
                  type: object
              testmap:
                type: array
                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
            required:
              - TestSiteID
    responses:
      '200':
        description: Test definition updated
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: success
                message:
                  type: string
                data:
                  type: object
                  properties:
                    TestSiteId:
                      type: integer
      '400':
        description: Validation error (e.g., invalid member TestSiteID)
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: failed
                message:
                  type: string
                  example: 'Invalid member TestSiteID(s): 185, 186. Make sure to use TestSiteID, not SeqScr or other values.'

  delete:
    tags: [Test]
    summary: Soft delete test definition
    security:
      - bearerAuth: []
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: integer
        description: Test Site ID to delete
    requestBody:
      content:
        application/json:
          schema:
            type: object
            properties:
              TestSiteID:
                type: integer
                description: Optional - can be provided in body instead of path
    responses:
      '200':
        description: Test disabled successfully
        content:
          application/json:
            schema:
              type: object
              properties:
                status:
                  type: string
                  example: success
                message:
                  type: string
                data:
                  type: object
                  properties:
                    TestSiteId:
                      type: integer
                    EndDate:
                      type: string
                      format: date-time
      '404':
        description: Test not found
      '422':
        description: Test already disabled
