Temporal
Huddle uses Temporal (self-hosted) for all durable, multi-step, cross-service work — document parsing, bond automation, and transactional email. Anything that must survive a restart, retry cleanly, or outlive a browser session runs as a Temporal workflow.
The client/worker split
Section titled “The client/worker split”- The API is the sole Temporal client. It defines no workflows — it starts them (on user actions or internal events) and watches their status (a single internal poller streams changes out over SSE).
- RAG and Notification are Temporal workers. Each polls its own task queue and executes the workflows registered on it.
graph LR
API[API — client] -->|start / watch status| RAGQ[rag queue]
API -->|start| NOTQ[notification queue]
RAGQ --> RAG[RAG worker]
NOTQ --> NOT[Notification worker]
The Temporal namespace is the deployment environment (development /
staging / production), so each environment’s workflows are isolated.
Task queues & workflows
Section titled “Task queues & workflows”| Queue | Worker | Workflows |
|---|---|---|
rag-tasks |
RAG | ProcessBondRequest (parent), ParseDocument, GenerateField, FindBond, FillBond, DeleteDocument |
notification |
Notification | SendInvite, SendOTP, SendBondRequest |
Deterministic workflow IDs
Section titled “Deterministic workflow IDs”The API derives each workflow’s ID as {taskQueue}/{workflow}/sha256(args).
Starting a workflow with identical args terminates and replaces the running
one — a natural dedupe for idempotent triggers.
Status → the UI
Section titled “Status → the UI”Temporal has no push channel, so workflow.Client runs one internal poller (a
Watcher, 1s tick) and the API exposes SSE …/watch endpoints that stream
a bare status (running / completed / failed) whenever it changes. The
app consumes those streams server-side and re-exposes them as tRPC
subscriptions.
This is how the UI reflects parse / generate / fill / find progress live —
without per-second polling from the browser. See
API › Watching workflow status.
Inspecting workflows
Section titled “Inspecting workflows”Open the Temporal web UI in a browser and sign in with your Huddle Google Workspace account (Google SSO — access is restricted to the org). From there you can inspect workflows, task queues, and — via the Workers tab — live worker health: per-worker task-slot usage, poll activity, and cache hit rate.
Deployment
Section titled “Deployment”Self-hosted on Railway from the temporal repo (its own Railway project,
deploys from main). Single-container temporalio/server — all four roles in
one process — backed by Postgres, with schema setup and per-environment
namespace creation handled at boot. One namespace per environment
(production / staging / development); services target theirs via
TEMPORAL_NAMESPACE. Deployment, SSO, and configuration specifics live in the
repo.