ado-git-repo-insights 3.3.0__tar.gz → 3.6.0__tar.gz

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 (189) hide show
  1. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.github/workflows/ci.yml +70 -2
  2. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.gitignore +1 -0
  3. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/CHANGELOG.md +40 -0
  4. ado_git_repo_insights-3.6.0/CONTRIBUTING.md +156 -0
  5. {ado_git_repo_insights-3.3.0/src/ado_git_repo_insights.egg-info → ado_git_repo_insights-3.6.0}/PKG-INFO +1 -1
  6. ado_git_repo_insights-3.6.0/VERSION +1 -0
  7. ado_git_repo_insights-3.6.0/docs/DASHBOARD-HARDENING-PLAN.md +280 -0
  8. ado_git_repo_insights-3.6.0/docs/PHASE7.md +160 -0
  9. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tasks/extract-prs/task.json +1 -1
  10. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/dashboard.test.js +418 -0
  11. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/dashboard.js +150 -4
  12. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/vss-extension.json +1 -1
  13. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/package-lock.json +2 -2
  14. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/package.json +1 -1
  15. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/pyproject.toml +3 -0
  16. ado_git_repo_insights-3.6.0/scripts/check-ui-bundle-sync.sh +80 -0
  17. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/cli.py +237 -0
  18. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/transform/aggregators.py +162 -10
  19. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/VSS.SDK.min.js +2 -0
  20. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/artifact-client.js +580 -0
  21. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/dashboard.js +2223 -0
  22. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/dataset-loader.js +783 -0
  23. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/error-codes.js +172 -0
  24. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/error-types.js +187 -0
  25. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/index.html +282 -0
  26. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/settings.html +84 -0
  27. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/settings.js +554 -0
  28. ado_git_repo_insights-3.6.0/src/ado_git_repo_insights/ui_bundle/styles.css +1477 -0
  29. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0/src/ado_git_repo_insights.egg-info}/PKG-INFO +1 -1
  30. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights.egg-info/SOURCES.txt +14 -3
  31. ado_git_repo_insights-3.6.0/tests/unit/test_aggregators.py +1244 -0
  32. ado_git_repo_insights-3.6.0/tests/unit/test_cli_args.py +99 -0
  33. ado_git_repo_insights-3.3.0/VERSION +0 -1
  34. ado_git_repo_insights-3.3.0/docs/PHASE5.md +0 -348
  35. ado_git_repo_insights-3.3.0/docs/PHASE6.md +0 -62
  36. ado_git_repo_insights-3.3.0/docs/phase5-contract-notes.md +0 -203
  37. ado_git_repo_insights-3.3.0/tests/unit/test_aggregators.py +0 -549
  38. ado_git_repo_insights-3.3.0/tests/unit/test_cli_args.py +0 -34
  39. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.editorconfig +0 -0
  40. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.gitattributes +0 -0
  41. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.github/scripts/check-baseline-integrity.js +0 -0
  42. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.github/scripts/validate-test-results.py +0 -0
  43. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.github/workflows/release.yml +0 -0
  44. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.gitleaks.toml +0 -0
  45. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.husky/pre-commit +0 -0
  46. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.husky/pre-push +0 -0
  47. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.pre-commit-config.yaml +0 -0
  48. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/.releaserc.json +0 -0
  49. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/LICENSE +0 -0
  50. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/MERMAID.md +0 -0
  51. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/README.md +0 -0
  52. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/agents/INVARIANTS.md +0 -0
  53. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/agents/definition-of-done.md +0 -0
  54. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/agents/victory-gates.md +0 -0
  55. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/config.example.yaml +0 -0
  56. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/DEFAULT-DASHBOARD-ENHANCEMENT-PLAN.md +0 -0
  57. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/ENABLE-ML-FEATURES.md +0 -0
  58. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/EXTENSION.md +0 -0
  59. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/INSTALLATION.md +0 -0
  60. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/MANUAL_WALKTHROUGH.md +0 -0
  61. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/SESSION.md +0 -0
  62. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/SUMMARY.md +0 -0
  63. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/ado-pipeline-smoke-check.md +0 -0
  64. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/dataset-contract.md +0 -0
  65. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/rollout-plan.md +0 -0
  66. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/docs/runbook.md +0 -0
  67. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/images/README.md +0 -0
  68. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/images/icon.png +0 -0
  69. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/images/icon.png.placeholder +0 -0
  70. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/jest.config.js +0 -0
  71. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/overview.md +0 -0
  72. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/package-lock.json +0 -0
  73. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/package.json +0 -0
  74. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/scripts/copy-vss-sdk.sh +0 -0
  75. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/scripts/update-perf-baseline.js +0 -0
  76. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tasks/extract-prs/index.js +0 -0
  77. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tasks/extract-prs/index.test.js +0 -0
  78. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tasks/extract-prs/package-lock.json +0 -0
  79. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tasks/extract-prs/package.json +0 -0
  80. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/test-output.txt +0 -0
  81. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/test-results.json +0 -0
  82. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/ado-sdk.test.js +0 -0
  83. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/api-patterns.test.js +0 -0
  84. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/auth-pattern.test.js +0 -0
  85. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/chunked-loading.test.js +0 -0
  86. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/cross-project-settings.test.js +0 -0
  87. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/dataset-loader.test.js +0 -0
  88. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/date-range-warning.test.js +0 -0
  89. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/error-codes.test.js +0 -0
  90. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/fixtures/aggregates/dimensions.json +0 -0
  91. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/fixtures/aggregates/weekly_rollups/2026-W02.json +0 -0
  92. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/fixtures/dataset-manifest.json +0 -0
  93. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/fixtures/insights/summary.json +0 -0
  94. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/fixtures/perf-baselines.json +0 -0
  95. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/fixtures/predictions/trends.json +0 -0
  96. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/fixtures.test.js +0 -0
  97. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/metrics.test.js +0 -0
  98. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/mocks/ado-sdk.js +0 -0
  99. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/performance.test.js +0 -0
  100. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/pipeline-artifact-url.test.js +0 -0
  101. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/production-issues.test.js +0 -0
  102. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/sdk-bundling.test.js +0 -0
  103. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/setup.js +0 -0
  104. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/tests/synthetic-fixtures.test.js +0 -0
  105. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/VSS.SDK.min.js +0 -0
  106. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/artifact-client.js +0 -0
  107. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/dataset-loader.js +0 -0
  108. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/error-codes.js +0 -0
  109. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/error-types.js +0 -0
  110. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/index.html +0 -0
  111. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/settings.html +0 -0
  112. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/settings.js +0 -0
  113. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension/ui/styles.css +0 -0
  114. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/extension-verification-test.yml +0 -0
  115. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/insights-verification-test.yml +0 -0
  116. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/pr-insights-pipeline.yml +0 -0
  117. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/sample-pipeline.yml +0 -0
  118. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/schemas/dataset-manifest.schema.json +0 -0
  119. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/schemas/insights.schema.json +0 -0
  120. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/schemas/predictions.schema.json +0 -0
  121. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/scripts/check-version-unchanged.sh +0 -0
  122. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/scripts/csv_diff.py +0 -0
  123. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/scripts/generate-synthetic-dataset.py +0 -0
  124. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/scripts/stamp-extension-version.js +0 -0
  125. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/scripts/validate-task-inputs.js +0 -0
  126. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/setup.cfg +0 -0
  127. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/__init__.py +0 -0
  128. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/config.py +0 -0
  129. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/extractor/__init__.py +0 -0
  130. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/extractor/ado_client.py +0 -0
  131. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/extractor/pr_extractor.py +0 -0
  132. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/ml/__init__.py +0 -0
  133. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/ml/date_utils.py +0 -0
  134. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/ml/forecaster.py +0 -0
  135. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/ml/insights.py +0 -0
  136. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/persistence/__init__.py +0 -0
  137. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/persistence/database.py +0 -0
  138. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/persistence/models.py +0 -0
  139. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/persistence/repository.py +0 -0
  140. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/transform/__init__.py +0 -0
  141. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/transform/csv_generator.py +0 -0
  142. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/utils/__init__.py +0 -0
  143. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/utils/datetime_utils.py +0 -0
  144. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/utils/logging_config.py +0 -0
  145. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights/utils/run_summary.py +0 -0
  146. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights.egg-info/dependency_links.txt +0 -0
  147. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights.egg-info/entry_points.txt +0 -0
  148. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights.egg-info/requires.txt +0 -0
  149. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/src/ado_git_repo_insights.egg-info/top_level.txt +0 -0
  150. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/__init__.py +0 -0
  151. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/fixtures/README.md +0 -0
  152. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/integration/__init__.py +0 -0
  153. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/integration/test_backfill_convergence.py +0 -0
  154. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/integration/test_db_open_failure.py +0 -0
  155. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/integration/test_golden_outputs.py +0 -0
  156. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/integration/test_incremental_run.py +0 -0
  157. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/integration/test_multi_project_scoping.py +0 -0
  158. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/integration/test_phase5_ml_integration.py +0 -0
  159. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/test_redaction.py +0 -0
  160. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/__init__.py +0 -0
  161. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_ado_client_pagination.py +0 -0
  162. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_artifacts_dir.py +0 -0
  163. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_chunk_selection.py +0 -0
  164. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_cli_exit_code.py +0 -0
  165. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_comments_cli.py +0 -0
  166. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_comments_extraction.py +0 -0
  167. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_completed_only.py +0 -0
  168. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_config_validation.py +0 -0
  169. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_csv_contract.py +0 -0
  170. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_csv_determinism.py +0 -0
  171. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_date_range_defaults.py +0 -0
  172. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_datetime_utils.py +0 -0
  173. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_forecaster_contract.py +0 -0
  174. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_insights_contract.py +0 -0
  175. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_insights_id_stability.py +0 -0
  176. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_insights_schema.py +0 -0
  177. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_logging_config.py +0 -0
  178. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_ml_cli_flags.py +0 -0
  179. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_monday_alignment.py +0 -0
  180. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_operational_summary.py +0 -0
  181. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_predictions_schema.py +0 -0
  182. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_retry_policy.py +0 -0
  183. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_run_summary.py +0 -0
  184. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_secret_redaction.py +0 -0
  185. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_summary_drift_guard.py +0 -0
  186. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_synthetic_dataset.py +0 -0
  187. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_team_extraction.py +0 -0
  188. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_upsert_keys.py +0 -0
  189. {ado_git_repo_insights-3.3.0 → ado_git_repo_insights-3.6.0}/tests/unit/test_version_validation.py +0 -0
