fluxq-engine 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -0
- package/dist/api/client.d.ts +82 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +75 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/controllers.d.ts +12 -0
- package/dist/api/controllers.d.ts.map +1 -0
- package/dist/api/controllers.js +569 -0
- package/dist/api/controllers.js.map +1 -0
- package/dist/api/middleware.d.ts +7 -0
- package/dist/api/middleware.d.ts.map +1 -0
- package/dist/api/middleware.js +133 -0
- package/dist/api/middleware.js.map +1 -0
- package/dist/api/routes.d.ts +3 -0
- package/dist/api/routes.d.ts.map +1 -0
- package/dist/api/routes.js +46 -0
- package/dist/api/routes.js.map +1 -0
- package/dist/api/server.d.ts +4 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +72 -0
- package/dist/api/server.js.map +1 -0
- package/dist/core/classifiers/bloodPressure.d.ts +9 -0
- package/dist/core/classifiers/bloodPressure.d.ts.map +1 -0
- package/dist/core/classifiers/bloodPressure.js +178 -0
- package/dist/core/classifiers/bloodPressure.js.map +1 -0
- package/dist/core/classifiers/cholesterol.d.ts +9 -0
- package/dist/core/classifiers/cholesterol.d.ts.map +1 -0
- package/dist/core/classifiers/cholesterol.js +123 -0
- package/dist/core/classifiers/cholesterol.js.map +1 -0
- package/dist/core/classifiers/diabetes.d.ts +8 -0
- package/dist/core/classifiers/diabetes.d.ts.map +1 -0
- package/dist/core/classifiers/diabetes.js +154 -0
- package/dist/core/classifiers/diabetes.js.map +1 -0
- package/dist/core/classifiers/general.d.ts +8 -0
- package/dist/core/classifiers/general.d.ts.map +1 -0
- package/dist/core/classifiers/general.js +84 -0
- package/dist/core/classifiers/general.js.map +1 -0
- package/dist/core/classifiers/index.d.ts +5 -0
- package/dist/core/classifiers/index.d.ts.map +1 -0
- package/dist/core/classifiers/index.js +113 -0
- package/dist/core/classifiers/index.js.map +1 -0
- package/dist/core/classifiers/redFlags.d.ts +10 -0
- package/dist/core/classifiers/redFlags.d.ts.map +1 -0
- package/dist/core/classifiers/redFlags.js +59 -0
- package/dist/core/classifiers/redFlags.js.map +1 -0
- package/dist/core/clinicalMultiplier.d.ts +6 -0
- package/dist/core/clinicalMultiplier.d.ts.map +1 -0
- package/dist/core/clinicalMultiplier.js +199 -0
- package/dist/core/clinicalMultiplier.js.map +1 -0
- package/dist/core/demo.d.ts +3 -0
- package/dist/core/demo.d.ts.map +1 -0
- package/dist/core/demo.js +128 -0
- package/dist/core/demo.js.map +1 -0
- package/dist/core/fairnessEngine.d.ts +13 -0
- package/dist/core/fairnessEngine.d.ts.map +1 -0
- package/dist/core/fairnessEngine.js +156 -0
- package/dist/core/fairnessEngine.js.map +1 -0
- package/dist/core/metricsCalculator.d.ts +23 -0
- package/dist/core/metricsCalculator.d.ts.map +1 -0
- package/dist/core/metricsCalculator.js +159 -0
- package/dist/core/metricsCalculator.js.map +1 -0
- package/dist/core/predictor.d.ts +11 -0
- package/dist/core/predictor.d.ts.map +1 -0
- package/dist/core/predictor.js +45 -0
- package/dist/core/predictor.js.map +1 -0
- package/dist/core/priorityScorer.d.ts +17 -0
- package/dist/core/priorityScorer.d.ts.map +1 -0
- package/dist/core/priorityScorer.js +129 -0
- package/dist/core/priorityScorer.js.map +1 -0
- package/dist/core/queueConfig.d.ts +4 -0
- package/dist/core/queueConfig.d.ts.map +1 -0
- package/dist/core/queueConfig.js +114 -0
- package/dist/core/queueConfig.js.map +1 -0
- package/dist/core/queueOptimizer.d.ts +24 -0
- package/dist/core/queueOptimizer.d.ts.map +1 -0
- package/dist/core/queueOptimizer.js +269 -0
- package/dist/core/queueOptimizer.js.map +1 -0
- package/dist/core/simulator.d.ts +12 -0
- package/dist/core/simulator.d.ts.map +1 -0
- package/dist/core/simulator.js +181 -0
- package/dist/core/simulator.js.map +1 -0
- package/dist/core/types.d.ts +249 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +20 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueueOptimizer = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const predictor_1 = require("./predictor");
|
|
6
|
+
const priorityScorer_1 = require("./priorityScorer");
|
|
7
|
+
const fairnessEngine_1 = require("./fairnessEngine");
|
|
8
|
+
class QueueOptimizer {
|
|
9
|
+
constructor(config = {}) {
|
|
10
|
+
this.config = { ...types_1.DEFAULT_CONFIG, ...config };
|
|
11
|
+
this.predictor = new predictor_1.DurationPredictor();
|
|
12
|
+
this.priorityScorer = new priorityScorer_1.PriorityScorer(this.config);
|
|
13
|
+
this.fairnessEngine = new fairnessEngine_1.FairnessEngine(this.config);
|
|
14
|
+
}
|
|
15
|
+
optimize(patients, doctors) {
|
|
16
|
+
const patientsWithDurations = this.predictor.predictDurationBatch(patients);
|
|
17
|
+
const scored = this.priorityScorer.scoreAllPatients(patientsWithDurations, doctors);
|
|
18
|
+
const sorted = scored.map(s => s.patient);
|
|
19
|
+
return this.fairnessEngine.enforceInterleaving(sorted);
|
|
20
|
+
}
|
|
21
|
+
buildOptimizedQueueDynamic(patients, startTime, doctors, debug = false) {
|
|
22
|
+
const remaining = patients.slice();
|
|
23
|
+
const availableDocs = doctors?.filter(d => d.isAvailable) ?? [];
|
|
24
|
+
const numServers = Math.max(1, availableDocs.length);
|
|
25
|
+
const allPreQueued = numServers > 1 &&
|
|
26
|
+
remaining.every(p => p.arrivalTime.getTime() <= startTime.getTime());
|
|
27
|
+
if (allPreQueued) {
|
|
28
|
+
return this.schedulePreQueued(remaining, startTime, numServers);
|
|
29
|
+
}
|
|
30
|
+
const optimized = [];
|
|
31
|
+
const serverTimes = new Array(numServers).fill(startTime.getTime());
|
|
32
|
+
let consecutiveHigh = 0;
|
|
33
|
+
let savedServerTimes = null;
|
|
34
|
+
const batchSize = numServers;
|
|
35
|
+
while (remaining.length > 0) {
|
|
36
|
+
if (remaining.length === batchSize) {
|
|
37
|
+
savedServerTimes = [...serverTimes];
|
|
38
|
+
}
|
|
39
|
+
let earliestIdx = 0;
|
|
40
|
+
for (let i = 1; i < numServers; i++) {
|
|
41
|
+
if (serverTimes[i] < serverTimes[earliestIdx])
|
|
42
|
+
earliestIdx = i;
|
|
43
|
+
}
|
|
44
|
+
let currentTime = new Date(serverTimes[earliestIdx]);
|
|
45
|
+
let arrivedPatients = remaining.filter(p => p.arrivalTime.getTime() <= currentTime.getTime());
|
|
46
|
+
if (arrivedPatients.length === 0) {
|
|
47
|
+
const nextArrival = Math.min(...remaining.map(p => p.arrivalTime.getTime()));
|
|
48
|
+
currentTime = new Date(nextArrival);
|
|
49
|
+
serverTimes[earliestIdx] = nextArrival;
|
|
50
|
+
arrivedPatients = remaining.filter(p => p.arrivalTime.getTime() <= currentTime.getTime());
|
|
51
|
+
}
|
|
52
|
+
const withWait = arrivedPatients.map(p => ({
|
|
53
|
+
...p,
|
|
54
|
+
waitTime: Math.max(p.waitTime || 0, (currentTime.getTime() - p.arrivalTime.getTime()) / 60000),
|
|
55
|
+
}));
|
|
56
|
+
const hasStandardOrLow = withWait.some(p => p.urgency === 'STANDARD' || p.urgency === 'LOW');
|
|
57
|
+
const needsInterleaving = consecutiveHigh >= this.config.interleaveAfter && hasStandardOrLow;
|
|
58
|
+
const mandatory = this.fairnessEngine.getMandatoryNextSlotPatients(withWait);
|
|
59
|
+
let selected;
|
|
60
|
+
if (needsInterleaving) {
|
|
61
|
+
const stdCandidates = withWait.filter(p => p.urgency === 'STANDARD' || p.urgency === 'LOW');
|
|
62
|
+
selected = stdCandidates.sort((a, b) => (a.estimatedDuration || 15) - (b.estimatedDuration || 15))[0];
|
|
63
|
+
consecutiveHigh = 0;
|
|
64
|
+
}
|
|
65
|
+
else if (mandatory.length > 0 && !withWait.some(p => p.urgency === 'CRITICAL' || p.urgency === 'HIGH')) {
|
|
66
|
+
selected = mandatory.sort((a, b) => (b.waitTime || 0) - (a.waitTime || 0))[0];
|
|
67
|
+
consecutiveHigh = 0;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const scored = this.priorityScorer.scoreAllPatients(withWait, doctors);
|
|
71
|
+
if (remaining.length > numServers * 2) {
|
|
72
|
+
const topScore = scored[0].score;
|
|
73
|
+
const threshold = topScore * 0.88;
|
|
74
|
+
const topTier = scored.filter(s => s.score >= threshold);
|
|
75
|
+
if (topTier.length > 1) {
|
|
76
|
+
topTier.sort((a, b) => (a.patient.estimatedDuration || 15) - (b.patient.estimatedDuration || 15));
|
|
77
|
+
selected = topTier[0].patient;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
selected = scored[0].patient;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
selected = scored[0].patient;
|
|
85
|
+
}
|
|
86
|
+
if (selected.urgency === 'CRITICAL' || selected.urgency === 'HIGH') {
|
|
87
|
+
consecutiveHigh++;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
consecutiveHigh = 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
optimized.push(selected);
|
|
94
|
+
const effectiveStart = Math.max(currentTime.getTime(), selected.arrivalTime.getTime());
|
|
95
|
+
const duration = selected.estimatedDuration || 15;
|
|
96
|
+
serverTimes[earliestIdx] = effectiveStart + duration * 60000;
|
|
97
|
+
const idx = remaining.findIndex(p => p.id === selected.id);
|
|
98
|
+
remaining.splice(idx, 1);
|
|
99
|
+
}
|
|
100
|
+
if (savedServerTimes && optimized.length > batchSize) {
|
|
101
|
+
const batch = optimized.splice(-batchSize);
|
|
102
|
+
const perms = this.permute(batch);
|
|
103
|
+
let bestPerm = batch;
|
|
104
|
+
let bestMaxWait = Infinity;
|
|
105
|
+
for (const perm of perms) {
|
|
106
|
+
const times = [...savedServerTimes];
|
|
107
|
+
let maxWait = 0;
|
|
108
|
+
for (const p of perm) {
|
|
109
|
+
let bestIdx = 0;
|
|
110
|
+
for (let i = 1; i < times.length; i++) {
|
|
111
|
+
if (times[i] < times[bestIdx])
|
|
112
|
+
bestIdx = i;
|
|
113
|
+
}
|
|
114
|
+
const effectiveStart = Math.max(times[bestIdx], p.arrivalTime.getTime());
|
|
115
|
+
const wait = (effectiveStart - p.arrivalTime.getTime()) / 60000;
|
|
116
|
+
maxWait = Math.max(maxWait, wait);
|
|
117
|
+
times[bestIdx] = effectiveStart + (p.estimatedDuration || 15) * 60000;
|
|
118
|
+
}
|
|
119
|
+
if (maxWait < bestMaxWait) {
|
|
120
|
+
bestMaxWait = maxWait;
|
|
121
|
+
bestPerm = perm;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
optimized.push(...bestPerm);
|
|
125
|
+
}
|
|
126
|
+
return optimized;
|
|
127
|
+
}
|
|
128
|
+
permute(arr) {
|
|
129
|
+
if (arr.length <= 1)
|
|
130
|
+
return [arr];
|
|
131
|
+
const result = [];
|
|
132
|
+
for (let i = 0; i < arr.length; i++) {
|
|
133
|
+
const rest = arr.filter((_, j) => j !== i);
|
|
134
|
+
for (const perm of this.permute(rest)) {
|
|
135
|
+
result.push([arr[i], ...perm]);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
}
|
|
140
|
+
schedulePreQueued(patients, startTime, numServers) {
|
|
141
|
+
const URGENCY_RANK = { CRITICAL: 1, HIGH: 2, STANDARD: 3, LOW: 4 };
|
|
142
|
+
const byUrgency = patients.slice().sort((a, b) => {
|
|
143
|
+
const ud = (URGENCY_RANK[a.urgency] ?? 5) - (URGENCY_RANK[b.urgency] ?? 5);
|
|
144
|
+
return ud !== 0 ? ud : (a.estimatedDuration || 15) - (b.estimatedDuration || 15);
|
|
145
|
+
});
|
|
146
|
+
const urgentCount = byUrgency.filter(p => p.urgency === 'CRITICAL' || p.urgency === 'HIGH').length;
|
|
147
|
+
const urgentSlots = Math.min(numServers - 1, urgentCount);
|
|
148
|
+
const firstBatch = byUrgency.slice(0, urgentSlots);
|
|
149
|
+
const usedIds = new Set(firstBatch.map(p => p.id));
|
|
150
|
+
const shortCandidates = byUrgency.filter(p => !usedIds.has(p.id));
|
|
151
|
+
shortCandidates.sort((a, b) => (a.estimatedDuration || 15) - (b.estimatedDuration || 15));
|
|
152
|
+
const slotsLeft = numServers - firstBatch.length;
|
|
153
|
+
for (let i = 0; i < slotsLeft && i < shortCandidates.length; i++) {
|
|
154
|
+
firstBatch.push(shortCandidates[i]);
|
|
155
|
+
usedIds.add(shortCandidates[i].id);
|
|
156
|
+
}
|
|
157
|
+
const remaining = byUrgency.filter(p => !usedIds.has(p.id));
|
|
158
|
+
const remainingUrgent = remaining.filter(p => p.urgency === 'CRITICAL' || p.urgency === 'HIGH');
|
|
159
|
+
const remainingOther = remaining.filter(p => p.urgency !== 'CRITICAL' && p.urgency !== 'HIGH');
|
|
160
|
+
remainingUrgent.sort((a, b) => {
|
|
161
|
+
const ud = (URGENCY_RANK[a.urgency] ?? 5) - (URGENCY_RANK[b.urgency] ?? 5);
|
|
162
|
+
return ud !== 0 ? ud : (a.estimatedDuration || 15) - (b.estimatedDuration || 15);
|
|
163
|
+
});
|
|
164
|
+
remainingOther.sort((a, b) => (a.estimatedDuration || 15) - (b.estimatedDuration || 15));
|
|
165
|
+
const result = [...firstBatch, ...remainingUrgent, ...remainingOther];
|
|
166
|
+
if (result.length > numServers) {
|
|
167
|
+
const serverTimes = new Array(numServers).fill(startTime.getTime());
|
|
168
|
+
const preBatchLen = result.length - numServers;
|
|
169
|
+
for (let i = 0; i < preBatchLen; i++) {
|
|
170
|
+
let minIdx = 0;
|
|
171
|
+
for (let j = 1; j < numServers; j++) {
|
|
172
|
+
if (serverTimes[j] < serverTimes[minIdx])
|
|
173
|
+
minIdx = j;
|
|
174
|
+
}
|
|
175
|
+
const p = result[i];
|
|
176
|
+
const effectiveStart = Math.max(serverTimes[minIdx], p.arrivalTime.getTime());
|
|
177
|
+
serverTimes[minIdx] = effectiveStart + (p.estimatedDuration || 15) * 60000;
|
|
178
|
+
}
|
|
179
|
+
const lastBatch = result.slice(-numServers);
|
|
180
|
+
const perms = this.permute(lastBatch);
|
|
181
|
+
let bestPerm = lastBatch;
|
|
182
|
+
let bestMaxWait = Infinity;
|
|
183
|
+
for (const perm of perms) {
|
|
184
|
+
const times = [...serverTimes];
|
|
185
|
+
let maxWait = 0;
|
|
186
|
+
for (const p of perm) {
|
|
187
|
+
let bIdx = 0;
|
|
188
|
+
for (let j = 1; j < times.length; j++) {
|
|
189
|
+
if (times[j] < times[bIdx])
|
|
190
|
+
bIdx = j;
|
|
191
|
+
}
|
|
192
|
+
const eff = Math.max(times[bIdx], p.arrivalTime.getTime());
|
|
193
|
+
maxWait = Math.max(maxWait, (eff - p.arrivalTime.getTime()) / 60000);
|
|
194
|
+
times[bIdx] = eff + (p.estimatedDuration || 15) * 60000;
|
|
195
|
+
}
|
|
196
|
+
if (maxWait < bestMaxWait) {
|
|
197
|
+
bestMaxWait = maxWait;
|
|
198
|
+
bestPerm = perm;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
result.splice(-numServers, numServers, ...bestPerm);
|
|
202
|
+
}
|
|
203
|
+
return result;
|
|
204
|
+
}
|
|
205
|
+
generateQueueOrder(patients, startTime = new Date(), doctors) {
|
|
206
|
+
const queueOrders = [];
|
|
207
|
+
const availableDocs = doctors?.filter(d => d.isAvailable) ?? [];
|
|
208
|
+
const numServers = Math.max(1, availableDocs.length);
|
|
209
|
+
const serverTimes = new Array(numServers).fill(startTime.getTime());
|
|
210
|
+
patients.forEach((patient, index) => {
|
|
211
|
+
let bestIdx = 0;
|
|
212
|
+
for (let i = 1; i < numServers; i++) {
|
|
213
|
+
if (serverTimes[i] < serverTimes[bestIdx])
|
|
214
|
+
bestIdx = i;
|
|
215
|
+
}
|
|
216
|
+
if (patient.preferredDoctorId && availableDocs.length > 0) {
|
|
217
|
+
const prefIdx = availableDocs.findIndex(d => d.id === patient.preferredDoctorId);
|
|
218
|
+
if (prefIdx !== -1 && serverTimes[prefIdx] - serverTimes[bestIdx] <= 5 * 60000) {
|
|
219
|
+
bestIdx = prefIdx;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const effectiveStart = Math.max(serverTimes[bestIdx], patient.arrivalTime.getTime());
|
|
223
|
+
const estimatedStartTime = new Date(effectiveStart);
|
|
224
|
+
const duration = patient.estimatedDuration || 15;
|
|
225
|
+
const estimatedEndTime = new Date(effectiveStart + duration * 60000);
|
|
226
|
+
const estimatedWaitTime = (effectiveStart - patient.arrivalTime.getTime()) / 60000;
|
|
227
|
+
const assignedDoctor = availableDocs[bestIdx] || undefined;
|
|
228
|
+
queueOrders.push({
|
|
229
|
+
patient,
|
|
230
|
+
position: index + 1,
|
|
231
|
+
estimatedStartTime,
|
|
232
|
+
estimatedEndTime,
|
|
233
|
+
estimatedWaitTime: Math.max(0, estimatedWaitTime),
|
|
234
|
+
assignedDoctor,
|
|
235
|
+
priorityScore: this.priorityScorer.calculatePriorityScore(patient, patients, doctors),
|
|
236
|
+
});
|
|
237
|
+
serverTimes[bestIdx] = estimatedEndTime.getTime();
|
|
238
|
+
});
|
|
239
|
+
return queueOrders;
|
|
240
|
+
}
|
|
241
|
+
compareQueues(patients, startTime = new Date(), doctors) {
|
|
242
|
+
const patientsWithDurations = this.predictor.predictDurationBatch(patients);
|
|
243
|
+
const baselineQueue = patientsWithDurations
|
|
244
|
+
.slice()
|
|
245
|
+
.sort((a, b) => a.arrivalTime.getTime() - b.arrivalTime.getTime());
|
|
246
|
+
const optimizedQueue = this.buildOptimizedQueueDynamic(patientsWithDurations, startTime, doctors);
|
|
247
|
+
return {
|
|
248
|
+
baseline: this.generateQueueOrder(baselineQueue, startTime, doctors),
|
|
249
|
+
optimized: this.generateQueueOrder(optimizedQueue, startTime, doctors),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
getConfig() {
|
|
253
|
+
return this.config;
|
|
254
|
+
}
|
|
255
|
+
setConfig(config) {
|
|
256
|
+
this.config = { ...this.config, ...config };
|
|
257
|
+
this.priorityScorer = new priorityScorer_1.PriorityScorer(this.config);
|
|
258
|
+
this.fairnessEngine = new fairnessEngine_1.FairnessEngine(this.config);
|
|
259
|
+
}
|
|
260
|
+
debugScores(patients, doctors) {
|
|
261
|
+
const patientsWithDurations = this.predictor.predictDurationBatch(patients);
|
|
262
|
+
return patientsWithDurations.map(patient => ({
|
|
263
|
+
patient,
|
|
264
|
+
explanation: this.priorityScorer.getScoreExplanation(patient, patientsWithDurations, doctors),
|
|
265
|
+
}));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
exports.QueueOptimizer = QueueOptimizer;
|
|
269
|
+
//# sourceMappingURL=queueOptimizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queueOptimizer.js","sourceRoot":"","sources":["../../src/core/queueOptimizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Patient, Doctor, QueueOptimizationConfig, OptimizationResult } from './types';
|
|
2
|
+
export declare class QueueSimulator {
|
|
3
|
+
private optimizer;
|
|
4
|
+
private fairnessEngine;
|
|
5
|
+
private config;
|
|
6
|
+
private startTime;
|
|
7
|
+
constructor(config?: Partial<QueueOptimizationConfig>, startTime?: Date);
|
|
8
|
+
simulate(patients: Patient[], doctors?: Doctor[]): OptimizationResult;
|
|
9
|
+
private generateRecommendations;
|
|
10
|
+
formatResults(result: OptimizationResult, doctors?: Doctor[]): string;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=simulator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulator.d.ts","sourceRoot":"","sources":["../../src/core/simulator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,MAAM,EACN,uBAAuB,EACvB,kBAAkB,EAInB,MAAM,SAAS,CAAC;AAUjB,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,SAAS,CAAO;gBAEZ,MAAM,GAAE,OAAO,CAAC,uBAAuB,CAAM,EAAE,SAAS,GAAE,IAAiB;IAOvF,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,kBAAkB;IAoDrE,OAAO,CAAC,uBAAuB;IAkF/B,aAAa,CAAC,MAAM,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM;CA+FtE"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueueSimulator = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const queueOptimizer_1 = require("./queueOptimizer");
|
|
6
|
+
const metricsCalculator_1 = require("./metricsCalculator");
|
|
7
|
+
const fairnessEngine_1 = require("./fairnessEngine");
|
|
8
|
+
class QueueSimulator {
|
|
9
|
+
constructor(config = {}, startTime = new Date()) {
|
|
10
|
+
this.config = { ...types_1.DEFAULT_CONFIG, ...config };
|
|
11
|
+
this.optimizer = new queueOptimizer_1.QueueOptimizer(this.config);
|
|
12
|
+
this.fairnessEngine = new fairnessEngine_1.FairnessEngine(this.config);
|
|
13
|
+
this.startTime = startTime;
|
|
14
|
+
}
|
|
15
|
+
simulate(patients, doctors) {
|
|
16
|
+
if (patients.length === 0) {
|
|
17
|
+
const emptyMetrics = metricsCalculator_1.MetricsCalculator.calculateMetrics([], this.config.scheduledWindowMinutes);
|
|
18
|
+
return {
|
|
19
|
+
baselineQueue: [],
|
|
20
|
+
optimizedQueue: [],
|
|
21
|
+
baselineMetrics: emptyMetrics,
|
|
22
|
+
optimizedMetrics: emptyMetrics,
|
|
23
|
+
fairnessReport: { agingBoosts: [], violations: [], fairnessScore: 100, starvationRisks: [] },
|
|
24
|
+
recommendations: ['No patients to optimize'],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const patientsWithWait = patients.map(p => ({
|
|
28
|
+
...p,
|
|
29
|
+
waitTime: Math.max(p.waitTime || 0, (this.startTime.getTime() - p.arrivalTime.getTime()) / 60000),
|
|
30
|
+
}));
|
|
31
|
+
const { baseline, optimized } = this.optimizer.compareQueues(patientsWithWait, this.startTime, doctors);
|
|
32
|
+
const numDocs = doctors?.filter(d => d.isAvailable).length ?? 1;
|
|
33
|
+
const baselineMetrics = metricsCalculator_1.MetricsCalculator.calculateMetrics(baseline, this.config.scheduledWindowMinutes, numDocs);
|
|
34
|
+
const optimizedMetrics = metricsCalculator_1.MetricsCalculator.calculateMetrics(optimized, this.config.scheduledWindowMinutes, numDocs);
|
|
35
|
+
const fairnessReport = this.fairnessEngine.generateReport(optimized, patientsWithWait);
|
|
36
|
+
const recommendations = this.generateRecommendations(baselineMetrics, optimizedMetrics, baseline, optimized, fairnessReport);
|
|
37
|
+
return {
|
|
38
|
+
baselineQueue: baseline,
|
|
39
|
+
optimizedQueue: optimized,
|
|
40
|
+
baselineMetrics,
|
|
41
|
+
optimizedMetrics,
|
|
42
|
+
fairnessReport,
|
|
43
|
+
recommendations,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
generateRecommendations(baselineMetrics, optimizedMetrics, baselineQueue, optimizedQueue, fairnessReport) {
|
|
47
|
+
const recs = [];
|
|
48
|
+
const waitReduction = baselineMetrics.averageWaitTime === 0
|
|
49
|
+
? 0
|
|
50
|
+
: ((baselineMetrics.averageWaitTime - optimizedMetrics.averageWaitTime) /
|
|
51
|
+
baselineMetrics.averageWaitTime) *
|
|
52
|
+
100;
|
|
53
|
+
recs.push(`β
Priority scheduling reduces avg wait by ${waitReduction.toFixed(1)}% ` +
|
|
54
|
+
`(${baselineMetrics.averageWaitTime.toFixed(1)} β ${optimizedMetrics.averageWaitTime.toFixed(1)} min)`);
|
|
55
|
+
const urgencyAvg = (queue, urgency) => {
|
|
56
|
+
const matched = queue.filter(o => o.patient.urgency === urgency);
|
|
57
|
+
if (matched.length === 0)
|
|
58
|
+
return 0;
|
|
59
|
+
return matched.reduce((s, o) => s + o.estimatedWaitTime, 0) / matched.length;
|
|
60
|
+
};
|
|
61
|
+
const critBase = urgencyAvg(baselineQueue, 'CRITICAL');
|
|
62
|
+
const critOpt = urgencyAvg(optimizedQueue, 'CRITICAL');
|
|
63
|
+
if (critBase > 0 && critOpt < critBase) {
|
|
64
|
+
const pct = ((critBase - critOpt) / critBase) * 100;
|
|
65
|
+
recs.push(`π₯ CRITICAL patient avg wait reduced ${pct.toFixed(0)}% ` +
|
|
66
|
+
`(${critBase.toFixed(1)} β ${critOpt.toFixed(1)} min)`);
|
|
67
|
+
}
|
|
68
|
+
const highBase = urgencyAvg(baselineQueue, 'HIGH');
|
|
69
|
+
const highOpt = urgencyAvg(optimizedQueue, 'HIGH');
|
|
70
|
+
if (highBase > 0 && highOpt < highBase) {
|
|
71
|
+
const pct = ((highBase - highOpt) / highBase) * 100;
|
|
72
|
+
recs.push(`π HIGH-urgency patient avg wait reduced ${pct.toFixed(0)}% ` +
|
|
73
|
+
`(${highBase.toFixed(1)} β ${highOpt.toFixed(1)} min)`);
|
|
74
|
+
}
|
|
75
|
+
if (fairnessReport.violations.length > 0) {
|
|
76
|
+
recs.push(`β οΈ ${fairnessReport.violations.length} fairness violation(s) detected β ` +
|
|
77
|
+
`consider adding another provider or adjusting interleave ratio`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
recs.push('β
Zero fairness violations β all rules F1βF4 passed');
|
|
81
|
+
}
|
|
82
|
+
if (optimizedMetrics.doctorUtilization < 85) {
|
|
83
|
+
recs.push(`π Doctor utilization at ${optimizedMetrics.doctorUtilization.toFixed(1)}% β ` +
|
|
84
|
+
`reduce idle gaps by pre-assigning next patient during consultations`);
|
|
85
|
+
}
|
|
86
|
+
if (optimizedMetrics.totalOvertime > 0) {
|
|
87
|
+
recs.push(`β±οΈ ${optimizedMetrics.totalOvertime.toFixed(0)} min overtime β ` +
|
|
88
|
+
`cap intake 30 min before window end or add express lane for LOW urgency`);
|
|
89
|
+
}
|
|
90
|
+
if (fairnessReport.starvationRisks.length > 0) {
|
|
91
|
+
recs.push(`π ${fairnessReport.starvationRisks.length} patient(s) approaching starvation threshold β ` +
|
|
92
|
+
`monitor and consider early promotion`);
|
|
93
|
+
}
|
|
94
|
+
return recs;
|
|
95
|
+
}
|
|
96
|
+
formatResults(result, doctors) {
|
|
97
|
+
const totalPatients = result.optimizedQueue.length;
|
|
98
|
+
const windowMin = this.config.scheduledWindowMinutes;
|
|
99
|
+
let out = `
|
|
100
|
+
## π₯ SIMULATION SUMMARY
|
|
101
|
+
Window: ${windowMin} min | Patients: ${totalPatients} | Doctors: ${doctors?.length ?? 1}
|
|
102
|
+
Specialties: ${doctors?.map(d => d.specialty).filter((v, i, a) => a.indexOf(v) === i).join(', ') || 'General'}
|
|
103
|
+
|
|
104
|
+
## π PATIENT QUEUE TABLE (Optimized Order)
|
|
105
|
+
ββββββββ¬βββββββββββ¬βββββββββ¬ββββββββββββ¬ββββββββββ¬ββββββββββ¬βββββββββββ
|
|
106
|
+
β # β ID βUrgency β Entry β Est Dur β PriScoreβ Doctor β
|
|
107
|
+
ββββββββΌβββββββββββΌβββββββββΌββββββββββββΌββββββββββΌββββββββββΌβββββββββββ€`;
|
|
108
|
+
for (const o of result.optimizedQueue) {
|
|
109
|
+
const entry = o.patient.arrivalTime.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
|
|
110
|
+
const dur = `${o.patient.estimatedDuration || '?'} min`;
|
|
111
|
+
const pri = (o.priorityScore ?? 0).toFixed(1);
|
|
112
|
+
const doc = o.assignedDoctor?.name || 'Auto';
|
|
113
|
+
out += `\nβ ${String(o.position).padStart(4)} β ${o.patient.id.padEnd(8)} β${o.patient.urgency.padEnd(8)}β ${entry.padEnd(9)} β ${dur.padEnd(7)} β ${pri.padStart(7)} β ${doc.padEnd(8)} β`;
|
|
114
|
+
}
|
|
115
|
+
out += `\nββββββββ΄βββββββββββ΄βββββββββ΄ββββββββββββ΄ββββββββββ΄ββββββββββ΄βββββββββββ`;
|
|
116
|
+
const b = result.baselineMetrics;
|
|
117
|
+
const o = result.optimizedMetrics;
|
|
118
|
+
const d = (bv, ov) => {
|
|
119
|
+
const diff = ov - bv;
|
|
120
|
+
return (diff >= 0 ? '+' : '') + diff.toFixed(1);
|
|
121
|
+
};
|
|
122
|
+
const dPct = (bv, ov) => {
|
|
123
|
+
if (bv === 0)
|
|
124
|
+
return '+0.0%';
|
|
125
|
+
const pct = ((ov - bv) / Math.abs(bv)) * 100;
|
|
126
|
+
return (pct >= 0 ? '+' : '') + pct.toFixed(1) + '%';
|
|
127
|
+
};
|
|
128
|
+
out += `
|
|
129
|
+
|
|
130
|
+
## π BASELINE vs OPTIMIZED COMPARISON
|
|
131
|
+
βββββββββββββββββββββββββββ¬βββββββββββββββ¬βββββββββββββββ¬βββββββββββββββ
|
|
132
|
+
β Metric β Baseline β Optimized β Ξ Change β
|
|
133
|
+
βββββββββββββββββββββββββββΌβββββββββββββββΌβββββββββββββββΌβββββββββββββββ€
|
|
134
|
+
β Avg Wait Time (min) β ${String(b.averageWaitTime.toFixed(1)).padStart(12)} β ${String(o.averageWaitTime.toFixed(1)).padStart(12)} β ${String(d(b.averageWaitTime, o.averageWaitTime)).padStart(12)} β
|
|
135
|
+
β Median Wait Time (min) β ${String(b.medianWaitTime.toFixed(1)).padStart(12)} β ${String(o.medianWaitTime.toFixed(1)).padStart(12)} β ${String(d(b.medianWaitTime, o.medianWaitTime)).padStart(12)} β
|
|
136
|
+
β Max Wait Time (min) β ${String(b.maxWaitTime.toFixed(1)).padStart(12)} β ${String(o.maxWaitTime.toFixed(1)).padStart(12)} β ${String(d(b.maxWaitTime, o.maxWaitTime)).padStart(12)} β
|
|
137
|
+
β Provider Utilization % β ${String(b.doctorUtilization.toFixed(1)).padStart(12)} β ${String(o.doctorUtilization.toFixed(1)).padStart(12)} β ${String(d(b.doctorUtilization, o.doctorUtilization)).padStart(12)} β
|
|
138
|
+
β Throughput (pts/hr) β ${String(b.throughput.toFixed(1)).padStart(12)} β ${String(o.throughput.toFixed(1)).padStart(12)} β ${String(dPct(b.throughput, o.throughput)).padStart(12)} β
|
|
139
|
+
β Patient Satisfaction β ${String(b.patientSatisfaction.toFixed(1)).padStart(12)} β ${String(o.patientSatisfaction.toFixed(1)).padStart(12)} β ${String(d(b.patientSatisfaction, o.patientSatisfaction)).padStart(12)} β
|
|
140
|
+
β Total Overtime (min) β ${String(b.totalOvertime.toFixed(1)).padStart(12)} β ${String(o.totalOvertime.toFixed(1)).padStart(12)} β ${String(d(b.totalOvertime, o.totalOvertime)).padStart(12)} β
|
|
141
|
+
βββββββββββββββββββββββββββ΄βββββββββββββββ΄βββββββββββββββ΄βββββββββββββββ`;
|
|
142
|
+
const fr = result.fairnessReport;
|
|
143
|
+
out += `
|
|
144
|
+
|
|
145
|
+
## βοΈ FAIRNESS REPORT
|
|
146
|
+
Fairness Score: ${fr.fairnessScore}/100`;
|
|
147
|
+
if (fr.agingBoosts.length > 0) {
|
|
148
|
+
out += `\n\nAging Boosts Applied:`;
|
|
149
|
+
for (const ab of fr.agingBoosts) {
|
|
150
|
+
out += `\n β’ ${ab.patientId}: waited ${ab.waitMinutes.toFixed(0)} min β +${ab.boostApplied} priority boost`;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
out += `\nNo aging boosts needed.`;
|
|
155
|
+
}
|
|
156
|
+
if (fr.violations.length > 0) {
|
|
157
|
+
out += `\n\nRule Violations:`;
|
|
158
|
+
for (const v of fr.violations) {
|
|
159
|
+
out += `\n β [${v.rule}] ${v.patientId}: ${v.reason}`;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
out += `\nNo rule violations (F1βF4 all passed). β
`;
|
|
164
|
+
}
|
|
165
|
+
if (fr.starvationRisks.length > 0) {
|
|
166
|
+
out += `\n\nStarvation Risk List:`;
|
|
167
|
+
for (const sr of fr.starvationRisks) {
|
|
168
|
+
out += `\n β οΈ ${sr.patientId} (${sr.urgency}): ${sr.currentWait.toFixed(0)} min / ${sr.threshold} min threshold (${sr.percentToThreshold}%)`;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
out += `
|
|
172
|
+
|
|
173
|
+
## π‘ RECOMMENDATIONS`;
|
|
174
|
+
result.recommendations.forEach((rec, i) => {
|
|
175
|
+
out += `\n${i + 1}. ${rec}`;
|
|
176
|
+
});
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.QueueSimulator = QueueSimulator;
|
|
181
|
+
//# sourceMappingURL=simulator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simulator.js","sourceRoot":"","sources":["../../src/core/simulator.ts"],"names":[],"mappings":"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"}
|