Skip to content

feat(domain): add tasks/model.rs Task aggregate + Phase/Status/Priority VOs#25

Merged
mpiton merged 3 commits into
mainfrom
feat/task-T-109-tasks-model
May 5, 2026
Merged

feat(domain): add tasks/model.rs Task aggregate + Phase/Status/Priority VOs#25
mpiton merged 3 commits into
mainfrom
feat/task-T-109-tasks-model

Conversation

@mpiton
Copy link
Copy Markdown
Owner

@mpiton mpiton commented May 5, 2026

Summary

Implements Tasks bounded-context entity + value objects (task T-109). Unblocks T-110 (TaskRepository implementation), T-117 (TypeScript codegen), T-131 (architecture test). Phase state machine encodes ADR-013: agent halts at PR creation, leaving the final merge to humans.

Changes

  • New domain/tasks/model.rs: Task aggregate (id, project_id, title, body, status, phase, priority, github_issue_id, created_at/updated_at with RFC3339 serde), three value objects: Phase enum (Backlog → Spec → Plan → Code → Qa → Pr → Done), Status enum (Pending/Running/Queued/Paused/Failed/Completed/Aborted), Priority enum (P0/P1/P2). Task::new(project_id, title) seeds fresh TaskId + Backlog phase + Pending status + all optional fields = None.
  • New domain/shared/time.rs: now_utc() helper as single seam for wall-clock reads (enables future Clock port DI per ARCHI §4 without touching call sites).
  • New domain/shared/test_support.rs: assert_send_sync() compile-time check (zero runtime cost, single source) + json_roundtrip(value, expected_json) helper collapsing 4-line serialize-then-deserialize boilerplate across all value-object tests.
  • Updated domain/shared/mod.rs: exposed test_support module.
  • Updated CHANGELOG.md: detailed Added entry for Task + Phase/Status/Priority, Changed entry explaining /simplify test consolidations (5 task_new_* tests → 1, 3 serde tests → 1, removed tautological value_objects_are_copy_eq_hash).

Testing

cargo test --workspace              # 99 tests pass (105→99 after consolidation)
cargo test -p forgent --lib domain  # domain tests only, 100% coverage
cargo clippy --workspace -- -D warnings
cargo fmt --check

All 10 domain/tasks/model.rs tests pass at 100% coverage (lines/regions/functions):

  • task_new_seeds_documented_defaults
  • two_new_tasks_get_different_ids
  • phase_progresses_linearly_through_pipeline
  • phase_done_has_no_successor
  • value_objects_serde_use_pascal_case_variants
  • task_serde_roundtrip_uses_rfc3339_timestamps
  • task_with_optional_fields_set_serde_roundtrips
  • value_objects_are_send_sync

