Skip to main content

Scope and status

Draft design for a center’s daily and periodic reports and staff replies. All examples are synthetic. This page proposes behavior; it does not enable receiving, change senders, provision infrastructure, or apply a schema migration. Invitations and paid custom-domain entitlements are separate designs. Parents should reply to a report and reach authorized center staff, who can read, assign, answer and resolve the conversation beside its student and parent records. Undeliverable addresses must stop consuming sends. Defaults below require product, security and privacy acceptance before activation. Preserve report approval, unsubscribe, workspace permissions and unknown-send-outcome fences.

Verified source baseline

Paths and lines below refer to commit 691e9f70ad7a8c071c57b85752a4b8b56b8e4bc6, inspected without customer data. The supplied brief identifies notifications@tuturuuu.com and SES ap-southeast-1 as the operational sender/region. Code supports configurable workspace credentials; this inspection does not establish live configuration. See the report reply foundation and report behavior. This proposal extends their contracts; it must not be interpreted as changing the disabled foundation today.

Reply address and delivery flow

Keep the currently approved From identity until the project owner approves a change. Configure one verified inbound subdomain, illustrated only as replies.example.test, with a workspace routing policy. Verify DNS ownership, MX routing and a synthetic ingress canary before readiness can become true. Sending identities require SES verification and SPF/DKIM/DMARC alignment independently of inbound MX verification. No DNS or sender change is authorized by this draft. Proposed address: r2.<opaque-id>.<mac>@replies.example.test. Use a 128-bit random identifier and a truncated 128-bit HMAC-SHA256, base64url encoded; the resulting local part fits 64 bytes. MAC input is a canonical versioned tuple containing the opaque ID, workspace, report/post generation, recipient binding, expiry and key version, resolved from private storage. No student name, address or record ID appears in the address. Constant-time verification, a versioned keyring, expiry and revocation prevent tampering and support rotation. Store a lookup digest and encrypted reconstruction material; never expose token values in logs or UI. Extend the existing identity API with a versioned codec; do not silently change its 48-hex parser. Retain legacy decoding only for legitimately issued identities with their original scope and validity. Preserve immutable accepted/unknown send history. Proposed token validity is 180 days; expired replies enter a bounded staff-only exception queue without disclosing report contents or sending a bounce loop. Validate this lifecycle against the eventual retention decision. Cloudflare Email Routing hands raw mail to a Worker. The Worker verifies the exact envelope domain and token, authenticates transport provenance, validates the current workspace/record relationship, and admits durable work. Token possession allows routing only: it does not authenticate a parent or authorize disclosure. Require the bound parent address and verified sender-authentication evidence; forwarded mail, changed guardians, ambiguous identity or failed authentication go to restricted review. Never trust caller-supplied Authentication-Results headers. A staff member must verify a changed contact through the existing contact process. Use the token binding to select the workspace before matching In-Reply-To or References against stored outbound/inbound Internet Message-IDs in that same workspace and conversation. Store SES provider IDs separately from RFC IDs. Conflicting token/header targets go to review; missing headers may start a thread under the valid bound report. Subject matching alone must never join students or workspaces. Deduplicate by transport event and raw digest, with collision review for reused Message-IDs. Persist before acknowledging; failed persistence retries within the configured budget. An acceptance timeout is reconciled, not resent.

Staff inbox and safe replies

Provide a workspace inbox within the report and contact experience, linked to the student, verified parent relationship, original report/post and read-only report snapshot. Reuse mail storage but grant no access to the shared notifications mailbox. Staff roles are viewer, responder, manager and suppression administrator; membership alone is insufficient. Enforce workspace and record permissions on reads, writes, search, attachment downloads and realtime events. Support unassigned/mine/team queues, assign/reassign with optimistic concurrency, reply drafts with approved templates and report context, and open/pending/resolved states. Replies use the center’s approved sender and the same protected send path; never allow arbitrary From, recipient, CC or BCC fields to create an open relay. Show send failures and suppression reasons, and preserve drafts. Accepted by SES is distinct from delivered. New eligible parent replies reopen resolved threads. Proposed SLA: first human response within one business day, using the workspace timezone and staff calendar. Measure from the oldest unanswered eligible inbound message, pause only for explicit waiting-on-parent state, and alert assigned staff and then the manager once per escalation level. Auto-replies never satisfy SLA. Provide unread, status, assignment, report period, student, overdue and delivery filters; keep global suppression details hidden from ordinary workspace staff. Detect Auto-Submitted, mailing-list/precedence signals, vacation headers, DSN MIME and empty-envelope bounces. Classify OOO/auto-replies separately, avoid reopening or generating automatic acknowledgements, and allow manual reclassification. Only authenticated SES events may create infrastructure suppression; a forged bounce-shaped email cannot blacklist an address. Human reports of abuse enter staff review. Add bilingual reply instructions only after qualified routing: “Reply to this email to reach the center” and “Trả lời email này để liên hệ trung tâm”. Quarantine attachments before display or forwarding. Check MIME signatures, allowlisted types, decompressed size, archive depth and malware verdict; reject executables and password-protected archives unless a separate safe review process exists. Default to 10 MB per message, 5 attachments, 20 MB expanded total and one archive layer. A timeout or unavailable scanner stays quarantined. Use a private object store, short-lived authorized downloads, sanitized HTML and blocked remote images. No public scanner uploads of parent/student data. A compatible scanning service and its processor agreement are rollout prerequisites.

