bf5ca2c615
PR5b, the final code piece of the WhatsApp intake track. A daily cron (04:15) enforces the channel's retention table; the receipt itself stays 7-year WORM under BFL and is never touched. Retention actions (lib/retention.ts, each isolated and idempotent): - whatsapp_messages transcripts past 90 days: body_text + raw_payload cleared in id batches under a wall-clock budget; the row skeleton (wamid, direction, timestamps, status, inbox_item_id) survives for audit. Only rows still carrying content match. - Rows with phone_link_id IS NULL (unknown senders, orphans) past 30 days: deleted. - Link codes expired more than 24h ago: deleted, used or not. - Sender rate counters idle 2+ days: deleted (minute/day window keys are dead weight after that). - Links revoked 90+ days ago: phone_enc crypto-shredded to '' (column is NOT NULL), one-shot via neq guard; phone_hash and phone_masked kept for uniqueness history and audit display. Route mirrors the sweep cron exactly: withCronContext + registry gate (503 EXTENSION_DISABLED when the extension is off). vercel.json gets the schedule and both Docker crontabs are regenerated. Compliance: new whatsapp.receipt_intake activity in .compliance/ropa.yaml covering purpose, Art 6(1)(b)/(c)/(f) bases with the Art 14(5)(b) note for third-party attendee names, Meta Platforms Ireland as processor (Cloud API, EU SCC addendum, Local Storage region DE), the differentiated retention table, and security measures. Co-authored-by: Jakob Wennberg <jakob.wennberg@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
82 lines
1.8 KiB
JSON
82 lines
1.8 KiB
JSON
{
|
|
"regions": ["arn1"],
|
|
"crons": [
|
|
{
|
|
"path": "/api/deadlines/status/cron",
|
|
"schedule": "0 6 * * *"
|
|
},
|
|
{
|
|
"path": "/api/invoices/recurring/cron",
|
|
"schedule": "0 * * * *"
|
|
},
|
|
{
|
|
"path": "/api/settings/booking-templates/sync/cron",
|
|
"schedule": "30 4 * * *"
|
|
},
|
|
{
|
|
"path": "/api/tax-deadlines/cron",
|
|
"schedule": "0 0 * * *"
|
|
},
|
|
{
|
|
"path": "/api/extensions/enable-banking/sync/cron",
|
|
"schedule": "0 5 * * *"
|
|
},
|
|
{
|
|
"path": "/api/extensions/stripe/transactions/cron",
|
|
"schedule": "30 3 * * *"
|
|
},
|
|
{
|
|
"path": "/api/documents/verify/cron",
|
|
"schedule": "0 3 * * *"
|
|
},
|
|
{
|
|
"path": "/api/sandbox/cleanup/cron",
|
|
"schedule": "0 4 * * *"
|
|
},
|
|
{
|
|
"path": "/api/events/cleanup/cron",
|
|
"schedule": "0 2 * * *"
|
|
},
|
|
{
|
|
"path": "/api/extensions/cloud-backup/auto-sync/cron",
|
|
"schedule": "0 * * * *"
|
|
},
|
|
{
|
|
"path": "/api/idempotency/cleanup/cron",
|
|
"schedule": "30 * * * *"
|
|
},
|
|
{
|
|
"path": "/api/pending-operations/expire/cron",
|
|
"schedule": "30 2 * * *"
|
|
},
|
|
{
|
|
"path": "/api/extensions/skatteverket/skattekonto/sync/cron",
|
|
"schedule": "0 4 * * *"
|
|
},
|
|
{
|
|
"path": "/api/extensions/skatteverket/agi/kvittenser/cron",
|
|
"schedule": "*/15 * * * *"
|
|
},
|
|
{
|
|
"path": "/api/extensions/skatteverket/vat/kvittenser/cron",
|
|
"schedule": "30 */2 * * *"
|
|
},
|
|
{
|
|
"path": "/api/webhooks/dispatch/cron",
|
|
"schedule": "* * * * *"
|
|
},
|
|
{
|
|
"path": "/api/extensions/whatsapp-inbox/sweep/cron",
|
|
"schedule": "* * * * *"
|
|
},
|
|
{
|
|
"path": "/api/extensions/whatsapp-inbox/retention/cron",
|
|
"schedule": "15 4 * * *"
|
|
},
|
|
{
|
|
"path": "/api/bookkeeping/accruals/post-due/cron",
|
|
"schedule": "15 5 * * *"
|
|
}
|
|
]
|
|
}
|