Sprints are time-boxed iterations for organizing work. They help teams plan, execute, and track progress in focused periods. Sprints can be in different states and contain cards with story points for velocity tracking.
pub enum SprintStatus { Planning, // Sprint created but not started Active, // Sprint is currently running Completed, // Sprint finished successfully Cancelled, // Sprint was cancelled}
// Create a new sprintlet sprint = Sprint::new( board_id, 1, // sprint number Some(0), // name index (optional) Some("sprint".to_string()) // prefix override (optional));assert_eq!(sprint.status, SprintStatus::Planning);assert!(sprint.start_date.is_none());
Sprints start in Planning status with no dates set. They remain in planning until explicitly activated.
Sprints can override card prefixes for all assigned cards:
// Set sprint's card prefixsprint.update_card_prefix(Some("hotfix".to_string()));// All cards in this sprint will use "hotfix" prefixlet card_prefix = sprint.effective_card_prefix(&board, "task");// Returns: "hotfix"
Use sprint-level card prefixes for special sprint types (e.g., “hotfix” sprint, “mvp” sprint) to automatically categorize all work.
let duration_days = 14; // 2-week sprintsprint.activate(duration_days);assert_eq!(sprint.status, SprintStatus::Active);assert!(sprint.start_date.is_some());assert!(sprint.end_date.is_some());// End date is automatically calculatedlet expected_end = start_date + Duration::days(14);assert_eq!(sprint.end_date, Some(expected_end));
Only one sprint should be active per board at a time. The board’s active_sprint_id tracks the current sprint.
Cards maintain a complete history of sprint assignments:
// View all sprints a card has been part offor log in card.get_sprint_history() { println!("Sprint {}: {} → {}", log.sprint_number, log.started_at, log.ended_at.map(|d| format!("{}", d)) .unwrap_or("ongoing".to_string()) );}// End the current sprint log when moving cardscard.end_current_sprint_log();
// Set board-level defaultboard.sprint_duration_days = Some(14); // 2 weeks// Use when activating sprintif let Some(duration) = board.sprint_duration_days { sprint.activate(duration);}
// Get next sprint number for a prefixlet number = board.get_next_sprint_number("sprint");// Returns 1, then 2, then 3, etc.// Multiple prefixes have independent sequencesboard.get_next_sprint_number("release"); // Returns 1board.get_next_sprint_number("sprint"); // Returns 2
// Check if sprint has endedif sprint.is_ended() { println!("Sprint ended on {:?}", sprint.end_date);}// Only returns true for Active sprints past their end_dateassert_eq!(sprint.status, SprintStatus::Active);assert!(Utc::now() > sprint.end_date.unwrap());