Skip to content

Sprint Planning Dashboard

Listing cells

On the main view there is the list of the cells. They are retrieved by looking for Jira boards with the JIRA_SPRINT_BOARD_PREFIX prefix.

Cell's dashboard


The basic idea for calculating estimations is the following:

  1. SPRINT_HOURS_RESERVED_FOR_PLANNING hours are reserved for the planning of the next sprint.
  2. SPRINT_HOURS_RESERVED_FOR_EPIC_MANAGEMENT hours are reserved for epic management for each sprint.
  3. Reserved time for reviewing is defined in SPRINT_HOURS_RESERVED_FOR_REVIEW as a json dict, where you can define the review time for any amount of story points. Jira tickets without story points will have a null value here, so the default behavior can be specified by defining this as a key. Example configuration: javascript SPRINT_HOURS_RESERVED_FOR_REVIEW = { "null": 2, "0": 0.5, "1.9": 1, "2": 3, "5.1": 6 } Here we are defining that:

    1. If no story points are set for an issue, it will reserve 2 hours for its review.
    2. If 0 story points are set for an issue, it will reserve 0.5 hours for its review.
    3. If 1.9 story points are set for an issue, it will reserve 1 hour for its review.
    4. If 2 story points are set for an issue, it will reserve 3 hours for its review.
    5. If 5.1 story points are set for an issue, it will reserve 6 hours for its review.
    6. If the ticket has an amount of story points that is not defined in the SPRINT_HOURS_RESERVED_FOR_REVIEW setting, then it will use the review time for the nearest number of story points defined. For example:
      1. If 3 story points are set for an issue, it will reserve 3 hours for its review as the closest number of story points defined is 2.
      2. If more than 5.1 story points (6, 10, 20, etc.) are defined for an issue, it will reserve 6 hours for its review because the closest story points value defined is 5.1.

    Note: The null value is required in SPRINT_HOURS_RESERVED_FOR_REVIEW.

  4. Each of these defaults can be overridden for each ticket by putting the following in the ticket's description:

    1. [~crafty]: plan <time> per sprint for epic management
    2. [~crafty]: plan <time> per sprint for this task
    3. [~crafty]: plan <time> for reviewing this task

    Note: The <time> should match the following regexp. Anything like 1h 30m, 1h or 30m will work.


    Note 2: crafty may need to be replaced with the value set in JIRA_BOT_USERNAME.


For each member of the cell this view displays:

  1. Assignee, reviewer, upstream and epic-related hours for the present and upcoming sprint.
  2. Tickets that are missing an estimation.
  3. Scheduled vacations for the upcoming sprint, which are retrieved from the Google Calendar events that match GOOGLE_CALENDAR_VACATION_REGEX. Partial vacations (based on the time of the meeting for each person's day) are retrieved from the GOOGLE_AVAILABILITY_RANGE of the GOOGLE_CONTACT_SPREADSHEET using the GOOGLE_AVAILABILITY_REGEX. The minus (-) suffix there indicates that the member's timezone is UTC-X. This is taken into account if user's workday spans over two days in UTC (i.e. start hour is after end hour).
  4. Committed time, which is the sum of all estimation hours.
  5. Goal for the next sprint, which is calculated by summing up user's commitments for each day of the sprint and subtractingSPRINT_HOURS_RESERVED_FOR_PLANNING and Vacation hours from it.
  6. Remaining time, which is the result of Goal - Committed.
  7. Toggles:
    1. Ongoing work. Default: true.
      This is useful to for planning the next sprint upfront by making an assumption that all work from the current sprint will be completed on time.
    2. Accepted (flagged) tickets. Default: false.
      If tickets are preassigned and flagged, then the assignees can use this option to determine whether they need to pass on some tickets.

User's dashboard

This view shows all assigned (as Assignee or Reviewer 1) tickets of the user with:

  1. Task's key (you can hover over it to see the ticket's name)
  2. User's role
  3. Current status of the ticket
  4. Remaining time for the current user
  5. Sprint indicator (active or future one)
  6. Epic/Story indicator

Note: if a ticket is flagged, then its row's background will be yellow.


After you refresh the board for the second time, you'll immediately see cached data and a spinner showing that it's being reloaded. This makes using the dashboard much smoother.

Creating new sprints

