From 4b3de447b50323eb29f4b062410dd6d14bbee351 Mon Sep 17 00:00:00 2001 From: Bamco Date: Sun, 19 Nov 2023 13:36:41 +0100 Subject: [PATCH] fix schedule next self reflect --- .../firestore/users/exercises/self_reflect.ts | 42 +++++++++++++++---- .../src/pubsub/scheduled-task-runner.ts | 5 ++- .../src/pubsub/user-exercises/self_reflect.ts | 2 +- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/apps/backend-functions/src/firestore/users/exercises/self_reflect.ts b/apps/backend-functions/src/firestore/users/exercises/self_reflect.ts index 1b43b971..760732cb 100644 --- a/apps/backend-functions/src/firestore/users/exercises/self_reflect.ts +++ b/apps/backend-functions/src/firestore/users/exercises/self_reflect.ts @@ -1,5 +1,5 @@ import { arrayUnion, db, onDocumentCreate, onDocumentUpdate } from '@strive/api/firebase' -import { SelfReflectEntry, SelfReflectFrequency, SelfReflectSettings, Message, Personal, Stakeholder, createSelfReflectEntry, createSelfReflectSettings, createDearFutureSelf, createMessage, getFrequency } from '@strive/model' +import { SelfReflectEntry, SelfReflectFrequency, SelfReflectSettings, Message, Personal, Stakeholder, createSelfReflectEntry, createSelfReflectSettings, createDearFutureSelf, createMessage, getFrequency, SelfReflectFrequencyWithNever } from '@strive/model' import { getDocument, getDocumentSnap, toDate, unique } from '../../../shared/utils' import { addDays, addMonths, addQuarters, addWeeks, addYears, differenceInDays, formatISO, isBefore, isEqual, startOfDay, startOfMonth, startOfQuarter, startOfWeek } from 'date-fns' import { getNextDay, startOfSelfReflectYear } from '@strive/exercises/self-reflect/utils/date.utils' @@ -192,8 +192,8 @@ async function addDearFutureSelfMessage(uid: string, message: Message) { } } -export function upsertReminder(uid: string, settings: SelfReflectSettings) { - const { performAt, performFrequencies } = getNextReminder(settings) +export async function upsertReminder(uid: string, settings: SelfReflectSettings) { + const { performAt, performFrequencies } = await getNextReminder(settings, uid) const id = `${uid}selfreflect` const task: ScheduledTaskUserExerciseSelfReflect = { @@ -206,11 +206,26 @@ export function upsertReminder(uid: string, settings: SelfReflectSettings) { return upsertScheduledTask(id, task) } -export function getNextReminder(settings: SelfReflectSettings) { +export async function getNextReminder(settings: SelfReflectSettings, uid: string) { if (settings.preferredDay === 'never') throw new Error('Should not set reminders if preferred day is never') + const ref = db.collection(`Users/${uid}/Exercises/SelfReflect/Entries`) + const getLastEntry = async (frequency: SelfReflectFrequency) => { + const snap = await ref.where('frequency', '==', frequency).orderBy('createdAt', 'desc').limit(1).get() + if (snap.empty) return undefined + return createSelfReflectEntry(toDate(snap.docs[0].data())) + } + + const [daily, weekly, monthly, quarterly, yearly] = await Promise.all([ + getLastEntry('daily'), + getLastEntry('weekly'), + getLastEntry('monthly'), + getLastEntry('quarterly'), + getLastEntry('yearly') + ]) + const frequencies = getAvailableFrequencies(settings) - const now = settings.createdAt + const now = new Date() const startOfNextFrequency = { daily: (date: Date) => startOfDay(addDays(date, 1)), @@ -241,11 +256,16 @@ export function getNextReminder(settings: SelfReflectSettings) { for (const frequency of frequencies) { const start = startOfNextFrequency[frequency](now) - const next = getNextDay(start, settings.preferredDay) + const next = frequency === 'daily' ? start : getNextDay(start, settings.preferredDay) // do not send reminder if the next reminder is too soon - and thus try to set next next reminder - const difference = differenceInDays(next, now) - if (difference > minDays[frequency]) { + const lastEntry = frequency === 'daily' ? daily + : frequency === 'weekly' ? weekly + : frequency === 'monthly' ? monthly + : frequency === 'quarterly' ? quarterly + : yearly + + if (!lastEntry || differenceInDays(next, lastEntry.createdAt) > minDays[frequency]) { if (!performAt || isBefore(next, performAt)) { performAt = next @@ -277,5 +297,9 @@ export function getNextReminder(settings: SelfReflectSettings) { } function getAvailableFrequencies(settings: SelfReflectSettings) { - return unique(settings.questions.map(({ frequency }) => frequency).filter(frequency => frequency !== 'never')) as SelfReflectFrequency[] + const frequencies = settings.questions.map(({ frequency }) => frequency) + const availableFrequencies = frequencies.filter(frequency => frequency !== 'never') as SelfReflectFrequency[] + const order: SelfReflectFrequency[] = ['daily', 'weekly', 'monthly', 'quarterly', 'yearly'] + const orderedFrequencies = availableFrequencies.sort((a, b) => order.indexOf(a) - order.indexOf(b)) + return unique(orderedFrequencies) } diff --git a/apps/backend-functions/src/pubsub/scheduled-task-runner.ts b/apps/backend-functions/src/pubsub/scheduled-task-runner.ts index acc086b5..8fad37f5 100644 --- a/apps/backend-functions/src/pubsub/scheduled-task-runner.ts +++ b/apps/backend-functions/src/pubsub/scheduled-task-runner.ts @@ -1,4 +1,4 @@ -import { db, functions, admin } from '@strive/api/firebase' +import { db, functions, admin, logger } from '@strive/api/firebase' import { wrapPubsubOnRunHandler } from '@strive/api/sentry' import { getDocument } from '../shared/utils' @@ -62,8 +62,9 @@ async () => { if (reschedulingTasks.some(task => task === worker)) return await snapshot.ref.update({ status: 'complete' }) }) - .catch(async () => { + .catch(async (error) => { await snapshot.ref.update({ status: 'error' }) + throw error }) jobs.push(job) } diff --git a/apps/backend-functions/src/pubsub/user-exercises/self_reflect.ts b/apps/backend-functions/src/pubsub/user-exercises/self_reflect.ts index 76a86e61..8521d150 100644 --- a/apps/backend-functions/src/pubsub/user-exercises/self_reflect.ts +++ b/apps/backend-functions/src/pubsub/user-exercises/self_reflect.ts @@ -40,7 +40,7 @@ export async function sendSelfReflectPuthNotification(settings: SelfReflectSetti } export async function scheduleNextSelfReflectReminder(settings: SelfReflectSettings, userId: string) { - const { performAt, performFrequencies: frequencies } = getNextReminder(settings) + const { performAt, performFrequencies: frequencies } = await getNextReminder(settings, userId) const task: ScheduledTaskUserExerciseSelfReflect = { worker: enumWorkerType.userExerciseSelfReflect,