5 Commits (14cc87974310710380addf0c239c22a11f3c1252)

Author SHA1 Message Date
Elijah Voigt c9142edbbf feat(quotesdb): DB layer — add submissions_locked + update_admin_auth_code
Add three new QuoteRepository trait methods and a seed helper:
- update_admin_auth_code(current, new_code): replaces the admin code if
  `current` matches; generates a fresh passphrase when new_code is None;
  returns DbError::Forbidden on mismatch.
- get_submissions_locked(): reads the submissions_locked key from
  admin_config; returns false when the key is absent.
- set_submissions_locked(locked): upserts "1"/"0" into admin_config.
- seed_submissions_locked(): INSERT OR IGNORE "0" — safe to call on every
  startup without clobbering an active lock.

Implemented in both NativeRepository (rusqlite) and D1Repository (wasm32).
Updated startup seeding in main.rs (native and wasm32 paths) to call
seed_submissions_locked after the existing admin auth code seeding.

Added 7 unit tests in db/native.rs covering all four specified scenarios:
default false, set-then-get, seed does not overwrite, correct code succeeds,
None new_code generates passphrase, wrong code returns Forbidden, stored
code unchanged after Forbidden.

MockRepo in handlers/mod.rs updated with stub implementations of all four
new trait methods to satisfy the trait bound.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3 months ago
Elijah Voigt 267a95aa13 feat(quotesdb): admin super auth code for quote moderation
Add an admin_config table storing a single admin auth code that
bypasses per-quote auth checks for update and delete operations.
The code is auto-generated on first startup and printed to stderr.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3 months ago
Elijah Voigt bdf99b32c4 feat(quotesdb): add workers-rs WASM entry point to api binary
- Gate native Tokio/Axum main() with #[cfg(not(target_arch = "wasm32"))]
- Add #![cfg_attr(target_arch = "wasm32", no_main)] to suppress missing-main error
- Add #[worker::event(fetch)] entry point using worker::HttpRequest / http::Response<axum::body::Body>
- Enable `http` feature on worker dep so fetch handler uses standard http types
- Add axum (json+query features), tower-service, and http to wasm32 deps
- Move async-trait to shared [dependencies] so both targets have it
- Make db::d1 module pub so main.rs can access D1Repository on wasm32
- Fix worker::d1::Database → D1Database and PreparedStatement → D1PreparedStatement
- Add #[cfg_attr(target_arch = "wasm32", worker::send)] to all 7 handler fns
  so their futures satisfy Axum's Handler<Send> bound on single-threaded wasm32
3 months ago
Elijah Voigt bc48924d16 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
Elijah Voigt 91ecd91176 refactor(quotesdb): collapse to single crate with api and ui binaries
Replaces the three separate sub-crates (api/, ui/, tests/) with a single
Cargo crate at the quotesdb/ root. Shared code lives in src/lib.rs; the
api and ui are multi-binary targets; integration tests use the standard
Cargo tests/ layout. Trunk files moved to project root with data-bin="ui".

Closes ticket b38032.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3 months ago