@beauraines/sprint-tracker 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.eslintrc.json +16 -0
  2. package/.github/dependabot.yml +21 -0
  3. package/CHANGELOG.md +52 -0
  4. package/R/HeloSprintBurndown.R +138 -0
  5. package/R/ProjectHealth.R +109 -0
  6. package/R/backlogByTeam.R +52 -0
  7. package/R/backlogHealth.R +163 -0
  8. package/R/burndDownChart.R +144 -0
  9. package/R/carryOverAdjustedVelocity.R +154 -0
  10. package/R/featureTeamBacklog.R +73 -0
  11. package/R/projectHealth.Rmd +111 -0
  12. package/R/sprintOutcomes.R +142 -0
  13. package/R/sprintOutcomesCli.R +103 -0
  14. package/R/sprintOutcomesFeatureTeam.R +143 -0
  15. package/R/timeInCodeReview.R +157 -0
  16. package/README.md +181 -0
  17. package/cli.js +55 -0
  18. package/cmds/addOutcomes.js +98 -0
  19. package/cmds/addProject.js +53 -0
  20. package/cmds/addSprint.js +117 -0
  21. package/cmds/config.js +33 -0
  22. package/cmds/getSprintDetails.js +86 -0
  23. package/cmds/visualizations.js +116 -0
  24. package/docker-compose.yml +11 -0
  25. package/migrations/20230222011333-create-health-table.sql +10 -0
  26. package/migrations/20230222011334-outcomes.sql +42 -0
  27. package/migrations/20231206093700-seed-outcomes-table.sql +9 -0
  28. package/migrations.js +20 -0
  29. package/package.json +50 -0
  30. package/scripts/generateBacklogByTeam.sh +20 -0
  31. package/scripts/generateBacklogHealth.sh +12 -0
  32. package/scripts/generateChart.sh +7 -0
  33. package/scripts/generateFeatureTeamBacklog.sh +16 -0
  34. package/scripts/generateSprintOutcomePlot.sh +12 -0
  35. package/scripts/sprintOutcomes.sh +29 -0
  36. package/sql/bugsOpenedDuringSprint.sql +14 -0
  37. package/sql/bugsOpenedDuringSprintFeature.sql +14 -0
  38. package/sql/capacityAdjustedVelocity.sql +48 -0
  39. package/sql/carryOver.sql +33 -0
  40. package/sql/commitment.sql +30 -0
  41. package/sql/commitmentMet.sql +60 -0
  42. package/sql/completed.sql +40 -0
  43. package/sql/descoped.sql +21 -0
  44. package/sql/pullForward.sql +19 -0
  45. package/sql/pullForwardFeature.sql +10 -0
  46. package/sql/sprintOutcomes.sql +25 -0
  47. package/sql/sprint_outcomes.sql +23 -0
  48. package/src/addOutcomes.js +94 -0
  49. package/src/addSprint.js +108 -0
  50. package/src/getSprintDetails.js +88 -0
  51. package/utils/display.js +68 -0
  52. package/utils/input.js +24 -0
  53. package/utils/readConfig.js +74 -0
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -xe
3
+
4
+
5
+
6
+ sqlite3 --header --csv tracker.db < sql/sprint_outcomes.sql | clipivot sum -r2 -c3 --val story_points |
7
+ graph - --bar --xlabel Sprints --ylabel 'Story Points' --title 'ECOM Accessibility Sprint Outcomes' --bar-label
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ if ! docker info > /dev/null 2>&1; then
4
+ echo "This script uses docker, and it isn't running - please start docker and try again!"
5
+ exit 1
6
+ fi
7
+
8
+ # PROJECT_DIR must have trailing slash
9
+ PROJECT_DIR=/Users/beauraines/projects/
10
+ IMAGE=rocker/tidyverse
11
+
12
+ cd ~/Documents/Expeditors/feature-team-work-items
13
+
14
+ jq -r '.[]| [.id,.fields."System.Title",.fields."System.WorkItemType",.fields."System.IterationPath",.fields."System.State", input_filename] | @csv' feature-team-*.json > ~/projects/featureTeamBacklog.csv
15
+
16
+ docker run -it --rm -v ${PROJECT_DIR}:/home/rstudio/projects/ ${IMAGE} su -c 'Rscript /home/rstudio/projects/sprint-tracker/R/featureTeamBacklog.R 2>/dev/null' rstudio
@@ -0,0 +1,12 @@
1
+ #!/bin/bash
2
+
3
+ if ! docker info > /dev/null 2>&1; then
4
+ echo "This script uses docker, and it isn't running - please start docker and try again!"
5
+ exit 1
6
+ fi
7
+
8
+ # PROJECT_DIR must have trailing slash
9
+ PROJECT_DIR=/Users/beauraines/projects/
10
+ IMAGE=rocker/tidyverse
11
+
12
+ docker run -it --rm -v ${PROJECT_DIR}:/home/rstudio/projects/ ${IMAGE} su -c 'Rscript /home/rstudio/projects/sprint-tracker/R/sprintOutcomes.R 2>/dev/null' rstudio
@@ -0,0 +1,29 @@
1
+ #!/bin/bash
2
+ #set -x
3
+
4
+ # Get Sprint Outcome data
5
+
6
+ # How to make this dynamic - like the lines that start with cat
7
+
8
+
9
+ cat 2023-07-25T18:00-07:00.csv | csvsql --query /Users/beauraines/projects/sprint-tracker/sql/commitment.sql
10
+ cat 2023-07-25T18:00-07:00.csv | csvsql --query /Users/beauraines/projects/sprint-tracker/sql/commitment.sql | csvlook
11
+ csvsql --query ~/projects/sprint-tracker/sql/commitmentMet.sql 2023-08-07T18:00-07:00.csv 2023-07-25T18:00-07:00.csv | csvlook --no-inference
12
+ cat 2023-08-07T18:00-07:00.csv | csvsql --no-inference --query ~/projects/sprint-tracker/sql/foo2.sql | csvlook
13
+ cat 2023-08-07T18:00-07:00.csv | csvsql --no-inference --query ~/projects/sprint-tracker/sql/completed.sql | csvlook
14
+
15
+ csvsql --query ~/projects/sprint-tracker/sql/descoped.sql 2023-08-07T18:00-07:00.csv 2023-07-25T18:00-07:00.csv | csvlook
16
+ cat 2023-07-25T18:00-07:00.csv | csvsql --query /Users/beauraines/projects/sprint-tracker/sql/commitment.sql
17
+ cat 2023-08-07T18:00-07:00.csv | csvsql --no-inference --query ~/projects/sprint-tracker/sql/completed.sql | csvlook
18
+ csvsql --query ~/projects/sprint-tracker/sql/pullForward.sql 2023-07-25T18:00-07:00.csv 2023-08-07T18:00-07:00.csv | csvlook
19
+ csvsql --query ~/projects/sprint-tracker/sql/descoped.sql 2023-08-07T18:00-07:00.csv 2023-07-25T18:00-07:00.csv | csvlook
20
+ csvsql --query ~/projects/sprint-tracker/sql/carryOver.sql 2023-08-07T18:00-07:00.csv | csvlook
21
+
22
+ csvsql --query ~/projects/sprint-tracker/sql/commitmentMet.sql 2023-08-07T18:00-07:00.csv 2023-07-25T18:00-07:00.csv | csvlook --no-inference
23
+ cat 2023-08-07T18:00-07:00.csv | csvsql --no-inference --query ~/projects/sprint-tracker/sql/completed.sql | csvlook
24
+ csvsql --query ~/projects/sprint-tracker/sql/pullForward.sql 2023-07-25T18:00-07:00.csv 2023-08-07T18:00-07:00.csv | csvlook
25
+ csvsql --query ~/projects/sprint-tracker/sql/descoped.sql 2023-08-07T18:00-07:00.csv 2023-07-25T18:00-07:00.csv | csvlook
26
+ csvsql --query ~/projects/sprint-tracker/sql/carryOver.sql 2023-08-07T18:00-07:00.csv | csvlook
27
+ cat 2023-07-25T18:00-07:00.csv | csvsql --query /Users/beauraines/projects/sprint-tracker/sql/commitment.sql
28
+ cat 2023-07-25T18:00-07:00.csv | csvsql --query /Users/beauraines/projects/sprint-tracker/sql/commitment.sql | csvlook
29
+ csvsql --query ~/projects/sprint-tracker/sql/commitmentMet.sql 2023-08-07T18:00-07:00.csv 2023-07-25T18:00-07:00.csv | csvlook --no-inference
@@ -0,0 +1,14 @@
1
+ -- csvsql --query ~/projects/sprint-tracker/sql/bugsOpenedDuringSprint.sql 2023-08-22T16:30-07:00.csv 2023-09-04T18:00-07:00.csv | csvlook
2
+ SELECT
3
+ end.ID,
4
+ end.Title,
5
+ end.State,
6
+ end."Area Path"
7
+ FROM
8
+ '2023-09-04T18:00-07:00' end
9
+ left join '2023-08-22T16:30-07:00' start on start.id = end.id
10
+ WHERE
11
+ start.id is null and
12
+ end."Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
13
+ -- end."Area Path" = 'The Helo Project\Solution Team\Feature Team 1'
14
+ and end.'Work Item Type' = 'Bug'
@@ -0,0 +1,14 @@
1
+ -- csvsql --query ~/projects/sprint-tracker/sql/bugsOpenedDuringSprintFeature.sql 2023-08-22T16:30-07:00.csv 2023-09-04T18:00-07:00.csv | csvlook
2
+ SELECT
3
+ end.ID,
4
+ end.Title,
5
+ end.State,
6
+ end."Area Path"
7
+ FROM
8
+ '2023-09-04T18:00-07:00' end
9
+ left join '2023-08-22T16:30-07:00' start on start.id = end.id
10
+ WHERE
11
+ start.id is null and
12
+ -- end."Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
13
+ end."Area Path" = 'The Helo Project\Solution Team\Feature Team 1'
14
+ and end.'Work Item Type' = 'Bug'
@@ -0,0 +1,48 @@
1
+ select
2
+ s.id,
3
+ s.sprint_name,
4
+ s.start_date,
5
+ s.end_date,
6
+ case
7
+ when developers is null and s.start_date < '2022-05-25' then 2
8
+ when developers is null and s.start_date >= '2022-05-25' then 3
9
+ else developers
10
+ end
11
+ developers, -- if null, before 2022-05-25 only 2, 2022-05-25 and after, 3
12
+ ifnull(non_working_days,0) AS non_working_days,
13
+ ifnull(developer_pto_days,0) as developer_pto_days,
14
+ so.story_points AS story_points_delivered,
15
+ case
16
+ when developers is null and s.start_date < '2022-05-25' then 2
17
+ when developers is null and s.start_date >= '2022-05-25' then 3
18
+ else developers
19
+ end * (10 - ifnull(non_working_days,0)) - ifnull(developer_pto_days,0) AS developer_days,
20
+
21
+ /* case
22
+ when developers is null and s.start_date < '2022-05-25' then 2
23
+ when developers is null and s.start_date >= '2022-05-25' then 3
24
+ else developers
25
+ end * (10 - ifnull(non_working_days,0)) - ifnull(developer_pto_days,0) / 30 AS something,
26
+
27
+
28
+ cast(so.story_points as REAL) / (case
29
+ when developers is null and s.start_date < '2022-05-25' then 2
30
+ when developers is null and s.start_date >= '2022-05-25' then 3
31
+ else developers
32
+ end * (10 - ifnull(non_working_days,0)) - ifnull(developer_pto_days,0)) AS points_per_developer_day,
33
+
34
+ cast(so.story_points as REAL) / (case
35
+ when developers is null and s.start_date < '2022-05-25' then 2
36
+ when developers is null and s.start_date >= '2022-05-25' then 3
37
+ else developers
38
+ end * (10 - ifnull(non_working_days,0)) - ifnull(developer_pto_days,0)) * case
39
+ when developers is null and s.start_date < '2022-05-25' then 2
40
+ when developers is null and s.start_date >= '2022-05-25' then 3
41
+ else developers
42
+ end * 10 AS capacity_adjusted_velocity,*/
43
+
44
+ so.notes
45
+ from sprints s
46
+ JOIN sprint_outcomes so on so.sprint_id = s.id and so.outcome_id = 1 -- delivered stories only
47
+ WHERE
48
+ s.project_id = 4;
@@ -0,0 +1,33 @@
1
+ -- csvsql --query ~/projects/sprint-tracker/sql/carryOver.sql 2023-09-04T18:00-07:00.csv | csvlook
2
+
3
+ SELECT
4
+ "Area Path",
5
+ count(*),
6
+ sum("Story Points"),
7
+ sum(CASE
8
+ WHEN "Story Points" = 0 -- Coerce any unestimated work-item to 1 point
9
+ THEN 1
10
+ ELSE "Story Points"
11
+ END) Story_Points_Adjusted
12
+ FROM
13
+ '2023-09-04T18:00-07:00'
14
+ WHERE
15
+ "Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
16
+ and State not in ('Closed','As Designed','Wont Fix')
17
+ GROUP BY "Area Path"
18
+
19
+ UNION
20
+ SELECT
21
+ 'Total',
22
+ count(*),
23
+ sum("Story Points"),
24
+ sum(CASE
25
+ WHEN "Story Points" = 0 -- Coerce any unestimated work-item to 1 point
26
+ THEN 1
27
+ ELSE "Story Points"
28
+ END) Story_Points_Adjusted
29
+ FROM
30
+ '2023-09-04T18:00-07:00'
31
+ WHERE
32
+ "Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
33
+ and State not in ('Closed','As Designed','Wont Fix')
@@ -0,0 +1,30 @@
1
+ -- cat 2023-08-22T16:30-07:00.csv | csvsql --query /Users/beauraines/projects/sprint-tracker/sql/commitment.sql | csvlook
2
+ SELECT
3
+ start."Area Path",
4
+ count(*) AS Committed_Stories,
5
+ sum(CASE
6
+ WHEN "Story Points" = 0 -- Coerce any unestimated work-item to 1 point
7
+ THEN 1
8
+ ELSE "Story Points"
9
+ END) Committed_Story_Points
10
+ FROM
11
+ stdin AS start
12
+ WHERE
13
+ start."Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
14
+ GROUP BY
15
+ start."Area Path"
16
+
17
+ UNION
18
+
19
+ SELECT
20
+ 'Total',
21
+ count(*) AS Committed_Stories,
22
+ sum(CASE
23
+ WHEN "Story Points" = 0 -- Coerce any unestimated work-item to 1 point
24
+ THEN 1
25
+ ELSE "Story Points"
26
+ END) Committed_Story_Points
27
+ FROM
28
+ stdin AS start
29
+ WHERE
30
+ start."Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
@@ -0,0 +1,60 @@
1
+ -- csvsql --query ~/projects/sprint-tracker/sql/commitmentMet.sql 2023-09-04T18:00-07:00.csv 2023-08-22T16:30-07:00.csv | csvlook --no-inference
2
+
3
+ WITH start AS (
4
+ SELECT
5
+ *,
6
+ CASE
7
+ WHEN "Story Points" = 0 -- Coerce any unestimated work-item to 1 point
8
+ THEN 1
9
+ ELSE "Story Points"
10
+ END Story_Points_Adjusted
11
+ FROM
12
+ '2023-08-22T16:30-07:00'
13
+ ),
14
+
15
+ end as (
16
+ SELECT
17
+ *,
18
+ CASE
19
+ WHEN "Story Points" = 0 -- Coerce any unestimated work-item to 1 point
20
+ THEN 1
21
+ ELSE "Story Points"
22
+ END Story_Points_Adjusted
23
+ FROM
24
+ '2023-09-04T18:00-07:00'
25
+
26
+ )
27
+
28
+
29
+
30
+ SELECT
31
+ start."Area Path",
32
+ count(*) AS Commitment,
33
+ sum(start."Story_Points_Adjusted") AS Committed_Story_Points,
34
+ sum(CASE WHEN end.State in ('Closed','As Designed') THEN 1 ELSE 0 END) AS Closed_Stories,
35
+ sum(CASE WHEN end.State in ('Closed','As Designed') THEN end."Story_Points_Adjusted" ELSE 0 END) AS Closed_Story_Points,
36
+ sum(CASE WHEN end.State = 'Closed' THEN 1 WHEN end.State = 'QA Review' THEN 1 WHEN end.State = 'In QA' THEN 1 WHEN end.State = 'In UAT' THEN 1 ELSE 0 END) AS QA_Stories,
37
+ cast(sum(CASE WHEN end.State = 'Closed' THEN 1 ELSE 0 END) as float) / count(*) AS Commited_Story_Percent
38
+ FROM
39
+ start
40
+ LEFT join end on end.id = start.id and start."Area Path" = end."Area Path" -- committed work-items move between teams
41
+ WHERE
42
+ start."Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
43
+ GROUP BY
44
+ start."Area Path"
45
+
46
+ UNION
47
+
48
+ SELECT
49
+ 'Total',
50
+ count(*) AS Commitment,
51
+ sum(start."Story_Points_Adjusted") AS Committed_Story_Points,
52
+ sum(CASE WHEN end.State = 'Closed' THEN 1 ELSE 0 END) AS Closed_Stories,
53
+ sum(CASE WHEN end.State in ('Closed','As Designed') THEN end."Story_Points_Adjusted" ELSE 0 END) AS Closed_Story_Points,
54
+ sum(CASE WHEN end.State = 'Closed' THEN 1 WHEN end.State = 'QA Review' THEN 1 WHEN end.State = 'In QA' THEN 1 WHEN end.State = 'In UAT' THEN 1 ELSE 0 END) AS QA_Stories,
55
+ cast(sum(CASE WHEN end.State = 'Closed' THEN 1 ELSE 0 END) as float) / count(*) AS Commited_Story_Percent
56
+ FROM
57
+ start
58
+ LEFT join end on end.id = start.id and start."Area Path" = end."Area Path"
59
+ WHERE
60
+ start."Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
@@ -0,0 +1,40 @@
1
+ -- cat 2023-09-04T18:00-07:00.csv | csvsql --no-inference --query ~/projects/sprint-tracker/sql/completed.sql | csvlook
2
+ WITH work_items AS
3
+ (SELECT
4
+ *,
5
+ CASE
6
+ WHEN "Story Points" = 0 -- Coerce any unestimated work-item to 1 point
7
+ THEN 1
8
+ ELSE "Story Points"
9
+ END Story_Points_Adjusted
10
+ FROM
11
+ stdin
12
+ )
13
+
14
+ SELECT
15
+ "Area Path",
16
+ sum(CASE WHEN State in ('Closed','As Designed','Wont Fix') THEN 1 ELSE 0 END) AS Closed_Stories,
17
+ sum(CASE WHEN State in ('Closed','As Designed','Wont Fix') THEN Story_Points_Adjusted ELSE 0 END) AS Closed_Story_Points,
18
+ sum(CASE WHEN State in ('Closed','As Designed','QA Review','In QA','In UAT') THEN 1 ELSE 0 END) AS Closed_Including_QA_Stories,
19
+ sum(CASE WHEN State in ('QA Review','In QA','In UAT') THEN 1 ELSE 0 END) AS QA_Stories
20
+ FROM
21
+ work_items
22
+ WHERE
23
+ State in ('Closed','QA Review','In QA','In UAT','As Designed','Wont Fix')
24
+ and "Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
25
+ GROUP BY
26
+ "Area Path"
27
+
28
+ UNION
29
+
30
+ SELECT
31
+ "Total",
32
+ sum(CASE WHEN State in ('Closed','As Designed','Wont Fix') THEN 1 ELSE 0 END) AS Closed_Stories,
33
+ sum(CASE WHEN State in ('Closed','As Designed','Wont Fix') THEN Story_Points_Adjusted ELSE 0 END) AS Closed_Story_Points,
34
+ sum(CASE WHEN State in ('Closed','As Designed','QA Review','In QA','In UAT') THEN 1 ELSE 0 END) AS Closed_Including_QA_Stories,
35
+ sum(CASE WHEN State in ('QA Review','In QA','In UAT') THEN 1 ELSE 0 END) AS QA_Stories
36
+ FROM
37
+ work_items
38
+ WHERE
39
+ State in ('Closed','QA Review','In QA','In UAT','As Designed','Wont Fix')
40
+ and "Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
@@ -0,0 +1,21 @@
1
+ -- csvsql --query ~/projects/sprint-tracker/sql/descoped.sql 2023-09-04T18:00-07:00.csv 2023-08-22T16:30-07:00.csv | csvlook --no-inference
2
+ SELECT
3
+ start.'Work Item Type',
4
+ start."Area Path",
5
+ count(*),
6
+ -- sum(start."Story Points"),
7
+ sum(CASE
8
+ WHEN start."Story Points" = 0 -- Coerce any unestimated work-item to 1 point
9
+ THEN 1
10
+ ELSE start."Story Points"
11
+ END) AS Story_Points
12
+ FROM
13
+ '2023-09-04T18:00-07:00' end
14
+ right join '2023-08-22T16:30-07:00' start on start.id = end.id
15
+ WHERE
16
+ end.id is null and
17
+ start."Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
18
+ -- start."Area Path" in ('The Helo Project\Solution Team\Feature Team 1')
19
+ GROUP BY
20
+ start.'Work Item Type',
21
+ start."Area Path"
@@ -0,0 +1,19 @@
1
+ -- csvsql --query ~/projects/sprint-tracker/sql/pullForward.sql 2023-08-22T16:30-07:00.csv 2023-09-04T18:00-07:00.csv | csvlook
2
+ SELECT
3
+ end.'Work Item Type',
4
+ count(*),
5
+ -- sum(end."Story Points"),
6
+ sum(CASE
7
+ WHEN end."Story Points" = 0 -- Coerce any unestimated work-item to 1 point
8
+ THEN 1
9
+ ELSE end."Story Points"
10
+ END) AS Story_Points
11
+ FROM
12
+ '2023-09-04T18:00-07:00' end
13
+ left join '2023-08-22T16:30-07:00' start on start.id = end.id
14
+ WHERE
15
+ start.id is null and
16
+ -- end."Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
17
+ end."Area Path" = 'The Helo Project\Solution Team\Feature Team 1'
18
+ GROUP BY
19
+ end.'Work Item Type'
@@ -0,0 +1,10 @@
1
+ -- csvsql --query ~/projects/sprint-tracker/sql/pullForwardFeature.sql 2023-09-04T18:00-07:00.csv 2023-08-22T16:30-07:00.csv | csvlook
2
+ SELECT
3
+ end.*
4
+ FROM
5
+ '2023-09-04T18:00-07:00' end
6
+ left join '2023-08-22T16:30-07:00' start on start.id = end.id
7
+ WHERE
8
+ start.id is null and
9
+ -- end."Area Path" not in ('The Helo Project\Solution Team\Data Science','The Helo Project\Solution Team\Product Ownership','The Helo Project\Solution Team\QA Team')
10
+ end."Area Path" = 'The Helo Project\Solution Team\Feature Team 1'
@@ -0,0 +1,25 @@
1
+ -- SQLite
2
+ SELECT
3
+ p.name project_name,
4
+ s.id sprint_id,
5
+ s.sprint_name,
6
+ s.end_date,
7
+ case
8
+ when o.name = 'Commitment' then 'A-Commitment'
9
+ when o.name = 'Delivered' then 'B-Delivered'
10
+ else o.name
11
+ end outcome,
12
+ -- s.commited_points,
13
+ -- so.issue_count,
14
+ -- so.story_points,
15
+ ifnull(so.story_points, so.issue_count) AS story_points -- accounts for unpointed bug stories
16
+
17
+ from projects p
18
+
19
+ JOIN sprints s on s.project_id = p.id
20
+ JOIN sprint_outcomes so on so.sprint_id = s.id
21
+ JOIN outcomes o on o.id = so.outcome_id
22
+
23
+ WHERE
24
+ -- p.id = 10 -- Helo Project Team
25
+ p.id = 11 -- Feature Team One
@@ -0,0 +1,23 @@
1
+ -- SQLite
2
+ SELECT
3
+ p.name project_name,
4
+ s.id sprint_id,
5
+ s.sprint_name,
6
+ case
7
+ when o.name = 'Commitment' then 'A-Commitment'
8
+ when o.name = 'Delivered' then 'B-Delivered'
9
+ else o.name
10
+ end outcome,
11
+ -- s.commited_points,
12
+ -- so.issue_count,
13
+ so.story_points
14
+
15
+ from projects p
16
+
17
+ JOIN sprints s on s.project_id = p.id
18
+ JOIN sprint_outcomes so on so.sprint_id = s.id
19
+ JOIN outcomes o on o.id = so.outcome_id
20
+
21
+ WHERE
22
+ p.pm_name like 'Beau%'
23
+
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env node
2
+
3
+ const prompt = require('prompt-sync')({sigint:true});
4
+ const {homedir} = require('os');
5
+ const { database: db } = require('helpers')
6
+
7
+
8
+ async function main() {
9
+ // TODO read from a config or CLI
10
+ // TODO add migrations check or index function
11
+ let database = `${homedir}/projects/sprint-tracker/tracker.db`
12
+
13
+ // list projects
14
+
15
+ let statement = 'select * from projects;';
16
+
17
+ let projects = await db.query(database,statement)
18
+
19
+ for (const project of projects) {
20
+ console.log(project.id, project.name)
21
+ }
22
+
23
+ // Select the project
24
+ let project_id
25
+
26
+ let text = 'Enter the project id: '
27
+ while (!project_id) {
28
+ project_id = prompt(text)
29
+
30
+ // validate the response
31
+ if (!projects.find(x => (x.id == project_id))) {
32
+ console.error('Invalid project id')
33
+ project_id = null
34
+ }
35
+ }
36
+
37
+
38
+ console.log(project_id)
39
+
40
+ // Add new sprint
41
+
42
+ let sprints = await db.query(database,`select id, sprint_name AS name from sprints where project_id = ${project_id};`)
43
+
44
+ // FIXME - sprint_name isn't being displayed because the function is looking for name
45
+ console.log('If your sprint is not displayed, you will have to manually add it.')
46
+ let sprintId = promptForInput(sprints,'Enter the sprint id: ')
47
+
48
+ // enter outcomes
49
+ let sprintOutcomes = []
50
+ let outcomes = await db.query(database,'select * from outcomes;')
51
+ for (const outcome of outcomes) {
52
+ // TODO Fix output formatting
53
+ console.log(outcome.id, outcome.name, outcome.description)
54
+ let issue_count = prompt('Enter the number of stories or a blank line to skip: ')
55
+ if (issue_count == '' ) {
56
+ continue
57
+ }
58
+ let story_points = prompt('Enter the number of story points: ')
59
+ let notes = prompt('Enter any notes: ')
60
+
61
+ sprintOutcomes.push({
62
+ sprint_id: sprintId,
63
+ outcome_id: outcome.id,
64
+ issue_count,
65
+ story_points,
66
+ notes
67
+ })
68
+ }
69
+ // validate sprint_outcomes
70
+
71
+ console.log(sprintOutcomes)
72
+
73
+ // Save outcomes to DB
74
+ let result = await db.insert(database,'sprint_outcomes',sprintOutcomes,['sprint_id','outcome_id'])
75
+ }
76
+
77
+ main()
78
+
79
+ function promptForInput(items,promptText) {
80
+ let id
81
+ for (const item of items) {
82
+ console.log(item.id, item.name)
83
+ }
84
+ while (!id) {
85
+ id = prompt(promptText)
86
+
87
+ // validate the response
88
+ if (!items.find(x => (x.id == id))) {
89
+ console.error('Invalid id')
90
+ id = null
91
+ }
92
+ }
93
+ return id
94
+ }
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+
3
+ const prompt = require('prompt-sync')({sigint:true});
4
+ const {homedir} = require('os');
5
+ const { database: db } = require('helpers')
6
+
7
+
8
+ async function main() {
9
+ // TODO read from a config or CLI
10
+ let database = `${homedir}/projects/sprint-tracker/tracker.db`
11
+
12
+ // list projects
13
+
14
+ let statement = 'select * from projects;';
15
+
16
+ let projects = await db.query(database,statement)
17
+
18
+ for (const project of projects) {
19
+ console.log(project.id, project.name)
20
+ }
21
+
22
+ // Select the project
23
+ let project_id
24
+
25
+ let text = 'Enter the project id: '
26
+ while (!project_id) {
27
+ project_id = prompt(text)
28
+
29
+ // validate the response
30
+ if (!projects.find(x => (x.id == project_id))) {
31
+ console.error('Invalid project id')
32
+ project_id = null
33
+ }
34
+ }
35
+
36
+
37
+ console.log(project_id)
38
+
39
+ // Get new sprint information from user
40
+
41
+ let sprint_name = prompt('Enter the sprint name: ')
42
+ let start_date = prompt('Enter the sprint start date: ')
43
+ let end_date = prompt('Enter the sprint end date: ')
44
+ let non_working_days = prompt('Enter the number of non working days: ')
45
+ let developers = prompt('Enter the number of developers assigned: ')
46
+ let developer_pto_days = prompt('Enter the total number of developer PTO days: ')
47
+
48
+ let sprint = {
49
+ sprint_name,
50
+ project_id,
51
+ start_date,
52
+ end_date,
53
+ non_working_days,
54
+ developers,
55
+ developer_pto_days
56
+ }
57
+
58
+ // Save outcomes to DB
59
+ let result = await db.insert(database,'sprints',[sprint])
60
+ let sprintId = result[0].lastID
61
+
62
+ // Prompt for commitment
63
+ let sprintOutcomes = []
64
+ let outcomes = await db.query(database,`select * from outcomes where name = 'Commitment';`)
65
+ for (const outcome of outcomes) {
66
+ // TODO Fix output formatting
67
+ console.log(outcome.id, outcome.name, outcome.description)
68
+ let issue_count = prompt('Enter the number of stories or a blank line to skip: ')
69
+ if (issue_count == '' ) {
70
+ continue
71
+ }
72
+ let story_points = prompt('Enter the number of story points: ')
73
+ let notes = prompt('Enter any notes: ')
74
+
75
+ sprintOutcomes.push({
76
+ sprint_id: sprintId,
77
+ outcome_id: outcome.id,
78
+ issue_count,
79
+ story_points,
80
+ notes
81
+ })
82
+ }
83
+ // validate sprint_outcomes
84
+
85
+ console.log(sprintOutcomes)
86
+
87
+ // Save outcomes to DB
88
+ result = await db.insert(database,'sprint_outcomes',sprintOutcomes,['sprint_id','outcome_id'])
89
+ }
90
+
91
+ main()
92
+
93
+ function promptForInput(items,promptText) {
94
+ let id
95
+ for (const item of items) {
96
+ console.log(item.id, item.name)
97
+ }
98
+ while (!id) {
99
+ id = prompt(promptText)
100
+
101
+ // validate the response
102
+ if (!items.find(x => (x.id == id))) {
103
+ console.error('Invalid id')
104
+ id = null
105
+ }
106
+ }
107
+ return id
108
+ }