clqms-be/app/Config/Routes.php

295 lines
13 KiB
PHP
Raw Normal View History

2025-06-26 14:09:25 +07:00
<?php
use CodeIgniter\Router\RouteCollection;
/**
* @var RouteCollection $routes
*/
$routes->get('/', function () {
feat(api): transition to headless architecture and enhance order management This commit marks a significant architectural shift, transitioning the CLQMS backend to a fully headless REST API. All view-related components have been removed to focus solely on providing a robust, stateless API for clinical laboratory workflows. ### Architectural Changes - **Headless API Transition:** - Removed all view files (`app/Views/v2`), associated page controllers (`PagesController`), and routes (`Routes.php`). The application no longer serves a front-end UI. - The root endpoint (`/`) now returns a simple "Backend Running" status message. - **Developer Tooling & Guidance:** - Replaced `CLAUDE.md` with `GEMINI.md` to provide updated context and instructional guidelines for Gemini agents. - Updated `.serena/project.yml` with project configuration. ### Feature Enhancements - **Advanced Order Management (`OrderTestModel`):** - **Test Expansion:** The `createOrder` process now automatically expands `GROUP` (panel) tests into their individual components and recursively includes all parameter dependencies for `CALC` (calculated) tests. - **Order Comments:** Added support for attaching comments to an order via the `ordercom` table. - **Status Tracking:** Order status updates are now correctly recorded in the `orderstatus` table. - **Schema Alignment:** Switched from `OrderID` to `InternalOID` as the primary key for internal operations. - **Reference Range Refactor (`TestsController`):** - Simplified reference range logic by consolidating `refthold` and `refvset` into the main `refnum` and `reftxt` tables. - Standardized `RefType` handling to support `NMRC`, `TEXT`, `THOLD`, and `VSET` codes from the `reference_type` ValueSet. ### Other Changes - **Documentation:** - `PRD.md`, `README.md`, and `TODO.md` were updated to reflect the headless architecture, refined scope, and current project priorities. - **Database:** - Removed obsolete `RefTHoldID` and `RefVSetID` columns from the `patres` table migration. - **Testing:** - Added new feature tests for `ContactController`, `OrganizationController`, and `TestsController`.
2026-01-31 09:27:32 +07:00
return "Backend Running";
});
$routes->options('(:any)', function () {
return '';
});
$routes->group('api', ['filter' => 'auth'], function ($routes) {
$routes->get('dashboard', 'DashboardController::index');
$routes->get('result', 'ResultController::index');
$routes->get('sample', 'SampleController::index');
2025-09-04 09:42:30 +07:00
});
feat(api): transition to headless architecture and enhance order management This commit marks a significant architectural shift, transitioning the CLQMS backend to a fully headless REST API. All view-related components have been removed to focus solely on providing a robust, stateless API for clinical laboratory workflows. ### Architectural Changes - **Headless API Transition:** - Removed all view files (`app/Views/v2`), associated page controllers (`PagesController`), and routes (`Routes.php`). The application no longer serves a front-end UI. - The root endpoint (`/`) now returns a simple "Backend Running" status message. - **Developer Tooling & Guidance:** - Replaced `CLAUDE.md` with `GEMINI.md` to provide updated context and instructional guidelines for Gemini agents. - Updated `.serena/project.yml` with project configuration. ### Feature Enhancements - **Advanced Order Management (`OrderTestModel`):** - **Test Expansion:** The `createOrder` process now automatically expands `GROUP` (panel) tests into their individual components and recursively includes all parameter dependencies for `CALC` (calculated) tests. - **Order Comments:** Added support for attaching comments to an order via the `ordercom` table. - **Status Tracking:** Order status updates are now correctly recorded in the `orderstatus` table. - **Schema Alignment:** Switched from `OrderID` to `InternalOID` as the primary key for internal operations. - **Reference Range Refactor (`TestsController`):** - Simplified reference range logic by consolidating `refthold` and `refvset` into the main `refnum` and `reftxt` tables. - Standardized `RefType` handling to support `NMRC`, `TEXT`, `THOLD`, and `VSET` codes from the `reference_type` ValueSet. ### Other Changes - **Documentation:** - `PRD.md`, `README.md`, and `TODO.md` were updated to reflect the headless architecture, refined scope, and current project priorities. - **Database:** - Removed obsolete `RefTHoldID` and `RefVSetID` columns from the `patres` table migration. - **Testing:** - Added new feature tests for `ContactController`, `OrganizationController`, and `TestsController`.
2026-01-31 09:27:32 +07:00
// V2 Auth API Routes (public - no auth required)
$routes->group('v2/auth', function ($routes) {
$routes->post('login', 'AuthV2Controller::login');
$routes->post('register', 'AuthV2Controller::register');
$routes->get('check', 'AuthV2Controller::checkAuth');
$routes->post('logout', 'AuthV2Controller::logout');
});
2025-11-10 16:02:52 +07:00
// Faker
$routes->get('faker/faker-patient/(:num)', 'faker\FakerPatient::sendMany/$1');
$routes->group('api', function ($routes) {
// Auth
$routes->group('auth', function ($routes) {
$routes->post('login', 'AuthController::login');
$routes->post('change_pass', 'AuthController::change_pass');
$routes->post('register', 'AuthController::register');
$routes->get('check', 'AuthController::checkAuth');
$routes->post('logout', 'AuthController::logout');
});
// Patient
$routes->group('patient', function ($routes) {
$routes->get('/', 'Patient\PatientController::index');
$routes->post('/', 'Patient\PatientController::create');
$routes->get('(:num)', 'Patient\PatientController::show/$1');
$routes->delete('/', 'Patient\PatientController::delete');
$routes->patch('/', 'Patient\PatientController::update');
$routes->get('check', 'Patient\PatientController::patientCheck');
});
// PatVisit
$routes->group('patvisit', function ($routes) {
$routes->get('/', 'PatVisitController::index');
$routes->post('/', 'PatVisitController::create');
$routes->get('patient/(:num)', 'PatVisitController::showByPatient/$1');
$routes->get('(:any)', 'PatVisitController::show/$1');
$routes->delete('/', 'PatVisitController::delete');
$routes->patch('/', 'PatVisitController::update');
});
$routes->group('patvisitadt', function ($routes) {
$routes->get('visit/(:num)', 'PatVisitController::getADTByVisit/$1');
$routes->get('(:num)', 'PatVisitController::showADT/$1');
$routes->post('/', 'PatVisitController::createADT');
$routes->patch('/', 'PatVisitController::updateADT');
$routes->delete('/', 'PatVisitController::deleteADT');
});
// Master Data
// Location
$routes->group('location', function ($routes) {
$routes->get('/', 'LocationController::index');
$routes->get('(:num)', 'LocationController::show/$1');
$routes->post('/', 'LocationController::create');
$routes->patch('/', 'LocationController::update');
$routes->delete('/', 'LocationController::delete');
});
// Contact
$routes->group('contact', function ($routes) {
$routes->get('/', 'Contact\ContactController::index');
$routes->get('(:num)', 'Contact\ContactController::show/$1');
$routes->post('/', 'Contact\ContactController::create');
$routes->patch('/', 'Contact\ContactController::update');
$routes->delete('/', 'Contact\ContactController::delete');
});
$routes->group('occupation', function ($routes) {
$routes->get('/', 'Contact\OccupationController::index');
$routes->get('(:num)', 'Contact\OccupationController::show/$1');
$routes->post('/', 'Contact\OccupationController::create');
$routes->patch('/', 'Contact\OccupationController::update');
//$routes->delete('/', 'Contact\OccupationController::delete');
});
$routes->group('medicalspecialty', function ($routes) {
$routes->get('/', 'Contact\MedicalSpecialtyController::index');
$routes->get('(:num)', 'Contact\MedicalSpecialtyController::show/$1');
$routes->post('/', 'Contact\MedicalSpecialtyController::create');
$routes->patch('/', 'Contact\MedicalSpecialtyController::update');
});
// Lib ValueSet (file-based)
$routes->group('valueset', function ($routes) {
$routes->get('/', 'ValueSetController::index');
$routes->get('(:any)', 'ValueSetController::index/$1');
$routes->post('refresh', 'ValueSetController::refresh');
// User ValueSet (database-based)
$routes->group('user', function ($routes) {
$routes->group('items', function ($routes) {
$routes->get('/', 'ValueSetController::items');
$routes->get('(:num)', 'ValueSetController::showItem/$1');
$routes->post('/', 'ValueSetController::createItem');
$routes->put('(:num)', 'ValueSetController::updateItem/$1');
$routes->delete('(:num)', 'ValueSetController::deleteItem/$1');
});
$routes->group('def', function ($routes) {
$routes->get('/', 'ValueSetDefController::index');
$routes->get('(:num)', 'ValueSetDefController::show/$1');
$routes->post('/', 'ValueSetDefController::create');
$routes->put('(:num)', 'ValueSetDefController::update/$1');
$routes->delete('(:num)', 'ValueSetDefController::delete/$1');
});
});
feat(valueset): refactor from ID-based to name-based lookups Complete overhaul of the valueset system to use human-readable names instead of numeric IDs for improved maintainability and API consistency. - PatientController: Renamed 'Gender' field to 'Sex' in validation rules - ValuesetController: Changed API endpoints from ID-based (/:num) to name-based (/:any) - TestsController: Refactored to use ValueSet library instead of direct valueset queries - Added ValueSet library (app/Libraries/ValueSet.php) with static lookup methods: - getOptions() - returns dropdown format [{value, label}] - getLabel(, ) - returns label for a value - transformLabels(, ) - batch transform records - get() and getRaw() for Lookups compatibility - Added ValueSetApiController for public valueset API endpoints - Added ValueSet refresh endpoint (POST /api/valueset/refresh) - Added DemoOrderController for testing order creation without auth - 2026-01-12-000001: Convert valueset references from VID to VValue - 2026-01-12-000002: Rename patient.Gender column to Sex - OrderTestController: Now uses OrderTestModel with proper model pattern - TestsController: Uses ValueSet library for all lookup operations - ValueSetController: Simplified to use name-based lookups - Updated all organization (account/site/workstation) dialogs and index views - Updated specimen container dialogs and index views - Updated tests_index.php with ValueSet integration - Updated patient dialog form and index views - Removed .factory/config.json and CLAUDE.md (replaced by AGENTS.md) - Consolidated lookups in Lookups.php (removed inline valueset constants) - Updated all test files to match new field names - 32 modified files, 17 new files, 2 deleted files - Net: +661 insertions, -1443 deletions (significant cleanup)
2026-01-12 16:53:41 +07:00
});
// Result ValueSet
$routes->group('result', function ($routes) {
$routes->group('valueset', function ($routes) {
$routes->get('/', 'Result\ResultValueSetController::index');
$routes->get('(:num)', 'Result\ResultValueSetController::show/$1');
$routes->post('/', 'Result\ResultValueSetController::create');
$routes->put('(:num)', 'Result\ResultValueSetController::update/$1');
$routes->delete('(:num)', 'Result\ResultValueSetController::delete/$1');
});
feat(valueset): refactor from ID-based to name-based lookups Complete overhaul of the valueset system to use human-readable names instead of numeric IDs for improved maintainability and API consistency. - PatientController: Renamed 'Gender' field to 'Sex' in validation rules - ValuesetController: Changed API endpoints from ID-based (/:num) to name-based (/:any) - TestsController: Refactored to use ValueSet library instead of direct valueset queries - Added ValueSet library (app/Libraries/ValueSet.php) with static lookup methods: - getOptions() - returns dropdown format [{value, label}] - getLabel(, ) - returns label for a value - transformLabels(, ) - batch transform records - get() and getRaw() for Lookups compatibility - Added ValueSetApiController for public valueset API endpoints - Added ValueSet refresh endpoint (POST /api/valueset/refresh) - Added DemoOrderController for testing order creation without auth - 2026-01-12-000001: Convert valueset references from VID to VValue - 2026-01-12-000002: Rename patient.Gender column to Sex - OrderTestController: Now uses OrderTestModel with proper model pattern - TestsController: Uses ValueSet library for all lookup operations - ValueSetController: Simplified to use name-based lookups - Updated all organization (account/site/workstation) dialogs and index views - Updated specimen container dialogs and index views - Updated tests_index.php with ValueSet integration - Updated patient dialog form and index views - Removed .factory/config.json and CLAUDE.md (replaced by AGENTS.md) - Consolidated lookups in Lookups.php (removed inline valueset constants) - Updated all test files to match new field names - 32 modified files, 17 new files, 2 deleted files - Net: +661 insertions, -1443 deletions (significant cleanup)
2026-01-12 16:53:41 +07:00
});
// Counter
$routes->group('counter', function ($routes) {
$routes->get('/', 'CounterController::index');
$routes->get('(:num)', 'CounterController::show/$1');
$routes->post('/', 'CounterController::create');
$routes->patch('/', 'CounterController::update');
$routes->delete('/', 'CounterController::delete');
});
// AreaGeo
$routes->group('areageo', function ($routes) {
$routes->get('/', 'AreaGeoController::index');
$routes->get('provinces', 'AreaGeoController::getProvinces');
$routes->get('cities', 'AreaGeoController::getCities');
});
// Organization
$routes->group('organization', function ($routes) {
// Account
$routes->group('account', function ($routes) {
$routes->get('/', 'Organization\AccountController::index');
$routes->get('(:num)', 'Organization\AccountController::show/$1');
$routes->post('/', 'Organization\AccountController::create');
$routes->patch('/', 'Organization\AccountController::update');
$routes->delete('/', 'Organization\AccountController::delete');
});
// Site
$routes->group('site', function ($routes) {
$routes->get('/', 'Organization\SiteController::index');
$routes->get('(:num)', 'Organization\SiteController::show/$1');
$routes->post('/', 'Organization\SiteController::create');
$routes->patch('/', 'Organization\SiteController::update');
$routes->delete('/', 'Organization\SiteController::delete');
});
// Discipline
$routes->group('discipline', function ($routes) {
$routes->get('/', 'Organization\DisciplineController::index');
$routes->get('(:num)', 'Organization\DisciplineController::show/$1');
$routes->post('/', 'Organization\DisciplineController::create');
$routes->patch('/', 'Organization\DisciplineController::update');
$routes->delete('/', 'Organization\DisciplineController::delete');
});
// Department
$routes->group('department', function ($routes) {
$routes->get('/', 'Organization\DepartmentController::index');
$routes->get('(:num)', 'Organization\DepartmentController::show/$1');
$routes->post('/', 'Organization\DepartmentController::create');
$routes->patch('/', 'Organization\DepartmentController::update');
$routes->delete('/', 'Organization\DepartmentController::delete');
});
// Workstation
$routes->group('workstation', function ($routes) {
$routes->get('/', 'Organization\WorkstationController::index');
$routes->get('(:num)', 'Organization\WorkstationController::show/$1');
$routes->post('/', 'Organization\WorkstationController::create');
$routes->patch('/', 'Organization\WorkstationController::update');
$routes->delete('/', 'Organization\WorkstationController::delete');
});
});
// Specimen
$routes->group('specimen', function ($routes) {
feat(routes): add container alias endpoint for ContainerDefController Added an alternative route alias 'container' that points to ContainerDefController, providing backward compatibility and flexibility in API endpoint naming. - Routes '/api/specimen/container' to ContainerDefController methods - Supports GET, GET with ID, POST, and PATCH operations - Existing '/api/specimen/containerdef' routes remain unchanged File: app/Config/Routes.php (+7 lines) --- refactor(seeds): update and standardize seed data across multiple seeders Improved data consistency and coverage in database seeds: AreaGeoSeeder.php: - Updated geographic area data for better regional coverage - Standardized data format and field values DummySeeder.php: - Refactored dummy data generation for test environments - Improved data integrity and relationships PatientSeeder.php: - Enhanced patient test data with more realistic scenarios - Updated patient demographic information - Improved test result distributions Total: 111 lines changed across seed files --- docs: add CLQMS project documentation - Added project documentation file: "prj_clinical laboratory quality management system_3a.docx" - Comprehensive project specification and requirements document --- test: remove deprecated TestDefSiteTest.php - Removed obsolete test file that is no longer needed - Test coverage consolidated into other test classes File: tests/feature/TestDef/TestDefSiteTest.php (-374 lines) --- Summary: - +58 lines added (routes, seeds, docs) - -434 lines removed (deprecated test file) - 6 files affected
2026-01-07 16:55:25 +07:00
// Container aliases - 'container' and 'containerdef' both point to ContainerDefController
$routes->group('container', function ($routes) {
$routes->get('/', 'Specimen\ContainerDefController::index');
$routes->get('(:num)', 'Specimen\ContainerDefController::show/$1');
$routes->post('/', 'Specimen\ContainerDefController::create');
$routes->patch('/', 'Specimen\ContainerDefController::update');
});
$routes->group('containerdef', function ($routes) {
$routes->get('/', 'Specimen\ContainerDefController::index');
$routes->get('(:num)', 'Specimen\ContainerDefController::show/$1');
$routes->post('/', 'Specimen\ContainerDefController::create');
$routes->patch('/', 'Specimen\ContainerDefController::update');
});
$routes->group('prep', function ($routes) {
$routes->get('/', 'Specimen\SpecimenPrepController::index');
$routes->get('(:num)', 'Specimen\SpecimenPrepController::show/$1');
$routes->post('/', 'Specimen\SpecimenPrepController::create');
$routes->patch('/', 'Specimen\SpecimenPrepController::update');
});
$routes->group('status', function ($routes) {
$routes->get('/', 'Specimen\SpecimenStatusController::index');
$routes->get('(:num)', 'Specimen\SpecimenStatusController::show/$1');
$routes->post('/', 'Specimen\SpecimenStatusController::create');
$routes->patch('/', 'Specimen\SpecimenStatusController::update');
});
$routes->group('collection', function ($routes) {
$routes->get('/', 'Specimen\SpecimenCollectionController::index');
$routes->get('(:num)', 'Specimen\SpecimenCollectionController::show/$1');
$routes->post('/', 'Specimen\SpecimenCollectionController::create');
$routes->patch('/', 'Specimen\SpecimenCollectionController::update');
});
$routes->get('/', 'Specimen\SpecimenController::index');
$routes->get('(:num)', 'Specimen\SpecimenController::show/$1');
$routes->post('/', 'Specimen\SpecimenController::create');
$routes->patch('/', 'Specimen\SpecimenController::update');
});
// Tests
$routes->group('tests', function ($routes) {
$routes->get('/', 'TestsController::index');
$routes->get('(:num)', 'TestsController::show/$1');
$routes->post('/', 'TestsController::create');
$routes->patch('/', 'TestsController::update');
});
feat(valueset): refactor from ID-based to name-based lookups Complete overhaul of the valueset system to use human-readable names instead of numeric IDs for improved maintainability and API consistency. - PatientController: Renamed 'Gender' field to 'Sex' in validation rules - ValuesetController: Changed API endpoints from ID-based (/:num) to name-based (/:any) - TestsController: Refactored to use ValueSet library instead of direct valueset queries - Added ValueSet library (app/Libraries/ValueSet.php) with static lookup methods: - getOptions() - returns dropdown format [{value, label}] - getLabel(, ) - returns label for a value - transformLabels(, ) - batch transform records - get() and getRaw() for Lookups compatibility - Added ValueSetApiController for public valueset API endpoints - Added ValueSet refresh endpoint (POST /api/valueset/refresh) - Added DemoOrderController for testing order creation without auth - 2026-01-12-000001: Convert valueset references from VID to VValue - 2026-01-12-000002: Rename patient.Gender column to Sex - OrderTestController: Now uses OrderTestModel with proper model pattern - TestsController: Uses ValueSet library for all lookup operations - ValueSetController: Simplified to use name-based lookups - Updated all organization (account/site/workstation) dialogs and index views - Updated specimen container dialogs and index views - Updated tests_index.php with ValueSet integration - Updated patient dialog form and index views - Removed .factory/config.json and CLAUDE.md (replaced by AGENTS.md) - Consolidated lookups in Lookups.php (removed inline valueset constants) - Updated all test files to match new field names - 32 modified files, 17 new files, 2 deleted files - Net: +661 insertions, -1443 deletions (significant cleanup)
2026-01-12 16:53:41 +07:00
// Orders
$routes->group('ordertest', function ($routes) {
$routes->get('/', 'OrderTestController::index');
$routes->get('(:any)', 'OrderTestController::show/$1');
$routes->post('/', 'OrderTestController::create');
$routes->patch('/', 'OrderTestController::update');
$routes->delete('/', 'OrderTestController::delete');
$routes->post('status', 'OrderTestController::updateStatus');
});
// Demo/Test Routes (No Auth)
$routes->group('api/demo', function ($routes) {
$routes->post('order', 'Test\DemoOrderController::createDemoOrder');
$routes->get('orders', 'Test\DemoOrderController::listDemoOrders');
});
// Edge API - Integration with tiny-edge
$routes->group('edge', function ($routes) {
$routes->post('results', 'EdgeController::results');
$routes->get('orders', 'EdgeController::orders');
$routes->post('orders/(:num)/ack', 'EdgeController::ack/$1');
$routes->post('status', 'EdgeController::status');
});
});
// Khusus
2025-12-01 16:47:52 +07:00
/*
2025-10-22 13:40:27 +07:00
$routes->get('/api/zones', 'Zones::index');
$routes->get('/api/zones/synchronize', 'Zones::synchronize');
$routes->get('/api/zones/provinces', 'Zones::getProvinces');
2025-12-01 16:47:52 +07:00
$routes->get('/api/zones/cities', 'Zones::getCities');
2025-12-22 16:54:19 +07:00
*/