fix: wrap test group members under testdefgrp

Align CALC/GROUP request and response payloads to use the testdefgrp.members structure in controller handling, feature tests, and OpenAPI schemas/examples for a consistent API contract.
This commit is contained in:
mahdahar 2026-04-02 09:06:42 +07:00
parent eeaed768c9
commit 694c5a6211
5 changed files with 235 additions and 191 deletions

View File

@ -92,9 +92,13 @@ class TestsController extends BaseController
if ($typeCode === 'CALC') {
$row['testdefcal'] = $this->modelCal->getByTestSiteID($id);
$row['members'] = $this->modelGrp->getGroupMembers($id);
$row['testdefgrp'] = [
'members' => $this->modelGrp->getGroupMembers($id),
];
} elseif ($typeCode === 'GROUP') {
$row['members'] = $this->modelGrp->getGroupMembers($id);
$row['testdefgrp'] = [
'members' => $this->modelGrp->getGroupMembers($id),
];
} elseif ($typeCode !== 'TITLE') {
$refType = $row['RefType'] ?? '';
$resultType = $row['ResultType'] ?? '';
@ -511,7 +515,7 @@ class TestsController extends BaseController
{
$memberIDs = [];
$rawMembers = $input['members'] ?? [];
$rawMembers = $input['testdefgrp']['members'] ?? [];
if (is_array($rawMembers)) {
foreach ($rawMembers as $member) {
if (is_array($member)) {

View File

@ -4671,17 +4671,21 @@ paths:
FormulaCode:
type: string
description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
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
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:
@ -5096,9 +5100,10 @@ paths:
DepartmentID: 2
testdefcal:
FormulaCode: CKD_EPI(CREA,AGE,GENDER)
members:
- TestSiteID: 21
- TestSiteID: 22
testdefgrp:
members:
- TestSiteID: 21
- TestSiteID: 22
CALC_full:
summary: Calculated test with numeric reference ranges and map
value:
@ -5137,9 +5142,10 @@ paths:
DepartmentID: 2
testdefcal:
FormulaCode: CKD_EPI(CREA,AGE,GENDER)
members:
- TestSiteID: 21
- TestSiteID: 22
testdefgrp:
members:
- TestSiteID: 21
- TestSiteID: 22
GROUP_with_members:
summary: Group/profile test with members and mapping
value:
@ -5163,9 +5169,10 @@ paths:
ConDefID: 1
ClientTestCode: LIPID_C
ClientTestName: Lipid Client
members:
- TestSiteID: 169
- TestSiteID: 170
testdefgrp:
members:
- TestSiteID: 169
- TestSiteID: 170
responses:
'201':
description: Test definition created
@ -5327,17 +5334,21 @@ paths:
FormulaCode:
type: string
description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
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
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:
@ -7050,41 +7061,45 @@ components:
description: Calculated test details (only for CALC type)
items:
type: object
members:
type: array
description: |
Group members (for GROUP and CALC types).
When creating or updating, provide members in members array 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 members array 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
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
@ -7338,15 +7353,16 @@ components:
FormulaCode: CKD_EPI(CREA,AGE,GENDER)
Unit1: mL/min/1.73m2
Decimal: 0
members:
- TestSiteID: 21
TestSiteCode: CREA
TestSiteName: Creatinine
TestType: TEST
- TestSiteID: 51
TestSiteCode: AGE
TestSiteName: Age
TestType: PARAM
testdefgrp:
members:
- TestSiteID: 21
TestSiteCode: CREA
TestSiteName: Creatinine
TestType: TEST
- TestSiteID: 51
TestSiteCode: AGE
TestSiteName: Age
TestType: PARAM
refnum:
- RefNumID: 5
NumRefType: NMRC
@ -7380,21 +7396,22 @@ components:
isVisibleScr: 1
isVisibleRpt: 1
isCountStat: 1
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
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:

View File

@ -183,41 +183,45 @@ TestDefinition:
description: Calculated test details (only for CALC type)
items:
type: object
members:
type: array
description: |
Group members (for GROUP and CALC types).
When creating or updating, provide members in members array 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 members array 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
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
@ -467,15 +471,16 @@ TestDefinition:
FormulaCode: CKD_EPI(CREA,AGE,GENDER)
Unit1: mL/min/1.73m2
Decimal: 0
members:
- TestSiteID: 21
TestSiteCode: CREA
TestSiteName: Creatinine
TestType: TEST
- TestSiteID: 51
TestSiteCode: AGE
TestSiteName: Age
TestType: PARAM
testdefgrp:
members:
- TestSiteID: 21
TestSiteCode: CREA
TestSiteName: Creatinine
TestType: TEST
- TestSiteID: 51
TestSiteCode: AGE
TestSiteName: Age
TestType: PARAM
refnum:
- RefNumID: 5
NumRefType: NMRC
@ -509,21 +514,22 @@ TestDefinition:
isVisibleScr: 1
isVisibleRpt: 1
isCountStat: 1
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
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:

View File

@ -185,17 +185,21 @@
FormulaCode:
type: string
description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
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
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:
@ -610,9 +614,10 @@
DepartmentID: 2
testdefcal:
FormulaCode: CKD_EPI(CREA,AGE,GENDER)
members:
- TestSiteID: 21
- TestSiteID: 22
testdefgrp:
members:
- TestSiteID: 21
- TestSiteID: 22
CALC_full:
summary: Calculated test with numeric reference ranges and map
value:
@ -651,9 +656,10 @@
DepartmentID: 2
testdefcal:
FormulaCode: CKD_EPI(CREA,AGE,GENDER)
members:
- TestSiteID: 21
- TestSiteID: 22
testdefgrp:
members:
- TestSiteID: 21
- TestSiteID: 22
GROUP_with_members:
summary: Group/profile test with members and mapping
value:
@ -677,9 +683,10 @@
ConDefID: 1
ClientTestCode: LIPID_C
ClientTestName: Lipid Client
members:
- TestSiteID: 169
- TestSiteID: 170
testdefgrp:
members:
- TestSiteID: 169
- TestSiteID: 170
responses:
'201':
@ -827,17 +834,21 @@
FormulaCode:
type: string
description: Formula expression for calculated tests (e.g., "{TBIL} - {DBIL}")
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
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:

View File

@ -364,11 +364,12 @@ class TestCreateVariantsTest extends CIUnitTestCase
$show->assertStatus(200);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertArrayHasKey('members', $showData);
$this->assertArrayNotHasKey('testdefgrp', $showData);
$this->assertArrayHasKey('testdefgrp', $showData);
$this->assertArrayHasKey('members', $showData['testdefgrp']);
$this->assertArrayNotHasKey('members', $showData);
if ($members !== []) {
$this->assertCount(count($members), $showData['members']);
$this->assertCount(count($members), $showData['testdefgrp']['members']);
}
}
@ -435,9 +436,10 @@ class TestCreateVariantsTest extends CIUnitTestCase
$show->assertStatus(200);
$showData = json_decode($show->getJSON(), true)['data'];
$this->assertArrayHasKey('members', $showData);
$this->assertArrayNotHasKey('testdefgrp', $showData);
$this->assertCount(count($members), $showData['members']);
$this->assertArrayHasKey('testdefgrp', $showData);
$this->assertArrayHasKey('members', $showData['testdefgrp']);
$this->assertArrayNotHasKey('members', $showData);
$this->assertCount(count($members), $showData['testdefgrp']['members']);
}
private function buildTechnicalPayload(string $testType, array $details = []): array
@ -471,7 +473,9 @@ class TestCreateVariantsTest extends CIUnitTestCase
'isVisibleScr' => 1,
'isVisibleRpt' => 1,
'isCountStat' => 0,
'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members),
'testdefgrp' => [
'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members),
],
'details' => [
'DisciplineID' => 2,
'DepartmentID' => 2,
@ -494,7 +498,9 @@ class TestCreateVariantsTest extends CIUnitTestCase
'isVisibleScr' => 1,
'isVisibleRpt' => 1,
'isCountStat' => 1,
'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members),
'testdefgrp' => [
'members' => array_map(fn ($id) => ['TestSiteID' => $id], $members),
],
'testmap' => $testmap,
];
}