clqms-be/.serena/memories/architecture_structure.md
mahdahar 282c642da6 feat: add OpenSpec workflow, Serena integration, User API, and Specimen delete endpoint
- Add OpenSpec experimental workflow with commands (opsx-apply, opsx-archive, opsx-explore, opsx-propose)
- Add Serena memory system for project context
- Implement User API (UserController, UserModel, routes)
- Add Specimen delete endpoint
- Update Test definitions and Routes
- Sync API documentation (OpenAPI)
- Archive completed 2026-03-08-backend-specs change
2026-03-09 07:00:12 +07:00

17 KiB

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)

/api/v2/auth/login       # User login
/api/v2/auth/register    # User registration
/api/demo/order          # Create demo order

Authenticated Routes (JWT Required)

/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)

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