--- # quotesdb-04cw title: 'quotesdb/api: DB layer — add submissions_locked + update_admin_auth_code' status: completed type: feature priority: high created_at: 2026-03-10T23:32:07Z updated_at: 2026-03-10T23:32:07Z --- ## Goal Extend the DB abstraction layer with three new trait methods and seed on startup. ## New trait methods (add to `src/bin/api/db/mod.rs`) ```rust /// Replace the admin auth code if `current` matches. /// If `new_code` is None, generates a fresh 4-word passphrase. /// Returns the new auth code on success. /// Returns Err(DbError::Forbidden) if `current` does not match. async fn update_admin_auth_code( &self, current: &str, new_code: Option<&str>, ) -> Result; /// Return whether submissions are currently locked. async fn get_submissions_locked(&self) -> Result; /// Persist the submissions lock state. async fn set_submissions_locked(&self, locked: bool) -> Result<(), DbError>; ``` ## Implementations Implement in both: - `src/bin/api/db/native.rs` (NativeRepository — rusqlite) - `src/bin/api/db/d1.rs` (D1Repository — Cloudflare Workers WASM) ## Seeding (startup) In `src/bin/api/main.rs` (both native and wasm32 paths), after seeding `admin_auth_code`, also seed `submissions_locked = '0'` using `INSERT OR IGNORE` (use `set_submissions_locked` only when the key is absent, or add a dedicated `seed_submissions_locked` helper). ## Testing Add unit/integration tests in `src/bin/api/handlers/mod.rs` test module or `tests/` covering: - get_submissions_locked returns false by default - set_submissions_locked(true) then get_submissions_locked returns true - update_admin_auth_code with correct current succeeds - update_admin_auth_code with wrong current returns Forbidden ## Validation Run from `quotesdb/`: ``` cargo fmt && cargo check && cargo clippy && cargo test ``` ## Commit scope `feat(quotesdb): ...` ## Design reference `docs/plans/2026-03-04-admin-features-design.md`