writeonce/docs/examples/web-app/README.md
shoney.arickathil 20322d4905 feat(examples): framework skeleton + web-app scaffold (iter 16 Task 1)
- docs/examples/writeonce-framework: library project (no fn main) — wo.toml,
  README (what it is + the honest v1 limits + the proxy TLS/h2 story), and
  http/types.wo: pub Req/Resp records + the response builders (ok_text/
  ok_json/created/not_found/bad_request/unauthorized/conflict/server_error/
  redirect). Typechecks + emits entry-less via woc --emit (1767-byte image).
- docs/examples/web-app: manifest with the real [deps] entry (future GitHub
  URL as documentation; the gate substitutes a file:// remote) + README
  (routes table, run instructions, nginx h2-in-front sketch). Code lands
  with Task 4.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:43:19 +02:00

1.4 KiB

web-app — the storefront sample

A small store: Product/Order as @table classes, JSON routes, one auth middleware — built on writeonce-framework, which it imports through [deps] (iteration 15). This app is iteration 16's acceptance workload: just web-app runs the whole chain — fetch → lock → build → serve → curl matrix → restart persistence → SIGTERM.

Routes

Route What
GET /products list (JSON array)
GET /products/:id one product or 404
POST /products create from a JSON body (name, price, stock); 400 on malformed JSON; 409 on a duplicate name (@unique)
POST /orders create (product, qty); FK checked
DELETE /products/:id 409 while orders reference it (FK restrict), 200 after

Every request needs authorization: Bearer <token> (the auth middleware); the token comes from the WA_TOKEN env var.

Run

woc .                       # fetches deps, builds target/web-app
WA_TOKEN=secret WO_DATA=./data ./target/web-app 8080

TLS / HTTP2

None here, deliberately: deploy behind nginx/caddy — the proxy terminates TLS+ALPN and speaks h2 to browsers while this backend serves HTTP/1.1 keep-alive. Sketch:

server {
  listen 443 ssl;
  http2 on;
  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
  }
}