todo-ddd-example

module
v0.0.0-...-ec9b500 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 25, 2026 License: Apache-2.0

README

todo-ddd-example

Go Report Card tests

Stack

  • Architecture: Follows/Inspired by Clean Architecture with DDD and basic CQRS. Caching, tracing and auditing via decorators with gowrap.
  • Database: PostgreSQL with pgroll for zero-downtime schema migrations. sqlc for type-safe queries.
  • API: Contract-first via OpenAPI 3.0 with oapi-codegen.
    • Automatic request/response validation.
    • Spec-defined rate limiting.
    • Idempotency keys to let clients safely handle non-idempotent request retries.
  • Observability: OpenTelemetry with Jaeger and Prometheus.
  • Messaging: RabbitMQ for events and Redis PubSub for cross-node WebSocket synchronization. Transactional outbox pattern with at-least-once delivery.
  • Tooling: Custom generated CLI client from the OpenAPI spec with completion if using direnv.
  • Infra: Docker swarm for multinode deployment with Caddy.
  • CI: See .github/workflows/tests.yaml.

Setup

make deploy

Test

make test

Web UIs

Example API usage

Full flow with MFA via generated todo-cli client:

scripts/example-flow.sh # with local swarm
# or
API_URL="http://localhost:8099" scripts/example-flow.sh # with make dev

Websockets and message queues

First register, login and create a workspace:

./todo-cli register -p '{"email": "user@example.com", "name": "User", "password": "Password123!"}'
export API_TOKEN=$(./todo-cli login -p '{"email": "user@example.com", "password": "Password123!"}' | jq -r .accessToken)

export WS_ID=$(./todo-cli onboard-workspace -p '{"name": "My Workspace"}' | jq -r .id)

Websockets:

$ make ws-listen
>>> Connected (press CTRL+C to quit)
# < {"event":"todo.created","id":"ae1e2ddc-5880-4f9a-8c3f-1d1fae16fbd8","status":"PENDING","title":"New todo 1770748039"}
# < {"event":"todo.updated","id":"ae1e2ddc-5880-4f9a-8c3f-1d1fae16fbd8","status":"COMPLETED","title":"New todo 1770748039"}
$ ./todo-cli create-todo $WS_ID -p '{"title": "New todo"}'
{"id":"ae1e2ddc-5880-4f9a-8c3f-1d1fae16fbd8"}
...
$ ./todo-cli complete-todo ae1e2ddc-5880-4f9a-8c3f-1d1fae16fbd8
...
$ ./todo-cli get-workspace-todos $WS_ID
>>> [{"id":"ae1e2ddc-5880-4f9a-8c3f-1d1fae16fbd8",...}]

Rabbitmq messages:

$ make rabbitmq-watch
>>> Tailing live events on 'todo_events'...
...

$ ./todo-cli complete-todo $(./todo-cli create-todo $WS_ID -p '{"title": "New todo"}' | jq -r .id)
# ...will show "todo.created" and "todo.completed" messages in watcher

Directories

Path Synopsis
cmd
api command
cli command
Code generated by project.
Code generated by project.
cli/gen command
generated/api
Package internal provides primitives to interact with the openapi HTTP API.
Package internal provides primitives to interact with the openapi HTTP API.
generated/client
Package client provides primitives to interact with the openapi HTTP API.
Package client provides primitives to interact with the openapi HTTP API.
shared/causation
Package causation provides context-based propagation of identity, auditing, and traceability metadata to track the origin and sequence of operations.
Package causation provides context-based propagation of identity, auditing, and traceability metadata to track the origin and sequence of operations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL