Skip to content

PithomLabs/zeroapp

Repository files navigation

ZeroApp Prototype: Order Fulfillment System

A structured UI prototype for CRUD applications with complex business processes, demonstrating a cohesive e-commerce order fulfillment workflow using modern technologies.

ZeroApp UI

Tech Stack

  • 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

Project Structure

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

Current Status

✅ Completed

  • 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.RunWithRetry
    • CancelShipment() compensation handler
  • UserSession (Restate Virtual Object)
    • AddItem() - add product to cart
    • GetBasket() - view cart items
    • Checkout() - initiate checkout with payment Awakeable + state-based idempotency (Pattern C)
  • OrderFulfillmentWorkflow (Restate Workflow)
    • Run() - main saga orchestration with defer compensations
    • OnApprove() - resolve admin approval promise
  • Main server with Chi router
  • Auth middleware (X-User-ID header extraction)

🚧 In Progress

  • 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

⏳ Planned

  • Admin UI (separate portal)
  • Notification system with SQLite persistence
  • Order history tracking
  • Complete testing scenarios

Quick Start (When Complete)

Prerequisites

  • Go 1.23+
  • Docker (for Restate runtime)

1. Start Restate Server

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:latest

2. Register Services with Restate

For this repo, run the convenience script

./register-services.sh
http://localhost:9070/

3. Build and Run Backend

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 .
./server

The 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

4. Access the Application

Business Process Flow

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

API Endpoints (Planned)

Product Catalog (SQLite)

  • GET /api/products - List all products
  • GET /api/products/{id} - Get product details

Cart Management (Restate - UserSession)

  • POST /api/cart/add - Add item to cart
    • Header: X-User-ID: alice
    • Body: {"product_id": 1, "quantity": 2}
  • GET /api/cart - View cart
    • Header: X-User-ID: alice

Checkout (Restate - UserSession + Workflow)

  • POST /api/checkout - Initiate checkout
    • Header: X-User-ID: alice
    • Body: {"order_id": "order-123", "shipping_address": "..."}
    • Response: Payment awaitable created, returns awaitable ID

Payment Gateway (Awakeable Resolution)

  • POST /api/payment/callback - External payment gateway webhook
    • Body: {"awakeable_id": "...", "transaction_id": "txn-456", "amount": 10000, "status": "success"}
    • Resumes suspended checkout

Workflow Management (Restate - OrderFulfillmentWorkflow)

  • POST /api/workflow/{orderID}/approve - Admin approves order
    • Body: {"approved": true}
  • GET /api/workflow/{orderID}/status - Get workflow state

SSE Streaming

  • GET /stream/notifications - Real-time notification stream
  • GET /stream/workflow/{orderID} - Workflow progress updates

Testing Scenarios (Planned)

1. Happy Path

# 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

2. Payment Failure

# 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

3. Admin Rejection (Compensation)

# Admin rejects order
curl -X POST http://localhost:8082/api/workflow/order-123/approve \
  -d '{"approved": false}'

# Result: Workflow triggers compensations, inventory released

4. Shipping Failure (Compensation)

# 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

Key Patterns Demonstrated

1. Awakeables (Payment Flow)

  • UserSession.Checkout creates Awakeable
  • Payment gateway receives awakeable ID
  • External callback resolves Awakeable
  • Checkout resumes automatically

2. Sagas with Compensations (Order Workflow)

  • Defer-based compensation stack (LIFO)
  • Guarded compensations (only if step succeeded)
  • TerminalError triggers rollback

3. Durable Promises (Admin Approval)

  • Workflow suspends waiting for promise
  • Shared handler resolves promise
  • Workflow resumes automatically

4. State-Based Idempotency (Pattern C)

  • Explicit deduplication keys in Restate state
  • Early return if already executed
  • Prevents duplicate payments/workflows

References

License

Prototype/Educational Project