Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/J0S3-LEON/pf_pruebasAseguramientoCalid_SDD/llms.txt

Use this file to discover all available pages before exploring further.

MindFlow’s Notification Service keeps students aware of upcoming deadlines without overwhelming them. It runs as a scheduled cron job every hour, scans for tasks whose deadlines fall within the next 24 hours, and dispatches a reminder if the task still has pending micro-objectives. To prevent notification fatigue, the service enforces a hard cap of 3 dispatched notifications per student per 24-hour window. When a student is in the middle of an active EMA session, all deadline reminders are suppressed for the duration of that session — avoiding interruption at the most cognitively sensitive moment. Every notification event, whether sent, failed, or suppressed, is recorded in the notification_logs table with a UTC timestamp and a delivery status.

Trigger condition

A deadline reminder is eligible to be dispatched when all of the following conditions are true:
  1. The task has is_deleted = false.
  2. The task’s deadline falls within the next 24 hours from the current time.
  3. The task has at least one micro-objective where is_completed = false and is_audit_only = false.

Notification frequency cap

The Notification Service enforces a maximum of 3 sent notifications per student per 24-hour rolling window. Once a student has 3 sent records within that window, no further dispatches occur for the remainder of that period — even if additional eligible tasks exist. This limit is checked via the getDispatchCount method before any dispatch attempt is made.

Session suppression

If the student has an active session (is_active = true) at the time the cron job runs, all deadline reminders for that student are suppressed. A suppressed record is still written to notification_logs so the event is fully auditable. Suppression ends as soon as the session becomes inactive (i.e. after the fatigue score is submitted and the session is closed).

Retry logic

1
First delivery attempt
2
The Notification Service attempts to deliver the notification. On success, the log record is written (or updated) with status = "sent" and attemptCount = 1.
3
Retry on failure
4
If delivery fails, attemptCount is incremented and the record status stays "pending". On the next cron run, the service detects the existing pending record and attempts delivery again.
5
Maximum attempts reached
6
After 3 consecutive failed attempts, the record is updated to status = "failed" and no further retries occur for that notification event.
Once a notification is marked failed after 3 unsuccessful delivery attempts, it will not be retried again for that event — ever. The record remains in notification_logs as a permanent audit entry. If the underlying delivery issue is resolved, new notification events for future deadlines will be processed normally.

Audit logging

Every notification event — dispatched, failed, or suppressed — produces exactly one record in notification_logs. No event is silently dropped. Notification log fields
FieldTypeDescription
idUUIDUnique identifier of the log record
studentIdUUIDThe student this notification targets
taskIdUUIDThe task whose deadline triggered the reminder
statuspending | sent | failed | suppressedCurrent delivery status
attemptCountintegerNumber of delivery attempts made so far
dispatchedAtUtcUTC timestampWhen this log record was created or last updated

The INotificationService interface

interface INotificationService {
  dispatchReminders(): Promise<void>; // cron job every hour
  suppressDuringSession(studentId: string): Promise<boolean>;
  getDispatchCount(studentId: string, windowHours: number): Promise<number>;
}
  • dispatchReminders() — the main entry point, decorated with @Cron(CronExpression.EVERY_HOUR). Finds all eligible tasks and processes each student-task pair.
  • suppressDuringSession(studentId) — queries the sessions table for an active session (is_active = true). Returns a Promise<boolean> that resolves to true if one exists, meaning notifications should be suppressed.
  • getDispatchCount(studentId, windowHours) — counts sent records in the notification_logs table within the given rolling window. Used to enforce the 3-per-day cap.

Processing flow per task

The following diagram shows the decision path the Notification Service follows for each eligible student-task pair on every cron run:
1
Check for active session
2
Call suppressDuringSession(studentId). If true, write a suppressed log record and skip to the next task.
3
Check frequency cap
4
Call getDispatchCount(studentId, 24). If the count is ≥ 3, skip without writing a log record (the cap is silent).
5
Look up or create a log record
6
Search for an existing pending or failed record for this student-task pair within the last 24 hours with attemptCount < 3. If none exists, create a new record with status = "pending".
7
Attempt delivery
8
Call the internal deliver(studentId, taskId) method. In production this connects to a push/email/WebSocket provider.
9
Update status
10
  • Success: update or create the record with status = "sent" and the final attemptCount.
  • Failure: increment attemptCount. If attemptCount >= 3, set status = "failed". Otherwise keep status = "pending" for the next retry.
  • The Notification Service runs as a scheduled cron job every hour — it does not push to clients in real time. Notifications are processed in batch on the server. Notification logs are an internal audit trail and are not exposed through a public API endpoint.

    Build docs developers (and LLMs) love