kinemotion 0.61.0__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.61.0 → kinemotion-0.62.0}/CHANGELOG.md +12 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/PKG-INFO +1 -1
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/auth.py +4 -1
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/database.py +6 -1
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/middleware.py +1 -1
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/analysis.py +67 -4
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/__init__.py +7 -1
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/validation.py +14 -2
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/tests/conftest.py +10 -2
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/ResultsDisplay.tsx +11 -5
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/hooks/useDatabaseStatus.ts +7 -11
- {kinemotion-0.61.0 → kinemotion-0.62.0}/pyproject.toml +1 -1
- {kinemotion-0.61.0 → kinemotion-0.62.0}/uv.lock +1 -1
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/api/api-reference-quick-commands.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/api/cloud-run-cpu-specifications-investigation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/api/supabase-authentication-setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/authentication/auth-provider-comparison-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/authentication/auth-providers-comparison-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-authentication-quick-start.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-authentication-setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-authentication-technical-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-google-oauth-setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-production-setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/authentication/supabase-quick-start-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/biomechanics/camera-angle-empirical-validation-results-45-superior-for-media-pipe.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/biomechanics/camera-perspective-analysis-45deg-vs-lateral.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/biomechanics/cmj-landing-detection-window-validation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/biomechanics/cmj-physiological-bounds-for-validation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/biomechanics/cmj-validation-implementation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/biomechanics/drop-jump-vs-cmj-key-differences.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/biomechanics/technical-implementation-45deg-perspective-correction.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/codebase/codebase-architecture-overview.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/codebase/validation-architecture-visual-hierarchy-after-refactoring.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/codebase/validation-code-duplication-evidence.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/codebase/validation-module-architecture-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/codebase/validation-refactoring-complete-architecture-improvement.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/automated-deployment-setup-git-hub-actions-with-workload-identity-federation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/backend-repository-split-migration-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/backend-repository-split-step-by-step-execution-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/cloud-run-security-least-privilege-service-account-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/cors-and-memory-issues-production-debugging-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/current-kinemotion-architecture-correct-deployment-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/frontend-repository-split-migration-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/frontend-repository-split-step-by-step-execution-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/production-deployment-guide-vercel-google-cloud-run.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/quick-deployment-commands-vercel-and-cloud-run.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/deployment/vercel-monorepo-deployment-best-practice.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/athlete-pose3d-and-cross-platform-determinism-investigation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/athlete-pose3d-final-strategy-accuracy-and-robustness.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/athlete-pose3d-media-pipe-enhancement-plan.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/athlete-pose3d-phase-1-implementation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/backend-authentication-and-logging-status.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/backend-code-coverage-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/backend-code-duplication-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/backend-granular-logging-implementation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/backend-kinemotion-decoupling-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/backend-sonar-cloud-integration-status.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/basic-memory-naming-hook-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/ci-caching-issue-investigation-deep-squat-test-failure.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/ci-vs-local-test-failure-investigation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/claude-code-hook-configuration.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/cmj-phase-detection-testing-gap-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/commit-review-r2-video-storage-migration-fe74d1f.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/comprehensive-timing-instrumentation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/cross-platform-determinism-analysis-final-results.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/database-setup-scripts-complete-implementation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/development-standards-quality-gates.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/drop-jump-detection-complete-fix-all-metrics-within-target.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/drop-jump-detection-failure-analysis-per-video-breakdown.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/drop-jump-fix-drop-start-successful-landing-and-takeoff-remain.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/fast-api-app.py Refactoring Plan - Modular Architecture.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/fast-api-refactoring-completion-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/feature-request-system-configuration.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/follow-up-improvements-to-r2-video-storage-migration.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/frontend-dependencies-analysis-nov-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/google-oauth-setup-script-final-review-production-ready.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/google-oauth-setup-script-review-issues-and-recommendations.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/hook-complete-audit-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/hook-configuration-audit.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/hook-quick-reference.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/i18n-implementation-plan-for-validation-messages.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/keyboard-interrupt-test-suite-failure-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/model-import-conflict-resolution-fast-api-refactoring.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/non-deterministic-analysis-root-cause-and-solution.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/optimal-timing-implementation-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/p0-p1-p2-test-suite-fixes-final-report.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/pose-detection-baseline-evaluation-results.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/pose-detection-optimization-complete-success-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/pose-detection-parameter-optimization-framework.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/structured-logging-implementation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/structured-logging-implementation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/supabase-dashboard-navigation-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/supabase-database-integration-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/supabase-documentation-validation-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/test-coverage-asymmetry-analysis-cmj-vs-drop-jump.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/test-coverage-equivalence-achievement-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/test-suite-comprehensive-review-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/test-suite-comprehensive-review-structure-and-gaps.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-complete-report.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-progress-report.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/unused-and-experimental-features-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/unused-code-detection-prompt-template.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/unused-code-identification-and-decorator-application-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/unused-code-verification-final-pass-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/using-multiple-mcp-reasoning-servers-simultaneously.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/velocity-threshold-empirical-validation-study.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/development/vercel-authentication-options-for-user-id-tracking.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/agent-documentation-standards-update.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/documentation-audit-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/i18n-documentation-cleanup-completed.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/issue-12-mvp-scaffolding-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/issue-12-unblocked-tasks-breakdown.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/issue-12-use-real-metrics-now.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/kinemotion-project-setup-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/kinemotion-supabase-production-configuration.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/mcp-sequential-thinking-alternatives-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/performance-optimization-pose-tracker-pool-timing-instrumentation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/project-state-summary-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/specialized-subagents-routing-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/supabase-setup-instructions-for-kinemotion.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/project-management/version-mismatch-analysis-kinemotion-0370-vs-0300.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/research/performance-improvement-analysis-30s-18s.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/strategy/deployment-decision-analysis-for-kinemotion.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/strategy/mvp-feedback-collection-plan.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/strategy/mvp-first-strategic-direction.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/strategy/mvp-validation-checkpoints.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/strategy/pose2sim-migration-evaluation-and-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/strategy/strategic-priority-tasks-current-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.basic-memory/strategy/third-party-auth-providers-with-free-tiers-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/agents/biomechanics-specialist.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/agents/computer-vision-engineer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/agents/devops-cicd-engineer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/agents/frontend-developer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/agents/ml-data-scientist.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/agents/project-manager.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/agents/python-backend-developer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/agents/qa-test-engineer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/agents/technical-writer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.claude/settings.local.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.cursor/mcp.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.dockerignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.envrc +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.gitattributes +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.github/dependabot.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.github/pull_request_template.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.github/workflows/deploy-backend.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.github/workflows/docs.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.github/workflows/release.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.github/workflows/test.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.mcp.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.pre-commit-config.yaml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.readthedocs.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/backend-cors-fastapi-middleware-order.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/camera-perspective-validation-study.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/code_style_and_conventions.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/current-project-architecture.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/deployment-checklist-and-known-issues.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/deployment-setup-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/github-project-setup-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/mvp-first-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/mvp-roadmap-and-priorities.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/project_overview.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/specialist-agents-routing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/memories/suggested_commands.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.serena/project.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.tool-versions +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/.vercelignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/CLAUDE.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/CODE_OF_CONDUCT.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/CONTRIBUTING.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/Dockerfile +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/GEMINI.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/LICENSE +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/SECURITY.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/.coveragerc +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/.dockerignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/.env.example +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/Dockerfile +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/docs/fly-deployment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/docs/implementation-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/docs/setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/docs/tests.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/pyproject.toml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/analysis_api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/config.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/dependencies.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/exceptions.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app/main.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/app.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/logging_config.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/models/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/models/database.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/models/responses.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/models/storage.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/database.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/health.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/routes/platform.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/analysis_service.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/storage_service.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/video_processor.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/types.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/utils/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/utils/rate_limiter.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/supabase-schema.sql +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/tests/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/tests/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/tests/test_api_endpoints.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/tests/test_error_handling.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/tests/test_health.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/tests/test_r2_integration.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/backend/tests/test_validation.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/api/cmj.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/api/core.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/api/dropjump.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/api/overview.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/I18N-README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/agents-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/errors-findings.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/feature-request-system.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/feedback-system-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/i18n-architecture-diagram.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/i18n-cheat-sheet.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/i18n-quick-start-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/i18n-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/i18n-validation-messages-specification.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/supabase-database-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/test-suite-review-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/testing-standards.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/testing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/type-hints.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/validation-plan.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/validation-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/development/wallball-norep-detection.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/bulk-processing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/camera-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/cloud-run-deployment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/cmj-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/cmj-recording-protocol-es.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/cmj-recording-protocol.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/deployment-checklist.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/local-testing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/setup-issue-12.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/supabase-setup/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/supabase-setup/quickstart.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/supabase-setup/scripts-reference.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/guides/supabase-setup/setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/index.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/quick-start.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/reference/cloud-run-quick-reference.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/reference/json-output-format.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/reference/json-structure-comparison.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/reference/parameters.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/reference/pose-systems.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/paper-downloader/HOW-TO-FIND-DOIS.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/paper-downloader/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/paper-downloader/dois.txt +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/paper-downloader/download.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/paper-downloader/pyproject.toml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/paper-downloader/uv.lock +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/sports-biomechanics-pose-estimation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/MANUAL-DOWNLOAD-GUIDE.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/convert_pdfs.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Ward_Putting-i-in-Team.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2011_Harper_10-to-5-Jump-Test.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2014_Samozino_FV-Imbalance.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/jump-performance/2022_Wells_Golf-Clubhead-CMJ.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Moore_Economical-Running-Technique.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/smartphone-technology/2022_Bishop_MyJumpLab-Validation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/markdown/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/online-references-for-papers.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Ward_Putting-i-in-Team.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2011_Harper_10-to-5-Jump-Test.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2014_Samozino_FV-Imbalance.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/jump-performance/2022_Wells_Golf-Clubhead-CMJ.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Moore_Economical-Running-Technique.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/smartphone-technology/2022_Bishop_MyJumpLab-Validation.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/research/thirdparty/pdfs/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/1-STRATEGIC_SUMMARY.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/2-STRATEGIC_ANALYSIS.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/MVP_FEEDBACK_COLLECTION.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/MVP_VALIDATION_CHECKPOINTS.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/STYLE_GUIDE.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/02-technical-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/03-refactoring-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BIOMECHANICS/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BIOMECHANICS/02-technical-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BIOMECHANICS/03-reference-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/BIOMECHANICS/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/COMPUTER_VISION/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/COMPUTER_VISION/02-real-time-architecture.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/COMPUTER_VISION/03-implementation-checklist.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/COMPUTER_VISION/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/01-agent-consensus.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/02-critical-findings.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/03-roadmap-adjustments.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/04-decision-points.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/risk-register.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/CONSOLIDATED/timeline-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/02-infrastructure-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/03-implementation-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/02-technical-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/03-parameter-specifications.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/QA_TESTING/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/QA_TESTING/02-roadmap-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/QA_TESTING/03-testing-checklists.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/QA_TESTING/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/02-documentation-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/03-action-plan.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/strategy/pose2sim-migration-evaluation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/technical/framerate.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/technical/implementation-details.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/technical/imu-metadata.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/technical/real-time-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/technical/triple-extension.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/translations/es/camera-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/validation/determinism-test.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/validation/known-height-validation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/docs/validation-status.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/examples/bulk/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/examples/bulk/bulk_processing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/examples/bulk/simple_example.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/examples/programmatic_usage.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/.editorconfig +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/.env.example +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/.gitattributes +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/.yarn/releases/yarn-4.12.0.cjs +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/.yarnrc.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/index.html +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/package.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/App.i18n.integration.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/App.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/App.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/Auth.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/Auth.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/ErrorBoundary.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/ErrorBoundary.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/ErrorDisplay.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/FeatureRequestButton.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/FeedbackForm.css +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/FeedbackForm.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/FeedbackForm.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/LanguageSwitcher.css +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/LanguageSwitcher.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/LanguageSwitcher.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/LoadingSpinner.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/LoadingSpinner.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/RecentUploads.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/RecentUploads.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/ResultsDisplay.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/ResultsSkeleton.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/UploadForm.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/components/UploadForm.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/config/links.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/hooks/useAnalysis.test.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/hooks/useAnalysis.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/hooks/useAuth.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/hooks/useBackendVersion.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/hooks/useLanguage.test.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/hooks/useLanguage.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/hooks/useRecentUploads.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/i18n/config.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/i18n/locales/en/translation.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/i18n/locales/es/translation.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/i18n/locales/fr/translation.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/index.css +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/lib/supabase.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/main.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/test/setup.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/types/api.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/src/vite-env.d.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/vercel.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/vite.config.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/frontend/yarn.lock +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/justfile +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/local_dev.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/mkdocs.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/demos/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/demos/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/demos/api_demo.ipynb +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/demos/batch_processing_demo.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/demos/sample_data/.gitkeep +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/presentation_guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/revealjs/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/revealjs/Makefile +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/revealjs/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/revealjs/slides.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/presentation/speaker_script.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/requirements-docs.txt +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/samples/cmjs/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/SCRIPTS_QUICKREF.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/analyze_determinism_variance.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/basic-memory-utils.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/debug_contact_states.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/debug_detection.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/find_unused_features.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/generate_test_data.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/optimize_detection_params.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/plot_cmj_velocities.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/plot_validation_results.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/plot_velocities.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/prepare_ground_truth.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/project/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/project/add-issue.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/project/batch-set-fields.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/project/helpers.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/project/list.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/project/set-field.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/project/set-status.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/project/summary.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/project.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/setup-github-deploy.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/setup-google-oauth.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/setup-supabase-local.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/setup-supabase-production.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/supabasedb/setup-supabase-database.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/supabasedb/setup_supabase_db.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/test_acceleration_standing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/test_determinism.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/test_drop_start_debug.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/scripts/validate_known_heights.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/sonar-project.properties +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cmj/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cmj/analysis.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cmj/api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cmj/cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cmj/debug_overlay.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cmj/joint_angles.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cmj/kinematics.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cmj/metrics_validator.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/cmj/validation_bounds.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/auto_tuning.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/cli_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/debug_overlay_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/determinism.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/experimental.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/filtering.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/formatting.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/metadata.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/pipeline_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/pose.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/quality.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/smoothing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/timing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/validation.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/core/video_io.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/dropjump/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/dropjump/analysis.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/dropjump/api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/dropjump/cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/dropjump/debug_overlay.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/dropjump/kinematics.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/dropjump/metrics_validator.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/dropjump/validation_bounds.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/src/kinemotion/py.typed +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cli/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cli/test_cmj.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cli/test_dropjump.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cli/test_imports.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cmj/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cmj/test_analysis.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cmj/test_api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cmj/test_cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cmj/test_joint_angles.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cmj/test_kinematics.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/cmj/test_physiological_bounds.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/conftest.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_auto_tuning.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_cli_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_filtering.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_formatting.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_metadata.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_pipeline_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_pose.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_quality.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_smoothing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_timing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_validation.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/core/test_video_io.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/dropjump/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/dropjump/test_adaptive_threshold.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/dropjump/test_analysis.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/dropjump/test_api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/dropjump/test_cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/dropjump/test_contact_detection.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/dropjump/test_kinematics.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.62.0}/tests/dropjump/test_physiological_bounds.py +0 -0
- {kinemotion-0.61.0 → 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
|
|
@@ -7,6 +7,18 @@ 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
|
+
|
|
10
22
|
## kinemotion-v0.61.0 (2025-12-15)
|
|
11
23
|
|
|
12
24
|
### Feat
|
|
@@ -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
|
|
|
@@ -34,7 +35,11 @@ class DatabaseClient:
|
|
|
34
35
|
"SUPABASE_ANON_KEY, or SUPABASE_KEY"
|
|
35
36
|
)
|
|
36
37
|
|
|
37
|
-
|
|
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
|
+
)
|
|
38
43
|
logger.info("database_client_initialized", supabase_url=self.supabase_url)
|
|
39
44
|
|
|
40
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,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from .analysis_service import AnalysisService
|
|
4
4
|
from .storage_service import StorageService
|
|
5
|
-
from .validation import
|
|
5
|
+
from .validation import (
|
|
6
|
+
is_test_password_valid,
|
|
7
|
+
validate_jump_type,
|
|
8
|
+
validate_referer,
|
|
9
|
+
validate_video_file,
|
|
10
|
+
)
|
|
6
11
|
from .video_processor import VideoProcessorService
|
|
7
12
|
|
|
8
13
|
__all__ = [
|
|
@@ -12,4 +17,5 @@ __all__ = [
|
|
|
12
17
|
"validate_video_file",
|
|
13
18
|
"validate_jump_type",
|
|
14
19
|
"validate_referer",
|
|
20
|
+
"is_test_password_valid",
|
|
15
21
|
]
|
{kinemotion-0.61.0 → kinemotion-0.62.0}/backend/src/kinemotion_backend/services/validation.py
RENAMED
|
@@ -51,6 +51,19 @@ def validate_jump_type(jump_type: str) -> str:
|
|
|
51
51
|
return normalized
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def is_test_password_valid(x_test_password: str | None = None) -> bool:
|
|
55
|
+
"""Check if test password is valid (for debugging backdoor).
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
x_test_password: Optional test password header
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
True if test password is configured and matches
|
|
62
|
+
"""
|
|
63
|
+
test_password = os.getenv("TEST_PASSWORD")
|
|
64
|
+
return bool(test_password and x_test_password == test_password)
|
|
65
|
+
|
|
66
|
+
|
|
54
67
|
def validate_referer(referer: str | None, x_test_password: str | None = None) -> None:
|
|
55
68
|
"""Validate request comes from authorized frontend.
|
|
56
69
|
|
|
@@ -66,8 +79,7 @@ def validate_referer(referer: str | None, x_test_password: str | None = None) ->
|
|
|
66
79
|
return
|
|
67
80
|
|
|
68
81
|
# Allow bypass with test password (for curl testing, debugging)
|
|
69
|
-
|
|
70
|
-
if test_password and x_test_password == test_password:
|
|
82
|
+
if is_test_password_valid(x_test_password):
|
|
71
83
|
return # Bypass referer check
|
|
72
84
|
|
|
73
85
|
allowed_referers = [
|
|
@@ -39,6 +39,9 @@ def setup_test_environment() -> None:
|
|
|
39
39
|
os.environ["R2_BUCKET_NAME"] = "test-bucket"
|
|
40
40
|
os.environ["SUPABASE_URL"] = "https://test.supabase.co"
|
|
41
41
|
os.environ["SUPABASE_ANON_KEY"] = "test-anon-key"
|
|
42
|
+
# Test password for /analyze endpoint authentication bypass
|
|
43
|
+
os.environ["TEST_PASSWORD"] = "test-password-12345"
|
|
44
|
+
os.environ["TEST_USER_ID"] = "test-user-00000000-0000-0000-0000-000000000000"
|
|
42
45
|
|
|
43
46
|
yield
|
|
44
47
|
|
|
@@ -51,6 +54,8 @@ def setup_test_environment() -> None:
|
|
|
51
54
|
"R2_BUCKET_NAME",
|
|
52
55
|
"SUPABASE_URL",
|
|
53
56
|
"SUPABASE_ANON_KEY",
|
|
57
|
+
"TEST_PASSWORD",
|
|
58
|
+
"TEST_USER_ID",
|
|
54
59
|
]
|
|
55
60
|
for key in env_vars:
|
|
56
61
|
os.environ.pop(key, None)
|
|
@@ -126,8 +131,11 @@ def app() -> FastAPI:
|
|
|
126
131
|
|
|
127
132
|
@pytest.fixture
|
|
128
133
|
def client(app: FastAPI) -> TestClient:
|
|
129
|
-
"""Test client for the FastAPI application."""
|
|
130
|
-
|
|
134
|
+
"""Test client for the FastAPI application with test authentication."""
|
|
135
|
+
test_client = TestClient(app)
|
|
136
|
+
# Add test password header to all requests for authentication bypass
|
|
137
|
+
test_client.headers["x-test-password"] = "test-password-12345"
|
|
138
|
+
return test_client
|
|
131
139
|
|
|
132
140
|
|
|
133
141
|
@pytest.fixture
|