feat: daily intake-reminder worker for paid orders with incomplete intake
Adds a systemd-timed worker that nudges customers who paid but never completed
their intake form (which stalls fulfillment).
- migration 087: intake_reminder_count + intake_reminder_last_at on
compliance_orders (makes the daily run idempotent and bounded), plus a
partial index for the paid-order eligibility scan.
- scripts/workers/intake_reminder.py: each run emails any paid order with
intake_data_validated != TRUE, capped at 10 reminders/order, at most one
consolidated email per customer per day (groups a customer's incomplete
services into one email). Reuses the post-payment intake URL format
(/order/{slug}?order={n}) and the API's email validation, skipping
placeholder/invalid addresses (synthetic@, pipeline.com, etc.). Sends via
smtplib with SMTP_PASS (verified working in the worker container).
- worker-crons: pw-intake-reminder timer, daily ~noon ET (16:00 UTC).
This commit is contained in:
parent
00c960f5b5
commit
6d4c323ab6
3 changed files with 295 additions and 0 deletions
26
api/migrations/087_intake_reminders.sql
Normal file
26
api/migrations/087_intake_reminders.sql
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
-- 087: Daily intake-reminder tracking on compliance_orders.
|
||||
--
|
||||
-- After a customer pays, we email them an intake form link for each service so
|
||||
-- we can collect the data needed to prepare the filing. Some customers never
|
||||
-- complete intake, which stalls fulfillment. The intake-reminder worker
|
||||
-- (scripts/workers/intake_reminder.py) runs daily at noon ET and nudges any
|
||||
-- PAID order whose intake is still incomplete (intake_data_validated IS NOT
|
||||
-- TRUE), up to a cap of 10 reminders, skipping placeholder/invalid emails.
|
||||
--
|
||||
-- These two columns make the daily run idempotent and bounded:
|
||||
-- intake_reminder_count -- how many reminders we've sent (cap: 10)
|
||||
-- intake_reminder_last_at -- when we last reminded (so we send at most 1/day)
|
||||
--
|
||||
-- Both default to a no-reminders-yet state and are NULL/0 for every existing
|
||||
-- row, so the worker treats all currently-incomplete paid orders as eligible.
|
||||
|
||||
ALTER TABLE compliance_orders
|
||||
ADD COLUMN IF NOT EXISTS intake_reminder_count integer NOT NULL DEFAULT 0;
|
||||
|
||||
ALTER TABLE compliance_orders
|
||||
ADD COLUMN IF NOT EXISTS intake_reminder_last_at timestamptz;
|
||||
|
||||
-- Speeds up the daily eligibility scan (paid + incomplete intake).
|
||||
CREATE INDEX IF NOT EXISTS idx_compliance_orders_intake_reminder
|
||||
ON compliance_orders (payment_status, intake_data_validated, intake_reminder_count)
|
||||
WHERE payment_status = 'paid';
|
||||
Loading…
Add table
Add a link
Reference in a new issue