kinemotion 0.60.1__tar.gz → 0.62.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.
- kinemotion-0.62.0/.basic-memory/api/testing-backend-authentication-quick-reference.md +158 -0
- kinemotion-0.62.0/.basic-memory/project-management/backend-authentication-architecture-decision.md +98 -0
- kinemotion-0.62.0/.basic-memory/project-management/backend-authentication-implementation-complete.md +137 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.github/workflows/deploy-backend.yml +1 -1
- {kinemotion-0.60.1 → kinemotion-0.62.0}/CHANGELOG.md +19 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/PKG-INFO +1 -1
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/auth.py +4 -1
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/database.py +19 -3
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/middleware.py +1 -1
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/analysis.py +67 -4
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/health.py +21 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/__init__.py +7 -1
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/validation.py +14 -2
- kinemotion-0.62.0/backend/supabase-schema.sql +70 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/tests/conftest.py +10 -2
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/ResultsDisplay.tsx +11 -5
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/hooks/useDatabaseStatus.ts +7 -11
- kinemotion-0.62.0/frontend/src/lib/supabase.ts +23 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/pyproject.toml +1 -1
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/supabasedb/setup-supabase-database.sh +23 -15
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/supabasedb/setup_supabase_db.py +21 -13
- {kinemotion-0.60.1 → kinemotion-0.62.0}/uv.lock +1 -1
- kinemotion-0.60.1/backend/supabase-schema.sql +0 -148
- kinemotion-0.60.1/frontend/src/lib/supabase.ts +0 -20
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/api/api-reference-quick-commands.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/api/cloud-run-cpu-specifications-investigation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/api/supabase-authentication-setup-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/authentication/auth-provider-comparison-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/authentication/auth-providers-comparison-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-authentication-quick-start.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-authentication-setup-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-authentication-technical-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-google-oauth-setup-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-production-setup-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-quick-start-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/biomechanics/camera-angle-empirical-validation-results-45-superior-for-media-pipe.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/biomechanics/camera-perspective-analysis-45deg-vs-lateral.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/biomechanics/cmj-landing-detection-window-validation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/biomechanics/cmj-physiological-bounds-for-validation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/biomechanics/cmj-validation-implementation-complete.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/biomechanics/drop-jump-vs-cmj-key-differences.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/biomechanics/technical-implementation-45deg-perspective-correction.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/codebase/codebase-architecture-overview.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/codebase/validation-architecture-visual-hierarchy-after-refactoring.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/codebase/validation-code-duplication-evidence.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/codebase/validation-module-architecture-analysis.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/codebase/validation-refactoring-complete-architecture-improvement.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/automated-deployment-setup-git-hub-actions-with-workload-identity-federation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/backend-repository-split-migration-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/backend-repository-split-step-by-step-execution-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/cloud-run-security-least-privilege-service-account-setup.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/cors-and-memory-issues-production-debugging-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/current-kinemotion-architecture-correct-deployment-setup.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/frontend-repository-split-migration-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/frontend-repository-split-step-by-step-execution-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/production-deployment-guide-vercel-google-cloud-run.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/quick-deployment-commands-vercel-and-cloud-run.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/deployment/vercel-monorepo-deployment-best-practice.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/athlete-pose3d-and-cross-platform-determinism-investigation-complete.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/athlete-pose3d-final-strategy-accuracy-and-robustness.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/athlete-pose3d-media-pipe-enhancement-plan.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/athlete-pose3d-phase-1-implementation-complete.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/backend-authentication-and-logging-status.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/backend-code-coverage-analysis.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/backend-code-duplication-analysis.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/backend-granular-logging-implementation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/backend-kinemotion-decoupling-strategy.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/backend-sonar-cloud-integration-status.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/basic-memory-naming-hook-analysis.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/ci-caching-issue-investigation-deep-squat-test-failure.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/ci-vs-local-test-failure-investigation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/claude-code-hook-configuration.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/cmj-phase-detection-testing-gap-analysis.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/commit-review-r2-video-storage-migration-fe74d1f.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/comprehensive-timing-instrumentation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/cross-platform-determinism-analysis-final-results.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/database-setup-scripts-complete-implementation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/development-standards-quality-gates.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/drop-jump-detection-complete-fix-all-metrics-within-target.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/drop-jump-detection-failure-analysis-per-video-breakdown.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/drop-jump-fix-drop-start-successful-landing-and-takeoff-remain.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/fast-api-app.py Refactoring Plan - Modular Architecture.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/fast-api-refactoring-completion-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/feature-request-system-configuration.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/follow-up-improvements-to-r2-video-storage-migration.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/frontend-dependencies-analysis-nov-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/google-oauth-setup-script-final-review-production-ready.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/google-oauth-setup-script-review-issues-and-recommendations.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/hook-complete-audit-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/hook-configuration-audit.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/hook-quick-reference.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/i18n-implementation-plan-for-validation-messages.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/keyboard-interrupt-test-suite-failure-analysis.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/model-import-conflict-resolution-fast-api-refactoring.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/non-deterministic-analysis-root-cause-and-solution.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/optimal-timing-implementation-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/p0-p1-p2-test-suite-fixes-final-report.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/pose-detection-baseline-evaluation-results.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/pose-detection-optimization-complete-success-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/pose-detection-parameter-optimization-framework.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/structured-logging-implementation-complete.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/structured-logging-implementation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/supabase-dashboard-navigation-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/supabase-database-integration-setup.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/supabase-documentation-validation-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/test-coverage-asymmetry-analysis-cmj-vs-drop-jump.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/test-coverage-equivalence-achievement-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/test-suite-comprehensive-review-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/test-suite-comprehensive-review-structure-and-gaps.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-complete-report.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-progress-report.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/unused-and-experimental-features-strategy.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/unused-code-detection-prompt-template.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/unused-code-identification-and-decorator-application-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/unused-code-verification-final-pass-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/using-multiple-mcp-reasoning-servers-simultaneously.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/velocity-threshold-empirical-validation-study.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/development/vercel-authentication-options-for-user-id-tracking.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/agent-documentation-standards-update.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/documentation-audit-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/i18n-documentation-cleanup-completed.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/issue-12-mvp-scaffolding-complete.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/issue-12-unblocked-tasks-breakdown.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/issue-12-use-real-metrics-now.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/kinemotion-project-setup-complete.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/kinemotion-supabase-production-configuration.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/mcp-sequential-thinking-alternatives-analysis.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/performance-optimization-pose-tracker-pool-timing-instrumentation-complete.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/project-state-summary-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/specialized-subagents-routing-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/supabase-setup-instructions-for-kinemotion.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/project-management/version-mismatch-analysis-kinemotion-0370-vs-0300.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/research/performance-improvement-analysis-30s-18s.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/strategy/deployment-decision-analysis-for-kinemotion.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/strategy/mvp-feedback-collection-plan.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/strategy/mvp-first-strategic-direction.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/strategy/mvp-validation-checkpoints.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/strategy/pose2sim-migration-evaluation-and-strategy.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/strategy/strategic-priority-tasks-current-roadmap.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.basic-memory/strategy/third-party-auth-providers-with-free-tiers-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/agents/biomechanics-specialist.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/agents/computer-vision-engineer.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/agents/devops-cicd-engineer.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/agents/frontend-developer.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/agents/ml-data-scientist.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/agents/project-manager.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/agents/python-backend-developer.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/agents/qa-test-engineer.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/agents/technical-writer.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.claude/settings.local.json +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.cursor/mcp.json +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.dockerignore +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.envrc +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.gitattributes +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.github/dependabot.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.github/pull_request_template.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.github/workflows/docs.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.github/workflows/release.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.github/workflows/test.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.gitignore +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.mcp.json +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.pre-commit-config.yaml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.readthedocs.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/.gitignore +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/backend-cors-fastapi-middleware-order.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/camera-perspective-validation-study.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/code_style_and_conventions.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/current-project-architecture.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/deployment-checklist-and-known-issues.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/deployment-setup-complete.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/github-project-setup-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/mvp-first-strategy.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/mvp-roadmap-and-priorities.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/project_overview.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/specialist-agents-routing.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/memories/suggested_commands.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.serena/project.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.tool-versions +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/.vercelignore +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/CLAUDE.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/CODE_OF_CONDUCT.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/CONTRIBUTING.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/Dockerfile +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/GEMINI.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/LICENSE +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/SECURITY.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/.coveragerc +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/.dockerignore +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/.env.example +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/Dockerfile +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/docs/fly-deployment.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/docs/implementation-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/docs/setup.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/docs/tests.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/pyproject.toml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/analysis_api.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/config.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/dependencies.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/exceptions.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/main.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/logging_config.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/models/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/models/database.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/models/responses.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/models/storage.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/database.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/platform.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/analysis_service.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/storage_service.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/video_processor.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/types.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/utils/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/src/kinemotion_backend/utils/rate_limiter.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/tests/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/tests/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/tests/test_api_endpoints.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/tests/test_error_handling.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/tests/test_health.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/tests/test_r2_integration.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/backend/tests/test_validation.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/api/cmj.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/api/core.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/api/dropjump.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/api/overview.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/I18N-README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/agents-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/errors-findings.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/feature-request-system.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/feedback-system-setup.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/i18n-architecture-diagram.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/i18n-cheat-sheet.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/i18n-quick-start-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/i18n-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/i18n-validation-messages-specification.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/supabase-database-setup.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/test-suite-review-december-2025.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/testing-standards.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/testing.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/type-hints.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/validation-plan.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/validation-roadmap.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/development/wallball-norep-detection.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/bulk-processing.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/camera-setup.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/cloud-run-deployment.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/cmj-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/cmj-recording-protocol-es.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/cmj-recording-protocol.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/deployment-checklist.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/local-testing.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/setup-issue-12.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/supabase-setup/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/supabase-setup/quickstart.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/supabase-setup/scripts-reference.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/guides/supabase-setup/setup-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/index.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/quick-start.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/reference/cloud-run-quick-reference.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/reference/json-output-format.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/reference/json-structure-comparison.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/reference/parameters.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/reference/pose-systems.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/paper-downloader/HOW-TO-FIND-DOIS.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/paper-downloader/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/paper-downloader/dois.txt +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/paper-downloader/download.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/paper-downloader/pyproject.toml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/paper-downloader/uv.lock +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/sports-biomechanics-pose-estimation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/MANUAL-DOWNLOAD-GUIDE.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/convert_pdfs.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Ward_Putting-i-in-Team.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2011_Harper_10-to-5-Jump-Test.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2014_Samozino_FV-Imbalance.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2022_Wells_Golf-Clubhead-CMJ.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Moore_Economical-Running-Technique.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/smartphone-technology/2022_Bishop_MyJumpLab-Validation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/online-references-for-papers.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Ward_Putting-i-in-Team.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2011_Harper_10-to-5-Jump-Test.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2014_Samozino_FV-Imbalance.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2022_Wells_Golf-Clubhead-CMJ.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Moore_Economical-Running-Technique.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/smartphone-technology/2022_Bishop_MyJumpLab-Validation.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.pdf +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/1-STRATEGIC_SUMMARY.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/2-STRATEGIC_ANALYSIS.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/MVP_FEEDBACK_COLLECTION.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/MVP_VALIDATION_CHECKPOINTS.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/STYLE_GUIDE.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/01-executive-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/02-technical-assessment.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/03-refactoring-roadmap.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BIOMECHANICS/01-executive-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BIOMECHANICS/02-technical-assessment.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BIOMECHANICS/03-reference-guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BIOMECHANICS/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/COMPUTER_VISION/01-executive-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/COMPUTER_VISION/02-real-time-architecture.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/COMPUTER_VISION/03-implementation-checklist.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/COMPUTER_VISION/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/01-agent-consensus.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/02-critical-findings.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/03-roadmap-adjustments.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/04-decision-points.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/risk-register.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/timeline-roadmap.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/01-executive-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/02-infrastructure-assessment.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/03-implementation-roadmap.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/01-executive-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/02-technical-assessment.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/03-parameter-specifications.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/QA_TESTING/01-executive-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/QA_TESTING/02-roadmap-assessment.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/QA_TESTING/03-testing-checklists.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/QA_TESTING/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/01-executive-summary.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/02-documentation-strategy.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/03-action-plan.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/strategy/pose2sim-migration-evaluation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/technical/framerate.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/technical/implementation-details.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/technical/imu-metadata.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/technical/real-time-analysis.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/technical/triple-extension.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/translations/es/camera-setup.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/validation/determinism-test.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/validation/known-height-validation.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/docs/validation-status.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/examples/bulk/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/examples/bulk/bulk_processing.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/examples/bulk/simple_example.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/examples/programmatic_usage.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/.editorconfig +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/.env.example +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/.gitattributes +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/.gitignore +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/.yarn/releases/yarn-4.12.0.cjs +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/.yarnrc.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/index.html +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/package.json +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/App.i18n.integration.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/App.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/App.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/Auth.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/Auth.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/ErrorBoundary.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/ErrorBoundary.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/ErrorDisplay.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/FeatureRequestButton.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/FeedbackForm.css +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/FeedbackForm.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/FeedbackForm.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/LanguageSwitcher.css +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/LanguageSwitcher.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/LanguageSwitcher.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/LoadingSpinner.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/LoadingSpinner.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/RecentUploads.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/RecentUploads.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/ResultsDisplay.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/ResultsSkeleton.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/UploadForm.test.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/components/UploadForm.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/config/links.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/hooks/useAnalysis.test.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/hooks/useAnalysis.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/hooks/useAuth.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/hooks/useBackendVersion.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/hooks/useLanguage.test.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/hooks/useLanguage.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/hooks/useRecentUploads.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/i18n/config.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/i18n/locales/en/translation.json +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/i18n/locales/es/translation.json +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/i18n/locales/fr/translation.json +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/index.css +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/main.tsx +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/test/setup.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/types/api.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/src/vite-env.d.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/vercel.json +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/vite.config.ts +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/frontend/yarn.lock +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/justfile +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/local_dev.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/mkdocs.yml +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/.gitignore +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/demos/.gitignore +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/demos/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/demos/api_demo.ipynb +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/demos/batch_processing_demo.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/demos/sample_data/.gitkeep +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/presentation_guide.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/revealjs/.gitignore +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/revealjs/Makefile +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/revealjs/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/revealjs/slides.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/presentation/speaker_script.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/requirements-docs.txt +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/samples/cmjs/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/SCRIPTS_QUICKREF.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/analyze_determinism_variance.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/basic-memory-utils.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/debug_contact_states.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/debug_detection.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/find_unused_features.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/generate_test_data.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/optimize_detection_params.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/plot_cmj_velocities.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/plot_validation_results.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/plot_velocities.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/prepare_ground_truth.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/project/README.md +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/project/add-issue.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/project/batch-set-fields.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/project/helpers.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/project/list.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/project/set-field.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/project/set-status.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/project/summary.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/project.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/setup-github-deploy.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/setup-google-oauth.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/setup-supabase-local.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/setup-supabase-production.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/test_acceleration_standing.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/test_determinism.sh +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/test_drop_start_debug.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/scripts/validate_known_heights.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/sonar-project.properties +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/api.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cli.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cmj/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cmj/analysis.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cmj/api.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cmj/cli.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cmj/debug_overlay.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cmj/joint_angles.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cmj/kinematics.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cmj/metrics_validator.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/cmj/validation_bounds.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/auto_tuning.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/cli_utils.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/debug_overlay_utils.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/determinism.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/experimental.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/filtering.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/formatting.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/metadata.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/pipeline_utils.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/pose.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/quality.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/smoothing.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/timing.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/validation.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/core/video_io.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/dropjump/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/dropjump/analysis.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/dropjump/api.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/dropjump/cli.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/dropjump/debug_overlay.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/dropjump/kinematics.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/dropjump/metrics_validator.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/dropjump/validation_bounds.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/src/kinemotion/py.typed +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cli/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cli/test_cmj.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cli/test_dropjump.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cli/test_imports.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cmj/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cmj/test_analysis.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cmj/test_api.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cmj/test_cli.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cmj/test_joint_angles.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cmj/test_kinematics.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/cmj/test_physiological_bounds.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/conftest.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_auto_tuning.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_cli_utils.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_filtering.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_formatting.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_metadata.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_pipeline_utils.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_pose.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_quality.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_smoothing.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_timing.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_validation.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/core/test_video_io.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/dropjump/__init__.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/dropjump/test_adaptive_threshold.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/dropjump/test_analysis.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/dropjump/test_api.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/dropjump/test_cli.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/dropjump/test_contact_detection.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/dropjump/test_kinematics.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/dropjump/test_physiological_bounds.py +0 -0
- {kinemotion-0.60.1 → kinemotion-0.62.0}/tests/dropjump/test_validation_integration.py +0 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Testing Backend Authentication - Quick Reference
|
|
3
|
+
type: note
|
|
4
|
+
permalink: api/testing-backend-authentication-quick-reference
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Testing Backend Authentication
|
|
8
|
+
|
|
9
|
+
## Backdoor Testing (No JWT Required)
|
|
10
|
+
|
|
11
|
+
### Using curl
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Test /analyze endpoint with backdoor
|
|
15
|
+
curl -X POST http://localhost:8000/api/analyze \
|
|
16
|
+
-H "x-test-password: your-test-password" \
|
|
17
|
+
-F "file=@video.mp4" \
|
|
18
|
+
-F "jump_type=cmj" \
|
|
19
|
+
-F "quality=balanced"
|
|
20
|
+
|
|
21
|
+
# Test with debug video
|
|
22
|
+
curl -X POST http://localhost:8000/api/analyze \
|
|
23
|
+
-H "x-test-password: your-test-password" \
|
|
24
|
+
-F "file=@video.mp4" \
|
|
25
|
+
-F "jump_type=cmj" \
|
|
26
|
+
-F "quality=balanced" \
|
|
27
|
+
-F "debug=true"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Using Postman
|
|
31
|
+
|
|
32
|
+
1. Method: `POST`
|
|
33
|
+
2. URL: `http://localhost:8000/api/analyze`
|
|
34
|
+
3. Headers tab:
|
|
35
|
+
- Add: `x-test-password: your-test-password`
|
|
36
|
+
4. Body tab → form-data:
|
|
37
|
+
- `file` (type: File) → select video
|
|
38
|
+
- `jump_type` (type: Text) → `cmj` or `drop_jump`
|
|
39
|
+
- `quality` (type: Text) → `fast`, `balanced`, or `accurate`
|
|
40
|
+
- `debug` (type: Text, optional) → `true` or `false`
|
|
41
|
+
|
|
42
|
+
### Setting Environment Variables
|
|
43
|
+
|
|
44
|
+
**Local development** (`.env`):
|
|
45
|
+
```bash
|
|
46
|
+
TEST_PASSWORD=my-secret-testing-password
|
|
47
|
+
TEST_USER_ID=test-user-00000000-0000-0000-0000-000000000000
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Cloud Run deployment** (via GitHub Actions or gcloud):
|
|
51
|
+
```bash
|
|
52
|
+
gcloud run services update kinemotion-backend \
|
|
53
|
+
--region us-central1 \
|
|
54
|
+
--set-env-vars TEST_PASSWORD=my-secret-password
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Production Testing (With JWT)
|
|
60
|
+
|
|
61
|
+
### Frontend Integration
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// 1. Get session after user logs in
|
|
65
|
+
const { session } = useAuth()
|
|
66
|
+
|
|
67
|
+
// 2. Use token in Authorization header
|
|
68
|
+
const token = session?.access_token
|
|
69
|
+
const response = await fetch(`${backendUrl}/api/analyze`, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: {
|
|
72
|
+
'Authorization': `Bearer ${token}`
|
|
73
|
+
},
|
|
74
|
+
body: formData
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Testing with Personal JWT (Advanced)
|
|
79
|
+
|
|
80
|
+
If you need to test without frontend:
|
|
81
|
+
|
|
82
|
+
1. Log in to app via frontend
|
|
83
|
+
2. Open browser DevTools Console
|
|
84
|
+
3. Get your token:
|
|
85
|
+
```javascript
|
|
86
|
+
const { data } = await supabase.auth.getSession()
|
|
87
|
+
console.log(data.session.access_token)
|
|
88
|
+
```
|
|
89
|
+
4. Use in curl:
|
|
90
|
+
```bash
|
|
91
|
+
curl -X POST http://localhost:8000/api/analyze \
|
|
92
|
+
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
|
|
93
|
+
-F "file=@video.mp4" \
|
|
94
|
+
-F "jump_type=cmj"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Verifying User ID Organization in R2
|
|
100
|
+
|
|
101
|
+
After successful upload, check R2 bucket:
|
|
102
|
+
|
|
103
|
+
**Backdoor test** → Should be in:
|
|
104
|
+
```
|
|
105
|
+
uploads/test-user-00000000-0000-0000-0000-000000000000/2025/12/15/...
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Authenticated user** → Should be in:
|
|
109
|
+
```
|
|
110
|
+
uploads/{user_id}/2025/12/15/...
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Where `{user_id}` is the Supabase user UUID.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Troubleshooting
|
|
118
|
+
|
|
119
|
+
### 401 Unauthorized (No backdoor)
|
|
120
|
+
|
|
121
|
+
**Error**: `Authentication required`
|
|
122
|
+
|
|
123
|
+
**Causes**:
|
|
124
|
+
- Missing `Authorization` header
|
|
125
|
+
- Invalid JWT token
|
|
126
|
+
- Expired token
|
|
127
|
+
- TEST_PASSWORD not configured
|
|
128
|
+
|
|
129
|
+
**Solution**:
|
|
130
|
+
- Provide valid JWT token, OR
|
|
131
|
+
- Set TEST_PASSWORD env var and use `x-test-password` header
|
|
132
|
+
|
|
133
|
+
### 403 Forbidden (Referer Check)
|
|
134
|
+
|
|
135
|
+
**Error**: `Direct API access not allowed. Use the web interface.`
|
|
136
|
+
|
|
137
|
+
**Causes**:
|
|
138
|
+
- Missing Referer header
|
|
139
|
+
- Referer from unauthorized origin
|
|
140
|
+
|
|
141
|
+
**Solution**:
|
|
142
|
+
- Use from frontend (referer set automatically), OR
|
|
143
|
+
- Include `x-test-password` header to bypass (if TEST_PASSWORD set)
|
|
144
|
+
|
|
145
|
+
### Files in anonymous/ folder
|
|
146
|
+
|
|
147
|
+
**Cause**: Uploading with TEST_PASSWORD but not setting TEST_USER_ID
|
|
148
|
+
|
|
149
|
+
**Solution**: Set TEST_USER_ID env var or use authenticated request
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Success Indicators
|
|
154
|
+
|
|
155
|
+
✅ Response includes metrics and URLs (JSON 200)
|
|
156
|
+
✅ Files in R2 under `uploads/{user_id}/...` not `anonymous/`
|
|
157
|
+
✅ Can save feedback to `/api/analysis/sessions` with same auth
|
|
158
|
+
✅ Logs show `user_id` in analysis started/completed entries
|
kinemotion-0.62.0/.basic-memory/project-management/backend-authentication-architecture-decision.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Backend Authentication Architecture Decision
|
|
3
|
+
type: note
|
|
4
|
+
permalink: project-management/backend-authentication-architecture-decision
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Authentication Architecture Options for /analyze Endpoint
|
|
8
|
+
|
|
9
|
+
## Current State
|
|
10
|
+
- `/analyze` endpoint: **Public (no auth)** → files saved as `anonymous`
|
|
11
|
+
- `/api/analysis/sessions` endpoint: **Requires auth** → 401 errors until SUPABASE_PUBLISHABLE_KEY was set
|
|
12
|
+
- Issue: User IDs never passed to storage, so no user organization in R2
|
|
13
|
+
|
|
14
|
+
## Option A: Add Authentication to /analyze
|
|
15
|
+
Require JWT token for video analysis upload
|
|
16
|
+
|
|
17
|
+
### Pros
|
|
18
|
+
- User uploads immediately organized by user ID in R2 (no "anonymous" folder clutter)
|
|
19
|
+
- Single consistent auth model across entire backend
|
|
20
|
+
- Session ID returned from analysis is tied to authenticated user
|
|
21
|
+
- Easier user management and analytics (know who uploaded what)
|
|
22
|
+
- Prevents abuse (rate limiting per user instead of globally)
|
|
23
|
+
- Better for compliance/auditing (track all user actions)
|
|
24
|
+
|
|
25
|
+
### Cons
|
|
26
|
+
- **Breaks existing workflow**: Frontend must authenticate BEFORE uploading video
|
|
27
|
+
- Frontend must fetch auth token before making `/analyze` request
|
|
28
|
+
- Adds latency to video upload (auth check required)
|
|
29
|
+
- API less flexible (can't generate quick demos without login)
|
|
30
|
+
- Complicates testing/development (need to authenticate first)
|
|
31
|
+
- Reduces discoverability (users must login to try the feature)
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Option B: Keep /analyze Public, Return Session ID
|
|
36
|
+
Keep video analysis public but return ephemeral session ID that can be claimed by authenticated user
|
|
37
|
+
|
|
38
|
+
### Pros
|
|
39
|
+
- **Zero friction user experience**: Upload video immediately without login
|
|
40
|
+
- Users can try the feature without committing to account creation
|
|
41
|
+
- Better for demos and marketing
|
|
42
|
+
- Faster upload (no auth overhead)
|
|
43
|
+
- Reduces initial friction to adoption
|
|
44
|
+
- Guests can analyze videos without creating account
|
|
45
|
+
- Optional: Can send session to email/link for later claiming
|
|
46
|
+
|
|
47
|
+
### Cons
|
|
48
|
+
- Files stay in `anonymous/` folder (harder to organize)
|
|
49
|
+
- Session IDs need TTL (expire after N hours if not claimed)
|
|
50
|
+
- Need migration logic to move anonymous sessions to user when they login
|
|
51
|
+
- More complex database schema (sessions linked to either user_id or session_id)
|
|
52
|
+
- Harder to enforce rate limiting (per IP instead of per user)
|
|
53
|
+
- Anonymous sessions could fill up storage
|
|
54
|
+
- Audit trail less complete (guest activities not tracked)
|
|
55
|
+
- Two different storage paths to manage
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Option C: Both (Recommended)
|
|
60
|
+
Offer both authenticated AND guest analysis
|
|
61
|
+
|
|
62
|
+
### Pros
|
|
63
|
+
- **Best UX**: Guests can try immediately, authenticated users get benefits
|
|
64
|
+
- Maximizes adoption (low barrier to entry)
|
|
65
|
+
- Users experience value before creating account
|
|
66
|
+
- Authenticated users get proper tracking/organization
|
|
67
|
+
- Can implement "upgrade" flow (guest → user)
|
|
68
|
+
- Flexible for different use cases (demos, research, production)
|
|
69
|
+
- Solves the "try before you buy" problem
|
|
70
|
+
- Future monetization: Basic (guest) vs Premium (registered)
|
|
71
|
+
|
|
72
|
+
### Cons
|
|
73
|
+
- **Most complex**: Handle both auth and anonymous sessions
|
|
74
|
+
- Two code paths to maintain and test
|
|
75
|
+
- Database migration needed (sessions table needs optional user_id)
|
|
76
|
+
- Storage organization more complicated (both `anonymous/` and `users/{id}/`)
|
|
77
|
+
- Rate limiting needs dual strategy (per-IP for guests, per-user for authenticated)
|
|
78
|
+
- More edge cases to handle and debug
|
|
79
|
+
- Longer development timeline
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Recommendation Context
|
|
84
|
+
|
|
85
|
+
**For MVP (current goal):**
|
|
86
|
+
- Option B (guest-friendly) makes sense if you're trying to get product in coaches' hands quickly
|
|
87
|
+
- Coaches can try without friction
|
|
88
|
+
- You get immediate feedback on use cases
|
|
89
|
+
|
|
90
|
+
**For Production (coaches paying):**
|
|
91
|
+
- Option C (both) provides best UX
|
|
92
|
+
- Coaches get analytics/tracking when they're part of org
|
|
93
|
+
- Guests can demonstrate to team before purchasing
|
|
94
|
+
|
|
95
|
+
**Current Blocker:**
|
|
96
|
+
- Fix auth.py to use SUPABASE_PUBLISHABLE_KEY (DONE) ✅
|
|
97
|
+
- This unblocks Option A or C immediately
|
|
98
|
+
- Option B requires no backend changes (already works)
|
kinemotion-0.62.0/.basic-memory/project-management/backend-authentication-implementation-complete.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Backend Authentication Implementation Complete
|
|
3
|
+
type: note
|
|
4
|
+
permalink: project-management/backend-authentication-implementation-complete
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Backend Authentication Implementation
|
|
8
|
+
|
|
9
|
+
## Changes Made
|
|
10
|
+
|
|
11
|
+
### 1. Fixed SupabaseAuth to Support Modern Supabase Keys ✅
|
|
12
|
+
**File**: `backend/src/kinemotion_backend/auth.py`
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
# Before: Only checked SUPABASE_ANON_KEY
|
|
16
|
+
self.supabase_anon_key = os.getenv("SUPABASE_ANON_KEY", "")
|
|
17
|
+
|
|
18
|
+
# After: Prefers modern keys, falls back to legacy
|
|
19
|
+
self.supabase_anon_key = (
|
|
20
|
+
os.getenv("SUPABASE_PUBLISHABLE_KEY")
|
|
21
|
+
or os.getenv("SUPABASE_ANON_KEY")
|
|
22
|
+
or ""
|
|
23
|
+
)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This fixes JWT token verification in the `/api/analysis/sessions` endpoint when using modern Supabase API key format (`sb_publishable_...`).
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
### 2. Added Authentication to /analyze Endpoint ✅
|
|
31
|
+
**File**: `backend/src/kinemotion_backend/routes/analysis.py`
|
|
32
|
+
|
|
33
|
+
- Requires JWT token in `Authorization: Bearer <token>` header
|
|
34
|
+
- Extracts user_id from token
|
|
35
|
+
- Passes user_id to storage service for proper R2 organization
|
|
36
|
+
- **Backdoor for testing**: Accept `x-test-password` header to bypass auth
|
|
37
|
+
|
|
38
|
+
**New helper function**:
|
|
39
|
+
```python
|
|
40
|
+
async def get_user_id_for_analysis(
|
|
41
|
+
credentials: HTTPAuthorizationCredentials | None = Depends(security),
|
|
42
|
+
x_test_password: str | None = Header(None),
|
|
43
|
+
) -> str:
|
|
44
|
+
# If TEST_PASSWORD matches x-test-password header, use test user ID
|
|
45
|
+
# Otherwise validate JWT token
|
|
46
|
+
# Returns user_id in both cases
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### 3. Added Test Password Backdoor Utility ✅
|
|
52
|
+
**File**: `backend/src/kinemotion_backend/services/validation.py`
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
def is_test_password_valid(x_test_password: str | None = None) -> bool:
|
|
56
|
+
"""Check if test password is valid (for debugging backdoor)."""
|
|
57
|
+
test_password = os.getenv("TEST_PASSWORD")
|
|
58
|
+
return bool(test_password and x_test_password == test_password)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This centralizes the backdoor check for reuse across endpoints.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## How the Authentication Flow Works
|
|
66
|
+
|
|
67
|
+
### For Production (Authenticated Users)
|
|
68
|
+
1. Frontend user logs in with Supabase auth
|
|
69
|
+
2. Frontend gets JWT token from `session.access_token`
|
|
70
|
+
3. Frontend includes `Authorization: Bearer <token>` header in POST to `/analyze`
|
|
71
|
+
4. Backend validates token using SupabaseAuth
|
|
72
|
+
5. Backend extracts user_id from token
|
|
73
|
+
6. Uploads organized in R2 as `uploads/{user_id}/2025/12/15/...`
|
|
74
|
+
|
|
75
|
+
### For Testing/Debugging (Backdoor)
|
|
76
|
+
1. Set `TEST_PASSWORD` environment variable on backend
|
|
77
|
+
2. Use curl or Postman with `x-test-password` header matching TEST_PASSWORD
|
|
78
|
+
3. Backend bypasses JWT validation
|
|
79
|
+
4. Uploads organized in R2 as `uploads/test-user-00000000-0000-0000-0000-000000000000/...` (or custom TEST_USER_ID)
|
|
80
|
+
|
|
81
|
+
**Example curl**:
|
|
82
|
+
```bash
|
|
83
|
+
curl -X POST http://localhost:8000/api/analyze \
|
|
84
|
+
-H "x-test-password: my-secret-password" \
|
|
85
|
+
-F "file=@video.mp4" \
|
|
86
|
+
-F "jump_type=cmj" \
|
|
87
|
+
-F "quality=balanced"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Files Modified
|
|
93
|
+
|
|
94
|
+
1. ✅ `backend/src/kinemotion_backend/auth.py` - Support modern Supabase keys
|
|
95
|
+
2. ✅ `backend/src/kinemotion_backend/routes/analysis.py` - Add auth + backdoor
|
|
96
|
+
3. ✅ `backend/src/kinemotion_backend/services/validation.py` - Add backdoor check utility
|
|
97
|
+
4. ✅ `backend/src/kinemotion_backend/services/__init__.py` - Export backdoor utility
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Next Steps
|
|
102
|
+
|
|
103
|
+
1. **Deploy to Cloud Run** with these environment variables:
|
|
104
|
+
- `SUPABASE_PUBLISHABLE_KEY` (already set)
|
|
105
|
+
- `SUPABASE_SECRET_KEY` (already set)
|
|
106
|
+
- `TEST_PASSWORD=your-secret-password` (for backdoor)
|
|
107
|
+
- `TEST_USER_ID=optional-custom-test-user-id` (defaults to test-user-...)
|
|
108
|
+
|
|
109
|
+
2. **Update frontend** to send JWT token:
|
|
110
|
+
```typescript
|
|
111
|
+
const token = session?.access_token
|
|
112
|
+
const response = await fetch(`${backendUrl}/api/analyze`, {
|
|
113
|
+
method: 'POST',
|
|
114
|
+
headers: {
|
|
115
|
+
'Authorization': `Bearer ${token}`
|
|
116
|
+
},
|
|
117
|
+
body: formData
|
|
118
|
+
})
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
3. **Test feedback submission** end-to-end:
|
|
122
|
+
- Upload video (authenticated)
|
|
123
|
+
- See upload organized by user_id in R2
|
|
124
|
+
- Save feedback (uses same auth)
|
|
125
|
+
- Verify both operations use authenticated user
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Architecture Decision
|
|
130
|
+
|
|
131
|
+
✅ **Option A Selected**: Require authentication on both `/analyze` and `/api/analysis/sessions`
|
|
132
|
+
|
|
133
|
+
- All user uploads immediately organized by user_id in R2
|
|
134
|
+
- Single consistent auth model across all endpoints
|
|
135
|
+
- Rate limiting per-user (not per-IP)
|
|
136
|
+
- Full audit trail
|
|
137
|
+
- Backdoor for testing/debugging without creating test accounts
|
|
@@ -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,
|
|
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,25 @@ 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.62.0 (2025-12-15)
|
|
11
|
+
|
|
12
|
+
### Feat
|
|
13
|
+
|
|
14
|
+
- implement complete backend authentication with modern Supabase key support
|
|
15
|
+
|
|
16
|
+
### Fix
|
|
17
|
+
|
|
18
|
+
- use useAuth hook to get session token for feedback submission
|
|
19
|
+
- use backend API URL for feedback submission
|
|
20
|
+
- use environment variable for backend API URL in database status check
|
|
21
|
+
|
|
22
|
+
## kinemotion-v0.61.0 (2025-12-15)
|
|
23
|
+
|
|
24
|
+
### Feat
|
|
25
|
+
|
|
26
|
+
- update Supabase integration to use modern API keys
|
|
27
|
+
- update frontend to use modern Supabase publishable key
|
|
28
|
+
|
|
10
29
|
## kinemotion-v0.60.1 (2025-12-15)
|
|
11
30
|
|
|
12
31
|
### Fix
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kinemotion
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.62.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
|
|
@@ -31,7 +31,10 @@ class SupabaseAuth:
|
|
|
31
31
|
def __init__(self) -> None:
|
|
32
32
|
"""Initialize Supabase authentication."""
|
|
33
33
|
self.supabase_url = os.getenv("SUPABASE_URL", "")
|
|
34
|
-
|
|
34
|
+
# Prefer modern keys, fall back to legacy for compatibility
|
|
35
|
+
self.supabase_anon_key = (
|
|
36
|
+
os.getenv("SUPABASE_PUBLISHABLE_KEY") or os.getenv("SUPABASE_ANON_KEY") or ""
|
|
37
|
+
)
|
|
35
38
|
|
|
36
39
|
if not self.supabase_url:
|
|
37
40
|
raise ValueError("SUPABASE_URL must be set")
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import os
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
6
|
+
import httpx
|
|
6
7
|
import structlog
|
|
7
8
|
from supabase import Client, create_client
|
|
8
9
|
|
|
@@ -15,15 +16,30 @@ class DatabaseClient:
|
|
|
15
16
|
def __init__(self) -> None:
|
|
16
17
|
"""Initialize Supabase client."""
|
|
17
18
|
self.supabase_url = os.getenv("SUPABASE_URL", "")
|
|
18
|
-
|
|
19
|
+
|
|
20
|
+
# Prefer modern keys, fall back to legacy for compatibility
|
|
21
|
+
self.supabase_key = (
|
|
22
|
+
os.getenv("SUPABASE_PUBLISHABLE_KEY")
|
|
23
|
+
or os.getenv("SUPABASE_SECRET_KEY")
|
|
24
|
+
or os.getenv("SUPABASE_ANON_KEY")
|
|
25
|
+
or os.getenv("SUPABASE_KEY")
|
|
26
|
+
)
|
|
19
27
|
|
|
20
28
|
if not self.supabase_url:
|
|
21
29
|
raise ValueError("SUPABASE_URL must be set")
|
|
22
30
|
|
|
23
31
|
if not self.supabase_key:
|
|
24
|
-
raise ValueError(
|
|
32
|
+
raise ValueError(
|
|
33
|
+
"No Supabase API key found. Set one of: "
|
|
34
|
+
"SUPABASE_PUBLISHABLE_KEY, SUPABASE_SECRET_KEY, "
|
|
35
|
+
"SUPABASE_ANON_KEY, or SUPABASE_KEY"
|
|
36
|
+
)
|
|
25
37
|
|
|
26
|
-
|
|
38
|
+
# Configure http client with timeout and verify settings to avoid deprecation warnings
|
|
39
|
+
http_client = httpx.Client(timeout=10.0, verify=True)
|
|
40
|
+
self.client: Client = create_client(
|
|
41
|
+
self.supabase_url, self.supabase_key, http_client=http_client
|
|
42
|
+
)
|
|
27
43
|
logger.info("database_client_initialized", supabase_url=self.supabase_url)
|
|
28
44
|
|
|
29
45
|
async def create_analysis_session(
|
|
@@ -54,8 +54,8 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
|
|
|
54
54
|
auth_header = request.headers.get("authorization")
|
|
55
55
|
if auth_header and auth_header.startswith("Bearer ") and supabase_auth:
|
|
56
56
|
token = auth_header.replace("Bearer ", "")
|
|
57
|
+
auth_start = time.time()
|
|
57
58
|
try:
|
|
58
|
-
auth_start = time.time()
|
|
59
59
|
user_id = supabase_auth.get_user_id(token)
|
|
60
60
|
user_email = supabase_auth.get_user_email(token)
|
|
61
61
|
auth_duration_ms = (time.time() - auth_start) * 1000
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
"""Video analysis routes for kinemotion backend."""
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
import time
|
|
4
5
|
|
|
5
|
-
from fastapi import
|
|
6
|
+
from fastapi import (
|
|
7
|
+
APIRouter,
|
|
8
|
+
Depends,
|
|
9
|
+
File,
|
|
10
|
+
Form,
|
|
11
|
+
Header,
|
|
12
|
+
HTTPException,
|
|
13
|
+
Request,
|
|
14
|
+
UploadFile,
|
|
15
|
+
status,
|
|
16
|
+
)
|
|
6
17
|
from fastapi.responses import JSONResponse
|
|
7
18
|
|
|
8
19
|
try:
|
|
@@ -13,9 +24,10 @@ except ImportError:
|
|
|
13
24
|
fastapi_limiter_available = False
|
|
14
25
|
RateLimiter = None # type: ignore[assignment]
|
|
15
26
|
|
|
27
|
+
from ..auth import SupabaseAuth
|
|
16
28
|
from ..logging_config import get_logger
|
|
17
29
|
from ..models.responses import AnalysisResponse
|
|
18
|
-
from ..services import AnalysisService, validate_referer
|
|
30
|
+
from ..services import AnalysisService, is_test_password_valid, validate_referer
|
|
19
31
|
from ..utils import NoOpLimiter
|
|
20
32
|
|
|
21
33
|
logger = get_logger(__name__)
|
|
@@ -29,6 +41,51 @@ else:
|
|
|
29
41
|
limiter = RateLimiter() # type: ignore[operator]
|
|
30
42
|
|
|
31
43
|
|
|
44
|
+
async def get_user_id_for_analysis(
|
|
45
|
+
request: Request,
|
|
46
|
+
x_test_password: str | None = Header(None), # noqa: B008
|
|
47
|
+
) -> str:
|
|
48
|
+
"""Extract user ID from JWT token or use test backdoor.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
request: HTTP request (to access Authorization header)
|
|
52
|
+
x_test_password: Optional test password for debugging
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
User ID (from token or test backdoor)
|
|
56
|
+
|
|
57
|
+
Raises:
|
|
58
|
+
HTTPException: If authentication fails and test password not provided
|
|
59
|
+
"""
|
|
60
|
+
# Allow bypass with test password (for curl testing, debugging)
|
|
61
|
+
if is_test_password_valid(x_test_password):
|
|
62
|
+
test_user_id = os.getenv("TEST_USER_ID", "test-user-00000000-0000-0000-0000-000000000000")
|
|
63
|
+
logger.info("analysis_test_password_used", user_id=test_user_id)
|
|
64
|
+
return test_user_id
|
|
65
|
+
|
|
66
|
+
# Otherwise require valid JWT token from Authorization header
|
|
67
|
+
auth_header = request.headers.get("authorization")
|
|
68
|
+
if not auth_header or not auth_header.startswith("Bearer "):
|
|
69
|
+
raise HTTPException(
|
|
70
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
71
|
+
detail="Authentication required",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
token = auth_header.replace("Bearer ", "")
|
|
75
|
+
try:
|
|
76
|
+
auth = SupabaseAuth()
|
|
77
|
+
user_id = auth.get_user_id(token)
|
|
78
|
+
return user_id
|
|
79
|
+
except HTTPException:
|
|
80
|
+
raise
|
|
81
|
+
except Exception as e:
|
|
82
|
+
logger.error("user_id_extraction_failed", error=str(e))
|
|
83
|
+
raise HTTPException(
|
|
84
|
+
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
85
|
+
detail="Invalid authentication credentials",
|
|
86
|
+
) from e
|
|
87
|
+
|
|
88
|
+
|
|
32
89
|
@router.post("/analyze")
|
|
33
90
|
@limiter.limit("3/minute")
|
|
34
91
|
async def analyze_video(
|
|
@@ -39,6 +96,7 @@ async def analyze_video(
|
|
|
39
96
|
debug: str = Form("false"), # noqa: B008
|
|
40
97
|
referer: str | None = Header(None), # noqa: B008
|
|
41
98
|
x_test_password: str | None = Header(None), # noqa: B008
|
|
99
|
+
user_id: str = Depends(get_user_id_for_analysis), # noqa: B008
|
|
42
100
|
) -> JSONResponse:
|
|
43
101
|
"""Analyze video and return jump metrics.
|
|
44
102
|
|
|
@@ -46,17 +104,21 @@ async def analyze_video(
|
|
|
46
104
|
- Drop Jump: Analyzes ground contact and flight time
|
|
47
105
|
- CMJ: Analyzes jump height, countermovement depth, and phases
|
|
48
106
|
|
|
107
|
+
Requires authentication via JWT token in Authorization header, or TEST_PASSWORD
|
|
108
|
+
header for testing/debugging.
|
|
109
|
+
|
|
49
110
|
Args:
|
|
50
111
|
file: Video file to analyze (multipart/form-data)
|
|
51
112
|
jump_type: Type of jump ("drop_jump" or "cmj")
|
|
52
113
|
quality: Analysis quality preset ("fast", "balanced", or "accurate")
|
|
53
114
|
debug: Debug overlay flag ("true" or "false", default "false")
|
|
115
|
+
user_id: Authenticated user ID (extracted from JWT or test password)
|
|
54
116
|
|
|
55
117
|
Returns:
|
|
56
118
|
JSON response with metrics or error details
|
|
57
119
|
|
|
58
120
|
Raises:
|
|
59
|
-
HTTPException: If
|
|
121
|
+
HTTPException: If authentication or processing fails
|
|
60
122
|
"""
|
|
61
123
|
start_time = time.time()
|
|
62
124
|
|
|
@@ -76,6 +138,7 @@ async def analyze_video(
|
|
|
76
138
|
jump_type=jump_type,
|
|
77
139
|
quality=quality,
|
|
78
140
|
debug=enable_debug,
|
|
141
|
+
user_id=user_id,
|
|
79
142
|
)
|
|
80
143
|
|
|
81
144
|
# Perform analysis using service layer
|
|
@@ -84,7 +147,7 @@ async def analyze_video(
|
|
|
84
147
|
jump_type=jump_type,
|
|
85
148
|
quality=quality,
|
|
86
149
|
debug=enable_debug,
|
|
87
|
-
user_id=
|
|
150
|
+
user_id=user_id,
|
|
88
151
|
)
|
|
89
152
|
|
|
90
153
|
# Log analysis completion
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
from datetime import datetime, timezone
|
|
5
|
+
from importlib.metadata import version
|
|
5
6
|
|
|
6
7
|
import structlog
|
|
7
8
|
from fastapi import APIRouter
|
|
@@ -22,11 +23,31 @@ async def health_check() -> dict[str, str | bool]:
|
|
|
22
23
|
os.getenv("R2_ENDPOINT") and os.getenv("R2_ACCESS_KEY") and os.getenv("R2_SECRET_KEY")
|
|
23
24
|
)
|
|
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
|
+
|
|
25
44
|
return {
|
|
26
45
|
"status": "healthy",
|
|
27
46
|
"service": "kinemotion-backend",
|
|
28
47
|
"version": "0.1.0",
|
|
29
48
|
"environment": os.getenv("ENVIRONMENT", "development"),
|
|
49
|
+
"kinemotion_version": kinemotion_version,
|
|
30
50
|
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
31
51
|
"r2_configured": r2_configured,
|
|
52
|
+
"database_connected": database_connected,
|
|
32
53
|
}
|