You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Elijah Voigt a5b7c8d856 feat(quotesdb): implement API DB layer and all HTTP handlers
DB layer (src/bin/api/db/):
- native.rs: NativeRepository (tokio-rusqlite) implementing all CRUD ops,
  dynamic WHERE for filters, two-phase auth check for update, 13 unit tests
- d1.rs: D1Repository wasm32 stub (all methods return Internal error)
- connection.rs: open() helper — WAL + foreign_keys pragmas
- mod.rs: cfg-gate async_trait (Send on native, ?Send on wasm32)

Handlers (src/bin/api/handlers/mod.rs):
- All 7 routes: GET /api/, random, {id}, list, PUT create, POST update, DELETE
- Router order: random BEFORE {id} (prevents "random" matching as id)
- Auth: X-Auth-Code header validation → 403 on mismatch
- 13 handler unit tests with MockRepo

main.rs: opens DB, runs migrations, wraps in Arc<dyn Repo + Send + Sync>,
  binds on $PORT (default 3000)

Cargo.toml: tower dev-dep for ServiceExt::oneshot in tests

All 32 tests pass (26 api + 6 lib)

Tickets closed: 00aff0 a5049d 6e829e 28e7d9 886bfd 2ce22e 5dbb7d 05f8ae
                d792e2 5d9f5a b20b5a 175382 03bb91

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3 months ago
..
.gitignore feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago
README.md feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago
d1.tf feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago
dns.tf feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago
main.tf feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago
pages.tf feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago
providers.tf feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago
schema.sql feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago
variables.tf feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago
worker.tf feat(quotesdb): implement API DB layer and all HTTP handlers 3 months ago

README.md

quotesdb Infrastructure

OpenTofu configuration for deploying quotesdb to Cloudflare.

Resources provisioned

Resource Description
cloudflare_d1_database.quotesdb D1 SQLite database backing the API
cloudflare_workers_script.api Compiled Wasm Worker serving /api/*
cloudflare_worker_route.api Routes quotes.elijah.run/api/* to the Worker
cloudflare_pages_project.ui Pages project hosting the Yew SPA
cloudflare_record.ui CNAME quotes.elijah.run → Pages
cloudflare_pages_domain.ui Custom domain binding on Pages

Required credentials

Variable Description
TF_VAR_cloudflare_api_token Cloudflare API token (Workers, D1, Pages, DNS edit)
TF_VAR_cloudflare_account_id Cloudflare account ID
TF_VAR_cloudflare_zone_id Zone ID for elijah.run

Export these before running tofu:

export TF_VAR_cloudflare_api_token="..."
export TF_VAR_cloudflare_account_id="..."
export TF_VAR_cloudflare_zone_id="..."

First-time setup (chicken-and-egg)

D1 must exist before the Worker can bind to it. On the very first deploy:

cd infra/
tofu init
tofu apply -target=cloudflare_d1_database.quotesdb
wrangler d1 execute quotesdb --file schema.sql --remote
tofu apply

Subsequent deploys: CI/CD handles everything automatically.

Local apply

cd quotesdb/infra/
tofu init
tofu plan
tofu apply

State

State is stored locally in terraform.tfstate (gitignored). For a team setup, migrate to a remote backend (S3-compatible bucket, Terraform Cloud, etc.).

Files

File Purpose
main.tf Terraform block and provider version constraints
providers.tf Cloudflare provider configuration
variables.tf Input variable declarations
d1.tf Cloudflare D1 database resource
worker.tf Cloudflare Workers script + route
pages.tf Cloudflare Pages project
dns.tf DNS record and custom domain binding
schema.sql Idempotent D1 schema (applied via wrangler, not tofu)
.gitignore Ignores state, lock, and credential files