Skip to content

Background Jobs

PinTeach uses BullMQ + Redis for background job processing. All workers are initialized in apps/api/src/index.ts.

#WorkerSchedulePurpose
1auto-completePer sessionComplete sessions after end + grace period
2calendar-sync5 min cronRetry pending calendar sync records
3drive-copyOn demandCopy Drive files to student folders
4drive-sync3 AM dailyVerify Drive file integrity
5lifecycle-detection6 AM dailyDetect gaps, churn, streaks
6content-analyticsPeriodicAggregate content usage metrics
7audit-cleanup1st of month, 2 AMClean old audit logs by retention tier
8data-retentionSunday 3 AMGDPR data retention enforcement
9waitlist-expiryHourlyExpire stale waitlist offers, cascade notifications
10metric-alertsPeriodicMonitor teacher KPI thresholds, generate alert notifications
11scheduled-messagesDelayed jobsProcess scheduled contact reminders

Scheduled per-session at endsAt + gracePeriodMinutes. Two modes:

  • AUTO_COMPLETE: Session → completed, CreditLedger: CONSUME
  • PENDING_REVIEW: Session → pending_review, notify teacher

Every 5 minutes. Processes batch of 20 pending session_calendar_sync records. Skips if the google-calendar circuit breaker is open.

On-demand (triggered when Drive resources are linked to sessions). Concurrency: 3. Protected by circuit breaker + rate limiter. Blocked jobs are re-queued with DelayedError.

Daily at 3 AM. Verifies Drive file integrity by checking if files still exist. Marks trashed/deleted files in drive_file_copies.

Daily at 6 AM. For all teachers, detects:

  • Session gaps (no class in N days)
  • Churn (no activity in N days)
  • Expiring enrollments
  • Session streaks (consistent weekly attendance)

Uses per-teacher retention_settings thresholds.

Periodic aggregation of content usage metrics into content_analytics_cache. Powers the content insights dashboard.

1st of each month at 2 AM. Batched deletes per retention tier:

  • Financial: 7 years
  • Student: 3 years
  • General: 1 year
  • Fallback: 6 months

Sundays at 3 AM. Per-teacher GDPR enforcement:

  1. Auto-delete inactive students past threshold
  2. Clean old session content
  3. Clean old contact log entries
  4. Check overdue erasure requests

Hourly. Expires notified waitlist entries past expiresAt (48h window). Auto-notifies the next person in line.

Periodic metric alerts check. Monitors teacher KPI thresholds and generates notifications when metrics cross alert boundaries.

Processes delayed BullMQ jobs for scheduled contact reminders. On fire: creates contact_log entry + teacher_notification. Teacher still manually contacts via WhatsApp/email. Recovers overdue pending messages on startup (re-enqueues with delay: 0).

Workers use circuit breakers and rate limiters for external API calls:

  • Circuit breaker: Redis-backed, shared across API + workers
  • Rate limiter: Sliding-window, per-teacher + global levels
  • Failed jobs: Re-queued with exponential backoff via BullMQ

Drive copy worker uses tryAcquire() — if rate limited, re-queues with DelayedError instead of waiting.