kinemotion 0.48.0__tar.gz → 0.49.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.

Potentially problematic release.


This version of kinemotion might be problematic. Click here for more details.

Files changed (532) hide show
  1. kinemotion-0.49.0/.basic-memory/development/feature-request-system-configuration.md +97 -0
  2. kinemotion-0.49.0/.basic-memory/development/supabase-database-integration-setup.md +104 -0
  3. {kinemotion-0.48.0 → kinemotion-0.49.0}/CHANGELOG.md +18 -0
  4. {kinemotion-0.48.0 → kinemotion-0.49.0}/PKG-INFO +1 -1
  5. kinemotion-0.49.0/backend/src/kinemotion_backend/analysis_api.py +303 -0
  6. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/src/kinemotion_backend/app.py +66 -2
  7. kinemotion-0.49.0/backend/src/kinemotion_backend/database.py +298 -0
  8. kinemotion-0.49.0/backend/src/kinemotion_backend/models.py +108 -0
  9. kinemotion-0.49.0/backend/src/kinemotion_backend/types.py +5 -0
  10. kinemotion-0.49.0/backend/supabase-schema.sql +148 -0
  11. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/README.md +2 -0
  12. kinemotion-0.49.0/docs/development/feature-request-system.md +191 -0
  13. kinemotion-0.49.0/docs/development/feedback-system-setup.md +192 -0
  14. kinemotion-0.49.0/frontend/src/components/FeatureRequestButton.tsx +103 -0
  15. kinemotion-0.49.0/frontend/src/components/FeedbackForm.css +308 -0
  16. kinemotion-0.49.0/frontend/src/components/FeedbackForm.tsx +212 -0
  17. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/ResultsDisplay.tsx +190 -0
  18. kinemotion-0.49.0/frontend/src/config/links.ts +46 -0
  19. kinemotion-0.49.0/frontend/src/hooks/useDatabaseStatus.ts +62 -0
  20. kinemotion-0.49.0/frontend/src/test/setup.ts +21 -0
  21. kinemotion-0.49.0/frontend/src/vite-env.d.ts +35 -0
  22. {kinemotion-0.48.0 → kinemotion-0.49.0}/pyproject.toml +1 -1
  23. {kinemotion-0.48.0 → kinemotion-0.49.0}/sonar-project.properties +1 -1
  24. {kinemotion-0.48.0 → kinemotion-0.49.0}/uv.lock +1 -1
  25. kinemotion-0.48.0/frontend/src/test/setup.ts +0 -1
  26. kinemotion-0.48.0/frontend/src/vite-env.d.ts +0 -9
  27. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/README.md +0 -0
  28. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/api/api-reference-quick-commands.md +0 -0
  29. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/api/cloud-run-cpu-specifications-investigation.md +0 -0
  30. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/api/supabase-authentication-setup-guide.md +0 -0
  31. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/authentication/auth-provider-comparison-december-2025.md +0 -0
  32. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/authentication/auth-providers-comparison-december-2025.md +0 -0
  33. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/authentication/supabase-authentication-quick-start.md +0 -0
  34. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/authentication/supabase-authentication-setup-guide.md +0 -0
  35. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/authentication/supabase-authentication-technical-guide.md +0 -0
  36. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/authentication/supabase-google-oauth-setup-guide.md +0 -0
  37. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/authentication/supabase-production-setup-guide.md +0 -0
  38. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/authentication/supabase-quick-start-guide.md +0 -0
  39. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/biomechanics/camera-angle-empirical-validation-results-45-superior-for-media-pipe.md +0 -0
  40. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/biomechanics/camera-perspective-analysis-45deg-vs-lateral.md +0 -0
  41. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/biomechanics/cmj-landing-detection-window-validation.md +0 -0
  42. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/biomechanics/cmj-physiological-bounds-for-validation.md +0 -0
  43. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/biomechanics/cmj-validation-implementation-complete.md +0 -0
  44. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/biomechanics/drop-jump-vs-cmj-key-differences.md +0 -0
  45. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/biomechanics/technical-implementation-45deg-perspective-correction.md +0 -0
  46. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/codebase/codebase-architecture-overview.md +0 -0
  47. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/codebase/validation-architecture-visual-hierarchy-after-refactoring.md +0 -0
  48. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/codebase/validation-code-duplication-evidence.md +0 -0
  49. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/codebase/validation-module-architecture-analysis.md +0 -0
  50. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/codebase/validation-refactoring-complete-architecture-improvement.md +0 -0
  51. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/automated-deployment-setup-git-hub-actions-with-workload-identity-federation.md +0 -0
  52. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/backend-repository-split-migration-guide.md +0 -0
  53. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/backend-repository-split-step-by-step-execution-guide.md +0 -0
  54. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/cloud-run-security-least-privilege-service-account-setup.md +0 -0
  55. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/cors-and-memory-issues-production-debugging-guide.md +0 -0
  56. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/current-kinemotion-architecture-correct-deployment-setup.md +0 -0
  57. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/frontend-repository-split-migration-guide.md +0 -0
  58. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/frontend-repository-split-step-by-step-execution-guide.md +0 -0
  59. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/production-deployment-guide-vercel-google-cloud-run.md +0 -0
  60. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/quick-deployment-commands-vercel-and-cloud-run.md +0 -0
  61. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/deployment/vercel-monorepo-deployment-best-practice.md +0 -0
  62. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/athlete-pose3d-and-cross-platform-determinism-investigation-complete.md +0 -0
  63. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/athlete-pose3d-final-strategy-accuracy-and-robustness.md +0 -0
  64. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/athlete-pose3d-media-pipe-enhancement-plan.md +0 -0
  65. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/athlete-pose3d-phase-1-implementation-complete.md +0 -0
  66. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/backend-authentication-and-logging-status.md +0 -0
  67. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/backend-code-coverage-analysis.md +0 -0
  68. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/backend-code-duplication-analysis.md +0 -0
  69. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/backend-kinemotion-decoupling-strategy.md +0 -0
  70. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/backend-sonar-cloud-integration-status.md +0 -0
  71. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/basic-memory-naming-hook-analysis.md +0 -0
  72. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/ci-caching-issue-investigation-deep-squat-test-failure.md +0 -0
  73. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/ci-vs-local-test-failure-investigation.md +0 -0
  74. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/claude-code-hook-configuration.md +0 -0
  75. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/cmj-phase-detection-testing-gap-analysis.md +0 -0
  76. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/commit-review-r2-video-storage-migration-fe74d1f.md +0 -0
  77. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/comprehensive-timing-instrumentation.md +0 -0
  78. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/cross-platform-determinism-analysis-final-results.md +0 -0
  79. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/development-standards-quality-gates.md +0 -0
  80. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/drop-jump-detection-complete-fix-all-metrics-within-target.md +0 -0
  81. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/drop-jump-detection-failure-analysis-per-video-breakdown.md +0 -0
  82. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/drop-jump-fix-drop-start-successful-landing-and-takeoff-remain.md +0 -0
  83. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/follow-up-improvements-to-r2-video-storage-migration.md +0 -0
  84. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/frontend-dependencies-analysis-nov-2025.md +0 -0
  85. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/google-oauth-setup-script-final-review-production-ready.md +0 -0
  86. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/google-oauth-setup-script-review-issues-and-recommendations.md +0 -0
  87. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/hook-complete-audit-summary.md +0 -0
  88. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/hook-configuration-audit.md +0 -0
  89. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/hook-quick-reference.md +0 -0
  90. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/keyboard-interrupt-test-suite-failure-analysis.md +0 -0
  91. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/non-deterministic-analysis-root-cause-and-solution.md +0 -0
  92. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/optimal-timing-implementation-summary.md +0 -0
  93. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/p0-p1-p2-test-suite-fixes-final-report.md +0 -0
  94. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/pose-detection-baseline-evaluation-results.md +0 -0
  95. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/pose-detection-optimization-complete-success-summary.md +0 -0
  96. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/pose-detection-parameter-optimization-framework.md +0 -0
  97. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/structured-logging-implementation-complete.md +0 -0
  98. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/structured-logging-implementation.md +0 -0
  99. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/supabase-dashboard-navigation-december-2025.md +0 -0
  100. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/test-coverage-asymmetry-analysis-cmj-vs-drop-jump.md +0 -0
  101. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/test-coverage-equivalence-achievement-summary.md +0 -0
  102. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/test-suite-comprehensive-review-december-2025.md +0 -0
  103. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/test-suite-comprehensive-review-structure-and-gaps.md +0 -0
  104. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-complete-report.md +0 -0
  105. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-progress-report.md +0 -0
  106. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/unused-and-experimental-features-strategy.md +0 -0
  107. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/unused-code-detection-prompt-template.md +0 -0
  108. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/unused-code-identification-and-decorator-application-december-2025.md +0 -0
  109. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/unused-code-verification-final-pass-december-2025.md +0 -0
  110. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/using-multiple-mcp-reasoning-servers-simultaneously.md +0 -0
  111. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/velocity-threshold-empirical-validation-study.md +0 -0
  112. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/development/vercel-authentication-options-for-user-id-tracking.md +0 -0
  113. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/documentation-audit-december-2025.md +0 -0
  114. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/issue-12-mvp-scaffolding-complete.md +0 -0
  115. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/issue-12-unblocked-tasks-breakdown.md +0 -0
  116. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/issue-12-use-real-metrics-now.md +0 -0
  117. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/kinemotion-project-setup-complete.md +0 -0
  118. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/kinemotion-supabase-production-configuration.md +0 -0
  119. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/mcp-sequential-thinking-alternatives-analysis.md +0 -0
  120. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/performance-optimization-pose-tracker-pool-timing-instrumentation-complete.md +0 -0
  121. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/project-state-summary-december-2025.md +0 -0
  122. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/specialized-subagents-routing-guide.md +0 -0
  123. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/supabase-setup-instructions-for-kinemotion.md +0 -0
  124. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/project-management/version-mismatch-analysis-kinemotion-0370-vs-0300.md +0 -0
  125. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/strategy/deployment-decision-analysis-for-kinemotion.md +0 -0
  126. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/strategy/mvp-feedback-collection-plan.md +0 -0
  127. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/strategy/mvp-first-strategic-direction.md +0 -0
  128. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/strategy/mvp-validation-checkpoints.md +0 -0
  129. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/strategy/pose2sim-migration-evaluation-and-strategy.md +0 -0
  130. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/strategy/strategic-priority-tasks-current-roadmap.md +0 -0
  131. {kinemotion-0.48.0 → kinemotion-0.49.0}/.basic-memory/strategy/third-party-auth-providers-with-free-tiers-december-2025.md +0 -0
  132. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/agents/biomechanics-specialist.md +0 -0
  133. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/agents/computer-vision-engineer.md +0 -0
  134. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/agents/devops-cicd-engineer.md +0 -0
  135. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/agents/frontend-developer.md +0 -0
  136. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/agents/ml-data-scientist.md +0 -0
  137. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/agents/project-manager.md +0 -0
  138. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/agents/python-backend-developer.md +0 -0
  139. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/agents/qa-test-engineer.md +0 -0
  140. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/agents/technical-writer.md +0 -0
  141. {kinemotion-0.48.0 → kinemotion-0.49.0}/.claude/settings.local.json +0 -0
  142. {kinemotion-0.48.0 → kinemotion-0.49.0}/.cursor/mcp.json +0 -0
  143. {kinemotion-0.48.0 → kinemotion-0.49.0}/.dockerignore +0 -0
  144. {kinemotion-0.48.0 → kinemotion-0.49.0}/.envrc +0 -0
  145. {kinemotion-0.48.0 → kinemotion-0.49.0}/.gitattributes +0 -0
  146. {kinemotion-0.48.0 → kinemotion-0.49.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  147. {kinemotion-0.48.0 → kinemotion-0.49.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  148. {kinemotion-0.48.0 → kinemotion-0.49.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  149. {kinemotion-0.48.0 → kinemotion-0.49.0}/.github/dependabot.yml +0 -0
  150. {kinemotion-0.48.0 → kinemotion-0.49.0}/.github/pull_request_template.md +0 -0
  151. {kinemotion-0.48.0 → kinemotion-0.49.0}/.github/workflows/deploy-backend.yml +0 -0
  152. {kinemotion-0.48.0 → kinemotion-0.49.0}/.github/workflows/docs.yml +0 -0
  153. {kinemotion-0.48.0 → kinemotion-0.49.0}/.github/workflows/release.yml +0 -0
  154. {kinemotion-0.48.0 → kinemotion-0.49.0}/.github/workflows/test.yml +0 -0
  155. {kinemotion-0.48.0 → kinemotion-0.49.0}/.gitignore +0 -0
  156. {kinemotion-0.48.0 → kinemotion-0.49.0}/.mcp.json +0 -0
  157. {kinemotion-0.48.0 → kinemotion-0.49.0}/.pre-commit-config.yaml +0 -0
  158. {kinemotion-0.48.0 → kinemotion-0.49.0}/.readthedocs.yml +0 -0
  159. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/.gitignore +0 -0
  160. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/backend-cors-fastapi-middleware-order.md +0 -0
  161. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/camera-perspective-validation-study.md +0 -0
  162. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/code_style_and_conventions.md +0 -0
  163. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/current-project-architecture.md +0 -0
  164. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/deployment-checklist-and-known-issues.md +0 -0
  165. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/deployment-setup-complete.md +0 -0
  166. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/github-project-setup-summary.md +0 -0
  167. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/mvp-first-strategy.md +0 -0
  168. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/mvp-roadmap-and-priorities.md +0 -0
  169. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/project_overview.md +0 -0
  170. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/specialist-agents-routing.md +0 -0
  171. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/memories/suggested_commands.md +0 -0
  172. {kinemotion-0.48.0 → kinemotion-0.49.0}/.serena/project.yml +0 -0
  173. {kinemotion-0.48.0 → kinemotion-0.49.0}/.tool-versions +0 -0
  174. {kinemotion-0.48.0 → kinemotion-0.49.0}/.vercelignore +0 -0
  175. {kinemotion-0.48.0 → kinemotion-0.49.0}/CLAUDE.md +0 -0
  176. {kinemotion-0.48.0 → kinemotion-0.49.0}/CODE_OF_CONDUCT.md +0 -0
  177. {kinemotion-0.48.0 → kinemotion-0.49.0}/CONTRIBUTING.md +0 -0
  178. {kinemotion-0.48.0 → kinemotion-0.49.0}/Dockerfile +0 -0
  179. {kinemotion-0.48.0 → kinemotion-0.49.0}/GEMINI.md +0 -0
  180. {kinemotion-0.48.0 → kinemotion-0.49.0}/LICENSE +0 -0
  181. {kinemotion-0.48.0 → kinemotion-0.49.0}/README.md +0 -0
  182. {kinemotion-0.48.0 → kinemotion-0.49.0}/SECURITY.md +0 -0
  183. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/.dockerignore +0 -0
  184. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/.env.example +0 -0
  185. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/Dockerfile +0 -0
  186. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/README.md +0 -0
  187. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/docs/fly-deployment.md +0 -0
  188. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/docs/implementation-summary.md +0 -0
  189. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/docs/setup.md +0 -0
  190. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/docs/tests.md +0 -0
  191. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/pyproject.toml +0 -0
  192. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/src/kinemotion_backend/__init__.py +0 -0
  193. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/src/kinemotion_backend/auth.py +0 -0
  194. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/src/kinemotion_backend/logging_config.py +0 -0
  195. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/src/kinemotion_backend/middleware.py +0 -0
  196. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/tests/README.md +0 -0
  197. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/tests/__init__.py +0 -0
  198. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/tests/conftest.py +0 -0
  199. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/tests/test_api_endpoints.py +0 -0
  200. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/tests/test_error_handling.py +0 -0
  201. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/tests/test_health.py +0 -0
  202. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/tests/test_r2_integration.py +0 -0
  203. {kinemotion-0.48.0 → kinemotion-0.49.0}/backend/tests/test_validation.py +0 -0
  204. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/api/cmj.md +0 -0
  205. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/api/core.md +0 -0
  206. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/api/dropjump.md +0 -0
  207. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/api/overview.md +0 -0
  208. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/development/agents-guide.md +0 -0
  209. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/development/errors-findings.md +0 -0
  210. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/development/test-suite-review-december-2025.md +0 -0
  211. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/development/testing-standards.md +0 -0
  212. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/development/testing.md +0 -0
  213. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/development/type-hints.md +0 -0
  214. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/development/validation-plan.md +0 -0
  215. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/development/validation-roadmap.md +0 -0
  216. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/development/wallball-norep-detection.md +0 -0
  217. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/guides/bulk-processing.md +0 -0
  218. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/guides/camera-setup.md +0 -0
  219. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/guides/cloud-run-deployment.md +0 -0
  220. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/guides/cmj-guide.md +0 -0
  221. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/guides/cmj-recording-protocol-es.md +0 -0
  222. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/guides/cmj-recording-protocol.md +0 -0
  223. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/guides/deployment-checklist.md +0 -0
  224. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/guides/local-testing.md +0 -0
  225. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/guides/setup-issue-12.md +0 -0
  226. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/index.md +0 -0
  227. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/quick-start.md +0 -0
  228. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/reference/cloud-run-quick-reference.md +0 -0
  229. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/reference/json-output-format.md +0 -0
  230. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/reference/json-structure-comparison.md +0 -0
  231. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/reference/parameters.md +0 -0
  232. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/reference/pose-systems.md +0 -0
  233. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/paper-downloader/HOW-TO-FIND-DOIS.md +0 -0
  234. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/paper-downloader/README.md +0 -0
  235. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/paper-downloader/dois.txt +0 -0
  236. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/paper-downloader/download.py +0 -0
  237. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/paper-downloader/pyproject.toml +0 -0
  238. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/paper-downloader/uv.lock +0 -0
  239. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/sports-biomechanics-pose-estimation.md +0 -0
  240. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/MANUAL-DOWNLOAD-GUIDE.md +0 -0
  241. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/README.md +0 -0
  242. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/convert_pdfs.py +0 -0
  243. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.md +0 -0
  244. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.md +0 -0
  245. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.md +0 -0
  246. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.md +0 -0
  247. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Ward_Putting-i-in-Team.md +0 -0
  248. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.md +0 -0
  249. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.md +0 -0
  250. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.md +0 -0
  251. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.md +0 -0
  252. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.md +0 -0
  253. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.md +0 -0
  254. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.md +0 -0
  255. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.md +0 -0
  256. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.md +0 -0
  257. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.md +0 -0
  258. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.md +0 -0
  259. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.md +0 -0
  260. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.md +0 -0
  261. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/jump-performance/2011_Harper_10-to-5-Jump-Test.md +0 -0
  262. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.md +0 -0
  263. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/jump-performance/2014_Samozino_FV-Imbalance.md +0 -0
  264. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.md +0 -0
  265. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.md +0 -0
  266. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.md +0 -0
  267. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/jump-performance/2022_Wells_Golf-Clubhead-CMJ.md +0 -0
  268. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.md +0 -0
  269. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.md +0 -0
  270. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.md +0 -0
  271. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Moore_Economical-Running-Technique.md +0 -0
  272. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.md +0 -0
  273. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.md +0 -0
  274. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.md +0 -0
  275. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.md +0 -0
  276. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.md +0 -0
  277. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/smartphone-technology/2022_Bishop_MyJumpLab-Validation.md +0 -0
  278. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.md +0 -0
  279. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.md +0 -0
  280. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.md +0 -0
  281. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.md +0 -0
  282. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.md +0 -0
  283. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/markdown/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.md +0 -0
  284. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/online-references-for-papers.md +0 -0
  285. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.pdf +0 -0
  286. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.pdf +0 -0
  287. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.pdf +0 -0
  288. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.pdf +0 -0
  289. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Ward_Putting-i-in-Team.pdf +0 -0
  290. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.pdf +0 -0
  291. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.pdf +0 -0
  292. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.pdf +0 -0
  293. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.pdf +0 -0
  294. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.pdf +0 -0
  295. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.pdf +0 -0
  296. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.pdf +0 -0
  297. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.pdf +0 -0
  298. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.pdf +0 -0
  299. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.pdf +0 -0
  300. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.pdf +0 -0
  301. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.pdf +0 -0
  302. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.pdf +0 -0
  303. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/jump-performance/2011_Harper_10-to-5-Jump-Test.pdf +0 -0
  304. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.pdf +0 -0
  305. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/jump-performance/2014_Samozino_FV-Imbalance.pdf +0 -0
  306. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.pdf +0 -0
  307. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.pdf +0 -0
  308. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.pdf +0 -0
  309. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/jump-performance/2022_Wells_Golf-Clubhead-CMJ.pdf +0 -0
  310. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.pdf +0 -0
  311. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.pdf +0 -0
  312. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.pdf +0 -0
  313. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Moore_Economical-Running-Technique.pdf +0 -0
  314. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.pdf +0 -0
  315. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.pdf +0 -0
  316. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.pdf +0 -0
  317. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.pdf +0 -0
  318. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.pdf +0 -0
  319. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/smartphone-technology/2022_Bishop_MyJumpLab-Validation.pdf +0 -0
  320. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.pdf +0 -0
  321. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.pdf +0 -0
  322. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.pdf +0 -0
  323. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.pdf +0 -0
  324. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.pdf +0 -0
  325. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/research/thirdparty/pdfs/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.pdf +0 -0
  326. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/1-STRATEGIC_SUMMARY.md +0 -0
  327. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/2-STRATEGIC_ANALYSIS.md +0 -0
  328. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/MVP_FEEDBACK_COLLECTION.md +0 -0
  329. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/MVP_VALIDATION_CHECKPOINTS.md +0 -0
  330. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/README.md +0 -0
  331. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/STYLE_GUIDE.md +0 -0
  332. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/01-executive-summary.md +0 -0
  333. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/02-technical-assessment.md +0 -0
  334. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/03-refactoring-roadmap.md +0 -0
  335. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/README.md +0 -0
  336. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/BIOMECHANICS/01-executive-summary.md +0 -0
  337. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/BIOMECHANICS/02-technical-assessment.md +0 -0
  338. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/BIOMECHANICS/03-reference-guide.md +0 -0
  339. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/BIOMECHANICS/README.md +0 -0
  340. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/COMPUTER_VISION/01-executive-summary.md +0 -0
  341. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/COMPUTER_VISION/02-real-time-architecture.md +0 -0
  342. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/COMPUTER_VISION/03-implementation-checklist.md +0 -0
  343. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/COMPUTER_VISION/README.md +0 -0
  344. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/CONSOLIDATED/01-agent-consensus.md +0 -0
  345. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/CONSOLIDATED/02-critical-findings.md +0 -0
  346. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/CONSOLIDATED/03-roadmap-adjustments.md +0 -0
  347. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/CONSOLIDATED/04-decision-points.md +0 -0
  348. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/CONSOLIDATED/README.md +0 -0
  349. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/CONSOLIDATED/risk-register.md +0 -0
  350. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/CONSOLIDATED/timeline-roadmap.md +0 -0
  351. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/01-executive-summary.md +0 -0
  352. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/02-infrastructure-assessment.md +0 -0
  353. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/03-implementation-roadmap.md +0 -0
  354. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/README.md +0 -0
  355. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/01-executive-summary.md +0 -0
  356. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/02-technical-assessment.md +0 -0
  357. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/03-parameter-specifications.md +0 -0
  358. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/README.md +0 -0
  359. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/QA_TESTING/01-executive-summary.md +0 -0
  360. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/QA_TESTING/02-roadmap-assessment.md +0 -0
  361. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/QA_TESTING/03-testing-checklists.md +0 -0
  362. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/QA_TESTING/README.md +0 -0
  363. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/01-executive-summary.md +0 -0
  364. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/02-documentation-strategy.md +0 -0
  365. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/03-action-plan.md +0 -0
  366. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/README.md +0 -0
  367. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/strategy/pose2sim-migration-evaluation.md +0 -0
  368. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/technical/framerate.md +0 -0
  369. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/technical/implementation-details.md +0 -0
  370. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/technical/imu-metadata.md +0 -0
  371. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/technical/real-time-analysis.md +0 -0
  372. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/technical/triple-extension.md +0 -0
  373. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/translations/es/camera-setup.md +0 -0
  374. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/validation/determinism-test.md +0 -0
  375. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/validation/known-height-validation.md +0 -0
  376. {kinemotion-0.48.0 → kinemotion-0.49.0}/docs/validation-status.md +0 -0
  377. {kinemotion-0.48.0 → kinemotion-0.49.0}/examples/bulk/README.md +0 -0
  378. {kinemotion-0.48.0 → kinemotion-0.49.0}/examples/bulk/bulk_processing.py +0 -0
  379. {kinemotion-0.48.0 → kinemotion-0.49.0}/examples/bulk/simple_example.py +0 -0
  380. {kinemotion-0.48.0 → kinemotion-0.49.0}/examples/programmatic_usage.py +0 -0
  381. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/.editorconfig +0 -0
  382. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/.env.example +0 -0
  383. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/.gitattributes +0 -0
  384. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/.gitignore +0 -0
  385. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/.yarn/releases/yarn-4.12.0.cjs +0 -0
  386. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/.yarnrc.yml +0 -0
  387. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/README.md +0 -0
  388. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/index.html +0 -0
  389. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/package.json +0 -0
  390. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/App.test.tsx +0 -0
  391. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/App.tsx +0 -0
  392. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/Auth.tsx +0 -0
  393. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/ErrorBoundary.tsx +0 -0
  394. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/ErrorDisplay.tsx +0 -0
  395. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/LoadingSpinner.tsx +0 -0
  396. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/RecentUploads.tsx +0 -0
  397. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/ResultsDisplay.test.tsx +0 -0
  398. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/ResultsSkeleton.tsx +0 -0
  399. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/UploadForm.test.tsx +0 -0
  400. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/components/UploadForm.tsx +0 -0
  401. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/hooks/useAnalysis.test.ts +0 -0
  402. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/hooks/useAnalysis.ts +0 -0
  403. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/hooks/useAuth.ts +0 -0
  404. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/hooks/useBackendVersion.ts +0 -0
  405. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/hooks/useRecentUploads.ts +0 -0
  406. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/index.css +0 -0
  407. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/lib/supabase.ts +0 -0
  408. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/main.tsx +0 -0
  409. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/src/types/api.ts +0 -0
  410. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/vercel.json +0 -0
  411. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/vite.config.ts +0 -0
  412. {kinemotion-0.48.0 → kinemotion-0.49.0}/frontend/yarn.lock +0 -0
  413. {kinemotion-0.48.0 → kinemotion-0.49.0}/justfile +0 -0
  414. {kinemotion-0.48.0 → kinemotion-0.49.0}/local_dev.sh +0 -0
  415. {kinemotion-0.48.0 → kinemotion-0.49.0}/mkdocs.yml +0 -0
  416. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/.gitignore +0 -0
  417. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/README.md +0 -0
  418. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/demos/.gitignore +0 -0
  419. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/demos/README.md +0 -0
  420. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/demos/api_demo.ipynb +0 -0
  421. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/demos/batch_processing_demo.py +0 -0
  422. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/demos/sample_data/.gitkeep +0 -0
  423. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/presentation_guide.md +0 -0
  424. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/revealjs/.gitignore +0 -0
  425. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/revealjs/Makefile +0 -0
  426. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/revealjs/README.md +0 -0
  427. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/revealjs/slides.md +0 -0
  428. {kinemotion-0.48.0 → kinemotion-0.49.0}/presentation/speaker_script.md +0 -0
  429. {kinemotion-0.48.0 → kinemotion-0.49.0}/requirements-docs.txt +0 -0
  430. {kinemotion-0.48.0 → kinemotion-0.49.0}/samples/cmjs/README.md +0 -0
  431. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/README.md +0 -0
  432. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/SCRIPTS_QUICKREF.md +0 -0
  433. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/analyze_determinism_variance.py +0 -0
  434. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/basic-memory-utils.sh +0 -0
  435. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/debug_contact_states.py +0 -0
  436. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/debug_detection.py +0 -0
  437. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/find_unused_features.py +0 -0
  438. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/generate_test_data.py +0 -0
  439. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/optimize_detection_params.py +0 -0
  440. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/plot_cmj_velocities.py +0 -0
  441. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/plot_validation_results.py +0 -0
  442. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/plot_velocities.py +0 -0
  443. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/prepare_ground_truth.py +0 -0
  444. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/project/README.md +0 -0
  445. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/project/add-issue.sh +0 -0
  446. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/project/batch-set-fields.sh +0 -0
  447. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/project/helpers.sh +0 -0
  448. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/project/list.sh +0 -0
  449. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/project/set-field.sh +0 -0
  450. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/project/set-status.sh +0 -0
  451. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/project/summary.sh +0 -0
  452. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/project.sh +0 -0
  453. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/setup-github-deploy.sh +0 -0
  454. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/setup-google-oauth.sh +0 -0
  455. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/setup-supabase-local.sh +0 -0
  456. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/setup-supabase-production.sh +0 -0
  457. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/test_acceleration_standing.py +0 -0
  458. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/test_determinism.sh +0 -0
  459. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/test_drop_start_debug.py +0 -0
  460. {kinemotion-0.48.0 → kinemotion-0.49.0}/scripts/validate_known_heights.py +0 -0
  461. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/__init__.py +0 -0
  462. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/api.py +0 -0
  463. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cli.py +0 -0
  464. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cmj/__init__.py +0 -0
  465. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cmj/analysis.py +0 -0
  466. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cmj/api.py +0 -0
  467. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cmj/cli.py +0 -0
  468. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cmj/debug_overlay.py +0 -0
  469. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cmj/joint_angles.py +0 -0
  470. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cmj/kinematics.py +0 -0
  471. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cmj/metrics_validator.py +0 -0
  472. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/cmj/validation_bounds.py +0 -0
  473. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/__init__.py +0 -0
  474. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/auto_tuning.py +0 -0
  475. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/cli_utils.py +0 -0
  476. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/debug_overlay_utils.py +0 -0
  477. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/determinism.py +0 -0
  478. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/experimental.py +0 -0
  479. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/filtering.py +0 -0
  480. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/formatting.py +0 -0
  481. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/metadata.py +0 -0
  482. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/pipeline_utils.py +0 -0
  483. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/pose.py +0 -0
  484. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/quality.py +0 -0
  485. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/smoothing.py +0 -0
  486. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/timing.py +0 -0
  487. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/validation.py +0 -0
  488. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/core/video_io.py +0 -0
  489. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/dropjump/__init__.py +0 -0
  490. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/dropjump/analysis.py +0 -0
  491. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/dropjump/api.py +0 -0
  492. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/dropjump/cli.py +0 -0
  493. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/dropjump/debug_overlay.py +0 -0
  494. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/dropjump/kinematics.py +0 -0
  495. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/dropjump/metrics_validator.py +0 -0
  496. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/dropjump/validation_bounds.py +0 -0
  497. {kinemotion-0.48.0 → kinemotion-0.49.0}/src/kinemotion/py.typed +0 -0
  498. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/__init__.py +0 -0
  499. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cli/__init__.py +0 -0
  500. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cli/test_cmj.py +0 -0
  501. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cli/test_dropjump.py +0 -0
  502. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cli/test_imports.py +0 -0
  503. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cmj/__init__.py +0 -0
  504. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cmj/test_analysis.py +0 -0
  505. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cmj/test_api.py +0 -0
  506. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cmj/test_cli.py +0 -0
  507. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cmj/test_joint_angles.py +0 -0
  508. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cmj/test_kinematics.py +0 -0
  509. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/cmj/test_physiological_bounds.py +0 -0
  510. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/conftest.py +0 -0
  511. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/__init__.py +0 -0
  512. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_auto_tuning.py +0 -0
  513. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_cli_utils.py +0 -0
  514. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_filtering.py +0 -0
  515. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_formatting.py +0 -0
  516. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_metadata.py +0 -0
  517. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_pipeline_utils.py +0 -0
  518. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_pose.py +0 -0
  519. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_quality.py +0 -0
  520. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_smoothing.py +0 -0
  521. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_timing.py +0 -0
  522. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_validation.py +0 -0
  523. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/core/test_video_io.py +0 -0
  524. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/dropjump/__init__.py +0 -0
  525. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/dropjump/test_adaptive_threshold.py +0 -0
  526. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/dropjump/test_analysis.py +0 -0
  527. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/dropjump/test_api.py +0 -0
  528. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/dropjump/test_cli.py +0 -0
  529. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/dropjump/test_contact_detection.py +0 -0
  530. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/dropjump/test_kinematics.py +0 -0
  531. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/dropjump/test_physiological_bounds.py +0 -0
  532. {kinemotion-0.48.0 → kinemotion-0.49.0}/tests/dropjump/test_validation_integration.py +0 -0
@@ -0,0 +1,97 @@
1
+ ---
2
+ title: Feature Request System Configuration
3
+ type: note
4
+ permalink: development/feature-request-system-configuration
5
+ ---
6
+
7
+ # Feature Request & Feedback System Configuration
8
+
9
+ ## Frontend Configuration
10
+
11
+ ### External Links Setup
12
+ Edit `frontend/src/config/links.ts`:
13
+
14
+ ```typescript
15
+ export const EXTERNAL_LINKS = {
16
+ // Replace with actual Google Forms URL
17
+ FEATURE_REQUEST: 'https://docs.google.com/forms/d/e/YOUR_FORM_ID/viewform',
18
+ GITHUB_ISSUES: 'https://github.com/feniix/kinemotion/issues',
19
+ DOCUMENTATION: 'https://github.com/feniix/kinemotion#readme',
20
+ } as const
21
+
22
+ export const UI_CONFIG = {
23
+ FEATURE_REQUEST: {
24
+ enabled: true,
25
+ buttonText: 'Request Feature',
26
+ buttonIcon: '💡',
27
+ tooltip: 'Share your ideas and suggestions for improving Kinemotion',
28
+ openInNewTab: true,
29
+ },
30
+ } as const
31
+ ```
32
+
33
+ ### Google Forms Setup
34
+
35
+ 1. Create form at [Google Forms](https://forms.google.com)
36
+ 2. Include fields:
37
+ - Feature category (Analysis, UI, Performance, etc.)
38
+ - Feature description
39
+ - Use case/priority
40
+ - Additional comments
41
+ 3. Get form URL and update FEATURE_REQUEST constant
42
+
43
+ ## Component Usage
44
+
45
+ ### FeatureRequestButton Props
46
+ ```typescript
47
+ <FeatureRequestButton
48
+ variant="primary" // or "secondary"
49
+ size="medium" // "small", "medium", "large"
50
+ showIcon={true}
51
+ className="custom-class"
52
+ />
53
+ ```
54
+
55
+ ### Button Styles
56
+ - **Primary**: Blue background (`#6366f1`), white text
57
+ - **Secondary**: Light gray background (`#f3f4f6`), dark text
58
+ - **Sizes**: Small (0.75rem font), Medium (0.875rem), Large (1rem font)
59
+
60
+ ## Database Detection
61
+
62
+ The frontend automatically detects backend database connectivity:
63
+
64
+ ```typescript
65
+ const { status: dbStatus, loading: dbLoading } = useDatabaseStatus()
66
+
67
+ // Conditional UI rendering
68
+ {dbStatus?.database_connected && (
69
+ <button>Add Coach Feedback</button>
70
+ )}
71
+
72
+ {!dbStatus?.database_connected && (
73
+ <span>Database Offline - Feedback Unavailable</span>
74
+ )}
75
+ ```
76
+
77
+ ## Files Created
78
+ - `frontend/src/components/FeatureRequestButton.tsx`
79
+ - `frontend/src/components/FeedbackForm.tsx`
80
+ - `frontend/src/hooks/useDatabaseStatus.ts`
81
+ - `frontend/src/config/links.ts`
82
+
83
+ ## Integration Points
84
+ - **ResultsDisplay**: Dedicated feedback section
85
+ - **Health Check**: Database status in `/health` endpoint
86
+ - **Analytics**: Google Analytics tracking included
87
+
88
+ ## User Flow
89
+ 1. Analysis completes → Results display
90
+ 2. "Share Your Feedback" section appears
91
+ 3. Options based on database status:
92
+ - Database connected: Coach feedback + feature request + report issue
93
+ - Database offline: Feature request + report issue + error message
94
+ 4. Feature request opens Google Forms in new tab
95
+ 5. Coach feedback saves to Supabase (if connected)
96
+
97
+ This system provides comprehensive user feedback collection while maintaining a seamless experience.
@@ -0,0 +1,104 @@
1
+ ---
2
+ title: Supabase Database Integration Setup
3
+ type: note
4
+ permalink: development/supabase-database-integration-setup
5
+ ---
6
+
7
+ # Supabase Database Integration for Coach Feedback
8
+
9
+ ## Database Schema
10
+
11
+ Run this SQL in Supabase SQL Editor to create the required tables:
12
+
13
+ ```sql
14
+ -- Analysis Sessions Table
15
+ CREATE TABLE IF NOT EXISTS analysis_sessions (
16
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
17
+ user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
18
+ jump_type VARCHAR(50) NOT NULL CHECK (jump_type IN ('cmj', 'drop_jump')),
19
+ quality_preset VARCHAR(20) NOT NULL CHECK (quality_preset IN ('fast', 'balanced', 'accurate')),
20
+ original_video_url TEXT,
21
+ debug_video_url TEXT,
22
+ results_json_url TEXT,
23
+ analysis_data JSONB NOT NULL,
24
+ processing_time_s FLOAT,
25
+ upload_id VARCHAR(50),
26
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
27
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
28
+ );
29
+
30
+ -- Coach Feedback Table
31
+ CREATE TABLE IF NOT EXISTS coach_feedback (
32
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
33
+ analysis_session_id UUID NOT NULL REFERENCES analysis_sessions(id) ON DELETE CASCADE,
34
+ coach_user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
35
+ notes TEXT,
36
+ rating INTEGER CHECK (rating >= 1 AND rating <= 5),
37
+ tags TEXT[] DEFAULT '{}',
38
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
39
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
40
+ );
41
+
42
+ -- Indexes and RLS policies included in full schema
43
+ ```
44
+
45
+ ## Backend Integration
46
+
47
+ ### New Files Created:
48
+ - `backend/src/kinemotion_backend/database.py` - Async Supabase client
49
+ - `backend/src/kinemotion_backend/analysis_api.py` - Feedback API endpoints
50
+ - `backend/src/kinemotion_backend/models.py` - Pydantic models
51
+ - `backend/supabase-schema.sql` - Complete database schema
52
+
53
+ ### API Endpoints:
54
+ - `POST /api/analysis/sessions` - Create analysis sessions
55
+ - `GET /api/analysis/sessions` - List user sessions
56
+ - `GET /api/analysis/sessions/{id}` - Get session with feedback
57
+ - `POST /api/analysis/sessions/{id}/feedback` - Add coach feedback
58
+ - `GET /api/analysis/database-status` - Check database connection
59
+
60
+ ### Key Features:
61
+ - Optional authentication (works with/without user login)
62
+ - JSONB storage for flexible analysis data querying
63
+ - Row Level Security for data privacy
64
+ - Async database operations
65
+ - Graceful error handling
66
+
67
+ ## Frontend Integration
68
+
69
+ ### Components Added:
70
+ - `FeedbackForm.tsx` - Modal feedback form with rating, tags, notes
71
+ - `FeatureRequestButton.tsx` - Reusable feature request button
72
+ - `useDatabaseStatus.ts` - Hook for checking database connectivity
73
+
74
+ ### Configuration:
75
+ - `config/links.ts` - External links and UI settings
76
+ - Google Forms integration for feature requests
77
+ - Conditional UI based on database status
78
+
79
+ ### User Experience:
80
+ - Smart feedback section with multiple options
81
+ - Database connection detection
82
+ - Responsive design
83
+ - Analytics tracking ready
84
+
85
+ ## Setup Requirements:
86
+ 1. Run database schema in Supabase
87
+ 2. Configure SUPABASE_URL and SUPABASE_ANON_KEY
88
+ 3. Update Google Forms URL in frontend config
89
+ 4. Test integration with authenticated/unauthenticated users
90
+
91
+ ## Example Queries:
92
+ ```sql
93
+ -- Average jump height by user
94
+ SELECT user_id, AVG((analysis_data->'data'->>'jump_height')::float) as avg_jump_height
95
+ FROM analysis_sessions WHERE jump_type = 'cmj' GROUP BY user_id;
96
+
97
+ -- Sessions with feedback
98
+ SELECT s.*, f.rating, f.notes
99
+ FROM analysis_sessions s
100
+ LEFT JOIN coach_feedback f ON s.id = f.analysis_session_id
101
+ WHERE f.id IS NOT NULL;
102
+ ```
103
+
104
+ This system enables comprehensive coach feedback collection and athlete performance tracking.
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  <!-- version list -->
9
9
 
10
+ ## v0.49.0 (2025-12-13)
11
+
12
+ ### Bug Fixes
13
+
14
+ - Normalize timing log event names to proper snake_case keys
15
+ ([`ecbb154`](https://github.com/feniix/kinemotion/commit/ecbb154dc19f2de47c10bea9f638b13eb71026b4))
16
+
17
+ ### Chores
18
+
19
+ - Update sonar app version
20
+ ([`2975f7b`](https://github.com/feniix/kinemotion/commit/2975f7bf0ab4732ca92f7c9728ed3d8911992ca1))
21
+
22
+ ### Features
23
+
24
+ - Implement comprehensive feedback system with Supabase database integration
25
+ ([`9bcf73f`](https://github.com/feniix/kinemotion/commit/9bcf73f79436e2b4de900b58f95258719fcdce80))
26
+
27
+
10
28
  ## v0.48.0 (2025-12-12)
11
29
 
12
30
  ### Chores
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kinemotion
3
- Version: 0.48.0
3
+ Version: 0.49.0
4
4
  Summary: Video-based kinematic analysis for athletic performance
5
5
  Project-URL: Homepage, https://github.com/feniix/kinemotion
6
6
  Project-URL: Repository, https://github.com/feniix/kinemotion
@@ -0,0 +1,303 @@
1
+ """API endpoints for analysis sessions and coach feedback."""
2
+
3
+ from typing import Any
4
+
5
+ import structlog
6
+ from fastapi import APIRouter, Depends, HTTPException, status
7
+ from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
8
+
9
+ from kinemotion_backend.auth import SupabaseAuth
10
+ from kinemotion_backend.database import get_database_client
11
+ from kinemotion_backend.models import (
12
+ AnalysisSessionCreate,
13
+ AnalysisSessionResponse,
14
+ AnalysisSessionWithFeedback,
15
+ CoachFeedbackCreate,
16
+ CoachFeedbackResponse,
17
+ DatabaseError,
18
+ )
19
+
20
+ logger = structlog.get_logger()
21
+ router = APIRouter(prefix="/api/analysis", tags=["Analysis"])
22
+ security = HTTPBearer()
23
+ auth = SupabaseAuth()
24
+
25
+
26
+ async def get_current_user_id(
27
+ credentials: HTTPAuthorizationCredentials = Depends(security), # noqa: B008
28
+ ) -> str:
29
+ """Extract user ID from JWT token."""
30
+ try:
31
+ return auth.get_user_id(credentials.credentials)
32
+ except Exception as e:
33
+ logger.warning("user_authentication_failed", error=str(e))
34
+ raise HTTPException(
35
+ status_code=status.HTTP_401_UNAUTHORIZED,
36
+ detail="Invalid authentication credentials",
37
+ ) from e
38
+
39
+
40
+ @router.post(
41
+ "/sessions",
42
+ response_model=AnalysisSessionResponse,
43
+ status_code=status.HTTP_201_CREATED,
44
+ responses={400: {"model": DatabaseError}, 500: {"model": DatabaseError}},
45
+ )
46
+ async def create_analysis_session(
47
+ session_data: AnalysisSessionCreate,
48
+ user_id: str = Depends(get_current_user_id),
49
+ ) -> AnalysisSessionResponse:
50
+ """Create a new analysis session record.
51
+
52
+ This endpoint stores analysis metadata and results in the database.
53
+ It's typically called after video analysis is completed.
54
+ """
55
+ try:
56
+ db_client = get_database_client()
57
+ session_record = await db_client.create_analysis_session(
58
+ user_id=user_id,
59
+ jump_type=session_data.jump_type,
60
+ quality_preset=session_data.quality_preset,
61
+ analysis_data=session_data.analysis_data,
62
+ original_video_url=session_data.original_video_url,
63
+ debug_video_url=session_data.debug_video_url,
64
+ results_json_url=session_data.results_json_url,
65
+ processing_time_s=session_data.processing_time_s,
66
+ upload_id=session_data.upload_id,
67
+ )
68
+
69
+ logger.info(
70
+ "analysis_session_api_created",
71
+ session_id=session_record["id"],
72
+ user_id=user_id,
73
+ jump_type=session_data.jump_type,
74
+ )
75
+
76
+ return AnalysisSessionResponse(**session_record)
77
+
78
+ except Exception as e:
79
+ logger.error(
80
+ "create_analysis_session_api_error",
81
+ error=str(e),
82
+ user_id=user_id,
83
+ exc_info=True,
84
+ )
85
+ raise HTTPException(
86
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
87
+ detail=f"Failed to create analysis session: {str(e)}",
88
+ ) from e
89
+
90
+
91
+ @router.get(
92
+ "/sessions",
93
+ response_model=list[AnalysisSessionResponse],
94
+ responses={401: {"model": DatabaseError}, 500: {"model": DatabaseError}},
95
+ )
96
+ async def get_user_analysis_sessions(
97
+ limit: int = 50,
98
+ user_id: str = Depends(get_current_user_id),
99
+ ) -> list[AnalysisSessionResponse]:
100
+ """Get analysis sessions for the current user.
101
+
102
+ Args:
103
+ limit: Maximum number of sessions to return (default: 50)
104
+ """
105
+ try:
106
+ if limit <= 0 or limit > 100:
107
+ raise HTTPException(
108
+ status_code=status.HTTP_400_BAD_REQUEST,
109
+ detail="Limit must be between 1 and 100",
110
+ )
111
+
112
+ db_client = get_database_client()
113
+ sessions = await db_client.get_user_analysis_sessions(
114
+ user_id=user_id, limit=limit
115
+ )
116
+
117
+ logger.info(
118
+ "user_analysis_sessions_api_retrieved",
119
+ user_id=user_id,
120
+ count=len(sessions),
121
+ )
122
+
123
+ return [AnalysisSessionResponse(**session) for session in sessions]
124
+
125
+ except HTTPException:
126
+ raise
127
+ except Exception as e:
128
+ logger.error(
129
+ "get_user_analysis_sessions_api_error",
130
+ error=str(e),
131
+ user_id=user_id,
132
+ exc_info=True,
133
+ )
134
+ raise HTTPException(
135
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
136
+ detail=f"Failed to retrieve analysis sessions: {str(e)}",
137
+ ) from e
138
+
139
+
140
+ @router.get(
141
+ "/sessions/{session_id}",
142
+ response_model=AnalysisSessionWithFeedback,
143
+ responses={
144
+ 401: {"model": DatabaseError},
145
+ 404: {"model": DatabaseError},
146
+ 500: {"model": DatabaseError},
147
+ },
148
+ )
149
+ async def get_analysis_session(
150
+ session_id: str,
151
+ user_id: str = Depends(get_current_user_id),
152
+ ) -> AnalysisSessionWithFeedback:
153
+ """Get a specific analysis session with feedback.
154
+
155
+ Users can only access their own analysis sessions.
156
+ """
157
+ try:
158
+ db_client = get_database_client()
159
+ session = await db_client.get_analysis_session(
160
+ session_id=session_id, user_id=user_id
161
+ )
162
+
163
+ if not session:
164
+ raise HTTPException(
165
+ status_code=status.HTTP_404_NOT_FOUND,
166
+ detail="Analysis session not found",
167
+ )
168
+
169
+ # Get feedback for this session
170
+ feedback = await db_client.get_session_feedback(analysis_session_id=session_id)
171
+
172
+ logger.info(
173
+ "analysis_session_api_retrieved",
174
+ session_id=session_id,
175
+ user_id=user_id,
176
+ feedback_count=len(feedback),
177
+ )
178
+
179
+ session_with_feedback = AnalysisSessionWithFeedback(**session)
180
+ session_with_feedback.feedback = [
181
+ CoachFeedbackResponse(**fb) for fb in feedback
182
+ ]
183
+
184
+ return session_with_feedback
185
+
186
+ except HTTPException:
187
+ raise
188
+ except Exception as e:
189
+ logger.error(
190
+ "get_analysis_session_api_error",
191
+ error=str(e),
192
+ session_id=session_id,
193
+ user_id=user_id,
194
+ exc_info=True,
195
+ )
196
+ raise HTTPException(
197
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
198
+ detail=f"Failed to retrieve analysis session: {str(e)}",
199
+ ) from e
200
+
201
+
202
+ @router.get(
203
+ "/database-status",
204
+ response_model=dict[str, Any],
205
+ responses={500: {"model": DatabaseError}},
206
+ )
207
+ async def get_database_status() -> dict[str, Any]:
208
+ """Check if the database is connected and working."""
209
+ try:
210
+ db_client = get_database_client()
211
+
212
+ # Try a simple query to test the connection
213
+ # We'll test by trying to access the analysis_sessions table
214
+ db_client.client.table("analysis_sessions").select("id").limit(1).execute()
215
+
216
+ return {
217
+ "database_connected": True,
218
+ "tables_exist": True,
219
+ "message": "Database connection successful",
220
+ }
221
+
222
+ except Exception as e:
223
+ logger.error("database_status_check_failed", error=str(e), exc_info=True)
224
+ return {
225
+ "database_connected": False,
226
+ "tables_exist": False,
227
+ "message": f"Database connection failed: {str(e)}",
228
+ }
229
+
230
+
231
+ @router.post(
232
+ "/sessions/{session_id}/feedback",
233
+ response_model=CoachFeedbackResponse,
234
+ status_code=status.HTTP_201_CREATED,
235
+ responses={
236
+ 400: {"model": DatabaseError},
237
+ 401: {"model": DatabaseError},
238
+ 404: {"model": DatabaseError},
239
+ 500: {"model": DatabaseError},
240
+ },
241
+ )
242
+ async def create_coach_feedback(
243
+ session_id: str,
244
+ feedback_data: CoachFeedbackCreate,
245
+ coach_user_id: str = Depends(get_current_user_id),
246
+ ) -> CoachFeedbackResponse:
247
+ """Add coach feedback to an analysis session.
248
+
249
+ Any authenticated user can provide feedback on analysis sessions.
250
+ """
251
+ try:
252
+ # Validate that the session exists
253
+ db_client = get_database_client()
254
+ session = await db_client.get_analysis_session(
255
+ session_id=session_id, user_id=coach_user_id
256
+ )
257
+
258
+ if not session:
259
+ # Try to get session without user restriction
260
+ # (coaches can provide feedback on any session)
261
+ # This would require modifying the database client
262
+ # to allow unrestricted access for feedback
263
+ # For now, we'll assume users can only provide feedback
264
+ # on their own sessions
265
+ raise HTTPException(
266
+ status_code=status.HTTP_404_NOT_FOUND,
267
+ detail="Analysis session not found",
268
+ )
269
+
270
+ # Override the session_id from the URL to ensure consistency
271
+ feedback_data.analysis_session_id = session_id
272
+
273
+ feedback_record = await db_client.create_coach_feedback(
274
+ analysis_session_id=session_id,
275
+ coach_user_id=coach_user_id,
276
+ notes=feedback_data.notes,
277
+ rating=feedback_data.rating,
278
+ tags=feedback_data.tags,
279
+ )
280
+
281
+ logger.info(
282
+ "coach_feedback_api_created",
283
+ feedback_id=feedback_record["id"],
284
+ session_id=session_id,
285
+ coach_user_id=coach_user_id,
286
+ )
287
+
288
+ return CoachFeedbackResponse(**feedback_record)
289
+
290
+ except HTTPException:
291
+ raise
292
+ except Exception as e:
293
+ logger.error(
294
+ "create_coach_feedback_api_error",
295
+ error=str(e),
296
+ session_id=session_id,
297
+ coach_user_id=coach_user_id,
298
+ exc_info=True,
299
+ )
300
+ raise HTTPException(
301
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
302
+ detail=f"Failed to create coach feedback: {str(e)}",
303
+ ) from e
@@ -4,6 +4,7 @@ Real metrics integration with Cloudflare R2 storage for video and results manage
4
4
  """
5
5
 
6
6
  import os
7
+ import re
7
8
  import tempfile
8
9
  from contextlib import asynccontextmanager
9
10
  from datetime import datetime, timezone
@@ -33,6 +34,8 @@ from kinemotion.core.timing import (
33
34
  from slowapi import Limiter, _rate_limit_exceeded_handler
34
35
  from slowapi.util import get_remote_address
35
36
 
37
+ from kinemotion_backend.analysis_api import router as analysis_router
38
+ from kinemotion_backend.database import get_database_client
36
39
  from kinemotion_backend.logging_config import get_logger, setup_logging
37
40
  from kinemotion_backend.middleware import RequestLoggingMiddleware
38
41
 
@@ -360,6 +363,8 @@ try:
360
363
  except ValueError:
361
364
  logger.warning("r2_storage_not_configured", message="R2 credentials not provided")
362
365
 
366
+ # Include analysis API router
367
+ app.include_router(analysis_router)
363
368
 
364
369
  # ========== Helper Functions ==========
365
370
 
@@ -520,6 +525,18 @@ async def health_check() -> dict[str, Any]:
520
525
  except Exception:
521
526
  kinemotion_version = "unknown"
522
527
 
528
+ # Check database connection
529
+ database_connected = False
530
+ try:
531
+ from kinemotion_backend.database import get_database_client
532
+
533
+ db_client = get_database_client()
534
+ # Test database with a simple query
535
+ db_client.client.table("analysis_sessions").select("id").limit(1).execute()
536
+ database_connected = True
537
+ except Exception as db_error:
538
+ logger.warning("database_health_check_failed", error=str(db_error))
539
+
523
540
  return {
524
541
  "status": "ok",
525
542
  "service": "kinemotion-backend",
@@ -528,6 +545,7 @@ async def health_check() -> dict[str, Any]:
528
545
  "timestamp": datetime.now(timezone.utc).isoformat(),
529
546
  "r2_configured": r2_client is not None,
530
547
  "trackers_initialized": len(global_pose_trackers) > 0,
548
+ "database_connected": database_connected,
531
549
  }
532
550
 
533
551
 
@@ -672,9 +690,10 @@ async def analyze_video(
672
690
  and "timing_breakdown_ms" in metrics["metadata"]["processing"]
673
691
  ):
674
692
  timing_breakdown = metrics["metadata"]["processing"]["timing_breakdown_ms"]
675
- # Normalize keys for easier jq parsing: spaces → underscores, lowercase
693
+ # Normalize keys: remove special chars, spaces → underscores, lowercase
676
694
  normalized_timings = {
677
- stage.lower().replace(" ", "_") + "_ms": duration
695
+ re.sub(r"[^\w\s]", "", stage).lower().replace(" ", "_")
696
+ + "_ms": duration
678
697
  for stage, duration in timing_breakdown.items()
679
698
  }
680
699
  # Log each timing stage as a separate event for granular monitoring
@@ -744,6 +763,51 @@ async def analyze_video(
744
763
  )
745
764
  processing_time = time.time() - start_time
746
765
 
766
+ # Optionally store analysis session in database if user is authenticated
767
+ user_id = None
768
+ try:
769
+ auth_header = request.headers.get("Authorization")
770
+ if auth_header and auth_header.startswith("Bearer "):
771
+ from kinemotion_backend.auth import SupabaseAuth
772
+
773
+ auth = SupabaseAuth()
774
+ token = auth_header.split(" ")[1]
775
+ user_id = auth.get_user_id(token)
776
+ logger.info("user_authenticated_for_analysis", user_id=user_id)
777
+ except Exception as e:
778
+ logger.info("analysis_save_no_auth", reason=str(e))
779
+ user_id = None
780
+
781
+ # Store in database if authenticated
782
+ session_id = None
783
+ if user_id:
784
+ try:
785
+ db_client = get_database_client()
786
+ session_record = await db_client.create_analysis_session(
787
+ user_id=user_id,
788
+ jump_type=jump_type,
789
+ quality_preset=quality,
790
+ analysis_data=metrics,
791
+ original_video_url=original_video_url,
792
+ debug_video_url=debug_video_url,
793
+ results_json_url=results_url,
794
+ processing_time_s=processing_time,
795
+ upload_id=upload_id,
796
+ )
797
+ session_id = session_record["id"]
798
+ logger.info(
799
+ "analysis_session_saved",
800
+ session_id=session_id,
801
+ user_id=user_id,
802
+ )
803
+ except Exception as e:
804
+ # Log error but don't fail the analysis - this is optional storage
805
+ logger.warning(
806
+ "analysis_session_save_failed",
807
+ error=str(e),
808
+ user_id=user_id,
809
+ )
810
+
747
811
  # Build successful response
748
812
  jump_type_display = "drop_jump" if jump_type == "drop_jump" else "cmj"
749
813
  response = AnalysisResponse(