Trinitas Volunteers

How the app is built

High-level architecture notes for developers and curious admins.

Stack

  • Astro 6 SSR on Cloudflare Pages for the web UI at volunteers.trinitaschurch.com.
  • Cloudflare D1 (SQLite) for the database.
  • Cloudflare Workers for the email worker, the weekly-reminder cron worker, and the Tail worker (error forwarding).
  • Cloudflare Email Service for transactional email from deacons@trinitaschurch.com.
  • Mailchimp for the weekly reminder campaign (pluggable — see below).
  • Tailwind with the same design tokens as the sibling trinitaschurch/website repo.

Three Workers, linked by Service Bindings

  volunteers-web   ──RPC──▶   volunteers-email
      │                               ▲
      │ (D1 binding)                  │ RPC
      ▼                               │
     D1   ◀──(D1 binding)───  volunteers-scheduler  (cron: Sun 18:00 UTC)
  • volunteers-web — everything users see. Auth, admin, CRUD, UI.
  • volunteers-email — the only Worker that imports email provider SDKs and the only writer of the email_campaigns / email_messages tables.
  • volunteers-scheduler — a tiny cron Worker that fires once a week, reads next Sunday’s assignments, and calls the email Worker to queue the reminder campaign.
  • volunteers-tail — Tail Worker bound as an error consumer on the other three; posts to a deacons’ Slack channel.

Email provider plugin layers

Three swappable layers, each selected via env flag:

  1. Send (transactional, per-message): cf_email default, resend / mandrill / mailchimp_transactional available.
  2. Campaign (scheduled fan-out): direct (per-recipient via Layer 1) or mailchimp (Marketing API with IF/ELSEIF). Selectable per-kind.
  3. Audience sync (list membership): mailchimp or noop.

To remove Mailchimp entirely: flip the campaign and audience providers, delete the mailchimp.ts files, drop the API key. No other code changes.

Observability

  • Workers Logs with structured JSON lines.
  • Logpush to R2 bucket trinitas-church-logs for 30-day retention.
  • Workers Analytics Engine custom dataset with dimensional metrics on every send and every schedule generation.
  • Web Analytics (privacy-friendly page views).
  • D1 Insights (built-in query stats).
  • Health Check on a /_healthz endpoint that flips to 503 if the weekly cron hasn’t fired in 8 days.
  • Tail Worker forwards unhandled errors to Slack within minutes.

Database schema

Nineteen tables (users, roles, availability, services, assignments, coverage_requests, swap_proposals, groups, group_members, applications, application_steps, …). The full schema is in migrations/0001_init.sql in the repo.

Repo

Source at github.com/trinitaschurch/volunteers. Private. Infra in github.com/trinitaschurch/infra.