ADR-0006: Delete dead EC2 background processors

Context

PropFlow's Next.js server (EC2 / PM2) starts a handful of setInterval background processors at boot time via src/instrumentation.ts. Over the course of 2025-2026 several of them have become redundant:

Processor File Why it exists Why it's dead
Email Replay src/lib/email/replay-stalled.ts Resurrect email ingestion records stuck in processing/received after a server crash. SQS FIFO redrive + propflow-inbound.fifo DLQ now handle retries transparently. The processor only runs when SQS_INBOUND_QUEUE_URL is unset — which prod hasn't done since Phase 2.
Dead Letter Retry src/lib/email/retry-processor.ts Periodically retry outbound emails that SendGrid/SES rejected with a transient error. SendGrid's native retry + SES bounce handler cover every real-world case. The DL table has not had a successful resend in weeks.
Sync Digest src/lib/rent-roll/sync-digest-processor.ts Fire a daily 8 AM CT digest email summarizing rent-roll sync activity. Replaced by an ad-hoc admin trigger POST /api/admin/sync-digest + the daily cron described in scripts/. Nobody reads the auto-sent digest.
Voice Trace src/lib/voice/voice-trace-processor.ts Backfill AgentTrace rows from ElevenLabs 20 s after each call, because ElevenLabs finalises analysis after the webhook fires. The voice call-ended webhook now builds the trace inline from the same payload (analysis arrives in the webhook body; the 20 s race is gone).

In addition, two processors ARE still producing value, but the timer-on-EC2 shape is the wrong primitive for them:

Processor File Better shape
Application Link src/lib/leasing/application-link-processor.ts EventBridge Scheduler one-shot: tour confirmation schedules an invocation for now + postTourFollowUpDelayMinutes.
Listings Sync src/lib/leasing/listings-sync-processor.ts EventBridge rate(15 m) rule targeting a tiny Lambda.

Decision

  1. Delete the four dead processors (file + tests + comments). Their DynamoDB artefacts (e.g. dead-letter table entries, voice trace status flags) are left in place — no prod data is touched by this ADR.
  2. Migrate application-link to a one-shot EventBridge Scheduler + Lambda (propflow-application-link). Call site: applyTourIntent (action=confirm and auto-confirmed propose).
  3. Migrate listings-sync to an EventBridge rate(15m) rule + Lambda (propflow-listings-sync).
  4. Until the new Lambdas have been live for one week, the existing setInterval versions of application-link and listings-sync stay running as a belt-and-braces safety net. After the cutover week, delete the *-processor.ts files and the startX() calls in src/instrumentation.ts.
  5. All prod AWS resource creation (EventBridge rules, Scheduler schedules, IAM policies) is performed out-of-band via the deploy scripts checked in under lambda/<name>/deploy.sh. This ADR does not create any cloud resources on its own.

Consequences

Implementation notes