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.

122 lines
3.4 KiB
Markdown

+++
title = "quotesdb/ui: admin API client functions"
priority = 5
status = "done"
ticket_type = "feature"
dependencies = []
+++
## Admin API client functions (UI)
Add four async functions to the UI API client module that cover every admin and status endpoint introduced by the API tickets. These functions are consumed by the /admin page and the /submit page.
---
## Files to modify
- `src/bin/ui/api.rs` — add four new public async functions
---
## New types
Add to `src/bin/ui/api.rs` (or to a shared types module imported by api.rs):
```rust
/// Response from GET /api/status.
#[derive(Deserialize, Clone, PartialEq)]
pub struct StatusResponse {
pub submissions_locked: bool,
}
/// Response from POST /api/admin/reset-auth-code.
#[derive(Deserialize)]
struct ResetAuthCodeResponse {
pub auth_code: String,
}
/// Response from POST /api/admin/lock or /api/admin/unlock.
#[derive(Deserialize)]
struct LockResponse {
pub submissions_locked: bool,
}
```
---
## New functions
```rust
/// Fetch the current submission lock state from GET /api/status.
/// Returns Ok(StatusResponse) on success or ApiError on failure.
pub async fn get_status() -> Result<StatusResponse, ApiError> { ... }
/// Call POST /api/admin/reset-auth-code.
/// Sends X-Admin-Code: admin_code in the request header.
/// Body: { "new_code": new_code } (omit field if new_code is None).
/// Returns the new auth code string on success, or ApiError on failure.
pub async fn admin_reset_auth_code(
current: &str,
new_code: Option<&str>,
admin_code: &str,
) -> Result<String, ApiError> { ... }
/// Call POST /api/admin/lock.
/// Sends X-Admin-Code: admin_code in the request header.
/// Returns Ok(true) on success, or ApiError (including ApiError::Forbidden on 403).
pub async fn admin_lock(admin_code: &str) -> Result<bool, ApiError> { ... }
/// Call POST /api/admin/unlock.
/// Sends X-Admin-Code: admin_code in the request header.
/// Returns Ok(false) on success, or ApiError (including ApiError::Forbidden on 403).
pub async fn admin_unlock(admin_code: &str) -> Result<bool, ApiError> { ... }
```
Implementation notes:
- Use the same `gloo_net::http::Request` pattern already used in `api.rs` for other endpoints.
- Add an `ApiError::Forbidden` variant (or reuse an existing error variant) to communicate `403` responses back to the UI so pages can show "Wrong auth code." without a generic error.
- `admin_reset_auth_code`: serialize the body as `{ "new_code": "..." }` when `new_code` is `Some`, or as `{}` when `None`.
- `admin_lock` and `admin_unlock` send no request body (empty POST).
---
## ApiError extension
If `ApiError` does not already have a `Forbidden` variant, add one:
```rust
pub enum ApiError {
// ... existing variants ...
/// The server returned 403 Forbidden (wrong admin code).
Forbidden,
}
```
Map HTTP 403 → `ApiError::Forbidden` in each new function before returning.
---
## Tests
This module compiles only for `wasm32-unknown-unknown` so no `cargo test` unit tests are practical here. Instead, verify the build compiles cleanly:
```sh
cargo check --target wasm32-unknown-unknown --bin ui
```
Write a brief doc-comment on each function describing its endpoint, required header, and error conditions.
---
## Validation
```sh
cargo fmt && cargo check --target wasm32-unknown-unknown --bin ui
```
---
## Commit
```
feat(quotesdb): admin API client functions in UI
```