Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,998 changes: 2,998 additions & 0 deletions cloudflare-workers/api-edge/package-lock.json

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions cloudflare-workers/api-edge/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "opensandbox-api-edge",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "wrangler dev",
"deploy": "wrangler deploy",
"test": "vitest"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20240924.0",
"typescript": "^5.5.0",
"vitest": "^2.0.0",
"wrangler": "^3.78.0"
}
}
48 changes: 48 additions & 0 deletions cloudflare-workers/api-edge/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// api-edge Worker — global API entry point.
//
// All routes are placeholders — implementation lands in subsequent commits.
// Until then this Worker rejects everything with 501 Not Implemented except
// /health (so wrangler deploy succeeds and connectivity can be verified).

export { CreditAccount } from "../../shared/credit_account";

export interface Env {
OPENCOMPUTER_DB: D1Database;
SESSIONS_KV: KVNamespace;
CREDIT_ACCOUNT: DurableObjectNamespace;
SESSION_JWT_SECRET: string;
CF_ADMIN_SECRET: string;
STRIPE_WEBHOOK_SECRET: string;
STRIPE_API_KEY: string;
WORKOS_API_KEY: string;
WORKOS_CLIENT_ID: string;
EVENT_SECRET: string;
WORKER_ENV: string;
CELLS: string;
}

export default {
async fetch(req: Request, env: Env): Promise<Response> {
const url = new URL(req.url);

if (url.pathname === "/health") {
return new Response(
JSON.stringify({ ok: true, env: env.WORKER_ENV, cells: env.CELLS.split(",") }),
{ headers: { "content-type": "application/json" } },
);
}

// TODO routes (in this order, see docs/dev-cutover-runbook.md):
// POST /auth/login
// POST /auth/refresh
// POST /auth/logout
// POST /webhooks/stripe
// POST /api/sandboxes — auth, /check on DO, cell select, cap-mint, proxy
// GET /api/sandboxes — D1 sandboxes_index
// GET /api/sandboxes/{id} — metadata + cell_endpoint
// ANY /api/sandboxes/{id}/* — 307 to {cell_id}.app.opensandbox.ai
// GET /internal/halt-list — HMAC, called by CP halt_reconciler

return new Response("not implemented", { status: 501 });
},
} satisfies ExportedHandler<Env>;
17 changes: 17 additions & 0 deletions cloudflare-workers/api-edge/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "Bundler",
"lib": ["ES2022"],
"types": ["@cloudflare/workers-types"],
"strict": true,
"noImplicitAny": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"noEmit": true
},
"include": ["src/**/*.ts", "../shared/**/*.ts"]
}
55 changes: 55 additions & 0 deletions cloudflare-workers/api-edge/wrangler.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# api-edge Worker — global API entry point at app.opencomputer.dev / app.dev.opensandbox.ai
#
# Routes:
# POST /auth/login, /auth/refresh, /auth/logout — WorkOS flow + session JWT
# POST /webhooks/stripe — Stripe webhook (DO /mark-pro)
# POST /api/sandboxes — create flow (auth + credit check + cell select + cap-token mint + proxy to CP)
# GET /api/sandboxes — cross-region list (D1 sandboxes_index)
# GET /api/sandboxes/{id} — metadata with cell_endpoint
# ANY /api/sandboxes/{id}/* — 307 redirect to {cell_id}.app.opensandbox.ai (dumb-client fallback)
# GET /internal/halt-list — HMAC-auth, called by CP halt_reconciler

name = "opensandbox-edge-dev"
main = "src/index.ts"
compatibility_date = "2026-04-28"
compatibility_flags = ["nodejs_compat"]
account_id = "1241f114453e32d292197e3fb36210b2"

# Route the Worker at app.dev.opensandbox.ai once the zone goes live.
# Until then, accessible at opensandbox-edge-dev.brian-124.workers.dev.
# routes = [
# { pattern = "app.dev.opensandbox.ai/*", zone_name = "opensandbox.ai" }
# ]

[[d1_databases]]
binding = "OPENCOMPUTER_DB"
database_name = "opencomputer-dev"
database_id = "f9e534bf-a9f3-4b30-81cd-f9eb9087e96d"

[[kv_namespaces]]
binding = "SESSIONS_KV"
id = "694f22abd551461da4ad99839f161b2f"

[[durable_objects.bindings]]
name = "CREDIT_ACCOUNT"
class_name = "CreditAccount"
script_name = "opensandbox-edge-dev"

[[migrations]]
tag = "v1"
new_sqlite_classes = ["CreditAccount"]

# Secrets (set via `wrangler secret put`):
# SESSION_JWT_SECRET — HMAC for session JWT (shared with all CPs in cell fleet)
# CF_ADMIN_SECRET — HMAC for /admin/halt-org and /admin/resume-org callbacks to CPs
# STRIPE_WEBHOOK_SECRET — verifies inbound Stripe webhook signatures
# STRIPE_API_KEY — for creating Stripe customer + subscription on /mark-pro
# WORKOS_API_KEY — server-side WorkOS API for /auth/login
# WORKOS_CLIENT_ID — WorkOS client identifier
# EVENT_SECRET — HMAC for /internal/halt-list endpoint (shared with CP halt_reconciler)

[vars]
WORKER_ENV = "dev"
# Cells available in this deployment. The edge Worker uses this to validate
# cell_id selections and to construct cell_endpoint URLs.
CELLS = "azure-westus2-cell-a"
Loading