Queue Management & Display Board
Relevant source files
The following files were used as context for generating this wiki page:The Queue Management and Display Board system facilitates real-time patient flow tracking within the clinic and provides a privacy-conscious waiting-room interface. The system categorizes appointments into specific states and prioritizes patients based on consultation status, urgent tags, and arrival time.
Sources: packages/contracts/src/queue.ts:1-12, README.md:21-21
Queue Categorization
The queue system organizes one day's appointments into four distinct logical groups, presented as tabs in the clinic dashboard.
| Tab | Content | Ordering Logic |
|---|---|---|
| My OPD | Active patients (Waiting or In Consultation) | 1. In consultation, 2. Priority-tagged, 3. Arrival order |
| Booked | Patients who have not arrived yet | By scheduled time |
| Completed | Finished consultations | Most recent first |
| Closed | Cancelled, No-show, or Rescheduled visits | By time of closure |
Sources: packages/contracts/src/queue.ts:4-12, apps/web/app/clinic/queue/page.tsx:28-28
Sorting and Priority
The "My OPD" view uses a specific multi-tier sorting algorithm to ensure clinical efficiency:
- Status: Patients currently with the doctor (
in_consultation) appear first. - Priority Tags: Patients with tags configured as
sortToTop(e.g., "Emergency") are moved ahead of the general waiting list. - Arrival Time: Among general waiting patients, those who checked in earlier appear higher.
Sources: apps/e2e/tests/queue.spec.ts:63-75, apps/api/test/queue.int.test.ts:98-111
System Architecture
The queue system utilizes a modular monolith backend (Fastify) and a Next.js frontend. Data is synchronized via polling to maintain real-time status updates for staff.
This diagram illustrates the data flow from the PostgreSQL database through the Queue Service to the web clients.
Sources: apps/web/app/clinic/queue/page.tsx:32-32, apps/api/src/modules/queue/routes.ts:25-30, README.md:18-21
Waiting-Room Display Board
The Display Board is a public-facing interface designed for waiting rooms. It ensures patient privacy by displaying only token numbers and doctor names, never full patient names.
Display Privacy and Security
- Token-based URLs: Screens are identified by a high-entropy token in the URL fragment (e.g.,
/display#token). The API does not store the token itself, only a hash. - Data Anonymization: The
DisplayBoardcontract strictly limits fields todoctorName,nowServing(token), andnext(array of tokens). - Revocation: Clinic admins can revoke a screen link at any time, which immediately invalidates the token hash in the database.
Sources: packages/contracts/src/queue.ts:46-56, apps/api/test/queue.int.test.ts:134-164, apps/e2e/tests/queue.spec.ts:93-108
Display Board API Interaction
The display board operates as a public endpoint where the token is the sole credential.
The interaction ensures that a public display device only receives anonymized token data without requiring staff authentication.
Sources: apps/api/src/modules/queue/routes.ts:48-51, apps/api/test/queue.int.test.ts:145-155
Staff Queue Interaction
Staff members (Doctors and Front Desk) interact with the queue to manage patient transitions.
Key Actions
- Check-in: Moves a patient from "Booked" to "My OPD".
- Start Consultation: Changes status to
in_consultationand moves the patient to the top of the "My OPD" list. - Complete: Moves the patient to the "Completed" tab and updates the
averageConsultationMinutesmetric. - Cancel/No-show: Moves the patient to the "Closed" tab.
Sources: apps/web/app/clinic/queue/page.tsx:88-100, apps/api/test/queue.int.test.ts:109-118
API Endpoints
| Method | Endpoint | Access | Description |
|---|---|---|---|
| GET | /queue | Staff | Retrieves grouped appointments and average consultation time. |
| GET | /display-screens | Admin | Lists all configured waiting-room screens. |
| POST | /display-screens | Admin | Generates a new high-entropy display link. |
| POST | /display-screens/:id/revoke | Admin | Deletes a screen and invalidates its token. |
| POST | /display/board | Public | Returns token numbers for a specific display screen. |
Sources: apps/api/src/modules/queue/routes.ts:25-52
Data Structures
The system relies on strict Zod schemas to enforce data consistency across the monorepo.
QueueResponse
export const QueueResponse = z.object({
date: z.iso.date(),
myOpd: z.array(Appointment),
booked: z.array(Appointment),
completed: z.array(Appointment),
closed: z.array(Appointment),
averageConsultationMinutes: z.number().nullable(),
});
Sources: packages/contracts/src/queue.ts:14-22
DisplayBoard
export const DisplayBoard = z.object({
clinicName: z.string(),
date: z.iso.date(),
doctors: z.array(
z.object({
doctorName: z.string().nullable(),
nowServing: z.number().int().nullable(),
next: z.array(z.number().int()),
}),
),
});
Sources: packages/contracts/src/queue.ts:50-61
Implementation Details
UI Refresh Logic
The frontend implements a polling mechanism to keep the queue current:
- The queue data refreshes every 15 seconds while the page is visible.
- The "current time" reference updates every 30 seconds to accurately calculate waiting durations.
- Event listeners for
visibilitychangetrigger an immediate refresh when the user returns to the tab.
Sources: apps/web/app/clinic/queue/page.tsx:32-84
Performance Metrics
The system calculates the averageConsultationMinutes, which is the mean time elapsed from the start to the completion of all consultations for the selected day.
Sources: packages/contracts/src/queue.ts:20-21, apps/api/test/queue.int.test.ts:117-118
Summary
The Queue Management and Display Board module provides a unified interface for staff to manage patient throughput and for patients to track their status anonymously. By combining strict sorting logic, token-based privacy for public screens, and automated UI refreshes, the system ensures both operational efficiency and patient confidentiality.