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:
parent
8c44cc84a2
commit
fcaf9b74ea
@ -24,6 +24,9 @@ $routes->group('api', ['filter' => 'auth'], function ($routes) {
|
|||||||
// Swagger API Documentation (public - no filters)
|
// Swagger API Documentation (public - no filters)
|
||||||
$routes->add('swagger', 'PagesController::swagger');
|
$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)
|
// V2 Auth API Routes (public - no auth required)
|
||||||
$routes->group('v2/auth', function ($routes) {
|
$routes->group('v2/auth', function ($routes) {
|
||||||
$routes->post('login', 'AuthV2Controller::login');
|
$routes->post('login', 'AuthV2Controller::login');
|
||||||
|
|||||||
43
app/Controllers/OpenApiDocs.php
Normal file
43
app/Controllers/OpenApiDocs.php
Normal 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()
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -32,7 +32,7 @@ class TestDefSiteModel extends BaseModel {
|
|||||||
protected $useSoftDeletes = true;
|
protected $useSoftDeletes = true;
|
||||||
protected $deletedField = "EndDate";
|
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,
|
$builder = $this->select("testdefsite.TestSiteID, testdefsite.TestSiteCode, testdefsite.TestSiteName, testdefsite.TestType,
|
||||||
testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.VisibleScr, testdefsite.VisibleRpt,
|
testdefsite.SeqScr, testdefsite.SeqRpt, testdefsite.VisibleScr, testdefsite.VisibleRpt,
|
||||||
testdefsite.CountStat, testdefsite.StartDate, testdefsite.EndDate")
|
testdefsite.CountStat, testdefsite.StartDate, testdefsite.EndDate")
|
||||||
@ -54,15 +54,33 @@ class TestDefSiteModel extends BaseModel {
|
|||||||
$builder->where('testdefsite.VisibleRpt', $visibleRpt);
|
$builder->where('testdefsite.VisibleRpt', $visibleRpt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($keyword) {
|
if ($search) {
|
||||||
$builder->like('testdefsite.TestSiteName', $keyword);
|
$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, [
|
$rows = ValueSet::transformLabels($rows, [
|
||||||
'TestType' => 'test_type',
|
'TestType' => 'test_type',
|
||||||
]);
|
]);
|
||||||
return $rows;
|
|
||||||
|
return [
|
||||||
|
'data' => $rows,
|
||||||
|
'pagination' => [
|
||||||
|
'total' => $total
|
||||||
|
]
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTest($TestSiteID) {
|
public function getTest($TestSiteID) {
|
||||||
|
|||||||
@ -357,7 +357,7 @@
|
|||||||
|
|
||||||
// Initialize Swagger UI
|
// Initialize Swagger UI
|
||||||
const ui = SwaggerUIBundle({
|
const ui = SwaggerUIBundle({
|
||||||
url: "<?= base_url('api-docs.yaml') ?>?v=<?= time() ?>",
|
url: "<?= base_url('api-docs') ?>?v=<?= time() ?>",
|
||||||
dom_id: '#swagger-ui',
|
dom_id: '#swagger-ui',
|
||||||
deepLinking: true,
|
deepLinking: true,
|
||||||
presets: [
|
presets: [
|
||||||
|
|||||||
162
public/API_DOCS_README.md
Normal file
162
public/API_DOCS_README.md
Normal 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
4124
public/api-docs.bundled.yaml
Normal file
File diff suppressed because it is too large
Load Diff
4528
public/api-docs.yaml
4528
public/api-docs.yaml
File diff suppressed because it is too large
Load Diff
96
public/bundle-api-docs.js
Normal file
96
public/bundle-api-docs.js
Normal 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);
|
||||||
|
}
|
||||||
55
public/bundle-api-docs.php
Normal file
55
public/bundle-api-docs.php
Normal 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
97
public/bundle-api-docs.py
Normal 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}")
|
||||||
44
public/components/schemas/authentication.yaml
Normal file
44
public/components/schemas/authentication.yaml
Normal 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
|
||||||
34
public/components/schemas/common.yaml
Normal file
34
public/components/schemas/common.yaml
Normal 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
|
||||||
75
public/components/schemas/edge-api.yaml
Normal file
75
public/components/schemas/edge-api.yaml
Normal 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
|
||||||
157
public/components/schemas/master-data.yaml
Normal file
157
public/components/schemas/master-data.yaml
Normal 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
|
||||||
53
public/components/schemas/orders.yaml
Normal file
53
public/components/schemas/orders.yaml
Normal 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
|
||||||
59
public/components/schemas/organization.yaml
Normal file
59
public/components/schemas/organization.yaml
Normal 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
|
||||||
105
public/components/schemas/patient-visit.yaml
Normal file
105
public/components/schemas/patient-visit.yaml
Normal 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
|
||||||
205
public/components/schemas/patient.yaml
Normal file
205
public/components/schemas/patient.yaml
Normal 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
|
||||||
10
public/components/schemas/securitySchemes.yaml
Normal file
10
public/components/schemas/securitySchemes.yaml
Normal 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
|
||||||
132
public/components/schemas/specimen.yaml
Normal file
132
public/components/schemas/specimen.yaml
Normal 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
|
||||||
278
public/components/schemas/tests.yaml
Normal file
278
public/components/schemas/tests.yaml
Normal 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
|
||||||
77
public/components/schemas/valuesets.yaml
Normal file
77
public/components/schemas/valuesets.yaml
Normal 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)
|
||||||
167
public/paths/authentication.yaml
Normal file
167
public/paths/authentication.yaml
Normal 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
42
public/paths/demo.yaml
Normal 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
103
public/paths/edge-api.yaml
Normal 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
|
||||||
59
public/paths/master-data.yaml
Normal file
59
public/paths/master-data.yaml
Normal 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
150
public/paths/orders.yaml
Normal 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
|
||||||
367
public/paths/organization.yaml
Normal file
367
public/paths/organization.yaml
Normal 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
|
||||||
487
public/paths/patient-visits.yaml
Normal file
487
public/paths/patient-visits.yaml
Normal 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
163
public/paths/patients.yaml
Normal 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
263
public/paths/results.yaml
Normal 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
289
public/paths/specimen.yaml
Normal 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
113
public/paths/tests.yaml
Normal 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
498
public/paths/valuesets.yaml
Normal 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
|
||||||
Loading…
x
Reference in New Issue
Block a user