8.3 KiB
+++ title = "quotesdb" priority = 8 status = "done" ticket_type = "project" dependencies = ["ce1e4f", "f3dc74", "c3503b", "25c413"] +++
REQUIRED: Use `superpowers:executing-plans` to implement this plan task-by-task. SUGGESTED: Use `superpowers:dispatching-parallel-agents` for parallel agent dispatch. SUGGESTED: Use `superpowers:subagent-driven-development` for agent dispatch within a session. SUGGESTED: Use `superpowers:verification-before-completion` before marking any phase complete. SUGGESTED: Use `superpowers:finishing-a-development-branch` when ready to merge. SUGGESTED: Use `superpowers:using-git-worktrees` for parallel work in isolated branches. SUGGESTED: Use `superpowers:test-driven-development` during development. Bootstrap the `quotesdb` service (Rust/Axum backend on Cloudflare Workers + Yew frontend on Cloudflare Pages), then orchestrate parallel agents to plan and implement the work.All four sub-project tickets (f3dc74 api, c3503b ui, ce1e4f qa, 25c413 infra) must be completed and closed before this ticket can close.
- Phase 0 (done): Design finalized — see
docs/plans/2026-02-27-quotesdb-design.md - Phase 1: Dispatch 4 parallel planning agents (each in a git worktree) to create nbd tickets per domain
- Phase 2: Dispatch 4 parallel implementation orchestrators per domain
Tech Stack: Rust, Axum, Tokio, workers-rs, SQLx, Turso (local) / Cloudflare D1 (prod), Yew, Trunk, OpenTofu, Cloudflare Workers + Pages
### Database SchemaCREATE TABLE quotes (
id TEXT PRIMARY KEY, -- NanoID (~21 chars)
text TEXT NOT NULL,
author TEXT NOT NULL,
source TEXT, -- optional: book, speech, etc.
date TEXT, -- optional: ISO date YYYY-MM-DD
auth_code TEXT NOT NULL, -- 4-word passphrase e.g. ocean-table-purple-storm
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE quote_tags (
quote_id TEXT NOT NULL REFERENCES quotes(id) ON DELETE CASCADE,
tag TEXT NOT NULL,
PRIMARY KEY (quote_id, tag)
);
API Endpoints
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /api/ |
OpenAPI spec (JSON) | None |
| GET | /api/quotes |
List quotes, 10/page. Query: ?page=N&author=X&tag=Y |
None |
| GET | /api/quotes/random |
Random quote | None |
| GET | /api/quotes/:id |
Get quote by NanoID | None |
| PUT | /api/quotes |
Create a quote | None (auth_code optional in body) |
| POST | /api/quotes/:id |
Update a quote | X-Auth-Code header |
| DELETE | /api/quotes/:id |
Delete a quote | X-Auth-Code header |
Note: GET /api/quotes/random must be registered BEFORE GET /api/quotes/:id in the router.
Request/Response Shapes
PUT /api/quotes — Create
// Request body (auth_code optional — generated if omitted)
{
"text": "...",
"author": "...",
"source": "Stanford Commencement 2005",
"tags": ["motivation"],
"date": "2005-06-12",
"auth_code": "ocean-table-purple-storm"
}
// Response 201
{
"quote": { "id": "V1StG...", "text": "...", "author": "...", ... },
"auth_code": "ocean-table-purple-storm"
}
GET /api/quotes — List
{
"quotes": [...],
"page": 1,
"total_pages": 4,
"total_count": 38
}
Error responses: { "error": "message" } with appropriate HTTP status.
Auth
- No user accounts. Each quote has an
auth_code(4-word passphrase). - Auth codes are stored plaintext.
- Provided via
X-Auth-Codeheader for update/delete. - On mismatch:
403 Forbidden. - Auth code is always returned in the create response.
Frontend Pages (Yew)
| Route | Page |
|---|---|
/ |
Home — random quote + "Browse all" link |
/browse |
Paginated list with author/tag filter controls |
/quotes/:id |
Single quote — view, edit (auth prompt), delete (auth prompt) |
/author/:name |
All quotes by an author |
/submit |
New quote form |
Required skill: Use
superpowers:dispatching-parallel-agentsbefore dispatching.
Dispatch 4 agents IN PARALLEL (single message, 4 Task tool calls). Each works in a dedicated git worktree on its own branch. Each agent's job:
- Read the design doc at
docs/plans/2026-02-27-quotesdb-design.md - Plan their domain thoroughly
- Create nbd tickets for every piece of work (using
nbd create --ftype md --json) - Commit their tickets on their branch
Agent 1: api-planner
Branch: quotesdb/api | Directory: src/bin/api/
You are a senior Rust backend engineer. Plan and ticket all backend API work for
quotesdb.The backend is Rust + Axum + Tokio targeting Cloudflare Workers (workers-rs), with SQLx/Turso for dev and Cloudflare D1 in production. An auto-generated OpenAPI spec is required.
Create one ticket per: Cargo.toml setup, database migrations, each endpoint handler, auth code generator, NanoID generator, pagination logic, tag filtering, OpenAPI spec generation, unit tests, and documentation files.
Agent 2: ui-planner
Branch: quotesdb/ui | Directory: src/bin/ui/
You are a senior Rust frontend engineer. Plan and ticket all frontend UI work for
quotesdb.The frontend is Rust + Yew compiled to wasm32-unknown-unknown, built by Trunk, hosted on Cloudflare Pages.
Create one ticket per: Cargo.toml + Trunk.toml setup, Yew app shell + routing, each page component (Home, Browse, Quote Detail, Author, Submit), API client module, auth code modal, pagination component, and documentation files.
Agent 3: qa-planner
Branch: quotesdb/qa | Directory: tests/
You are a senior QA engineer. Plan and ticket all integration test work for
quotesdb.Tests live in
tests/as Cargo integration tests, using a real HTTP client against a locally-spawned API server with a temporary SQLite database.Create one ticket per: dev-dependencies setup, test server harness, and one test suite per endpoint (list, get, random, create, update, delete, tags, router ordering).
Agent 4: infra-planner
Branch: quotesdb/infra | Directory: infra/
You are a Terraform/OpenTofu expert. Plan and ticket all infrastructure work for
quotesdb.Resources needed: Cloudflare Worker (API), Cloudflare D1 database, Cloudflare Pages project, custom domain
quotes.elijah.run. Use OpenTofu with the Cloudflare provider.Create one ticket per: OpenTofu project init, Workers script resource, D1 database resource, Pages project, custom domain, secrets docs, migration workflow docs, and infra README.
Phase 2 — Parallel Implementation Orchestrators
Required skill: Use
superpowers:dispatching-parallel-agentsbefore dispatching.
After all planning branches are merged, dispatch 4 orchestrator agents IN PARALLEL. Each orchestrator:
- Lists all tickets for their domain (
nbd ready --json) - Dispatches a sub-agent per ticket (one at a time — complete one before starting the next)
- Reviews the sub-agent's work after each ticket (validate:
cargo fmt && cargo check && cargo clippy && cargo test) - Continues to the next ticket
Domain orchestrators:
- api-orchestrator — works in
src/bin/api/, dispatches 1 sub-agent per api ticket - ui-orchestrator — works in
src/bin/ui/, dispatches 1 sub-agent per ui ticket - qa-orchestrator — works in
tests/, dispatches 1 sub-agent per qa ticket - infra-orchestrator — works in
infra/, dispatches 1 sub-agent per infra ticket
Each sub-agent receives: design doc context, the specific ticket body, validation commands, and the conventional commit scope (feat(quotesdb): ...).
# From quotesdb/
cargo fmt && cargo check && cargo clippy && cargo test
# Start API server locally
cargo run
# Build UI to Wasm
trunk build
# Dry-run infra (from infra/)
tofu plan
Manual smoke test:
# Create a quote
curl -X PUT http://localhost:8787/api/quotes \
-H "Content-Type: application/json" \
-d '{"text":"Hello world","author":"Test"}'
# List quotes
curl http://localhost:8787/api/quotes
# Random quote
curl http://localhost:8787/api/quotes/random