# CLAUDE.md — Vibed Mono-Repo ## Repository Structure This is a mono-repo of self-contained HTTP web services. Each service lives in its own top-level folder and is an independent Rust crate (no Cargo workspace). There is no cross-service communication — each service is a standalone application. ``` vibed/ ├── CLAUDE.md ├── README.md # repo-wide overview with descriptions of each project ├── LICENSE-APACHE ├── LICENSE-MIT ├── flake.nix # base Nix flake — all services inherit or extend this ├── flake.lock ├── common/ # shared library crate (types, utilities, etc.) │ ├── Cargo.toml │ └── src/ │ └── lib.rs ├── / │ ├── Cargo.toml │ ├── src/ │ │ ├── main.rs │ │ └── tests.rs # unit tests module │ ├── tests/ # integration tests │ ├── docs/ │ │ ├── PLANNING.md # development phases and work logs │ │ └── ARCHITECTURE.md # component overview and interactions │ ├── infra/ # OpenTofu infrastructure │ │ └── main.tf │ ├── flake.nix # service-specific flake (inherits base) │ └── README.md # what, how, run, test, license, disclaimer └── ... ``` ## Tech Stack ### Language & Tooling - **Language:** Rust (all software) - **Local development:** Nix with Nix Flakes for dependency management - **Infrastructure:** OpenTofu with the Cloudflare provider (stored in each service's `infra/` subfolder) - **Formatting:** Default `rustfmt` conventions (no custom `rustfmt.toml`) ### Backend - **Framework:** Tower + Axum - **Runtime:** Tokio - **Target:** Cloudflare Workers via [workers-rs](https://github.com/cloudflare/workers-rs) - **Deployment:** OpenTofu with the Cloudflare provider (prefer over wrangler for infrastructure management) - **API format:** JSON-encoded request and response payloads - **API spec:** Each backend service must have an auto-generated OpenAPI spec. _TODO: choose tooling crate._ ### Frontend - **Framework:** Yew (Rust compiled to Wasm) - **Build tool:** Trunk (`trunk serve` for local dev) - **Compile target:** `wasm32-unknown-unknown` (included in the Nix dev shell via rust-overlay) - **Hosting:** Cloudflare Pages ### Data - **Production database:** Cloudflare D1 (SQLite-compatible) - **Local database:** Turso (file-backed SQLite) - **Query layer:** SQLx ## Shared Code The `common/` crate is a shared library for types, utilities, and definitions reused across services. Individual services depend on it via a path dependency in their `Cargo.toml`: ```toml [dependencies] common = { path = "../common" } ``` ## Chosen Crates When a crate is chosen to solve a problem, it becomes the standard for that purpose across all services. Add new entries here as decisions are made. | Purpose | Crate | Notes | |---|---|---| | | | | _This table is intentionally empty. Populate it as crate decisions are made during development._ ## Secrets & Configuration - **Local:** `.env` files for local secrets. **Never commit `.env` files to the repository.** - **Production:** Wrangler secrets (`wrangler secret put `). - Add `.env` to `.gitignore` at both the repo root and service level. ## Running Services Locally ```sh # Backend service (from the service directory) cargo run # Frontend service (from the service directory) trunk serve ``` ## Validation Run these commands **in order** from the service directory before committing changes: ```sh cargo fmt # 1. consistent formatting cargo check # 2. code is syntactically correct cargo clippy # 3. code follows best practices cargo test # 4. code is logically valid ``` ## Git Conventions This repository follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary). Commit messages must use the format: ``` [optional scope]: [optional body] [optional footer(s)] ``` Common types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `ci`, `build`. Use the service name as the scope when the change is scoped to a single service (e.g., `feat(my-service): add user endpoint`). ## License All code in this repository is dual-licensed under: - [Apache License, Version 2.0](LICENSE-APACHE) - [MIT License](LICENSE-MIT) This follows standard Rust ecosystem convention. Each service README should reference this dual license. ## Code Style & Documentation ### Rust - All public functions, structs, enums, and modules must have rustdoc comments describing how they work. - Include doc-examples where applicable — these double as doctests. - Unit tests live in a `tests` module (`tests.rs` file) within the crate's root module or relevant submodules. - Each service has a `tests/` directory for integration-style tests. ### Infrastructure - Every OpenTofu `resource` and `data` block must have a comment explaining its purpose. ### Release Builds Release builds must be compiled with settings to minimize binary size. Add this to each service's `Cargo.toml`: ```toml [profile.release] opt-level = "z" lto = true strip = true codegen-units = 1 ``` ## Testing ### Structure - **Unit tests:** `src/tests.rs` module (or submodule-local `tests` modules) - **Integration tests:** `tests/` directory at the service root ### Coverage - Target 80%+ code coverage; higher is better. - _TODO: determine coverage tooling (e.g., `cargo-tarpaulin`, `cargo-llvm-cov`)._ ## Project Documentation Each service must maintain the following: ### README.md Covers: - What the project is - How it works - How to run it - How to test it - License (Apache-2.0 + MIT dual license) - Disclaimer that the software was written with Claude Code (include the specific model used) ### docs/PLANNING.md - Development phases - Work logs - Kept up to date as work progresses ### docs/ARCHITECTURE.md - Component overview - How components interact ### Task Tracking Tasks are tracked with **Beads**. The markdown docs (PLANNING, ARCHITECTURE) are for human-readable documentation only — not task management. ## Repo-Wide Files | File | Purpose | |---|---| | `CLAUDE.md` | This file — conventions and instructions for Claude Code | | `README.md` | Repo overview with a description of each service | | `LICENSE-APACHE` | Apache 2.0 license text | | `LICENSE-MIT` | MIT license text | | `flake.nix` | Base Nix flake — all service flakes inherit or extend this | | `common/` | Shared library crate for cross-service types and utilities | ## Nix - All local development uses Nix. - Dependencies are managed with Nix Flakes. - The repo root has a base `flake.nix` that services should either use directly or inherit and extend with their own `flake.nix`. ## Task Tracking with nbd `nbd` is a CLI tool for managing work tickets, designed for agent workflows. ### Initialisation ```sh nbd init ``` Run once in the project root. Creates `.nbd/tickets/`. Safe to run multiple times. ### Core commands ```sh # Create a new ticket (use --ftype md for a human-readable body) nbd create --title "Add OAuth login" --type feature --priority 7 --ftype md --json # List all open tickets (sorted by priority) nbd list --json # Read a specific ticket nbd read --json # Update a ticket nbd update --status in_progress --json nbd update --status done --json ``` ### Finding what to work on ```sh # All tickets that are unblocked and ready to start nbd ready --json # The single highest-priority unblocked ticket nbd next --json ``` ### Workflow 1. **Before starting** — create a ticket: `nbd create --title "..." --ftype md --json` 2. **When starting** — mark it in progress: `nbd update --status in_progress --json` 3. **When done** — mark it complete: `nbd update --status done --json` ### Guidelines - **Always pass `--json`** to every command for structured, unambiguous output. - **Always pass `--ftype md`** when creating tickets — markdown format keeps the body human-readable. - Use `jq` to parse and transform JSON output when needed. - Priority scale 0–10: use **7–9** for bugs, **5** for normal tasks, **3** for nice-to-haves. - `--type` choices: `project`, `feature`, `task`, `bug`. - Use `--deps id1,id2` to express blockers — tickets that must be done first. - Create tickets *before* starting non-trivial tasks, not after.