56 scheduled jobs across two systems. Each job lives in exactly one.
Fonteum runs scheduled work across two cron systems: Inngest (for jobs that need step-level retries, event emission, or observability) and Vercel cron (for lightweight HTTP-only operations). Ownership is decided by the AGENTS.md §cron-doctrine decision tree; the tools/cron-ownership-check.sh CI gate blocks any job that lands in both systems or is missing from this page.
Step-orchestrated work — retries, observability, event emission.
Inngest owns work that needs structured failure handling. Source pullers (network can flap), identity-linker (multi-step batch), webhook-deliverer (per-recipient retry), and citation-discoverer (rate-limited external API) all rely on Inngest’s step primitives + dashboard observability.
| Job ID | Schedule (UTC) | Source file | Purpose |
|---|---|---|---|
care-compare-asc-monthly | 0 6 1 * * | src/inngest/functions/care-compare-asc-monthly.ts | Monthly CMS Care Compare ASC refresh reminder; emits fonteum/source.refresh_due for the operator-triggered ASC ingest. |
care-compare-dialysis-monthly | 0 6 1 * * | src/inngest/functions/care-compare-dialysis-monthly.ts | Monthly CMS Care Compare Dialysis refresh reminder; emits fonteum/source.refresh_due for the operator-triggered dialysis ingest. |
citation-discoverer | 0 9 * * * | src/inngest/functions/citation-discoverer.ts | Daily OpenAlex poll for papers citing Fonteum data; populates discovered_citations moderation queue. |
daily-refresh-stale-check | 0 9 * * * | src/inngest/functions/source-refresh-reminders.ts | Logs sources that have not refreshed within their declared cadence; surfaces in /freshness degraded badge. |
health-check | 0 7 * * * | src/inngest/functions/health-check.ts | Daily Inngest dashboard ping confirming the function-registration round-trip is alive. |
identity-linker | */5 * * * * | src/inngest/functions/identity-linker.ts | Polling job that resolves NPI ↔ PECOS-ID ↔ CCN ↔ LEIE provider identity links in batches. |
methodology-publisher | 0 7 * * * | src/inngest/functions/methodology-publisher.ts | Detects methodology version bumps + emits fonteum/methodology.published event for downstream consumers. |
records-request-reminders | 0 8 * * * | src/inngest/functions/records-request-reminders.ts | Scans outstanding public-records requests; emails operator when SLA breach is imminent (e.g. AZ ROC PR-0006673). |
refresh-reminder-<family> | per-source from cron-sources.cron_expression | src/inngest/functions/source-refresh-reminders.ts | Family-specific cadence reminder that nags the operator to refresh a source on schedule (NPPES, Care Compare, etc.). |
source-health-monitor | */15 * * * * | src/inngest/functions/source-health-monitor.ts | HEAD probe per source upstream URL; flips source_health_status row + emits fonteum/source.health_status_changed. |
source-puller-bea-regional | 0 6 1 10 * | src/inngest/functions/source-puller-bea-regional.ts | Annual October BEA Regional pull — area-level GDP + per-capita income. |
source-puller-bls-oews | 0 6 1 5 * | src/inngest/functions/source-puller-bls-oews.ts | Annual May BLS OEWS pull — occupational employment + wage statistics. |
source-puller-hrsa-hpsa | 0 6 1 1,4,7,10 * | src/inngest/functions/source-puller-hrsa-hpsa.ts | Quarterly HRSA HPSA pull — Health Professional Shortage Area designations. |
source-puller-leie | 0 6 1 * * | src/inngest/functions/source-puller-leie.ts | Monthly OIG LEIE pull — federal program exclusions list. |
source-puller-open-payments | 0 6 30 6 * | src/inngest/functions/source-puller-open-payments.ts | Annual late-June CMS Open Payments pull — Sunshine Act manufacturer-physician general payments. |
source-puller-pecos | 0 6 * * 0 | src/inngest/functions/source-puller-pecos.ts | Weekly Sunday CMS PECOS PPEF pull — Medicare provider enrollment status. |
event-emitterevent: fonteum/source.snapshot_inserted | event | src/inngest/functions/event-emitter.ts | Fans source-snapshot-inserted events into downstream consumers (webhook-deliverer, methodology-publisher). |
refresh-manual-triggerevent: source.refresh.manual_triggered | event | src/inngest/functions/source-refresh-reminders.ts | Operator-fired manual refresh of a source family — re-runs the puller out-of-cadence. |
webhook-delivererevent: webhook.delivery.queued | event | src/inngest/functions/webhook-deliverer.ts | Per-recipient webhook delivery with backoff retry; consumes events emitted by the source-snapshot pipeline. |
source-puller-provider-utilization | per-source cron_expression (0 6 * * *) | src/inngest/functions/source-puller-provider-utilization.ts | Daily CMS Provider Utilization & Payment Data snapshot pull; attests, chains, and emits snapshot events. |
source-puller-inpatient-utilization | per-source cron_expression (20 6 * * *) | src/inngest/functions/source-puller-inpatient-utilization.ts | Daily CMS Inpatient Utilization snapshot pull; attests, chains, and emits snapshot events. |
source-puller-outpatient-utilization | per-source cron_expression (40 6 * * *) | src/inngest/functions/source-puller-outpatient-utilization.ts | Daily CMS Outpatient Utilization snapshot pull; attests, chains, and emits snapshot events. |
fhir-bulk-export-workerevent: fhir.bulk.export.requested | event | src/inngest/functions/fhir-bulk-export-worker.ts | Processes FHIR R4 Bulk Data Access ($export) job requests; writes NDJSON output, updates job status. |
nsa-compliance-quarterly | 0 9 15 3,6,9,12 * | src/inngest/functions/nsa-compliance-quarterly.ts | Quarterly NSA/surprise-billing compliance score computation across IDR + MRF datasets. |
real-act-compliance-quarterly | 0 9 15 3,6,9,12 * | src/inngest/functions/real-act-compliance-quarterly.ts | Quarterly REAL Act network-adequacy compliance scoring for health plans. |
provider-directory-accuracy-quarterly | 0 9 15 3,6,9,12 * | src/inngest/functions/provider-directory-accuracy-quarterly.ts | Quarterly Provider Directory Accuracy Index (PDAI) computation across all 51 jurisdictions. |
zenodo-publisher | */15 * * * * | src/inngest/functions/zenodo-publisher.ts | Polls methodology_change_log for unpublished entries; publishes approved methodology versions to Zenodo. |
hospital-margin-annual | 0 9 1 12 * | src/inngest/functions/hospital-margin-annual.ts | Annual hospital financial margin computation from HCRIS cost reports; runs each December 1. |
chain-extender | */5 * * * * | src/inngest/functions/chain-extender.ts | Polls snapshot_attestations for unchained rows; links previous_link_hash to extend the attestation chain. |
endpoint-uptime-monitor | */5 * * * * | src/inngest/functions/endpoint-uptime-monitor.ts | 5-min /api/health ping; records result in endpoint_uptime_checks for rolling 24h/30d uptime % shown on /status dashboard. |
freshness-watchdog | 0 14 * * * | src/inngest/functions/freshness-watchdog.ts | Daily dataset freshness audit: fetches /api/freshness, compares last_updated against declared cadence, emails operator when any dataset exceeds its threshold or endpoint uptime < 99% over 24h. |
snapshot-archive | 0 3 * * * | src/inngest/functions/snapshot-archive.ts | Daily 03:00 UTC content-addressed snapshot of NPPES + PECOS source datasets to S3 (fonteum-snapshots). Deduped by SHA-256; indexes captured_at in dataset_snapshots for /status Last-snapshot column and 36h freshness gate. |
risk-signal-refresh | 0 4 * * * | src/inngest/functions/risk-signal-refresh.ts | Daily 04:00 UTC recompute of risk signals for up to 10K NPIs in provider_risk_signals (stalest first). Fires 1h after snapshot-archive so fresh NPPES/PECOS data is captured first. Upserts via ON CONFLICT (npi, signal_type). |
risk-signal-refresh-error-alertevent: inngest/function.failed | event | src/inngest/functions/risk-signal-refresh.ts | Event-triggered: listens for inngest/function.failed scoped to risk-signal-refresh and sends a Resend operator alert. |
daily-dataset-snapshotter | 15 6 * * * | src/inngest/functions/daily-dataset-snapshotter.ts | Daily 06:15 UTC row-count snapshot for 7 core dataset families (NPPES, OIG LEIE, PECOS, QPP MIPS, POS, Care Compare NH, source manifest). Upserts source_snapshot rows and inserts snapshot_attestation rows so the chain-extender can sign them. Supports the Wave 6Z W1.1 chain bootstrap goal of ≥7 daily signed links. |
Lightweight HTTP-only ticks — fire-and-forget acceptable.
Vercel cron owns work that completes fast, has no external dependencies that fail interestingly, and doesn’t need step-orchestration. Defined in vercel.json crons[]; each entry maps to a src/app/api/cron/<name>/route.ts handler.
| Job ID | Schedule (UTC) | Source file | Purpose |
|---|---|---|---|
ai-citation-sampler | 0 6 * * * | src/app/api/cron/ai-citation-sampler/route.ts | Samples AI assistants for citations of Fonteum data; logs to ai_citations. |
archive-events | 0 4 * * * | src/app/api/cron/archive-events/route.ts | Daily housekeeping — archives old page_views + claim_funnel_events to keep hot tables small. |
auction-sweeper | */15 * * * * | src/app/api/cron/auction-sweeper/route.ts | Closes expired ppl_auctions + locks the winning bid as the active featured listing. |
audit-deploy | 0 8 * * * | src/app/api/cron/audit-deploy/route.ts | Daily post-deploy audit — checks recent deploys against schema-validation + launch-gate baselines. |
monthly-market-reports | 0 6 1 * * | src/app/api/cron/monthly-market-reports/route.ts | Monthly per-vertical local-market PDF report generator for owner_digest distribution. |
outreach-drip | 0 15 * * * | src/app/api/cron/outreach-drip/route.ts | Daily outbound drip campaigns to claim-targets; reads outreach_queue. |
outreach-followup | 0 9 * * * | src/app/api/cron/outreach-followup/route.ts | Daily backlink outreach followup cron — sends d+5 and d+12 follow-up emails to prospects who have not replied. |
owner-digest | 0 14 * * * | src/app/api/cron/owner-digest/route.ts | Daily owner-tier digest email — review aggregates, listing performance, alerts. |
partner-reconciliation | 0 9 * * 1 | src/app/api/cron/partner-reconciliation/route.ts | Weekly Monday partner-attribution reconciliation — matches partner_clicks to landed conversions. |
ping-new-urls | 17 * * * * | src/app/api/cron/ping-new-urls/route.ts | Hourly IndexNow ping for newly-published URLs (claim_drafts → published listings, new research studies). |
ping-sitemaps | 30 2 * * * | src/app/api/cron/ping-sitemaps/route.ts | Daily Google + Bing sitemap-ping notification. |
recompute-rankings | 0 5 * * * | src/app/api/cron/recompute-rankings/route.ts | Daily vertical_city_rankings rollup — composite score across review aggregates + license + provenance. |
recompute-response-leaderboards | 0 4 * * * | src/app/api/cron/recompute-response-leaderboards/route.ts | Daily response_leaderboards rollup — owner-response-rate analytics. |
referrals-expire | 0 3 * * * | src/app/api/cron/referrals-expire/route.ts | Daily owner_referrals expiry — closes unredeemed referral credits past their TTL. |
review-request-drip | */15 * * * * | src/app/api/cron/review-request-drip/route.ts | Every 15 min — sends queued review_requests to owner-claimed customers. |
revalidate-stats | 0 * * * * | src/app/api/revalidate-stats/route.ts | Hourly ISR cache revalidation for /coverage + per-vertical stat pages. |
schema-audit | 0 6 * * 0 | src/app/api/cron/schema-audit/route.ts | Weekly Sunday rich-results / Schema.org test against every public surface; logs to schema_audit_reports. |
schema-validate | 30 3 * * * | src/app/api/cron/schema-validate/route.ts | Daily JSON-LD validity scan; logs to schema_validation_runs. |
snapshot-review-themes | 0 3 * * * | src/app/api/cron/snapshot-review-themes/route.ts | Daily snapshot of business_review_themes deltas → business_review_theme_snapshots. |
submit-gsc-sitemaps | 15 3 * * * | src/app/api/cron/submit-gsc-sitemaps/route.ts | Daily Google Search Console sitemap submission across the 40-domain network. |
weekly-seo-report | 0 8 * * 1 | src/app/api/cron/weekly-seo-report/route.ts | Weekly Monday SEO performance rollup → weekly_seo_reports table; consumed by /admin dashboards. |
Decision tree per AGENTS.md §cron-doctrine.
- Does the job need step-level retries, idempotency, or step-orchestration? → Inngest.
- Does the job emit events that downstream Inngest functions consume? → Inngest.
- Does the job need observability beyond simple HTTP-200/non-200? → Inngest.
- Lightweight HTTP-only operation that completes in seconds with no external failure modes? → Vercel cron.
When unclear, default to Inngest — it is strictly more capable. The tools/cron-ownership-check.shCI gate blocks any job that lands in both systems and any job that is missing from this page’s registry.