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.
5.8 KiB
5.8 KiB
@../CLAUDE.md
CLAUDE.md — quotesdb
Run all commands from the relevant sub-directory within `quotesdb/` (e.g., `api/`, `ui/`, `infra/`) — not from the repository root or the `quotesdb/` root.Project Overview
quotesdb is a quotes web application in the vibed mono-repo. It consists of:
api/— Rust/Axum backend on Cloudflare Workersui/— Yew (Rust/Wasm) frontend on Cloudflare Pagestests/— Integration test crateinfra/— OpenTofu infrastructure (Cloudflare D1, Workers, Pages)docs/— Project-level docs and design plans
Design reference: docs/plans/2026-02-27-quotesdb-design.md
Ticket Hierarchy
Tickets are organised as a dependency tree rooted at the project ticket:
quotesdb (root project ticket, ec118c)
├── quotesdb/api (sub-project ticket)
│ ├── quotesdb/api/<ticket-id> (task/feature/bug tickets)
│ └── ...
├── quotesdb/ui
│ └── ...
├── quotesdb/qa
│ └── ...
└── quotesdb/infra
└── ...
Rules:
- Create a ticket before starting any non-trivial work.
- Each work ticket must list its sub-project ticket as a dependency (
--deps <sub-project-id>). - Each sub-project ticket must list the root project ticket (
ec118c) as a dependency. - Only close a ticket after its work has been validated (all
cargo fmt/check/clippy/testpass, or equivalent for infra).
Branch & Worktree Workflow
All work happens in git worktrees on named branches.
Branch naming
quotesdb/<domain>/<ticket-id>
Examples:
quotesdb/api/a1b2c3quotesdb/ui/d4e5f6quotesdb/qa/g7h8i9quotesdb/infra/j0k1l2
Merge target
All completed work branches merge into the quotesdb branch (not main).
Typical flow
# Create worktree for a ticket
git worktree add .claude/worktrees/quotesdb-api-<id> -b quotesdb/api/<id>
# ... do the work ...
# Validate before merging (from the relevant sub-directory)
cargo fmt && cargo check && cargo clippy && cargo test
# Merge into quotesdb branch
git checkout quotesdb
git merge quotesdb/api/<id>
# Remove worktree
git worktree remove .claude/worktrees/quotesdb-api-<id>
Domain Expert Sub-Agents
Dispatch all implementation work to a domain expert sub-agent. Match the domain to the agent:
| Domain | Agent role |
|---|---|
api/ |
Senior Rust backend engineer — expert in API design, Axum, workers-rs, SQLx, and unit testing |
ui/ |
Senior Rust frontend engineer — expert in Yew, Wasm, Trunk, and web design |
tests/ |
Senior QA engineer — expert in Rust integration testing and HTTP test harnesses |
infra/ |
DevOps/infrastructure engineer — expert in OpenTofu, Terraform, and Cloudflare |
| Anything else | Software architect — expert in cloud services, Rust software patterns, and system design |
Each sub-agent should receive:
- The relevant section of
docs/plans/2026-02-27-quotesdb-design.md - The specific nbd ticket body
- The validation commands to run before closing the ticket
- The conventional commit scope to use (e.g.,
feat(quotesdb-api): ...)
Design Reference
Database Schema
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 |
Router order:
GET /api/quotes/randommust be registered beforeGET /api/quotes/:id.
Auth
- No user accounts. Each quote has an
auth_code(4-word passphrase), stored plaintext. - Provided via
X-Auth-Codeheader for update/delete. On mismatch:403 Forbidden. - Auth code is always returned in the create response.
Frontend Routes (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 submission form |
API Specification
The API spec lives at api/openapi.yaml (OpenAPI 3.1.0, YAML format).
- The spec is the source of truth for all endpoint contracts.
- Validate with Redocly CLI after any changes (from the
quotesdb/directory):
redocly lint api/openapi.yaml
For infra changes, run from the infra/ directory:
tofu validate
tofu plan