(Plus 2 tests in shared/time.rs, 0 tests in shared/test_support.rs — it's compile-time helpers only.)

Related Issues

  • Closes #T-109
  • Refs T-110 (TaskRepository), T-117 (TypeScript codegen), T-131 (architecture test)

Notes for Reviewer

Architecture purity: No ts-rs in domain layer. TS bindings for Task come from interfaces-layer DTOs (T-117/T-118), keeping ARCHI §4.1 boundaries clean. Domain stays import-pure: only serde + time + uuid (architecture test still green).

Phase semantics: Phase::next() returns Option with Done → None per ADR-013 — agent creates PR but does not merge (merge is human action). Linear encoding (Backlog → Spec → ... → Pr → Done) is now type-level.

Clock port setup: Task::new calls shared now_utc() rather than OffsetDateTime::now_utc() inline. Future Clock port DI (ARCHI §4) can swap the implementation without touching call sites.

Test consolidation (from /simplify follow-up):

  • 5 task_new_* tests merged into 1 task_new_seeds_documented_defaults (single Task::new covers 8 assertions)
  • 3 Phase/Status/Priority_serde_roundtrip tests collapsed via new json_roundtrip helper
  • Dropped value_objects_are_copy_eq_hash (runtime test of std's HashSet dedup; Copy/Eq/Hash are compile-time guaranteed by derive)

Shared helpers: assert_send_sync() and json_roundtrip() are new in test_support.rs; ids.rs and error.rs still have their own copies (refactoring those to use the shared version is T-132 follow-up, not in scope here).

Checklist

  • Tests added (10 tests at 100% coverage, domain target ≥90%)
  • Docs updated (CHANGELOG.md, module docs)
  • No secrets, debug prints, or commented code
  • Self-reviewed diff
  • Architecture test green, clippy green, fmt green

Summary by CodeRabbit

  • New Features

    • Introduces a Task model with workflow phases (Backlog → Done), execution statuses, priorities, timestamps, and a convenient task constructor for consistent seeding.
  • Infrastructure

    • Safer persistence migrations with atomic execution and rollback behavior, plus improved migration idempotency.
    • Added shared time utility and test helpers to improve reliability of timing and serialization tests.

mpiton added 2 commits May 5, 2026 15:21
…ty VOs (task T-109)

Sprint 1 / Track A — pure-domain Tasks bounded-context types.

Three Copy enums (Phase, Status, Priority) deriving full
Debug + Clone + Copy + PartialEq + Eq + Hash + serde, plus a Task
aggregate with RFC3339-serialized timestamps. Phase::next encodes
the linear pipeline progression Backlog → Spec → Plan → Code → Qa
→ Pr → Done with Done → None (ADR-013: agent halts at PR
creation). Task::new seeds defaults: TaskId::new(), phase=Backlog,
status=Pending, body/priority/github_issue_id=None,
created_at == updated_at = now_utc.

Domain stays import-pure (only serde + time + crate::domain::shared::ids::TaskId);
no ts-rs annotation here — TS bindings come via interfaces-layer
DTOs in T-117/T-118 to keep ARCHI §4.1 dependency rule.

16 unit tests cover defaults, every Phase transition, serde
roundtrips for VOs and the full aggregate, Send+Sync bounds, and
HashSet usability of each VO. Coverage 100% lines/regions/functions
on domain/tasks/model.rs (domain target ≥90%).

cargo test --workspace: 105 passed (was 90).
tests/architecture.rs still green — no forbidden imports leaked.
- Collapsed three Phase/Status/Priority serde-roundtrip tests into one
  table-driven test using the new json_roundtrip helper.
- Folded five task_new_* default-assertion tests into one consolidated
  task_new_seeds_documented_defaults covering all defaults in a single
  Task::new call.
- Dropped value_objects_are_copy_eq_hash — HashSet dedup was testing
  std's contract, not ours; the derives are compile-time guaranteed.
- Trimmed module doc-comment paragraph already enforced by
  tests/architecture.rs.
- Introduced domain/shared/time::now_utc() (Clock-port DI seam) and
  domain/shared/test_support::{assert_send_sync, json_roundtrip}
  (#[cfg(test)]-gated) so the helpers are reusable as peer modules
  land.

Net cargo test --workspace 105 → 99 (six redundant tests removed).
Coverage on domain/tasks/model.rs unchanged at 100% lines/regions/
functions; new shared/time.rs and shared/test_support.rs at 100%.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 96480a0f-f8c7-45c9-bd2e-3dc52c3710ed

📥 Commits

Reviewing files that changed from the base of the PR and between 93940ee and 1089d3f.

📒 Files selected for processing (1)
  • CHANGELOG.md
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md

📝 Walkthrough

Walkthrough

Adds a Task domain model (value objects Phase/Status/Priority and Task entity with Task::new), a shared UTC time seam now_utc(), and test-only helpers (assert_send_sync, json_roundtrip) with accompanying unit tests and changelog entries.

Changes

Task Domain Model & Test Infrastructure

Layer / File(s) Summary
Data Shape / Value Objects
src-tauri/src/domain/tasks/model.rs
Introduces Phase, Status, Priority enums (serde) and Phase::next().
Time Seam
src-tauri/src/domain/shared/time.rs
Adds pub fn now_utc() -> OffsetDateTime and tests for UTC offset and monotonicity.
Entity & Seeding
src-tauri/src/domain/tasks/model.rs
Adds Task struct with RFC3339 timestamps and pub fn new(project_id, title) seeding defaults using now_utc().
Test Helpers
src-tauri/src/domain/shared/test_support.rs, src-tauri/src/domain/shared/mod.rs
Adds test-only assert_send_sync<T: Send + Sync>(), json_roundtrip<T>(), and conditionally exposes pub mod test_support under #[cfg(test)].
Tests / Validation
src-tauri/src/domain/tasks/model.rs (tests), src-tauri/src/domain/shared/time.rs (tests)
Unit tests cover Task defaults, distinct IDs, phase progression, serde roundtrips, RFC3339 timestamps, optional-field roundtrips, and Send/Sync assertions.
Changelog
CHANGELOG.md
Documents added domain types, time seam, test helpers, and related persistence/migration notes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • mpiton/forgent#5: Implements scaffolding for the domain modules (shared/time.rs, shared/mod.rs, and tasks/model.rs) that this PR fills in.

Poem

🐰
A Backlog seed, a Phase that climbs,
Timestamps tied to UTC times.
Tests that whisper, "Send and Sync,"
JSON roundtrips—smooth as a wink.
Hopping onward, small changes fine.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding Task aggregate and Phase/Status/Priority value objects to the domain model, which aligns with the primary objective (T-109 Tasks bounded-context implementation).
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/task-T-109-tasks-model

Comment @coderabbitai help to get the list of available commands and usage tips.

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented May 5, 2026

Merging this PR will not alter performance

✅ 7 untouched benchmarks


Comparing feat/task-T-109-tasks-model (1089d3f) with main (a5e1afd)

Open in CodSpeed

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="CHANGELOG.md">

<violation number="1" location="CHANGELOG.md:9">
P3: This changelog bullet accidentally appends the ids.rs change details after the tasks/model.rs summary (starting with "(`new`, `from_uuid`)…"). Trim the entry so it ends after the tasks/model.rs summary to avoid duplicated/misleading release notes.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread CHANGELOG.md Outdated
…ntry

Cubic flagged the orphan ids.rs paragraph in the T-109 /simplify entry on
CHANGELOG.md:9 — the bullet duplicated content from the T-108 entry above.
Trimmed at the intended end of the T-109 summary.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant