kinemotion 0.60.0__tar.gz → 0.61.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 (592) hide show
  1. {kinemotion-0.60.0 → kinemotion-0.61.0}/.github/workflows/deploy-backend.yml +1 -1
  2. {kinemotion-0.60.0 → kinemotion-0.61.0}/CHANGELOG.md +13 -0
  3. {kinemotion-0.60.0 → kinemotion-0.61.0}/PKG-INFO +1 -1
  4. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/pyproject.toml +1 -1
  5. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/analysis_api.py +3 -9
  6. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/app/config.py +1 -3
  7. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/app/main.py +2 -6
  8. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/app.py +8 -22
  9. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/auth.py +1 -3
  10. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/database.py +18 -17
  11. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/middleware.py +2 -7
  12. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/models/database.py +3 -9
  13. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/models/responses.py +2 -6
  14. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/models/storage.py +2 -6
  15. kinemotion-0.61.0/backend/src/kinemotion_backend/routes/health.py +53 -0
  16. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/services/analysis_service.py +1 -3
  17. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/services/storage_service.py +2 -6
  18. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/services/validation.py +1 -2
  19. kinemotion-0.61.0/backend/supabase-schema.sql +70 -0
  20. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/tests/conftest.py +1 -2
  21. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/tests/test_error_handling.py +3 -9
  22. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/tests/test_r2_integration.py +3 -9
  23. kinemotion-0.61.0/frontend/src/lib/supabase.ts +23 -0
  24. {kinemotion-0.60.0 → kinemotion-0.61.0}/pyproject.toml +1 -1
  25. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/supabasedb/setup-supabase-database.sh +23 -15
  26. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/supabasedb/setup_supabase_db.py +21 -13
  27. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cmj/analysis.py +4 -12
  28. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cmj/api.py +5 -15
  29. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cmj/cli.py +9 -25
  30. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cmj/debug_overlay.py +3 -9
  31. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cmj/kinematics.py +11 -31
  32. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cmj/metrics_validator.py +27 -67
  33. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cmj/validation_bounds.py +1 -3
  34. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/auto_tuning.py +2 -6
  35. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/debug_overlay_utils.py +4 -13
  36. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/determinism.py +1 -3
  37. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/filtering.py +2 -6
  38. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/pipeline_utils.py +2 -5
  39. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/pose.py +4 -12
  40. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/quality.py +2 -6
  41. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/smoothing.py +3 -9
  42. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/validation.py +2 -6
  43. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/dropjump/analysis.py +9 -26
  44. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/dropjump/api.py +4 -12
  45. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/dropjump/cli.py +5 -14
  46. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/dropjump/debug_overlay.py +1 -3
  47. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/dropjump/kinematics.py +9 -27
  48. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/dropjump/metrics_validator.py +7 -20
  49. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/dropjump/validation_bounds.py +1 -3
  50. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cli/test_cmj.py +24 -72
  51. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cli/test_dropjump.py +7 -21
  52. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cmj/test_analysis.py +16 -46
  53. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cmj/test_api.py +1 -3
  54. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cmj/test_joint_angles.py +15 -44
  55. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cmj/test_kinematics.py +1 -3
  56. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cmj/test_physiological_bounds.py +12 -46
  57. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_cli_utils.py +1 -3
  58. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_filtering.py +6 -18
  59. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_pipeline_utils.py +2 -6
  60. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_pose.py +1 -3
  61. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_quality.py +6 -18
  62. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_smoothing.py +26 -78
  63. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_validation.py +3 -9
  64. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_video_io.py +4 -12
  65. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/dropjump/test_adaptive_threshold.py +3 -9
  66. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/dropjump/test_analysis.py +1 -3
  67. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/dropjump/test_api.py +1 -3
  68. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/dropjump/test_contact_detection.py +2 -6
  69. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/dropjump/test_kinematics.py +2 -7
  70. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/dropjump/test_physiological_bounds.py +12 -50
  71. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/dropjump/test_validation_integration.py +3 -9
  72. {kinemotion-0.60.0 → kinemotion-0.61.0}/uv.lock +1 -1
  73. kinemotion-0.60.0/backend/src/kinemotion_backend/routes/health.py +0 -34
  74. kinemotion-0.60.0/backend/supabase-schema.sql +0 -148
  75. kinemotion-0.60.0/frontend/src/lib/supabase.ts +0 -20
  76. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/README.md +0 -0
  77. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/api/api-reference-quick-commands.md +0 -0
  78. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/api/cloud-run-cpu-specifications-investigation.md +0 -0
  79. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/api/supabase-authentication-setup-guide.md +0 -0
  80. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/authentication/auth-provider-comparison-december-2025.md +0 -0
  81. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/authentication/auth-providers-comparison-december-2025.md +0 -0
  82. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/authentication/supabase-authentication-quick-start.md +0 -0
  83. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/authentication/supabase-authentication-setup-guide.md +0 -0
  84. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/authentication/supabase-authentication-technical-guide.md +0 -0
  85. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/authentication/supabase-google-oauth-setup-guide.md +0 -0
  86. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/authentication/supabase-production-setup-guide.md +0 -0
  87. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/authentication/supabase-quick-start-guide.md +0 -0
  88. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/biomechanics/camera-angle-empirical-validation-results-45-superior-for-media-pipe.md +0 -0
  89. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/biomechanics/camera-perspective-analysis-45deg-vs-lateral.md +0 -0
  90. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/biomechanics/cmj-landing-detection-window-validation.md +0 -0
  91. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/biomechanics/cmj-physiological-bounds-for-validation.md +0 -0
  92. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/biomechanics/cmj-validation-implementation-complete.md +0 -0
  93. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/biomechanics/drop-jump-vs-cmj-key-differences.md +0 -0
  94. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/biomechanics/technical-implementation-45deg-perspective-correction.md +0 -0
  95. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/codebase/codebase-architecture-overview.md +0 -0
  96. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/codebase/validation-architecture-visual-hierarchy-after-refactoring.md +0 -0
  97. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/codebase/validation-code-duplication-evidence.md +0 -0
  98. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/codebase/validation-module-architecture-analysis.md +0 -0
  99. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/codebase/validation-refactoring-complete-architecture-improvement.md +0 -0
  100. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/automated-deployment-setup-git-hub-actions-with-workload-identity-federation.md +0 -0
  101. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/backend-repository-split-migration-guide.md +0 -0
  102. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/backend-repository-split-step-by-step-execution-guide.md +0 -0
  103. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/cloud-run-security-least-privilege-service-account-setup.md +0 -0
  104. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/cors-and-memory-issues-production-debugging-guide.md +0 -0
  105. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/current-kinemotion-architecture-correct-deployment-setup.md +0 -0
  106. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/frontend-repository-split-migration-guide.md +0 -0
  107. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/frontend-repository-split-step-by-step-execution-guide.md +0 -0
  108. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/production-deployment-guide-vercel-google-cloud-run.md +0 -0
  109. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/quick-deployment-commands-vercel-and-cloud-run.md +0 -0
  110. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/deployment/vercel-monorepo-deployment-best-practice.md +0 -0
  111. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/athlete-pose3d-and-cross-platform-determinism-investigation-complete.md +0 -0
  112. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/athlete-pose3d-final-strategy-accuracy-and-robustness.md +0 -0
  113. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/athlete-pose3d-media-pipe-enhancement-plan.md +0 -0
  114. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/athlete-pose3d-phase-1-implementation-complete.md +0 -0
  115. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/backend-authentication-and-logging-status.md +0 -0
  116. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/backend-code-coverage-analysis.md +0 -0
  117. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/backend-code-duplication-analysis.md +0 -0
  118. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/backend-granular-logging-implementation.md +0 -0
  119. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/backend-kinemotion-decoupling-strategy.md +0 -0
  120. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/backend-sonar-cloud-integration-status.md +0 -0
  121. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/basic-memory-naming-hook-analysis.md +0 -0
  122. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/ci-caching-issue-investigation-deep-squat-test-failure.md +0 -0
  123. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/ci-vs-local-test-failure-investigation.md +0 -0
  124. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/claude-code-hook-configuration.md +0 -0
  125. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/cmj-phase-detection-testing-gap-analysis.md +0 -0
  126. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/commit-review-r2-video-storage-migration-fe74d1f.md +0 -0
  127. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/comprehensive-timing-instrumentation.md +0 -0
  128. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/cross-platform-determinism-analysis-final-results.md +0 -0
  129. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/database-setup-scripts-complete-implementation.md +0 -0
  130. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/development-standards-quality-gates.md +0 -0
  131. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/drop-jump-detection-complete-fix-all-metrics-within-target.md +0 -0
  132. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/drop-jump-detection-failure-analysis-per-video-breakdown.md +0 -0
  133. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/drop-jump-fix-drop-start-successful-landing-and-takeoff-remain.md +0 -0
  134. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/fast-api-app.py Refactoring Plan - Modular Architecture.md +0 -0
  135. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/fast-api-refactoring-completion-summary.md +0 -0
  136. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/feature-request-system-configuration.md +0 -0
  137. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/follow-up-improvements-to-r2-video-storage-migration.md +0 -0
  138. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/frontend-dependencies-analysis-nov-2025.md +0 -0
  139. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/google-oauth-setup-script-final-review-production-ready.md +0 -0
  140. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/google-oauth-setup-script-review-issues-and-recommendations.md +0 -0
  141. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/hook-complete-audit-summary.md +0 -0
  142. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/hook-configuration-audit.md +0 -0
  143. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/hook-quick-reference.md +0 -0
  144. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/i18n-implementation-plan-for-validation-messages.md +0 -0
  145. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/keyboard-interrupt-test-suite-failure-analysis.md +0 -0
  146. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/model-import-conflict-resolution-fast-api-refactoring.md +0 -0
  147. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/non-deterministic-analysis-root-cause-and-solution.md +0 -0
  148. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/optimal-timing-implementation-summary.md +0 -0
  149. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/p0-p1-p2-test-suite-fixes-final-report.md +0 -0
  150. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/pose-detection-baseline-evaluation-results.md +0 -0
  151. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/pose-detection-optimization-complete-success-summary.md +0 -0
  152. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/pose-detection-parameter-optimization-framework.md +0 -0
  153. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/structured-logging-implementation-complete.md +0 -0
  154. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/structured-logging-implementation.md +0 -0
  155. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/supabase-dashboard-navigation-december-2025.md +0 -0
  156. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/supabase-database-integration-setup.md +0 -0
  157. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/supabase-documentation-validation-december-2025.md +0 -0
  158. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/test-coverage-asymmetry-analysis-cmj-vs-drop-jump.md +0 -0
  159. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/test-coverage-equivalence-achievement-summary.md +0 -0
  160. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/test-suite-comprehensive-review-december-2025.md +0 -0
  161. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/test-suite-comprehensive-review-structure-and-gaps.md +0 -0
  162. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-complete-report.md +0 -0
  163. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-progress-report.md +0 -0
  164. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/unused-and-experimental-features-strategy.md +0 -0
  165. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/unused-code-detection-prompt-template.md +0 -0
  166. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/unused-code-identification-and-decorator-application-december-2025.md +0 -0
  167. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/unused-code-verification-final-pass-december-2025.md +0 -0
  168. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/using-multiple-mcp-reasoning-servers-simultaneously.md +0 -0
  169. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/velocity-threshold-empirical-validation-study.md +0 -0
  170. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/development/vercel-authentication-options-for-user-id-tracking.md +0 -0
  171. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/agent-documentation-standards-update.md +0 -0
  172. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/documentation-audit-december-2025.md +0 -0
  173. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/i18n-documentation-cleanup-completed.md +0 -0
  174. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/issue-12-mvp-scaffolding-complete.md +0 -0
  175. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/issue-12-unblocked-tasks-breakdown.md +0 -0
  176. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/issue-12-use-real-metrics-now.md +0 -0
  177. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/kinemotion-project-setup-complete.md +0 -0
  178. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/kinemotion-supabase-production-configuration.md +0 -0
  179. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/mcp-sequential-thinking-alternatives-analysis.md +0 -0
  180. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/performance-optimization-pose-tracker-pool-timing-instrumentation-complete.md +0 -0
  181. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/project-state-summary-december-2025.md +0 -0
  182. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/specialized-subagents-routing-guide.md +0 -0
  183. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/supabase-setup-instructions-for-kinemotion.md +0 -0
  184. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/project-management/version-mismatch-analysis-kinemotion-0370-vs-0300.md +0 -0
  185. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/research/performance-improvement-analysis-30s-18s.md +0 -0
  186. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/strategy/deployment-decision-analysis-for-kinemotion.md +0 -0
  187. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/strategy/mvp-feedback-collection-plan.md +0 -0
  188. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/strategy/mvp-first-strategic-direction.md +0 -0
  189. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/strategy/mvp-validation-checkpoints.md +0 -0
  190. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/strategy/pose2sim-migration-evaluation-and-strategy.md +0 -0
  191. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/strategy/strategic-priority-tasks-current-roadmap.md +0 -0
  192. {kinemotion-0.60.0 → kinemotion-0.61.0}/.basic-memory/strategy/third-party-auth-providers-with-free-tiers-december-2025.md +0 -0
  193. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/agents/biomechanics-specialist.md +0 -0
  194. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/agents/computer-vision-engineer.md +0 -0
  195. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/agents/devops-cicd-engineer.md +0 -0
  196. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/agents/frontend-developer.md +0 -0
  197. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/agents/ml-data-scientist.md +0 -0
  198. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/agents/project-manager.md +0 -0
  199. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/agents/python-backend-developer.md +0 -0
  200. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/agents/qa-test-engineer.md +0 -0
  201. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/agents/technical-writer.md +0 -0
  202. {kinemotion-0.60.0 → kinemotion-0.61.0}/.claude/settings.local.json +0 -0
  203. {kinemotion-0.60.0 → kinemotion-0.61.0}/.cursor/mcp.json +0 -0
  204. {kinemotion-0.60.0 → kinemotion-0.61.0}/.dockerignore +0 -0
  205. {kinemotion-0.60.0 → kinemotion-0.61.0}/.envrc +0 -0
  206. {kinemotion-0.60.0 → kinemotion-0.61.0}/.gitattributes +0 -0
  207. {kinemotion-0.60.0 → kinemotion-0.61.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  208. {kinemotion-0.60.0 → kinemotion-0.61.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  209. {kinemotion-0.60.0 → kinemotion-0.61.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  210. {kinemotion-0.60.0 → kinemotion-0.61.0}/.github/dependabot.yml +0 -0
  211. {kinemotion-0.60.0 → kinemotion-0.61.0}/.github/pull_request_template.md +0 -0
  212. {kinemotion-0.60.0 → kinemotion-0.61.0}/.github/workflows/docs.yml +0 -0
  213. {kinemotion-0.60.0 → kinemotion-0.61.0}/.github/workflows/release.yml +0 -0
  214. {kinemotion-0.60.0 → kinemotion-0.61.0}/.github/workflows/test.yml +0 -0
  215. {kinemotion-0.60.0 → kinemotion-0.61.0}/.gitignore +0 -0
  216. {kinemotion-0.60.0 → kinemotion-0.61.0}/.mcp.json +0 -0
  217. {kinemotion-0.60.0 → kinemotion-0.61.0}/.pre-commit-config.yaml +0 -0
  218. {kinemotion-0.60.0 → kinemotion-0.61.0}/.readthedocs.yml +0 -0
  219. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/.gitignore +0 -0
  220. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/backend-cors-fastapi-middleware-order.md +0 -0
  221. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/camera-perspective-validation-study.md +0 -0
  222. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/code_style_and_conventions.md +0 -0
  223. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/current-project-architecture.md +0 -0
  224. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/deployment-checklist-and-known-issues.md +0 -0
  225. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/deployment-setup-complete.md +0 -0
  226. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/github-project-setup-summary.md +0 -0
  227. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/mvp-first-strategy.md +0 -0
  228. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/mvp-roadmap-and-priorities.md +0 -0
  229. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/project_overview.md +0 -0
  230. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/specialist-agents-routing.md +0 -0
  231. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/memories/suggested_commands.md +0 -0
  232. {kinemotion-0.60.0 → kinemotion-0.61.0}/.serena/project.yml +0 -0
  233. {kinemotion-0.60.0 → kinemotion-0.61.0}/.tool-versions +0 -0
  234. {kinemotion-0.60.0 → kinemotion-0.61.0}/.vercelignore +0 -0
  235. {kinemotion-0.60.0 → kinemotion-0.61.0}/CLAUDE.md +0 -0
  236. {kinemotion-0.60.0 → kinemotion-0.61.0}/CODE_OF_CONDUCT.md +0 -0
  237. {kinemotion-0.60.0 → kinemotion-0.61.0}/CONTRIBUTING.md +0 -0
  238. {kinemotion-0.60.0 → kinemotion-0.61.0}/Dockerfile +0 -0
  239. {kinemotion-0.60.0 → kinemotion-0.61.0}/GEMINI.md +0 -0
  240. {kinemotion-0.60.0 → kinemotion-0.61.0}/LICENSE +0 -0
  241. {kinemotion-0.60.0 → kinemotion-0.61.0}/README.md +0 -0
  242. {kinemotion-0.60.0 → kinemotion-0.61.0}/SECURITY.md +0 -0
  243. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/.coveragerc +0 -0
  244. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/.dockerignore +0 -0
  245. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/.env.example +0 -0
  246. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/Dockerfile +0 -0
  247. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/README.md +0 -0
  248. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/docs/fly-deployment.md +0 -0
  249. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/docs/implementation-summary.md +0 -0
  250. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/docs/setup.md +0 -0
  251. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/docs/tests.md +0 -0
  252. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/__init__.py +0 -0
  253. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/app/__init__.py +0 -0
  254. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/app/dependencies.py +0 -0
  255. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/app/exceptions.py +0 -0
  256. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/logging_config.py +0 -0
  257. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/models/__init__.py +0 -0
  258. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/routes/__init__.py +0 -0
  259. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/routes/analysis.py +0 -0
  260. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/routes/database.py +0 -0
  261. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/routes/platform.py +0 -0
  262. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/services/__init__.py +0 -0
  263. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/services/video_processor.py +0 -0
  264. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/types.py +0 -0
  265. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/utils/__init__.py +0 -0
  266. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/src/kinemotion_backend/utils/rate_limiter.py +0 -0
  267. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/tests/README.md +0 -0
  268. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/tests/__init__.py +0 -0
  269. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/tests/test_api_endpoints.py +0 -0
  270. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/tests/test_health.py +0 -0
  271. {kinemotion-0.60.0 → kinemotion-0.61.0}/backend/tests/test_validation.py +0 -0
  272. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/README.md +0 -0
  273. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/api/cmj.md +0 -0
  274. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/api/core.md +0 -0
  275. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/api/dropjump.md +0 -0
  276. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/api/overview.md +0 -0
  277. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/I18N-README.md +0 -0
  278. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/agents-guide.md +0 -0
  279. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/errors-findings.md +0 -0
  280. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/feature-request-system.md +0 -0
  281. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/feedback-system-setup.md +0 -0
  282. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/i18n-architecture-diagram.md +0 -0
  283. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/i18n-cheat-sheet.md +0 -0
  284. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/i18n-quick-start-guide.md +0 -0
  285. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/i18n-summary.md +0 -0
  286. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/i18n-validation-messages-specification.md +0 -0
  287. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/supabase-database-setup.md +0 -0
  288. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/test-suite-review-december-2025.md +0 -0
  289. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/testing-standards.md +0 -0
  290. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/testing.md +0 -0
  291. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/type-hints.md +0 -0
  292. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/validation-plan.md +0 -0
  293. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/validation-roadmap.md +0 -0
  294. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/development/wallball-norep-detection.md +0 -0
  295. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/bulk-processing.md +0 -0
  296. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/camera-setup.md +0 -0
  297. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/cloud-run-deployment.md +0 -0
  298. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/cmj-guide.md +0 -0
  299. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/cmj-recording-protocol-es.md +0 -0
  300. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/cmj-recording-protocol.md +0 -0
  301. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/deployment-checklist.md +0 -0
  302. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/local-testing.md +0 -0
  303. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/setup-issue-12.md +0 -0
  304. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/supabase-setup/README.md +0 -0
  305. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/supabase-setup/quickstart.md +0 -0
  306. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/supabase-setup/scripts-reference.md +0 -0
  307. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/guides/supabase-setup/setup-guide.md +0 -0
  308. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/index.md +0 -0
  309. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/quick-start.md +0 -0
  310. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/reference/cloud-run-quick-reference.md +0 -0
  311. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/reference/json-output-format.md +0 -0
  312. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/reference/json-structure-comparison.md +0 -0
  313. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/reference/parameters.md +0 -0
  314. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/reference/pose-systems.md +0 -0
  315. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/paper-downloader/HOW-TO-FIND-DOIS.md +0 -0
  316. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/paper-downloader/README.md +0 -0
  317. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/paper-downloader/dois.txt +0 -0
  318. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/paper-downloader/download.py +0 -0
  319. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/paper-downloader/pyproject.toml +0 -0
  320. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/paper-downloader/uv.lock +0 -0
  321. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/sports-biomechanics-pose-estimation.md +0 -0
  322. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/MANUAL-DOWNLOAD-GUIDE.md +0 -0
  323. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/README.md +0 -0
  324. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/convert_pdfs.py +0 -0
  325. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.md +0 -0
  326. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.md +0 -0
  327. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.md +0 -0
  328. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.md +0 -0
  329. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Ward_Putting-i-in-Team.md +0 -0
  330. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.md +0 -0
  331. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.md +0 -0
  332. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.md +0 -0
  333. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.md +0 -0
  334. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.md +0 -0
  335. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.md +0 -0
  336. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.md +0 -0
  337. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.md +0 -0
  338. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.md +0 -0
  339. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.md +0 -0
  340. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.md +0 -0
  341. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.md +0 -0
  342. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.md +0 -0
  343. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/jump-performance/2011_Harper_10-to-5-Jump-Test.md +0 -0
  344. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.md +0 -0
  345. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/jump-performance/2014_Samozino_FV-Imbalance.md +0 -0
  346. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.md +0 -0
  347. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.md +0 -0
  348. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.md +0 -0
  349. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/jump-performance/2022_Wells_Golf-Clubhead-CMJ.md +0 -0
  350. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.md +0 -0
  351. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.md +0 -0
  352. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.md +0 -0
  353. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Moore_Economical-Running-Technique.md +0 -0
  354. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.md +0 -0
  355. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.md +0 -0
  356. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.md +0 -0
  357. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.md +0 -0
  358. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.md +0 -0
  359. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/smartphone-technology/2022_Bishop_MyJumpLab-Validation.md +0 -0
  360. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.md +0 -0
  361. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.md +0 -0
  362. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.md +0 -0
  363. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.md +0 -0
  364. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.md +0 -0
  365. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/markdown/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.md +0 -0
  366. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/online-references-for-papers.md +0 -0
  367. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.pdf +0 -0
  368. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.pdf +0 -0
  369. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.pdf +0 -0
  370. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.pdf +0 -0
  371. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Ward_Putting-i-in-Team.pdf +0 -0
  372. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.pdf +0 -0
  373. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.pdf +0 -0
  374. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.pdf +0 -0
  375. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.pdf +0 -0
  376. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.pdf +0 -0
  377. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.pdf +0 -0
  378. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.pdf +0 -0
  379. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.pdf +0 -0
  380. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.pdf +0 -0
  381. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.pdf +0 -0
  382. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.pdf +0 -0
  383. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.pdf +0 -0
  384. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.pdf +0 -0
  385. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/jump-performance/2011_Harper_10-to-5-Jump-Test.pdf +0 -0
  386. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.pdf +0 -0
  387. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/jump-performance/2014_Samozino_FV-Imbalance.pdf +0 -0
  388. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.pdf +0 -0
  389. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.pdf +0 -0
  390. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.pdf +0 -0
  391. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/jump-performance/2022_Wells_Golf-Clubhead-CMJ.pdf +0 -0
  392. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.pdf +0 -0
  393. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.pdf +0 -0
  394. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.pdf +0 -0
  395. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Moore_Economical-Running-Technique.pdf +0 -0
  396. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.pdf +0 -0
  397. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.pdf +0 -0
  398. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.pdf +0 -0
  399. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.pdf +0 -0
  400. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.pdf +0 -0
  401. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/smartphone-technology/2022_Bishop_MyJumpLab-Validation.pdf +0 -0
  402. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.pdf +0 -0
  403. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.pdf +0 -0
  404. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.pdf +0 -0
  405. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.pdf +0 -0
  406. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.pdf +0 -0
  407. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/research/thirdparty/pdfs/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.pdf +0 -0
  408. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/1-STRATEGIC_SUMMARY.md +0 -0
  409. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/2-STRATEGIC_ANALYSIS.md +0 -0
  410. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/MVP_FEEDBACK_COLLECTION.md +0 -0
  411. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/MVP_VALIDATION_CHECKPOINTS.md +0 -0
  412. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/README.md +0 -0
  413. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/STYLE_GUIDE.md +0 -0
  414. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/01-executive-summary.md +0 -0
  415. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/02-technical-assessment.md +0 -0
  416. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/03-refactoring-roadmap.md +0 -0
  417. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/README.md +0 -0
  418. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/BIOMECHANICS/01-executive-summary.md +0 -0
  419. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/BIOMECHANICS/02-technical-assessment.md +0 -0
  420. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/BIOMECHANICS/03-reference-guide.md +0 -0
  421. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/BIOMECHANICS/README.md +0 -0
  422. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/COMPUTER_VISION/01-executive-summary.md +0 -0
  423. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/COMPUTER_VISION/02-real-time-architecture.md +0 -0
  424. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/COMPUTER_VISION/03-implementation-checklist.md +0 -0
  425. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/COMPUTER_VISION/README.md +0 -0
  426. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/CONSOLIDATED/01-agent-consensus.md +0 -0
  427. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/CONSOLIDATED/02-critical-findings.md +0 -0
  428. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/CONSOLIDATED/03-roadmap-adjustments.md +0 -0
  429. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/CONSOLIDATED/04-decision-points.md +0 -0
  430. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/CONSOLIDATED/README.md +0 -0
  431. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/CONSOLIDATED/risk-register.md +0 -0
  432. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/CONSOLIDATED/timeline-roadmap.md +0 -0
  433. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/01-executive-summary.md +0 -0
  434. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/02-infrastructure-assessment.md +0 -0
  435. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/03-implementation-roadmap.md +0 -0
  436. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/README.md +0 -0
  437. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/01-executive-summary.md +0 -0
  438. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/02-technical-assessment.md +0 -0
  439. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/03-parameter-specifications.md +0 -0
  440. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/README.md +0 -0
  441. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/QA_TESTING/01-executive-summary.md +0 -0
  442. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/QA_TESTING/02-roadmap-assessment.md +0 -0
  443. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/QA_TESTING/03-testing-checklists.md +0 -0
  444. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/QA_TESTING/README.md +0 -0
  445. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/01-executive-summary.md +0 -0
  446. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/02-documentation-strategy.md +0 -0
  447. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/03-action-plan.md +0 -0
  448. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/README.md +0 -0
  449. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/strategy/pose2sim-migration-evaluation.md +0 -0
  450. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/technical/framerate.md +0 -0
  451. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/technical/implementation-details.md +0 -0
  452. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/technical/imu-metadata.md +0 -0
  453. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/technical/real-time-analysis.md +0 -0
  454. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/technical/triple-extension.md +0 -0
  455. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/translations/es/camera-setup.md +0 -0
  456. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/validation/determinism-test.md +0 -0
  457. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/validation/known-height-validation.md +0 -0
  458. {kinemotion-0.60.0 → kinemotion-0.61.0}/docs/validation-status.md +0 -0
  459. {kinemotion-0.60.0 → kinemotion-0.61.0}/examples/bulk/README.md +0 -0
  460. {kinemotion-0.60.0 → kinemotion-0.61.0}/examples/bulk/bulk_processing.py +0 -0
  461. {kinemotion-0.60.0 → kinemotion-0.61.0}/examples/bulk/simple_example.py +0 -0
  462. {kinemotion-0.60.0 → kinemotion-0.61.0}/examples/programmatic_usage.py +0 -0
  463. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/.editorconfig +0 -0
  464. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/.env.example +0 -0
  465. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/.gitattributes +0 -0
  466. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/.gitignore +0 -0
  467. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/.yarn/releases/yarn-4.12.0.cjs +0 -0
  468. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/.yarnrc.yml +0 -0
  469. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/README.md +0 -0
  470. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/index.html +0 -0
  471. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/package.json +0 -0
  472. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/App.i18n.integration.test.tsx +0 -0
  473. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/App.test.tsx +0 -0
  474. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/App.tsx +0 -0
  475. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/Auth.test.tsx +0 -0
  476. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/Auth.tsx +0 -0
  477. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/ErrorBoundary.test.tsx +0 -0
  478. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/ErrorBoundary.tsx +0 -0
  479. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/ErrorDisplay.tsx +0 -0
  480. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/FeatureRequestButton.tsx +0 -0
  481. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/FeedbackForm.css +0 -0
  482. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/FeedbackForm.test.tsx +0 -0
  483. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/FeedbackForm.tsx +0 -0
  484. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/LanguageSwitcher.css +0 -0
  485. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/LanguageSwitcher.test.tsx +0 -0
  486. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/LanguageSwitcher.tsx +0 -0
  487. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/LoadingSpinner.test.tsx +0 -0
  488. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/LoadingSpinner.tsx +0 -0
  489. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/RecentUploads.test.tsx +0 -0
  490. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/RecentUploads.tsx +0 -0
  491. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/ResultsDisplay.test.tsx +0 -0
  492. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/ResultsDisplay.tsx +0 -0
  493. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/ResultsSkeleton.tsx +0 -0
  494. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/UploadForm.test.tsx +0 -0
  495. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/components/UploadForm.tsx +0 -0
  496. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/config/links.ts +0 -0
  497. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/hooks/useAnalysis.test.ts +0 -0
  498. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/hooks/useAnalysis.ts +0 -0
  499. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/hooks/useAuth.ts +0 -0
  500. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/hooks/useBackendVersion.ts +0 -0
  501. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/hooks/useDatabaseStatus.ts +0 -0
  502. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/hooks/useLanguage.test.ts +0 -0
  503. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/hooks/useLanguage.ts +0 -0
  504. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/hooks/useRecentUploads.ts +0 -0
  505. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/i18n/config.ts +0 -0
  506. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/i18n/locales/en/translation.json +0 -0
  507. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/i18n/locales/es/translation.json +0 -0
  508. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/i18n/locales/fr/translation.json +0 -0
  509. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/index.css +0 -0
  510. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/main.tsx +0 -0
  511. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/test/setup.ts +0 -0
  512. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/types/api.ts +0 -0
  513. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/src/vite-env.d.ts +0 -0
  514. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/vercel.json +0 -0
  515. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/vite.config.ts +0 -0
  516. {kinemotion-0.60.0 → kinemotion-0.61.0}/frontend/yarn.lock +0 -0
  517. {kinemotion-0.60.0 → kinemotion-0.61.0}/justfile +0 -0
  518. {kinemotion-0.60.0 → kinemotion-0.61.0}/local_dev.sh +0 -0
  519. {kinemotion-0.60.0 → kinemotion-0.61.0}/mkdocs.yml +0 -0
  520. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/.gitignore +0 -0
  521. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/README.md +0 -0
  522. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/demos/.gitignore +0 -0
  523. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/demos/README.md +0 -0
  524. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/demos/api_demo.ipynb +0 -0
  525. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/demos/batch_processing_demo.py +0 -0
  526. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/demos/sample_data/.gitkeep +0 -0
  527. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/presentation_guide.md +0 -0
  528. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/revealjs/.gitignore +0 -0
  529. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/revealjs/Makefile +0 -0
  530. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/revealjs/README.md +0 -0
  531. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/revealjs/slides.md +0 -0
  532. {kinemotion-0.60.0 → kinemotion-0.61.0}/presentation/speaker_script.md +0 -0
  533. {kinemotion-0.60.0 → kinemotion-0.61.0}/requirements-docs.txt +0 -0
  534. {kinemotion-0.60.0 → kinemotion-0.61.0}/samples/cmjs/README.md +0 -0
  535. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/README.md +0 -0
  536. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/SCRIPTS_QUICKREF.md +0 -0
  537. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/analyze_determinism_variance.py +0 -0
  538. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/basic-memory-utils.sh +0 -0
  539. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/debug_contact_states.py +0 -0
  540. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/debug_detection.py +0 -0
  541. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/find_unused_features.py +0 -0
  542. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/generate_test_data.py +0 -0
  543. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/optimize_detection_params.py +0 -0
  544. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/plot_cmj_velocities.py +0 -0
  545. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/plot_validation_results.py +0 -0
  546. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/plot_velocities.py +0 -0
  547. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/prepare_ground_truth.py +0 -0
  548. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/project/README.md +0 -0
  549. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/project/add-issue.sh +0 -0
  550. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/project/batch-set-fields.sh +0 -0
  551. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/project/helpers.sh +0 -0
  552. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/project/list.sh +0 -0
  553. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/project/set-field.sh +0 -0
  554. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/project/set-status.sh +0 -0
  555. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/project/summary.sh +0 -0
  556. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/project.sh +0 -0
  557. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/setup-github-deploy.sh +0 -0
  558. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/setup-google-oauth.sh +0 -0
  559. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/setup-supabase-local.sh +0 -0
  560. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/setup-supabase-production.sh +0 -0
  561. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/test_acceleration_standing.py +0 -0
  562. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/test_determinism.sh +0 -0
  563. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/test_drop_start_debug.py +0 -0
  564. {kinemotion-0.60.0 → kinemotion-0.61.0}/scripts/validate_known_heights.py +0 -0
  565. {kinemotion-0.60.0 → kinemotion-0.61.0}/sonar-project.properties +0 -0
  566. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/__init__.py +0 -0
  567. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/api.py +0 -0
  568. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cli.py +0 -0
  569. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cmj/__init__.py +0 -0
  570. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/cmj/joint_angles.py +0 -0
  571. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/__init__.py +0 -0
  572. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/cli_utils.py +0 -0
  573. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/experimental.py +0 -0
  574. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/formatting.py +0 -0
  575. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/metadata.py +0 -0
  576. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/timing.py +0 -0
  577. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/core/video_io.py +0 -0
  578. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/dropjump/__init__.py +0 -0
  579. {kinemotion-0.60.0 → kinemotion-0.61.0}/src/kinemotion/py.typed +0 -0
  580. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/__init__.py +0 -0
  581. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cli/__init__.py +0 -0
  582. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cli/test_imports.py +0 -0
  583. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cmj/__init__.py +0 -0
  584. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/cmj/test_cli.py +0 -0
  585. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/conftest.py +0 -0
  586. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/__init__.py +0 -0
  587. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_auto_tuning.py +0 -0
  588. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_formatting.py +0 -0
  589. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_metadata.py +0 -0
  590. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/core/test_timing.py +0 -0
  591. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/dropjump/__init__.py +0 -0
  592. {kinemotion-0.60.0 → kinemotion-0.61.0}/tests/dropjump/test_cli.py +0 -0
@@ -134,7 +134,7 @@ jobs:
134
134
  --allow-unauthenticated
135
135
  --service-account=kinemotion-backend-runtime@${{ env.GCP_PROJECT_ID }}.iam.gserviceaccount.com
136
136
  --set-env-vars=CORS_ORIGINS=https://kinemotion.vercel.app,JSON_LOGS=true,LOG_LEVEL=INFO
137
- --set-secrets=SUPABASE_URL=SUPABASE_URL:latest,SUPABASE_ANON_KEY=SUPABASE_ANON_KEY:latest,R2_ENDPOINT=R2_ENDPOINT:latest,R2_ACCESS_KEY=R2_ACCESS_KEY:latest,R2_SECRET_KEY=R2_SECRET_KEY:latest,R2_BUCKET_NAME=R2_BUCKET_NAME:latest
137
+ --set-secrets=SUPABASE_URL=SUPABASE_URL:latest,SUPABASE_PUBLISHABLE_KEY=SUPABASE_PUBLISHABLE_KEY:latest,SUPABASE_SECRET_KEY=SUPABASE_SECRET_KEY:latest,R2_ENDPOINT=R2_ENDPOINT:latest,R2_ACCESS_KEY=R2_ACCESS_KEY:latest,R2_SECRET_KEY=R2_SECRET_KEY:latest,R2_BUCKET_NAME=R2_BUCKET_NAME:latest
138
138
 
139
139
  - name: Verify deployment health
140
140
  run: |
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  <!-- version list -->
9
9
 
10
+ ## kinemotion-v0.61.0 (2025-12-15)
11
+
12
+ ### Feat
13
+
14
+ - update Supabase integration to use modern API keys
15
+ - update frontend to use modern Supabase publishable key
16
+
17
+ ## kinemotion-v0.60.1 (2025-12-15)
18
+
19
+ ### Fix
20
+
21
+ - prevent auth_duration_ms from polluting non-auth logs
22
+
10
23
  ## kinemotion-v0.60.0 (2025-12-15)
11
24
 
12
25
  ### Feat
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kinemotion
3
- Version: 0.60.0
3
+ Version: 0.61.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
@@ -80,7 +80,7 @@ filterwarnings = [
80
80
  ]
81
81
 
82
82
  [tool.ruff]
83
- line-length = 88
83
+ line-length = 99
84
84
  target-version = "py310"
85
85
 
86
86
  [tool.ruff.lint]
@@ -118,9 +118,7 @@ async def get_user_analysis_sessions(
118
118
  )
119
119
 
120
120
  db_client = get_database_client()
121
- sessions = await db_client.get_user_analysis_sessions(
122
- user_id=user_id, limit=limit
123
- )
121
+ sessions = await db_client.get_user_analysis_sessions(user_id=user_id, limit=limit)
124
122
 
125
123
  logger.info(
126
124
  "user_analysis_sessions_api_retrieved",
@@ -164,9 +162,7 @@ async def get_analysis_session(
164
162
  """
165
163
  try:
166
164
  db_client = get_database_client()
167
- session = await db_client.get_analysis_session(
168
- session_id=session_id, user_id=user_id
169
- )
165
+ session = await db_client.get_analysis_session(session_id=session_id, user_id=user_id)
170
166
 
171
167
  if not session:
172
168
  raise HTTPException(
@@ -185,9 +181,7 @@ async def get_analysis_session(
185
181
  )
186
182
 
187
183
  session_with_feedback = AnalysisSessionWithFeedback(**session)
188
- session_with_feedback.feedback = [
189
- CoachFeedbackResponse(**fb) for fb in feedback
190
- ]
184
+ session_with_feedback.feedback = [CoachFeedbackResponse(**fb) for fb in feedback]
191
185
 
192
186
  return session_with_feedback
193
187
 
@@ -31,9 +31,7 @@ class Settings:
31
31
  R2_SECRET_KEY: str = os.getenv("R2_SECRET_KEY", "")
32
32
  R2_BUCKET_NAME: str = os.getenv("R2_BUCKET_NAME", "kinemotion")
33
33
  R2_PUBLIC_BASE_URL: str = os.getenv("R2_PUBLIC_BASE_URL", "").rstrip("/")
34
- R2_PRESIGN_EXPIRATION_S: int = int(
35
- os.getenv("R2_PRESIGN_EXPIRATION_S", "604800")
36
- ) # 7 days
34
+ R2_PRESIGN_EXPIRATION_S: int = int(os.getenv("R2_PRESIGN_EXPIRATION_S", "604800")) # 7 days
37
35
 
38
36
  # Security settings
39
37
  TESTING: bool = os.getenv("TESTING", "").lower() == "true"
@@ -114,18 +114,14 @@ def _add_exception_handlers(app: FastAPI) -> None:
114
114
  from fastapi import HTTPException, Request
115
115
  from fastapi.responses import JSONResponse
116
116
 
117
- async def http_exception_handler(
118
- request: Request, exc: HTTPException
119
- ) -> JSONResponse:
117
+ async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
120
118
  """Handle HTTP exceptions."""
121
119
  return JSONResponse(
122
120
  status_code=exc.status_code,
123
121
  content={"message": exc.detail},
124
122
  )
125
123
 
126
- async def general_exception_handler(
127
- request: Request, exc: Exception
128
- ) -> JSONResponse:
124
+ async def general_exception_handler(request: Request, exc: Exception) -> JSONResponse:
129
125
  """Handle general exceptions."""
130
126
  logger.error(f"Unhandled exception: {exc}", exc_info=True)
131
127
  return JSONResponse(
@@ -118,9 +118,7 @@ class R2StorageClient:
118
118
  self.public_base_url = (os.getenv("R2_PUBLIC_BASE_URL") or "").rstrip("/")
119
119
  # Fallback: presigned URL expiration seconds (default 7 days, S3 max)
120
120
  try:
121
- self.presign_expiration_s = int(
122
- os.getenv("R2_PRESIGN_EXPIRATION_S") or "604800"
123
- )
121
+ self.presign_expiration_s = int(os.getenv("R2_PRESIGN_EXPIRATION_S") or "604800")
124
122
  except ValueError:
125
123
  self.presign_expiration_s = 604800
126
124
 
@@ -171,9 +169,7 @@ class R2StorageClient:
171
169
  normalized_key = key.lstrip("/")
172
170
  if self.public_base_url:
173
171
  return f"{self.public_base_url}/{normalized_key}"
174
- return self.generate_presigned_url(
175
- normalized_key, expiration=self.presign_expiration_s
176
- )
172
+ return self.generate_presigned_url(normalized_key, expiration=self.presign_expiration_s)
177
173
 
178
174
  def upload_file(self, local_path: str, remote_key: str) -> str:
179
175
  """Upload file to R2 storage.
@@ -386,8 +382,7 @@ def _validate_video_file(file: UploadFile) -> None:
386
382
  file_ext = Path(file.filename).suffix.lower()
387
383
  if file_ext not in valid_extensions:
388
384
  raise ValueError(
389
- f"Invalid video format: {file_ext}. "
390
- f"Supported formats: {', '.join(valid_extensions)}"
385
+ f"Invalid video format: {file_ext}. Supported formats: {', '.join(valid_extensions)}"
391
386
  )
392
387
 
393
388
  # Check file size (max 500MB for practical limits)
@@ -650,9 +645,7 @@ async def analyze_video(
650
645
  upload_start = time.time()
651
646
  r2_video_key = f"videos/{jump_type}/{upload_id}{upload_suffix}"
652
647
  try:
653
- original_video_url = r2_client.upload_file(
654
- temp_video_path, r2_video_key
655
- )
648
+ original_video_url = r2_client.upload_file(temp_video_path, r2_video_key)
656
649
  upload_duration = time.time() - upload_start
657
650
  logger.info(
658
651
  "timing_r2_input_video_upload",
@@ -700,8 +693,7 @@ async def analyze_video(
700
693
  timing_breakdown = metrics["metadata"]["processing"]["timing_breakdown_ms"]
701
694
  # Normalize keys: remove special chars, spaces → underscores, lowercase
702
695
  normalized_timings = {
703
- re.sub(r"[^\w\s]", "", stage).lower().replace(" ", "_")
704
- + "_ms": duration
696
+ re.sub(r"[^\w\s]", "", stage).lower().replace(" ", "_") + "_ms": duration
705
697
  for stage, duration in timing_breakdown.items()
706
698
  }
707
699
  # Log each timing stage as a separate event for granular monitoring
@@ -728,9 +720,7 @@ async def analyze_video(
728
720
  try:
729
721
  results_upload_start = time.time()
730
722
  results_json = json.dumps(metrics, indent=2)
731
- results_url = r2_client.put_object(
732
- r2_results_key, results_json.encode()
733
- )
723
+ results_url = r2_client.put_object(r2_results_key, results_json.encode())
734
724
  results_upload_duration = time.time() - results_upload_start
735
725
  logger.info(
736
726
  "timing_r2_results_upload",
@@ -740,9 +730,7 @@ async def analyze_video(
740
730
  )
741
731
  except OSError as e:
742
732
  # Log error but don't fail - results still available in response
743
- logger.warning(
744
- "r2_results_upload_failed", error=str(e), key=r2_results_key
745
- )
733
+ logger.warning("r2_results_upload_failed", error=str(e), key=r2_results_key)
746
734
 
747
735
  # Upload Debug Video if it was created
748
736
  if (
@@ -892,9 +880,7 @@ async def analyze_video(
892
880
  Path(temp_video_path).unlink()
893
881
  logger.debug("temp_file_cleaned", path=temp_video_path)
894
882
  except OSError as e:
895
- logger.warning(
896
- "temp_file_cleanup_failed", path=temp_video_path, error=str(e)
897
- )
883
+ logger.warning("temp_file_cleanup_failed", path=temp_video_path, error=str(e))
898
884
 
899
885
  # Clean up temporary debug video file
900
886
  if temp_debug_video_path and Path(temp_debug_video_path).exists():
@@ -110,9 +110,7 @@ class SupabaseAuth:
110
110
  # Fallback: Verify via Supabase Auth server (works for all projects)
111
111
  return self._verify_via_auth_server(token, start_time)
112
112
 
113
- def _verify_via_auth_server(
114
- self, token: str, overall_start_time: float
115
- ) -> dict[str, Any]:
113
+ def _verify_via_auth_server(self, token: str, overall_start_time: float) -> dict[str, Any]:
116
114
  """Verify token by calling Supabase Auth server.
117
115
 
118
116
  This is the recommended fallback for HS256 tokens per Supabase docs.
@@ -15,13 +15,24 @@ class DatabaseClient:
15
15
  def __init__(self) -> None:
16
16
  """Initialize Supabase client."""
17
17
  self.supabase_url = os.getenv("SUPABASE_URL", "")
18
- self.supabase_key = os.getenv("SUPABASE_ANON_KEY", "")
18
+
19
+ # Prefer modern keys, fall back to legacy for compatibility
20
+ self.supabase_key = (
21
+ os.getenv("SUPABASE_PUBLISHABLE_KEY")
22
+ or os.getenv("SUPABASE_SECRET_KEY")
23
+ or os.getenv("SUPABASE_ANON_KEY")
24
+ or os.getenv("SUPABASE_KEY")
25
+ )
19
26
 
20
27
  if not self.supabase_url:
21
28
  raise ValueError("SUPABASE_URL must be set")
22
29
 
23
30
  if not self.supabase_key:
24
- raise ValueError("SUPABASE_ANON_KEY must be set")
31
+ raise ValueError(
32
+ "No Supabase API key found. Set one of: "
33
+ "SUPABASE_PUBLISHABLE_KEY, SUPABASE_SECRET_KEY, "
34
+ "SUPABASE_ANON_KEY, or SUPABASE_KEY"
35
+ )
25
36
 
26
37
  self.client: Client = create_client(self.supabase_url, self.supabase_key)
27
38
  logger.info("database_client_initialized", supabase_url=self.supabase_url)
@@ -70,9 +81,7 @@ class DatabaseClient:
70
81
  "upload_id": upload_id,
71
82
  }
72
83
 
73
- response = (
74
- self.client.table("analysis_sessions").insert(session_data).execute()
75
- )
84
+ response = self.client.table("analysis_sessions").insert(session_data).execute()
76
85
 
77
86
  if response.data:
78
87
  session_data = response.data[0]
@@ -140,9 +149,7 @@ class DatabaseClient:
140
149
  )
141
150
  raise
142
151
 
143
- async def get_analysis_session(
144
- self, session_id: str, user_id: str
145
- ) -> dict[str, Any] | None:
152
+ async def get_analysis_session(self, session_id: str, user_id: str) -> dict[str, Any] | None:
146
153
  """Get a specific analysis session.
147
154
 
148
155
  Args:
@@ -160,9 +167,7 @@ class DatabaseClient:
160
167
  self.client.table("analysis_sessions")
161
168
  .select("*")
162
169
  .eq("id", session_id)
163
- .eq(
164
- "user_id", user_id
165
- ) # Ensure user can only access their own sessions
170
+ .eq("user_id", user_id) # Ensure user can only access their own sessions
166
171
  .single()
167
172
  .execute()
168
173
  )
@@ -217,9 +222,7 @@ class DatabaseClient:
217
222
  "tags": tags or [],
218
223
  }
219
224
 
220
- response = (
221
- self.client.table("coach_feedback").insert(feedback_data).execute()
222
- )
225
+ response = self.client.table("coach_feedback").insert(feedback_data).execute()
223
226
 
224
227
  if response.data:
225
228
  feedback_data = response.data[0]
@@ -246,9 +249,7 @@ class DatabaseClient:
246
249
  )
247
250
  raise
248
251
 
249
- async def get_session_feedback(
250
- self, analysis_session_id: str
251
- ) -> list[dict[str, Any]]:
252
+ async def get_session_feedback(self, analysis_session_id: str) -> list[dict[str, Any]]:
252
253
  """Get all feedback for an analysis session.
253
254
 
254
255
  Args:
@@ -19,9 +19,7 @@ try:
19
19
  supabase_auth = SupabaseAuth()
20
20
  logger.info("supabase_auth_initialized")
21
21
  except ValueError:
22
- logger.warning(
23
- "supabase_auth_not_configured", message="Supabase credentials not provided"
24
- )
22
+ logger.warning("supabase_auth_not_configured", message="Supabase credentials not provided")
25
23
 
26
24
 
27
25
  class RequestLoggingMiddleware(BaseHTTPMiddleware):
@@ -62,11 +60,10 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
62
60
  user_email = supabase_auth.get_user_email(token)
63
61
  auth_duration_ms = (time.time() - auth_start) * 1000
64
62
 
65
- # Bind user info to logging context
63
+ # Bind user info to logging context (auth_duration_ms only in auth event)
66
64
  structlog.contextvars.bind_contextvars(
67
65
  user_id=user_id,
68
66
  user_email=user_email,
69
- auth_duration_ms=round(auth_duration_ms, 2),
70
67
  )
71
68
 
72
69
  # Store in request state for use in endpoints
@@ -75,8 +72,6 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
75
72
 
76
73
  logger.info(
77
74
  "user_authenticated",
78
- user_id=user_id,
79
- email=user_email,
80
75
  auth_duration_ms=round(auth_duration_ms, 2),
81
76
  )
82
77
  except Exception as e:
@@ -14,15 +14,11 @@ class AnalysisSessionCreate(BaseModel):
14
14
  quality_preset: str = Field(
15
15
  ..., description="Analysis quality: 'fast', 'balanced', or 'accurate'"
16
16
  )
17
- original_video_url: str | None = Field(
18
- None, description="R2 URL for original video"
19
- )
17
+ original_video_url: str | None = Field(None, description="R2 URL for original video")
20
18
  debug_video_url: str | None = Field(None, description="R2 URL for debug video")
21
19
  results_json_url: str | None = Field(None, description="R2 URL for results JSON")
22
20
  analysis_data: dict[str, Any] = Field(..., description="Analysis results as JSON")
23
- processing_time_s: float | None = Field(
24
- None, description="Processing time in seconds"
25
- )
21
+ processing_time_s: float | None = Field(None, description="Processing time in seconds")
26
22
  upload_id: str | None = Field(None, description="Upload ID from analysis system")
27
23
 
28
24
  @field_validator("jump_type")
@@ -65,9 +61,7 @@ class CoachFeedbackCreate(BaseModel):
65
61
  analysis_session_id: UUID = Field(..., description="ID of the analysis session")
66
62
  notes: str | None = Field(None, description="Coach notes about the analysis")
67
63
  rating: int | None = Field(None, ge=1, le=5, description="Rating from 1-5")
68
- tags: list[str] = Field(
69
- default_factory=list, description="Tags for categorizing feedback"
70
- )
64
+ tags: list[str] = Field(default_factory=list, description="Tags for categorizing feedback")
71
65
 
72
66
  @field_validator("rating")
73
67
  @classmethod
@@ -14,9 +14,7 @@ class ValidationIssue(BaseModel):
14
14
  class ValidationResults(BaseModel):
15
15
  """Validation results from analysis."""
16
16
 
17
- status: str = Field(
18
- ..., description="Status: PASS, FAIL, WARNING, or PASS_WITH_WARNINGS"
19
- )
17
+ status: str = Field(..., description="Status: PASS, FAIL, WARNING, or PASS_WITH_WARNINGS")
20
18
  issues: list[ValidationIssue] = Field(
21
19
  default_factory=list, description="List of validation issues"
22
20
  )
@@ -26,9 +24,7 @@ class MetricsData(BaseModel):
26
24
  """Analysis metrics with optional metadata and validation."""
27
25
 
28
26
  data: dict[str, Any] | None = Field(None, description="Actual metric values")
29
- metadata: dict[str, Any] | None = Field(
30
- None, description="Metric metadata and descriptions"
31
- )
27
+ metadata: dict[str, Any] | None = Field(None, description="Metric metadata and descriptions")
32
28
  validation: ValidationResults | None = Field(
33
29
  None, description="Validation results for metrics"
34
30
  )
@@ -21,9 +21,7 @@ class R2StorageClient:
21
21
  self.public_base_url = (os.getenv("R2_PUBLIC_BASE_URL") or "").rstrip("/")
22
22
  # Fallback: presigned URL expiration seconds (default 7 days, S3 max)
23
23
  try:
24
- self.presign_expiration_s = int(
25
- os.getenv("R2_PRESIGN_EXPIRATION_S") or "604800"
26
- )
24
+ self.presign_expiration_s = int(os.getenv("R2_PRESIGN_EXPIRATION_S") or "604800")
27
25
  except ValueError:
28
26
  self.presign_expiration_s = 604800
29
27
 
@@ -74,9 +72,7 @@ class R2StorageClient:
74
72
  normalized_key = key.lstrip("/")
75
73
  if self.public_base_url:
76
74
  return f"{self.public_base_url}/{normalized_key}"
77
- return self.generate_presigned_url(
78
- normalized_key, expiration=self.presign_expiration_s
79
- )
75
+ return self.generate_presigned_url(normalized_key, expiration=self.presign_expiration_s)
80
76
 
81
77
  def upload_file(self, local_path: str, remote_key: str) -> str:
82
78
  """Upload file to R2 storage.
@@ -0,0 +1,53 @@
1
+ """Health check routes for kinemotion backend."""
2
+
3
+ import os
4
+ from datetime import datetime, timezone
5
+ from importlib.metadata import version
6
+
7
+ import structlog
8
+ from fastapi import APIRouter
9
+
10
+ logger = structlog.get_logger()
11
+ router = APIRouter(tags=["Health"])
12
+
13
+
14
+ @router.get("/health")
15
+ async def health_check() -> dict[str, str | bool]:
16
+ """Health check endpoint.
17
+
18
+ Returns:
19
+ Dict with health status information
20
+ """
21
+ # Check R2 configuration
22
+ r2_configured = bool(
23
+ os.getenv("R2_ENDPOINT") and os.getenv("R2_ACCESS_KEY") and os.getenv("R2_SECRET_KEY")
24
+ )
25
+
26
+ # Get kinemotion version safely
27
+ try:
28
+ kinemotion_version = version("kinemotion")
29
+ except Exception:
30
+ kinemotion_version = "unknown"
31
+
32
+ # Check database connection
33
+ database_connected = False
34
+ try:
35
+ from kinemotion_backend.database import get_database_client
36
+
37
+ db_client = get_database_client()
38
+ # Test database with a simple query
39
+ db_client.client.table("analysis_sessions").select("id").limit(1).execute()
40
+ database_connected = True
41
+ except Exception as db_error:
42
+ logger.warning("database_health_check_failed", error=str(db_error))
43
+
44
+ return {
45
+ "status": "healthy",
46
+ "service": "kinemotion-backend",
47
+ "version": "0.1.0",
48
+ "environment": os.getenv("ENVIRONMENT", "development"),
49
+ "kinemotion_version": kinemotion_version,
50
+ "timestamp": datetime.now(timezone.utc).isoformat(),
51
+ "r2_configured": r2_configured,
52
+ "database_connected": database_connected,
53
+ }
@@ -110,9 +110,7 @@ class AnalysisService:
110
110
  temp_debug = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
111
111
  temp_debug_video_path = temp_debug.name
112
112
  temp_debug.close()
113
- logger.info(
114
- "debug_video_path_created", debug_video_path=temp_debug_video_path
115
- )
113
+ logger.info("debug_video_path_created", debug_video_path=temp_debug_video_path)
116
114
 
117
115
  # Process video with detailed timing
118
116
  logger.info("video_processing_started")
@@ -24,9 +24,7 @@ class StorageService:
24
24
  """
25
25
  return self.client.upload_file(local_path, remote_key)
26
26
 
27
- async def upload_analysis_results(
28
- self, results: dict[str, Any], remote_key: str
29
- ) -> str:
27
+ async def upload_analysis_results(self, results: dict[str, Any], remote_key: str) -> str:
30
28
  """Upload analysis results as JSON to R2 storage.
31
29
 
32
30
  Args:
@@ -41,9 +39,7 @@ class StorageService:
41
39
  results_json = json.dumps(results, indent=2).encode("utf-8")
42
40
  return self.client.put_object(remote_key, results_json)
43
41
 
44
- async def generate_unique_key(
45
- self, filename: str, user_id: str | None = None
46
- ) -> str:
42
+ async def generate_unique_key(self, filename: str, user_id: str | None = None) -> str:
47
43
  """Generate unique storage key for uploaded file.
48
44
 
49
45
  Args:
@@ -21,8 +21,7 @@ def validate_video_file(file: UploadFile) -> None:
21
21
  file_ext = Path(file.filename).suffix.lower()
22
22
  if file_ext not in valid_extensions:
23
23
  raise ValueError(
24
- f"Invalid video format: {file_ext}. "
25
- f"Supported formats: {', '.join(valid_extensions)}"
24
+ f"Invalid video format: {file_ext}. Supported formats: {', '.join(valid_extensions)}"
26
25
  )
27
26
 
28
27
  # Check file size if available (UploadFile.size is often None in test client)
@@ -0,0 +1,70 @@
1
+
2
+ -- Enable required extensions
3
+ CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
4
+
5
+ -- Analysis Sessions Table
6
+ CREATE TABLE IF NOT EXISTS analysis_sessions (
7
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
8
+ user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
9
+ jump_type VARCHAR(50) NOT NULL CHECK (jump_type IN ('cmj', 'drop_jump')),
10
+ quality_preset VARCHAR(20) NOT NULL CHECK (quality_preset IN ('fast', 'balanced', 'accurate')),
11
+ original_video_url TEXT,
12
+ debug_video_url TEXT,
13
+ results_json_url TEXT,
14
+ analysis_data JSONB NOT NULL,
15
+ processing_time_s FLOAT,
16
+ upload_id VARCHAR(50),
17
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
18
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
19
+ );
20
+
21
+ -- Coach Feedback Table
22
+ CREATE TABLE IF NOT EXISTS coach_feedback (
23
+ id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
24
+ analysis_session_id UUID NOT NULL REFERENCES analysis_sessions(id) ON DELETE CASCADE,
25
+ coach_user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
26
+ notes TEXT,
27
+ rating INTEGER CHECK (rating >= 1 AND rating <= 5),
28
+ tags TEXT[] DEFAULT '{}',
29
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
30
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
31
+ );
32
+
33
+ -- Create indexes for performance
34
+ CREATE INDEX IF NOT EXISTS idx_analysis_sessions_user_id ON analysis_sessions(user_id);
35
+ CREATE INDEX IF NOT EXISTS idx_analysis_sessions_created_at ON analysis_sessions(created_at DESC);
36
+ CREATE INDEX IF NOT EXISTS idx_coach_feedback_analysis_session_id ON coach_feedback(analysis_session_id);
37
+ CREATE INDEX IF NOT EXISTS idx_coach_feedback_coach_user_id ON coach_feedback(coach_user_id);
38
+
39
+ -- Enable Row Level Security
40
+ ALTER TABLE analysis_sessions ENABLE ROW LEVEL SECURITY;
41
+ ALTER TABLE coach_feedback ENABLE ROW LEVEL SECURITY;
42
+
43
+ -- RLS Policy: Users can only see their own analysis sessions
44
+ CREATE POLICY "users_can_read_own_sessions" ON analysis_sessions
45
+ FOR SELECT
46
+ USING (auth.uid() = user_id);
47
+
48
+ CREATE POLICY "users_can_create_own_sessions" ON analysis_sessions
49
+ FOR INSERT
50
+ WITH CHECK (auth.uid() = user_id);
51
+
52
+ -- RLS Policy: Coaches can read feedback for their own analyses or sessions they're coaching
53
+ CREATE POLICY "coaches_can_read_feedback" ON coach_feedback
54
+ FOR SELECT
55
+ USING (
56
+ auth.uid() = coach_user_id OR
57
+ auth.uid() IN (
58
+ SELECT user_id FROM analysis_sessions
59
+ WHERE id = coach_feedback.analysis_session_id
60
+ )
61
+ );
62
+
63
+ CREATE POLICY "coaches_can_create_feedback" ON coach_feedback
64
+ FOR INSERT
65
+ WITH CHECK (auth.uid() = coach_user_id);
66
+
67
+ CREATE POLICY "coaches_can_update_own_feedback" ON coach_feedback
68
+ FOR UPDATE
69
+ USING (auth.uid() = coach_user_id)
70
+ WITH CHECK (auth.uid() = coach_user_id);
@@ -97,8 +97,7 @@ def mock_kinemotion_analysis(
97
97
  "kinemotion_backend.services.storage_service.StorageService.upload_video"
98
98
  )
99
99
  upload_results_patch = (
100
- "kinemotion_backend.services.storage_service."
101
- "StorageService.upload_analysis_results"
100
+ "kinemotion_backend.services.storage_service.StorageService.upload_analysis_results"
102
101
  )
103
102
  with (
104
103
  patch(cmj_patch) as mock_cmj,
@@ -162,15 +162,11 @@ def test_multiple_errors_sequential(
162
162
  files_valid = {"file": ("test.mp4", BytesIO(sample_video_bytes), "video/mp4")}
163
163
 
164
164
  # First request with invalid file
165
- response1 = client.post(
166
- "/api/analyze", files=files_invalid, data={"jump_type": "cmj"}
167
- )
165
+ response1 = client.post("/api/analyze", files=files_invalid, data={"jump_type": "cmj"})
168
166
  assert response1.status_code == 422
169
167
 
170
168
  # Second request with valid file
171
- response2 = client.post(
172
- "/api/analyze", files=files_valid, data={"jump_type": "cmj"}
173
- )
169
+ response2 = client.post("/api/analyze", files=files_valid, data={"jump_type": "cmj"})
174
170
  assert response2.status_code == 200
175
171
 
176
172
 
@@ -220,9 +216,7 @@ def test_keyboard_interrupt_returns_500(
220
216
  cmj_patch = "kinemotion_backend.services.video_processor.process_cmj_video"
221
217
  with patch(cmj_patch) as mock_cmj:
222
218
  mock_cmj.side_effect = KeyboardInterrupt()
223
- response = client.post(
224
- "/api/analyze", files=files, data={"jump_type": "cmj"}
225
- )
219
+ response = client.post("/api/analyze", files=files, data={"jump_type": "cmj"})
226
220
 
227
221
  assert response.status_code == 500
228
222
  except KeyboardInterrupt:
@@ -154,9 +154,7 @@ def test_r2_upload_file_success() -> None:
154
154
  with patch("kinemotion_backend.models.storage.boto3.client") as mock_boto3:
155
155
  mock_s3 = MagicMock()
156
156
  mock_boto3.return_value = mock_s3
157
- mock_s3.generate_presigned_url.return_value = (
158
- "https://r2.example.com/presigned-url"
159
- )
157
+ mock_s3.generate_presigned_url.return_value = "https://r2.example.com/presigned-url"
160
158
 
161
159
  client = R2StorageClient()
162
160
  url = client.upload_file("/tmp/test.mp4", "videos/test.mp4")
@@ -252,9 +250,7 @@ def test_get_object_url_with_custom_expiration() -> None:
252
250
  with patch("kinemotion_backend.models.storage.boto3.client") as mock_boto3:
253
251
  mock_s3 = MagicMock()
254
252
  mock_boto3.return_value = mock_s3
255
- mock_s3.generate_presigned_url.return_value = (
256
- "https://r2.example.com/presigned"
257
- )
253
+ mock_s3.generate_presigned_url.return_value = "https://r2.example.com/presigned"
258
254
 
259
255
  client = R2StorageClient()
260
256
  url = client.get_object_url("videos/test.mp4")
@@ -416,9 +412,7 @@ def test_r2_put_object_success() -> None:
416
412
  with patch("kinemotion_backend.models.storage.boto3.client") as mock_boto3:
417
413
  mock_s3 = MagicMock()
418
414
  mock_boto3.return_value = mock_s3
419
- mock_s3.generate_presigned_url.return_value = (
420
- "https://r2.example.com/presigned-url"
421
- )
415
+ mock_s3.generate_presigned_url.return_value = "https://r2.example.com/presigned-url"
422
416
 
423
417
  client = R2StorageClient()
424
418
  url = client.put_object("results/test.json", b'{"status": "ok"}')