Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,40 @@ All notable changes to adhd-ranch. Follows [Keep a Changelog](https://keepachang

## [Unreleased]

### Added — 034 focus/task invariants in domain (PR #40, in flight)

- `crates/domain/src/error.rs` — new `DomainError` enum: `EmptyTitle`, `EmptyTaskText`
- `NewFocus::new(title, description) -> Result<Self, DomainError>` validated constructor
- `crates/domain/src/focus.rs` — `TaskText` newtype with validated `new` + `as_str`
- `From<DomainError> for CommandError` — maps to `BadRequest`
- Command-handler regression tests assert blank input → `BadRequest`

### Changed — 034

- `Commands::create_focus` and `Commands::append_task` no longer carry their own `trim().is_empty()` guards; they call `NewFocus::new` and `TaskText::new` instead
- Focus title and task text invariants now enforced once in `crates/domain/`

### Added — 035 unit tests for `MarkdownFocusStore` (PR #41, in flight)

- 8 direct unit tests in `crates/storage/src/focus_store.rs`: create/list roundtrip, timer sidecar present/absent, delete + delete-of-unknown, corrupted `timer.json`, append/delete task persistence
- Storage seam now independently trusted without going through `Commands`

### Changed — 035

- `MarkdownFocusStore::list()` degrades to `timer: None` when `timer.json` is corrupted instead of failing the whole load — UI keeps showing the focus, user can recreate the timer

### Changed — 033 pig/drag IPC moved into `api/` layer (PR #39, in flight)

- `src/api/pig.ts` — new typed wrappers: `setPigDragActive`, `updatePigRects`, `subscribeGatherPigs`, `subscribeDisplayRegion`
- `src/types/pig.ts` — shared `SpawnRegion`, `PigHitRect` (api/ no longer depends on hooks/)
- `src/components/App.tsx` and `src/hooks/usePigMovement.ts` no longer import `@tauri-apps/api/core` or `@tauri-apps/api/event`; both go through `src/api/pig.ts`
- Subscription effects wrap a no-op fallback so cleanup cannot raise an unhandled rejection on strict-mode unmount

### Fixed

- `Taskfile.yaml` — drop stale `ralph/` include (left dangling by `dabed05 remove ralph dir`); `task check` runs again
- `issues/` — archive pre-merge drafts of 013/016/018/019/020 and move 032 into `issues/done/` (PR #42)

### Added — 028 focus timer: domain types + full-stack creation (PR #32)

- `crates/domain/src/timer.rs` — pure domain: `FocusTimer`, `TimerPreset` (2/4/8/16/32m + Custom), `TimerStatus`, `timer_remaining_secs()`, `growth_factor()`
Expand Down
8 changes: 8 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ An optional countdown attached to a Focus at creation time. Stores `duration_sec

A named duration choice offered at Focus creation: 2m, 4m, 8m, 16m, 32m, or Custom (free integer minutes). Maps to `duration_secs` in `FocusTimer`.

### TaskText

Newtype wrapper around a non-empty `String`. Construct via `TaskText::new(text)` — returns `DomainError::EmptyTaskText` for blank input. The only way `Commands::append_task` passes text into the storage layer.

### DomainError

Errors raised by validated domain constructors (`NewFocus::new`, `TaskText::new`). Variants: `EmptyTitle`, `EmptyTaskText`. Maps to `CommandError::BadRequest` at the commands layer. Domain owns the invariants; the commands layer owns the protocol mapping.

Comment thread
coderabbitai[bot] marked this conversation as resolved.
## Persistence

Focus = a self-contained directory under `~/.adhd-ranch/focuses/<slug>/`:
Expand Down
6 changes: 3 additions & 3 deletions issues/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Each issue is a self-contained vertical slice an AFK coding agent ("ralph") can

Complete these before picking up any other open issue. All are unblocked and independent — grab any order.

- [ ] [033 — Extract pig/drag IPC into api/ layer](033-pig-ipc-api-layer.md)
- [ ] [034 — Move Focus/Task invariants into domain](034-focus-invariants-in-domain.md)
- [ ] [035 — Unit tests for MarkdownFocusStore](035-focus-store-unit-tests.md)
- [~] [033 — Extract pig/drag IPC into api/ layer](033-pig-ipc-api-layer.md) — PR #39 open, awaiting review
- [~] [034 — Move Focus/Task invariants into domain](034-focus-invariants-in-domain.md) — PR #40 open, awaiting review
- [~] [035 — Unit tests for MarkdownFocusStore](035-focus-store-unit-tests.md) — PR #41 open, awaiting review
- [ ] [036 — Generate TypeScript types from Rust via ts-rs](036-ts-types-from-rust.md)

## How to pick up an issue
Expand Down
Loading