Skip to content

Sprints

Sprints enable agile workflow management within projects. Each sprint has a defined time range, a goal, and a set of tasks pulled from the project backlog.

Model

Sprint
├── name, goal?
├── projectId (cascade delete)
├── startDate, endDate
├── status: planned | active | completed | cancelled
└── tasks (many-to-many via Task.sprintId)

API Endpoints

MethodPathDescription
GET/api/projects/:projectId/sprintsList project sprints
GET/api/projects/:projectId/sprints/velocitySprint velocity data
GET/api/sprints/:idSprint details
POST/api/sprintsCreate sprint
PATCH/api/sprints/:idUpdate sprint
DELETE/api/sprints/:idDelete sprint
POST/api/sprints/:id/tasksAdd tasks to sprint
DELETE/api/sprints/:sprintId/tasks/:taskIdRemove task from sprint

Sprint Lifecycle

planned ──► active ──► completed

                └──► cancelled
  • planned — sprint is defined but not yet started
  • active — current sprint in progress
  • completed — sprint finished
  • cancelled — sprint abandoned

Frontend

Sprint Board

The SprintBoard.vue component provides a Kanban-style board with:

  • Backlog — tasks not assigned to any sprint
  • Active Sprint — tasks in the current sprint with drag-and-drop status updates

Sprint Backlog

The SprintBacklog.vue component displays tasks available for assignment to a sprint, with filtering and bulk selection.

Sprint Store

typescript
const store = useSprintsStore()
const { sprints, currentSprint } = storeToRefs(store)

await store.fetchByProject(projectId)
await store.create({ name, goal, projectId, startDate, endDate })
await store.update(id, { name, status, startDate, endDate })
await store.remove(id)
await store.addTasks(sprintId, taskIds)
await store.removeTask(sprintId, taskId)
await store.fetchVelocity(projectId)

Key Implementation Details

  • Only one sprint should be active at a time per project
  • Velocity data is calculated from completed sprints (story points or task count)
  • Tasks can belong to at most one sprint at a time
  • Sprint dates should not overlap within the same project