Kata · Product EngineerKata
// Systems

Production-grade by default.

The happy path is the easy part.

A dropped connection. A slow write. A worker that restarts halfway through a job. A provider that stops answering.

I design systems around what happens next. Domain logic never touches infrastructure or transport directly. State changes and background work have explicit boundaries. Side effects are durable, retriable, and observable, never best-effort.

The infrastructure can change. The boundaries should not.

ScopeBackend
StandardProduction
StorePostgres
RuleDurable Intent
01 / The Spine

The infrastructure changes. The boundaries don't.

Every system I build roughly* reduces to the same small set of boundaries. The technologies underneath can change. The responsibilities shouldn't.

CLIENTnext/react
APInode/go
DOMAINtypescript/go
DB - OUTBOXpostgres
QUEUEredis
WORKERSbullmq/asynq
 
01Client next/react

Typed end-to-end. Transport concerns stay at the edge; the client shapes the experience, not the domain logic.

02API node/go

The boundary. Validation, Auth, Versioning. No business rules live in the transport layer.

03Domain typescript/go

Where the business actually lives. Framework-agnostic, infrastructure-blind, and explicitly testable.

04DB / Outbox postgres

The absolute source of truth. State changes and the intent to do background work are committed in one atomic transaction. A write that doesn't survive a crash isn't done.

05Queue redis

Infra for asynchronous work. Decouples state persistence from downstream processing.

06Workers bullmq/asynq

Durable execution. Payments, AI processing, external integrations, anything slow. Retried on failure, strictly logged, out of the request path. Provider outages are absorbed here.

02 / Boundaries

Good systems make the wrong dependencies difficult.

Transport shouldn't own business rules. The domain shouldn't know whether the database is Postgres or Mongo. Application code shouldn't know whether a job runs on BullMQ or Asynq.

Transportaccept and translate intent
Domaindecide what the system means
Infrastructurepersist, publish, execute, observe
External providersperform work outside the system

Dependency flows inward, never the other way.

In practice
feature/
  api/v1/     # router, handlers, DTOs
  domain/     # pure models, services 
  infra/      # repos, workers, queues

Adding api/v2/ touches exactly one folder. domain/ and infra/ don't move. Versioning enforced by structure, not convention.

03 / State + Outbox

State changes and intent should agree.

When a request changes state and also needs background work done, those two facts should never quietly disagree. The database records both in one atomic transaction: the state change, and the intent to perform the work. The worker executes that intent independently of the original request.

DB WRITE ✓QUEUE PUBLISH ✕

State says "send it." Nothing will.

QUEUE PUBLISH ✓DB WRITE ✕

Work exists for a state that never committed.

The outbox closes that gap.

04 / Durable Execution

Background work should behave like work, not a promise.

Anything slow, failure-prone, or externally dependent leaves the request path: payments, emails, AI processing, external integrations. The worker owns execution. The system records attempts. Failures retry in a controlled way, and side effects are safe to repeat.

This isn't exactly-once execution. Distributed systems don't get that claim for free. The goal is durable intent, controlled retries, and idempotent effects.

If it fails, it should also leave evidence: what was requested, what state it reached, how many attempts happened, where execution stopped, and why. That's logs, execution history, request context, and traces tied together, not a single dashboard promising visibility it can't deliver.

05 / Failure at the Edge

External systems are allowed to fail.

A provider isn't part of your reliability boundary. It's a failure boundary.

When this failsUser seesWorker does
Payment provider downPayment not confirmedRetries with a scoped idempotency key; nothing marked paid without confirmation
Email provider downNothing, not in their pathQueued and retried, execution recorded
06 / Invariants

A few rules that don't move

01Committed intent must not disappear.
02A side effect must be safe to retry.
03Important execution must leave a record.
04Domain code must not depend directly on infrastructure.

Each invariant isolates a specific system failure mode, from atomic local persistence up to the external provider boundary, preventing partial completion and data inconsistency.

07 / In Practice

Same principles, different problems.

DreamStack

The infrastructure is the product. The problem is making execution durable, observable, and replaceable.

View DreamStack →

SiteStamp

The input is messy, physical-world evidence. The problem is turning it into structured, traceable output.

View SiteStamp →

Build for the second failure.

Shipping fast only matters if the system survives production.

The happy path is easy. I design for what happens when a provider times out, the network drops, or a process dies halfway through a job.