StateSet Worker
Run the StateSet iCommerce engine in a Cloudflare Sandbox —wrangler deploy and you have a full commerce engine with messaging channels, MCP tools, and an admin UI.
Architecture
Requirements
- Workers Paid plan ($5 USD/month) — required for Cloudflare Sandbox containers
- Anthropic API key — or use AI Gateway for routing and analytics
- Cloudflare Access (authentication)
- AI Gateway (optional, for API routing/analytics)
- R2 Storage (optional, for persistence)
Quick Start
https://stateset-sandbox.your-subdomain.workers.dev/.
The first request takes 1-2 minutes while the container boots. A loading page is shown during startup.
To use the admin UI and protected routes, you’ll need to:
- Set up Cloudflare Access for authentication
- Enable R2 storage so commerce data persists (recommended)
Setting Up Cloudflare Access
The admin UI at/_admin/ and all /api/admin/* routes require Cloudflare Access authentication.
1. Enable Access on workers.dev
- Go to the Workers & Pages dashboard
- Select your Worker (
stateset-sandbox) - In Settings > Domains & Routes, click the
...menu on the workers.dev row - Click Enable Cloudflare Access
- Configure who can access (email allow list, Google, GitHub, etc.)
- Copy the Application Audience (AUD) tag
2. Set Access Secrets
3. Redeploy
/_admin/ requires Cloudflare Access authentication.
Persistent Storage (R2)
By default, commerce data (SQLite database, config) is lost when the container restarts. R2 storage enables persistence.Setup
- Go to R2 > Overview in the Cloudflare Dashboard
- Click Manage R2 API Tokens
- Create a token with Object Read & Write permissions for the
stateset-databucket
How It Works
SQLite backup — The commerce database is backed up safely using SQLite’s built-in.backup API, which handles concurrent writes correctly. A cron job runs every 5 minutes.
Config sync — Gateway configuration is synced to R2 via rsync.
Restore on boot — On container startup, data is restored from R2 if the backup is newer than local data. An integrity check verifies the database before restoring.
Manual backup — Trigger an immediate backup from the admin UI Storage tab or via POST /api/admin/storage/sync.
Admin UI
Access the admin UI at/_admin/ with three tabs:
- Overview — Gateway status, commerce stats (customers, orders, returns, products), channel summary, restart controls
- Channels — Per-channel status cards for all 6 messaging channels (Telegram, Discord, Slack, WhatsApp, Email, SMS)
- Storage — R2 configuration status, last backup time, manual backup button, backup strategy info
Messaging Channels
Configure channels via environment secrets. Each channel is enabled automatically when its token is set.Telegram
Discord
Slack
SMS (Twilio)
Commerce Settings
AI Gateway (Optional)
Route API requests through Cloudflare AI Gateway for caching, rate limiting, and analytics:ANTHROPIC_API_KEY if both are set.
Container Lifecycle
By default, the container stays alive indefinitely. To sleep after inactivity (reduces cost, adds cold start latency):Debug Endpoints
Enable withDEBUG_ROUTES=true (requires Cloudflare Access):
| Endpoint | Description |
|---|---|
GET /debug/version | Container and stateset version info |
GET /debug/processes | All container processes (add ?logs=true for output) |
GET /debug/cli?cmd=... | Run a CLI command in the container |
GET /debug/logs?id=... | Logs for a specific process |
GET /debug/env | Sanitized environment configuration |
GET /debug/container-config | Gateway config from inside the container |
Local Development
DEV_MODE=true in .dev.vars to skip Cloudflare Access auth.
All Secrets Reference
| Secret | Required | Description |
|---|---|---|
ANTHROPIC_API_KEY | Yes* | Anthropic API key (or use AI Gateway) |
AI_GATEWAY_API_KEY | Yes* | AI Gateway provider key (requires AI_GATEWAY_BASE_URL) |
AI_GATEWAY_BASE_URL | No | AI Gateway endpoint URL |
OPENAI_API_KEY | No | OpenAI API key (alternative provider) |
CF_ACCESS_TEAM_DOMAIN | Yes | Cloudflare Access team domain |
CF_ACCESS_AUD | Yes | Cloudflare Access application audience |
STATESET_GATEWAY_TOKEN | No | Gateway auth token |
R2_ACCESS_KEY_ID | No | R2 access key for persistent storage |
R2_SECRET_ACCESS_KEY | No | R2 secret key for persistent storage |
CF_ACCOUNT_ID | No | Cloudflare account ID (required for R2) |
TELEGRAM_BOT_TOKEN | No | Telegram channel |
DISCORD_BOT_TOKEN | No | Discord channel |
SLACK_BOT_TOKEN | No | Slack channel |
SLACK_APP_TOKEN | No | Slack channel (required with SLACK_BOT_TOKEN) |
WHATSAPP_TOKEN | No | WhatsApp channel |
EMAIL_SMTP_HOST | No | Email channel |
TWILIO_ACCOUNT_SID | No | SMS channel (Twilio) |
ALLOW_APPLY | No | Set to true to enable apply mode |
DEFAULT_MODEL | No | Override default AI model |
DEV_MODE | No | Set to true for local dev (skips auth) |
DEBUG_ROUTES | No | Set to true to enable /debug/* routes |
SANDBOX_SLEEP_AFTER | No | Container sleep timeout: never (default), 10m, 1h |
ANTHROPIC_API_KEY or AI_GATEWAY_API_KEY is required.
Troubleshooting
Container fails to start: Checknpx wrangler tail for logs. Verify ANTHROPIC_API_KEY is set.
R2 not mounting: Ensure all three secrets are set (R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, CF_ACCOUNT_ID). R2 mounting only works in production.
Access denied on admin routes: Verify CF_ACCESS_TEAM_DOMAIN and CF_ACCESS_AUD are set correctly.
Slow first request: Cold starts take 1-2 minutes. A loading page is shown automatically.
Config changes not working: Update the Dockerfile cache bust comment and redeploy.