Tags: BabelQueue/babelqueue-node
Tags
feat(gdpr): runtime field encryption for x-gdpr-sensitive — Node core… … (ADR-0030) The SDK-enforcement half of GDPR governance (mirrors the Go reference). New gdpr module: a caller-bound Cipher interface (sync encrypt/decrypt onto KMS/Vault) + a reference AesGcmCipher on node:crypto (AES-GCM, base64(iv||ct||tag)), and protect/unprotect helpers that encrypt/decrypt exactly the schema's x-gdpr-sensitive leaves in place (nested + array + root), byte-for-byte round-trip, wrong key -> typed DecryptError. schema.sensitivePaths() parses x-gdpr-sensitive (validation-neutral). data stays pure JSON (ciphertext string) so the envelope is frozen (GR-1, schema_version 1, trace_id preserved); the Cipher seam keeps the core zero-dep (GR-7). Opt-in; schema validation on cleartext. v1.7.0.
feat(outbox): transactional outbox helper — Node core (ADR-0029) Ports the producer-side transactional outbox: Outbox.write encodes the frozen envelope and persists it via a caller-bound OutboxStore inside the caller's own DB transaction (no dual-write), and OutboxRelay.flush/drain forwards stored rows verbatim through an OutboxTransport — mark-published only after publish resolves, a rejecting publish -> markFailed + linear backoff (row stays pending), one poison row never blocks the batch. At-least-once handoff; consumers dedupe on meta.id (the Idempotent mirror). Frozen bytes ride verbatim (GR-1/4/5); store+transport are interfaces so the core stays zero-dep (GR-7). v1.6.0.
feat(replay): replay-bypass side-effect guard — Node core (ADR-0027) A deliberate DLQ replay can tell its handler to skip external side-effects that already fired (don't re-charge/re-email) while the idempotent core still runs — mirroring the Go reference. New src/replay.ts (HEADER_REPLAY_BYPASS + isReplay + bypassExternalEffects) + redrive bypass wiring. Rides the out-of-band HeaderCarrier seam beside the frozen envelope (GR-1), trace_id preserved (GR-4). Opt-in. v1.5.0.