Complete overhaul of the valueset system to use human-readable names
instead of numeric IDs for improved maintainability and API consistency.
- PatientController: Renamed 'Gender' field to 'Sex' in validation rules
- ValuesetController: Changed API endpoints from ID-based (/:num) to name-based (/:any)
- TestsController: Refactored to use ValueSet library instead of direct valueset queries
- Added ValueSet library (app/Libraries/ValueSet.php) with static lookup methods:
- getOptions() - returns dropdown format [{value, label}]
- getLabel(, ) - returns label for a value
- transformLabels(, ) - batch transform records
- get() and getRaw() for Lookups compatibility
- Added ValueSetApiController for public valueset API endpoints
- Added ValueSet refresh endpoint (POST /api/valueset/refresh)
- Added DemoOrderController for testing order creation without auth
- 2026-01-12-000001: Convert valueset references from VID to VValue
- 2026-01-12-000002: Rename patient.Gender column to Sex
- OrderTestController: Now uses OrderTestModel with proper model pattern
- TestsController: Uses ValueSet library for all lookup operations
- ValueSetController: Simplified to use name-based lookups
- Updated all organization (account/site/workstation) dialogs and index views
- Updated specimen container dialogs and index views
- Updated tests_index.php with ValueSet integration
- Updated patient dialog form and index views
- Removed .factory/config.json and CLAUDE.md (replaced by AGENTS.md)
- Consolidated lookups in Lookups.php (removed inline valueset constants)
- Updated all test files to match new field names
- 32 modified files, 17 new files, 2 deleted files
- Net: +661 insertions, -1443 deletions (significant cleanup)
CLQMS (Clinical Laboratory Quality Management System)
The core backend engine for modern clinical laboratory workflows.
CLQMS is a robust, mission-critical API suite designed to streamline laboratory operations, ensure data integrity, and manage complex diagnostic workflows. Built on a foundation of precision and regulatory compliance, this system handles everything from patient registration to high-throughput test resulting.
🏛️ Core Architecture & Design
The system is currently undergoing a strategic Architectural Redesign to consolidate legacy structures into a high-performance, maintainable schema. This design, spearheaded by leadership, focuses on reducing technical debt and improving data consistency across:
- Unified Test Definitions: Consolidating technical, calculated, and site-specific test data.
- Reference Range Centralization: A unified engine for numeric, threshold, text, and coded results.
- Ordered Workflow Management: Precise tracking of orders from collection to verification.
🛡️ Strategic Pillars
- Precision & Accuracy: Strict validation for all laboratory parameters and reference ranges.
- Scalability: Optimized for high-volume diagnostic environments.
- Compliance: Built-in audit trails and status history for full traceability.
- Interoperability: Modular architecture designed for LIS, HIS, and analyzer integrations.
🛠️ Technical Stack
| Component | Specification |
|---|---|
| Language | PHP 8.1+ (PSR-compliant) |
| Framework | CodeIgniter 4 |
| Security | JWT (JSON Web Tokens) Authorization |
| Database | MySQL (Optimized Schema Migration in progress) |
📂 Documentation & Specifications
For detailed architectural blueprints and API specifications, please refer to the internal documentation:
👉 Internal Documentation Index
Key documents:
- Database Schema Redesign Proposal
- API Contract: Patient Registration
- Database Design Review (Reference)
🔧 Valueset Reference (VSetDefID)
When working on UI components or dropdowns, always check for existing ValueSets before hardcoding options. Use the API endpoint /api/valueset/valuesetdef/{ID} to fetch options dynamically.
| VSetDefID | Purpose | Usage |
|---|---|---|
| 27 | Test Types | TEST, PARAM, GROUP, CALC, TITLE |
| 28 | Methods | Lab test methods |
| 29 | Specimen Types | Blood, Urine, etc. |
| 30 | Ref Types | NMRC (Numeric), TEXT, LIST |
| 31 | Range Types | STD (Standard), AGSX (Age/Sex), COND |
Important: Always use ValueSet lookups for configurable options. This ensures consistency and allows administrators to modify options without code changes.
📚 Static Lookups Library (app/Libraries/Lookups.php)
For frequently used lookup values, CLQMS provides a static library with all values hardcoded. This eliminates database queries for common dropdowns and improves performance.
Available Lookups
| Constant | VSetID | Description |
|---|---|---|
WS_TYPE |
1 | Workstation type (Primary, Secondary) |
ENABLE_DISABLE |
2 | Enable/disable flags |
GENDER |
3 | Gender (Female, Male, Unknown) |
MARITAL_STATUS |
4 | Marital status (A/D/M/S/W/B/U/O) |
DEATH_INDICATOR |
5 | Death indicator (Y/N) |
IDENTIFIER_TYPE |
6 | ID types (KTP, Passport, SSN, SIM) |
OPERATION |
7 | CRUD operations (Create, Read, Update, Delete) |
ORDER_PRIORITY |
10 | Order priority (S=Stat, A=ASAP, R=Routine, P=Preop, etc.) |
ORDER_STATUS |
11 | Order status (A/CA/CM/DC/ER/HD/IP/RP/SC/CL/AC/DL) |
SPECIMEN_TYPE |
15 | Specimen types (BLD, SER, PLAS, UR, CSF, etc.) |
SPECIMEN_STATUS |
20 | Specimen status (STC, SCtd, SArrv, SRcvd, SAna, etc.) |
SPECIMEN_CONDITION |
21 | Specimen condition (HEM, ITC, LIP, etc.) |
TEST_TYPE |
27 | Test types (TEST, PARAM, CALC, GROUP, TITLE) |
RESULT_UNIT |
28 | Result units (g/dL, mg/dL, x10^6/mL, etc.) |
RACE |
30 | Ethnicity/race (Jawa, Sunda, Batak, etc.) |
RELIGION |
31 | Religion (Islam, Kristen, Katolik, Hindu, Budha, etc.) |
SITE_TYPE |
37 | Site type (GH, PH, GHL, PHL, GL, PL) |
SITE_CLASS |
38 | Site class (A/B/C/D/Utm/Ptm) |
RESULT_TYPE |
43 | Result type (NMRIC, RANGE, TEXT, VSET) |
RANGE_TYPE |
45 | Range type (REF, CRTC, VAL, RERUN) |
HIV_RESULT |
1001 | HIV results (NEG, POS, GZ) |
Plus 25+ more categories - see app/Libraries/Lookups.php for complete list.
Usage
use App\Libraries\Lookups;
// Get all lookups formatted for frontend
$allLookups = Lookups::getAll();
// Get single lookup (returns [{value: 'X', label: 'Y'}, ...])
$gender = Lookups::get('GENDER');
// Get raw associative array
$priorities = Lookups::getRaw('ORDER_PRIORITY');
// Returns: ['S' => 'Stat', 'A' => 'ASAP', 'R' => 'Routine', ...]
// Get label by key
$label = Lookups::getLabel('GENDER', '1'); // Returns 'Female'
Frontend Usage (Alpine.js)
// In your PHP view file
<script>
const LOOKUPS = <?= json_encode(\App\Libraries\Lookups::getAll()) ?>;
console.log(LOOKUPS.gender);
// Output: [{"value":"1","label":"Female"},{"value":"2","label":"Male"},{"value":"3","label":"Unknown"}]
</script>
When to Use
| Approach | Use Case |
|---|---|
| Static Lookups | Frequently used values that rarely change (gender, status, types) |
API /api/valueset* |
Dynamic values that may be modified by admins at runtime |
📋 Master Data Management
CLQMS provides comprehensive master data management for laboratory operations. All master data is accessible via the V2 UI at /v2/master/* endpoints.
🧪 Laboratory Tests (/v2/master/tests)
The Test Definitions module manages all laboratory test configurations including parameters, calculated tests, and test panels.
Test Types
| Type Code | Description | Table |
|---|---|---|
TEST |
Individual laboratory test with technical specs | testdefsite + testdeftech |
PARAM |
Parameter value (non-lab measurement) | testdefsite + testdeftech |
CALC |
Calculated test with formula | testdefsite + testdefcal |
GROUP |
Panel/profile containing multiple tests | testdefsite + testdefgrp |
TITLE |
Section title for report organization | testdefsite |
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/tests |
List all tests with optional filtering |
GET |
/api/tests/{id} |
Get test details with type-specific data |
POST |
/api/tests |
Create new test definition |
PATCH |
/api/tests |
Update existing test |
DELETE |
/api/tests |
Soft delete test (sets EndDate) |
Filtering Parameters
TestSiteName- Search by test name (partial match)TestType- Filter by test type VID (1-5)VisibleScr- Filter by screen visibility (0/1)VisibleRpt- Filter by report visibility (0/1)
Test Response Structure
{
"status": "success",
"message": "Data fetched successfully",
"data": [
{
"TestSiteID": 1,
"TestSiteCode": "CBC",
"TestSiteName": "Complete Blood Count",
"TestType": 4,
"TypeCode": "GROUP",
"TypeName": "Group Test",
"SeqScr": 50,
"VisibleScr": 1,
"VisibleRpt": 1
}
]
}
📏 Reference Ranges (/v2/master/refrange)
Reference Ranges define normal and critical values for test results. The system supports multiple reference range types based on patient demographics.
Reference Range Types
| Type | Table | Description |
|---|---|---|
| Numeric | refnum |
Numeric ranges with age/sex criteria |
| Threshold | refthold |
Critical threshold values |
| Text | reftxt |
Text-based reference values |
| Value Set | refvset |
Coded reference values |
Numeric Reference Range Structure
| Field | Description |
|---|---|
NumRefType |
Type: REF (Reference), CRTC (Critical), VAL (Validation), RERUN |
RangeType |
RANGE or THOLD |
Sex |
Gender filter (0=All, 1=Female, 2=Male) |
AgeStart |
Minimum age (years) |
AgeEnd |
Maximum age (years) |
LowSign |
Low boundary sign (=, <, <=) |
Low |
Low boundary value |
HighSign |
High boundary sign (=, >, >=) |
High |
High boundary value |
Flag |
Result flag (H, L, A, etc.) |
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/refnum |
List numeric reference ranges |
GET |
/api/refnum/{id} |
Get reference range details |
POST |
/api/refnum |
Create reference range |
PATCH |
/api/refnum |
Update reference range |
DELETE |
/api/refnum |
Soft delete reference range |
📑 Value Sets (/v2/master/valuesets)
Value Sets are configurable dropdown options used throughout the system. Each Value Set Definition (VSetDef) contains multiple Value Set Values (ValueSet).
Value Set Hierarchy
valuesetdef (VSetDefID, VSName, VSDesc)
└── valueset (VID, VSetID, VValue, VDesc, VOrder, VCategory)
Common Value Sets
| VSetDefID | Name | Example Values |
|---|---|---|
| 1 | Priority | STAT (S), ASAP (A), Routine (R), Preop (P) |
| 2 | Enable/Disable | Disabled (0), Enabled (1) |
| 3 | Gender | Female (1), Male (2), Unknown (3) |
| 10 | Order Status | STC, SCtd, SArrv, SRcvd, SAna, etc. |
| 15 | Specimen Type | BLD, SER, PLAS, UR, CSF, etc. |
| 16 | Unit | L, mL, g/dL, mg/dL, etc. |
| 27 | Test Type | TEST, PARAM, CALC, GROUP, TITLE |
| 28 | Result Unit | g/dL, g/L, mg/dL, x10^6/mL, etc. |
| 35 | Test Activity | Order, Analyse, VER, REV, REP |
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/valuesetdef |
List all value set definitions |
GET |
/api/valuesetdef/{id} |
Get valueset with all values |
GET |
/api/valuesetdef/{id}/values |
Get values for specific valueset |
POST |
/api/valuesetdef |
Create new valueset definition |
PATCH |
/api/valuesetdef |
Update valueset definition |
DELETE |
/api/valuesetdef |
Delete valueset definition |
Value Set Response Structure
{
"status": "success",
"data": {
"VSetDefID": 27,
"VSName": "Test Type",
"VSDesc": "testdefsite.TestType",
"values": [
{ "VID": 1, "VValue": "TEST", "VDesc": "Test", "VOrder": 1 },
{ "VID": 2, "VValue": "PARAM", "VDesc": "Parameter", "VOrder": 2 },
{ "VID": 3, "VValue": "CALC", "VDesc": "Calculated Test", "VOrder": 3 },
{ "VID": 4, "VValue": "GROUP", "VDesc": "Group Test", "VOrder": 4 },
{ "VID": 5, "VValue": "TITLE", "VDesc": "Title", "VOrder": 5 }
]
}
}
📊 Database Tables Summary
| Category | Tables | Purpose |
|---|---|---|
| Tests | testdefsite, testdeftech, testdefcal, testdefgrp, testmap |
Test definitions |
| Reference Ranges | refnum, refthold, reftxt, refvset |
Result validation |
| Value Sets | valuesetdef, valueset |
Configurable options |
🔌 Edge API - Instrument Integration
The Edge API provides endpoints for integrating laboratory instruments via the tiny-edge middleware. Results from instruments are staged in the edgeres table before processing into the main patient results (patres).
Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/edge/results |
Receive instrument results (stored in edgeres) |
GET |
/api/edge/orders |
Fetch pending orders for an instrument |
POST |
/api/edge/orders/:id/ack |
Acknowledge order delivery to instrument |
POST |
/api/edge/status |
Log instrument status updates |
Workflow
Instrument → tiny-edge → POST /api/edge/results → edgeres table → [Manual/Auto Processing] → patres table
Key Features:
- Staging Table: All results land in
edgeresfirst for validation - Rerun Handling: Duplicate
SampleID+TestSiteCodeincrementsAspCntinpatres - Configurable Processing: Auto or manual processing based on settings
- Status Tracking: Full audit trail via
edgestatusandedgeacktables
📜 Usage Notice
This repository contains proprietary information intended for the 5Panda Team and authorized collaborators.
© 2025 5Panda Team. Engineering Precision in Clinical Diagnostics.