SES events and suppression

Configure a dedicated SES configuration set in ap-southeast-1, publishing send, delivery, bounce, complaint and delivery-delay events to a Standard SNS topic. Attach the set and opaque correlation tags on every relevant send, including raw MIME staff replies. Limit SNS publish permission to the SES source account and configuration set. AWS documents this configuration-set destination. SNS delivers to a Cloudflare HTTPS webhook. Verify the signature over AWS’s canonical envelope, require the expected topic/account/region, and validate the certificate chain and exact HTTPS SNS certificate host/path with redirects disabled. Verify subscription confirmations before confirming through a pinned AWS endpoint; never fetch arbitrary SubscribeURL or certificate URLs. Prefer signature version 2 and reject unconfigured versions. Follow AWS’s SNS signature verification. Bound payloads, reject malformed events, deduplicate topic + SNS message ID, and also deduplicate semantic delivery events by provider send/recipient/type. Timestamp policy must accommodate documented retries; old unrecognized events require reconciliation rather than silently restoring sending. Resolve the trusted send ledger to workspace and recipient; event tags alone are not authority. Atomically persist the event and hard-bounce/complaint suppression before acknowledging success. Materialize suppression synchronously on this path; queue expensive analysis afterwards. If persistence is unavailable, return a retryable failure and halt affected outbound admission until event health recovers. Unknown send IDs enter a restricted reconciliation queue and raise an alert. Apply conservative address normalization consistently (trim, domain normalization, existing case policy); do not collapse plus tags or provider-specific dots. Role-based and disposable addresses are WATCHED/review signals rather than blanket rejections of legitimate guardian contacts. Aggregate domain failure signals with minimum volume and a bounded hold; security operators may impose a global domain block with evidence. One center’s soft failures must not block unrelated centers. Use a single authoritative pre-send decision at enqueue for feedback and again immediately before provider invocation for races. Return skipped with reason codes such as workspace_blacklist, global_hard_bounce, complaint, watch_cooldown, unsubscribed or suppression_unavailable; distinguish retryable holds from terminal skips. Suppression committed before admission wins; mail already accepted by SES cannot be recalled. Serialize per-recipient admission with suppression updates and minimize the remaining provider handoff window. Never let a generic retry, test-send or manual reply bypass protection. Import the existing manual email_blacklist idempotently using a private export or server-side read, checkpoint and dry-run counts. Preserve email/domain/pattern scope, provenance, reason and original block semantics; ambiguous patterns require review and remain enforced by the legacy checker. Keep existing global blocks global. Reconcile counts/checksums and concurrent writes before switching readers; dual-read the union during transition, never use last-write-wins to clear blocks. No customer export, address list or raw SNS payload belongs in a PR or log.

Dashboard and alerts

Workspace staff see sent, accepted, delivered, skipped with reason, WATCHED, blocked, unanswered and overdue counts. Operators see configuration-set/account health, webhook lag, last verified event, queue age, DLQ, scanner failures and remaining work budgets. Display time window and denominator with bounce/complaint rates; use provider-send/recipient counts and exclude duplicates. Keep SES account reputation metrics distinct from workspace application rates. Proposed early warnings are 2% hard-bounce and 0.05% complaint rates (minimum 100 sends for rate warnings; any complaint still suppresses immediately), or 80% of current SES quota. These are internal proposals, not claims about AWS limits. Infrastructure and security on-call own alerts near account limits. Add a five-minute stale-event warning while traffic exists, and deduplicate/escalate alerts through existing operational channels. Audited restore shows actor, scope, reason, evidence, previous state and result; ordinary staff see only actionable workspace information, never another workspace’s history.

Cloudflare ownership and cost stop fences

Follow Cloudflare backend ownership: Workers handle ingress and send admission; Queues isolate parsing/scanning and outbound jobs; existing Cron Control handles bounded SLA, retention and recheck batches. Supabase remains the system of record. Next routes provide authenticated UI/API adapters only. Do not add Vercel background work, pg_cron, Edge Functions or Trigger.dev processors, or run duplicate legacy and new queue owners. Before pilot, approve workspace and global daily/monthly limits for sends, accepted bytes, object storage, scan bytes, queue operations, database calls and alerts. An unconfigured budget means disabled. Reserve worst-case units atomically before work, including retry amplification; reconcile actual use without refunding unknown outcomes. Initial qualification bounds: batches of 50, three attempts per job within 24 hours, one scan per content hash/version, one SLA alert per escalation level, finite DLQ retention, and operator-approved replay with its own budget. Maintain a durable global/workspace stop state and monotonic epoch checked before every paid operation, provider submission, retry, alarm and queue re-enqueue. Recheck after leases or waits; restarting must not reset counters or stop state. Completed, suppressed, expired, exhausted and cancelled jobs schedule no further work. Stop outbound sends first; reserve a separate bounded budget for receiving suppression events. If that budget is exhausted, keep sends stopped and persist an explicit reconciliation gap. Automatic SNS/queue retries must have finite policies; total shutdown disables upstream subscriptions/routing after durable capture or explicitly recorded loss, not endless failure responses. An application fence cannot eliminate unavoidable ingress invocations or bytes already accepted by providers. Include an operator upstream-disable runbook and measure those residual costs. Billing alerts, ingress rate limits and CPU caps alone do not prove a spending cap. Before activation record service-specific operation counts, failure/restart tests and stop evidence in the adoption guidance.

