(query, queryParams)
| 234 | * @returns {Object.<string, boolean>} An object where each key represents a date between the start and end date, and the value for each key represents whether a progress document exists for that date or not. |
| 235 | */ |
| 236 | const getProgressRecords = async (query, queryParams) => { |
| 237 | const { startDate, endDate } = queryParams; |
| 238 | const docsData = {}; |
| 239 | const queryResult = await query.get(); |
| 240 | if (!queryResult.size) { |
| 241 | throw new NotFound(PROGRESS_DOCUMENT_NOT_FOUND); |
| 242 | } |
| 243 | const progressesDocs = queryResult.docs; |
| 244 | progressesDocs.forEach((doc) => { |
| 245 | const date = new Date(doc.data().date).toISOString().slice(0, 10); |
| 246 | // Validate that date is in YYYY-MM-DD format (e.g., "2023-05-09") |
| 247 | // ^ = start of string, \d{4} = exactly 4 digits, - = literal dash, \d{2} = exactly 2 digits, $ = end of string |
| 248 | if (/^\d{4}-\d{2}-\d{2}$/.test(date)) { |
| 249 | Object.defineProperty(docsData, date, { |
| 250 | value: true, |
| 251 | enumerable: true, |
| 252 | writable: true, |
| 253 | configurable: true, |
| 254 | }); |
| 255 | } |
| 256 | }); |
| 257 | |
| 258 | const progressRecords = {}; |
| 259 | const currentDate = new Date(startDate); |
| 260 | while (currentDate <= new Date(endDate)) { |
| 261 | const date = currentDate.toISOString().slice(0, 10); |
| 262 | if (/^\d{4}-\d{2}-\d{2}$/.test(date)) { |
| 263 | const hasProgress = Object.prototype.hasOwnProperty.call(docsData, date) ? Reflect.get(docsData, date) : false; |
| 264 | Object.defineProperty(progressRecords, date, { |
| 265 | value: Boolean(hasProgress), |
| 266 | enumerable: true, |
| 267 | writable: true, |
| 268 | configurable: true, |
| 269 | }); |
| 270 | } |
| 271 | currentDate.setDate(currentDate.getDate() + 1); |
| 272 | } |
| 273 | return progressRecords; |
| 274 | }; |
| 275 | |
| 276 | /** |
| 277 | * Retrieves progress records for a given date range. |
no test coverage detected