clqms-fe1/docs/frontend-implementation-plan.md
mahdahar 6a270e181c feat: Complete Phase 0 foundation
- Initialize SvelteKit project with Tailwind CSS and DaisyUI
- Configure API base URL and environment variables
- Create base API client with JWT token handling (src/lib/api/client.js)
- Implement login/logout flow (src/lib/api/auth.js, src/routes/login/+page.svelte)
- Create root layout with navigation (src/routes/+layout.svelte)
- Set up protected route group with auth checks (src/routes/(app)/+layout.svelte)
- Create dashboard homepage (src/routes/(app)/dashboard/+page.svelte)
- Add auth state store with localStorage persistence (src/lib/stores/auth.js)

All Phase 0 foundation items completed per implementation plan.
2026-02-09 21:39:14 +07:00

16 KiB

CLQMS Frontend Implementation Plan

Project Overview

CLQMS (Clinical Laboratory Quality Management System) frontend built with SvelteKit using the KISS (Keep It Simple) principle.

Architecture Decisions (KISS Principles)

  • No TypeScript - Plain JavaScript to keep it simple
  • Tailwind CSS & DaisyUI - Utility classes, minimal custom CSS
  • Simple Fetch API - Manual wrapper functions, no codegen
  • 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

Implementation Phases

Phase 0: Foundation COMPLETED

Priority: High | Time Estimate: 1-2 hours | Status: Done

  • Initialize SvelteKit project with Tailwind CSS
  • Configure API base URL and environment variables
  • Create base API client with JWT token handling
  • Implement login/logout flow
  • Create root layout with navigation
  • Set up protected route group with auth checks
  • Create dashboard homepage

Key Files:

  • src/lib/api/client.js - Base fetch wrapper
  • src/lib/api/auth.js - Auth endpoints
  • src/lib/stores/auth.js - Auth state management
  • src/routes/+layout.svelte - Root layout
  • src/routes/(app)/+layout.svelte - Protected layout
  • src/routes/login/+page.svelte - Login page

Phase 1: Foundation Data

Priority: High | Time Estimate: 4-6 hours

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

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
  • GET /api/location/{id} - Get location details
  • GET /api/contact - List contacts
  • POST /api/contact - Create contact
  • 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)

API Endpoints:

  • GET /api/occupation - List occupations
  • POST /api/occupation - Create occupation
  • PATCH /api/occupation - Update occupation
  • GET /api/occupation/{id} - Get occupation details
  • GET /api/medicalspecialty - List specialties
  • POST /api/medicalspecialty - Create specialty
  • PATCH /api/medicalspecialty - Update specialty
  • GET /api/medicalspecialty/{id} - Get specialty details
  • GET /api/counter - List counters
  • POST /api/counter - Create counter
  • PATCH /api/counter - Update counter
  • DELETE /api/counter - Delete counter
  • GET /api/counter/{id} - Get counter details

1d. Master Data - Geography

  • Provinces list (read-only dropdown)
  • Cities list with province filter

API Endpoints:

  • GET /api/areageo/provinces - List provinces
  • GET /api/areageo/cities - List cities (with province_id filter)

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

2b. Advanced Patient Features

  • Patient identifier management (KTP, PASS, SSN, etc.)
  • Patient linking (family relationships)
  • Custodian/guardian assignment
  • Patient address management

Fields to Implement:

  • PatientID, AlternatePID
  • Prefix, NameFirst, NameMiddle, NameLast, NameMaiden, Suffix
  • Sex, Birthdate, PlaceOfBirth, Citizenship
  • Address fields (Street_1/2/3, ZIP, Province, City, Country)
  • Contact (Phone, MobilePhone, EmailAddress1/2)
  • Identifiers (PatIdt - type and number)
  • Demographics (Race, MaritalStatus, Religion, Ethnic)
  • Linked patients (LinkTo)
  • Custodian
  • DeathIndicator, TimeOfDeath
  • Comments (PatCom)

Phase 3: Patient Visits

Priority: High | Time Estimate: 2-3 hours

Dependencies: Patients, Master Data (locations, contacts)

  • Visits list page with filters
  • Create visit form
  • Edit visit form
  • View visits by patient
  • ADT workflow (Admit/Discharge/Transfer)

API Endpoints:

  • GET /api/patvisit - List visits
  • POST /api/patvisit - Create visit
  • PATCH /api/patvisit - Update visit
  • DELETE /api/patvisit - Delete visit
  • GET /api/patvisit/{id} - Get visit by ID
  • GET /api/patvisit/patient/{patientId} - Get visits by patient
  • POST /api/patvisitadt - Create ADT visit
  • PATCH /api/patvisitadt - Update ADT visit

Fields:

  • VisitID, PatientID, VisitDate, VisitType
  • SiteID, LocationID, DepartmentID
  • AttendingPhysician, ReferringPhysician

Phase 4: Specimen Management

Priority: Medium | Time Estimate: 2-3 hours

Dependencies: ValueSets (specimen types, collection methods, statuses)

  • Specimens list page
  • Specimen create/edit forms
  • Container definitions management
  • Specimen preparation methods
  • Specimen statuses
  • Collection methods

