diff --git a/docs/api-docs.yaml b/docs/api-docs.yaml
index 320a8f1..025d4af 100644
--- a/docs/api-docs.yaml
+++ b/docs/api-docs.yaml
@@ -327,25 +327,109 @@ components:
PatientVisit:
type: object
properties:
- VisitID:
+ InternalPVID:
+ type: integer
+ description: Primary key (auto-generated)
+ PVID:
type: string
- PatientID:
- type: string
- VisitDate:
- type: string
- format: date-time
- VisitType:
+ 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 (for standalone ADT operations)
+ 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
- DepartmentID:
+ description: Location/ward reference
+ AttDoc:
type: integer
- AttendingPhysician:
+ 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
- ReferringPhysician:
+ format: date-time
+ EndDate:
type: string
+ format: date-time
+ ArchivedDate:
+ type: string
+ format: date-time
+ DelDate:
+ type: string
+ format: date-time
# Organization
Account:
@@ -617,13 +701,24 @@ components:
format: date-time
OrderStatus:
type: string
- description: Order status code
+ 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
- description: Priority code
+ enum: [R, S, U]
+ description: |
+ R: Routine
+ S: Stat
+ U: Urgent
PriorityLabel:
type: string
description: Priority display text
@@ -758,78 +853,160 @@ components:
Location:
type: object
properties:
- id:
+ LocationID:
type: integer
- LocationCode:
- type: string
- LocationName:
- type: string
- LocationType:
- type: string
+ 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:
- id:
+ ContactID:
type: integer
- ContactName:
+ description: Primary key
+ NameFirst:
type: string
- ContactType:
+ 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
- Email:
+ description: Primary phone number
+ MobilePhone1:
type: string
- Address:
+ description: Primary mobile number
+ MobilePhone2:
type: string
+ description: Secondary mobile number
Specialty:
type: string
- description: Specialty code
- SpecialtyLabel:
+ description: Medical specialty code
+ SubSpecialty:
type: string
- description: Specialty display text
- Occupation:
+ description: Sub-specialty code
+ CreateDate:
type: string
- description: Occupation code
- OccupationLabel:
+ format: date-time
+ EndDate:
type: string
+ format: date-time
description: Occupation display text
Occupation:
type: object
properties:
- id:
+ OccupationID:
type: integer
- OccupationCode:
+ description: Primary key
+ OccCode:
type: string
- OccupationName:
+ 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:
- id:
+ SpecialtyID:
type: integer
- SpecialtyCode:
+ description: Primary key
+ SpecialtyText:
type: string
- SpecialtyName:
+ 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:
- id:
+ CounterID:
type: integer
- CounterName:
+ description: Primary key
+ CounterDesc:
type: string
- Prefix:
+ 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
- CurrentValue:
- type: integer
- SiteID:
- type: integer
+ description: Reset pattern (e.g., D=Daily, M=Monthly, Y=Yearly)
+ CreateDate:
+ type: string
+ format: date-time
+ EndDate:
+ type: string
+ format: date-time
# Dashboard
DashboardSummary:
@@ -1039,11 +1216,27 @@ paths:
schema:
type: integer
default: 20
- - name: search
+ - name: InternalPID
+ in: query
+ schema:
+ type: integer
+ description: Filter by internal patient ID
+ - name: PatientID
in: query
schema:
type: string
- description: Search by PatientID or name
+ 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
@@ -1094,15 +1287,21 @@ paths:
delete:
tags: [Patients]
- summary: Delete patient
+ summary: Delete patient (soft delete)
security:
- bearerAuth: []
- parameters:
- - name: PatientID
- in: query
- required: true
- schema:
- type: string
+ 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
@@ -1116,9 +1315,15 @@ paths:
parameters:
- name: PatientID
in: query
- required: true
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
@@ -1194,6 +1399,9 @@ paths:
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:
@@ -1201,14 +1409,73 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/PatientVisit'
+ 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:
@@ -1216,10 +1483,70 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/PatientVisit'
+ 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]
@@ -1242,9 +1569,21 @@ paths:
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/PatientVisit'
/api/patvisit/patient/{patientId}:
get:
@@ -1257,10 +1596,22 @@ paths:
in: path
required: true
schema:
- type: string
+ 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/PatientVisit'
/api/patvisitadt:
post:
@@ -1274,12 +1625,14 @@ paths:
application/json:
schema:
type: object
+ required:
+ - InternalPVID
+ - ADTCode
properties:
- PatientID:
- type: string
- VisitType:
- type: string
- ADTEvent:
+ InternalPVID:
+ type: integer
+ description: Internal Visit ID from patvisit table (required)
+ ADTCode:
type: string
enum: [A01, A02, A03, A04, A08]
description: |
@@ -1288,9 +1641,38 @@ paths:
A03: Discharge
A04: Register
A08: Update
+ LocationID:
+ type: integer
+ description: Location/ward ID
+ 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
responses:
'201':
description: ADT visit created
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ type: object
+ properties:
+ PVADTID:
+ type: integer
patch:
tags: [Patient Visits]
@@ -1302,10 +1684,54 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/PatientVisit'
+ type: object
+ required:
+ - PVADTID
+ properties:
+ PVADTID:
+ type: integer
+ description: ADT record ID (required)
+ InternalPVID:
+ type: integer
+ description: Internal Visit ID from patvisit table
+ 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 ID
+ 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
responses:
'200':
description: ADT visit updated
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ type: object
# ========================================
# Organization - Account Routes
@@ -1356,7 +1782,18 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/Account'
+ type: object
+ required:
+ - id
+ properties:
+ id:
+ type: integer
+ AccountName:
+ type: string
+ AccountCode:
+ type: string
+ AccountType:
+ type: string
responses:
'200':
description: Account updated
@@ -1366,6 +1803,17 @@ paths:
summary: Delete account
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - id
+ properties:
+ id:
+ type: integer
responses:
'200':
description: Account deleted
@@ -1424,7 +1872,18 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/Site'
+ type: object
+ required:
+ - id
+ properties:
+ id:
+ type: integer
+ SiteName:
+ type: string
+ SiteCode:
+ type: string
+ AccountID:
+ type: integer
responses:
'200':
description: Site updated
@@ -1434,6 +1893,17 @@ paths:
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
@@ -1487,6 +1957,21 @@ paths:
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
@@ -1496,6 +1981,17 @@ paths:
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
@@ -1549,6 +2045,23 @@ paths:
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
@@ -1558,6 +2071,17 @@ paths:
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
@@ -1611,6 +2135,25 @@ paths:
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
@@ -1620,6 +2163,17 @@ paths:
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
@@ -1673,6 +2227,12 @@ paths:
summary: Update specimen
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Specimen'
responses:
'200':
description: Specimen updated
@@ -1743,6 +2303,41 @@ paths:
'200':
description: Container definition details
+ # ContainerDef aliases (same as /api/specimen/container)
+ /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/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]
@@ -1911,12 +2506,34 @@ paths:
in: query
schema:
type: integer
+ - 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: TestSiteName
+ in: query
+ schema:
+ type: string
+ description: Search by test name or code
responses:
'200':
description: List of test definitions
@@ -1992,15 +2609,27 @@ paths:
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: [pending, in-progress, completed, cancelled]
- - name: PatientID
- 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
@@ -2026,7 +2655,11 @@ paths:
type: string
Priority:
type: string
- enum: [routine, stat, urgent]
+ enum: [R, S, U]
+ description: |
+ R: Routine
+ S: Stat
+ U: Urgent
SiteID:
type: integer
RequestingPhysician:
@@ -2088,7 +2721,14 @@ paths:
type: string
OrderStatus:
type: string
- enum: [pending, in-progress, completed, cancelled]
+ 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
@@ -2222,18 +2862,49 @@ paths:
/api/valueset:
get:
tags: [ValueSets]
- summary: List value set definitions
+ summary: List lib value sets
+ description: List all library/system value sets from JSON files
security:
- bearerAuth: []
parameters:
- - name: VSetCode
- in: path
- description: Optional value set code to get specific valueset
+ - name: search
+ in: query
schema:
type: string
+ description: Optional search term to filter value sets
responses:
'200':
- description: List of value sets
+ description: List of lib value sets with item counts
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ data:
+ type: object
+ additionalProperties:
+ type: integer
+ description: Number of items in each value set
+
+ /api/valueset/{key}:
+ get:
+ tags: [ValueSets]
+ summary: Get lib value set by key
+ description: Get a specific library/system value set from JSON files
+ security:
+ - bearerAuth: []
+ parameters:
+ - name: key
+ in: path
+ required: true
+ schema:
+ type: string
+ description: Value set key (e.g., marital_status, sex)
+ responses:
+ '200':
+ description: Lib value set details
content:
application/json:
schema:
@@ -2244,23 +2915,29 @@ paths:
data:
type: array
items:
- $ref: '#/components/schemas/ValueSetDef'
+ type: object
+ properties:
+ value:
+ type: string
+ label:
+ type: string
/api/valueset/refresh:
post:
tags: [ValueSets]
- summary: Refresh ValueSet cache
- description: Clear and reload the ValueSet library cache
+ summary: Refresh lib ValueSet cache
+ description: Clear and reload the library/system ValueSet cache from JSON files
security:
- bearerAuth: []
responses:
'200':
- description: Cache refreshed
+ description: Lib ValueSet cache refreshed
- /api/valueset/items:
+ /api/valueset/user/items:
get:
tags: [ValueSets]
- summary: List value set items
+ summary: List user value set items
+ description: List value set items from database (user-defined)
security:
- bearerAuth: []
parameters:
@@ -2271,7 +2948,7 @@ paths:
description: Filter by ValueSet ID
responses:
'200':
- description: List of value set items
+ description: List of user value set items
content:
application/json:
schema:
@@ -2284,7 +2961,8 @@ paths:
post:
tags: [ValueSets]
- summary: Create value set item
+ summary: Create user value set item
+ description: Create value set item in database (user-defined)
security:
- bearerAuth: []
requestBody:
@@ -2295,12 +2973,13 @@ paths:
$ref: '#/components/schemas/ValueSetItem'
responses:
'201':
- description: Value set item created
+ description: User value set item created
- /api/valueset/items/{id}:
+ /api/valueset/user/items/{id}:
get:
tags: [ValueSets]
- summary: Get value set item by ID
+ summary: Get user value set item by ID
+ description: Get value set item from database (user-defined)
security:
- bearerAuth: []
parameters:
@@ -2311,11 +2990,12 @@ paths:
type: integer
responses:
'200':
- description: Value set item details
+ description: User value set item details
put:
tags: [ValueSets]
- summary: Update value set item
+ summary: Update user value set item
+ description: Update value set item in database (user-defined)
security:
- bearerAuth: []
parameters:
@@ -2332,11 +3012,12 @@ paths:
$ref: '#/components/schemas/ValueSetItem'
responses:
'200':
- description: Value set item updated
+ description: User value set item updated
delete:
tags: [ValueSets]
- summary: Delete value set item
+ summary: Delete user value set item
+ description: Delete value set item from database (user-defined)
security:
- bearerAuth: []
parameters:
@@ -2347,21 +3028,23 @@ paths:
type: integer
responses:
'200':
- description: Value set item deleted
+ description: User value set item deleted
- /api/valuesetdef:
+ /api/valueset/user/def:
get:
tags: [ValueSets]
- summary: List value set definitions
+ summary: List user value set definitions
+ description: List value set definitions from database (user-defined)
security:
- bearerAuth: []
responses:
'200':
- description: List of value set definitions
+ description: List of user value set definitions
post:
tags: [ValueSets]
- summary: Create value set definition
+ summary: Create user value set definition
+ description: Create value set definition in database (user-defined)
security:
- bearerAuth: []
requestBody:
@@ -2372,12 +3055,13 @@ paths:
$ref: '#/components/schemas/ValueSetDef'
responses:
'201':
- description: Value set definition created
+ description: User value set definition created
- /api/valuesetdef/{id}:
+ /api/valueset/user/def/{id}:
get:
tags: [ValueSets]
- summary: Get value set definition by ID
+ summary: Get user value set definition by ID
+ description: Get value set definition from database (user-defined)
security:
- bearerAuth: []
parameters:
@@ -2388,11 +3072,12 @@ paths:
type: integer
responses:
'200':
- description: Value set definition details
+ description: User value set definition details
put:
tags: [ValueSets]
- summary: Update value set definition
+ summary: Update user value set definition
+ description: Update value set definition in database (user-defined)
security:
- bearerAuth: []
parameters:
@@ -2409,11 +3094,12 @@ paths:
$ref: '#/components/schemas/ValueSetDef'
responses:
'200':
- description: Value set definition updated
+ description: User value set definition updated
delete:
tags: [ValueSets]
- summary: Delete value set definition
+ summary: Delete user value set definition
+ description: Delete value set definition from database (user-defined)
security:
- bearerAuth: []
parameters:
@@ -2424,7 +3110,7 @@ paths:
type: integer
responses:
'200':
- description: Value set definition deleted
+ description: User value set definition deleted
# ========================================
# Master Data Routes
@@ -2435,9 +3121,33 @@ paths:
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/Location'
post:
tags: [Master Data]
@@ -2449,25 +3159,104 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/Location'
+ type: object
+ required:
+ - LocCode
+ - LocFull
+ properties:
+ SiteID:
+ type: integer
+ LocCode:
+ type: string
+ maxLength: 6
+ Parent:
+ type: integer
+ LocFull:
+ type: string
+ maxLength: 255
+ Description:
+ type: string
+ maxLength: 255
+ LocType:
+ type: string
responses:
'201':
description: Location created
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ type: object
patch:
tags: [Master Data]
summary: Update location
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - LocCode
+ - LocFull
+ properties:
+ LocationID:
+ type: integer
+ SiteID:
+ type: integer
+ LocCode:
+ type: string
+ maxLength: 6
+ Parent:
+ type: integer
+ LocFull:
+ type: string
+ maxLength: 255
+ Description:
+ type: string
+ maxLength: 255
+ LocType:
+ type: string
responses:
'200':
description: Location updated
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ type: object
delete:
tags: [Master Data]
summary: Delete location
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - LocationID
+ properties:
+ LocationID:
+ type: integer
responses:
'200':
description: Location deleted
@@ -2484,9 +3273,21 @@ paths:
required: true
schema:
type: integer
+ description: LocationID (primary key)
responses:
'200':
description: Location details
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ $ref: '#/components/schemas/Location'
/api/contact:
get:
@@ -2497,6 +3298,19 @@ paths:
responses:
'200':
description: List of contacts
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/Contact'
post:
tags: [Master Data]
@@ -2508,7 +3322,41 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/Contact'
+ type: object
+ required:
+ - NameFirst
+ properties:
+ 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
+ EmailAddress1:
+ type: string
+ format: email
+ EmailAddress2:
+ type: string
+ format: email
+ Phone:
+ type: string
+ MobilePhone1:
+ type: string
+ MobilePhone2:
+ type: string
+ Specialty:
+ type: string
+ SubSpecialty:
+ type: string
responses:
'201':
description: Contact created
@@ -2518,6 +3366,44 @@ paths:
summary: Update contact
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - NameFirst
+ properties:
+ ContactID:
+ type: integer
+ NameFirst:
+ type: string
+ NameLast:
+ type: string
+ Title:
+ type: string
+ Initial:
+ type: string
+ Birthdate:
+ type: string
+ format: date-time
+ EmailAddress1:
+ type: string
+ format: email
+ EmailAddress2:
+ type: string
+ format: email
+ Phone:
+ type: string
+ MobilePhone1:
+ type: string
+ MobilePhone2:
+ type: string
+ Specialty:
+ type: string
+ SubSpecialty:
+ type: string
responses:
'200':
description: Contact updated
@@ -2527,6 +3413,17 @@ paths:
summary: Delete contact
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - ContactID
+ properties:
+ ContactID:
+ type: integer
responses:
'200':
description: Contact deleted
@@ -2543,9 +3440,21 @@ paths:
required: true
schema:
type: integer
+ description: ContactID (primary key)
responses:
'200':
description: Contact details
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ $ref: '#/components/schemas/Contact'
/api/occupation:
get:
@@ -2556,6 +3465,19 @@ paths:
responses:
'200':
description: List of occupations
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/Occupation'
post:
tags: [Master Data]
@@ -2567,7 +3489,20 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/Occupation'
+ type: object
+ required:
+ - OccCode
+ - OccText
+ properties:
+ OccCode:
+ type: string
+ description: Occupation code (required)
+ OccText:
+ type: string
+ description: Occupation name/text (required)
+ Description:
+ type: string
+ description: Additional description
responses:
'201':
description: Occupation created
@@ -2577,6 +3512,24 @@ paths:
summary: Update occupation
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - OccCode
+ - OccText
+ properties:
+ OccupationID:
+ type: integer
+ OccCode:
+ type: string
+ OccText:
+ type: string
+ Description:
+ type: string
responses:
'200':
description: Occupation updated
@@ -2593,9 +3546,21 @@ paths:
required: true
schema:
type: integer
+ description: OccupationID (primary key)
responses:
'200':
description: Occupation details
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ $ref: '#/components/schemas/Occupation'
/api/medicalspecialty:
get:
@@ -2606,6 +3571,19 @@ paths:
responses:
'200':
description: List of medical specialties
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/MedicalSpecialty'
post:
tags: [Master Data]
@@ -2617,7 +3595,19 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/MedicalSpecialty'
+ type: object
+ required:
+ - SpecialtyText
+ properties:
+ SpecialtyText:
+ type: string
+ description: Specialty name/text (required)
+ Parent:
+ type: integer
+ description: Parent specialty ID
+ Title:
+ type: string
+ description: Title/abbreviation
responses:
'201':
description: Medical specialty created
@@ -2627,6 +3617,23 @@ paths:
summary: Update medical specialty
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - SpecialtyText
+ properties:
+ SpecialtyID:
+ type: integer
+ SpecialtyText:
+ type: string
+ Parent:
+ type: integer
+ Title:
+ type: string
responses:
'200':
description: Medical specialty updated
@@ -2643,9 +3650,21 @@ paths:
required: true
schema:
type: integer
+ description: SpecialtyID (primary key)
responses:
'200':
description: Medical specialty details
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ $ref: '#/components/schemas/MedicalSpecialty'
/api/counter:
get:
@@ -2656,6 +3675,19 @@ paths:
responses:
'200':
description: List of counters
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/Counter'
post:
tags: [Master Data]
@@ -2667,7 +3699,23 @@ paths:
content:
application/json:
schema:
- $ref: '#/components/schemas/Counter'
+ type: object
+ properties:
+ CounterDesc:
+ type: string
+ description: Counter description/name
+ CounterValue:
+ type: integer
+ description: Current counter value
+ CounterStart:
+ type: integer
+ description: Starting value
+ CounterEnd:
+ type: integer
+ description: Ending value (for auto-reset)
+ CounterReset:
+ type: string
+ description: Reset pattern (D=Daily, M=Monthly, Y=Yearly)
responses:
'201':
description: Counter created
@@ -2677,6 +3725,25 @@ paths:
summary: Update counter
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ CounterID:
+ type: integer
+ CounterDesc:
+ type: string
+ CounterValue:
+ type: integer
+ CounterStart:
+ type: integer
+ CounterEnd:
+ type: integer
+ CounterReset:
+ type: string
responses:
'200':
description: Counter updated
@@ -2686,6 +3753,17 @@ paths:
summary: Delete counter
security:
- bearerAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ required:
+ - CounterID
+ properties:
+ CounterID:
+ type: integer
responses:
'200':
description: Counter deleted
@@ -2702,9 +3780,21 @@ paths:
required: true
schema:
type: integer
+ description: CounterID (primary key)
responses:
'200':
description: Counter details
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ message:
+ type: string
+ data:
+ $ref: '#/components/schemas/Counter'
/api/areageo:
get:
diff --git a/docs/frontend-implementation-plan.md b/docs/frontend-implementation-plan.md
index f0c6ac0..88a902a 100644
--- a/docs/frontend-implementation-plan.md
+++ b/docs/frontend-implementation-plan.md
@@ -11,40 +11,7 @@
- **SvelteKit File-based Routing** - Standard patterns
- **Server-side auth checking** - SvelteKit hooks for session validation
-## Project Structure
-
-```
-src/
-├── lib/
-│ ├── api/ # API service functions
-│ │ ├── client.js # Base fetch wrapper with auth
-│ │ ├── auth.js # Auth endpoints
-│ │ ├── valuesets.js # ValueSet endpoints
-│ │ ├── masterdata.js # Master data endpoints
-│ │ ├── patients.js # Patient endpoints
-│ │ └── ...
-│ ├── components/ # Reusable Svelte components
-│ │ ├── FormInput.svelte
-│ │ ├── DataTable.svelte
-│ │ ├── SelectDropdown.svelte
-│ │ └── Layout.svelte
-│ └── stores/ # Svelte stores
-│ ├── auth.js # Auth state
-│ └── valuesets.js # Cached lookup values
-├── routes/
-│ ├── +layout.svelte # Root layout with nav
-│ ├── +page.svelte # Dashboard (home)
-│ ├── login/
-│ │ └── +page.svelte
-│ ├── (app)/ # Group: protected routes
-│ │ ├── +layout.svelte # Auth check
-│ │ ├── patients/
-│ │ ├── valuesets/
-│ │ ├── masterdata/
-│ │ └── ...
-│ └── api/ # Internal API routes (if needed)
-└── app.html
-```
+## Project Structure\n\n```\nsrc/\n├── lib/\n│ ├── api/ # API service functions\n│ │ ├── client.js # Base fetch wrapper with auth\n│ │ ├── auth.js # Auth endpoints\n│ │ ├── valuesets.js # ValueSet endpoints\n│ │ ├── locations.js # Location endpoints\n│ │ ├── contacts.js # Contact endpoints\n│ │ ├── specialties.js # Specialty endpoints\n│ │ └── ... # Other endpoint modules\n│ ├── components/ # Reusable Svelte components\n│ │ ├── DataTable.svelte\n│ │ ├── Modal.svelte\n│ │ ├── SelectDropdown.svelte\n│ │ ├── Sidebar.svelte\n│ │ └── ToastContainer.svelte\n│ ├── stores/ # Svelte stores\n│ │ ├── auth.js # Auth state\n│ │ └── valuesets.js # Cached lookup values\n│ └── utils/ # Utility functions\n│ └── toast.js # Toast notifications\n├── routes/\n│ ├── +layout.svelte # Root layout with nav\n│ ├── +page.svelte # Redirect to login\n│ ├── login/\n│ │ └── +page.svelte\n│ └── (app)/ # Group: protected routes\n│ ├── +layout.svelte # Auth check with sidebar\n│ ├── dashboard/\n│ │ └── +page.svelte\n│ └── master-data/\n│ ├── +page.svelte\n│ ├── locations/\n│ ├── contacts/\n│ ├── specialties/\n│ └── valuesets/\n├── app.css # Global styles with Tailwind\n└── app.html # HTML template\n```
## Implementation Phases
@@ -69,95 +36,137 @@ src/
---
-### Phase 1: Foundation Data
-**Priority:** High | **Time Estimate:** 4-6 hours
+### Phase 1: Foundation Data ✅ COMPLETED
+**Priority:** High | **Time Estimate:** 4-6 hours | **Status:** Done
**Why First:** These are prerequisites for all other modules. ValueSets provide dropdown options; Master Data provides reference entities.
-#### 1a. ValueSets Module
-- [ ] ValueSet definitions list page
-- [ ] ValueSet definitions create/edit form
-- [ ] ValueSet items management (CRUD)
-- [ ] Cache frequently used value sets in stores
+#### 1a. System ValueSets Module (Library) ✅ COMPLETED
+System ValueSets are pre-defined lookup values used throughout the application (gender, marital status, specimen types, etc.). These are read-only libraries fetched from JSON files and cached.
+
+- [x] ValueSet browser page (view system value sets by key)
+- [x] ValueSet items viewer (read-only)
+- [x] Cache frequently used value sets in stores
+- [x] SelectDropdown component using cached value sets
+- [x] Refresh ValueSet cache
+
+**API Endpoints (Library/System ValueSets):**
+- `GET /api/valueset` - List all library value sets with item counts
+- `GET /api/valueset/{key}` - Get library value set by key (e.g., 'marital_status', 'sex')
+- `POST /api/valueset/refresh` - Refresh library ValueSet cache from JSON files
+
+#### 1b. Master Data - Locations & Contacts ✅ COMPLETED
+- [x] Locations list page with search (supports LocCode, LocName filters)
+- [x] Locations create/edit form
+- [x] Contacts (Physicians) list page
+- [x] Contacts create/edit form
**API Endpoints:**
-- `GET /api/valueset` - List value set definitions
-- `POST /api/valuesetdef` - Create value set definition
-- `PUT /api/valuesetdef/{id}` - Update value set definition
-- `DELETE /api/valuesetdef/{id}` - Delete value set definition
-- `GET /api/valueset/items` - List value set items
-- `POST /api/valueset/items` - Create value set item
-- `PUT /api/valueset/items/{id}` - Update value set item
-- `DELETE /api/valueset/items/{id}` - Delete value set item
-- `POST /api/valueset/refresh` - Refresh cache
-#### 1b. Master Data - Locations & Contacts
-- [ ] Locations list page with search
-- [ ] Locations create/edit form
-- [ ] Contacts (Physicians) list page
-- [ ] Contacts create/edit form
-
-**API Endpoints:**
-- `GET /api/location` - List locations
-- `POST /api/location` - Create location
-- `PATCH /api/location` - Update location
-- `DELETE /api/location` - Delete location
+**Locations:**
+- `GET /api/location` - List locations (query: LocCode, LocName)
+- `POST /api/location` - Create location (required: LocCode, LocFull)
+- `PATCH /api/location` - Update location (required: LocCode, LocFull)
+- `DELETE /api/location` - Delete location (body: { LocationID })
- `GET /api/location/{id}` - Get location details
+
+**Location Schema:**
+- `LocationID` - Primary key (auto-generated)
+- `SiteID` - Reference to site
+- `LocCode` - Location code, max 6 chars (required)
+- `Parent` - Parent location ID (for hierarchical locations)
+- `LocFull` - Full location name, max 255 chars (required)
+- `Description` - Description, max 255 chars
+- `LocType` - Location type (e.g., ROOM, WARD, BUILDING)
+- `CreateDate`, `EndDate` - Timestamps
+
+**Contacts:**
- `GET /api/contact` - List contacts
-- `POST /api/contact` - Create contact
+- `POST /api/contact` - Create contact (required: NameFirst)
- `PATCH /api/contact` - Update contact
- `DELETE /api/contact` - Delete contact
- `GET /api/contact/{id}` - Get contact details
-#### 1c. Master Data - Supporting Entities
-- [ ] Occupations management
-- [ ] Medical Specialties management
-- [ ] Counters management (for ID generation)
+**Contact Schema:**
+- `ContactID` - Primary key (auto-generated)
+- `NameFirst` - First name (required)
+- `NameLast` - Last name
+- `Title` - Title (e.g., Dr, Mr, Mrs)
+- `Initial` - Middle initial
+- `Birthdate` - Date of birth (ISO 8601)
+- `EmailAddress1`, `EmailAddress2` - Email addresses
+- `Phone` - Primary phone
+- `MobilePhone1`, `MobilePhone2` - Mobile numbers
+- `Specialty` - Medical specialty code
+- `SubSpecialty` - Sub-specialty code
+- `CreateDate`, `EndDate` - Timestamps
+
+#### 1d. Master Data - Supporting Entities ✅ COMPLETED
+- [x] Occupations management
+- [x] Medical Specialties management
+- [x] Counters management (for ID generation)
**API Endpoints:**
+
+**Occupations:**
- `GET /api/occupation` - List occupations
-- `POST /api/occupation` - Create occupation
-- `PATCH /api/occupation` - Update occupation
+- `POST /api/occupation` - Create occupation (required: OccCode, OccText)
+- `PATCH /api/occupation` - Update occupation (required: OccCode, OccText)
- `GET /api/occupation/{id}` - Get occupation details
+
+**Occupation Schema:**
+- `OccupationID` - Primary key (auto-generated)
+- `OccCode` - Occupation code (required)
+- `OccText` - Occupation name/text (required)
+- `Description` - Additional description
+- `CreateDate` - Creation timestamp
+
+**Medical Specialties:**
- `GET /api/medicalspecialty` - List specialties
-- `POST /api/medicalspecialty` - Create specialty
-- `PATCH /api/medicalspecialty` - Update specialty
+- `POST /api/medicalspecialty` - Create specialty (required: SpecialtyText)
+- `PATCH /api/medicalspecialty` - Update specialty (required: SpecialtyText)
- `GET /api/medicalspecialty/{id}` - Get specialty details
+
+**Medical Specialty Schema:**
+- `SpecialtyID` - Primary key (auto-generated)
+- `SpecialtyText` - Specialty name/text (required)
+- `Parent` - Parent specialty ID (for hierarchical structure)
+- `Title` - Title/abbreviation
+- `CreateDate`, `EndDate` - Timestamps
+
+**Counters:**
- `GET /api/counter` - List counters
- `POST /api/counter` - Create counter
- `PATCH /api/counter` - Update counter
-- `DELETE /api/counter` - Delete counter
+- `DELETE /api/counter` - Delete counter (body: { CounterID })
- `GET /api/counter/{id}` - Get counter details
-#### 1d. Master Data - Geography
-- [ ] Provinces list (read-only dropdown)
-- [ ] Cities list with province filter
+**Counter Schema:**
+- `CounterID` - Primary key (auto-generated)
+- `CounterDesc` - Counter description/name
+- `CounterValue` - Current counter value
+- `CounterStart` - Starting value
+- `CounterEnd` - Ending value (for auto-reset)
+- `CounterReset` - Reset pattern (D=Daily, M=Monthly, Y=Yearly)
+
+#### 1e. Master Data - Geography ✅ COMPLETED
+- [x] Geographical areas list
+- [x] Provinces list (read-only dropdown)
+- [x] Cities list with province filter
**API Endpoints:**
+- `GET /api/areageo` - List all geographical areas
- `GET /api/areageo/provinces` - List provinces
-- `GET /api/areageo/cities` - List cities (with province_id filter)
+- `GET /api/areageo/cities?province_id={id}` - List cities (with province filter)
+
+**Notes:**
+- Geography endpoints are read-only (no POST/PATCH/DELETE)
+- Used for patient address province/city selection
+- Returns hierarchical location data
---
-### Phase 2: Patient Management
-**Priority:** High | **Time Estimate:** 3-4 hours
-
-**Dependencies:** Master Data (locations, contacts, occupations, provinces/cities)
-
-#### 2a. Patient CRUD
-- [ ] Patients list page with pagination and search
-- [ ] Patient create form with validation
-- [ ] Patient edit form
-- [ ] Patient detail view
-- [ ] Patient delete with confirmation
-
-**API Endpoints:**
-- `GET /api/patient` - List patients (with pagination, search)
-- `POST /api/patient` - Create patient
-- `PATCH /api/patient` - Update patient
-- `DELETE /api/patient` - Delete patient
-- `GET /api/patient/{id}` - Get patient by ID
-- `GET /api/patient/check` - Check if patient exists
+### Phase 2: Patient Management\n**Priority:** High | **Time Estimate:** 3-4 hours\n\n**Dependencies:** Master Data (locations, contacts, occupations, provinces/cities)\n\n#### 2a. Patient CRUD\n- [ ] Patients list page with pagination and search\n- [ ] Patient create form with validation\n- [ ] Patient edit form\n- [ ] Patient detail view\n- [ ] Patient delete with confirmation\n\n**API Endpoints:**\n- `GET /api/patient` - List patients (query: page, perPage, InternalPID, PatientID, Name, Birthdate)\n- `POST /api/patient` - Create patient\n- `PATCH /api/patient` - Update patient\n- `DELETE /api/patient` - Delete patient (soft delete, body: { InternalPID })\n- `GET /api/patient/{id}` - Get patient by ID\n- `GET /api/patient/check` - Check if patient exists (query: PatientID, EmailAddress1)
#### 2b. Advanced Patient Features
- [ ] Patient identifier management (KTP, PASS, SSN, etc.)
@@ -219,6 +228,7 @@ src/
- [ ] Specimen preparation methods
- [ ] Specimen statuses
- [ ] Collection methods
+- [ ] Samples list with status filtering
**API Endpoints:**
- `GET /api/specimen` - List specimens
@@ -241,46 +251,15 @@ src/
- `POST /api/specimen/collection` - Create collection method
- `PATCH /api/specimen/collection` - Update collection method
- `GET /api/specimen/collection/{id}` - Get collection method details
+- `GET /api/sample` - Get samples (with status filter)
---
-### Phase 5: Test Catalog
-**Priority:** Medium | **Time Estimate:** 2-3 hours
-
-**Dependencies:** Organization (disciplines, departments), ValueSets
-
-- [ ] Test definitions list with filtering
-- [ ] Create/edit test definitions
-- [ ] Test mapping management (host/client codes)
-
-**API Endpoints:**
-- `GET /api/tests` - List tests (with filters)
-- `POST /api/tests` - Create test
-- `PATCH /api/tests` - Update test
-- `GET /api/tests/{id}` - Get test details
-
-**Test Types:** TEST, PARAM, CALC, GROUP, TITLE
+### Phase 5: Test Catalog\n**Priority:** Medium | **Time Estimate:** 2-3 hours\n\n**Dependencies:** Organization (disciplines, departments), ValueSets\n\n- [ ] Test definitions list with filtering\n- [ ] Create/edit test definitions\n- [ ] Test mapping management (host/client codes)\n\n**API Endpoints:**\n- `GET /api/tests` - List tests\n- `POST /api/tests` - Create test\n- `PATCH /api/tests` - Update test\n- `GET /api/tests/{id}` - Get test details\n\n**Query Parameters:**\n- `page`, `perPage` - Pagination\n- `SiteID` - Filter by site\n- `TestType` - Filter by type (TEST, PARAM, CALC, GROUP, TITLE)\n- `VisibleScr` - Filter by screen visibility (0=hidden, 1=visible)\n- `VisibleRpt` - Filter by report visibility (0=hidden, 1=visible)\n- `TestSiteName` - Search by test name or code\n\n**Test Types:**\n- `TEST` - Technical test\n- `PARAM` - Parameter\n- `CALC` - Calculated\n- `GROUP` - Panel/Profile\n- `TITLE` - Section header\n\n**Test Definition Schema:**\n- `id` - Primary key\n- `TestCode` - Test code\n- `TestName` - Test name\n- `TestType` - Type (TEST, PARAM, CALC, GROUP, TITLE)\n- `DisciplineID` - Reference to discipline\n- `DepartmentID` - Reference to department\n- `SpecimenType` - Specimen type code\n- `Unit` - Measurement unit\n- `Formula` - Calculation formula
---
-### Phase 6: Orders
-**Priority:** High | **Time Estimate:** 3-4 hours
-
-**Dependencies:** Patients, Visits, Tests, Specimen, ValueSets (priorities, statuses)
-
-- [ ] Orders list with status filtering
-- [ ] Create order with test selection
-- [ ] Order detail view
-- [ ] Update order status
-- [ ] Order items management
-
-**API Endpoints:**
-- `GET /api/ordertest` - List orders (with filters)
-- `POST /api/ordertest` - Create order
-- `PATCH /api/ordertest` - Update order
-- `DELETE /api/ordertest` - Delete order
-- `GET /api/ordertest/{id}` - Get order details
-- `POST /api/ordertest/status` - Update order status
+### Phase 6: Orders\n**Priority:** High | **Time Estimate:** 3-4 hours\n\n**Dependencies:** Patients, Visits, Tests, Specimen, ValueSets (priorities, statuses)\n\n- [ ] Orders list with status filtering\n- [ ] Create order with test selection\n- [ ] Order detail view\n- [ ] Update order status\n- [ ] Order items management\n\n**API Endpoints:**\n- `GET /api/ordertest` - List orders (filters: OrderStatus, InternalPID, page, perPage)\n- `POST /api/ordertest` - Create order (requires: PatientID, Tests array)\n- `PATCH /api/ordertest` - Update order\n- `DELETE /api/ordertest` - Delete order\n- `GET /api/ordertest/{id}` - Get order details\n- `POST /api/ordertest/status` - Update order status (body: { OrderID, OrderStatus })\n\n**Order Status Values:**\n- `ORD` - Ordered\n- `SCH` - Scheduled\n- `ANA` - Analysis\n- `VER` - Verified\n- `REV` - Reviewed\n- `REP` - Reported\n\n**Priority Values:**\n- `R` - Routine\n- `S` - Stat\n- `U` - Urgent\n\n**OrderTest Schema:**\n- `OrderID` - Order identifier\n- `PatientID` - Reference to patient\n- `VisitID` - Reference to visit\n- `OrderDate` - Order timestamp (ISO 8601)\n- `OrderStatus` - Status code (ORD, SCH, ANA, VER, REV, REP)\n- `Priority` - Priority code (R, S, U)\n- `SiteID` - Reference to site\n- `RequestingPhysician` - Requesting physician identifier\n\n**Create Order Request:**\n```json\n{\n \"PatientID\": \"string\",\n \"VisitID\": \"string\" (optional),\n \"Priority\": \"R|S|U\",\n \"SiteID\": integer (optional),\n \"RequestingPhysician\": \"string\" (optional),\n \"Tests\": [\n {\n \"TestID\": integer,\n \"SpecimenType\": \"string\" (optional)\n }\n ]\n}\n```
---
@@ -295,56 +274,65 @@ src/
**API Endpoints:**
- `GET /api/dashboard` - Get dashboard summary
-- `GET /api/result` - Get patient results
-- `GET /api/sample` - Get samples
+ - Returns: pendingOrders, todayResults, criticalResults, activePatients
+- `GET /api/result` - Get patient results (filter by PatientID, pagination with page)
**Dashboard Metrics:**
-- pendingOrders
-- todayResults
-- criticalResults
-- activePatients
+- pendingOrders - Number of pending orders
+- todayResults - Results processed today
+- criticalResults - Critical/panic results
+- activePatients - Currently active patients
---
-### Phase 8: Organization Structure
-**Priority:** Medium | **Time Estimate:** 2-3 hours
+### Phase 8: User-defined ValueSets
+**Priority:** Medium | **Time Estimate:** 3-4 hours
+**Dependencies:** Test Catalog (Phase 5)
-- [ ] Accounts management
-- [ ] Sites management
-- [ ] Disciplines management
-- [ ] Departments management
-- [ ] Workstations management
+User-defined ValueSets are created and managed by lab administrators in the database (not from JSON files). These require full CRUD operations and are used for test result interpretation (reference ranges, flags, interpretations).
+
+- [ ] User ValueSet definitions list page
+- [ ] User ValueSet definition create/edit form
+- [ ] User ValueSet items management (CRUD)
**API Endpoints:**
-- `GET /api/organization/account` - List accounts
-- `POST /api/organization/account` - Create account
-- `PATCH /api/organization/account` - Update account
-- `DELETE /api/organization/account` - Delete account
-- `GET /api/organization/account/{id}` - Get account details
-- `GET /api/organization/site` - List sites
-- `POST /api/organization/site` - Create site
-- `PATCH /api/organization/site` - Update site
-- `DELETE /api/organization/site` - Delete site
-- `GET /api/organization/site/{id}` - Get site details
-- `GET /api/organization/discipline` - List disciplines
-- `POST /api/organization/discipline` - Create discipline
-- `PATCH /api/organization/discipline` - Update discipline
-- `DELETE /api/organization/discipline` - Delete discipline
-- `GET /api/organization/discipline/{id}` - Get discipline details
-- `GET /api/organization/department` - List departments
-- `POST /api/organization/department` - Create department
-- `PATCH /api/organization/department` - Update department
-- `DELETE /api/organization/department` - Delete department
-- `GET /api/organization/department/{id}` - Get department details
-- `GET /api/organization/workstation` - List workstations
-- `POST /api/organization/workstation` - Create workstation
-- `PATCH /api/organization/workstation` - Update workstation
-- `DELETE /api/organization/workstation` - Delete workstation
-- `GET /api/organization/workstation/{id}` - Get workstation details
+
+**User ValueSet Definitions:**
+- `GET /api/valueset/user/def` - List user value set definitions
+- `POST /api/valueset/user/def` - Create user value set definition
+- `GET /api/valueset/user/def/{id}` - Get user value set definition by ID
+- `PUT /api/valueset/user/def/{id}` - Update user value set definition
+- `DELETE /api/valueset/user/def/{id}` - Delete user value set definition
+
+**User ValueSet Items:**
+- `GET /api/valueset/user/items` - List user value set items (filter by VSetID)
+- `POST /api/valueset/user/items` - Create user value set item
+- `GET /api/valueset/user/items/{id}` - Get user value set item by ID
+- `PUT /api/valueset/user/items/{id}` - Update user value set item
+- `DELETE /api/valueset/user/items/{id}` - Delete user value set item
+
+**ValueSetDef Schema:**
+- `id` - Primary key
+- `VSetCode` - Value set code
+- `VSetName` - Value set name
+- `Description` - Description
+- `Category` - Category
+
+**ValueSetItem Schema:**
+- `id` - Primary key
+- `VSetID` - Reference to ValueSet definition
+- `VValue` - Value code
+- `VLabel` - Display label
+- `VSeq` - Sequence order
+- `IsActive` - Active flag (boolean)
---
-### Phase 9: Edge API (Instrument Integration)
+### Phase 9: Organization Structure\n**Priority:** Medium | **Time Estimate:** 2-3 hours\n\n- [ ] Accounts management\n- [ ] Sites management\n- [ ] Disciplines management\n- [ ] Departments management\n- [ ] Workstations management\n\n**API Endpoints:**\n\n**Accounts:**\n- `GET /api/organization/account` - List accounts\n- `POST /api/organization/account` - Create account\n- `PATCH /api/organization/account` - Update account (body: { id, AccountName, AccountCode, AccountType })\n- `DELETE /api/organization/account` - Delete account (body: { id })\n- `GET /api/organization/account/{id}` - Get account details\n\n**Account Schema:**\n- `id` - Primary key\n- `AccountName` - Account name\n- `AccountCode` - Account code\n- `AccountType` - Account type\n\n**Sites:**\n- `GET /api/organization/site` - List sites\n- `POST /api/organization/site` - Create site\n- `PATCH /api/organization/site` - Update site (body: { id, SiteName, SiteCode, AccountID })\n- `DELETE /api/organization/site` - Delete site (body: { id })\n- `GET /api/organization/site/{id}` - Get site details\n\n**Site Schema:**\n- `id` - Primary key\n- `SiteName` - Site name\n- `SiteCode` - Site code\n- `AccountID` - Reference to account\n\n**Disciplines:**\n- `GET /api/organization/discipline` - List disciplines\n- `POST /api/organization/discipline` - Create discipline\n- `PATCH /api/organization/discipline` - Update discipline (body: { id, DisciplineName, DisciplineCode })\n- `DELETE /api/organization/discipline` - Delete discipline (body: { id })\n- `GET /api/organization/discipline/{id}` - Get discipline details\n\n**Discipline Schema:**\n- `id` - Primary key\n- `DisciplineName` - Discipline name\n- `DisciplineCode` - Discipline code\n\n**Departments:**\n- `GET /api/organization/department` - List departments\n- `POST /api/organization/department` - Create department\n- `PATCH /api/organization/department` - Update department (body: { id, DeptName, DeptCode, SiteID })\n- `DELETE /api/organization/department` - Delete department (body: { id })\n- `GET /api/organization/department/{id}` - Get department details\n\n**Department Schema:**\n- `id` - Primary key\n- `DeptName` - Department name\n- `DeptCode` - Department code\n- `SiteID` - Reference to site\n\n**Workstations:**\n- `GET /api/organization/workstation` - List workstations\n- `POST /api/organization/workstation` - Create workstation\n- `PATCH /api/organization/workstation` - Update workstation (body: { id, WorkstationName, WorkstationCode, SiteID, DepartmentID })\n- `DELETE /api/organization/workstation` - Delete workstation (body: { id })\n- `GET /api/organization/workstation/{id}` - Get workstation details\n\n**Workstation Schema:**\n- `id` - Primary key\n- `WorkstationName` - Workstation name\n- `WorkstationCode` - Workstation code\n- `SiteID` - Reference to site\n- `DepartmentID` - Reference to department
+
+---
+
+### Phase 10: Edge API (Instrument Integration)
**Priority:** Low | **Time Estimate:** 2-3 hours
- [ ] Edge results viewer
@@ -352,9 +340,44 @@ src/
- [ ] Instrument status monitoring
**API Endpoints:**
-- `GET /api/edge/orders` - Fetch pending orders
-- `POST /api/edge/orders/{orderId}/ack` - Acknowledge order
-- `POST /api/edge/status` - Log instrument status
+- `GET /api/edge/orders` - Fetch pending orders (filter by instrument_id, status)
+- `POST /api/edge/orders/{orderId}/ack` - Acknowledge order delivery
+- `POST /api/edge/results` - Receive results from instrument (tiny-edge)
+- `POST /api/edge/status` - Log instrument status (status: online, offline, error, maintenance)
+
+---
+
+### Phase 11: Authentication
+**Priority:** High | **Time Estimate:** 1-2 hours | **Status:** ✅ COMPLETED
+
+Foundation authentication system for user login/logout and session management.
+
+- [x] Login page with form validation
+- [x] JWT token handling (HTTP-only cookie)
+- [x] Logout functionality
+- [x] Auth state management
+- [x] Protected route guards
+- [x] Auth status checking
+
+**API Endpoints:**
+
+**V1 Authentication:**
+- `POST /api/auth/login` - User login (returns JWT in cookie)
+- `POST /api/auth/logout` - User logout
+- `GET /api/auth/check` - Check authentication status
+- `POST /api/auth/register` - Register new user
+- `POST /api/auth/change_pass` - Change password (authenticated)
+
+**V2 Authentication:**
+- `POST /v2/auth/login` - V2 User login
+- `POST /v2/auth/logout` - V2 User logout
+- `GET /v2/auth/check` - V2 Check authentication
+- `POST /v2/auth/register` - V2 Register new user
+
+**Security:**
+- JWT tokens stored in HTTP-only cookies
+- Bearer token support for API requests
+- Automatic redirect to login on 401 responses
---
@@ -363,6 +386,8 @@ src/
### 1. FormInput.svelte
Text input with label, validation, and error display.
+**Status:** Not yet implemented - using native inputs with DaisyUI styling
+
```svelte