kanban-domain
Domain models and business logic for the kanban project management tool. Pure domain layer with no infrastructure dependencies.
Installation
Add to your Cargo.toml:
[]
= { = "../kanban-domain" }
API Reference
Core Entities
Board - Top-level kanban board
Card - Task with lifecycle and metadata
Sprint - Sprint lifecycle management
Column - Board organization
Supporting Types
// DTOs for safe entity modification
Card Dependencies
Directed graph system for card relationships:
ParentOfandBlocksenforce DAG constraints (cycle detection)- Edges referencing a deleted or archived card are automatically cleaned up
- Integrated into board persistence (import/export)
Sorting & Filtering
SortBy — Enum dispatch for card sorting:
CardFilter trait + concrete filters:
// Implementations: BoardFilter, ColumnFilter, SprintFilter, UnassignedOnlyFilter
Query Builder
Fluent API composing filter + sort + search:
let cards = new
.filter_by_column
.filter_by_sprint
.search
.sort
.sort_order
.execute;
History & Snapshots
HistoryManager maintains undo and redo stacks of Snapshot values. Each snapshot captures the full board state and can be serialized to/from JSON bytes.
Export / Import
;
;
BoardExporter produces single-board or all-boards JSON exports. BoardImporter reads JSON with automatic V1/V2 format detection and migration.
Architecture
Pure domain layer depending only on kanban-core. Implements rich domain models with encapsulated business logic:
kanban-core
↑
└── kanban-domain (pure business logic)
↑
└── kanban-tui, kanban-cli
Key Design Patterns
Prefix Hierarchy - Git branch naming with fallback chain:
- Card's assigned prefix → Sprint's card prefix → Board's card prefix → Default ("task")
- Enables per-card, per-sprint, or board-wide branch naming strategies
Counter System - Per-prefix independent numbering:
- Board maintains separate counters for each card prefix
- Board maintains separate counters for each sprint prefix
- Enables naming schemes like:
feature-1,bugfix-1,hotfix-1all starting at 1 - Auto-migration for legacy single-counter boards
Sprint History - Audit trail of card movements:
- Each card maintains
SprintLogentries when assigned to sprints - Tracks: when assigned, which sprint, when ended
- Enables sprint velocity and card journey analysis
Entity Update Safety - DTO pattern via Editable trait:
- DTOs provide type-safe, validated updates
- Case-insensitive enum parsing (Priority::High, priority::high both valid)
- Two-way conversion between domain entities and DTOs
Examples
Branch Name Generation
use ;
let mut board = new;
board.update_card_prefix;
let mut card = new;
card.set_assigned_prefix;
// Card prefix wins in hierarchy
let branch = card.branch_name;
// Result: "urgent-1/fix-bug"
Per-Prefix Card Numbering
use Board;
let mut board = new;
// Feature cards start at 1
let feature1 = board.get_next_card_number; // 1
let feature2 = board.get_next_card_number; // 2
// Bugfix cards are independent sequence
let bugfix1 = board.get_next_card_number; // 1
let bugfix2 = board.get_next_card_number; // 2
Sprint Lifecycle
use ;
let mut sprint = new;
assert_eq!;
// Start sprint (sets start_date and end_date)
sprint.activate; // 14-day sprint
assert_eq!;
// Complete sprint
sprint.complete;
assert_eq!;
Card Sprint Assignment
use Card;
let mut card = new;
// Assign to sprint (creates SprintLog entry)
card.assign_to_sprint;
// Get sprint history
let logs = card.get_sprint_history;
assert_eq!;
assert_eq!;
Updating Card Metadata
use ;
use Editable;
let update = CardMetadataDto ;
// Apply to card with validation
update.apply_to?;
assert_eq!;
assert_eq!;
Dependencies
kanban-core- Foundation types and traitsserde,serde_json- Serialization for JSON persistenceuuid- ID generation and UUID typeschrono- Date/time handlingasync-trait- Async trait support for future extensions
License
Apache 2.0 - See LICENSE.md for details