@@ -95,6 +95,18 @@ jobs:
95
95
 
96
96
  echo "✓ No CRLF detected in Unix-executed files"
97
97
 
98
+ # Guard: Verify UI bundle is in sync with extension/ui
99
+ ui-bundle-sync:
100
+ runs-on: ubuntu-latest
101
+ steps:
102
+ - uses: actions/checkout@v4
103
+
104
+ - name: Check UI Bundle Synchronization
105
+ run: |
106
+ chmod +x scripts/check-ui-bundle-sync.sh
107
+ ./scripts/check-ui-bundle-sync.sh
108
+ shell: bash
109
+
98
110
  # Guard: Block task Major changes without explicit marker
99
111
  task-major-guard:
100
112
  runs-on: ubuntu-latest
@@ -218,7 +230,35 @@ jobs:
218
230
  - name: Validate Test Results (Python)
219
231
  if: always() && matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
220
232
  run: |
221
- # Robust test validation using JUnit XML parsing
233
+ # Two-phase validation for robust CI diagnostics
234
+ # Phase 1: Check if pytest produced output at all
235
+ if [ ! -f test-results.xml ]; then
236
+ echo "::error::test-results.xml not found - pytest likely failed to start"
237
+ echo ""
238
+ echo "================================================================================"
239
+ echo "DIAGNOSTIC: pytest did not produce JUnit XML output"
240
+ echo "================================================================================"
241
+ echo ""
242
+ echo "Common causes:"
243
+ echo " 1. Import error in test file or source code"
244
+ echo " 2. Syntax error in Python files"
245
+ echo " 3. Missing dependency"
246
+ echo " 4. Test collection failed"
247
+ echo ""
248
+ echo "Check the 'Run Tests with Coverage' step above for the actual error."
249
+ echo ""
250
+ if [ -f pytest_output.txt ]; then
251
+ echo "================================================================================"
252
+ echo "Last 50 lines of pytest output:"
253
+ echo "================================================================================"
254
+ tail -50 pytest_output.txt
255
+ fi
256
+ echo ""
257
+ echo "================================================================================"
258
+ exit 1
259
+ fi
260
+
261
+ # Phase 2: Validate test results using JUnit XML parsing
222
262
  # MIN_COLLECTED: Minimum expected tests (update when adding/removing tests)
