clqms-be/CLAUDE.md

201 lines
6.3 KiB
Markdown
Raw Normal View History

# 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
```bash
# 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
```bash
# 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
```bash
# General help
spark help
# Generate code (scaffolding)
spark make:model ModelName
spark make:controller ControllerName
spark make:migration MigrationName
```
### API Documentation
```bash
# 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:**
```php
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)