# 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