clqms-be/CLAUDE.md

3.9 KiB

CLAUDE.md

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

Project Overview

CLQMS is a Clinical Laboratory Quality Management System built with CodeIgniter 4 (PHP 8.1+) providing a REST API backend for laboratory operations from patient registration through test resulting. The frontend uses Alpine.js views in app/Views/v2/.

Development Commands

# Install dependencies
composer install

# Run all tests
composer test
php vendor/bin/phpunit

# Run single test file
php vendor/bin/phpunit tests/feature/Patients/PatientIndexTest.php

# Run single test method
php vendor/bin/phpunit tests/feature/Patients/PatientIndexTest.php --filter=testIndexWithoutParams

# Run tests with coverage
php vendor/bin/phpunit --coverage-html build/logs/html

# Run CLI commands
php spark help
php spark db:seed DBSeeder

Architecture

Directory Structure

  • app/Controllers/{Domain}/ - API controllers organized by domain (Patient, Organization, Specimen, Result, Test)
  • app/Models/{Domain}/ - Domain models
  • app/Libraries/Data/*.json - Static lookup data (gender, order_priority, specimen_type, etc.)
  • app/Views/v2/ - Alpine.js frontend views
  • app/Database/Migrations/ - 10 consolidated migrations (2026-01-01-*)
  • tests/feature/ - API endpoint tests using FeatureTestTrait

Key Patterns

Controller Pattern:

class PatientController extends Controller {
    use ResponseTrait;
    protected $db;
    protected $model;

    public function __construct() {
        $this->db = \Config\Database::connect();
        $this->model = new PatientModel();
    }

    public function index() {
        try {
            $data = $this->model->findAll();
            return $this->respond(['status' => 'success', 'data' => $data], 200);
        } catch (\Exception $e) {
            return $this->failServerError($e->getMessage());
        }
    }
}

Model Pattern: Models extend BaseModel which auto-normalizes dates to/from UTC via beforeInsert/beforeUpdate callbacks. Use allowedFields for mass assignment and useSoftDeletes = true with deletedField = 'DelDate' for soft deletes.

API Response Format:

// Success
{"status": "success", "message": "...", "data": [...]}
// Error
{"status": "failed", "message": "..."}

Lookups Library

Use App\Libraries\Lookups for static dropdown values (loaded from JSON files, cached):

use App\Libraries\Lookups;

// Get dropdown-formatted data [{value: '1', label: 'Female'}, ...]
$gender = Lookups::get('gender');

// Get label by key
$label = Lookups::getLabel('gender', '1'); // 'Female'

// Clear cache after modifying lookup data
Lookups::clearCache();

For dynamic values managed at runtime, use the /api/valueset* endpoints instead.

JWT Authentication

Most API endpoints require JWT auth via AuthFilter. Public endpoints include /v2/login, /api/demo/*, /api/auth/*.

Database Conventions

Element Convention
Tables snake_case (patient, patvisit)
Columns PascalCase (InternalPID, PatientID)
Classes PascalCase (PatientController, BaseModel)
Methods/Variables camelCase (getPatient(), $internalPID)

Soft deletes use DelDate field - never hard delete records.

Key Routes

Method Endpoint Description
POST /api/auth/login JWT authentication
GET/POST /api/patient Patient CRUD
GET/POST /api/patvisit Patient visits
POST /api/ordertest Create orders
POST /api/edge/results Instrument integration (tiny-edge middleware)

Important Notes

  • All dates normalized to UTC automatically via BaseModel
  • No comments in code unless explicitly requested
  • Use transactions for multi-table operations
  • Validate input before DB operations using CodeIgniter validation rules