- 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
201 lines
6.3 KiB
Markdown
201 lines
6.3 KiB
Markdown
# 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)
|