API Endpoints:

  • GET /api/specimen - List specimens
  • POST /api/specimen - Create specimen
  • PATCH /api/specimen - Update specimen
  • GET /api/specimen/{id} - Get specimen details
  • GET /api/specimen/container - List containers
  • POST /api/specimen/container - Create container
  • PATCH /api/specimen/container - Update container
  • GET /api/specimen/container/{id} - Get container details
  • GET /api/specimen/prep - List preparations
  • POST /api/specimen/prep - Create preparation
  • PATCH /api/specimen/prep - Update preparation
  • GET /api/specimen/prep/{id} - Get preparation details
  • GET /api/specimen/status - List statuses
  • POST /api/specimen/status - Create status
  • PATCH /api/specimen/status - Update status
  • GET /api/specimen/status/{id} - Get status details
  • GET /api/specimen/collection - List collection methods
  • POST /api/specimen/collection - Create collection method
  • PATCH /api/specimen/collection - Update collection method
  • GET /api/specimen/collection/{id} - Get collection method details

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 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 7: Results & Dashboard

Priority: High | Time Estimate: 2-3 hours

Dependencies: Orders

  • Dashboard with summary cards
  • Results list with patient filtering
  • Sample tracking view

API Endpoints:

  • GET /api/dashboard - Get dashboard summary
  • GET /api/result - Get patient results
  • GET /api/sample - Get samples

Dashboard Metrics:

  • pendingOrders
  • todayResults
  • criticalResults
  • activePatients

Phase 8: Organization Structure

Priority: Medium | Time Estimate: 2-3 hours

  • Accounts management
  • Sites management
  • Disciplines management
  • Departments management
  • Workstations management

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

Phase 9: Edge API (Instrument Integration)

Priority: Low | Time Estimate: 2-3 hours

  • Edge results viewer
  • Pending orders for instruments
  • 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

Reusable Components to Build

1. FormInput.svelte

Text input with label, validation, and error display.

<FormInput 
  label="Patient ID"
  name="patientId"
  value={patientId}
  required
  pattern="[A-Za-z0-9]+"
/>

2. SelectDropdown.svelte

Dropdown populated from ValueSets or API data.

<SelectDropdown
  label="Gender"
  name="sex"
  value={sex}
  options={genderOptions}
/>

3. DataTable.svelte

Sortable, paginated table with actions.

<DataTable
  columns={['ID', 'Name', 'Status']}
  data={patients}
  onEdit={handleEdit}
  onDelete={handleDelete}
  pagination={true}
/>

4. SearchBar.svelte

Search input with debounce.

5. Modal.svelte

Reusable modal for confirmations and forms.


Code Patterns

API Client Pattern

// lib/api/client.js
const API_BASE = import.meta.env.VITE_API_URL || 'http://localhost/clqms01';

export async function apiFetch(endpoint, options = {}) {
  const token = get(authToken);
  
  const res = await fetch(`${API_BASE}${endpoint}`, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      ...(token && { 'Authorization': `Bearer ${token}` }),
      ...options.headers
    }
  });
  
  if (res.status === 401) {
    // Handle unauthorized
    authToken.set(null);
    goto('/login');
    return;
  }
  
  return res.json();
}

Form Handling Pattern

<script>
  let formData = { name: '', email: '' };
  let errors = {};
  let loading = false;

  async function handleSubmit() {
    loading = true;
    errors = {};
    
    const result = await createItem(formData);
    
    if (result.status === 'error') {
      errors = result.errors || { general: result.message };
    } else {
      // Success - redirect or show message
    }
    
    loading = false;
  }
</script>

<form on:submit|preventDefault={handleSubmit}>
  <FormInput 
    label="Name" 
    bind:value={formData.name}
    error={errors.name}
  />
  <button type="submit" disabled={loading}>
    {loading ? 'Saving...' : 'Save'}
  </button>
</form>

Store Pattern for ValueSets

// lib/stores/valuesets.js
import { writable } from 'svelte/store';

export const valueSets = writable({});

export async function loadValueSet(code) {
  const res = await fetch(`/api/valueset?VSetCode=${code}`);
  const data = await res.json();
  
  valueSets.update(vs => ({
    ...vs,
    [code]: data.data || []
  }));
}

// Usage in component:
// onMount(() => loadValueSet('GENDER'));

Environment Setup

Create .env file:

VITE_API_URL=http://localhost/clqms01

Getting Started

  1. Initialize SvelteKit:

    npm create svelte@latest clqms-fe
    cd clqms-fe
    npm install
    npx svelte-add@latest tailwindcss
    npm install
    
  2. Configure tailwind.config.js:

    export default {
      content: ['./src/**/*.{html,js,svelte,ts}'],
      theme: { extend: {} },
      plugins: []
    };
    
  3. Start with Phase 0:

    • Create API client
    • Set up auth stores
    • Build login page
    • Create protected layout

Navigation Structure

Dashboard (Home)
├── Master Data
│   ├── ValueSets
│   ├── Locations
│   ├── Contacts
│   ├── Occupations
│   ├── Medical Specialties
│   └── Counters
├── Organization
│   ├── Accounts
│   ├── Sites
│   ├── Disciplines
│   ├── Departments
│   └── Workstations
├── Patients
│   ├── All Patients
│   └── Patient Visits
├── Laboratory
│   ├── Specimens
│   ├── Tests
│   ├── Orders
│   └── Results
└── Edge
    └── Instrument Status

Notes

  • Use +layout.server.js for server-side auth checks
  • Use SvelteKit's invalidateAll() after mutations
  • Cache ValueSets in localStorage for better UX
  • Implement optimistic updates where appropriate
  • Use loading states for all async operations
  • Add toast notifications for success/error feedback