# nbd — Planning & Work Log ## Development Phases ### Phase 1: Crate Scaffold ✅ Set up the crate structure with no logic yet. - Created `Cargo.toml` with `clap` (derive), `async-std`, `serde`, `serde_json`; dev-dep `tempfile` - Added `[profile.release]` optimisations (`opt-level = "z"`, `lto`, `strip`, `codegen-units = 1`) - Created `src/main.rs` — `async-std` entry point with placeholder `main` - Created empty modules: `ticket.rs`, `store.rs`, `display.rs`, `tests.rs` - Created `tests/integration.rs` - Verified `cargo check` passed ### Phase 2: Data Model (`ticket.rs`) ✅ - Defined `Status` enum (`Todo`, `InProgress`, `Done`; default `Todo`) - Serialises to lowercase snake_case: `"todo"`, `"in_progress"`, `"done"` - Defined `TicketType` enum (`Project`, `Feature`, `Task`, `Bug`; default `Task`) - Serialises to lowercase: `"project"`, `"feature"`, `"task"`, `"bug"` - Defined `Ticket` struct with all required fields - Implemented `Ticket::new(id, title)` with defaults - Implemented `validate_priority(priority)` — errors if > 10 - Implemented `generate_id()` — 3 random bytes → 6 hex chars via `RandomState` - Unit tests: serialisation roundtrip, priority validation, ID format and uniqueness ### Phase 3: Storage (`store.rs`) ✅ - Implemented `find_nbd_root_from(start)` — walks up from `start` to find `.nbd/` - Implemented `find_nbd_root()` — starts from `std::env::current_dir()` - Implemented `tickets_dir(root)` — pure path computation - Implemented `ensure_tickets_dir(root)` — creates `.nbd/tickets/` if missing - Implemented `ticket_path(root, id)` — pure path computation - Implemented `write_ticket(root, ticket)` — serialise and write JSON file - Implemented `read_ticket(root, id)` — read and deserialise; descriptive error if not found - Implemented `list_tickets(root)` — read all `*.json`, sort by priority descending - Unit tests: write/read roundtrip, list returns all tickets, traversal from grandparent dir ### Phase 4: Display (`display.rs`) ✅ - Implemented `format_ticket(ticket)` / `print_ticket(ticket)` — full tabular view - Implemented `format_ticket_json(ticket)` / `print_ticket_json(ticket)` — pretty JSON - Implemented `format_list(tickets)` / `print_list(tickets)` — short summary table - Implemented `format_list_json(tickets)` / `print_list_json(tickets)` — JSON array - `format_*` functions return `String` for testability; `print_*` write to stdout - Unit tests: table output contains expected field values, JSON is valid ### Phase 5: CLI Commands (`main.rs`) ✅ - Defined `Cli` struct with global `--json` flag and `Commands` enum - Subcommands: `create`, `read`, `list`, `update` - Implemented `cmd_create`, `cmd_read`, `cmd_list`, `cmd_update` - Added `parse_status`, `parse_ticket_type`, `parse_deps`, `validate_deps` helpers - Fixed clippy warning: `map_or(false, ...)` → `is_some_and(...)` - Integration tests: create→read roundtrip, list, update merge, traversal from subdir, error on unknown ID, `--json` flag, dep replacement ### Phase 6: Documentation & Validation ✅ - Wrote `README.md` — what, how, usage, testing, license, Claude Code disclaimer - Wrote `docs/PLANNING.md` (this file) — phases and work log - Wrote `docs/ARCHITECTURE.md` — module overview and interactions - Ran `cargo fmt`, `cargo check`, `cargo clippy`, `cargo test` — all clean --- ## Post-MVP Roadmap See [`PLAN.md`](../PLAN.md) for the full list of planned post-MVP features, including: - `nbd init` — explicit initialisation command - `nbd ready` — list tickets with no blockers - `nbd archive` — mark tickets as Closed - `nbd update` git-diff-style output - Partial ID matching - SQLite cache - Nix flake - Multiple file format support (`.md`, `.toml`, `.jsonb`)