Event-sourced workflows in Go, wire-compatible with Fleuve (Python): same PostgreSQL schema, HTTP command shapes, optional NATS JetStream payloads, and admin UI bundle.
| Module | github.com/doomervibe/fleuve-go |
| Go | 1.25+ |
| Stores | PostgreSQL (events, offsets, activities, delays, …) |
| Streaming | NATS JetStream when enabled, else PostgreSQL polling |
- Durable workflows — append-only
stored_events, versioned perworkflow_id - Command gateway — REST API to create workflows and submit commands
- Runner — consumes the stream (JetStream or PG), runs activities, advances offsets safely
- Admin UI — vendored Vite
frontend_distembedded infleuve-ui(pkg/uiembed), same API the Python console uses - Activities — retries, checkpoints, persistence in
activities - Delays & cron —
delay_schedules(see Python parity for full semantics)
Important: Do not run Python and Go runners concurrently on the same stream scope. Use cutover, not mixed consumers. See docs/behavior-and-python-parity.md.
| Guide | Purpose |
|---|---|
| Getting started | Postgres, migrations, first run, counter example, gateway + UI |
| Architecture | Components, data flow, diagrams |
| Configuration | fleuve.toml, FLEUVE_*, OpenTelemetry, UI flags |
| HTTP API | Command gateway + admin JSON API |
| Packages | pkg/* layout and responsibilities |
| Bundled UI | Vendored admin frontend (pkg/uiembed) |
| Operations | Deploy order, migrations, observability |
| Python integration | Sharing a DB with Python Fleuve |
| Python parity | Ordering, offsets, recovery |
Full index: docs/README.md.
AI assistants: design and wiring conventions live in AGENTS.md and .cursor/skills/fleuve-go/.
1. Database — apply SQL in migrations/ in filename order (or use Compose below).
2. Environment
export FLEUVE_DATABASE_URL="postgresql://user:pass@localhost:5432/fleuve?sslmode=disable"
# Optional for JetStream mode:
export FLEUVE_NATS_URL="nats://localhost:4222"
export FLEUVE_ENABLE_JETSTREAM=true3. Binaries
go build -o fleuve-runner ./cmd/runner
go build -o fleuve-gateway ./cmd/gateway
go build -o fleuve-ui ./examples/ui_server4. Run (three terminals, same FLEUVE_DATABASE_URL)
./fleuve-runner # default -type CounterWorkflow
./fleuve-gateway -addr :8080
./fleuve-ui -addr :3000 # http://localhost:30005. Smoke test — create a counter workflow:
curl -sS -X POST http://localhost:8080/commands/CounterWorkflow \
-H "Content-Type: application/json" \
-d '{"workflow_id":"demo-1","command_type":"increment","payload":{"amount":1}}'Populate data without the gateway: examples/counter/README.md (go run ./examples/counter from repo root with FLEUVE_DATABASE_URL set).
docker compose up -d postgres nats fleuve-runner fleuve-gateway fleuve-uiServices and ports match docker-compose.yml. Optional profiles: tracing, monitoring.
Registered by fleuve-gateway and fleuve-runner via pkg/fleuvecmd. Gateway command types: increment (payload amount), reset.
Add more types in your module: implement model.Workflow, repo.NewPGXRepo, register on the gateway, and run the runner with a matching -type once wired in cmd/runner.
Static assets live under pkg/uiembed/dist/ and are embedded at compile time. To refresh from a sibling Python checkout (../les/fleuve/ui/frontend_dist) or set FLEUVE_UI_DIST to another path:
./scripts/vendor-fleuve-ui.sh
go build -o fleuve-ui ./examples/ui_serverThe read API and static app are libraries (pkg/uibackend, pkg/uiembed); examples/ui_server is a thin reference server. Integrators compose the handlers in their own main.
cmd/
gateway/ # REST command API
runner/ # Stream consumer + activities
migrations/ # PostgreSQL schema (apply in order)
pkg/ # Libraries (see docs/packages.md)
examples/ # counter/, ui_server/ (reference UI stack)
scripts/ # vendor-fleuve-ui.sh
MIT
