feat: Restructure OpenAPI documentation with modular components

- Add OpenApiDocs controller for serving bundled API docs

- Split monolithic api-docs.yaml into modular components/

- Add organized paths/ directory with endpoint definitions

- Create bundling scripts (JS, PHP, Python) for merging docs

- Add API_DOCS_README.md with documentation guidelines

- Update Routes.php for new API documentation endpoints

- Update swagger.php view and TestDefSiteModel
This commit is contained in:
mahdahar 2026-02-16 14:20:52 +07:00
parent 8c44cc84a2
commit fcaf9b74ea
34 changed files with 8642 additions and 4426 deletions

View File

@ -24,6 +24,9 @@ $routes->group('api', ['filter' => 'auth'], function ($routes) {
// Swagger API Documentation (public - no filters)
$routes->add('swagger', 'PagesController::swagger');
// OpenAPI Specification (server-side merged - public)
$routes->get('api-docs', 'OpenApiDocs::index');
// V2 Auth API Routes (public - no auth required)
$routes->group('v2/auth', function ($routes) {
$routes->post('login', 'AuthV2Controller::login');

View File

@ -0,0 +1,43 @@
<?php
namespace App\Controllers;
class OpenApiDocs extends BaseController
{
/**
* Serve pre-bundled OpenAPI specification
* Returns the bundled file with all paths and schemas resolved
*/
public function index()
{
try {
// Load pre-bundled OpenAPI spec
$bundledPath = FCPATH . 'api-docs.bundled.yaml';
if (!file_exists($bundledPath)) {
throw new \Exception("Bundled API docs not found: api-docs.bundled.yaml. Run: node bundle-api-docs.js");
}
$content = file_get_contents($bundledPath);
// Output as YAML
return $this->response
->setContentType('application/x-yaml')
->setHeader('Access-Control-Allow-Origin', '*')
->setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS')
->setHeader('Access-Control-Allow-Headers', 'Content-Type')
->setHeader('Cache-Control', 'no-cache, must-revalidate')
->setBody($content);
} catch (\Exception $e) {
log_message('error', 'OpenApiDocs Error: ' . $e->getMessage());
return $this->response
->setStatusCode(500)
->setContentType('application/json')
->setBody(json_encode([
'error' => 'Failed to serve OpenAPI spec',
'message' => $e->getMessage()
]));
}
}
}

View File

@ -32,7 +32,7 @@ class TestDefSiteModel extends BaseModel {
protected $useSoftDeletes = true;
protected $deletedField = "EndDate";
public function getTests($siteId = null, $testType = null, $visibleScr = null, $visibleRpt = null, $keyword = null) {
public function getTests($siteId = null, $testType = null, $visibleScr = null, $visibleRpt = null, $search = null, $page = 1, $perPage = 20) {
$builder = $this->select("testdefsite.TestSiteID, testdefsite.TestSiteCode, testdefsite.TestSiteName, testdefsite.TestType,
testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.VisibleScr, testdefsite.VisibleRpt,
testdefsite.CountStat, testdefsite.StartDate, testdefsite.EndDate")
@ -54,15 +54,33 @@ class TestDefSiteModel extends BaseModel {
$builder->where('testdefsite.VisibleRpt', $visibleRpt);
}
if ($keyword) {
$builder->like('testdefsite.TestSiteName', $keyword);
if ($search) {
$builder->groupStart()
->like('testdefsite.TestSiteCode', $search)
->orLike('testdefsite.TestSiteName', $search)
->groupEnd();
}
$rows = $builder->orderBy('testdefsite.SeqScr', 'ASC')->findAll();
// Get total count before pagination
$totalBuilder = clone $builder;
$total = $totalBuilder->countAllResults();
// Apply pagination
$offset = ($page - 1) * $perPage;
$rows = $builder->orderBy('testdefsite.SeqScr', 'ASC')
->limit($perPage, $offset)
->findAll();
$rows = ValueSet::transformLabels($rows, [
'TestType' => 'test_type',
]);
return $rows;
return [
'data' => $rows,
'pagination' => [
'total' => $total
]
];
}
public function getTest($TestSiteID) {

View File

@ -357,7 +357,7 @@
// Initialize Swagger UI
const ui = SwaggerUIBundle({
url: "<?= base_url('api-docs.yaml') ?>?v=<?= time() ?>",
url: "<?= base_url('api-docs') ?>?v=<?= time() ?>",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [

162
public/API_DOCS_README.md Normal file
View File

@ -0,0 +1,162 @@
# CLQMS OpenAPI Documentation Structure
## Overview
The OpenAPI documentation has been reorganized into a modular structure for better maintainability.
**Architecture:** Server-side resolution (CodeIgniter 4)
- Modular files in `paths/` and `components/schemas/` directories
- CodeIgniter controller merges files on-the-fly
- Single endpoint `/api-docs` serves complete specification
- No build step or bundling required
## How It Works
1. **Modular Development:** Edit files in `paths/` and `components/schemas/`
2. **Server-Side Merge:** `OpenApiDocs` controller loads and merges all files
3. **Single Endpoint:** Access `/api-docs` to get complete merged specification
4. **Cache Support:** Can add caching layer for production
## Recommended Usage
**For Swagger UI:** Use the CodeIgniter route `/api-docs` (already configured in `app/Views/swagger.php`)
**For development:** Edit modular files directly - changes are reflected immediately on next request
## Structure
```
public/
├── api-docs.yaml # Main entry point with schema references
├── api-docs.bundled.yaml # Bundled version (use this for Swagger UI)
├── components/
│ └── schemas/
│ ├── authentication.yaml
│ ├── common.yaml
│ ├── edge-api.yaml
│ ├── master-data.yaml
│ ├── orders.yaml
│ ├── organization.yaml
│ ├── patient-visit.yaml
│ ├── patient.yaml
│ ├── specimen.yaml
│ ├── tests.yaml
│ └── valuesets.yaml
├── paths/
│ ├── authentication.yaml
│ ├── demo.yaml
│ ├── edge-api.yaml
│ ├── master-data.yaml
│ ├── orders.yaml
│ ├── organization.yaml
│ ├── patient-visits.yaml
│ ├── patients.yaml
│ ├── results.yaml
│ ├── specimen.yaml
│ ├── tests.yaml
│ └── valuesets.yaml
└── bundle-api-docs.py # Bundler script
```
## Architecture
### Server-Side Resolution
The application uses a CodeIgniter 4 controller (`app/Controllers/OpenApiDocs.php`) that:
1. Loads `public/api-docs.yaml` (base spec with schemas)
2. Scans `public/paths/*.yaml` files
3. Merges all paths into the base spec
4. Outputs complete YAML response
### Benefits
- ✅ **No bundling step** - Files merged at runtime
- ✅ **Immediate updates** - Changes reflect immediately
- ✅ **Modular structure** - Separate files by domain
- ✅ **CI4 compatible** - Works with CodeIgniter 4
- ✅ **Nginx ready** - Can migrate to Nginx later
- ✅ **Cacheable** - Can add caching for production
## Usage
### For Development
Edit files directly:
- **Paths:** `public/paths/*.yaml`
- **Schemas:** `public/components/schemas/*.yaml`
### For Production/Swagger UI
**Endpoint:** `http://localhost/clqms01/api-docs`
The endpoint merges all files server-side and returns a complete OpenAPI specification that Swagger UI can consume.
## Caching (Optional)
For production, you can add caching to the `OpenApiDocs` controller:
```php
// In OpenApiDocs::index()
$cacheKey = 'openapi_spec_' . filemtime(FCPATH . 'api-docs.yaml');
if ($cached = cache()->get($cacheKey)) {
return $this->response->setBody($cached);
}
// ... build spec ...
// Cache for 5 minutes
cache()->save($cacheKey, $yaml, 300);
```
## Configuration Update
Update your application configuration to use the bundled file:
**PHP (CodeIgniter):**
```php
// Already updated in app/Views/swagger.php:
url: "<?= base_url('api-docs.bundled.yaml') ?>"
```
**JavaScript/Node:**
```javascript
// Change from:
const spec = await fetch('/api-docs.yaml');
// To:
const spec = await fetch('/api-docs.bundled.yaml');
```
## Benefits
1. **Modular**: Each domain has its own file
2. **Maintainable**: Easier to find and update specific endpoints
3. **Team-friendly**: Multiple developers can work on different files
4. **Schema Reuse**: Schemas defined once, referenced everywhere
5. **Better Versioning**: Individual domains can be versioned separately
## Migration Notes
- **From bundled to server-side:** Already done! The system now uses server-side resolution.
- **Nginx migration:** When ready to migrate to Nginx, the approach remains the same (CI4 handles the merging).
- **Back to bundling:** If needed, the bundler script is still available: `python bundle-api-docs.py`
## Troubleshooting
### Schema Resolution Errors
If you see errors like "Could not resolve reference", ensure:
1. Schema files exist in `components/schemas/`
2. References use correct relative paths (e.g., `./components/schemas/patient.yaml#/Patient`)
3. You're using the bundled file (`api-docs.bundled.yaml`) for OpenAPI tools
### Path Resolution Errors
OpenAPI 3.0 doesn't support external file references for paths. Always use the bundled version for serving the documentation.
## Migration Notes
- The original `api-docs.yaml` is preserved with schema references only
- All paths have been moved to individual files in `paths/` directory
- A bundler script merges everything into `api-docs.bundled.yaml`
- Update your application to serve `api-docs.bundled.yaml` instead

4124
public/api-docs.bundled.yaml Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

96
public/bundle-api-docs.js Normal file
View File

@ -0,0 +1,96 @@
#!/usr/bin/env node
/**
* OpenAPI Documentation Bundler - Node.js Version
*
* This script merges the modular OpenAPI specification files into a single
* api-docs.bundled.yaml file that can be served to Swagger UI.
*
* It merges paths from the paths/ directory and then uses Redocly CLI to resolve
* all $ref references into inline definitions.
*
* Usage: node bundle-api-docs.js
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const publicDir = __dirname;
const pathsDir = path.join(publicDir, 'paths');
const tempFile = path.join(publicDir, 'api-docs.merged.yaml');
const outputFile = path.join(publicDir, 'api-docs.bundled.yaml');
// Read the base api-docs.yaml
const apiDocsPath = path.join(publicDir, 'api-docs.yaml');
let apiDocsContent = fs.readFileSync(apiDocsPath, 'utf8');
// Parse YAML manually (simple approach - looking for paths: {})
const pathsMatch = apiDocsContent.match(/^paths:\s*\{\}/m);
if (!pathsMatch) {
console.error('Could not find empty paths section in api-docs.yaml');
process.exit(1);
}
// Read all path files
const pathFiles = fs.readdirSync(pathsDir)
.filter(f => f.endsWith('.yaml'))
.map(f => path.join(pathsDir, f));
console.log(`Found ${pathFiles.length} path files to merge...`);
// Merge all paths content
let mergedPaths = [];
for (const filepath of pathFiles) {
const filename = path.basename(filepath);
try {
let content = fs.readFileSync(filepath, 'utf8');
// Fix relative paths: ../components/ -> ./components/
// because paths are now at the root level after merging
content = content.replace(/\.\.\/components\//g, './components/');
mergedPaths.push(`# From: ${filename}\n${content}`);
console.log(` [OK] Merged paths from ${filename}`);
} catch (e) {
console.log(` [WARN] Failed to read ${filename}: ${e.message}`);
}
}
// Replace empty paths with merged paths
const pathsYaml = mergedPaths.join('\n\n');
const mergedContent = apiDocsContent.replace(
/^paths:\s*\{\}/m,
`paths:\n${pathsYaml.split('\n').map(line => ' ' + line).join('\n')}`
);
// Write merged file (still has $refs)
fs.writeFileSync(tempFile, mergedContent, 'utf8');
console.log(`\n[SUCCESS] Merged paths into: ${tempFile}`);
// Now use Redocly CLI to resolve all $ref references
console.log('\nResolving $ref references with Redocly CLI...');
try {
execSync(`redocly bundle "${tempFile}" -o "${outputFile}"`, {
cwd: publicDir,
stdio: 'inherit'
});
console.log(`\n[SUCCESS] Resolved all $ref references to: ${outputFile}`);
// Clean up temp file
fs.unlinkSync(tempFile);
console.log(`[CLEANUP] Removed temp file: ${tempFile}`);
// Show stats
const stats = fs.statSync(outputFile);
console.log(`\n${'='.repeat(60)}`);
console.log('Bundling complete!');
console.log(` Output: ${outputFile}`);
console.log(` Size: ${(stats.size / 1024).toFixed(1)} KB`);
console.log(`\nYou can now serve this file to Swagger UI.`);
console.log(`${'='.repeat(60)}`);
} catch (e) {
console.error(`\n[ERROR] Failed to run Redocly CLI: ${e.message}`);
console.error('Make sure Redocly CLI is installed: npm install -g @redocly/cli');
process.exit(1);
}

View File

@ -0,0 +1,55 @@
<?php
/**
* OpenAPI Documentation Bundler
*
* This script merges the modular OpenAPI specification files into a single
* api-docs.yaml file that can be served to Swagger UI or other OpenAPI tools.
*
* Usage: php bundle-api-docs.php
*/
$publicDir = __DIR__;
$componentsDir = $publicDir . '/components/schemas';
$pathsDir = $publicDir . '/paths';
$outputFile = $publicDir . '/api-docs.bundled.yaml';
// Read the base api-docs.yaml
$apiDocsContent = file_get_contents($publicDir . '/api-docs.yaml');
$apiDocs = yaml_parse($apiDocsContent);
if ($apiDocs === false) {
die("Error: Failed to parse api-docs.yaml\n");
}
// Merge paths from all path files
$paths = [];
$pathFiles = glob($pathsDir . '/*.yaml');
echo "Found " . count($pathFiles) . " path files to merge...\n";
foreach ($pathFiles as $filepath) {
$filename = basename($filepath);
$content = file_get_contents($filepath);
$parsed = yaml_parse($content);
if ($parsed === false) {
echo " ⚠ Warning: Failed to parse $filename\n";
continue;
}
$paths = array_merge($paths, $parsed);
echo " ✓ Merged " . count($parsed) . " paths from $filename\n";
}
// Replace the empty paths with merged paths
$apiDocs['paths'] = $paths;
// Write the bundled file
$bundledYaml = yaml_emit($apiDocs, YAML_UTF8_ENCODING);
file_put_contents($outputFile, $bundledYaml);
echo "\n✅ Successfully bundled OpenAPI spec to: $outputFile\n";
echo " Total paths: " . count($paths) . "\n";
echo " Total schemas: " . count($apiDocs['components']['schemas']) . "\n";

97
public/bundle-api-docs.py Normal file
View File

@ -0,0 +1,97 @@
#!/usr/bin/env python3
"""
OpenAPI Documentation Bundler
This script merges the modular OpenAPI specification files into a single
api-docs.bundled.yaml file that can be served to Swagger UI or other OpenAPI tools.
It merges paths from the paths/ directory and then uses Redocly CLI to resolve
all $ref references into inline definitions.
Usage: python bundle-api-docs.py
"""
import yaml
import os
import glob
import subprocess
public_dir = os.path.dirname(os.path.abspath(__file__))
components_dir = os.path.join(public_dir, "components", "schemas")
paths_dir = os.path.join(public_dir, "paths")
temp_file = os.path.join(public_dir, "api-docs.merged.yaml")
output_file = os.path.join(public_dir, "api-docs.bundled.yaml")
# Read the base api-docs.yaml
with open(os.path.join(public_dir, "api-docs.yaml"), "r", encoding="utf-8") as f:
api_docs = yaml.safe_load(f)
# Merge paths from all path files
paths = {}
path_files = glob.glob(os.path.join(paths_dir, "*.yaml"))
print(f"Found {len(path_files)} path files to merge...")
for filepath in path_files:
filename = os.path.basename(filepath)
try:
with open(filepath, "r", encoding="utf-8") as f:
parsed = yaml.safe_load(f)
if parsed:
paths.update(parsed)
print(f" [OK] Merged {len(parsed)} paths from {filename}")
except Exception as e:
print(f" [WARN] Failed to parse {filename}: {e}")
# Replace the empty paths with merged paths
api_docs["paths"] = paths
# Write the merged file (still has $refs)
with open(temp_file, "w", encoding="utf-8") as f:
yaml.dump(
api_docs,
f,
default_flow_style=False,
allow_unicode=True,
sort_keys=False,
width=4096,
)
print(f"\n[SUCCESS] Merged paths into: {temp_file}")
print(f" Total paths: {len(paths)}")
# Now use Redocly CLI to resolve all $ref references
print("\nResolving $ref references with Redocly CLI...")
try:
result = subprocess.run(
["redocly", "bundle", temp_file, "-o", output_file],
capture_output=True,
text=True,
cwd=public_dir,
)
if result.returncode == 0:
print(f" [SUCCESS] Resolved all $ref references to: {output_file}")
# Clean up temp file
os.remove(temp_file)
print(f" [CLEANUP] Removed temp file: {temp_file}")
else:
print(f" [ERROR] Redocly CLI failed:")
print(f" {result.stderr}")
exit(1)
except FileNotFoundError:
print(" [ERROR] Redocly CLI not found. Install with: npm install -g @redocly/cli")
exit(1)
except Exception as e:
print(f" [ERROR] Failed to run Redocly CLI: {e}")
exit(1)
print(f"\n{'=' * 60}")
print(f"Bundling complete!")
print(f" Output: {output_file}")
print(f" Total paths: {len(paths)}")
print(f" Total schemas: {len(api_docs.get('components', {}).get('schemas', {}))}")
print(f"\nYou can now serve this file to Swagger UI.")
print(f"{'=' * 60}")

View File

@ -0,0 +1,44 @@
LoginRequest:
type: object
required:
- username
- password
properties:
username:
type: string
example: labuser01
password:
type: string
format: password
example: secret123
LoginResponse:
type: object
properties:
status:
type: string
example: success
code:
type: integer
example: 200
message:
type: string
example: Login successful
RegisterRequest:
type: object
required:
- username
- password
- email
properties:
username:
type: string
password:
type: string
format: password
email:
type: string
format: email
full_name:
type: string

View File

@ -0,0 +1,34 @@
SuccessResponse:
type: object
properties:
status:
type: string
example: success
message:
type: string
code:
type: integer
example: 200
ErrorResponse:
type: object
properties:
status:
type: string
example: error
message:
type: string
errors:
type: object
DashboardSummary:
type: object
properties:
pendingOrders:
type: integer
todayResults:
type: integer
criticalResults:
type: integer
activePatients:
type: integer

View File

@ -0,0 +1,75 @@
EdgeResultRequest:
type: object
required:
- sample_id
- instrument_id
properties:
sample_id:
type: string
description: Sample barcode/identifier
instrument_id:
type: string
description: Instrument identifier
patient_id:
type: string
description: Patient identifier (optional)
results:
type: array
items:
type: object
properties:
test_code:
type: string
result_value:
type: string
unit:
type: string
flags:
type: string
enum: [H, L, N, A]
description: H=High, L=Low, N=Normal, A=Abnormal
EdgeResultResponse:
type: object
properties:
status:
type: string
example: success
message:
type: string
example: Result received and queued
data:
type: object
properties:
edge_res_id:
type: integer
sample_id:
type: string
instrument_id:
type: string
EdgeOrder:
type: object
properties:
OrderID:
type: string
PatientID:
type: string
SampleID:
type: string
Tests:
type: array
items:
type: object
properties:
TestCode:
type: string
TestName:
type: string
SpecimenType:
type: string
Priority:
type: string
DueDateTime:
type: string
format: date-time

View File

@ -0,0 +1,157 @@
Location:
type: object
properties:
LocationID:
type: integer
description: Primary key
SiteID:
type: integer
description: Reference to site
LocCode:
type: string
maxLength: 6
description: Location code (short identifier)
Parent:
type: integer
nullable: true
description: Parent location ID for hierarchical locations
LocFull:
type: string
maxLength: 255
description: Full location name
Description:
type: string
maxLength: 255
description: Location description
LocType:
type: string
description: Location type code (e.g., ROOM, WARD, BUILDING)
CreateDate:
type: string
format: date-time
EndDate:
type: string
format: date-time
nullable: true
Contact:
type: object
properties:
ContactID:
type: integer
description: Primary key
NameFirst:
type: string
description: First name (required)
NameLast:
type: string
description: Last name
Title:
type: string
description: Title (e.g., Dr, Mr, Mrs)
Initial:
type: string
description: Middle initial
Birthdate:
type: string
format: date-time
description: Date of birth
EmailAddress1:
type: string
format: email
description: Primary email address
EmailAddress2:
type: string
format: email
description: Secondary email address
Phone:
type: string
description: Primary phone number
MobilePhone1:
type: string
description: Primary mobile number
MobilePhone2:
type: string
description: Secondary mobile number
Specialty:
type: string
description: Medical specialty code
SubSpecialty:
type: string
description: Sub-specialty code
CreateDate:
type: string
format: date-time
EndDate:
type: string
format: date-time
description: Occupation display text
Occupation:
type: object
properties:
OccupationID:
type: integer
description: Primary key
OccCode:
type: string
description: Occupation code
OccText:
type: string
description: Occupation name/text
Description:
type: string
description: Additional description
CreateDate:
type: string
format: date-time
MedicalSpecialty:
type: object
properties:
SpecialtyID:
type: integer
description: Primary key
SpecialtyText:
type: string
description: Specialty name/text
Parent:
type: integer
description: Parent specialty ID for hierarchical structure
Title:
type: string
description: Title/abbreviation
CreateDate:
type: string
format: date-time
EndDate:
type: string
format: date-time
Counter:
type: object
properties:
CounterID:
type: integer
description: Primary key
CounterDesc:
type: string
description: Counter description/name
CounterValue:
type: integer
description: Current counter value
CounterStart:
type: integer
description: Starting value for the counter
CounterEnd:
type: integer
description: Ending value (for auto-reset)
CounterReset:
type: string
description: Reset pattern (e.g., D=Daily, M=Monthly, Y=Yearly)
CreateDate:
type: string
format: date-time
EndDate:
type: string
format: date-time

View File

@ -0,0 +1,53 @@
OrderTest:
type: object
properties:
OrderID:
type: string
PatientID:
type: string
VisitID:
type: string
OrderDate:
type: string
format: date-time
OrderStatus:
type: string
enum: [ORD, SCH, ANA, VER, REV, REP]
description: |
ORD: Ordered
SCH: Scheduled
ANA: Analysis
VER: Verified
REV: Reviewed
REP: Reported
OrderStatusLabel:
type: string
description: Order status display text
Priority:
type: string
enum: [R, S, U]
description: |
R: Routine
S: Stat
U: Urgent
PriorityLabel:
type: string
description: Priority display text
SiteID:
type: integer
RequestingPhysician:
type: string
OrderItem:
type: object
properties:
id:
type: integer
OrderID:
type: string
TestID:
type: integer
SpecimenID:
type: string
Status:
type: string

View File

@ -0,0 +1,59 @@
Account:
type: object
properties:
id:
type: integer
AccountName:
type: string
AccountCode:
type: string
AccountType:
type: string
Site:
type: object
properties:
id:
type: integer
SiteName:
type: string
SiteCode:
type: string
AccountID:
type: integer
Discipline:
type: object
properties:
id:
type: integer
DisciplineName:
type: string
DisciplineCode:
type: string
Department:
type: object
properties:
id:
type: integer
DeptName:
type: string
DeptCode:
type: string
SiteID:
type: integer
Workstation:
type: object
properties:
id:
type: integer
WorkstationName:
type: string
WorkstationCode:
type: string
SiteID:
type: integer
DepartmentID:
type: integer

View File

@ -0,0 +1,105 @@
PatientVisit:
type: object
properties:
InternalPVID:
type: integer
description: Primary key (auto-generated)
PVID:
type: string
description: Visit ID (auto-generated with DV prefix if not provided)
InternalPID:
type: integer
description: Reference to patient
EpisodeID:
type: string
description: Episode identifier
SiteID:
type: integer
description: Site reference
CreateDate:
type: string
format: date-time
EndDate:
type: string
format: date-time
ArchivedDate:
type: string
format: date-time
DelDate:
type: string
format: date-time
PatDiag:
type: object
description: Diagnosis information (optional)
properties:
DiagCode:
type: string
Diagnosis:
type: string
PatVisitADT:
type: object
description: ADT (Admission/Discharge/Transfer) information (optional)
properties:
ADTCode:
type: string
enum: [A01, A02, A03, A04, A08]
LocationID:
type: integer
AttDoc:
type: integer
description: Attending physician ContactID
RefDoc:
type: integer
description: Referring physician ContactID
AdmDoc:
type: integer
description: Admitting physician ContactID
CnsDoc:
type: integer
description: Consulting physician ContactID
PatVisitADT:
type: object
properties:
PVADTID:
type: integer
description: Primary key (auto-generated)
InternalPVID:
type: integer
description: Reference to patient visit
ADTCode:
type: string
enum: [A01, A02, A03, A04, A08]
description: |
A01: Admit
A02: Transfer
A03: Discharge
A04: Register
A08: Update
LocationID:
type: integer
description: Location/ward reference
AttDoc:
type: integer
description: Attending physician ContactID
RefDoc:
type: integer
description: Referring physician ContactID
AdmDoc:
type: integer
description: Admitting physician ContactID
CnsDoc:
type: integer
description: Consulting physician ContactID
CreateDate:
type: string
format: date-time
EndDate:
type: string
format: date-time
ArchivedDate:
type: string
format: date-time
DelDate:
type: string
format: date-time

View File

@ -0,0 +1,205 @@
PatientIdentifier:
type: object
properties:
IdentifierType:
type: string
enum: [KTP, PASS, SSN, SIM, KTAS]
description: |
KTP: 16 digit numeric
PASS: alphanumeric max 9
SSN: 9 digit numeric
SIM: 19-20 digit numeric
KTAS: 11 digit numeric
Identifier:
type: string
maxLength: 255
LinkedPatient:
type: object
description: Linked patient reference
properties:
InternalPID:
type: integer
description: Internal patient ID of the linked patient
PatientID:
type: string
description: Patient ID of the linked patient
Custodian:
type: object
description: Patient custodian/guardian
properties:
InternalPID:
type: integer
description: Internal patient ID of the custodian
PatientID:
type: string
description: Patient ID of the custodian
PatAttEntry:
type: object
description: Patient address/attorney entry
properties:
Address:
type: string
description: Address text
Patient:
type: object
required:
- PatientID
- Sex
- NameFirst
- Birthdate
properties:
PatientID:
type: string
maxLength: 30
pattern: '^[A-Za-z0-9]+$'
description: Internal patient identifier
AlternatePID:
type: string
maxLength: 30
pattern: '^[A-Za-z0-9]+$'
Prefix:
type: string
maxLength: 10
enum: [Mr, Mrs, Ms, Dr, Prof]
Sex:
type: string
enum: ['1', '2']
description: '1: Female, 2: Male'
NameFirst:
type: string
minLength: 1
maxLength: 60
pattern: "^[A-Za-z'\\. ]+$"
NameMiddle:
type: string
minLength: 1
maxLength: 60
NameMaiden:
type: string
minLength: 1
maxLength: 60
NameLast:
type: string
minLength: 1
maxLength: 60
Suffix:
type: string
maxLength: 10
Birthdate:
type: string
format: date-time
description: ISO 8601 UTC datetime
PlaceOfBirth:
type: string
maxLength: 100
Citizenship:
type: string
maxLength: 100
Street_1:
type: string
maxLength: 255
Street_2:
type: string
maxLength: 255
Street_3:
type: string
maxLength: 255
ZIP:
type: string
maxLength: 10
pattern: '^[0-9]+$'
Phone:
type: string
pattern: "^\\+?[0-9]{8,15}$"
MobilePhone:
type: string
pattern: "^\\+?[0-9]{8,15}$"
EmailAddress1:
type: string
format: email
maxLength: 100
EmailAddress2:
type: string
format: email
maxLength: 100
PatIdt:
$ref: 'patient.yaml#/PatientIdentifier'
LinkTo:
type: array
description: Array of linked patient references
items:
$ref: 'patient.yaml#/LinkedPatient'
Custodian:
$ref: 'patient.yaml#/Custodian'
DeathIndicator:
type: string
enum: [Y, N]
description: 'Y: Yes (deceased), N: No (alive)'
TimeOfDeath:
type: string
format: date-time
description: ISO 8601 UTC datetime of death
PatCom:
type: string
description: Patient comment/notes
PatAtt:
type: array
description: Patient address entries
items:
$ref: 'patient.yaml#/PatAttEntry'
Province:
type: integer
description: Province AreaGeoID (foreign key to areageo table)
ProvinceLabel:
type: string
description: Province name (resolved from areageo)
City:
type: integer
description: City AreaGeoID (foreign key to areageo table)
CityLabel:
type: string
description: City name (resolved from areageo)
Country:
type: string
maxLength: 10
description: Country ISO 3-letter code (e.g., IDN, USA)
CountryLabel:
type: string
description: Country name (resolved from valueset)
Race:
type: string
maxLength: 100
MaritalStatus:
type: string
enum: [A, B, D, M, S, W]
description: 'A: Annulled, B: Separated, D: Divorced, M: Married, S: Single, W: Widowed'
Religion:
type: string
maxLength: 100
Ethnic:
type: string
maxLength: 100
PatientListResponse:
type: object
properties:
status:
type: string
example: success
data:
type: array
items:
$ref: 'patient.yaml#/Patient'
pagination:
type: object
properties:
page:
type: integer
perPage:
type: integer
total:
type: integer

View File

@ -0,0 +1,10 @@
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: JWT token from login endpoint
cookieAuth:
type: apiKey
in: cookie
name: token
description: JWT token stored in HTTP-only cookie

View File

@ -0,0 +1,132 @@
Specimen:
type: object
properties:
id:
type: integer
SpecimenID:
type: string
PatientID:
type: string
SpecimenType:
type: string
description: Specimen type code
SpecimenTypeLabel:
type: string
description: Specimen type display text
CollectionDate:
type: string
format: date-time
CollectionMethod:
type: string
description: Collection method code
CollectionMethodLabel:
type: string
description: Collection method display text
ContainerID:
type: integer
SpecimenStatus:
type: string
description: Specimen status code
SpecimenStatusLabel:
type: string
description: Specimen status display text
BodySite:
type: string
description: Body site code
BodySiteLabel:
type: string
description: Body site display text
ContainerDef:
type: object
properties:
id:
type: integer
ContainerCode:
type: string
ContainerName:
type: string
ConCategory:
type: string
description: Container category code
ConCategoryLabel:
type: string
description: Container category display text
ConSize:
type: string
description: Container size code
ConSizeLabel:
type: string
description: Container size display text
CapColor:
type: string
description: Cap color code
CapColorLabel:
type: string
description: Cap color display text
SpecimenPrep:
type: object
properties:
id:
type: integer
PrepCode:
type: string
PrepName:
type: string
Description:
type: string
SpecimenStatus:
type: object
properties:
id:
type: integer
StatusCode:
type: string
StatusName:
type: string
Description:
type: string
Status:
type: string
description: Status code
StatusLabel:
type: string
description: Status display text
Activity:
type: string
description: Activity code
ActivityLabel:
type: string
description: Activity display text
SpecimenCollection:
type: object
properties:
id:
type: integer
CollectionCode:
type: string
CollectionName:
type: string
Description:
type: string
CollectionMethod:
type: string
description: Collection method code
CollectionMethodLabel:
type: string
description: Collection method display text
Additive:
type: string
description: Additive code
AdditiveLabel:
type: string
description: Additive display text
SpecimenRole:
type: string
description: Specimen role code
SpecimenRoleLabel:
type: string
description: Specimen role display text

View File

@ -0,0 +1,278 @@
TestDefinition:
type: object
properties:
id:
type: integer
TestCode:
type: string
TestName:
type: string
TestType:
type: string
enum: [TEST, PARAM, CALC, GROUP, TITLE]
description: |
TEST: Technical test
PARAM: Parameter
CALC: Calculated
GROUP: Panel/Profile
TITLE: Section header
DisciplineID:
type: integer
DisciplineName:
type: string
DepartmentID:
type: integer
DepartmentName:
type: string
Unit:
type: string
Formula:
type: string
refnum:
type: array
description: Numeric reference ranges (optional). Mutually exclusive with reftxt - a test can only have ONE reference type.
items:
type: object
properties:
RefNumID:
type: integer
NumRefType:
type: string
enum: [NMRC, THOLD]
description: NMRC=Numeric range, THOLD=Threshold
NumRefTypeLabel:
type: string
RangeType:
type: string
RangeTypeLabel:
type: string
Sex:
type: string
SexLabel:
type: string
LowSign:
type: string
LowSignLabel:
type: string
HighSign:
type: string
HighSignLabel:
type: string
High:
type: number
format: float
Low:
type: number
format: float
AgeStart:
type: integer
AgeEnd:
type: integer
Flag:
type: string
Interpretation:
type: string
reftxt:
type: array
description: Text reference ranges (optional). Mutually exclusive with refnum - a test can only have ONE reference type.
items:
type: object
properties:
RefTxtID:
type: integer
TxtRefType:
type: string
enum: [TEXT, VSET]
description: TEXT=Free text, VSET=Value set
TxtRefTypeLabel:
type: string
Sex:
type: string
SexLabel:
type: string
AgeStart:
type: integer
AgeEnd:
type: integer
RefTxt:
type: string
Flag:
type: string
examples:
$1:
Unit: mg/dL
refnum:
- RefNumID: 1
NumRefType: NMRC
NumRefTypeLabel: Numeric
RangeType: REF
RangeTypeLabel: Reference Range
Sex: '2'
SexLabel: Male
LowSign: GE
LowSignLabel: ">="
HighSign: LE
HighSignLabel: "<="
Low: 70
High: 100
AgeStart: 18
AgeEnd: 99
Flag: N
Interpretation: Normal
TEST_numeric_thold:
summary: Technical test - threshold reference (THOLD)
value:
id: 1
TestCode: GLU
TestName: Glucose
TestType: TEST
DisciplineID: 1
DepartmentID: 1
Unit: mg/dL
refnum:
- RefNumID: 2
NumRefType: THOLD
NumRefTypeLabel: Threshold
RangeType: PANIC
RangeTypeLabel: Panic Range
Sex: '1'
SexLabel: Female
LowSign: LT
LowSignLabel: "<"
High: 40
AgeStart: 0
AgeEnd: 120
Flag: L
Interpretation: Critical Low
$2:
Unit: null
reftxt:
- RefTxtID: 1
TxtRefType: TEXT
TxtRefTypeLabel: Text
Sex: '2'
SexLabel: Male
AgeStart: 18
AgeEnd: 99
RefTxt: 'NORM=Normal;HYPO=Hypochromic;MACRO=Macrocytic'
Flag: N
TEST_text_vset:
summary: Technical test - text reference (VSET)
value:
id: 1
TestCode: STAGE
TestName: Disease Stage
TestType: TEST
DisciplineID: 1
DepartmentID: 1
Unit: null
reftxt:
- RefTxtID: 2
TxtRefType: VSET
TxtRefTypeLabel: Value Set
Sex: '1'
SexLabel: Female
AgeStart: 0
AgeEnd: 120
RefTxt: 'STG1=Stage 1;STG2=Stage 2;STG3=Stage 3;STG4=Stage 4'
Flag: N
PARAM:
summary: Parameter - no reference range allowed
value:
id: 2
TestCode: GLU_FAST
TestName: Fasting Glucose
TestType: PARAM
DisciplineID: 1
DepartmentID: 1
Unit: mg/dL
$3:
Unit: null
Formula: "BUN / Creatinine"
refnum:
- RefNumID: 5
NumRefType: NMRC
NumRefTypeLabel: Numeric
RangeType: REF
RangeTypeLabel: Reference Range
Sex: '1'
SexLabel: Female
LowSign: GE
LowSignLabel: ">="
HighSign: LE
HighSignLabel: "<="
Low: 10
High: 20
AgeStart: 18
AgeEnd: 120
Flag: N
Interpretation: Normal
$4:
Unit: null
Formula: "BUN / Creatinine"
refnum:
- RefNumID: 6
NumRefType: THOLD
NumRefTypeLabel: Threshold
RangeType: PANIC
RangeTypeLabel: Panic Range
Sex: '1'
SexLabel: Female
LowSign: GT
LowSignLabel: ">"
Low: 20
AgeStart: 18
AgeEnd: 120
Flag: H
Interpretation: Elevated - possible prerenal cause
GROUP:
summary: Panel/Profile - no reference range allowed
value:
id: 4
TestCode: LIPID
TestName: Lipid Panel
TestType: GROUP
DisciplineID: 1
DepartmentID: 1
Unit: null
TITLE:
summary: Section header - no reference range allowed
value:
id: 5
TestCode: CHEM_HEADER
TestName: '--- CHEMISTRY ---'
TestType: TITLE
DisciplineID: 1
DepartmentID: 1
Unit: null
TestMap:
type: object
properties:
id:
type: integer
TestMapID:
type: integer
TestCode:
type: string
HostCode:
type: string
HostName:
type: string
ClientCode:
type: string
ClientName:
type: string
HostType:
type: string
description: Host type code
HostTypeLabel:
type: string
description: Host type display text
ClientType:
type: string
description: Client type code
ClientTypeLabel:
type: string
description: Client type display text

View File

@ -0,0 +1,77 @@
ValueSetLibItem:
type: object
description: Library/system value set item from JSON files
properties:
value:
type: string
description: The value/key code
label:
type: string
description: The display label
ValueSetDef:
type: object
description: User-defined value set definition (from database)
properties:
VSetID:
type: integer
description: Primary key
SiteID:
type: integer
description: Site reference
VSName:
type: string
description: Value set name
VSDesc:
type: string
description: Value set description
CreateDate:
type: string
format: date-time
description: Creation timestamp
EndDate:
type: string
format: date-time
nullable: true
description: Soft delete timestamp
ItemCount:
type: integer
description: Number of items in this value set
ValueSetItem:
type: object
description: User-defined value set item (from database)
properties:
VID:
type: integer
description: Primary key
SiteID:
type: integer
description: Site reference
VSetID:
type: integer
description: Reference to value set definition
VOrder:
type: integer
description: Display order
VValue:
type: string
description: The value code
VDesc:
type: string
description: The display description/label
VCategory:
type: string
description: Category code
CreateDate:
type: string
format: date-time
description: Creation timestamp
EndDate:
type: string
format: date-time
nullable: true
description: Soft delete timestamp
VSName:
type: string
description: Value set name (from joined definition)

View File

@ -0,0 +1,167 @@
/api/auth/login:
post:
tags: [Authentication]
summary: User login
description: Authenticate user and receive JWT token via HTTP-only cookie
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/authentication.yaml#/LoginRequest'
application/x-www-form-urlencoded:
schema:
$ref: '../components/schemas/authentication.yaml#/LoginRequest'
responses:
'200':
description: Login successful
headers:
Set-Cookie:
description: JWT token in HTTP-only cookie
schema:
type: string
content:
application/json:
schema:
$ref: '../components/schemas/authentication.yaml#/LoginResponse'
'400':
description: Missing username
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/ErrorResponse'
'401':
description: Invalid credentials
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/ErrorResponse'
/api/auth/logout:
post:
tags: [Authentication]
summary: User logout
description: Clear JWT token cookie
security:
- bearerAuth: []
responses:
'200':
description: Logout successful
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'
/api/auth/check:
get:
tags: [Authentication]
summary: Check authentication status
security:
- bearerAuth: []
- cookieAuth: []
responses:
'200':
description: Authenticated
content:
application/json:
schema:
type: object
properties:
authenticated:
type: boolean
user:
type: object
'401':
description: Not authenticated
/api/auth/register:
post:
tags: [Authentication]
summary: Register new user
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/authentication.yaml#/RegisterRequest'
responses:
'201':
description: User created
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'
/api/auth/change_pass:
post:
tags: [Authentication]
summary: Change password
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- current_password
- new_password
properties:
current_password:
type: string
format: password
new_password:
type: string
format: password
responses:
'200':
description: Password changed successfully
/v2/auth/login:
post:
tags: [Authentication]
summary: V2 User login
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/authentication.yaml#/LoginRequest'
responses:
'200':
description: Login successful
content:
application/json:
schema:
$ref: '../components/schemas/authentication.yaml#/LoginResponse'
/v2/auth/logout:
post:
tags: [Authentication]
summary: V2 User logout
responses:
'200':
description: Logout successful
/v2/auth/check:
get:
tags: [Authentication]
summary: V2 Check authentication
responses:
'200':
description: Auth check result
/v2/auth/register:
post:
tags: [Authentication]
summary: V2 Register new user
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/authentication.yaml#/RegisterRequest'
responses:
'201':
description: User created

42
public/paths/demo.yaml Normal file
View File

@ -0,0 +1,42 @@
/api/demo/hello:
get:
tags: [Demo]
summary: Hello world endpoint
description: Simple test endpoint that returns a greeting message
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
example: Hello, World!
/api/demo/ping:
get:
tags: [Demo]
summary: Ping endpoint
description: Health check endpoint to verify API is running
responses:
'200':
description: API is running
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
example: pong
timestamp:
type: string
format: date-time

103
public/paths/edge-api.yaml Normal file
View File

@ -0,0 +1,103 @@
/api/edge/results:
post:
tags: [Edge API]
summary: Receive results from instrument (tiny-edge)
description: |
Receives instrument results and stores them in the edgeres table for processing.
This endpoint is typically called by the tiny-edge middleware connected to laboratory analyzers.
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/edge-api.yaml#/EdgeResultRequest'
responses:
'201':
description: Result received and queued
content:
application/json:
schema:
$ref: '../components/schemas/edge-api.yaml#/EdgeResultResponse'
'400':
description: Invalid JSON payload
/api/edge/orders:
get:
tags: [Edge API]
summary: Fetch pending orders for instruments
description: Returns orders that need to be sent to laboratory instruments for testing
parameters:
- name: instrument_id
in: query
schema:
type: string
description: Filter by instrument
- name: status
in: query
schema:
type: string
enum: [pending, acknowledged]
description: Filter by status
responses:
'200':
description: List of orders
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
type: array
items:
$ref: '../components/schemas/edge-api.yaml#/EdgeOrder'
/api/edge/orders/{orderId}/ack:
post:
tags: [Edge API]
summary: Acknowledge order delivery
description: Mark order as acknowledged by the instrument
parameters:
- name: orderId
in: path
required: true
schema:
type: integer
description: Edge order ID
responses:
'200':
description: Order acknowledged
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'
/api/edge/status:
post:
tags: [Edge API]
summary: Log instrument status update
description: Receive status updates from laboratory instruments
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- instrument_id
- status
properties:
instrument_id:
type: string
status:
type: string
enum: [online, offline, error, maintenance]
message:
type: string
timestamp:
type: string
format: date-time
responses:
'200':
description: Status logged

View File

@ -0,0 +1,59 @@
/api/location:
get:
tags: [Master Data]
summary: List locations
security:
- bearerAuth: []
parameters:
- name: LocCode
in: query
schema:
type: string
description: Filter by location code
- name: LocName
in: query
schema:
type: string
description: Filter by location name (searches in LocFull)
responses:
'200':
description: List of locations
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: array
items:
$ref: '../components/schemas/master-data.yaml#/Location'
post:
tags: [Master Data]
summary: Create location
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- LocCode
- LocFull
properties:
SiteID:
type: integer
LocCode:
type: string
maxLength: 6
Parent:
type: integer
LocFull:
type: string
maxLength: 255

150
public/paths/orders.yaml Normal file
View File

@ -0,0 +1,150 @@
/api/ordertest:
get:
tags: [Orders]
summary: List orders
security:
- bearerAuth: []
parameters:
- name: page
in: query
schema:
type: integer
- name: perPage
in: query
schema:
type: integer
- name: InternalPID
in: query
schema:
type: integer
description: Filter by internal patient ID
- name: OrderStatus
in: query
schema:
type: string
enum: [ORD, SCH, ANA, VER, REV, REP]
description: |
ORD: Ordered
SCH: Scheduled
ANA: Analysis
VER: Verified
REV: Reviewed
REP: Reported
responses:
'200':
description: List of orders
post:
tags: [Orders]
summary: Create order
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- PatientID
- Tests
properties:
PatientID:
type: string
VisitID:
type: string
Priority:
type: string
enum: [R, S, U]
description: |
R: Routine
S: Stat
U: Urgent
SiteID:
type: integer
RequestingPhysician:
type: string
Tests:
type: array
items:
type: object
properties:
TestID:
type: integer
SpecimenType:
type: string
responses:
'201':
description: Order created successfully
patch:
tags: [Orders]
summary: Update order
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/orders.yaml#/OrderTest'
responses:
'200':
description: Order updated
delete:
tags: [Orders]
summary: Delete order
security:
- bearerAuth: []
responses:
'200':
description: Order deleted
/api/ordertest/status:
post:
tags: [Orders]
summary: Update order status
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- OrderID
- OrderStatus
properties:
OrderID:
type: string
OrderStatus:
type: string
enum: [ORD, SCH, ANA, VER, REV, REP]
description: |
ORD: Ordered
SCH: Scheduled
ANA: Analysis
VER: Verified
REV: Reviewed
REP: Reported
responses:
'200':
description: Order status updated
/api/ordertest/{id}:
get:
tags: [Orders]
summary: Get order by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Order details

View File

@ -0,0 +1,367 @@
/api/organization/account/{id}:
get:
tags: [Organization]
summary: Get account by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Account details
content:
application/json:
schema:
$ref: '../components/schemas/organization.yaml#/Account'
/api/organization/site:
get:
tags: [Organization]
summary: List sites
security:
- bearerAuth: []
responses:
'200':
description: List of sites
post:
tags: [Organization]
summary: Create site
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/organization.yaml#/Site'
responses:
'201':
description: Site created
patch:
tags: [Organization]
summary: Update site
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
properties:
id:
type: integer
SiteName:
type: string
SiteCode:
type: string
AccountID:
type: integer
responses:
'200':
description: Site updated
delete:
tags: [Organization]
summary: Delete site
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
properties:
id:
type: integer
responses:
'200':
description: Site deleted
/api/organization/site/{id}:
get:
tags: [Organization]
summary: Get site by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Site details
/api/organization/discipline:
get:
tags: [Organization]
summary: List disciplines
security:
- bearerAuth: []
responses:
'200':
description: List of disciplines
post:
tags: [Organization]
summary: Create discipline
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/organization.yaml#/Discipline'
responses:
'201':
description: Discipline created
patch:
tags: [Organization]
summary: Update discipline
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
properties:
id:
type: integer
DisciplineName:
type: string
DisciplineCode:
type: string
responses:
'200':
description: Discipline updated
delete:
tags: [Organization]
summary: Delete discipline
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
properties:
id:
type: integer
responses:
'200':
description: Discipline deleted
/api/organization/discipline/{id}:
get:
tags: [Organization]
summary: Get discipline by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Discipline details
/api/organization/department:
get:
tags: [Organization]
summary: List departments
security:
- bearerAuth: []
responses:
'200':
description: List of departments
post:
tags: [Organization]
summary: Create department
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/organization.yaml#/Department'
responses:
'201':
description: Department created
patch:
tags: [Organization]
summary: Update department
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
properties:
id:
type: integer
DeptName:
type: string
DeptCode:
type: string
SiteID:
type: integer
responses:
'200':
description: Department updated
delete:
tags: [Organization]
summary: Delete department
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
properties:
id:
type: integer
responses:
'200':
description: Department deleted
/api/organization/department/{id}:
get:
tags: [Organization]
summary: Get department by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Department details
/api/organization/workstation:
get:
tags: [Organization]
summary: List workstations
security:
- bearerAuth: []
responses:
'200':
description: List of workstations
post:
tags: [Organization]
summary: Create workstation
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/organization.yaml#/Workstation'
responses:
'201':
description: Workstation created
patch:
tags: [Organization]
summary: Update workstation
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
properties:
id:
type: integer
WorkstationName:
type: string
WorkstationCode:
type: string
SiteID:
type: integer
DepartmentID:
type: integer
responses:
'200':
description: Workstation updated
delete:
tags: [Organization]
summary: Delete workstation
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
properties:
id:
type: integer
responses:
'200':
description: Workstation deleted
/api/organization/workstation/{id}:
get:
tags: [Organization]
summary: Get workstation by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Workstation details

View File

@ -0,0 +1,487 @@
/api/patvisit:
get:
tags: [Patient Visits]
summary: List patient visits
security:
- bearerAuth: []
parameters:
- name: page
in: query
schema:
type: integer
- name: perPage
in: query
schema:
type: integer
responses:
'200':
description: List of patient visits
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: array
items:
$ref: '../components/schemas/patient-visit.yaml#/PatientVisit'
total:
type: integer
description: Total number of records
page:
type: integer
description: Current page number
per_page:
type: integer
description: Number of records per page
post:
tags: [Patient Visits]
summary: Create patient visit
description: |
Creates a new patient visit. PVID is auto-generated with 'DV' prefix if not provided.
Can optionally include PatDiag (diagnosis) and PatVisitADT (ADT information).
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- InternalPID
properties:
PVID:
type: string
description: Visit ID (auto-generated with DV prefix if not provided)
InternalPID:
type: integer
description: Patient ID (required)
EpisodeID:
type: string
description: Episode identifier
SiteID:
type: integer
description: Site reference
PatDiag:
type: object
description: Optional diagnosis information
properties:
DiagCode:
type: string
Diagnosis:
type: string
PatVisitADT:
type: object
description: Optional ADT information
properties:
ADTCode:
type: string
enum: [A01, A02, A03, A04, A08]
LocationID:
type: integer
AttDoc:
type: integer
RefDoc:
type: integer
AdmDoc:
type: integer
CnsDoc:
type: integer
responses:
'201':
description: Visit created successfully
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: object
properties:
PVID:
type: string
InternalPVID:
type: integer
patch:
tags: [Patient Visits]
summary: Update patient visit
description: |
Updates an existing patient visit. InternalPVID is required.
Can update main visit data, PatDiag, and add new PatVisitADT records.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- InternalPVID
properties:
InternalPVID:
type: integer
description: Visit ID (required)
PVID:
type: string
InternalPID:
type: integer
EpisodeID:
type: string
SiteID:
type: integer
PatDiag:
type: object
description: Diagnosis information (will update if exists)
properties:
DiagCode:
type: string
Diagnosis:
type: string
PatVisitADT:
type: array
description: Array of ADT records to add (new records only)
items:
type: object
properties:
ADTCode:
type: string
enum: [A01, A02, A03, A04, A08]
LocationID:
type: integer
AttDoc:
type: integer
RefDoc:
type: integer
AdmDoc:
type: integer
CnsDoc:
type: integer
sequence:
type: integer
description: Used for ordering multiple ADT records
responses:
'200':
description: Visit updated successfully
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
type: object
properties:
PVID:
type: string
InternalPVID:
type: integer
delete:
tags: [Patient Visits]
summary: Delete patient visit
security:
- bearerAuth: []
responses:
'200':
description: Visit deleted successfully
/api/patvisit/{id}:
get:
tags: [Patient Visits]
summary: Get visit by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
description: PVID (visit identifier like DV00001)
responses:
'200':
description: Visit details
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
$ref: '../components/schemas/patient-visit.yaml#/PatientVisit'
/api/patvisit/patient/{patientId}:
get:
tags: [Patient Visits]
summary: Get visits by patient ID
security:
- bearerAuth: []
parameters:
- name: patientId
in: path
required: true
schema:
type: integer
description: Internal Patient ID (InternalPID)
responses:
'200':
description: Patient visits list
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
type: array
items:
$ref: '../components/schemas/patient-visit.yaml#/PatientVisit'
/api/patvisitadt:
post:
tags: [Patient Visits]
summary: Create ADT record
description: Create a new Admission/Discharge/Transfer record
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/patient-visit.yaml#/PatVisitADT'
responses:
'201':
description: ADT record created successfully
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'
patch:
tags: [Patient Visits]
summary: Update ADT record
description: Update an existing ADT record
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/patient-visit.yaml#/PatVisitADT'
responses:
'200':
description: ADT record updated successfully
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'
delete:
tags: [Patient Visits]
summary: Delete ADT visit (soft delete)
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- PVADTID
properties:
PVADTID:
type: integer
description: ADT record ID to delete
responses:
'200':
description: ADT visit deleted successfully
/api/patvisitadt/visit/{visitId}:
get:
tags: [Patient Visits]
summary: Get ADT history by visit ID
description: Retrieve the complete Admission/Discharge/Transfer history for a visit, including all locations and doctors
security:
- bearerAuth: []
parameters:
- name: visitId
in: path
required: true
schema:
type: integer
description: Internal Visit ID (InternalPVID)
responses:
'200':
description: ADT history retrieved successfully
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
example: ADT history retrieved
data:
type: array
items:
type: object
properties:
PVADTID:
type: integer
InternalPVID:
type: integer
ADTCode:
type: string
enum: [A01, A02, A03, A04, A08]
LocationID:
type: integer
LocationName:
type: string
AttDoc:
type: integer
AttDocFirstName:
type: string
AttDocLastName:
type: string
RefDoc:
type: integer
RefDocFirstName:
type: string
RefDocLastName:
type: string
AdmDoc:
type: integer
AdmDocFirstName:
type: string
AdmDocLastName:
type: string
CnsDoc:
type: integer
CnsDocFirstName:
type: string
CnsDocLastName:
type: string
CreateDate:
type: string
format: date-time
EndDate:
type: string
format: date-time
delete:
tags: [Patient Visits]
summary: Delete ADT visit (soft delete)
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- PVADTID
properties:
PVADTID:
type: integer
description: ADT record ID to delete
responses:
'200':
description: ADT visit deleted successfully
/api/patvisitadt/{id}:
get:
tags: [Patient Visits]
summary: Get ADT record by ID
description: Retrieve a single ADT record by its ID, including location and doctor details
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
description: ADT record ID (PVADTID)
responses:
'200':
description: ADT record retrieved successfully
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
example: ADT record retrieved
data:
type: object
properties:
PVADTID:
type: integer
InternalPVID:
type: integer
ADTCode:
type: string
enum: [A01, A02, A03, A04, A08]
LocationID:
type: integer
LocationName:
type: string
AttDoc:
type: integer
AttDocFirstName:
type: string
AttDocLastName:
type: string
RefDoc:
type: integer
RefDocFirstName:
type: string
RefDocLastName:
type: string
AdmDoc:
type: integer
AdmDocFirstName:
type: string
AdmDocLastName:
type: string
CnsDoc:
type: integer
CnsDocFirstName:
type: string
CnsDocLastName:
type: string
CreateDate:
type: string
format: date-time
EndDate:
type: string
format: date-time

163
public/paths/patients.yaml Normal file
View File

@ -0,0 +1,163 @@
/api/patient:
get:
tags: [Patients]
summary: List patients
security:
- bearerAuth: []
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: perPage
in: query
schema:
type: integer
default: 20
- name: InternalPID
in: query
schema:
type: integer
description: Filter by internal patient ID
- name: PatientID
in: query
schema:
type: string
description: Filter by patient ID
- name: Name
in: query
schema:
type: string
description: Search by patient name
- name: Birthdate
in: query
schema:
type: string
format: date
description: Filter by birthdate (YYYY-MM-DD)
responses:
'200':
description: List of patients
content:
application/json:
schema:
$ref: '../components/schemas/patient.yaml#/PatientListResponse'
post:
tags: [Patients]
summary: Create new patient
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/patient.yaml#/Patient'
responses:
'201':
description: Patient created successfully
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'
'422':
description: Validation error
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/ErrorResponse'
patch:
tags: [Patients]
summary: Update patient
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/patient.yaml#/Patient'
responses:
'200':
description: Patient updated successfully
delete:
tags: [Patients]
summary: Delete patient (soft delete)
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- InternalPID
properties:
InternalPID:
type: integer
description: Internal patient record ID
responses:
'200':
description: Patient deleted successfully
/api/patient/check:
get:
tags: [Patients]
summary: Check if patient exists
security:
- bearerAuth: []
parameters:
- name: PatientID
in: query
schema:
type: string
description: Patient ID to check
- name: EmailAddress1
in: query
schema:
type: string
format: email
description: Email address to check
responses:
'200':
description: Patient check result
content:
application/json:
schema:
type: object
properties:
exists:
type: boolean
data:
$ref: '../components/schemas/patient.yaml#/Patient'
/api/patient/{id}:
get:
tags: [Patients]
summary: Get patient by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
description: Internal patient record ID
responses:
'200':
description: Patient details
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
$ref: '../components/schemas/patient.yaml#/Patient'

263
public/paths/results.yaml Normal file
View File

@ -0,0 +1,263 @@
/api/results:
get:
tags: [Results]
summary: Get patient results
description: Retrieve patient test results with optional filters
security:
- bearerAuth: []
parameters:
- name: InternalPID
in: query
schema:
type: integer
description: Filter by internal patient ID
- name: OrderID
in: query
schema:
type: string
description: Filter by order ID
- name: TestCode
in: query
schema:
type: string
description: Filter by test code
- name: date_from
in: query
schema:
type: string
format: date
description: Filter results from date (YYYY-MM-DD)
- name: date_to
in: query
schema:
type: string
format: date
description: Filter results to date (YYYY-MM-DD)
- name: verified_only
in: query
schema:
type: boolean
default: false
description: Return only verified results
responses:
'200':
description: List of patient results
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
type: array
items:
type: object
properties:
ResultID:
type: integer
InternalPID:
type: integer
OrderID:
type: string
TestID:
type: integer
TestCode:
type: string
TestName:
type: string
ResultValue:
type: string
Unit:
type: string
ReferenceRange:
type: string
AbnormalFlag:
type: string
Verified:
type: boolean
VerifiedBy:
type: string
VerifiedDate:
type: string
format: date-time
ResultDate:
type: string
format: date-time
post:
tags: [Results]
summary: Create or update result
description: Create a new result or update an existing result entry
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- InternalPID
- TestID
- ResultValue
properties:
InternalPID:
type: integer
OrderID:
type: string
TestID:
type: integer
ResultValue:
type: string
Unit:
type: string
AbnormalFlag:
type: string
enum: [H, L, N, A, C]
description: H=High, L=Low, N=Normal, A=Abnormal, C=Critical
responses:
'201':
description: Result created successfully
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'
/api/results/{id}:
get:
tags: [Results]
summary: Get result by ID
description: Retrieve a specific result entry by its ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
description: Result ID
responses:
'200':
description: Result details
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
type: object
properties:
ResultID:
type: integer
InternalPID:
type: integer
OrderID:
type: string
TestID:
type: integer
TestCode:
type: string
TestName:
type: string
ResultValue:
type: string
Unit:
type: string
ReferenceRange:
type: string
AbnormalFlag:
type: string
Verified:
type: boolean
VerifiedBy:
type: string
VerifiedDate:
type: string
format: date-time
ResultDate:
type: string
format: date-time
patch:
tags: [Results]
summary: Update result
description: Update an existing result entry
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
description: Result ID
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
ResultValue:
type: string
Unit:
type: string
AbnormalFlag:
type: string
enum: [H, L, N, A, C]
Verified:
type: boolean
responses:
'200':
description: Result updated successfully
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'
delete:
tags: [Results]
summary: Delete result
description: Soft delete a result entry
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
description: Result ID
responses:
'200':
description: Result deleted successfully
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'
/api/results/{id}/verify:
post:
tags: [Results]
summary: Verify result
description: Mark a result as verified by the current user
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
description: Result ID
responses:
'200':
description: Result verified successfully
content:
application/json:
schema:
$ref: '../components/schemas/common.yaml#/SuccessResponse'

289
public/paths/specimen.yaml Normal file
View File

@ -0,0 +1,289 @@
/api/specimen:
get:
tags: [Specimen]
summary: List specimens
security:
- bearerAuth: []
responses:
'200':
description: List of specimens
post:
tags: [Specimen]
summary: Create specimen
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/specimen.yaml#/Specimen'
responses:
'201':
description: Specimen created
patch:
tags: [Specimen]
summary: Update specimen
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/specimen.yaml#/Specimen'
responses:
'200':
description: Specimen updated
/api/specimen/{id}:
get:
tags: [Specimen]
summary: Get specimen by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Specimen details
/api/specimen/container:
get:
tags: [Specimen]
summary: List container definitions
security:
- bearerAuth: []
responses:
'200':
description: List of container definitions
post:
tags: [Specimen]
summary: Create container definition
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/specimen.yaml#/ContainerDef'
responses:
'201':
description: Container definition created
patch:
tags: [Specimen]
summary: Update container definition
security:
- bearerAuth: []
responses:
'200':
description: Container definition updated
/api/specimen/container/{id}:
get:
tags: [Specimen]
summary: Get container definition by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Container definition details
/api/specimen/containerdef:
get:
tags: [Specimen]
summary: List container definitions (alias)
security:
- bearerAuth: []
responses:
'200':
description: List of container definitions
post:
tags: [Specimen]
summary: Create container definition (alias)
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/specimen.yaml#/ContainerDef'
responses:
'201':
description: Container definition created
patch:
tags: [Specimen]
summary: Update container definition (alias)
security:
- bearerAuth: []
responses:
'200':
description: Container definition updated
/api/specimen/prep:
get:
tags: [Specimen]
summary: List specimen preparations
security:
- bearerAuth: []
responses:
'200':
description: List of specimen preparations
post:
tags: [Specimen]
summary: Create specimen preparation
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/specimen.yaml#/SpecimenPrep'
responses:
'201':
description: Specimen preparation created
patch:
tags: [Specimen]
summary: Update specimen preparation
security:
- bearerAuth: []
responses:
'200':
description: Specimen preparation updated
/api/specimen/prep/{id}:
get:
tags: [Specimen]
summary: Get specimen preparation by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Specimen preparation details
/api/specimen/status:
get:
tags: [Specimen]
summary: List specimen statuses
security:
- bearerAuth: []
responses:
'200':
description: List of specimen statuses
post:
tags: [Specimen]
summary: Create specimen status
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/specimen.yaml#/SpecimenStatus'
responses:
'201':
description: Specimen status created
patch:
tags: [Specimen]
summary: Update specimen status
security:
- bearerAuth: []
responses:
'200':
description: Specimen status updated
/api/specimen/status/{id}:
get:
tags: [Specimen]
summary: Get specimen status by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Specimen status details
/api/specimen/collection:
get:
tags: [Specimen]
summary: List specimen collection methods
security:
- bearerAuth: []
responses:
'200':
description: List of collection methods
post:
tags: [Specimen]
summary: Create specimen collection method
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/specimen.yaml#/SpecimenCollection'
responses:
'201':
description: Collection method created
patch:
tags: [Specimen]
summary: Update specimen collection method
security:
- bearerAuth: []
responses:
'200':
description: Collection method updated
/api/specimen/collection/{id}:
get:
tags: [Specimen]
summary: Get specimen collection method by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Collection method details

113
public/paths/tests.yaml Normal file
View File

@ -0,0 +1,113 @@
/api/tests:
get:
tags: [Tests]
summary: List test definitions
security:
- bearerAuth: []
parameters:
- name: page
in: query
schema:
type: integer
default: 1
description: Page number for pagination
- name: perPage
in: query
schema:
type: integer
default: 20
description: Number of items per page
- name: SiteID
in: query
schema:
type: integer
description: Filter by site ID
- name: TestType
in: query
schema:
type: string
enum: [TEST, PARAM, CALC, GROUP, TITLE]
description: Filter by test type
- name: VisibleScr
in: query
schema:
type: integer
enum: [0, 1]
description: Filter by screen visibility (0=hidden, 1=visible)
- name: VisibleRpt
in: query
schema:
type: integer
enum: [0, 1]
description: Filter by report visibility (0=hidden, 1=visible)
- name: search
in: query
schema:
type: string
description: Search by test code or name
responses:
'200':
description: List of test definitions
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
type: array
items:
$ref: '../components/schemas/tests.yaml#/TestDefinition'
pagination:
type: object
properties:
total:
type: integer
description: Total number of records matching the query
post:
tags: [Tests]
summary: Create test definition
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/tests.yaml#/TestDefinition'
responses:
'201':
description: Test definition created
patch:
tags: [Tests]
summary: Update test definition
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas/tests.yaml#/TestDefinition'
responses:
'200':
description: Test definition updated
/api/tests/{id}:
get:
tags: [Tests]
summary: Get test definition by ID
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Test definition details

498
public/paths/valuesets.yaml Normal file
View File

@ -0,0 +1,498 @@
/api/valueset:
get:
tags: [ValueSets]
summary: List lib value sets
description: List all library/system value sets from JSON files with item counts. Returns an object where keys are value set names and values are item counts.
security:
- bearerAuth: []
parameters:
- name: search
in: query
schema:
type: string
description: Optional search term to filter value set names
responses:
'200':
description: List of lib value sets with item counts
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
data:
type: object
additionalProperties:
type: integer
description: Number of items in each value set
example:
sex: 3
marital_status: 6
order_status: 6
/api/valueset/{key}:
get:
tags: [ValueSets]
summary: Get lib value set by key
description: |
Get a specific library/system value set from JSON files.
**Available value set keys:**
- `activity_result` - Activity Result
- `additive` - Additive
- `adt_event` - ADT Event
- `area_class` - Area Class
- `body_site` - Body Site
- `collection_method` - Collection Method
- `container_cap_color` - Container Cap Color
- `container_class` - Container Class
- `container_size` - Container Size
- `country` - Country
- `death_indicator` - Death Indicator
- `did_type` - DID Type
- `enable_disable` - Enable/Disable
- `entity_type` - Entity Type
- `ethnic` - Ethnic
- `fasting_status` - Fasting Status
- `formula_language` - Formula Language
- `generate_by` - Generate By
- `identifier_type` - Identifier Type
- `location_type` - Location Type
- `marital_status` - Marital Status
- `math_sign` - Math Sign
- `numeric_ref_type` - Numeric Reference Type
- `operation` - Operation (CRUD)
- `order_priority` - Order Priority
- `order_status` - Order Status
- `race` - Race (Ethnicity)
- `range_type` - Range Type
- `reference_type` - Reference Type
- `religion` - Religion
- `requested_entity` - Requested Entity
- `result_type` - Result Type
- `result_unit` - Result Unit
- `sex` - Sex
- `site_class` - Site Class
- `site_type` - Site Type
- `specimen_activity` - Specimen Activity
- `specimen_condition` - Specimen Condition
- `specimen_role` - Specimen Role
- `specimen_status` - Specimen Status
- `specimen_type` - Specimen Type
- `test_activity` - Test Activity
- `test_type` - Test Type
- `text_ref_type` - Text Reference Type
- `unit` - Unit
- `v_category` - VCategory
- `ws_type` - Workstation Type
security:
- bearerAuth: []
parameters:
- name: key
in: path
required: true
schema:
type: string
enum: [activity_result, additive, adt_event, area_class, body_site, collection_method, container_cap_color, container_class, container_size, country, death_indicator, did_type, enable_disable, entity_type, ethnic, fasting_status, formula_language, generate_by, identifier_type, location_type, marital_status, math_sign, numeric_ref_type, operation, order_priority, order_status, race, range_type, reference_type, religion, requested_entity, result_type, result_unit, sex, site_class, site_type, specimen_activity, specimen_condition, specimen_role, specimen_status, specimen_type, test_activity, test_type, text_ref_type, unit, v_category, ws_type]
description: Value set key name
responses:
'200':
description: Lib value set details
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
type: array
items:
$ref: '../components/schemas/valuesets.yaml#/ValueSetLibItem'
/api/valueset/refresh:
post:
tags: [ValueSets]
summary: Refresh lib ValueSet cache
description: Clear and reload the library/system ValueSet cache from JSON files. Call this after modifying JSON files in app/Libraries/Data/.
security:
- bearerAuth: []
responses:
'200':
description: Lib ValueSet cache refreshed
content:
application/json:
schema:
type: object
properties:
status:
type: string
example: success
message:
type: string
example: Cache cleared
/api/valueset/user/items:
get:
tags: [ValueSets]
summary: List user value set items
description: List value set items from database (user-defined)
security:
- bearerAuth: []
parameters:
- name: VSetID
in: query
schema:
type: integer
description: Filter by ValueSet ID
- name: search
in: query
schema:
type: string
description: Search term to filter by VValue, VDesc, or VSName
- name: param
in: query
schema:
type: string
description: Alternative search parameter (alias for search)
responses:
'200':
description: List of user value set items
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
type: array
items:
$ref: '../components/schemas/valuesets.yaml#/ValueSetItem'
post:
tags: [ValueSets]
summary: Create user value set item
description: Create value set item in database (user-defined)
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- VSetID
properties:
SiteID:
type: integer
description: Site reference (default 1)
VSetID:
type: integer
description: Reference to value set definition (required)
VOrder:
type: integer
description: Display order (default 0)
VValue:
type: string
description: The value code
VDesc:
type: string
description: The display description/label
responses:
'201':
description: User value set item created
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
$ref: '../components/schemas/valuesets.yaml#/ValueSetItem'
/api/valueset/user/items/{id}:
get:
tags: [ValueSets]
summary: Get user value set item by ID
description: Get value set item from database (user-defined)
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: User value set item details
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
$ref: '../components/schemas/valuesets.yaml#/ValueSetItem'
put:
tags: [ValueSets]
summary: Update user value set item
description: Update value set item in database (user-defined)
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
SiteID:
type: integer
description: Site reference
VSetID:
type: integer
description: Reference to value set definition
VOrder:
type: integer
description: Display order
VValue:
type: string
description: The value code
VDesc:
type: string
description: The display description/label
responses:
'200':
description: User value set item updated
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
$ref: '../components/schemas/valuesets.yaml#/ValueSetItem'
delete:
tags: [ValueSets]
summary: Delete user value set item
description: Delete value set item from database (user-defined)
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: User value set item deleted
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
/api/valueset/user/def:
get:
tags: [ValueSets]
summary: List user value set definitions
description: List value set definitions from database (user-defined)
security:
- bearerAuth: []
parameters:
- name: search
in: query
schema:
type: string
description: Optional search term to filter definitions
- name: page
in: query
schema:
type: integer
default: 1
description: Page number for pagination
- name: limit
in: query
schema:
type: integer
default: 100
description: Number of items per page
responses:
'200':
description: List of user value set definitions
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
type: array
items:
$ref: '../components/schemas/valuesets.yaml#/ValueSetDef'
meta:
type: object
properties:
total:
type: integer
page:
type: integer
limit:
type: integer
post:
tags: [ValueSets]
summary: Create user value set definition
description: Create value set definition in database (user-defined)
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
SiteID:
type: integer
description: Site reference (default 1)
VSName:
type: string
description: Value set name
VSDesc:
type: string
description: Value set description
responses:
'201':
description: User value set definition created
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
$ref: '../components/schemas/valuesets.yaml#/ValueSetDef'
/api/valueset/user/def/{id}:
get:
tags: [ValueSets]
summary: Get user value set definition by ID
description: Get value set definition from database (user-defined)
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: User value set definition details
content:
application/json:
schema:
type: object
properties:
status:
type: string
data:
$ref: '../components/schemas/valuesets.yaml#/ValueSetDef'
put:
tags: [ValueSets]
summary: Update user value set definition
description: Update value set definition in database (user-defined)
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
SiteID:
type: integer
description: Site reference
VSName:
type: string
description: Value set name
VSDesc:
type: string
description: Value set description
responses:
'200':
description: User value set definition updated
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string
data:
$ref: '../components/schemas/valuesets.yaml#/ValueSetDef'
delete:
tags: [ValueSets]
summary: Delete user value set definition
description: Delete value set definition from database (user-defined)
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: User value set definition deleted
content:
application/json:
schema:
type: object
properties:
status:
type: string
message:
type: string