In case when a user needs to schedule tickets for sprints that haven't been created yet, they can press Create Next Sprint to create a new one for the currently viewed cell.

Completing sprints

To complete a sprint, you need to have Staff status permissions. The main idea behind this is that sprints are not shared by cells - you need to have separate sprint for each one. You can press the Complete Sprint button on the cell's dashboard to schedule a Celery task with the following pipeline:

  1. Upload spillovers.
    This uploads all spillovers to the GOOGLE_SPILLOVER_SPREADSHEET. The following rows are filled in the spreadsheet:
    1. Ticket
      The key of the ticket.
    2. Status
      The status of the ticket at the moment of ending the sprint.
    3. Sprint
      The active sprint (the one that is currently being ended).
    4. Assignee
      The assignee, for whom the spillover is being counted.
    5. Reviewer 1
    6. Reviewer 2
    7. Reporter
    8. Story Points
    9. Estimated time
      The initial estimation of the ticket (in hours).
    10. Remaining time
      The remaining time for the ticket (in hours).
    11. Reason for the spillover
      The reason of the spillover is retrieved from the comments made within the active sprint. The assignees should provide it with a comment matching the following regexp: [~{JIRA_BOT_USERNAME}\]: <spillover>(.*)<\/spillover>. In case of multiple occurrences of comments matching this regexp, only the last one is taken into account. In case of no occurrences of such comments, the Jira bot will create a comment defined in SPILLOVER_REMINDER_MESSAGE.
  2. Upload commitments.
    The goal of each user from the dashboard is uploaded to the cell-specific commitments sheet of the GOOGLE_SPILLOVER_SPREADSHEET.
  3. Move archived issues out of the active sprint.
    There has been a bug before that disallowed completing the sprint if it had archived issues, so we're moving all of them out of the active sprint.
  4. Close the active sprint.
  5. Move issues from the closed sprint to the next one.
  6. Open the next sprint.
  7. Create role-specific tickets for the sprint after next.
    • The assignees for these tickets are retrieved from the GOOGLE_ROTATIONS_RANGE sheet belonging to GOOGLE_ROTATIONS_SPREADSHEET. The format of this sheet is the following:
      • The first column contains sprint number. You can instruct SprintCraft to create multiple tickets for the same role and week by dividing the sprint into parts, i.e., by putting Sprint 100a and Sprint 100b in separate rows.
      • The second column ("Date") is omitted for the purpose of ticket creation.
      • Headers of subsequent columns contain abbreviated role names prefixed with full cell names (e.g. Cell_1 FF). Their fields contain names of team members that should become assignees of the tickets to create.
        • If no assignee is configured for a certain role and (part of a) sprint, SprintCraft won't create a corresponding JIRA ticket. This means that if a cell only requires a single assignee for a given role, for example, it can adjust the data in GOOGLE_ROTATIONS_RANGE to list only one person for that role per sprint -- even if the sprint is generally divided into two (Sprint 100a and Sprint 100b) or more parts.
    • The metadata (name, story points) of these tickets is defined in JIRA_CELL_ROLES. Please see the docstring of this variable for a detailed explanation of its format.
    • The number of hours to allocate to the role-specific tickets is configurable individually for each cell. SprintCraft retrieves them from the GOOGLE_ALLOCATION_RANGE sheet belonging to GOOGLE_ROTATIONS_SPREADSHEET. This sheet has the following format:
      • The first column contains the part of the sprint for which hours are being specified (e.g. a, b, c). Entries in this column correspond to the division of sprints into parts (e.g. Sprint 100a, Sprint 100b) described above. For each role within a cell, this makes it possible to configure hour allocations for that role individually for each part of the sprint.
      • Headers of subsequent columns contain abbreviated role name prefixed with full cell names (e.g. Cell_1 FF). Their fields contain the number of hours to allocate for each part of the sprint.
        • If any of the fields belonging to these columns are empty (i.e., if they don't explicitly mention a certain number of hours to allocate), SprintCraft will assume that the corresponding allocation is 0 hours by default.
  8. Trigger the new sprint webhooks. Please see the Setting up webhooks section for more information about this.
  9. Release the sprint completion lock and clear the cache related to sprint start date. The sprint completion task is using a Redis lock for eliminating race conditions if a task is scheduled more than once.