clqms-be/CLAUDE.md
mahdahar e5ac1957fe ● refactor: update API responses to use {field}Label format
- Transform coded fields to lowercase with Label suffix for display text                                                                                                                                              - Controllers: OrderTestController, DemoOrderController, SpecimenController,
    SpecimenStatusController, SpecimenCollectionController, ContainerDefController,
    ContactController, TestMapController
  - Example: Priority: "R" → priority: "R", priorityLabel: "Routine"
  - Update api-docs.yaml with new OpenAPI schema definitions
  - Add API docs reminder to CLAUDE.md
2026-01-28 17:31:00 +07:00

6.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.


Tool Preference: Use Serena MCP

Always prioritize Serena MCP tools for code operations to minimize tool calls:

  • Use find_symbol / get_symbols_overview instead of Read for exploring code structure
  • Use replace_symbol_body instead of Edit for modifying functions, methods, classes
  • Use insert_before_symbol / insert_after_symbol for adding new code symbols
  • Use search_for_pattern instead of Grep for searching code patterns
  • Use list_dir / find_file instead of Glob for file discovery

This leverages semantic code understanding for this PHP codebase.


Common Commands

Testing

# Run all tests
vendor/bin/phpunit

# Run specific test file
vendor/bin/phpunit tests/feature/UniformShowTest.php

# Run tests in a directory
vendor/bin/phpunit app/Models

# Generate code coverage report
vendor/bin/phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m

Database

# Run migrations
spark migrate

# Rollback migrations
spark migrate:rollback

# Seed database
spark db:seed DBSeeder

# Refresh all migrations and seed
spark migrate:refresh --seed

CodeIgniter CLI

# General help
spark help

# Generate code (scaffolding)
spark make:model ModelName
spark make:controller ControllerName
spark make:migration MigrationName

API Documentation

# Keep api-docs.yaml updated whenever controllers change
# File: public/api-docs.yaml
# After modifying controllers, update the OpenAPI schema definitions
# to reflect new field names, types, and response formats

Architecture Overview

Core Pattern: MVC + Libraries

CLQMS follows CodeIgniter 4 conventions with these key architectural patterns:

Controllers (app/Controllers/)

  • Organized by domain: Patient/, Organization/, Specimen/, Test/, Contact/
  • Root-level controllers for cross-domain concerns: AuthController, EdgeController, ValueSetController
  • All controllers extend BaseController which provides request/response helpers

Models (app/Models/)

  • Organized by domain matching controllers: Patient/, Organization/, Specimen/, Test/, etc.
  • All models extend BaseModel which provides automatic UTC date normalization
  • Model callbacks: beforeInsert/Update normalize dates to UTC, afterFind/Insert/Update convert to UTC ISO format

Libraries (app/Libraries/)

  • ValueSet - Static lookup system using JSON files (see "Lookup System" below)

Lookup System: ValueSet Library

The system uses a JSON file-based lookup system instead of database queries for static values.

Location: app/Libraries/Data/*.json (44+ JSON files)

Key Files:

  • _meta.json - Metadata about lookup definitions
  • sex.json, order_status.json, specimen_type.json, test_type.json, etc.

Usage:

use App\Libraries\ValueSet;

// Get dropdown-formatted options
$options = ValueSet::get('sex'); // [["value"=>"1","label"=>"Female"],...]

// Get raw data
$raw = ValueSet::getRaw('sex'); // [["key"=>"1","value"=>"Female"],...]

// Get label for a specific key
$label = ValueSet::getLabel('sex', '1'); // "Female"

// Transform database records with lookup text labels
$data = ValueSet::transformLabels($patients, ['Sex' => 'sex']);

// Clear cache after modifying JSON files
ValueSet::clearCache();

When to use ValueSet vs API:

  • ValueSet library - Static values that rarely change (fast, cached)
  • API /api/valueset* - Dynamic values managed by admins at runtime

Database Migrations Structure

Migrations are numbered sequentially starting with 2026-01-01-:

Migration Tables Created
000001 valueset, counter, containerdef, occupation, specialty
000002 account, site, location, discipline, department
000003 patient, patidentifier, pataddress, patcontact
000004 contact, contactdetail, userdevices, loginattempts
000005 patvisit, patinsurance
000006 porder, orderitem
000007 specimen, specmenactivity, containerdef
000008 testdefinition, testactivity, refnum, reftxt
000009 patresult, patresultdetail, patresultcomment
000010 edgeres, edgestatus, edgeack, workstation

Authentication & Authorization

  • JWT-based authentication using firebase/php-jwt
  • AuthFilter - Route filter protecting API endpoints
  • AuthController - Login/logout endpoints (POST /api/login, POST /api/logout)
  • AuthV2Controller - V2 authentication endpoints

Edge API (Instrument Integration)

The EdgeController provides endpoints for laboratory instrument integration via tiny-edge middleware:

  • POST /api/edge/results - Receive instrument results (stored in edgeres table)
  • GET /api/edge/orders - Fetch pending orders for instruments
  • POST /api/edge/orders/:id/ack - Acknowledge order delivery
  • POST /api/edge/status - Log instrument status updates

Workflow: Instrument → tiny-edge → edgeres table → [Processing] → patresult table

Test Types System

Tests in testdefinition table support multiple types via TestType field:

Code Type Description
TEST Technical Individual lab test with specs
PARAM Parameter Non-lab measurement
CALC Calculated Test with formula
GROUP Panel/Profile Contains multiple tests
TITLE Section Report organization header

Reference Range Architecture

Reference ranges support multiple types for result validation:

Type Table Purpose
Numeric refnum Ranges with age/sex criteria
Threshold refthold Critical values
Text reftxt Text-based references
Value Set refvset Coded references

Routes Organization

Routes are defined in app/Config/Routes.php:

  • API routes: /api/{resource}
  • Auth-protected routes use AuthFilter

Project Structure Notes

  • Language: PHP 8.1+ (PSR-compliant)
  • Framework: CodeIgniter 4
  • Database: MySQL with migration-based schema management
  • Testing: PHPUnit 10.5+ (tests in tests/ directory)
  • Entry point: public/index.php (web), spark (CLI)
  • Environment config: .env file (copy from env template)