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.
464 lines
14 KiB
Markdown
464 lines
14 KiB
Markdown
+++
|
|
title = "quotesdb"
|
|
priority = 8
|
|
status = "todo"
|
|
ticket_type = "project"
|
|
dependencies = ["ce1e4f", "f3dc74", "c3503b", "25c413"]
|
|
+++
|
|
# QuotesDB Implementation Plan
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
> **For Claude:** SUGGESTED SUB-SKILL: Use agent-development for agent dispatch
|
|
> **For Claude:** SUGGESTED SUB-SKILL: Use dispatching-parallel-agents for agent dispatch
|
|
> **For Claude:** SUGGESTED SUB-SKILL: Use subagent-driven-development for agent dispatch
|
|
> **For Claude:** SUGGESTED SUB-SKILL: Use verification-before-completion for verification
|
|
> **For Claude:** SUGGESTED SUB-SKILL: Use finishing-a-development-branch for verification
|
|
> **For Claude:** SUGGESTED SUB-SKILL: Use using-git-worktrees for parallel work
|
|
> **For Claude:** SUGGESTED SUB-SKILL: Use test-driven-development for development workflow
|
|
|
|
**Goal:** 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.
|
|
|
|
**Architecture:** Three-phase delivery: (0) design ✓, (1) 4 parallel planning agents ticket work in git worktrees, (2) 4 parallel implementation orchestrators dispatch sub-agents per ticket. Each subdomain (api, ui, tests, infra) lives in its own directory under `quotesdb/` as an independent Rust crate.
|
|
|
|
**Tech Stack:** Rust, Axum, Tokio, workers-rs, SQLx, Turso (local) / Cloudflare D1 (prod), Yew, Trunk, OpenTofu, Cloudflare Workers + Pages
|
|
|
|
---
|
|
|
|
## Context
|
|
|
|
A new `quotesdb` service is being added to the vibed mono-repo. The design was finalized in Phase 0. This plan covers:
|
|
|
|
0. **Task 0:** Create nbd project ticket `quotesdb` (stop after this — user will trigger the rest)
|
|
1. **Task 1:** Bootstrap directory structure and design doc
|
|
2. **Task 2:** Phase 1 — dispatch 4 parallel planning agents (each in a git worktree) to create nbd tickets
|
|
3. **Task 3:** Merge planning branches
|
|
4. **Task 4:** Phase 2 — dispatch 4 parallel implementation orchestrators
|
|
|
|
---
|
|
|
|
## Finalized Design (Phase 0 Output)
|
|
|
|
### Database Schema
|
|
|
|
```sql
|
|
CREATE 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
|
|
```json
|
|
// 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
|
|
```json
|
|
{
|
|
"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-Code` header 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 |
|
|
|
|
---
|
|
|
|
## Task 1: Bootstrap Project Structure
|
|
|
|
**Step 1: Create the quotesdb branch**
|
|
```bash
|
|
git checkout -b quotesdb
|
|
```
|
|
|
|
**Step 2: Create directory skeleton**
|
|
|
|
```
|
|
quotesdb/
|
|
├── api/
|
|
│ ├── Cargo.toml
|
|
│ ├── src/
|
|
│ │ ├── main.rs
|
|
│ │ └── tests.rs
|
|
│ ├── tests/
|
|
│ ├── docs/
|
|
│ │ ├── PLANNING.md
|
|
│ │ └── ARCHITECTURE.md
|
|
│ ├── flake.nix
|
|
│ └── README.md
|
|
├── ui/
|
|
│ ├── Cargo.toml
|
|
│ ├── src/
|
|
│ │ ├── main.rs
|
|
│ │ └── tests.rs
|
|
│ ├── index.html
|
|
│ ├── Trunk.toml
|
|
│ ├── docs/
|
|
│ │ ├── PLANNING.md
|
|
│ │ └── ARCHITECTURE.md
|
|
│ ├── flake.nix
|
|
│ └── README.md
|
|
├── tests/
|
|
│ ├── Cargo.toml
|
|
│ ├── tests/
|
|
│ ├── docs/
|
|
│ │ └── PLANNING.md
|
|
│ └── README.md
|
|
├── infra/
|
|
│ └── main.tf
|
|
└── docs/
|
|
├── PLANNING.md
|
|
├── ARCHITECTURE.md
|
|
└── plans/
|
|
└── 2026-02-27-quotesdb-design.md
|
|
```
|
|
|
|
**Step 3: Write design doc**
|
|
|
|
Write the finalized design (from this plan's "Finalized Design" section) to `quotesdb/docs/plans/2026-02-27-quotesdb-design.md`.
|
|
|
|
**Step 4: Stub Cargo.toml files**
|
|
|
|
`quotesdb/api/Cargo.toml`:
|
|
```toml
|
|
[package]
|
|
name = "quotesdb-api"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
license = "MIT OR Apache-2.0"
|
|
|
|
[dependencies]
|
|
common = { path = "../../common" }
|
|
|
|
[profile.release]
|
|
opt-level = "z"
|
|
lto = true
|
|
strip = true
|
|
codegen-units = 1
|
|
```
|
|
|
|
`quotesdb/ui/Cargo.toml`:
|
|
```toml
|
|
[package]
|
|
name = "quotesdb-ui"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
license = "MIT OR Apache-2.0"
|
|
|
|
[dependencies]
|
|
common = { path = "../../common" }
|
|
|
|
[profile.release]
|
|
opt-level = "z"
|
|
lto = true
|
|
strip = true
|
|
codegen-units = 1
|
|
```
|
|
|
|
`quotesdb/tests/Cargo.toml`:
|
|
```toml
|
|
[package]
|
|
name = "quotesdb-tests"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
license = "MIT OR Apache-2.0"
|
|
```
|
|
|
|
**Step 5: Commit skeleton**
|
|
```bash
|
|
git add quotesdb/
|
|
git commit -m "chore(quotesdb): bootstrap project skeleton and design doc"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 2: Phase 1 — Parallel Planning Agents
|
|
|
|
> **Required skill:** Use `superpowers:dispatching-parallel-agents` before 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 is to:
|
|
|
|
1. Explore the design doc at `quotesdb/docs/plans/2026-02-27-quotesdb-design.md`
|
|
2. Plan their domain thoroughly
|
|
3. Create nbd tickets for every piece of work in their domain
|
|
4. Commit their tickets on their branch
|
|
|
|
The nbd tool is available in the devshell. Tickets live in `.nbd/tickets/`. Use `nbd` to create and manage tickets.
|
|
|
|
### Agent 1: api-planner
|
|
|
|
**Branch:** `quotesdb/api`
|
|
**Directory:** `quotesdb/api/`
|
|
|
|
**Prompt:**
|
|
> You are a senior Rust backend engineer. Your job is to plan and ticket all backend API work for the `quotesdb` project.
|
|
>
|
|
> Read the design doc at `quotesdb/docs/plans/2026-02-27-quotesdb-design.md` for full context.
|
|
>
|
|
> The backend is:
|
|
> - Rust, Axum, Tokio
|
|
> - Target: Cloudflare Workers (workers-rs crate)
|
|
> - Database: SQLx with Turso (local file-based SQLite) for dev, Cloudflare D1 in production
|
|
> - Auto-generated OpenAPI spec required
|
|
>
|
|
> Create one nbd ticket per logical work item. Typical tickets include:
|
|
> - Set up Cargo.toml with all dependencies
|
|
> - Implement database migrations (schema creation)
|
|
> - Implement each API endpoint (list, get, random, create, update, delete)
|
|
> - Implement auth code generation (4-word passphrase)
|
|
> - Implement NanoID generation for quote IDs
|
|
> - Implement pagination logic
|
|
> - Implement tag filtering (join with quote_tags)
|
|
> - Implement OpenAPI spec generation
|
|
> - Write unit tests for each handler
|
|
> - Write README.md, PLANNING.md, ARCHITECTURE.md
|
|
>
|
|
> Work on branch `quotesdb/api` (use git worktrees). Each ticket should have enough detail for a developer to implement it independently.
|
|
|
|
### Agent 2: ui-planner
|
|
|
|
**Branch:** `quotesdb/ui`
|
|
**Directory:** `quotesdb/ui/`
|
|
|
|
**Prompt:**
|
|
> You are a senior Rust frontend engineer with strong design sensibilities. Your job is to plan and ticket all frontend UI work for the `quotesdb` project.
|
|
>
|
|
> Read the design doc at `quotesdb/docs/plans/2026-02-27-quotesdb-design.md` for full context.
|
|
>
|
|
> The frontend is:
|
|
> - Rust + Yew compiled to Wasm (wasm32-unknown-unknown)
|
|
> - Build tool: Trunk (`trunk serve` for dev)
|
|
> - Hosted on Cloudflare Pages
|
|
>
|
|
> Pages to build:
|
|
> - `/` — Home: random quote of the day + "Browse all" link
|
|
> - `/browse` — Paginated quote list with author/tag filter controls
|
|
> - `/quotes/:id` — Single quote view + edit/delete forms (auth code prompt)
|
|
> - `/author/:name` — All quotes by an author
|
|
> - `/submit` — New quote submission form
|
|
>
|
|
> Create one nbd ticket per logical work item. Typical tickets include:
|
|
> - Set up Cargo.toml and Trunk.toml with all dependencies
|
|
> - Set up Yew app shell and routing
|
|
> - Implement each page component
|
|
> - Implement API client (fetch calls to backend)
|
|
> - Implement auth code prompt/modal
|
|
> - Implement pagination component
|
|
> - Write README.md, PLANNING.md, ARCHITECTURE.md
|
|
>
|
|
> Work on branch `quotesdb/ui` (use git worktrees). Each ticket should have enough detail for a developer to implement it independently.
|
|
|
|
### Agent 3: qa-planner
|
|
|
|
**Branch:** `quotesdb/qa`
|
|
**Directory:** `quotesdb/tests/`
|
|
|
|
**Prompt:**
|
|
> You are a senior QA engineer specializing in Rust integration testing. Your job is to plan and ticket all integration test work for the `quotesdb` project.
|
|
>
|
|
> Read the design doc at `quotesdb/docs/plans/2026-02-27-quotesdb-design.md` for full context.
|
|
>
|
|
> Integration tests live in `quotesdb/tests/` as a separate Rust crate. Tests should:
|
|
> - Spin up the API server with an in-memory SQLite database
|
|
> - Make real HTTP requests to test each endpoint
|
|
> - Verify correct behavior for happy paths and error cases
|
|
>
|
|
> Create one nbd ticket per logical test suite. Typical tickets include:
|
|
> - Set up test harness (test server, in-memory DB)
|
|
> - Test quote creation (valid body, auth code generation, auth code provided by user)
|
|
> - Test quote retrieval (by ID, not found)
|
|
> - Test quote listing (pagination, author filter, tag filter)
|
|
> - Test random quote endpoint
|
|
> - Test quote update (valid auth, wrong auth, not found)
|
|
> - Test quote deletion (valid auth, wrong auth, not found)
|
|
> - Test OpenAPI spec endpoint
|
|
> - Write README.md
|
|
>
|
|
> Work on branch `quotesdb/qa` (use git worktrees). Each ticket should have enough detail for a developer to implement it independently.
|
|
|
|
### Agent 4: infra-planner
|
|
|
|
**Branch:** `quotesdb/infra`
|
|
**Directory:** `quotesdb/infra/`
|
|
|
|
**Prompt:**
|
|
> You are a Terraform/OpenTofu expert. Your job is to plan and ticket all infrastructure work for the `quotesdb` project.
|
|
>
|
|
> Read the design doc at `quotesdb/docs/plans/2026-02-27-quotesdb-design.md` for full context.
|
|
>
|
|
> Infrastructure uses OpenTofu with the Cloudflare provider. Resources needed:
|
|
> - Cloudflare Worker for the backend API
|
|
> - Cloudflare D1 database (bound to the worker)
|
|
> - Cloudflare Pages project for the frontend
|
|
> - Custom domain: `quotes.elijah.run` for the frontend
|
|
>
|
|
> Create one nbd ticket per logical work item. Typical tickets include:
|
|
> - Set up OpenTofu project (providers, state backend)
|
|
> - Define Cloudflare Worker resource and build config
|
|
> - Define Cloudflare D1 database resource and binding
|
|
> - Define Cloudflare Pages project with custom domain
|
|
> - Write README.md for infra setup instructions
|
|
>
|
|
> Work on branch `quotesdb/infra` (use git worktrees). Each ticket should have enough detail for a developer to implement it independently.
|
|
|
|
---
|
|
|
|
## Task 3: Merge Planning Branches
|
|
|
|
After all 4 Phase 1 agents complete:
|
|
|
|
**Step 1: Review tickets from each branch**
|
|
```bash
|
|
git log quotesdb/api --oneline
|
|
git log quotesdb/ui --oneline
|
|
git log quotesdb/qa --oneline
|
|
git log quotesdb/infra --oneline
|
|
```
|
|
|
|
**Step 2: Merge all planning branches into `quotesdb`**
|
|
```bash
|
|
git checkout quotesdb
|
|
git merge quotesdb/api
|
|
git merge quotesdb/ui
|
|
git merge quotesdb/qa
|
|
git merge quotesdb/infra
|
|
```
|
|
|
|
**Step 3: Resolve any conflicts, commit**
|
|
|
|
---
|
|
|
|
## Task 4: Phase 2 — Parallel Implementation Orchestrators
|
|
|
|
> **Required skill:** Use `superpowers:dispatching-parallel-agents` before dispatching.
|
|
|
|
Dispatch 4 orchestrator agents IN PARALLEL. Each orchestrator:
|
|
1. Lists all tickets for their domain
|
|
2. Dispatches a fresh sub-agent per ticket (one at a time — complete one before starting the next)
|
|
3. Reviews the sub-agent's work after each ticket
|
|
4. Continues to the next ticket
|
|
|
|
### Implementation agent instructions (for each domain):
|
|
|
|
Each orchestrator should prompt its sub-agents with:
|
|
- Full design context from `quotesdb/docs/plans/2026-02-27-quotesdb-design.md`
|
|
- The specific ticket to implement
|
|
- Validation commands to run: `cargo fmt && cargo check && cargo clippy && cargo test`
|
|
- Conventional commit format: `feat(quotesdb-api): ...`
|
|
|
|
### Domain orchestrators:
|
|
|
|
**api-orchestrator** — works in `quotesdb/api/`, dispatches 1 sub-agent per api ticket
|
|
**ui-orchestrator** — works in `quotesdb/ui/`, dispatches 1 sub-agent per ui ticket
|
|
**qa-orchestrator** — works in `quotesdb/tests/`, dispatches 1 sub-agent per qa ticket
|
|
**infra-orchestrator** — works in `quotesdb/infra/`, dispatches 1 sub-agent per infra ticket
|
|
|
|
> **Note:** api and tests must share an API contract. If the api-orchestrator makes endpoint changes, update the design doc and notify the qa-orchestrator.
|
|
|
|
---
|
|
|
|
## Verification
|
|
|
|
After Phase 2 completes:
|
|
|
|
**Backend:**
|
|
```bash
|
|
cd quotesdb/api
|
|
cargo fmt && cargo check && cargo clippy && cargo test
|
|
cargo run # starts local server
|
|
```
|
|
|
|
**Frontend:**
|
|
```bash
|
|
cd quotesdb/ui
|
|
trunk serve # starts dev server at localhost:8080
|
|
```
|
|
|
|
**Integration tests:**
|
|
```bash
|
|
cd quotesdb/tests
|
|
cargo test
|
|
```
|
|
|
|
**Infrastructure:**
|
|
```bash
|
|
cd quotesdb/infra
|
|
tofu plan # dry-run Cloudflare infra
|
|
```
|
|
|
|
**Manual smoke test:**
|
|
```bash
|
|
# 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
|
|
```
|