Architecture
Overview
Health Observability follows a serverless monolith pattern: one Cloudflare Worker handles both static asset delivery and the REST API. The frontend is a fully static SPA served from the same Worker origin, eliminating CORS friction for same-origin API calls (while CORS headers are still emitted for flexibility).
Component Map
Request Lifecycle
Routing Strategy
The Worker uses a simple linear router — no framework. Routes are matched by method + exact pathname (or startsWith for parameterised deletes):
POST /api/blood-pressure → handleBpPost
GET /api/blood-pressure → handleBpGet
DELETE /api/blood-pressure/:id → handleBpDelete
POST /api/weight → handleWeightPost
GET /api/weight → handleWeightGet
DELETE /api/weight/:id → handleWeightDelete
GET /api/profile → handleProfileGet
PUT /api/profile → handleProfilePut
OPTIONS * → CORS preflight
* * → ASSETS fallback → 404
run_worker_first = true in wrangler.toml ensures API routes are evaluated before Cloudflare’s asset router.
Worker-First Asset Serving
Error Handling
All routes are wrapped in a top-level try/catch. Unhandled exceptions return a generic 500 JSON error. Route-level handlers return structured 400 errors for validation failures, with human-readable messages.
CORS Policy
All responses include:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE, PUT, OPTIONS
Access-Control-Allow-Headers: Content-Type
OPTIONS preflights short-circuit before any route matching.
Database Access Pattern
The Worker uses Cloudflare D1’s batch API (env.DB.batch([...stmts])) for write operations that span multiple tables. This provides atomicity within a single Worker invocation. Reads use individual prepared statements with parameterised bindings to prevent SQL injection.
Security Posture
| Concern | Mitigation |
|---|---|
| SQL Injection | D1 parameterised prepared statements throughout |
| Input validation | Server-side range checks on all numeric fields; array/type checks on tags |
| XSS | No server-side HTML rendering; JSON-only API |
| Auth | No authentication layer (personal/single-user tool) |
| CORS | Wildcard * — acceptable for a personal tool; tighten if needed |