Dentolize · Daily Notifications Cron Walkthrough

Glossary

UserAlertSettings — Prisma model, one row per user, holding a Boolean on/off switch per notification type (invoice, calendar, treasury, and now summaryCron, appointmentsCron, etc.). Created for a user via updateUserDetails's alertSettings.create block; if that row never exists for a user, some notification checks treat them as opted out, others as opted in — see Notification Settings Toggles.

summaryCron — the UserAlertSettings column (and AlertSettingsInput field) gating the Daily Summary notification. Default true.

appointmentsCron — the UserAlertSettings column gating the Daily Appointments Summary notification. Default true.

Daily Summary — the financial/operational push notification sent to users with analytics permissions: today's invoice total, remaining unpaid amount, patient payments, and completed-vs-total appointment count.

Daily Appointments Summary — the per-doctor push notification: today's completed appointment count and total time, plus tomorrow's upcoming count and first start time.

dailyNotificationsCron — the cron job (packages/server/src/cronJobs/companies/dailyNotificationsCron.js) that runs hourly, finds every company whose local time is currently 23:30, and sends both notification types for that company.

dailyCronTranslations.js — a standalone translation dictionary used only by dailyNotificationsCron, covering the app's 9 supported languages. Separate from the app's normal react-i18next translation files, since this code runs server-side in a cron with no client i18n context.

DO_ALL — the permission string representing full/unrestricted access (the "Owner" role in the sandbox roster carries this). Any of the specific VIEW_* permission checks are automatically satisfied by having DO_ALL.

VIEW_ANALYTICS_INVOICES / VIEW_ANALYTICS_PAYMENTS / VIEW_BRANCHES — the three specific permissions that, held together, qualify a user for the Daily Summary notification even without DO_ALL.

balanceInvoice — a Boolean field on Invoice marking an invoice as a patient-balance top-up rather than a real treatment invoice. Excluded from the Daily Summary's invoice total.

Company.timeZone — a nullable String field (e.g. "Asia/Riyadh") used by every cron that needs "the clinic's local day," including this one. See The Cron for what happens when it's unset.

Expo push token — the device-specific identifier the Dentolize mobile app registers for push delivery via Expo's push service, stored in User.pushNotifications (a String[]). Both new notification types are sent only over this channel — there is no email/SMS/WhatsApp equivalent.

executeCronJob — the admin-only GraphQL mutation that lets internal Dentolize staff manually run any registered cron job on demand, including dailyNotificationsCron with ignoreHour: true (processes every enabled company immediately, regardless of local time).

wrapCronJob / job context — the shared observability wrapper (packages/server/src/utils/observability/jobContext.js) every cron in this system is registered through: structured logging, an OpenTelemetry span, and a Sentry scope, all tagged with the job's name.