223
263
  # MAX_SKIPS: Maximum allowed skipped tests (0 = no skips allowed in CI)
224
264
  python .github/scripts/validate-test-results.py \
@@ -384,7 +424,35 @@ jobs:
384
424
  - name: Validate Test Results (Extension)
385
425
  if: always()
386
426
  run: |
387
- # Robust test validation using JUnit XML parsing
427
+ # Two-phase validation for robust CI diagnostics
428
+ # Phase 1: Check if Jest produced output at all
429
+ if [ ! -f extension/test-results.xml ]; then
430
+ echo "::error::extension/test-results.xml not found - Jest likely failed to start"
431
+ echo ""
432
+ echo "================================================================================"
433
+ echo "DIAGNOSTIC: Jest did not produce JUnit XML output"
434
+ echo "================================================================================"
435
+ echo ""
436
+ echo "Common causes:"
437
+ echo " 1. Syntax error in test file or source code"
438
+ echo " 2. Missing npm dependency"
439
+ echo " 3. Jest configuration issue"
440
+ echo " 4. Test collection failed"
441
+ echo ""
442
+ echo "Check the 'Run Extension UI Tests' step above for the actual error."
443
+ echo ""
444
+ if [ -f extension/npm_test_output.txt ]; then
445
+ echo "================================================================================"
446
+ echo "Last 50 lines of Jest output:"
447
+ echo "================================================================================"
448
+ tail -50 extension/npm_test_output.txt
449
+ fi
450
+ echo ""
451
+ echo "================================================================================"
452
+ exit 1
453
+ fi
454
+
455
+ # Phase 2: Validate test results using JUnit XML parsing
388
456
  # MIN_COLLECTED: Minimum expected tests (update when adding/removing tests)
