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.
vibed/quotesdb/.beans/quotesdb-6lh5--implement-ge...

126 lines
4.0 KiB
Markdown

---
# quotesdb-6lh5
title: Implement generate_id() in src/lib.rs — UUID v4 for WASM-compatible quote IDs
status: completed
type: task
priority: critical
created_at: 2026-03-10T23:32:08Z
updated_at: 2026-03-10T23:32:08Z
---
<context>
Resolved from TRIAGE ticket 6f2e18. The `nanoid` crate is not suitable for wasm32-unknown-unknown
because it depends on `rand`, which relies on thread-local RNG — unavailable in WASM. The safe,
WASM-compatible choice is UUID v4 via the `uuid` crate.
On the wasm32 target, `uuid`'s `v4` feature depends on `getrandom`, which requires the `wasm_js` feature
(renamed from `js` in getrandom 0.2; uuid 1.21+ requires getrandom ^0.4) to source entropy from the
Web Crypto API (`crypto.getRandomValues()`). This must be declared as a direct dependency in the
application's `Cargo.toml` at the wasm32 cfg section.
UUID v4 produces 36-character hyphenated strings (e.g. `550e8400-e29b-41d4-a716-446655440000`).
The design doc originally specified NanoID (~21 chars); UUID v4 is slightly longer but universally
supported and zero-risk on the Workers target. The DB schema comment should be updated accordingly.
</context>
<goal>
Add a `generate_id()` public function to `src/lib.rs` that:
- Returns a new UUID v4 as a `String`
- Compiles correctly for both the native host target AND `wasm32-unknown-unknown`
- Has a rustdoc comment with a doc-example (which also serves as a doctest)
</goal>
<implementation>
## 1. Cargo.toml changes
Add `uuid` to the shared (all-targets) dependencies section:
```toml
[dependencies]
uuid = { version = "1", features = ["v4", "serde"] }
```
Add `getrandom` with the `wasm_js` feature under the wasm32 cfg section (so native builds don't pull
in wasm-bindgen). **uuid 1.21+ requires getrandom ^0.4**; getrandom 0.4 renamed the `js` feature
to `wasm_js`. Also shared with the passphrase generator (ticket 03bb91 / TRIAGE 6ed325):
```toml
[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.4", features = ["wasm_js"] }
```
## 2. src/lib.rs — generate_id()
```rust
/// Generates a new UUID v4 string for use as a database primary key.
///
/// Returns a 36-character hyphenated UUID string. Compatible with both
/// native and `wasm32-unknown-unknown` targets (uses Web Crypto API via
/// `getrandom/wasm_js` on WASM).
///
/// # Examples
///
/// ```
/// let id = quotesdb::generate_id();
/// assert_eq!(id.len(), 36);
/// assert_eq!(id.chars().filter(|&c| c == '-').count(), 4);
/// ```
pub fn generate_id() -> String {
uuid::Uuid::new_v4().to_string()
}
```
## 3. Callers
- `PUT /api/quotes` handler (ticket 05f8ae): call `generate_id()` to produce the new quote's `id`
- No other callers at this stage
## 4. DB schema comment update
In `docs/plans/2026-02-27-quotesdb-design.md` and `CLAUDE.md` design reference, update the schema
comment from:
```sql
id TEXT PRIMARY KEY, -- NanoID (~21 chars)
```
to:
```sql
id TEXT PRIMARY KEY, -- UUID v4 (36 chars), generated by generate_id()
```
</implementation>
<constraints>
- `generate_id()` must be in `src/lib.rs` (shared code, not bin-specific)
- UUID v4 is the only correct choice — do NOT use `nanoid`, `rand::thread_rng`, or any
crate that pulls in thread-local RNG primitives for WASM
- `getrandom = { version = "0.4", features = ["wasm_js"] }` must be in the wasm32 cfg section only,
not in `[dependencies]`, to avoid pulling wasm-bindgen into native builds
- Do NOT use getrandom 0.2 or the old `js` feature name — uuid 1.21+ requires getrandom ^0.4
- All public items must have rustdoc comments (per project style)
</constraints>
<skills>
Use `superpowers:test-driven-development` — write a unit test verifying length (36) and hyphen
count (4) before implementing.
Use `superpowers:verification-before-completion` before closing.
</skills>
<validation>
Run in order from the `quotesdb/` directory:
```sh
cargo fmt
cargo check
cargo clippy
cargo test
```
</validation>
<commit>
`feat(quotesdb): add generate_id() using UUID v4 — WASM-compatible ID generation`
</commit>