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.
Files changed (90) hide show
  1. package/README.md +35 -0
  2. package/dist/api/client.d.ts +82 -0
  3. package/dist/api/client.d.ts.map +1 -0
  4. package/dist/api/client.js +75 -0
  5. package/dist/api/client.js.map +1 -0
  6. package/dist/api/controllers.d.ts +12 -0
  7. package/dist/api/controllers.d.ts.map +1 -0
  8. package/dist/api/controllers.js +569 -0
  9. package/dist/api/controllers.js.map +1 -0
  10. package/dist/api/middleware.d.ts +7 -0
  11. package/dist/api/middleware.d.ts.map +1 -0
  12. package/dist/api/middleware.js +133 -0
  13. package/dist/api/middleware.js.map +1 -0
  14. package/dist/api/routes.d.ts +3 -0
  15. package/dist/api/routes.d.ts.map +1 -0
  16. package/dist/api/routes.js +46 -0
  17. package/dist/api/routes.js.map +1 -0
  18. package/dist/api/server.d.ts +4 -0
  19. package/dist/api/server.d.ts.map +1 -0
  20. package/dist/api/server.js +72 -0
  21. package/dist/api/server.js.map +1 -0
  22. package/dist/core/classifiers/bloodPressure.d.ts +9 -0
  23. package/dist/core/classifiers/bloodPressure.d.ts.map +1 -0
  24. package/dist/core/classifiers/bloodPressure.js +178 -0
  25. package/dist/core/classifiers/bloodPressure.js.map +1 -0
  26. package/dist/core/classifiers/cholesterol.d.ts +9 -0
  27. package/dist/core/classifiers/cholesterol.d.ts.map +1 -0
  28. package/dist/core/classifiers/cholesterol.js +123 -0
  29. package/dist/core/classifiers/cholesterol.js.map +1 -0
  30. package/dist/core/classifiers/diabetes.d.ts +8 -0
  31. package/dist/core/classifiers/diabetes.d.ts.map +1 -0
  32. package/dist/core/classifiers/diabetes.js +154 -0
  33. package/dist/core/classifiers/diabetes.js.map +1 -0
  34. package/dist/core/classifiers/general.d.ts +8 -0
  35. package/dist/core/classifiers/general.d.ts.map +1 -0
  36. package/dist/core/classifiers/general.js +84 -0
  37. package/dist/core/classifiers/general.js.map +1 -0
  38. package/dist/core/classifiers/index.d.ts +5 -0
  39. package/dist/core/classifiers/index.d.ts.map +1 -0
  40. package/dist/core/classifiers/index.js +113 -0
  41. package/dist/core/classifiers/index.js.map +1 -0
  42. package/dist/core/classifiers/redFlags.d.ts +10 -0
  43. package/dist/core/classifiers/redFlags.d.ts.map +1 -0
  44. package/dist/core/classifiers/redFlags.js +59 -0
  45. package/dist/core/classifiers/redFlags.js.map +1 -0
  46. package/dist/core/clinicalMultiplier.d.ts +6 -0
  47. package/dist/core/clinicalMultiplier.d.ts.map +1 -0
  48. package/dist/core/clinicalMultiplier.js +199 -0
  49. package/dist/core/clinicalMultiplier.js.map +1 -0
  50. package/dist/core/demo.d.ts +3 -0
  51. package/dist/core/demo.d.ts.map +1 -0
  52. package/dist/core/demo.js +128 -0
  53. package/dist/core/demo.js.map +1 -0
  54. package/dist/core/fairnessEngine.d.ts +13 -0
  55. package/dist/core/fairnessEngine.d.ts.map +1 -0
  56. package/dist/core/fairnessEngine.js +156 -0
  57. package/dist/core/fairnessEngine.js.map +1 -0
  58. package/dist/core/metricsCalculator.d.ts +23 -0
  59. package/dist/core/metricsCalculator.d.ts.map +1 -0
  60. package/dist/core/metricsCalculator.js +159 -0
  61. package/dist/core/metricsCalculator.js.map +1 -0
  62. package/dist/core/predictor.d.ts +11 -0
  63. package/dist/core/predictor.d.ts.map +1 -0
  64. package/dist/core/predictor.js +45 -0
  65. package/dist/core/predictor.js.map +1 -0
  66. package/dist/core/priorityScorer.d.ts +17 -0
  67. package/dist/core/priorityScorer.d.ts.map +1 -0
  68. package/dist/core/priorityScorer.js +129 -0
  69. package/dist/core/priorityScorer.js.map +1 -0
  70. package/dist/core/queueConfig.d.ts +4 -0
  71. package/dist/core/queueConfig.d.ts.map +1 -0
  72. package/dist/core/queueConfig.js +114 -0
  73. package/dist/core/queueConfig.js.map +1 -0
  74. package/dist/core/queueOptimizer.d.ts +24 -0
  75. package/dist/core/queueOptimizer.d.ts.map +1 -0
  76. package/dist/core/queueOptimizer.js +269 -0
  77. package/dist/core/queueOptimizer.js.map +1 -0
  78. package/dist/core/simulator.d.ts +12 -0
  79. package/dist/core/simulator.d.ts.map +1 -0
  80. package/dist/core/simulator.js +181 -0
  81. package/dist/core/simulator.js.map +1 -0
  82. package/dist/core/types.d.ts +249 -0
  83. package/dist/core/types.d.ts.map +1 -0
  84. package/dist/core/types.js +20 -0
  85. package/dist/core/types.js.map +1 -0
  86. package/dist/index.d.ts +17 -0
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +42 -0
  89. package/dist/index.js.map +1 -0
  90. 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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"}