389
457
  # MAX_SKIPS: Maximum allowed skipped tests (0 = no skips allowed in CI)
390
458
  python .github/scripts/validate-test-results.py \
@@ -41,6 +41,7 @@ htmlcov/
41
41
  .cache
42
42
  nosetests.xml
43
43
  coverage.xml
44
+ test-results.xml
44
45
  *.cover
45
46
  *.py,cover
46
47
  .hypothesis/
@@ -1,3 +1,43 @@
1
+ # [3.6.0](https://github.com/oddessentials/ado-git-repo-insights/compare/v3.5.1...v3.6.0) (2026-01-19)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **ci:** add two-phase test validation for robust diagnostics ([ea1585a](https://github.com/oddessentials/ado-git-repo-insights/commit/ea1585ae173b8aa68640e6bc70036cf128e50b36))
7
+ * **tests:** add last_updated column to teams test fixtures ([f376e6f](https://github.com/oddessentials/ado-git-repo-insights/commit/f376e6f63fa2952f49bb45e6adacf0c483ebb792))
8
+
9
+
10
+ ### Features
11
+
12
+ * **aggregators:** implement by_team dimension slices (Phase 7.2) ([02c0728](https://github.com/oddessentials/ado-git-repo-insights/commit/02c07284a50c150c99fb5591a03da25771c484fd))
13
+ * **ci:** add UI bundle sync verification (Phase 7.1) ([0309a5b](https://github.com/oddessentials/ado-git-repo-insights/commit/0309a5b9ac36435f4679892555e04d544b8a3fd2))
14
+
15
+ ## [3.5.1](https://github.com/oddessentials/ado-git-repo-insights/compare/v3.5.0...v3.5.1) (2026-01-19)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * replace ui_bundle symlink with actual files for pip packaging ([6cb3504](https://github.com/oddessentials/ado-git-repo-insights/commit/6cb35048f21805e9cb28bbc47007faeb4eb0bc62))
21
+
22
+ # [3.5.0](https://github.com/oddessentials/ado-git-repo-insights/compare/v3.4.0...v3.5.0) (2026-01-19)
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * use relative symlink for ui_bundle (CI compatibility) ([2d27fcd](https://github.com/oddessentials/ado-git-repo-insights/commit/2d27fcd832b45ffc2f74282a9da2453b05d35a76))
28
+
29
+
30
+ ### Features
31
+
32
+ * **phase6:** add local dashboard and build-aggregates commands ([3233dcd](https://github.com/oddessentials/ado-git-repo-insights/commit/3233dcde7447ec48f71fa7c19b903ca1501e58be))
33
+
34
+ # [3.4.0](https://github.com/oddessentials/ado-git-repo-insights/compare/v3.3.0...v3.4.0) (2026-01-19)
35
+
36
+
37
+ ### Features
38
+
39
+ * **dashboard:** fix reviewer count bug and implement client-side filtering ([4f0526e](https://github.com/oddessentials/ado-git-repo-insights/commit/4f0526e62ae6ea18372ff7a0adb58fb9cd6b8fd5))
40
+
1
41
  # [3.3.0](https://github.com/oddessentials/ado-git-repo-insights/compare/v3.2.0...v3.3.0) (2026-01-18)
2
42
 
3
43
 
@@ -0,0 +1,156 @@
1
+ # Contributing to ADO Git Repo Insights
2
+
3
+ Thank you for your interest in contributing! This document covers the essential guidelines for contributing to this project.
4
+
5
+ ## Development Setup
6
+
7
+ 1. Clone the repository
8
+ 2. Install Python dependencies:
9
+ ```bash
10
+ pip install -e .[dev]
11
+ ```
12
+ 3. Install Node.js dependencies for extension development:
13
+ ```bash
14
+ cd extension && npm ci
15
+ ```
16
+ 4. Install pre-commit hooks:
17
+ ```bash
18
+ pip install pre-commit
19
+ pre-commit install
20
+ ```
21
+
22
+ ## Running Tests
23
+
24
+ ### Python Tests
25
+ ```bash
26
+ pytest
27
+ ```
28
+
29
+ ### Extension Tests
30
+ ```bash
31
+ cd extension && npm test
32
+ ```
33
+
34
+ ---
35
+
36
+ ## UI Bundle Synchronization (IMPORTANT)
37
+
38
+ The dashboard UI files exist in **two locations** that must stay synchronized:
39
+
40
+ | Location | Purpose |
41
+ |----------|---------|
42
+ | `extension/ui/` | Source of truth for Azure DevOps extension |
43
+ | `src/ado_git_repo_insights/ui_bundle/` | Copy for Python pip package |
44
+
45
+ ### Why Two Locations?
46
+
47
+ - **Symlinks don't work with pip packages**: When building Python wheels with setuptools, symlinks are not preserved. The wheel would contain broken symlinks instead of actual files.
48
+ - **The `ado-insights dashboard` command requires bundled UI files**: When users install via `pip install ado-git-repo-insights`, the UI files must be physically present in the package.
49
+
50
+ ### Synchronization Process
51
+
52
+ **After modifying any files in `extension/ui/`**, you must sync to `ui_bundle/`:
53
+
54
+ ```bash
55
+ cp -r extension/ui/* src/ado_git_repo_insights/ui_bundle/
56
+ ```
57
+
58
+ Then commit both locations together.
59
+
60
+ ### CI Enforcement
61
+
62
+ The `ui-bundle-sync` CI job automatically verifies synchronization on every PR. If the directories are out of sync, the job will fail and display:
63
+ - A patch-format diff showing the differences
64
+ - Instructions on how to fix the issue
65
+
66
+ ### Files Ignored During Sync Check
67
+
68
+ The following file patterns are ignored during synchronization checks:
69
+ - `*.map` (source maps)
70
+ - `.DS_Store` (macOS metadata)
71
+ - `*.swp`, `*~`, `*.bak` (editor backup files)
72
+
73
+ ---
74
+
75
+ ## Commit Message Format
76
+
77
+ This project uses [Conventional Commits](https://www.conventionalcommits.org/) for semantic versioning:
78
+
79
+ ```
80
+ <type>(<scope>): <description>
81
+
82
+ [optional body]
83
+
84
+ [optional footer(s)]
85
+ ```
86
+
87
+ ### Types
88
+ - `feat`: New feature (triggers minor version bump)
89
+ - `fix`: Bug fix (triggers patch version bump)
90
+ - `docs`: Documentation only
91
+ - `test`: Adding or updating tests
92
+ - `chore`: Maintenance tasks
93
+ - `refactor`: Code changes that neither fix bugs nor add features
94
+ - `perf`: Performance improvements
95
+ - `ci`: CI/CD changes
96
+
97
+ ### Breaking Changes
98
+
99
+ For breaking changes, add `BREAKING CHANGE:` in the commit body or append `!` after the type:
100
+
101
+ ```
102
+ feat(api)!: change response format
103
+
104
+ BREAKING CHANGE: The API now returns dates in ISO 8601 format.
105
+ ```
106
+
107
+ ### Task Version Changes
108
+
109
+ Changes to the Azure DevOps task Major version require special approval. Include `BREAKING TASK CHANGE:` in the PR title or commit message to acknowledge the breaking change.
110
+
111
+ ---
112
+
113
+ ## Pull Request Guidelines
114
+
115
+ 1. **Create a feature branch** from `main`
116
+ 2. **Write tests** for new functionality
117
+ 3. **Run the full test suite** before submitting
118
+ 4. **Keep PRs focused** - one feature or fix per PR
119
+ 5. **Update documentation** if behavior changes
120
+
121
+ ### CI Checks
122
+
123
+ All PRs must pass:
124
+ - Secret scanning (gitleaks)
125
+ - Line ending checks (no CRLF in Unix-executed files)
126
+ - UI bundle synchronization check
127
+ - Python tests (matrix: 3 OSes × 3 Python versions)
128
+ - Extension tests
129
+ - Pre-commit hooks (ruff, formatting)
130
+
131
+ ---
132
+
133
+ ## Architecture Notes
134
+
135
+ ### Dataset Contract
136
+
137
+ The dataset format is documented in `docs/dataset-contract.md`. Changes to the dataset schema require:
138
+ 1. Version bump in manifest
139
+ 2. Update to schema documentation
140
+ 3. Backward compatibility consideration
141
+
142
+ ### ML Features
143
+
144
+ ML features are optional and gated behind the `[ml]` extra:
145
+ ```bash
146
+ pip install ado-git-repo-insights[ml]
147
+ ```
148
+
149
+ The base package must function without ML dependencies. See `tests/unit/test_ml_cli_flags.py` for isolation tests.
150
+
151
+ ---
152
+
153
+ ## Questions?
154
+
155
+ - Check existing issues for similar questions
156
+ - Open a new issue with the `question` label
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ado-git-repo-insights
3
- Version: 3.3.0
3
+ Version: 3.6.0
4
4
  Summary: Extract Azure DevOps Pull Request metrics to SQLite and generate PowerBI-compatible CSVs.
5
5
  Author-email: "Odd Essentials, LLC" <admin@oddessentials.com>
6
6
  License: MIT
@@ -0,0 +1 @@
1
+ 3.6.0
@@ -0,0 +1,280 @@
1
+ # Dashboard Hardening & Enhancement Plan
2
+
3
+ This document outlines the implementation plan for hardening existing dashboard features, fixing bugs, and preparing for future enhancements.
4
+
5
+ ---
6
+
7
+ ## Executive Summary
8
+
9
+ ### Critical Issues Identified
10
+
11
+ 1. **Reviewer Activity Bug (P0)**: `reviewers_count` is hardcoded to `0` in `aggregators.py:501`
12
+ - Data exists in the `reviewers` table but is never counted
13
+ - UI correctly renders the value but always shows "0"
14
+
15
+ 2. **Filters Not Working (P0)**: Dimension filters are populated but never applied
16
+ - Filter dropdowns work (populated from `dimensions.json`)
17
+ - Filter state is tracked (`currentFilters` object)
18
+ - **Missing**: Client-side filtering logic in `refreshMetrics()`
19
+ - **Missing**: Pre-computed dimension slices in weekly rollups
20
+
21
+ 3. **Test Coverage Gaps (P1)**: No tests for filtering or reviewer aggregation
22
+
23
+ ---
24
+
25
+ ## Bug Analysis
26
+
27
+ ### Bug #1: Reviewer Count Always Zero
28
+
29
+ **Location**: `src/ado_git_repo_insights/transform/aggregators.py:501`
30
+
31
+ ```python
32
+ reviewers_count=0, # TODO: Add reviewer counting
33
+ ```
34
+
35
+ **Root Cause**: The weekly rollup generation never joins with the `reviewers` table.
36
+
37
+ **Fix Required**: Query unique reviewers per PR, then aggregate per week:
38
+ ```sql
39
+ SELECT COUNT(DISTINCT r.user_id) as reviewers_count
40
+ FROM reviewers r
41
+ JOIN pull_requests pr ON r.pull_request_uid = pr.pull_request_uid
42
+ WHERE pr.closed_date >= ? AND pr.closed_date <= ?
43
+ ```
44
+
45
+ **Test Data Verification**: The `reviewers` table schema exists and is validated:
46
+ - `database.py:117` validates `reviewers` table on connect
47
+ - Row counts are tracked in `_get_row_counts()` (line 665)
48
+
49
+ ---
50
+
51
+ ### Bug #2: Filters Not Applied
52
+
53
+ **Location**: `extension/ui/dashboard.js`
54
+
55
+ **Current Behavior**:
56
+ 1. `populateFilterDropdowns()` correctly loads dimensions (line 1522)
57
+ 2. `handleFilterChange()` updates `currentFilters` state (line 1560)
58
+ 3. `refreshMetrics()` loads data **ignoring filters** (line 809)
59
+
60
+ **Missing Logic**:
61
+ 1. **Client-side filtering**: After loading rollups, filter by selected repos/teams
62
+ 2. **Dimension-sliced data**: Aggregator should generate `by_repository` and `by_team` slices
63
+
64
+ **Test Fixture Shows Expected Format** (`2026-W02.json`):
65
+ ```json
66
+ {
67
+ "by_repository": {
68
+ "main-repo": { "pr_count": 22, "cycle_time_p50": 200.0 },
69
+ "secondary-repo": { "pr_count": 8, "cycle_time_p50": 360.0 }
70
+ },
71
+ "by_team": {
72
+ "Backend Team": { "pr_count": 18, "cycle_time_p50": 180.0 },
73
+ "Frontend Team": { "pr_count": 12, "cycle_time_p50": 300.0 }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Implementation Plan
81
+
82
+ ### Phase 1: Fix Reviewer Count Bug (P0)
83
+
84
+ **Tasks**:
85
+ 1. Modify `_generate_weekly_rollups()` in `aggregators.py`
86
+ 2. Add query to count distinct reviewers per week
87
+ 3. Add unit test for reviewer aggregation
88
+ 4. Verify in integration test
89
+
90
+ **SQL Query**:
91
+ ```sql
92
+ SELECT
93
+ strftime('%G-W%W', pr.closed_date) as week,
94
+ COUNT(DISTINCT r.user_id) as reviewers_count
95
+ FROM reviewers r
96
+ JOIN pull_requests pr ON r.pull_request_uid = pr.pull_request_uid
97
+ WHERE pr.closed_date IS NOT NULL AND pr.status = 'completed'
98
+ GROUP BY week
99
+ ```
100
+
101
+ **Estimated Effort**: 1-2 hours
102
+
103
+ ---
104
+
105
+ ### Phase 2: Implement Client-Side Filtering (P0)
106
+
107
+ **Tasks**:
108
+ 1. Add `filterRollups()` function to `dashboard.js`
109
+ 2. Modify `refreshMetrics()` to apply filters after loading
110
+ 3. Add dimension slicing to `aggregators.py` (optional for MVP)
111
+ 4. Add filter tests
112
+
113
+ **Implementation Approach** (MVP - Client-Side):
114
+ ```javascript
115
+ function filterRollups(rollups, filters) {
116
+ if (!filters.repos.length && !filters.teams.length) {
117
+ return rollups; // No filters, return all
118
+ }
119
+
120
+ // If rollups have by_repository/by_team slices, use those
121
+ // Otherwise, filter at aggregate level (less granular)
122
+ return rollups.map(rollup => {
123
+ let filtered = { ...rollup };
124
+ // Apply repo filter
125
+ if (filters.repos.length && rollup.by_repository) {
126
+ const repoData = filters.repos.map(r => rollup.by_repository[r]).filter(Boolean);
127
+ filtered.pr_count = repoData.reduce((sum, d) => sum + d.pr_count, 0);
128
+ // ... aggregate other metrics
129
+ }
130
+ return filtered;
131
+ });
132
+ }
133
+ ```
134
+
135
+ **Estimated Effort**: 2-3 hours
136
+
137
+ ---
138
+
139
+ ### Phase 3: Add Dimension-Sliced Data Generation (P1)
140
+
141
+ **Tasks**:
142
+ 1. Modify `_generate_weekly_rollups()` to include `by_repository` slices
143
+ 2. Add `by_team` slices (requires team membership join)
144
+ 3. Update test fixtures
145
+ 4. Add contract tests for new fields
146
+
147
+ **Query for Repository Slices**:
148
+ ```sql
149
+ SELECT
150
+ strftime('%G-W%W', pr.closed_date) as week,
151
+ r.repository_name,
152
+ COUNT(*) as pr_count,
153
+ PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY pr.cycle_time_minutes) as cycle_time_p50
154
+ FROM pull_requests pr
155
+ JOIN repositories r ON pr.repository_id = r.repository_id
156
+ WHERE pr.closed_date IS NOT NULL AND pr.status = 'completed'
157
+ GROUP BY week, r.repository_name
158
+ ```
159
+
160
+ **Estimated Effort**: 3-4 hours
161
+
162
+ ---
163
+
164
+ ### Phase 4: Enhanced Testing (P1)
165
+
166
+ **New Tests Required**:
167
+
168
+ 1. **Unit Test**: `test_aggregator_reviewer_count.py`
169
+ - Verify reviewers are counted per week
170
+ - Verify unique counting (no duplicates)
171
+
172
+ 2. **Unit Test**: `test_aggregator_dimension_slices.py`
173
+ - Verify `by_repository` slices generated
174
+ - Verify `by_team` slices generated
175
+
176
+ 3. **Integration Test**: `test_dashboard_filtering.js`
177
+ - Verify filter state updates URL
178
+ - Verify metrics change when filters applied
179
+ - Verify filter chips display
180
+
181
+ 4. **Contract Test**: `test_weekly_rollup_schema.py`
182
+ - Add schema validation for new fields
183
+ - Backward compatibility check
184
+
185
+ **Estimated Effort**: 2-3 hours
186
+
187
+ ---
188
+
189
+ ## Enhancement Ideas for Future Phases
190
+
191
+ ### Visual Enhancements
192
+
193
+ 1. **Interactive Chart Tooltips**: Already partially implemented, extend to all charts
194
+ 2. **Responsive Sparklines**: Already implemented, ensure consistent rendering
195
+ 3. **Loading States per Chart**: Show skeleton loaders during filter changes
196
+
197
+ ### Performance Optimizations
198
+
199
+ 1. **Lazy Loading Dimension Slices**: Only load repo/team data when filter selected
200
+ 2. **Caching Strategy**: Cache filtered results by filter combination
201
+ 3. **Virtual Scrolling**: For large dimension lists in filter dropdowns
202
+
203
+ ### Future Features (Phase 6+ Integration)
204
+
205
+ 1. **Local Dashboard Testing**:
206
+ - Download aggregates artifact from pipeline
207
+ - Serve locally for rapid iteration
208
+ - Validate compatibility between extension and local versions
209
+
210
+ 2. **Schema Compatibility Layer**:
211
+ ```javascript
212
+ // version-adapter.js
213
+ function adaptRollup(rollup, targetVersion) {
214
+ if (rollup.schema_version < targetVersion) {
215
+ // Add missing fields with defaults
216
+ return { ...rollup, by_repository: {}, by_team: {} };
217
+ }
218
+ return rollup;
219
+ }
220
+ ```
221
+
222
+ 3. **Dashboard Experimentation Framework**:
223
+ - A/B test new visualizations locally
224
+ - Validate with real data before deploying
225
+ - Share test configurations
226
+
227
+ ---
228
+
229
+ ## Success Criteria
230
+
231
+ After implementation:
232
+
233
+ - [ ] Reviewer Activity chart shows real data (not 0)
234
+ - [ ] Repository filter changes displayed metrics
235
+ - [ ] Team filter changes displayed metrics
236
+ - [ ] Filter combinations persist in URL
237
+ - [ ] All existing tests pass
238
+ - [ ] New tests cover filtering and reviewer aggregation
239
+ - [ ] No regressions in cycle time or throughput calculations
240
+
241
+ ---
242
+
243
+ ## Risk Assessment
244
+
245
+ | Risk | Impact | Mitigation |
246
+ |------|--------|------------|
247
+ | Breaking existing data contract | High | Add backward compat tests, version bump |
248
+ | Performance degradation with slices | Medium | Lazy load slices, cache aggressively |
249
+ | Filter state sync issues | Low | Use URL as source of truth |
250
+
251
+ ---
252
+
253
+ ## Appendix: Current Data Flow
254
+
255
+ ```
256
+ ┌─────────────────┐ ┌──────────────────┐ ┌────────────────┐
257
+ │ ADO API │ ──▶ │ SQLite Database │ ──▶ │ Aggregates │
258
+ │ (PRs, Reviewers)│ │ (pull_requests, │ │ (weekly_rollups│
259
+ │ │ │ reviewers) │ │ dimensions) │
260
+ └─────────────────┘ └──────────────────┘ └───────┬────────┘
261
+
262
+ ┌───────────────────────────────▼────────┐
263
+ │ Dashboard UI │
264
+ │ ┌─────────────┐ ┌─────────────────┐ │
265
+ │ │ Filters │ │ Metrics Display │ │
266
+ │ │ (NOT WORKING)│ │ (reviewers=0) │ │
267
+ │ └─────────────┘ └─────────────────┘ │
268
+ └────────────────────────────────────────┘
269
+ ```
270
+
271
+ **After Fix**:
272
+ ```
273
+ ┌────────────────────────────────────────┐
274
+ │ Dashboard UI │
275
+ │ ┌─────────────┐ ┌─────────────────┐ │
276
+ │ │ Filters │──│ Metrics Display │ │
277
+ │ │ (WORKING) │ │ (reviewers=N) │ │
278
+ │ └─────────────┘ └─────────────────┘ │
279
+ └────────────────────────────────────────┘
280
+ ```