diff --git a/README.md b/README.md index 592e1a8..a20bc05 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,72 @@ -# sv +# CLQMS Frontend -Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). +Clinical Laboratory Quality Management System (CLQMS) - SvelteKit frontend application. -## Creating a project +## Tech Stack -If you're seeing this, you've probably already done this step. Congrats! +- **Framework**: SvelteKit 2.50.2 with Svelte 5 (runes) +- **Styling**: Tailwind CSS 4 + DaisyUI 5 +- **Icons**: Lucide Svelte +- **Build Tool**: Vite 7.3.1 +- **Package Manager**: pnpm -```sh -# create a new project -npx sv create my-app +## Prerequisites + +- Node.js 18+ +- pnpm (`npm install -g pnpm`) +- Backend API running on `http://localhost:8000` + +## Setup + +```bash +# Install dependencies +pnpm install + +# Create environment file +cp .env.example .env ``` -To recreate this project with the same configuration: +## Development Commands -```sh -# recreate this project -npx sv create --template minimal --no-types --install npm . +```bash +# Start development server +pnpm run dev + +# Build for production +pnpm run build + +# Preview production build +pnpm run preview + +# Sync SvelteKit (runs automatically on install) +pnpm run prepare ``` -## Developing +## Project Structure -Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: - -```sh -npm run dev - -# or start the server and open the app in a new browser tab -npm run dev -- --open +``` +src/ + lib/ + api/ # API client and endpoints + stores/ # Svelte stores (auth, valuesets) + components/ # Reusable components + utils/ # Utility functions + routes/ # SvelteKit routes + (app)/ # Authenticated routes + dashboard/ + patients/ + master-data/ + login/ # Public routes ``` -## Building +## API Configuration -To create a production version of your app: +API requests to `/api` are proxied to `http://localhost:8000` in development (configured in `vite.config.js`). -```sh -npm run build -``` +## Authentication -You can preview the production build with `npm run preview`. +JWT-based authentication with automatic redirect to `/login` on 401 responses. -> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. +## Code Style + +See [AGENTS.md](./AGENTS.md) for detailed coding guidelines. diff --git a/docs/COMPREHENSIVE_IMPLEMENTATION_PLAN.md b/docs/COMPREHENSIVE_IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..c3e6e82 --- /dev/null +++ b/docs/COMPREHENSIVE_IMPLEMENTATION_PLAN.md @@ -0,0 +1,613 @@ +# Comprehensive Implementation Plan - CLQMS Frontend + +**Goal:** Complete implementation of all use cases +**Estimated Time:** 6-8 weeks (after MVP) +**This document:** All features beyond MVP scope + +--- + +## Phase 1: Authentication Enhancements (UC-01) +**Use Case:** UC-01 - Complete authentication flow +**Priority:** HIGH - Security & Multi-tenancy +**Dependencies:** Backend support for multi-site, password policies + +### 1.1 Multi-Site Selection +**Current:** Login with single site +**Required:** Support for users with access to multiple sites + +#### API Changes +``` +POST /api/auth/login +Response changes: +{ + "token": "...", + "user": { ... }, + "sites": [ + {"SiteID": "1", "SiteName": "Lab Jakarta", "SiteCode": "JK01"}, + {"SiteID": "2", "SiteName": "Lab Bandung", "SiteCode": "BD01"} + ], + "requiresSiteSelection": true +} +``` + +#### Frontend Implementation +**New Files:** +- `src/routes/login/SiteSelectionModal.svelte` +- `src/lib/stores/site.js` - Current site store + +**Modify:** +- `src/routes/login/+page.svelte` - Add site selection step + +**Features:** +- If personal email used: Show site selection dialog +- If site email used: Auto-select matching site +- Remember site selection in localStorage +- Site switcher in header/navigation +- Site context shown in UI (current site name) + +### 1.2 Password Expiration +**Requirements:** +- Track password expiry date +- Force password change when expired +- Grace period warning (7 days before expiry) + +#### API Changes +``` +POST /api/auth/login +Response includes: +{ + "passwordStatus": "valid" | "expired" | "expiring", + "passwordExpiryDate": "2025-03-01", + "daysUntilExpiry": 5 +} + +POST /api/auth/change-password +``` + +#### Frontend Implementation +**New Files:** +- `src/routes/login/PasswordExpiredModal.svelte` +- `src/routes/login/ChangePasswordModal.svelte` + +**Features:** +- Check password status on login +- If expired: Block access, show change password modal +- If expiring: Show warning banner with countdown +- Password strength requirements display +- Confirm password match validation + +### 1.3 Account Lockout +**Requirements:** +- Count failed login attempts +- Lock account after X failed attempts (configurable) +- Lockout duration: X hours (configurable) +- Clear attempts on successful login + +#### API Changes +``` +POST /api/auth/login +Error responses: +{ + "error": "ACCOUNT_LOCKED", + "message": "Please try again in 4 hours or contact system administrator", + "lockoutEndsAt": "2025-02-14T18:00:00Z", + "hoursRemaining": 4 +} + +POST /api/auth/login +On invalid password: +{ + "error": "INVALID_LOGIN", + "attemptsRemaining": 2 +} +``` + +#### Frontend Implementation +**Modify:** +- `src/routes/login/+page.svelte` - Handle lockout states + +**Features:** +- Display attempts remaining +- Show lockout timer with countdown +- "Contact administrator" link/info +- Visual indicator of account status + +### 1.4 Audit Logging Display +**Requirements:** +- View own login history +- Admin view: All user login history +- Filter by date, user, action + +#### API Changes +``` +GET /api/audit/login-logs?userId=&from=&to=&page= +Response: +{ + "logs": [ + { + "AuditID": 1, + "UserID": "admin", + "Action": "LOGIN_SUCCESS", + "Device": "Chrome 120.0 / Windows 10", + "IPAddress": "192.168.1.1", + "Timestamp": "2025-02-14T10:30:00Z" + } + ] +} +``` + +#### Frontend Implementation +**New Files:** +- `src/routes/(app)/admin/audit-logs/+page.svelte` +- `src/lib/api/audit.js` + +**Features:** +- Paginated log table +- Filters: Date range, User, Action type +- Export to CSV +- Device/IP details + +--- + +## Phase 2: Advanced Patient Management + +### 2.1 Enhanced Patient Registration (UC-02a Enhancements) +**Missing Features:** +- Duplicate identifier detection with "Multiple IDs found" handling +- UC-02b link suggestion when duplicates detected + +#### API Changes +``` +POST /api/patient/check-duplicate +{ + "IdentifierType": "KTP", + "Identifier": "1234567890" +} +Response: +{ + "hasDuplicates": true, + "duplicates": [ + {"PID": "P001", "Name": "John Doe", "DOB": "1990-01-01"} + ] +} +``` + +#### Frontend Implementation +**Modify:** +- `src/routes/(app)/patients/PatientFormModal.svelte` + +**New Files:** +- `src/routes/(app)/patients/DuplicateWarningModal.svelte` + +**Features:** +- Check for duplicates on identifier blur +- Show "Multiple IDs found" warning +- Options: + 1. Continue (create new, ignore duplicate) + 2. Link patients (redirect to UC-02b) + 3. Cancel +- Display duplicate patient details for comparison + +### 2.2 Patient Unlink (UC-02c) +**Requirements:** +- Reverse patient link operation +- Only Supervisor Lab, Manajer Lab +- Restore source PID to active status + +#### API Changes +``` +POST /api/patient/unlink +{ + "SourcePID": "P001", + "DestinationPID": "P002" +} +Creates ADT: A37 (Unlink Patient Information) +``` + +#### Frontend Implementation +**New Files:** +- `src/routes/(app)/patients/unlink/+page.svelte` + +**Features:** +- Search by PID to find linked patients +- Display destination with all linked sources +- Uncheck source PIDs to unlink +- Confirmation dialog +- Restore source PID edit/order capabilities + +--- + +## Phase 3: Advanced Visit Management + +### 3.1 Cancel Admission (UC-03b) +**Requirements:** +- Cancel patient admission +- Only Supervisor Lab, Manajer Lab +- Reason for cancellation +- ADT Code: A11 (Cancel Admit) + +#### API Changes +``` +POST /api/patvisit/:pvid/cancel-admission +{ + "Reason": "Insurance invalid", + "Notes": "..." +} +Creates ADT: A11 (Cancel Admit) +``` + +#### Frontend Implementation +**New Files:** +- `src/routes/(app)/patients/CancelAdmissionModal.svelte` + +**Features:** +- Available in visit actions (supervisor only) +- Reason dropdown + notes field +- Confirm cancellation +- Mark visit as cancelled +- Prevent new orders on cancelled visits + +### 3.2 Change Attending Doctor (UC-03c) +**Requirements:** +- Change primary doctor (DPJP) +- ADT Code: A54 (Change Attending Doctor) +- Track doctor history + +#### API Changes +``` +POST /api/patvisit/:pvid/change-attending-doctor +{ + "NewAttendingDoctorID": "DOC001" +} +Creates ADT: A54 +``` + +#### Frontend Implementation +**Modify:** +- `src/routes/(app)/patients/VisitFormModal.svelte` + +**Features:** +- Doctor dropdown with search +- Show current attending doctor +- Change history in ADT log +- Validation: Doctor must exist in contacts + +### 3.3 Change Consulting Doctor (UC-03d) +**Requirements:** +- Change consulting doctor (konsulen) +- ADT Code: A61 (Change Consulting Doctor) + +#### API Changes +``` +POST /api/patvisit/:pvid/change-consulting-doctor +{ + "NewConsultingDoctorID": "DOC002" +} +Creates ADT: A61 +``` + +#### Frontend Implementation +**Modify:** +- `src/routes/(app)/patients/VisitFormModal.svelte` + +**Features:** +- Similar to attending doctor change +- Separate field for consulting doctor +- History tracking + +--- + +## Phase 4: Test Ordering Enhancements + +### 4.1 Future Orders +**Requirements:** +- Schedule test order for future date +- Effective date validation + +#### Frontend Implementation +**Modify:** +- `src/routes/(app)/orders/new/+page.svelte` + +**Features:** +- "Effective Date" field (default: today) +- Future date validation (max 30 days?) +- Separate OID generation for future orders? +- View scheduled orders separately + +### 4.2 Order from PID (Alternative Flow) +**Requirements:** +- Create order using PID instead of PVID +- Show list of active PVIDs for patient +- Select PVID then proceed + +#### Frontend Implementation +**Modify:** +- `src/routes/(app)/orders/new/+page.svelte` + +**Features:** +- Toggle: "Use PID instead of PVID" +- PID search +- Display patient's active visits (not discharged) +- Select PVID to proceed + +### 4.3 Non-Patient Orders +**Requirements:** +- Orders without patient (QC, calibration, research) +- Different order type/flow + +#### API Changes +``` +POST /api/orders/non-patient +{ + "OrderType": "QC", + "Description": "...", + "Tests": [...] +} +``` + +#### Frontend Implementation +**New Files:** +- `src/routes/(app)/orders/non-patient/+page.svelte` + +--- + +## Phase 5: Specimen Management + +### 5.1 Specimen Tracking +**Requirements:** +- Full specimen lifecycle tracking +- Collection, receipt, rejection, disposal +- Barcode/label generation + +#### API Changes +``` +GET /api/specimens/:sid/status-history +PATCH /api/specimens/:sid/status +{ + "Status": "COLLECTED", // COLLECTED, RECEIVED, REJECTED, DISPOSED + "Notes": "..." +} +``` + +#### Frontend Implementation +**New Files:** +- `src/routes/(app)/specimens/+page.svelte` - Specimen list +- `src/routes/(app)/specimens/[sid]/+page.svelte` - Specimen detail +- `src/lib/api/specimens.js` (extend) + +**Features:** +- Specimen search (SID, OID, Patient) +- Status timeline/history +- Collection/receipt timestamps +- Rejection reason logging +- Label printing (integration with printer) + +### 5.2 Label Printing Integration +**Requirements:** +- Print patient labels +- Print order labels +- Print specimen labels +- Support for label printers + +#### Frontend Implementation +**New Files:** +- `src/lib/utils/labelPrinting.js` +- `src/routes/(app)/print/labels/+page.svelte` + +**Features:** +- Label templates (patient, order, specimen) +- Print dialog with printer selection +- Preview before print +- Batch printing +- Integration with browser print API or direct printer communication + +--- + +## Phase 6: Reporting & Analytics + +### 6.1 Cumulative Patient Reports +**Requirements:** +- View all test results across visits for linked patients +- Chronological view +- Filter by test type, date range + +#### API Changes +``` +GET /api/reports/patient-cumulative/:pid?from=&to=&tests= +Response: +{ + "patient": {...}, + "visits": [...], + "results": [ + { + "Date": "...", + "Test": "Glucose", + "Result": "120", + "Unit": "mg/dL", + "ReferenceRange": "70-100" + } + ] +} +``` + +#### Frontend Implementation +**New Files:** +- `src/routes/(app)/reports/patient-cumulative/+page.svelte` + +**Features:** +- Patient search +- Date range filter +- Test type filter +- Table view with trend indicators +- Export to PDF/Excel + +### 6.2 Workload Statistics +**Requirements:** +- Orders by time period +- Tests performed +- Turnaround time analysis + +#### Frontend Implementation +**New Files:** +- `src/routes/(app)/reports/workload/+page.svelte` + +--- + +## Phase 7: Administration Features + +### 7.1 User Management +**Requirements:** +- Create/edit users +- Role assignment +- Site access management +- Password reset + +#### Frontend Implementation +**New Files:** +- `src/routes/(app)/admin/users/+page.svelte` +- `src/routes/(app)/admin/users/UserFormModal.svelte` + +### 7.2 Role & Permission Management +**Requirements:** +- Define roles +- Configure menu access per role +- Action-level permissions + +### 7.3 System Configuration +**Requirements:** +- Global settings +- ADT code configuration +- Password policy settings +- Lockout configuration + +--- + +## Phase 8: Integration Features + +### 8.1 HL7/ADT Message Integration +**Requirements:** +- Receive ADT messages from HIS +- Send order updates to HIS +- Message queue management + +### 8.2 Instrument Integration +**Requirements:** +- Bidirectional communication with lab instruments +- Auto-result entry +- QC data import + +--- + +## Implementation Priority Matrix + +### Critical (Month 1-2) +1. Authentication: Multi-site selection +2. Patient: Enhanced duplicate detection +3. Visit: Cancel admission, doctor changes +4. Orders: Future orders, PID-based ordering + +### High (Month 2-3) +1. Authentication: Password expiration +2. Authentication: Account lockout +3. Patient: Unlink functionality +4. Specimens: Full tracking +5. Reports: Cumulative patient view + +### Medium (Month 3-4) +1. Authentication: Audit logs +2. Specimens: Label printing integration +3. Administration: User management +4. Administration: Role management + +### Low (Month 4+) +1. Non-patient orders +2. Workload statistics +3. System configuration UI +4. Instrument integration + +--- + +## Technical Considerations + +### Performance +- Implement pagination for all list endpoints +- Use virtual scrolling for large tables +- Cache patient/order data appropriately +- Lazy load audit logs + +### Security +- All admin actions require elevated permissions +- Audit all sensitive operations +- Encrypt sensitive data at rest +- Secure password storage (backend) + +### Scalability +- Support for multiple sites/locations +- Concurrent user handling +- Large dataset performance (100k+ patients) + +--- + +## Dependencies + +### Backend Must Support: +- [ ] Multi-site user management +- [ ] Password expiration tracking +- [ ] Failed login attempt tracking +- [ ] All ADT codes (A11, A54, A61, A24, A37) +- [ ] Advanced patient search (duplicate detection) +- [ ] Specimen status workflow +- [ ] Audit logging for all operations +- [ ] Role-based access control (RBAC) +- [ ] Label generation endpoints + +### Infrastructure: +- [ ] Label printer setup +- [ ] Barcode scanner integration +- [ ] HIS/HL7 integration (if needed) +- [ ] Backup and disaster recovery + +--- + +## Success Criteria + +### Phase 1 Complete: +- [ ] Users can select site on login +- [ ] Password expiration enforced +- [ ] Account lockout working +- [ ] Multi-site data isolation + +### Phase 2 Complete: +- [ ] Duplicate detection on registration +- [ ] Patient link/unlink functional +- [ ] Link validation (no multi-level) + +### Phase 3 Complete: +- [ ] All visit operations functional +- [ ] Complete ADT history for all actions +- [ ] Doctor change tracking + +### Phase 4 Complete: +- [ ] Future order scheduling +- [ ] PID-based ordering +- [ ] Non-patient order support + +### Phase 5 Complete: +- [ ] Full specimen lifecycle tracking +- [ ] Label printing operational +- [ ] Specimen status history + +### Phase 6 Complete: +- [ ] Cumulative reports for linked patients +- [ ] Workload statistics +- [ ] Export functionality + +### Phase 7 Complete: +- [ ] User management UI +- [ ] Role configuration +- [ ] System settings + +### Phase 8 Complete: +- [ ] HIS integration +- [ ] Instrument integration +- [ ] Message queue management diff --git a/docs/MVP_IMPLEMENTATION_PLAN.md b/docs/MVP_IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..6bbd9a9 --- /dev/null +++ b/docs/MVP_IMPLEMENTATION_PLAN.md @@ -0,0 +1,266 @@ +# MVP Implementation Plan - CLQMS Frontend + +**Goal:** Deliver core functionality for daily laboratory operations within shortest timeframe. +**Estimated Time:** 2-3 weeks +**Priority:** Critical features for production use + +--- + +## Phase 1: Test Ordering System (Week 1) +**Use Cases:** UC-5a, UC-5b +**Priority:** HIGHEST - Core lab functionality + +### API Endpoints Needed (Backend) +``` +POST /api/orders # Create new test order +GET /api/orders/:oid # Get order details +PATCH /api/orders/:oid # Update order +GET /api/orders # List/search orders +POST /api/specimens # Create specimen records +GET /api/specimens/:sid # Get specimen details +GET /api/orders/:oid/specimens # List specimens for order +``` + +### Frontend Implementation + +#### 1.1 Create Order Management Module +**New Files:** +- `src/routes/(app)/orders/+page.svelte` - Order list/search page +- `src/routes/(app)/orders/new/+page.svelte` - New order creation +- `src/routes/(app)/orders/[oid]/+page.svelte` - Order detail/edit +- `src/lib/api/orders.js` - Order API client +- `src/lib/api/specimens.js` - Specimen API client + +#### 1.2 Order List Page Features +- Search by OID, Patient ID, Patient Name +- Filter by status (SC, IP, CM, CL) +- Date range filter +- Quick actions: View, Edit, Print labels +- Table columns: OID, Patient, Date, Tests, Status + +#### 1.3 New Order Page Features +- Patient/PVID selection (search existing or quick admit) +- Test selection with search +- Specimen requirements display +- Comments/attachments +- Print label options (checkboxes): + - Print Patient Label + - Print Order Label + - Print Specimen Label +- Auto-generate OID and SID on save + +#### 1.4 Order Status Validation +- Prevent editing if status = CL (Closed) +- Prevent editing if status = AC (Archived) +- Prevent editing if status = DL (Deleted) +- Prevent removing tests that have results + +#### 1.5 Specimen Management +- Auto-create specimen records per test +- Display SID list after order creation +- Basic specimen tracking view + +--- + +## Phase 2: Patient Discharge (Week 1-2) +**Use Cases:** UC-04a, UC-04b +**Priority:** HIGH - Essential for visit lifecycle + +### API Endpoints Needed (Backend) +``` +POST /api/patvisit/:pvid/discharge # Create discharge ADT (A03) +POST /api/patvisit/:pvid/cancel-discharge # Cancel discharge (A13) +GET /api/orders/pvid/:pvid/open # Check for open orders +``` + +### Frontend Implementation + +#### 2.1 Update Visit Management +**Modify:** +- `src/routes/(app)/patients/+page.svelte` - Add discharge actions +- `src/routes/(app)/patients/VisitFormModal.svelte` - Add discharge button + +**New Files:** +- `src/routes/(app)/patients/DischargeModal.svelte` - Discharge confirmation +- `src/routes/(app)/patients/CancelDischargeModal.svelte` - Cancel discharge + +#### 2.2 Discharge Features +- Discharge button on active visits +- Validation: Check for open test orders (status: A, IP, SC, HD) +- If open orders exist: Show warning, block discharge +- ADT Code: A03 (Discharge) +- Required fields: Discharge date +- After discharge: Visit marked as closed (no more edits) + +#### 2.3 Cancel Discharge Features +- Available only for Supervisor Lab, Manajer Lab +- ADT Code: A13 (Cancel Discharge) +- Re-opens visit for editing +- Available in visit actions menu + +--- + +## Phase 3: Patient Transfer (Week 2) +**Use Cases:** UC-04 +**Priority:** MEDIUM-HIGH - Common daily operation + +### API Endpoints Needed (Backend) +``` +POST /api/patvisit/:pvid/transfer # Create transfer ADT (A02) +``` + +### Frontend Implementation + +#### 3.1 Transfer Feature +**Modify:** +- `src/routes/(app)/patients/VisitFormModal.svelte` - Add transfer section + +**New Files:** +- `src/routes/(app)/patients/TransferModal.svelte` - Location transfer + +#### 3.2 Transfer Features +- Transfer button on active visits +- Location dropdown (from master data) +- ADT Code: A02 (Patient Transfer) +- Update visit LocationID +- Track location history via ADT + +--- + +## Phase 4: Patient Link (Basic) (Week 2-3) +**Use Cases:** UC-02b +**Priority:** MEDIUM - Data quality improvement + +### API Endpoints Needed (Backend) +``` +GET /api/patient/search-duplicates # Find potential duplicates +POST /api/patient/link # Link patients (A24) +GET /api/patient/:pid/linked # Get linked patients +``` + +### Frontend Implementation + +#### 4.1 Patient Link Module +**New Files:** +- `src/routes/(app)/patients/link/+page.svelte` - Patient link page +- `src/lib/api/patient-links.js` - Link API client + +#### 4.2 Link Features +- Search by: Identifier (KTP/Passport), Name + DOB + Address +- Display matching patients +- Select destination (surviving) PID +- Select source PID(s) to link +- Confirmation dialog +- ADT Code: A24 (Link Patient) +- Validation: Prevent multi-level links, prevent linking already-linked sources + +#### 4.3 Visual Indicator +- Show "Linked" badge on patient records +- Display linked PIDs in patient detail + +--- + +## Navigation Updates + +### Sidebar Changes +Add to Laboratory section: +``` +Laboratory +├── Patients (existing) +├── Orders (NEW) +├── Specimens (NEW) +└── Patient Links (NEW) +``` + +--- + +## Database Schema Requirements (Backend) + +### Orders Table +```sql +ordertest: + - OrderID (OID) + - InternalOID + - PVID + - EffDate (future orders) + - EndDate (closed) + - ArchiveDate + - DelDate + - Comments + - CreatedBy, CreatedDate + +orderstatus: + - InternalOID + - OrderStatus (SC, IP, CM, CL, AC, DL) + - StatusDate + +ordertestdetail: + - InternalOID + - TestSiteID + - TestSequence +``` + +### Specimens Table +```sql +specimens: + - SpecimenID (SID) + - InternalSID + - InternalOID + - TestSiteID + - CollectionDate + - ReceivedDate + - ContainerID + - Status +``` + +--- + +## Testing Checklist + +### Test Ordering +- [ ] Create new order with multiple tests +- [ ] Search orders by patient name +- [ ] Edit pending order (SC status) +- [ ] Attempt to edit closed order (should fail) +- [ ] Print labels (UI only) +- [ ] View specimen list + +### Discharge +- [ ] Discharge patient with no open orders +- [ ] Attempt discharge with open orders (should block) +- [ ] Cancel discharge (supervisor only) +- [ ] Verify visit locked after discharge + +### Transfer +- [ ] Transfer patient to new location +- [ ] Verify location history updated + +### Patient Link +- [ ] Search duplicates by identifier +- [ ] Link two patients +- [ ] Verify destination patient shows cumulative data +- [ ] Verify source patient marked as linked + +--- + +## Out of Scope (MVP) +The following features are **NOT** included in MVP but documented for future phases: +- Multi-site authentication (UC-01 enhancements) +- Password expiration/lockout +- Patient Unlink (UC-02c) +- Cancel Admission (UC-03b) +- Change Attending/Consulting Doctor (UC-03c, UC-03d) +- Advanced duplicate detection with address matching +- Audit log viewing +- Specimen label printing integration +- Result entry integration + +--- + +## Success Criteria +1. Users can create test orders linked to patients +2. Users can discharge patients (when no open orders) +3. Users can transfer patients between locations +4. Users can link duplicate patient records +5. Order status validation prevents invalid edits +6. All operations create proper ADT audit records diff --git a/docs/api-docs.yaml b/docs/api-docs.yaml index f8620f9..439f531 100644 --- a/docs/api-docs.yaml +++ b/docs/api-docs.yaml @@ -281,14 +281,24 @@ components: items: $ref: '#/components/schemas/PatAttEntry' Province: + type: integer + description: Province AreaGeoID (foreign key to areageo table) + ProvinceLabel: type: string - description: Province area code + description: Province name (resolved from areageo) City: + type: integer + description: City AreaGeoID (foreign key to areageo table) + CityLabel: type: string - description: City area code + description: City name (resolved from areageo) Country: type: string - maxLength: 100 + 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 @@ -655,6 +665,276 @@ components: 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: + TEST_simple: + summary: Technical test - no reference range + value: + id: 1 + TestCode: GLU + TestName: Glucose + TestType: TEST + DisciplineID: 1 + DepartmentID: 1 + SpecimenType: SER + Unit: mg/dL + TEST_numeric_nmrc: + summary: Technical test - numeric reference (NMRC) + value: + id: 1 + TestCode: GLU + TestName: Glucose + TestType: TEST + DisciplineID: 1 + DepartmentID: 1 + SpecimenType: SER + 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 + SpecimenType: SER + 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 + TEST_text_text: + summary: Technical test - text reference (TEXT) + value: + id: 1 + TestCode: RBC_MORPH + TestName: RBC Morphology + TestType: TEST + DisciplineID: 1 + DepartmentID: 1 + SpecimenType: BLD + 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 + SpecimenType: null + 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 + SpecimenType: SER + Unit: mg/dL + CALC_numeric_nmrc: + summary: Calculated test - numeric reference (NMRC) + value: + id: 3 + TestCode: BUN_CR_RATIO + TestName: BUN/Creatinine Ratio + TestType: CALC + DisciplineID: 1 + DepartmentID: 1 + SpecimenType: SER + 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 + CALC_numeric_thold: + summary: Calculated test - threshold reference (THOLD) + value: + id: 3 + TestCode: BUN_CR_RATIO + TestName: BUN/Creatinine Ratio + TestType: CALC + DisciplineID: 1 + DepartmentID: 1 + SpecimenType: SER + 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 + SpecimenType: SER + Unit: null + TITLE: + summary: Section header - no reference range allowed + value: + id: 5 + TestCode: CHEM_HEADER + TestName: '--- CHEMISTRY ---' + TestType: TITLE + DisciplineID: 1 + DepartmentID: 1 + SpecimenType: null + Unit: null TestMap: type: object @@ -1672,52 +1952,23 @@ paths: items: $ref: '#/components/schemas/PatientVisit' - /api/patvisitadt: - post: + /api/patvisitadt/visit/{visitId}: + get: tags: [Patient Visits] - summary: Create ADT visit (Admission/Discharge/Transfer) + 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: [] - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - InternalPVID - - ADTCode - properties: - InternalPVID: - type: integer - description: Internal Visit ID from patvisit table (required) - 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 + parameters: + - name: visitId + in: path + required: true + schema: + type: integer + description: Internal Visit ID (InternalPVID) responses: - '201': - description: ADT visit created + '200': + description: ADT history retrieved successfully content: application/json: schema: @@ -1725,17 +1976,61 @@ paths: properties: status: type: string + example: success message: type: string + example: ADT history retrieved data: - type: object - properties: - PVADTID: - type: integer + 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 - patch: +$1 + delete: tags: [Patient Visits] - summary: Update ADT visit + summary: Delete ADT visit (soft delete) security: - bearerAuth: [] requestBody: @@ -1749,37 +2044,28 @@ paths: 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 + description: ADT record ID to delete responses: '200': - description: ADT visit updated + 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: @@ -1787,97 +2073,56 @@ paths: 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 - # ======================================== - # Organization - Account Routes - # ======================================== - /api/organization/account: - get: - tags: [Organization] - summary: List accounts - security: - - bearerAuth: [] - responses: - '200': - description: List of accounts - content: - application/json: - schema: - type: object - properties: - status: - type: string - data: - type: array - items: - $ref: '#/components/schemas/Account' - - post: - tags: [Organization] - summary: Create account - security: - - bearerAuth: [] - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/Account' - responses: - '201': - description: Account created - - patch: - tags: [Organization] - summary: Update account - security: - - bearerAuth: [] - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - id - properties: - id: - type: integer - AccountName: - type: string - AccountCode: - type: string - AccountType: - type: string - responses: - '200': - description: Account updated - - delete: - tags: [Organization] - 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 - - /api/organization/account/{id}: +$2/account/{id}: get: tags: [Organization] summary: Get account by ID diff --git a/docs/use_case_260214.md b/docs/use_case_260214.md new file mode 100644 index 0000000..a9287c4 --- /dev/null +++ b/docs/use_case_260214.md @@ -0,0 +1,514 @@ +Here is the converted Markdown format of the Use Case document. I have structured it with headers and lists to make it easily parsable by an AI agent. + +```markdown +# Use Case Document + +## Use Case – Authentication +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-01 | +| **Use Case Name** | Authentication | +| **Aktor Utama** | Admin Lab / Clerk, Analis Lab, Analis Lab Senior, Super User, Phlebotomist Lab, Perawat, DSPK/Konsulen, Supervisor Lab, Manajer Lab, Database Administrator, System Administrator | +| **Aktor Sekunder** | - | +| **Tujuan** | Verifikasi identitas pengguna, yang mencoba mengakses sistem, memastikan bahwa mereka adalah orang yang mereka klaim. Bertindak sebagai mekanisme keamanan primer untuk mencegah akses tidak sah, melindungi data, dan mengurangi risiko seperti pencurian identitas dan pelanggaran keamanan. | +| **Prasyarat** | Data pengguna sudah terdefinisi dalam sistem sebagai User atau Contact. | + +### Alur Utama +1. Aktor klik tombol Login. +2. System menampilkan login dialog yang terdiri dari User ID dan Password. +3. Aktor memasukkan email address sebagai User ID. +4. System memeriksa email address di table User, SiteStatus, Contact dan ContactDetail: + - Jika Aktor menggunakan email pribadi, maka System menampilkan pilihan sites dimana Aktor memiliki akses. Aktor, kemudian memilih salah satu site. + - Jika Aktor menggunakan email site, maka System langsung mengarahkan ke site yang bersangkutan. +5. Aktor memasukkan password. +6. System memeriksa kebenaran User ID dan password. +7. System memeriksa role dan menu apa saja yang bisa diakses Aktor. +8. System menampilkan halaman utama dengan menu sesuai role Aktor. + +### Alur Alternatif +- + +### Alur Pengecualian +* **Aktor tidak terdaftar:** + * System menampilkan pesan: “Unregistered user, please contact system administrator”. +* **Aktor ditemukan tetapi:** + * **Disabled:** System menampilkan pesan: “Disabled user, please contact system administrator”. + * **Password expired:** System menampilkan pesan: “Your password is expired, please contact system administrator”. + * **Password salah:** + * System menampilkan pesan: “Invalid login”. + * System menghitung jumlah percobaan login password yang gagal dan mencatat dalam Audit log (device dimana login attempt dilakukan, waktu). + * System menghentikan proses login untuk User ID tersebut selama x jam dan menampilkan pesan, ”Please try again in x hours or contact system administrator”. + +### Kondisi Akhir +* Aktor masuk ke halaman utama dan mendapat akses menu-menu system yang sesuai. +* Audit mencatat User ID, waktu, device dimana Aktor melakukan login. + +--- + +## Use Case – Patient Registration +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-02a | +| **Use Case Name** | Patient Registration | +| **Aktor Utama** | Admin Lab / Clerk, Analis Lab, Analis Lab Senior, Super User, Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Mencatatkan data demografi pasien baru ke oleh System | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi dalam System.
3. Pasien menunjukkan identitas yang sah (kartu identitas, atau rujukan). | + +### Alur Utama +1. Aktor membuka halaman Patient Management – Patient Registration. +2. Aktor memasukkan PID. +3. System memeriksa apakah PID sudah ada. +4. System meminta detail pasien (nama, tanggal lahir, jenis kelamin, informasi kontak, nomor identitas, dst). +5. Aktor memasukkan informasi demografis pasien, dengan mandatory data: + - patient.NameFirst + - patient.Gender + - patient.Birthdate +6. Jika Aktor memasukkan `patidt.IdentifierType` dan `patidt.Identifier`, maka System memeriksa apakah sudah ada record pasien yang menggunakan Identifier yang sama. +7. System membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A04` (Register), mengkonfirmasi registrasi berhasil dan menampilkan ringkasan pasien. +8. Aktor memberikan konfirmasi pendaftaran kepada Pasien (misalnya, slip cetak atau ID digital – barcode, QRIS, dll). + +### Alur Alternatif +* **Record pasien sudah ada:** + 1. Aktor memasukkan PID. + 2. System mengambil record yang sudah ada dan menampilkan data di halaman Patient Management – Patient Search & Update. + 3. Aktor memperbarui data jika diperlukan. + 4. Sistem menyimpan perubahan dan membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A08` (Update patient information). + +### Alur Pengecualian +* **Mandatory data tidak ada:** + * System menolak menyimpan record. + * Aktor diminta untuk melengkapi, setidaknya mandatory data. +* **Record pasien tidak ada tetapi ditemukan record yang menggunakan `patidt.IdentifierType` dan `patidt.Identifier` yang sama:** + * System menampilkan pesan ’Multiple IDs found”. + * System menampilkan records dengan `patidt.IdentifierType` dan `patidt.Identifier` yang sama. + * Aktor melakukan review. + * Aktor memilih salah satu dari kemungkinan berikut: + 1. Melanjutkan membuat record pasien baru, mengabaikan record ganda. + 2. Melanjutkan membuat record pasien baru, kemudian menggabungkan record pasien (lihat UC-02b). + 3. Membatalkan pendaftaran. + +### Kondisi Akhir +* Record pasien dibuat atau diperbarui di System. +* PID pasien tersedia untuk test ordering & tracing. +* Audit mencatat bahwa record dibuat/diperbarui secara manual, User ID yang mendaftarkan/memperbarui data pasien, device dimana, kapan, dan data apa yang dimasukkan. + +--- + +## Use Case – Patient Link +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-02b | +| **Use Case Name** | Patient Link | +| **Aktor Utama** | Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Link (menghubungkan) satu atau beberapa record (PID) pasien (source) dengan record pasien lainnya (destination). PatientID destination adalah surviving entity, yang akan digunakan dalam semua aktivitas laboratorium. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi dalam System.
3. PID source dan destination telah tercatat dalam System.
4. PID source dan destination memiliki `patidt.IdentifierType` dan `patidt.Identifier` yang sama atau nama, alamat dan tanggal lahir yang sama. | + +### Alur Utama +1. Aktor membuka halaman Patient Management - Patient Link. +2. Aktor mencari PID menggunakan: + - `patidt.IdentifierType` dan `patidt.Identifier` + - Nama, alamat dan tanggal lahir +3. System menampilkan semua PID dengan `patidt.IdentifierType` dan `patidt.Identifier` dan/atau nama, alamat dan tanggal lahir yang sama. +4. Aktor memilih dan menentukan satu PID untuk menjadi destination. (Lihat Alur Pengecualian). +5. Aktor memilih dan menentukan satu atau lebih, PID yang menjadi source. (Lihat Alur Pengecualian). +6. Aktor menghubungkan PID-PID tersebut dengan menekan tombol Link. +7. System meminta konfirmasi dari Aktor dengan menampilkan pesan,” Please confirm to link these patient records”. Disertai pilihan “Confirm” dan “Cancel”. +8. Aktor mengkonfirmasi Patient Link dengan menekan tombol Confirm. +9. System melakukan: + - Membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A24` (Link Patient Information). + - Mengkonfirmasi Patient Link berhasil. + - Menampilkan ringkasan PID yang dihubungkan. + +### Alur Alternatif +- + +### Alur Pengecualian +* **System menemukan bahwa suatu record pasien telah menjadi source, ditandai dengan field `patient.LinkTo` telah terisi dengan PID dari record lain (ditampilkan):** + * **Multiple link:** + * Aktor memilih dan menunjuk record tersebut sebagai source bagi PID yang berbeda. + * System menampilkan peringatan “Multiple link” di samping PID tersebut dan pilihan (check mark) tidak bisa dilakukan. + * **Multi-level Link:** + * Aktor memilih dan menunjuk record tersebut sebagai destination bagi PID yang berbeda. + * System menampilkan peringatan “Multi-level link” di samping PID tersebut dan pilihan (check mark) tidak bisa dilakukan. + * Jika semua atau satu-satunya PID mendapat peringatan tersebut maka, proses Patient Link sama sekali tidak bisa dilanjutkan. + * Jika ada PID lain yang tidak mendapat peringatan, maka proses Patient Link dilanjutkan atas PID tanpa peringatan. + +### Kondisi Akhir +* PID source terhubung dengan PID destination. +* Relasi source dengan test order dan lain-lain tidak berubah sebelum dan sesudah proses Patient Link. +* Semua test order milik PID source dan destination bisa ditampilkan dalam satu cumulative view/report. +* PID destination tersedia untuk test ordering & tracing. +* PID source tetap bisa dicari tetapi tidak bisa di-edit maupun digunakan untuk test ordering. +* Audit mencatat Patient Link dilakukan secara manual, waktu, User ID yang melakukan Patient Link serta device dimana aktivitas tersebut dilakukan. + +--- + +## Use Case – Patient Unlink +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-02c | +| **Use Case Name** | Patient Unlink | +| **Aktor Utama** | Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Melepaskan link antara source PID dan destination PID. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi dalam System.
3. Pasien sudah pernah registrasi di System, ditandai dengan adanya PID dengan `patidt.IdentifierType` dan `patidt.Identifier` yang sama. | + +### Alur Utama +1. Aktor membuka halaman Patient Management – Patient Unlink. +2. Aktor mencari record pasien menggunakan PID. +3. System menampilkan PID berikut data demografinya dan semua linked PID. +4. Aktor uncheck source PID(s) yang hendak dilepaskan dari destination PID. +5. Aktor melepas hubungan PID-PID tersebut dengan menekan tombol Unlink. +6. System meminta konfirmasi dari Aktor dengan menampilkan pesan,” Please confirm to unlink these patient records”. Disertai pilihan “Confirm” dan “Cancel”. +7. Aktor mengkonfirmasi Patient Unink dengan menekan tombol Confirm. +8. System melakukan: + - Mengosongkan field `patient.LinkTo` dari source PID. + - Membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A37` (Unlink Patient Information). + - Mengkonfirmasi Patient Unlink berhasil. + - Menampilkan ringkasan destination dan source PID yang unlinked. + +### Alur Alternatif +- + +### Alur Pengecualian +- + +### Kondisi Akhir +* Source PID aktif kembali, bisa diedit dan tersedia untuk test ordering & tracing. +* Unlink source terjadi bisa isi field LinkTo dikosongkan Kembali. +* Audit mencatat Patient Unlink dilakukan secara manual, waktu, User ID yang melakukan Patient Unlink dan device dimana aktivitas tersebut dilakukan. + +--- + +## Use Case – Patient Admission +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-03a | +| **Use Case Name** | Patient Admission | +| **Aktor Utama** | Admin Lab / Clerk, Analis Lab, Analis Lab Senior, Super User, Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Menerima pasien di fasyankes untuk perawatan atau observasi. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi oleh System.
3. Record pasien tersedia di System, ditandai dengan adanya PID. | + +### Alur Utama +1. Aktor membuka halaman Patient Visit Management – Patient Admission. +2. Aktor memasukkan PID. +3. System memeriksa apakah PID ada. +4. System menampilkan data demografi pasien dan meminta data-data: + - **Mandatory data:** PVID, dokter, location. + - **Optional data:** EpisodeID, diagnosis (bisa lebih dari satu), lampiran-lampiran. +5. System membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A01` (Admit), mengkonfirmasi admission berhasil dan menampilkan ringkasan admission. +6. Aktor memberikan konfirmasi admission kepada Pasien (misalnya, slip cetak atau ID digital – barcode, QRIS, dll). + +### Alur Alternatif +* **PID tidak ada:** + 1. System menampilkan pesan, “PID does not exist. Proceed to Patient Registration?”. + 2. Aktor memilih “Yes” dan System membuka halaman Patient Management – Patient Registration. + 3. Aktor melakukan activity patient registration dilanjutkan patient admission. +* **Pembaruan optional data:** + 1. Aktor membuka halaman Patient Visit Management – Admission Search & Update. + 2. Aktor memasukkan PVID. + 3. System mengambil record yang sudah ada. + 4. Aktor memperbarui data jika diperlukan. + 5. Sistem menyimpan perubahan. + +### Alur Pengecualian +* **Mandatory data tidak ada:** + * System menolak menyimpan record. + * Aktor diminta untuk melengkapi, setidaknya mandatory data. + +### Kondisi Akhir +* Kunjungan pasien ke fasyankes tercatat (patvisit records) di System, ditandai dengan adanya PVID dan direlasikan dengan dokter dan ruangan di fasyankes. +* Audit mencatat admission/perubahannya dilakukan secara manual, User ID yang melakukan, device dimana, kapan, dan data apa saja yang dimasukkan. + +--- + +## Use Case – Cancel Admission +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-03b | +| **Use Case Name** | Cancel Patient Admission | +| **Aktor Utama** | Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Membatalkan penerimaan pasien di fasyankes. Pembatalan bisa disebabkan: Data registrasi salah atau tidak lengkap, Cakupan asuransi tidak valid, Pasien menolak rawat inap, Pasien dialihkan, Permintaan rawat inap salah, Kondisi pasien berubah, Permintaan pasien, dll. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi oleh System.
3. Patient Visit Record tersedia di System, ditandai dengan adanya PVID. | + +### Alur Utama +1. Aktor membuka halaman Patient Visit Management – Admission Search & Update. +2. Aktor memasukkan PVID. +3. System menampilkan data admission pasien. +4. Aktor mengkonfirmasi pembatalan admission ke pihak terkait dan melakukan pembatalan. +5. System membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A11` (Cancel Admit), mengkonfirmasi cancel patient admission berhasil dan menampilkan ringkasan cancel patient admission. +6. Aktor memberikan konfirmasi cancel patient admission kepada pihak terkait (misalnya, slip cetak atau ID digital – barcode, QRIS, dll). + +### Alur Alternatif +- + +### Alur Pengecualian +- + +### Kondisi Akhir +* Cancel patient admission tercatat (patvisit records) di System, ditandai dengan record di `patvisitadt` dengan `patvisitadt.Code: A11`. +* Audit mencatat cancel patient admission dilakukan secara manual, User ID yang melakukan, device dimana, kapan, dan data apa yang dimasukkan. + +--- + +## Use Case – Change Attending Doctor +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-03c | +| **Use Case Name** | Change Attending Doctor | +| **Aktor Utama** | Admin Lab / Clerk, Analis Lab, Analis Lab Senior, Super User, Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Mengganti dokter yang bertanggung jawab atas pengobatan pasien (DPJP). | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi oleh System.
3. Patient Visit Record tersedia di System, ditandai dengan adanya PVID dan telah memiliki data Attending Doctor (`patvisitadt.AttDoc`). | + +### Alur Utama +1. Aktor membuka halaman Patient Visit Management – Admission Search & Update. +2. Aktor memasukkan PVID. +3. System menampilkan data admission pasien. +4. Aktor mengganti Attending Doctor. +5. System membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A54` (Change Attending Doctor), mengkonfirmasi penggantian dokter berhasil dan menampilkan data admission yang telah diperbarui. + +### Alur Alternatif +- + +### Alur Pengecualian +- + +### Kondisi Akhir +* Penggantian Attending Doctor di System sehingga bisa dilakukan pelacakan Attending Doctor sekarang dan sebelumnya. +* Audit mencatat User ID yang melakukan perubahan Attending Doctor, device dimana perubahan dilakukan, kapan. + +--- + +## Use Case – Change Consulting Doctor +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-03d | +| **Use Case Name** | Change Consulting Doctor | +| **Aktor Utama** | Admin Lab / Clerk, Analis Lab, Analis Lab Senior, Super User, Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Mengganti dokter konsulen. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi oleh System.
3. Patient Visit Record tersedia di System, ditandai dengan adanya PVID dan telah memiliki data Consulting Doctor (`patvisitadt.CnsDoc`). | + +### Alur Utama +1. Aktor membuka halaman Patient Visit Management – Admission Search & Update. +2. Aktor memasukkan PVID. +3. System menampilkan data admission pasien. +4. Aktor mengganti Consulting Doctor. +5. System membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A61` (Change Consulting Doctor), mengkonfirmasi penggantian dokter berhasil dan menampilkan data admission yang telah diperbarui. + +### Alur Alternatif +- + +### Alur Pengecualian +- + +### Kondisi Akhir +* Penggantian Consulting Doctor di System sehingga bisa dilakukan pelacakan Consulting Doctor sekarang dan sebelumnya. +* Audit mencatat User ID yang melakukan perubahan Consulting Doctor, device dimana perubahan dilakukan, kapan. + +--- + +## Use Case – Patient Transfer +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-04 | +| **Use Case Name** | Patient Transfer | +| **Aktor Utama** | Admin Lab / Clerk, Analis Lab, Analis Lab Senior, Super User, Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Memindahkan pasien dari satu lokasi ke lokasi lainnya. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi oleh System.
3. Patient Visit Record tersedia di System, ditandai dengan adanya PVID dan telah memiliki data Location ID (`patvisitadt.LocationID`). | + +### Alur Utama +1. Aktor membuka halaman Patient Visit Management – Transfer. +2. Aktor memasukkan PVID. +3. System menampilkan data admission pasien. +4. Aktor mengganti Location ID. +5. System membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A02` (Patient Transfer), mengkonfirmasi perpindahan lokasi berhasil dan menampilkan data admission yang telah diperbarui. + +### Alur Alternatif +- + +### Alur Pengecualian +- + +### Kondisi Akhir +* Penggantian Location ID di System sehingga bisa dilakukan pelacakan Location ID sekarang dan sebelumnya. +* Audit mencatat User ID yang melakukan perubahan Location ID, device dimana perubahan dilakukan dan kapan. + +--- + +## Use Case – Patient Discharge +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-04a | +| **Use Case Name** | Patient Discharge | +| **Aktor Utama** | Admin Lab / Clerk, Analis Lab, Analis Lab Senior, Super User, Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Mengakhiri kunjungan pasien. Close billing. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi oleh System.
3. Patient Visit Record tersedia di System, ditandai dengan adanya PVID. | + +### Alur Utama +1. Aktor membuka halaman Patient Visit Management – Discharge. +2. Aktor memasukkan PVID. +3. System memeriksa apakah PVID tersebut memiliki test order. +4. System memeriksa `orderstatus.OrderStatus` dari test order tsb. +5. System menampilkan data admission pasien. +6. Aktor mengisikan tanggal discharge. +7. System membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A03` (Discharge), mengkonfirmasi discharge/end visit berhasil dan menampilkan data admission yang telah di-discharge. + +### Alur Alternatif +- + +### Alur Pengecualian +* **Open test order:** + * System menolak discharge, jika menemukan `orderstatus.OrderStatus` bernilai ”A” atau “IP” atau “SC” atau “HD”. + * Aktor diminta untuk menyelesaikan test order terkait. + +### Kondisi Akhir +* Discharge visit di System. +* Audit mencatat User ID yang melakukan discharge, device dimana discharge dilakukan dan kapan. +* Semua record terkait visit tersebut tidak bisa diedit/update lagi – data-data pada `patvisit`, `patdiag`, `patvisitbill`. Hal-hal berikut tidak bisa dilakukan lagi: + - Perpindahan lokasi dan/atau dokter. + - Test order. + - Billing is closed. +* **Cancel discharge:** + - Bisa dilakukan atas instruksi dari HIS, misalnya berupa ADT message. + - Oleh orang tertentu saja di lab. + - Tidak meng-update existing record tetapi men-trigger tambahan `patvisitadt` record dengan Code: A13 (cancel discharge). + +--- + +## Use Case – Cancel Discharge +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-04b | +| **Use Case Name** | Cancel Patient Discharge | +| **Aktor Utama** | Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Membatalkan Patient Discharge. Open billing. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi oleh System.
3. Patient Visit Record tersedia di System, ditandai dengan adanya PVID dan telah discharge. | + +### Alur Utama +1. Aktor membuka halaman Patient Visit Management – Cancel Patient Discharge. +2. Aktor memasukkan PVID. +3. System menampilkan data admission pasien. +4. Aktor membatalkan discharge dengan menekan tombol Cancel Discharge. +5. System membuat record baru di `patvisitadt` dengan `patvisitadt.Code: A13` (Cancel Discharge), mengkonfirmasi cancel discharge berhasil dan menampilkan data admission yang telah dibatalkan discharge-nya. + +### Alur Alternatif +- + +### Alur Pengecualian +- + +### Kondisi Akhir +* Pembatalan discharge di System. +* Audit mencatat cancel discharge dilakukan secara manual, User ID yang melakukan, device dimana activity dilakukan dan kapan. +* Semua record terkait visit tersebut kembali bisa diedit/update lagi – data-data pada `patvisit`, `patdiag`, `patvisitbill`. Hal-hal berikut bisa dilakukan lagi: + - Perpindahan lokasi dan/atau dokter. + - Test order. + - Billing is re-open. + +--- + +## Use Case – Test Ordering +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-5a | +| **Use Case Name** | Test Ordering | +| **Aktor Utama** | Admin Lab / Clerk, Analis Lab, Analis Lab Senior, Super User, Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Membuat test order untuk pasien. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi oleh System.
3. Patient Visit Record tersedia di System, ditandai dengan adanya PVID. | + +### Alur Utama +1. Aktor membuka halaman Test Ordering – New Test Order. +2. Aktor memasukkan PVID. +3. System menampilkan data demografi, daftar PVID pasien berikut daftar OrderID (OID) yang telah dibuat sebelumnya (menghindari test order berlebihan). +4. Aktor bisa menambahkan komentar dan/atau lampiran ke test order. +5. Aktor memilih test yang diperlukan. +6. Aktor bisa memilih mencetak labels segera setelah klik tombol Save, dengan mencentang Print Patient Label, Print Order Label, Print Specimen Label check boxes. +7. Aktor menyimpan test order dengan menekan tombol Save. +8. System secara otomatis memberi OID. +9. System otomatis membuat records di table specimens. +10. System, mengkonfirmasi test ordering berhasil dan menampilkan data test order berikut daftar SID. + +### Alur Alternatif +* **PVID belum ada:** + 1. System mengarahkan Aktor ke halaman Patient Visit Management – Patient Admission. + 2. Aktor melakukan activity patient admission. + 3. Aktir kembali ke test ordering. +* **Test ordering menggunakan PID:** + 1. Aktor membuka halaman Test Ordering – New Test Order. + 2. Aktor memasukkan PID. + 3. System menampilkan daftar PVID yang belum discharge. + 4. Aktor memilih salah satu PVID dan melanjutkan activity test ordering. +* **Future Order:** + 1. Aktor mengisi Effective Date (`ordertest.EffDate`) untuk menjadwalkan kapan test order mulai dikerjakan. + 2. Aktor menyimpan test order dengan menekan tombol Save. + 3. System memberikan OID yang sesuai dengan Effective Date. +* **OID sudah ada:** + 1. Aktor membuka halaman Test Ordering – Test Order Search & Update. + 2. Aktor memasukan OID. + 3. System menampilkan data-data test order. + 4. Aktor melakukan update dan menyimpannya. +* **Non patient option** (Not detailed in text). + +### Alur Pengecualian +- + +### Kondisi Akhir +* Test order terbentuk di System ditandai dengan adanya OID dengan status (`orderstatus.OrderStatus`) ”SC” (In process, scheduled). +* SID terbentuk dan specimen label bisa dicetak atau tercetak otomatis. +* Audit mencatat test order dilakukan secara manual, User ID yang melakukan, device dimana activity dilakukan dan kapan. + +--- + +## Use Case – Update Test Order +| **Field** | **Description** | +| :--- | :--- | +| **Use Case ID** | UC-5b | +| **Use Case Name** | Update Test Order | +| **Aktor Utama** | Admin Lab / Clerk, Analis Lab, Analis Lab Senior, Super User, Supervisor Lab, Manajer Lab | +| **Aktor Sekunder** | Pasien | +| **Tujuan** | Memperbarui test order untuk pasien. | +| **Prasyarat** | 1. System beroperasi dan dapat diakses.
2. Petugas pendaftaran telah terautentikasi oleh System.
3. Test order tersedia di System, ditandai dengan adanya OID. | + +### Alur Utama +1. Aktor membuka halaman Test Ordering – Test Order Search & Update. +2. Aktor memasukkan OID. +3. System menampilkan data-data test order. +4. Aktor melakukan update dan menyimpannya. +5. System, mengkonfirmasi update test order berhasil dan menampilkan data test order berikut daftar SID. + +### Alur Alternatif +* **PVID belum ada:** + 1. System mengarahkan Aktor ke halaman Patient Visit Management – Patient Admission. + 2. Aktor melakukan activity patient admission. + 3. Aktir kembali ke test ordering. +* **Non patient option** (Not detailed in text). + +### Alur Pengecualian +* **Test order tidak ada:** + * System menolak melakukan update dan menampilkan pesan,” Test order does not exists”. +* **Test order berstatus closed:** Ditandai dengan `ordertest.EndDate` memiliki value dan `orderstatus.OrderStatus` bernilai CL (Closed). + * System menolak melakukan update dan menampilkan pesan,” This test order is inaccessible”. +* **Test order berstatus archived:** Ditandai dengan `ordertest.ArchiveDate` memiliki value dan `orderstatus.OrderStatus` bernilai AC (Archived). + * System menolak melakukan update dan menampilkan pesan,” This test order is already archived”. +* **Test order berstatus deleted:** Ditandai dengan `ordertest.DelDate` memiliki value dan `orderstatus.OrderStatus` bernilai DL (Deleted). + * System menolak melakukan update dan menampilkan pesan,” This test order is already deleted”. +* **Update dilakukan dengan menghapus test yang telah ada hasilnya:** + * System menampilkan data-data test order. + * Aktor mengganti test yang telah ada hasilnya. + * System menolak melakukan update dan menampilkan pesan,” This test order is inaccessible”. + +### Kondisi Akhir +* Test order terbentuk di System ditandai dengan adanya OID dengan status (`orderstatus.OrderStatus`) ”SC” (In process, scheduled). +* SID terbentuk dan specimen label bisa dicetak atau tercetak otomatis. +* Audit mencatat test order dilakukan secara manual, User ID yang melakukan, device dimana activity dilakukan dan kapan. +``` \ No newline at end of file diff --git a/src/app.css b/src/app.css index 5a4635e..857ebe7 100644 --- a/src/app.css +++ b/src/app.css @@ -1,8 +1,85 @@ @import 'tailwindcss'; -@plugin 'daisyui' { - themes: light --default, emerald, forest, dark; +@plugin 'daisyui'; + +@plugin 'daisyui/theme' { + name: 'clqms'; + default: true; + prefersdark: false; + color-scheme: light; + + --color-base-100: oklch(98% 0.01 240); + --color-base-200: oklch(96% 0.015 240); + --color-base-300: oklch(93% 0.02 240); + --color-base-content: oklch(25% 0.04 240); + + /* Primary: Emerald Green */ + --color-primary: oklch(60% 0.16 150); + --color-primary-content: oklch(98% 0.01 150); + + /* Secondary: Dark Blue */ + --color-secondary: oklch(35% 0.08 250); + --color-secondary-content: oklch(98% 0.01 250); + + /* Accent: Royal Blue */ + --color-accent: oklch(55% 0.22 250); + --color-accent-content: oklch(98% 0.01 250); + + --color-neutral: oklch(50% 0.05 240); + --color-neutral-content: oklch(98% 0.01 240); + + /* Semantic Colors */ + --color-info: oklch(70% 0.15 230); + --color-info-content: oklch(25% 0.04 230); + --color-success: oklch(65% 0.18 140); + --color-success-content: oklch(98% 0.01 140); + --color-warning: oklch(80% 0.16 85); + --color-warning-content: oklch(25% 0.04 85); + --color-error: oklch(60% 0.25 25); + --color-error-content: oklch(98% 0.01 25); + + /* Border radius */ + --radius-selector: 0.5rem; + --radius-field: 0.375rem; + --radius-box: 0.5rem; + + /* Base sizes */ + --size-selector: 0.25rem; + --size-field: 0.25rem; + + /* Border size */ + --border: 1px; + + /* Effects */ + --depth: 1; + --noise: 0; } @theme { - /* Custom theme variables can be added here */ + /* Custom color helpers */ + --color-emerald-50: #ecfdf5; + --color-emerald-100: #d1fae5; + --color-emerald-200: #a7f3d0; + --color-emerald-300: #6ee7b7; + --color-emerald-400: #34d399; + --color-emerald-500: #10b981; + --color-emerald-600: #059669; + --color-emerald-700: #047857; + --color-emerald-800: #065f46; + --color-emerald-900: #064e3b; + + --color-blue-50: #eff6ff; + --color-blue-100: #dbeafe; + --color-blue-200: #bfdbfe; + --color-blue-300: #93c5fd; + --color-blue-400: #60a5fa; + --color-blue-500: #3b82f6; + --color-blue-600: #2563eb; + --color-blue-700: #1d4ed8; + --color-blue-800: #1e40af; + --color-blue-900: #1e3a8a; + + --color-navy-600: #1e3a5f; + --color-navy-700: #1a2f4a; + --color-navy-800: #0f1f33; + --color-navy-900: #0a1628; } diff --git a/src/app.html b/src/app.html index ee46389..d8efd56 100644 --- a/src/app.html +++ b/src/app.html @@ -1,5 +1,5 @@ - + diff --git a/src/lib/api/specimens.js b/src/lib/api/specimens.js new file mode 100644 index 0000000..6bb87f0 --- /dev/null +++ b/src/lib/api/specimens.js @@ -0,0 +1,15 @@ +import { get } from './client.js'; + +export async function fetchSpecimenTypes(params = {}) { + const query = new URLSearchParams(params).toString(); + return get(query ? `/api/specimen/type?${query}` : '/api/specimen/type'); +} + +export async function fetchSpecimenType(id) { + return get(`/api/specimen/type/${id}`); +} + +export async function fetchSpecimenCollections(params = {}) { + const query = new URLSearchParams(params).toString(); + return get(query ? `/api/specimen/collection?${query}` : '/api/specimen/collection'); +} diff --git a/src/lib/api/tests.js b/src/lib/api/tests.js index ba99823..91fda5f 100644 --- a/src/lib/api/tests.js +++ b/src/lib/api/tests.js @@ -20,6 +20,13 @@ export async function createTest(data) { SeqRpt: data.SeqRpt, VisibleScr: data.VisibleScr ? '1' : '0', VisibleRpt: data.VisibleRpt ? '1' : '0', + // Type-specific fields + SpecimenType: data.SpecimenType, + Unit: data.Unit, + Formula: data.Formula, + // Reference ranges (only for TEST and CALC) + refnum: data.refnum, + reftxt: data.reftxt, }; return post('/api/tests', payload); } @@ -36,6 +43,21 @@ export async function updateTest(data) { SeqRpt: data.SeqRpt, VisibleScr: data.VisibleScr ? '1' : '0', VisibleRpt: data.VisibleRpt ? '1' : '0', + // Type-specific fields + SpecimenType: data.SpecimenType, + Unit: data.Unit, + Formula: data.Formula, + // Reference ranges (only for TEST and CALC) + refnum: data.refnum, + reftxt: data.reftxt, }; return patch('/api/tests', payload); } + +export async function deleteTest(id) { + // Soft delete - set IsActive to '0' + return patch('/api/tests', { + TestSiteID: id, + IsActive: '0', + }); +} diff --git a/src/lib/api/visits.js b/src/lib/api/visits.js index f14543e..1f995d4 100644 --- a/src/lib/api/visits.js +++ b/src/lib/api/visits.js @@ -32,3 +32,7 @@ export async function createADT(data) { export async function updateADT(data) { return patch('/api/patvisitadt', data); } + +export async function fetchVisitADTHistory(visitId) { + return get(`/api/patvisitadt/visit/${encodeURIComponent(visitId)}`); +} diff --git a/src/lib/components/HelpTooltip.svelte b/src/lib/components/HelpTooltip.svelte new file mode 100644 index 0000000..9ca0c2b --- /dev/null +++ b/src/lib/components/HelpTooltip.svelte @@ -0,0 +1,45 @@ + + + diff --git a/src/lib/components/Sidebar.svelte b/src/lib/components/Sidebar.svelte index a9e8fd0..100dc4e 100644 --- a/src/lib/components/Sidebar.svelte +++ b/src/lib/components/Sidebar.svelte @@ -97,16 +97,16 @@