Privacy and retention

Treat parent and minor correspondence, student links and suppression fingerprints as personal data. Vietnam’s PDPL, Law 91/2025/QH15 is effective from 1 January 2026. Privacy counsel must confirm applicable rules, controller/processor roles, lawful basis, child/guardian requirements, notices, rights handling and cross-border processing before pilot; this is a design gate, not a legal determination. Permission to receive reports does not automatically authorize marketing, AI training or unrelated reuse of replies. Proposed configurable retention: raw MIME/quarantine 7 days, attachments 30 days, conversation content 180 days after resolution, and minimized operational audit 365 days. These are product defaults for review, not statutory periods. Minimize report snapshots; keep content out of telemetry and alert payloads. Encrypt content and contact addresses; use keyed address digests for matching, with key rotation and restricted access. Pseudonymized data remains protected. Delete expired objects, derived text, search indexes and attachments with bounded Cloudflare jobs; propagate deletion tombstones through retries and backups under a documented backup-expiry policy. Existing immutable reply identities need a reviewed retention-specific purge mechanism; never weaken send-outcome fences by ordinary deletion/requeue. Retain only justified minimal suppression fingerprints and reasons while necessary to prevent unwanted contact, review necessity annually, and have counsel decide erasure exceptions and legal holds. Staff-only RLS and record authorization apply to service RPCs too; test tenant isolation, removed staff, changed guardians, signed-download expiry and access audits.

Schema sketch only

Conceptual extensions, not executable SQL or a migration. Final names, constraints, RLS and retention must be reviewed alongside the existing private mail schema. All workspace relationships require matching tenant keys and checked current permissions. Only infrastructure operators manage global state. Scoped staff APIs return block decisions without leaking other tenants’ events. Keep existing blacklist/bounce functions as adapters during rollout; one policy evaluator owns all sends, so old and new schemas cannot disagree permissively.

Effort ranges and phased rollout

Ranges are incremental engineering dev-days for one experienced engineer per slice, including implementation, focused tests and review fixes. They assume reuse of the foundations above; DNS/provider approvals, legal review and calendar waiting are excluded. Scanner integration and schema reconciliation drive the upper bounds. Total sequential effort is 33–54 dev-days, not elapsed time.
  1. Foundation/shadow: A then B, with policy simulation on synthetic events; preserve existing suppressions and reconcile the manual import. Production shadowing requires separate authorization and private telemetry.
  2. Suppression canary: enforce B for one admitted workspace, initially behind explicit enablement. Land E’s stop/budget controls before any billable pilot. Verify that queued sends skip immediately after accepted adverse events.
  3. Reply canary: C and D on synthetic recipients; qualify both daily and periodic reports, token rotation/expiry, retries, scans and staff permissions. Only then enable Reply-To and instructional copy together.
  4. Controlled rollout: F with user approval before real-parent mail. Expand workspace cohorts based on observed delivery and inbox handling, retaining per-workspace stop switches and an accountable staff owner.
Rollback disables new Reply-To issuance and outbound replies while retaining already-issued address receiving for its validity/retention window. Keep all suppression enforcement active. Cancel or quarantine unsent jobs; reconcile accepted/unknown sends before any replay. Schema rollout is additive until migration and retention rehearsals pass; do not drop historical identity tables. If security requires stopping receiving too, use the upstream stop runbook and record the gap for staff recovery rather than claiming replies remain available. Required regression coverage also includes out-of-order delivery after complaint, delay-plus-bounce dedupe, exactly three strikes at the 30-day boundary, concurrent manual blacklist writes, no automatic expiry of hard blocks, removal of staff access, private attachment URLs, deletion fencing, unknown SES acceptance, stop during a lease and exhausted retry budgets. This draft executes none of those runtime checks; implementation PRs must supply evidence before activation.

Decisions to resolve before implementation/pilot

The project owner must approve the outbound display name/address (recommend keep the existing approved identity initially), inbound subdomain/DNS owner, and real parent pilot cohort. Product must accept SLA hours, WATCHED cooldown/restore rules and domain-risk policy. Privacy/security must approve lawful basis, retention, minor/guardian handling, scanner processor/location and global restoration controls. Operations must approve numerical spend budgets, alert ownership and stop procedures. Collect sender/domain approval once per project through the program owner; no real mail or provider change is needed to review this design.