A structured UI prototype for CRUD applications with complex business processes, demonstrating a cohesive e-commerce order fulfillment workflow using modern technologies.
- Frontend: HTML/CSS/JavaScript + datastar.dev (SSE-based hypermedia)
- Backend: Chi router + Restate Go SDK + pithomlabs/rea framework
- Database: SQLite (modernc.org/sqlite - pure Go)
- Patterns: Virtual Objects, Sagas, Awakeables, Durable Promises
prototype/
βββ backend/
β βββ main.go # Server entry point
β βββ go.mod # Dependencies
β βββ db/
β β βββ sqlite.go # SQLite initialization
β β βββ migrations/
β β βββ 001_init.sql # Schema
β β βββ 002_seed.sql # Sample data
β βββ models/
β β βββ models.go # Data models (SQLite + Restate)
β βββ services/
β β βββ shipping_service.go # Stateless service with rea.RunWithRetry
β β βββ user_session.go # Virtual object (cart + checkout)
β β βββ order_workflow.go # Saga workflow with compensations
β βββ handlers/
β βββ auth.go # Auth middleware
β βββ ingress.go # Restate ingress handlers (IN PROGRESS)
β βββ products.go # SQLite product queries (TODO)
β βββ static.go # Frontend file serving (TODO)
βββ frontend/ # (TODO)
β βββ index.html
β βββ admin.html
β βββ css/
β βββ js/
βββ data/ # SQLite database location
β βββ app.db # Created on first run
βββ PROPOSAL.md # Original proposal
βββ PROPOSAL2.md # Updated proposal with SQLite
βββ README.md # This file
- SQLite schema (products, users, shipping_zones, notifications, order_history)
- Database initialization with modernc.org/sqlite
- Data models for all entities
- ShippingService (Restate Service)
InitiateShipment()with rea.RunWithRetryCancelShipment()compensation handler
- UserSession (Restate Virtual Object)
AddItem()- add product to cartGetBasket()- view cart itemsCheckout()- initiate checkout with payment Awakeable + state-based idempotency (Pattern C)
- OrderFulfillmentWorkflow (Restate Workflow)
Run()- main saga orchestration with defer compensationsOnApprove()- resolve admin approval promise
- Main server with Chi router
- Auth middleware (X-User-ID header extraction)
- Ingress handlers (cart, checkout, payment callback, workflow approval)
- [ ] Product catalog handlers (SQLite queries)
- SSE streaming endpoints
- Static file serving
- Frontend HTML/CSS/JS with datastar.dev
- Admin UI (separate portal)
- Notification system with SQLite persistence
- Order history tracking
- Complete testing scenarios
- Go 1.23+
- Docker (for Restate runtime)
For a quick taste of Restate server, download it to your local device here
For testing/QA, I recommend using Docker which you can download here. Save the trouble of installing Docker by downloading the deb binaries based on your Linux distro.
docker run --name restate_dev --rm \
-p 8082:8082 -p 9070:9070 -p 9071:9071 \
--add-host=host.docker.internal:host-gateway \
docker.io/restatedev/restate:latestFor this repo, run the convenience script
./register-services.shhttp://localhost:9070/I recommend using LiteIDE for easy one-click compile of golang programs. Download v38.3 here
cd backend
go mod tidy
go build -o server .
./serverThe backend will:
- Initialize SQLite database at
./data/app.db - Run migrations and seed sample data
- Start Restate SDK server on
:9080 - Start HTTP server on
:8082
- Frontend: http://localhost:8082
- Admin UI: http://localhost:8082/admin
- Health Check: http://localhost:8082/health
1. Browse Products (SQLite query)
β
2. Add to Cart (UserSession.AddItem - Restate state)
β
3. Checkout (UserSession.Checkout)
ββ Create Payment Awakeable
ββ [SUSPEND] Wait for payment...
ββ [RESUME] on payment callback
β
4. Launch Workflow (OrderFulfillmentWorkflow.Run)
ββ [SUSPEND] Wait for admin approval (Durable Promise)
ββ [RESUME] on admin approval
ββ Call ShippingService.InitiateShipment (Durable RPC with retry)
ββ Durable Sleep (5 seconds for delivery)
ββ Complete
On Failure:
ββ Trigger Compensations (LIFO order)
ββ CancelShipment (if shipping succeeded)
ββ Release Inventory
GET /api/products- List all productsGET /api/products/{id}- Get product details
POST /api/cart/add- Add item to cart- Header:
X-User-ID: alice - Body:
{"product_id": 1, "quantity": 2}
- Header:
GET /api/cart- View cart- Header:
X-User-ID: alice
- Header:
POST /api/checkout- Initiate checkout- Header:
X-User-ID: alice - Body:
{"order_id": "order-123", "shipping_address": "..."} - Response: Payment awaitable created, returns awaitable ID
- Header:
POST /api/payment/callback- External payment gateway webhook- Body:
{"awakeable_id": "...", "transaction_id": "txn-456", "amount": 10000, "status": "success"} - Resumes suspended checkout
- Body:
POST /api/workflow/{orderID}/approve- Admin approves order- Body:
{"approved": true}
- Body:
GET /api/workflow/{orderID}/status- Get workflow state
GET /stream/notifications- Real-time notification streamGET /stream/workflow/{orderID}- Workflow progress updates
# Add item to cart
curl -X POST http://localhost:8082/api/cart/add \
-H "X-User-ID: alice" \
-H "Content-Type: application/json" \
-d '{"product_id": 1, "quantity": 2}'
# Checkout (creates payment awakeable)
curl -X POST http://localhost:8082/api/checkout \
-H "X-User-ID: alice" \
-H "Content-Type: application/json" \
-d '{"order_id": "order-123", "shipping_address": "123 Main St"}'
# Simulate payment success (resolve awakeable)
curl -X POST http://localhost:8082/api/payment/callback \
-H "Content-Type: application/json" \
-d '{"awakeable_id": "<ID_FROM_LOGS>", "transaction_id": "txn-456", "amount": 10000, "status": "success"}'
# Admin approves workflow
curl -X POST http://localhost:8082/api/workflow/order-123/approve \
-H "Content-Type: application/json" \
-d '{"approved": true}'
# Result: Order completes after 5-second delivery timer# Simulate payment rejection
curl -X POST http://localhost:8082/api/payment/callback \
-d '{"awakeable_id": "<ID>", "status": "failed"}'
# Result: Checkout fails, workflow NOT launched, cart preserved# Admin rejects order
curl -X POST http://localhost:8082/api/workflow/order-123/approve \
-d '{"approved": false}'
# Result: Workflow triggers compensations, inventory released# Use special order ID that triggers shipping failure
curl -X POST http://localhost:8082/api/checkout \
-H "X-User-ID: alice" \
-d '{"order_id": "FAIL_SHIP", ...}'
# Result: ShippingService fails, compensations triggered- UserSession.Checkout creates Awakeable
- Payment gateway receives awakeable ID
- External callback resolves Awakeable
- Checkout resumes automatically
- Defer-based compensation stack (LIFO)
- Guarded compensations (only if step succeeded)
- TerminalError triggers rollback
- Workflow suspends waiting for promise
- Shared handler resolves promise
- Workflow resumes automatically
- Explicit deduplication keys in Restate state
- Early return if already executed
- Prevents duplicate payments/workflows
- PROPOSAL2.md - Detailed architecture proposal
- rea-06-sonnet45 - Reference implementation
- Restate Documentation
- rea Framework
- datastar.dev
Prototype/Educational Project
