docs(quotesdb): add project CLAUDE.md with workflow and design reference
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>quotesdb
parent
05bad425a7
commit
4c48370373
@ -0,0 +1,177 @@
|
|||||||
|
# CLAUDE.md — quotesdb
|
||||||
|
|
||||||
|
> Inherits all conventions from [@../CLAUDE.md](../CLAUDE.md). This file adds project-specific workflow, structure, and agent dispatch rules.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
`quotesdb` is a quotes web application in the vibed mono-repo. It consists of:
|
||||||
|
|
||||||
|
- **`api/`** — Rust/Axum backend on Cloudflare Workers
|
||||||
|
- **`ui/`** — Yew (Rust/Wasm) frontend on Cloudflare Pages
|
||||||
|
- **`tests/`** — Integration test crate
|
||||||
|
- **`infra/`** — 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/test` pass, 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/a1b2c3`
|
||||||
|
- `quotesdb/ui/d4e5f6`
|
||||||
|
- `quotesdb/qa/g7h8i9`
|
||||||
|
- `quotesdb/infra/j0k1l2`
|
||||||
|
|
||||||
|
### Merge target
|
||||||
|
|
||||||
|
All completed work branches merge into the **`quotesdb`** branch (not `main`).
|
||||||
|
|
||||||
|
### Typical flow
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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:
|
||||||
|
1. The relevant section of `docs/plans/2026-02-27-quotesdb-design.md`
|
||||||
|
2. The specific nbd ticket body
|
||||||
|
3. The validation commands to run before closing the ticket
|
||||||
|
4. The conventional commit scope to use (e.g., `feat(quotesdb-api): ...`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design Reference
|
||||||
|
|
||||||
|
### 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 |
|
||||||
|
|
||||||
|
> **Router order:** `GET /api/quotes/random` must be registered **before** `GET /api/quotes/:id`.
|
||||||
|
|
||||||
|
### Auth
|
||||||
|
|
||||||
|
- No user accounts. Each quote has an `auth_code` (4-word passphrase), 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 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 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Run in order from the relevant sub-directory before closing any ticket:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo fmt # 1. formatting
|
||||||
|
cargo check # 2. syntax
|
||||||
|
cargo clippy # 3. best practices
|
||||||
|
cargo test # 4. correctness
|
||||||
|
```
|
||||||
|
|
||||||
|
For infra tickets:
|
||||||
|
```sh
|
||||||
|
tofu validate
|
||||||
|
tofu plan
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue