Skip to main content

The seven layers

  1. Runtime route POST /v1/core/track — auth (api key | write key), Zod envelope, Upstash rate limit, permission core.events.write. NO business logic. Returns 202 {event_id} in <100 ms p95.
  2. Queue publication — QueuePort.publish(‘core.ingest’, envelope{job_id, tenant_id, correlation_id, data}). Adapter bound in core module composition root (Vercel Queues at F1).
  3. Processor (worker) — idempotency gate (core.processed_jobs by job_id; tracked_events idempotency_key as second fence). Steps in ONE logical flow: identity resolution/upsert → append tracked_events (partitioned; occurred_at predicate discipline) → incremental segment eval (diff → entered/exited) → rules engine match (compiled-rules cache per tenant).
  4. Domain writes — effects execute via loyalty domain services (e.g., award_points → ledger transaction + lot + balance projection SAME transaction).
  5. Outbox + audit — every state change emits events + audit_log rows with correlation_id/causation_id (ADR-017 pattern).
  6. Consumers — notification dispatch (resolveChannels → per-channel rail jobs), webhooks out (HMAC), cache invalidation, metering.
  7. Tests & budgets — unit: resolveChannels, DSL eval, rules dedupe; integration: full pipeline with duplicate job replay (must no-op); load: k6 track p95 <100 ms, end-to-end effect visibility <5 s p95 in cert. All budgets are DoD items.

What agents copy from here

Fast-ack shape · processed_jobs gate placement · one-transaction write+outbox+audit · correlation propagation · partition-key discipline · rail selection for notifications.