Skip to content

Commit 441b404

Browse files
Simulate partial day
1 parent 07513cc commit 441b404

File tree

3 files changed

+65
-17
lines changed

3 files changed

+65
-17
lines changed

app/config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ module.exports = {
3434

3535
// Date range for generating data
3636
daysToGenerate: 7,
37-
daysBeforeToday: 3
37+
daysBeforeToday: 3,
38+
39+
simulatedTime: '11:30', // 24h format
3840
},
3941

4042
screening: {

app/lib/generators/event-generator.js

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const generateId = require('../utils/id-generator');
44
const { faker } = require('@faker-js/faker');
55
const weighted = require('weighted');
66
const dayjs = require('dayjs');
7+
const config = require('../../config');
8+
79

810
const NOT_SCREENED_REASONS = [
911
"Recent mammogram at different facility",
@@ -14,7 +16,57 @@ const NOT_SCREENED_REASONS = [
1416
"Recent breast surgery"
1517
];
1618

19+
const determineEventStatus = (slotDateTime, currentDateTime, attendanceWeights) => {
20+
slotDateTime = dayjs(slotDateTime);
21+
22+
const simulatedTime = dayjs(currentDateTime);
23+
const slotDate = slotDateTime.startOf('day');
24+
const currentDate = simulatedTime.startOf('day');
25+
26+
// For future dates or future slots today, always return scheduled
27+
if (slotDateTime.isAfter(simulatedTime)) {
28+
return 'scheduled';
29+
}
30+
31+
if (slotDate.isBefore(currentDate)){
32+
const finalStatuses = ['attended', 'did_not_attend', 'attended_not_screened'];
33+
return weighted.select(finalStatuses, attendanceWeights);
34+
}
35+
36+
// For past slots, generate a status based on how long ago the slot was
37+
const minutesPassed = simulatedTime.diff(slotDateTime, 'minute');
38+
39+
// Define probability weights for different statuses based on time passed
40+
if (minutesPassed <= 60) {
41+
// Within 30 mins of appointment
42+
return weighted.select({
43+
'checked_in': 0.6,
44+
'attended': 0.1,
45+
'attended_not_screened': 0.1,
46+
'scheduled': 0.2,
47+
});
48+
} else {
49+
// More than 30 mins after appointment
50+
return weighted.select({
51+
'attended': 0.6,
52+
'attended_not_screened': 0.1,
53+
'scheduled': 0.2,
54+
});
55+
}
56+
};
57+
1758
const generateEvent = ({ slot, participant, clinic, outcomeWeights }) => {
59+
60+
// Get simulated current time
61+
const [hours, minutes] = config.clinics.simulatedTime.split(':');
62+
const currentDateTime = dayjs().hour(parseInt(hours)).minute(parseInt(minutes));
63+
64+
// Check if the event is from yesterday or before
65+
const eventDate = dayjs(slot.dateTime).startOf('day');
66+
const today = dayjs(currentDateTime).startOf('day');
67+
const isPast = dayjs(slot.dateTime).isBefore(currentDateTime);
68+
const isTodayBeforeCurrentTime = eventDate.isBefore(currentDateTime)
69+
1870
// If it's an assessment clinic, override the outcome weights to reflect higher probability of findings
1971
const eventWeights = clinic.serviceType === 'assessment' ?
2072
{
@@ -28,11 +80,6 @@ const generateEvent = ({ slot, participant, clinic, outcomeWeights }) => {
2880
[0.9, 0.08, 0.02] : // [attended, dna, attended_not_screened]
2981
[0.65, 0.25, 0.1]; // Original weights for screening
3082

31-
// Check if the event is from yesterday or before
32-
const eventDate = dayjs(slot.dateTime).startOf('day');
33-
const today = dayjs().startOf('day');
34-
const isPast = eventDate.isBefore(today);
35-
3683
// All future events and today's events start as scheduled
3784
if (!isPast) {
3885
return {
@@ -55,11 +102,10 @@ const generateEvent = ({ slot, participant, clinic, outcomeWeights }) => {
55102
};
56103
}
57104

58-
// For past events, generate final status with clinic-appropriate weights
59-
const finalStatuses = ['attended', 'did_not_attend', 'attended_not_screened'];
60-
const status = weighted.select(finalStatuses, attendanceWeights);
105+
// For past events, generate final status with clinic-appropriate weights
106+
const status = determineEventStatus(slot.dateTime, currentDateTime, attendanceWeights);
61107

62-
const event = {
108+
const event = {
63109
id: generateId(),
64110
participantId: participant.id,
65111
clinicId: clinic.id,
@@ -75,7 +121,7 @@ const generateEvent = ({ slot, participant, clinic, outcomeWeights }) => {
75121
faker.helpers.arrayElement(NOT_SCREENED_REASONS) : null
76122
},
77123
statusHistory: generateStatusHistory(status, slot.dateTime)
78-
};
124+
};
79125

80126
// Add outcome for completed events where participant attended
81127
if (status === 'attended') {
@@ -108,13 +154,13 @@ const generateStatusHistory = (finalStatus, dateTime) => {
108154
if (finalStatus === 'attended') {
109155
history.push(
110156
{
111-
status: 'pre_screening',
157+
status: 'checked_in',
112158
timestamp: new Date(baseDate.getTime() - (10 * 60 * 1000)).toISOString() // 10 mins before
113159
},
114-
{
115-
status: 'in_progress',
116-
timestamp: new Date(baseDate).toISOString()
117-
},
160+
// {
161+
// status: 'in_progress',
162+
// timestamp: new Date(baseDate).toISOString()
163+
// },
118164
{
119165
status: finalStatus,
120166
timestamp: new Date(baseDate.getTime() + (15 * 60 * 1000)).toISOString() // 15 mins after

app/lib/utils/status.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const getStatusTagColour = (status) => {
1414
closed: 'grey',
1515

1616
// Event statuses
17-
pre_screening: 'yellow',
17+
checked_in: 'yellow',
1818
attended: 'green',
1919
did_not_attend: 'red',
2020
attended_not_screened: 'orange'

0 commit comments

Comments
 (0)