zapier-decisions/decisions/D006-libsql-business-jetstream-work.md

2.3 KiB
Raw Permalink Blame History

D006 — Business data in libSQL; JetStream only for work

Status: accepted
Step: 6
Date: 2026-10-03

Launch topology is 3–5 machines (gateway, bridge, delivery, and related planes). Shared business state must not live as per-host SQLite files.

Decision

  1. System of record for business / accounting / customers / pricing is libSQL (Turso’s SQLite fork; server mode or hosted). That includes:

    • customers, segments, tiers, balances, Stripe / PO metadata
    • pricing and channel×segment rate cards
    • invoices and invoice lines
    • metered usage ledger (usage_entries and its append-only hash chain)
    • other accounting and CRM-style records for the Zapier/Verae edge stack
  2. NATS JetStream is used as necessary for multi-host work distribution (job queues, competing consumers, retries, durable event fans that are not the money ledger). Examples: ZAPIER_JOBS, worker pull/ack, bridge task streams.

  3. Core NATS (ephemeral) remains mandatory for Verae timestamp job-complete / jobId notifications (verae.ts.completed, verae.ts.receipt). Those must not move to JetStream.

  4. Timestamping-svc Go blockchain.db and other Go timestamping SQLite files stay on that service; this decision does not relocate them.

Relationship to earlier decisions

  • D001 (single prepaid writer) still holds: one logical writer path for prepaid/credits. The durable store for that path becomes libSQL, not per-process books.json or a private billing.db on each machine. Edge balanceCents may remain a cache filled from the billing/libSQL service.
  • Lab billing.db / zappier.db on 138 are the current single-host stand-in; migrate that schema into shared libSQL before splitting planes across hosts.

Non-goals

  • JetStream as the customer/balance/invoice/pricing database
  • Litestream as a multi-writer fabric (Litestream remains backup/DR for a primary if used)
  • Per-machine copies of customer or pricing tables

Implementation sketch

  • Keep repositories behind a small DB interface; swap better-sqlite3 / modernc file opens for libSQL client when the shared server is up.
  • One billing writer path owns usage hash-chain appends (BEGIN-style sequencing).
  • Gateway/bridge/delivery call billing APIs or the shared libSQL endpoint; they do not each open a local billing file for production.