420 lines
17 KiB
Markdown
420 lines
17 KiB
Markdown
|
|
# CLQMS Architecture & Codebase Structure
|
||
|
|
|
||
|
|
## High-Level Architecture
|
||
|
|
|
||
|
|
CLQMS follows a **clean architecture pattern** with clear separation of concerns:
|
||
|
|
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ API Consumers │
|
||
|
|
│ (Web Apps, Mobile Apps, Desktop Clients, Instruments) │
|
||
|
|
└────────────────────┬────────────────────────────────────────┘
|
||
|
|
│ HTTP/HTTPS (JSON)
|
||
|
|
┌────────────────────┴────────────────────────────────────────┐
|
||
|
|
│ REST API Layer │
|
||
|
|
│ (Controllers: Patient, Order, Specimen, Result, etc.) │
|
||
|
|
│ - JWT Authentication Filter │
|
||
|
|
│ - Request Validation │
|
||
|
|
│ - Response Formatting │
|
||
|
|
└────────────────────┬────────────────────────────────────────┘
|
||
|
|
│
|
||
|
|
┌────────────────────┴────────────────────────────────────────┐
|
||
|
|
│ Business Logic Layer │
|
||
|
|
│ (Models + Libraries + Services) │
|
||
|
|
│ - ValueSet Library (JSON-based lookups) │
|
||
|
|
│ - Base Model (UTC normalization) │
|
||
|
|
│ - Edge Processing Service │
|
||
|
|
└────────────────────┬────────────────────────────────────────┘
|
||
|
|
│
|
||
|
|
┌────────────────────┴────────────────────────────────────────┐
|
||
|
|
│ Data Access Layer │
|
||
|
|
│ (CodeIgniter Query Builder) │
|
||
|
|
└────────────────────┬────────────────────────────────────────┘
|
||
|
|
│
|
||
|
|
┌────────────────────┴────────────────────────────────────────┐
|
||
|
|
│ MySQL Database │
|
||
|
|
│ (Migration-managed schema) │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
## Directory Structure Overview
|
||
|
|
|
||
|
|
### Root Directory Files
|
||
|
|
```
|
||
|
|
clqms01-be/
|
||
|
|
├── .env # Environment configuration
|
||
|
|
├── .gitignore # Git ignore rules
|
||
|
|
├── AGENTS.md # AI agent instructions (THIS FILE)
|
||
|
|
├── README.md # Project documentation
|
||
|
|
├── PRD.md # Product Requirements Document
|
||
|
|
├── TODO.md # Implementation tasks
|
||
|
|
├── USER_STORIES.md # User stories
|
||
|
|
├── composer.json # PHP dependencies
|
||
|
|
├── composer.lock # Locked dependency versions
|
||
|
|
├── phpunit.xml.dist # PHPUnit configuration
|
||
|
|
├── spark # CodeIgniter CLI tool
|
||
|
|
└── preload.php # PHP preloader
|
||
|
|
```
|
||
|
|
|
||
|
|
### app/ - Application Core
|
||
|
|
```
|
||
|
|
app/
|
||
|
|
├── Controllers/ # API endpoint handlers
|
||
|
|
│ ├── BaseController.php # Base controller class
|
||
|
|
│ ├── AuthController.php # Authentication endpoints
|
||
|
|
│ ├── AuthV2Controller.php # V2 auth endpoints
|
||
|
|
│ ├── DashboardController.php # Dashboard data
|
||
|
|
│ ├── EdgeController.php # Instrument integration
|
||
|
|
│ ├── Patient/ # Patient management
|
||
|
|
│ │ └── PatientController.php
|
||
|
|
│ ├── Organization/ # Organization structure
|
||
|
|
│ │ ├── AccountController.php
|
||
|
|
│ │ ├── SiteController.php
|
||
|
|
│ │ ├── DisciplineController.php
|
||
|
|
│ │ ├── DepartmentController.php
|
||
|
|
│ │ └── WorkstationController.php
|
||
|
|
│ ├── Specimen/ # Specimen management
|
||
|
|
│ │ ├── SpecimenController.php
|
||
|
|
│ │ ├── SpecimenCollectionController.php
|
||
|
|
│ │ ├── SpecimenPrepController.php
|
||
|
|
│ │ ├── SpecimenStatusController.php
|
||
|
|
│ │ └── ContainerDefController.php
|
||
|
|
│ ├── OrderTest/ # Order management
|
||
|
|
│ │ └── OrderTestController.php
|
||
|
|
│ ├── Result/ # Result management
|
||
|
|
│ │ └── ResultController.php
|
||
|
|
│ ├── Test/ # Test definitions
|
||
|
|
│ │ └── TestsController.php
|
||
|
|
│ ├── Contact/ # Contact management
|
||
|
|
│ │ ├── ContactController.php
|
||
|
|
│ │ ├── OccupationController.php
|
||
|
|
│ │ └── MedicalSpecialtyController.php
|
||
|
|
│ ├── ValueSetController.php # ValueSet API endpoints
|
||
|
|
│ ├── ValueSetDefController.php # ValueSet definitions
|
||
|
|
│ ├── LocationController.php # Location management
|
||
|
|
│ ├── CounterController.php # Counter management
|
||
|
|
│ ├── PatVisitController.php # Patient visit management
|
||
|
|
│ └── SampleController.php # Sample management
|
||
|
|
│
|
||
|
|
├── Models/ # Data access layer
|
||
|
|
│ ├── BaseModel.php # Base model with UTC normalization
|
||
|
|
│ ├── Patient/ # Patient models
|
||
|
|
│ │ ├── PatientModel.php
|
||
|
|
│ │ ├── PatAttModel.php # Patient address
|
||
|
|
│ │ ├── PatComModel.php # Patient comments
|
||
|
|
│ │ └── PatIdtModel.php # Patient identifiers
|
||
|
|
│ ├── Organization/ # Organization models
|
||
|
|
│ │ ├── AccountModel.php
|
||
|
|
│ │ ├── SiteModel.php
|
||
|
|
│ │ ├── DisciplineModel.php
|
||
|
|
│ │ ├── DepartmentModel.php
|
||
|
|
│ │ └── WorkstationModel.php
|
||
|
|
│ ├── Specimen/ # Specimen models
|
||
|
|
│ │ ├── SpecimenModel.php
|
||
|
|
│ │ ├── SpecimenCollectionModel.php
|
||
|
|
│ │ ├── SpecimenPrepModel.php
|
||
|
|
│ │ ├── SpecimenStatusModel.php
|
||
|
|
│ │ └── ContainerDefModel.php
|
||
|
|
│ ├── OrderTest/ # Order models
|
||
|
|
│ │ ├── OrderTestModel.php
|
||
|
|
│ │ ├── OrderTestDetModel.php
|
||
|
|
│ │ └── OrderTestMapModel.php
|
||
|
|
│ ├── Result/ # Result models
|
||
|
|
│ │ ├── PatResultModel.php
|
||
|
|
│ │ └── ResultValueSetModel.php
|
||
|
|
│ ├── Test/ # Test models
|
||
|
|
│ │ ├── TestDefSiteModel.php
|
||
|
|
│ │ ├── TestDefTechModel.php
|
||
|
|
│ │ ├── TestDefCalModel.php
|
||
|
|
│ │ ├── TestDefGrpModel.php
|
||
|
|
│ │ └── RefNumModel.php
|
||
|
|
│ ├── Contact/ # Contact models
|
||
|
|
│ │ ├── ContactModel.php
|
||
|
|
│ │ ├── OccupationModel.php
|
||
|
|
│ │ └── MedicalSpecialtyModel.php
|
||
|
|
│ ├── ValueSet/ # ValueSet models (DB-based)
|
||
|
|
│ │ └── ValueSetModel.php
|
||
|
|
│ ├── EdgeResModel.php # Edge results
|
||
|
|
│ ├── CounterModel.php # Counter management
|
||
|
|
│ ├── PatVisitModel.php # Patient visits
|
||
|
|
│ └── ...
|
||
|
|
│
|
||
|
|
├── Libraries/ # Reusable libraries
|
||
|
|
│ ├── ValueSet.php # JSON-based lookup system
|
||
|
|
│ └── Data/ # ValueSet JSON files
|
||
|
|
│ ├── valuesets/
|
||
|
|
│ │ ├── sex.json
|
||
|
|
│ │ ├── marital_status.json
|
||
|
|
│ │ ├── race.json
|
||
|
|
│ │ ├── order_priority.json
|
||
|
|
│ │ ├── order_status.json
|
||
|
|
│ │ ├── specimen_type.json
|
||
|
|
│ │ ├── specimen_status.json
|
||
|
|
│ │ ├── result_status.json
|
||
|
|
│ │ ├── test_type.json
|
||
|
|
│ │ └── ... (many more)
|
||
|
|
│
|
||
|
|
├── Database/ # Database operations
|
||
|
|
│ ├── Migrations/ # Database schema migrations
|
||
|
|
│ │ ├── Format: YYYY-MM-DD-NNNNNN_Description.php
|
||
|
|
│ │ ├── Define up() and down() methods
|
||
|
|
│ │ └── Use $this->forge methods
|
||
|
|
│ └── Seeds/ # Database seeders
|
||
|
|
│
|
||
|
|
├── Config/ # Configuration files
|
||
|
|
│ ├── App.php # App configuration
|
||
|
|
│ ├── Database.php # Database configuration
|
||
|
|
│ ├── Routes.php # API route definitions
|
||
|
|
│ ├── Filters.php # Request filters (auth, etc.)
|
||
|
|
│ └── ...
|
||
|
|
│
|
||
|
|
├── Filters/ # Request/response filters
|
||
|
|
│ └── AuthFilter.php # JWT authentication filter
|
||
|
|
│
|
||
|
|
└── Helpers/ # Helper functions
|
||
|
|
└── utc_helper.php # UTC date conversion helpers
|
||
|
|
```
|
||
|
|
|
||
|
|
### public/ - Public Web Root
|
||
|
|
```
|
||
|
|
public/
|
||
|
|
├── index.php # Front controller (entry point)
|
||
|
|
├── api-docs.yaml # OpenAPI/Swagger documentation (CRITICAL!)
|
||
|
|
├── docs.html # API documentation HTML
|
||
|
|
├── .htaccess # Apache rewrite rules
|
||
|
|
└── robots.txt # SEO robots file
|
||
|
|
```
|
||
|
|
|
||
|
|
### tests/ - Test Suite
|
||
|
|
```
|
||
|
|
tests/
|
||
|
|
├── feature/ # Integration/API tests
|
||
|
|
│ ├── ContactControllerTest.php
|
||
|
|
│ ├── OrganizationControllerTest.php
|
||
|
|
│ ├── TestsControllerTest.php
|
||
|
|
│ ├── UniformShowTest.php # Tests show endpoint format
|
||
|
|
│ └── Patients/
|
||
|
|
│ └── PatientCreateTest.php
|
||
|
|
├── unit/ # Unit tests
|
||
|
|
├── _support/ # Test support utilities
|
||
|
|
└── README.md # Test documentation
|
||
|
|
```
|
||
|
|
|
||
|
|
### vendor/ - Composer Dependencies
|
||
|
|
```
|
||
|
|
vendor/
|
||
|
|
├── codeigniter4/ # CodeIgniter framework
|
||
|
|
├── firebase/ # JWT library
|
||
|
|
├── phpunit/ # PHPUnit testing framework
|
||
|
|
└── ... # Other dependencies
|
||
|
|
```
|
||
|
|
|
||
|
|
### writable/ - Writable Directory
|
||
|
|
```
|
||
|
|
writable/
|
||
|
|
├── cache/ # Application cache
|
||
|
|
├── logs/ # Application logs
|
||
|
|
├── session/ # Session files
|
||
|
|
└── uploads/ # File uploads
|
||
|
|
```
|
||
|
|
|
||
|
|
## API Route Structure
|
||
|
|
|
||
|
|
Routes are defined in `app/Config/Routes.php`:
|
||
|
|
|
||
|
|
### Public Routes (No Authentication)
|
||
|
|
```php
|
||
|
|
/api/v2/auth/login # User login
|
||
|
|
/api/v2/auth/register # User registration
|
||
|
|
/api/demo/order # Create demo order
|
||
|
|
```
|
||
|
|
|
||
|
|
### Authenticated Routes (JWT Required)
|
||
|
|
```php
|
||
|
|
/api/patient # Patient CRUD
|
||
|
|
/api/patvisit # Patient visit CRUD
|
||
|
|
/api/organization/* # Organization management
|
||
|
|
/api/specimen/* # Specimen management
|
||
|
|
/api/ordertest # Order management
|
||
|
|
/api/tests # Test definitions
|
||
|
|
/api/valueset/* # ValueSet management
|
||
|
|
/api/result/* # Result management
|
||
|
|
```
|
||
|
|
|
||
|
|
### Edge API (Instrument Integration)
|
||
|
|
```php
|
||
|
|
POST /api/edge/results # Receive results
|
||
|
|
GET /api/edge/orders # Fetch pending orders
|
||
|
|
POST /api/edge/orders/:id/ack # Acknowledge order
|
||
|
|
POST /api/edge/status # Log instrument status
|
||
|
|
```
|
||
|
|
|
||
|
|
## Core Design Patterns
|
||
|
|
|
||
|
|
### 1. BaseController Pattern
|
||
|
|
All controllers extend `BaseController`:
|
||
|
|
- Provides access to `$this->request`, `$this->response`
|
||
|
|
- Uses `ResponseTrait` for JSON responses
|
||
|
|
- Centralizes common functionality
|
||
|
|
|
||
|
|
### 2. BaseModel Pattern
|
||
|
|
All models extend `BaseModel`:
|
||
|
|
- **UTC Date Normalization**: Automatically converts dates to UTC before insert/update
|
||
|
|
- **ISO 8601 Output**: Automatically converts dates to ISO format on retrieval
|
||
|
|
- **Soft Deletes**: Automatic soft delete support via `DelDate` field
|
||
|
|
- **Hooks**: Uses `beforeInsert`, `beforeUpdate`, `afterFind`, etc.
|
||
|
|
|
||
|
|
### 3. ValueSet Pattern
|
||
|
|
JSON-based static lookup system:
|
||
|
|
- Fast, cached lookups for static values
|
||
|
|
- Easy maintenance via JSON files
|
||
|
|
- Automatic label transformation for API responses
|
||
|
|
- Clear cache after updates
|
||
|
|
|
||
|
|
### 4. Controller-Model-Database Flow
|
||
|
|
```
|
||
|
|
HTTP Request
|
||
|
|
↓
|
||
|
|
Controller (Validation, Auth)
|
||
|
|
↓
|
||
|
|
Model (Business Logic, Data Access)
|
||
|
|
↓
|
||
|
|
Database (MySQL via Query Builder)
|
||
|
|
↓
|
||
|
|
Model (Transform, Add Labels)
|
||
|
|
↓
|
||
|
|
Controller (Format Response)
|
||
|
|
↓
|
||
|
|
JSON Response
|
||
|
|
```
|
||
|
|
|
||
|
|
## Key Integration Points
|
||
|
|
|
||
|
|
### 1. JWT Authentication
|
||
|
|
- Filter: `AuthFilter` in `app/Filters/`
|
||
|
|
- Middleware checks JWT token from Cookie header
|
||
|
|
- Routes grouped with `'filter' => 'auth'`
|
||
|
|
|
||
|
|
### 2. Edge API Integration
|
||
|
|
- Controller: `EdgeController.php`
|
||
|
|
- Models: `EdgeResModel`, `EdgeStatusModel`, `EdgeAckModel`
|
||
|
|
- Staging: `edgeres` table for raw results
|
||
|
|
- Processing: Auto or manual to `patresult` table
|
||
|
|
|
||
|
|
### 3. ValueSet Integration
|
||
|
|
- Library: `ValueSet.php` in `app/Libraries/`
|
||
|
|
- Data: JSON files in `app/Libraries/Data/valuesets/`
|
||
|
|
- Usage: `ValueSet::get('name')`, `ValueSet::transformLabels()`
|
||
|
|
- Cache: Application-level caching
|
||
|
|
|
||
|
|
### 4. UTC Date Handling
|
||
|
|
- Model: `BaseModel.php` handles conversion
|
||
|
|
- Helper: `utc_helper.php` provides conversion functions
|
||
|
|
- Normalization: Local → UTC before DB operations
|
||
|
|
- Output: UTC → ISO 8601 for API responses
|
||
|
|
|
||
|
|
## Database Schema Organization
|
||
|
|
|
||
|
|
### Transactional Tables
|
||
|
|
- `patient` - Patient registry
|
||
|
|
- `porder` - Laboratory orders
|
||
|
|
- `specimen` - Specimens
|
||
|
|
- `patresult` - Patient results
|
||
|
|
- `patresultdetail` - Result details
|
||
|
|
- `patvisit` - Patient visits
|
||
|
|
- `edgeres` - Raw instrument results
|
||
|
|
|
||
|
|
### Master Data Tables
|
||
|
|
- `valueset` - Value set values
|
||
|
|
- `valuesetdef` - Value set definitions
|
||
|
|
- `testdefsite` - Test definitions
|
||
|
|
- `testdeftech` - Technical specs
|
||
|
|
- `testdefcal` - Calculated tests
|
||
|
|
- `testdefgrp` - Test groups
|
||
|
|
- `refnum` - Numeric reference ranges
|
||
|
|
- `reftxt` - Text reference ranges
|
||
|
|
|
||
|
|
### Organization Tables
|
||
|
|
- `account` - Accounts
|
||
|
|
- `site` - Sites
|
||
|
|
- `discipline` - Disciplines
|
||
|
|
- `department` - Departments
|
||
|
|
- `workstation` - Workstations
|
||
|
|
|
||
|
|
### Integration Tables
|
||
|
|
- `edgestatus` - Instrument status
|
||
|
|
- `edgeack` - Order acknowledgment
|
||
|
|
- `testmap` - Instrument test mapping
|
||
|
|
|
||
|
|
## Important Architectural Decisions
|
||
|
|
|
||
|
|
### 1. API-Only Design
|
||
|
|
- No view layer, no HTML rendering
|
||
|
|
- All responses are JSON
|
||
|
|
- Frontend-agnostic for maximum flexibility
|
||
|
|
|
||
|
|
### 2. JWT Authentication
|
||
|
|
- Stateless authentication
|
||
|
|
- Token stored in HTTP-only cookie
|
||
|
|
- 1-hour expiration (configurable)
|
||
|
|
|
||
|
|
### 3. Soft Deletes
|
||
|
|
- All transactional tables use `DelDate`
|
||
|
|
- Data preserved for audit trails
|
||
|
|
- Automatic filtering via BaseModel
|
||
|
|
|
||
|
|
### 4. UTC Timezone
|
||
|
|
- All database dates in UTC
|
||
|
|
- Automatic conversion via BaseModel
|
||
|
|
- ISO 8601 format for API responses
|
||
|
|
|
||
|
|
### 5. JSON-Based ValueSets
|
||
|
|
- Static lookups in JSON files
|
||
|
|
- Fast, cached access
|
||
|
|
- Easy to maintain and version control
|
||
|
|
|
||
|
|
### 6. Migration-Based Schema
|
||
|
|
- Database changes via migrations
|
||
|
|
- Version-controlled schema history
|
||
|
|
- Easy rollback capability
|
||
|
|
|
||
|
|
## Critical Files to Know
|
||
|
|
|
||
|
|
| File | Purpose | Importance |
|
||
|
|
|------|---------|------------|
|
||
|
|
| `AGENTS.md` | AI agent instructions | **Critical** - Always read first |
|
||
|
|
| `app/Config/Routes.php` | API route definitions | **Critical** - Defines all endpoints |
|
||
|
|
| `public/api-docs.yaml` | OpenAPI documentation | **Critical** - MUST update after changes |
|
||
|
|
| `app/Libraries/ValueSet.php` | Lookup system | High - Used throughout |
|
||
|
|
| `app/Models/BaseModel.php` | Base model with UTC | High - All models extend this |
|
||
|
|
| `app/Filters/AuthFilter.php` | JWT authentication | High - Secures endpoints |
|
||
|
|
| `phpunit.xml.dist` | Test configuration | Medium - Configure database for tests |
|
||
|
|
| `.env` | Environment config | High - Contains secrets (JWT_SECRET, DB creds) |
|
||
|
|
|
||
|
|
## Common Patterns for Code Navigation
|
||
|
|
|
||
|
|
### Finding Controller for an Endpoint
|
||
|
|
1. Check `app/Config/Routes.php` for route
|
||
|
|
2. Find controller class in `app/Controllers/`
|
||
|
|
3. View controller method implementation
|
||
|
|
|
||
|
|
### Finding Model for a Table
|
||
|
|
1. Table name: `patient` → Model: `PatientModel.php`
|
||
|
|
2. Look in `app/Models/` or subdirectories
|
||
|
|
3. Check `$table`, `$primaryKey`, `$allowedFields`
|
||
|
|
|
||
|
|
### Understanding a Feature
|
||
|
|
1. Start with controller method
|
||
|
|
2. Follow to model methods
|
||
|
|
3. Check related models via joins
|
||
|
|
4. Refer to migrations for table structure
|
||
|
|
5. Check API documentation in `public/api-docs.yaml`
|
||
|
|
|
||
|
|
### Adding a New Endpoint
|
||
|
|
1. Create controller method
|
||
|
|
2. Create/update model if needed
|
||
|
|
3. Add route in `app/Config/Routes.php`
|
||
|
|
4. Write tests in `tests/feature/`
|
||
|
|
5. Update `public/api-docs.yaml`
|
||
|
|
6. Run tests to verify
|