kinemotion 0.61.0__tar.gz → 0.63.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.
- kinemotion-0.63.0/.basic-memory/api/testing-backend-authentication-quick-reference.md +158 -0
- kinemotion-0.63.0/.basic-memory/project-management/backend-authentication-architecture-decision.md +98 -0
- kinemotion-0.63.0/.basic-memory/project-management/backend-authentication-implementation-complete.md +137 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/CHANGELOG.md +23 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/PKG-INFO +1 -1
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/auth.py +4 -1
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/database.py +23 -5
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/middleware.py +6 -8
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/routes/analysis.py +67 -4
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/routes/health.py +15 -3
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/services/__init__.py +7 -1
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/services/validation.py +14 -2
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/tests/conftest.py +10 -2
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/ResultsDisplay.tsx +11 -5
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/hooks/useDatabaseStatus.ts +7 -11
- {kinemotion-0.61.0 → kinemotion-0.63.0}/pyproject.toml +1 -1
- {kinemotion-0.61.0 → kinemotion-0.63.0}/uv.lock +1 -1
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/api/api-reference-quick-commands.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/api/cloud-run-cpu-specifications-investigation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/api/supabase-authentication-setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/authentication/auth-provider-comparison-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/authentication/auth-providers-comparison-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/authentication/supabase-authentication-quick-start.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/authentication/supabase-authentication-setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/authentication/supabase-authentication-technical-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/authentication/supabase-google-oauth-setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/authentication/supabase-production-setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/authentication/supabase-quick-start-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/biomechanics/camera-angle-empirical-validation-results-45-superior-for-media-pipe.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/biomechanics/camera-perspective-analysis-45deg-vs-lateral.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/biomechanics/cmj-landing-detection-window-validation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/biomechanics/cmj-physiological-bounds-for-validation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/biomechanics/cmj-validation-implementation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/biomechanics/drop-jump-vs-cmj-key-differences.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/biomechanics/technical-implementation-45deg-perspective-correction.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/codebase/codebase-architecture-overview.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/codebase/validation-architecture-visual-hierarchy-after-refactoring.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/codebase/validation-code-duplication-evidence.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/codebase/validation-module-architecture-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/codebase/validation-refactoring-complete-architecture-improvement.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/automated-deployment-setup-git-hub-actions-with-workload-identity-federation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/backend-repository-split-migration-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/backend-repository-split-step-by-step-execution-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/cloud-run-security-least-privilege-service-account-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/cors-and-memory-issues-production-debugging-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/current-kinemotion-architecture-correct-deployment-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/frontend-repository-split-migration-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/frontend-repository-split-step-by-step-execution-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/production-deployment-guide-vercel-google-cloud-run.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/quick-deployment-commands-vercel-and-cloud-run.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/deployment/vercel-monorepo-deployment-best-practice.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/athlete-pose3d-and-cross-platform-determinism-investigation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/athlete-pose3d-final-strategy-accuracy-and-robustness.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/athlete-pose3d-media-pipe-enhancement-plan.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/athlete-pose3d-phase-1-implementation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/backend-authentication-and-logging-status.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/backend-code-coverage-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/backend-code-duplication-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/backend-granular-logging-implementation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/backend-kinemotion-decoupling-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/backend-sonar-cloud-integration-status.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/basic-memory-naming-hook-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/ci-caching-issue-investigation-deep-squat-test-failure.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/ci-vs-local-test-failure-investigation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/claude-code-hook-configuration.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/cmj-phase-detection-testing-gap-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/commit-review-r2-video-storage-migration-fe74d1f.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/comprehensive-timing-instrumentation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/cross-platform-determinism-analysis-final-results.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/database-setup-scripts-complete-implementation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/development-standards-quality-gates.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/drop-jump-detection-complete-fix-all-metrics-within-target.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/drop-jump-detection-failure-analysis-per-video-breakdown.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/drop-jump-fix-drop-start-successful-landing-and-takeoff-remain.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/fast-api-app.py Refactoring Plan - Modular Architecture.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/fast-api-refactoring-completion-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/feature-request-system-configuration.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/follow-up-improvements-to-r2-video-storage-migration.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/frontend-dependencies-analysis-nov-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/google-oauth-setup-script-final-review-production-ready.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/google-oauth-setup-script-review-issues-and-recommendations.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/hook-complete-audit-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/hook-configuration-audit.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/hook-quick-reference.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/i18n-implementation-plan-for-validation-messages.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/keyboard-interrupt-test-suite-failure-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/model-import-conflict-resolution-fast-api-refactoring.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/non-deterministic-analysis-root-cause-and-solution.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/optimal-timing-implementation-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/p0-p1-p2-test-suite-fixes-final-report.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/pose-detection-baseline-evaluation-results.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/pose-detection-optimization-complete-success-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/pose-detection-parameter-optimization-framework.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/structured-logging-implementation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/structured-logging-implementation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/supabase-dashboard-navigation-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/supabase-database-integration-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/supabase-documentation-validation-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/test-coverage-asymmetry-analysis-cmj-vs-drop-jump.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/test-coverage-equivalence-achievement-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/test-suite-comprehensive-review-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/test-suite-comprehensive-review-structure-and-gaps.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-complete-report.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/test-suite-p0-p1-p2-fixes-progress-report.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/unused-and-experimental-features-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/unused-code-detection-prompt-template.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/unused-code-identification-and-decorator-application-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/unused-code-verification-final-pass-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/using-multiple-mcp-reasoning-servers-simultaneously.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/velocity-threshold-empirical-validation-study.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/development/vercel-authentication-options-for-user-id-tracking.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/agent-documentation-standards-update.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/documentation-audit-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/i18n-documentation-cleanup-completed.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/issue-12-mvp-scaffolding-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/issue-12-unblocked-tasks-breakdown.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/issue-12-use-real-metrics-now.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/kinemotion-project-setup-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/kinemotion-supabase-production-configuration.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/mcp-sequential-thinking-alternatives-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/performance-optimization-pose-tracker-pool-timing-instrumentation-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/project-state-summary-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/specialized-subagents-routing-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/supabase-setup-instructions-for-kinemotion.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/project-management/version-mismatch-analysis-kinemotion-0370-vs-0300.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/research/performance-improvement-analysis-30s-18s.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/strategy/deployment-decision-analysis-for-kinemotion.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/strategy/mvp-feedback-collection-plan.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/strategy/mvp-first-strategic-direction.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/strategy/mvp-validation-checkpoints.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/strategy/pose2sim-migration-evaluation-and-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/strategy/strategic-priority-tasks-current-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.basic-memory/strategy/third-party-auth-providers-with-free-tiers-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/agents/biomechanics-specialist.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/agents/computer-vision-engineer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/agents/devops-cicd-engineer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/agents/frontend-developer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/agents/ml-data-scientist.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/agents/project-manager.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/agents/python-backend-developer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/agents/qa-test-engineer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/agents/technical-writer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.claude/settings.local.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.cursor/mcp.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.dockerignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.envrc +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.gitattributes +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.github/dependabot.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.github/pull_request_template.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.github/workflows/deploy-backend.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.github/workflows/docs.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.github/workflows/release.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.github/workflows/test.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.mcp.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.pre-commit-config.yaml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.readthedocs.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/backend-cors-fastapi-middleware-order.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/camera-perspective-validation-study.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/code_style_and_conventions.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/current-project-architecture.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/deployment-checklist-and-known-issues.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/deployment-setup-complete.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/github-project-setup-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/mvp-first-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/mvp-roadmap-and-priorities.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/project_overview.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/specialist-agents-routing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/memories/suggested_commands.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.serena/project.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.tool-versions +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/.vercelignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/CLAUDE.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/CODE_OF_CONDUCT.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/CONTRIBUTING.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/Dockerfile +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/GEMINI.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/LICENSE +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/SECURITY.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/.coveragerc +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/.dockerignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/.env.example +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/Dockerfile +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/docs/fly-deployment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/docs/implementation-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/docs/setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/docs/tests.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/pyproject.toml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/analysis_api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/app/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/app/config.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/app/dependencies.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/app/exceptions.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/app/main.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/app.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/logging_config.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/models/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/models/database.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/models/responses.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/models/storage.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/routes/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/routes/database.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/routes/platform.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/services/analysis_service.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/services/storage_service.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/services/video_processor.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/types.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/utils/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/src/kinemotion_backend/utils/rate_limiter.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/supabase-schema.sql +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/tests/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/tests/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/tests/test_api_endpoints.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/tests/test_error_handling.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/tests/test_health.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/tests/test_r2_integration.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/backend/tests/test_validation.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/api/cmj.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/api/core.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/api/dropjump.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/api/overview.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/I18N-README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/agents-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/errors-findings.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/feature-request-system.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/feedback-system-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/i18n-architecture-diagram.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/i18n-cheat-sheet.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/i18n-quick-start-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/i18n-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/i18n-validation-messages-specification.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/supabase-database-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/test-suite-review-december-2025.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/testing-standards.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/testing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/type-hints.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/validation-plan.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/validation-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/development/wallball-norep-detection.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/bulk-processing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/camera-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/cloud-run-deployment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/cmj-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/cmj-recording-protocol-es.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/cmj-recording-protocol.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/deployment-checklist.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/local-testing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/setup-issue-12.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/supabase-setup/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/supabase-setup/quickstart.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/supabase-setup/scripts-reference.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/guides/supabase-setup/setup-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/index.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/quick-start.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/reference/cloud-run-quick-reference.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/reference/json-output-format.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/reference/json-structure-comparison.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/reference/parameters.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/reference/pose-systems.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/paper-downloader/HOW-TO-FIND-DOIS.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/paper-downloader/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/paper-downloader/dois.txt +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/paper-downloader/download.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/paper-downloader/pyproject.toml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/paper-downloader/uv.lock +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/sports-biomechanics-pose-estimation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/MANUAL-DOWNLOAD-GUIDE.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/convert_pdfs.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Ward_Putting-i-in-Team.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/jump-performance/2011_Harper_10-to-5-Jump-Test.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/jump-performance/2014_Samozino_FV-Imbalance.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/jump-performance/2022_Wells_Golf-Clubhead-CMJ.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/running-biomechanics/2016_Moore_Economical-Running-Technique.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/smartphone-technology/2022_Bishop_MyJumpLab-Validation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/markdown/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/online-references-for-papers.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Ward_Putting-i-in-Team.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/jump-performance/2011_Harper_10-to-5-Jump-Test.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/jump-performance/2014_Samozino_FV-Imbalance.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/jump-performance/2022_Wells_Golf-Clubhead-CMJ.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Moore_Economical-Running-Technique.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/smartphone-technology/2022_Bishop_MyJumpLab-Validation.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/research/thirdparty/pdfs/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.pdf +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/1-STRATEGIC_SUMMARY.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/2-STRATEGIC_ANALYSIS.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/MVP_FEEDBACK_COLLECTION.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/MVP_VALIDATION_CHECKPOINTS.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/STYLE_GUIDE.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/02-technical-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/03-refactoring-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/BIOMECHANICS/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/BIOMECHANICS/02-technical-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/BIOMECHANICS/03-reference-guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/BIOMECHANICS/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/COMPUTER_VISION/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/COMPUTER_VISION/02-real-time-architecture.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/COMPUTER_VISION/03-implementation-checklist.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/COMPUTER_VISION/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/CONSOLIDATED/01-agent-consensus.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/CONSOLIDATED/02-critical-findings.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/CONSOLIDATED/03-roadmap-adjustments.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/CONSOLIDATED/04-decision-points.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/CONSOLIDATED/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/CONSOLIDATED/risk-register.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/CONSOLIDATED/timeline-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/02-infrastructure-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/03-implementation-roadmap.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/DEVOPS_CI_CD/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/02-technical-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/03-parameter-specifications.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/QA_TESTING/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/QA_TESTING/02-roadmap-assessment.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/QA_TESTING/03-testing-checklists.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/QA_TESTING/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/01-executive-summary.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/02-documentation-strategy.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/03-action-plan.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/agent-assessments/TECHNICAL_WRITING/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/strategy/pose2sim-migration-evaluation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/technical/framerate.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/technical/implementation-details.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/technical/imu-metadata.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/technical/real-time-analysis.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/technical/triple-extension.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/translations/es/camera-setup.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/validation/determinism-test.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/validation/known-height-validation.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/docs/validation-status.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/examples/bulk/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/examples/bulk/bulk_processing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/examples/bulk/simple_example.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/examples/programmatic_usage.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/.editorconfig +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/.env.example +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/.gitattributes +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/.yarn/releases/yarn-4.12.0.cjs +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/.yarnrc.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/index.html +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/package.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/App.i18n.integration.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/App.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/App.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/Auth.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/Auth.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/ErrorBoundary.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/ErrorBoundary.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/ErrorDisplay.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/FeatureRequestButton.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/FeedbackForm.css +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/FeedbackForm.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/FeedbackForm.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/LanguageSwitcher.css +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/LanguageSwitcher.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/LanguageSwitcher.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/LoadingSpinner.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/LoadingSpinner.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/RecentUploads.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/RecentUploads.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/ResultsDisplay.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/ResultsSkeleton.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/UploadForm.test.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/components/UploadForm.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/config/links.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/hooks/useAnalysis.test.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/hooks/useAnalysis.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/hooks/useAuth.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/hooks/useBackendVersion.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/hooks/useLanguage.test.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/hooks/useLanguage.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/hooks/useRecentUploads.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/i18n/config.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/i18n/locales/en/translation.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/i18n/locales/es/translation.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/i18n/locales/fr/translation.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/index.css +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/lib/supabase.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/main.tsx +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/test/setup.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/types/api.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/src/vite-env.d.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/vercel.json +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/vite.config.ts +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/frontend/yarn.lock +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/justfile +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/local_dev.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/mkdocs.yml +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/demos/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/demos/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/demos/api_demo.ipynb +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/demos/batch_processing_demo.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/demos/sample_data/.gitkeep +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/presentation_guide.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/revealjs/.gitignore +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/revealjs/Makefile +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/revealjs/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/revealjs/slides.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/presentation/speaker_script.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/requirements-docs.txt +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/samples/cmjs/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/SCRIPTS_QUICKREF.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/analyze_determinism_variance.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/basic-memory-utils.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/debug_contact_states.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/debug_detection.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/find_unused_features.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/generate_test_data.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/optimize_detection_params.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/plot_cmj_velocities.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/plot_validation_results.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/plot_velocities.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/prepare_ground_truth.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/project/README.md +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/project/add-issue.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/project/batch-set-fields.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/project/helpers.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/project/list.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/project/set-field.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/project/set-status.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/project/summary.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/project.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/setup-github-deploy.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/setup-google-oauth.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/setup-supabase-local.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/setup-supabase-production.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/supabasedb/setup-supabase-database.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/supabasedb/setup_supabase_db.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/test_acceleration_standing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/test_determinism.sh +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/test_drop_start_debug.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/scripts/validate_known_heights.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/sonar-project.properties +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cmj/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cmj/analysis.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cmj/api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cmj/cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cmj/debug_overlay.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cmj/joint_angles.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cmj/kinematics.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cmj/metrics_validator.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/cmj/validation_bounds.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/auto_tuning.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/cli_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/debug_overlay_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/determinism.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/experimental.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/filtering.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/formatting.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/metadata.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/pipeline_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/pose.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/quality.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/smoothing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/timing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/validation.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/core/video_io.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/dropjump/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/dropjump/analysis.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/dropjump/api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/dropjump/cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/dropjump/debug_overlay.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/dropjump/kinematics.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/dropjump/metrics_validator.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/dropjump/validation_bounds.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/src/kinemotion/py.typed +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cli/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cli/test_cmj.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cli/test_dropjump.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cli/test_imports.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cmj/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cmj/test_analysis.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cmj/test_api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cmj/test_cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cmj/test_joint_angles.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cmj/test_kinematics.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/cmj/test_physiological_bounds.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/conftest.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_auto_tuning.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_cli_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_filtering.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_formatting.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_metadata.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_pipeline_utils.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_pose.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_quality.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_smoothing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_timing.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_validation.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/core/test_video_io.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/dropjump/__init__.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/dropjump/test_adaptive_threshold.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/dropjump/test_analysis.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/dropjump/test_api.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/dropjump/test_cli.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/dropjump/test_contact_detection.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/dropjump/test_kinematics.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.0}/tests/dropjump/test_physiological_bounds.py +0 -0
- {kinemotion-0.61.0 → kinemotion-0.63.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.63.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.63.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,29 @@ 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.63.0 (2025-12-15)
|
|
11
|
+
|
|
12
|
+
### Feat
|
|
13
|
+
|
|
14
|
+
- use email as unique identifier for users and storage organization
|
|
15
|
+
|
|
16
|
+
### Fix
|
|
17
|
+
|
|
18
|
+
- enhance database debugging with detailed connection logging
|
|
19
|
+
- revert httpx client configuration that broke Supabase compatibility
|
|
20
|
+
|
|
21
|
+
## kinemotion-v0.62.0 (2025-12-15)
|
|
22
|
+
|
|
23
|
+
### Feat
|
|
24
|
+
|
|
25
|
+
- implement complete backend authentication with modern Supabase key support
|
|
26
|
+
|
|
27
|
+
### Fix
|
|
28
|
+
|
|
29
|
+
- use useAuth hook to get session token for feedback submission
|
|
30
|
+
- use backend API URL for feedback submission
|
|
31
|
+
- use environment variable for backend API URL in database status check
|
|
32
|
+
|
|
10
33
|
## kinemotion-v0.61.0 (2025-12-15)
|
|
11
34
|
|
|
12
35
|
### Feat
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kinemotion
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.63.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")
|
|
@@ -17,11 +17,14 @@ class DatabaseClient:
|
|
|
17
17
|
self.supabase_url = os.getenv("SUPABASE_URL", "")
|
|
18
18
|
|
|
19
19
|
# Prefer modern keys, fall back to legacy for compatibility
|
|
20
|
+
# Check which key source is being used for debugging
|
|
21
|
+
supabase_publishable_key = os.getenv("SUPABASE_PUBLISHABLE_KEY")
|
|
22
|
+
supabase_secret_key = os.getenv("SUPABASE_SECRET_KEY")
|
|
23
|
+
supabase_anon_key = os.getenv("SUPABASE_ANON_KEY")
|
|
24
|
+
supabase_key = os.getenv("SUPABASE_KEY")
|
|
25
|
+
|
|
20
26
|
self.supabase_key = (
|
|
21
|
-
|
|
22
|
-
or os.getenv("SUPABASE_SECRET_KEY")
|
|
23
|
-
or os.getenv("SUPABASE_ANON_KEY")
|
|
24
|
-
or os.getenv("SUPABASE_KEY")
|
|
27
|
+
supabase_publishable_key or supabase_secret_key or supabase_anon_key or supabase_key
|
|
25
28
|
)
|
|
26
29
|
|
|
27
30
|
if not self.supabase_url:
|
|
@@ -34,8 +37,23 @@ class DatabaseClient:
|
|
|
34
37
|
"SUPABASE_ANON_KEY, or SUPABASE_KEY"
|
|
35
38
|
)
|
|
36
39
|
|
|
40
|
+
# Log which key source is being used (without exposing the actual key)
|
|
41
|
+
key_source = "unknown"
|
|
42
|
+
if supabase_publishable_key:
|
|
43
|
+
key_source = "SUPABASE_PUBLISHABLE_KEY"
|
|
44
|
+
elif supabase_secret_key:
|
|
45
|
+
key_source = "SUPABASE_SECRET_KEY"
|
|
46
|
+
elif supabase_anon_key:
|
|
47
|
+
key_source = "SUPABASE_ANON_KEY"
|
|
48
|
+
elif supabase_key:
|
|
49
|
+
key_source = "SUPABASE_KEY"
|
|
50
|
+
|
|
37
51
|
self.client: Client = create_client(self.supabase_url, self.supabase_key)
|
|
38
|
-
logger.info(
|
|
52
|
+
logger.info(
|
|
53
|
+
"database_client_initialized",
|
|
54
|
+
supabase_url=self.supabase_url,
|
|
55
|
+
key_source=key_source,
|
|
56
|
+
)
|
|
39
57
|
|
|
40
58
|
async def create_analysis_session(
|
|
41
59
|
self,
|
|
@@ -50,28 +50,26 @@ class RequestLoggingMiddleware(BaseHTTPMiddleware):
|
|
|
50
50
|
client_ip=request.client.host if request.client else "unknown",
|
|
51
51
|
)
|
|
52
52
|
|
|
53
|
-
# Extract and validate user
|
|
53
|
+
# Extract and validate user email from Authorization header
|
|
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
|
-
user_id = supabase_auth.get_user_id(token)
|
|
60
59
|
user_email = supabase_auth.get_user_email(token)
|
|
61
60
|
auth_duration_ms = (time.time() - auth_start) * 1000
|
|
62
61
|
|
|
63
|
-
# Bind user
|
|
62
|
+
# Bind user email to logging context
|
|
64
63
|
structlog.contextvars.bind_contextvars(
|
|
65
|
-
|
|
66
|
-
user_email=user_email,
|
|
64
|
+
email=user_email,
|
|
67
65
|
)
|
|
68
66
|
|
|
69
67
|
# Store in request state for use in endpoints
|
|
70
|
-
request.state.
|
|
71
|
-
request.state.user_email = user_email
|
|
68
|
+
request.state.email = user_email
|
|
72
69
|
|
|
73
70
|
logger.info(
|
|
74
71
|
"user_authenticated",
|
|
72
|
+
email=user_email,
|
|
75
73
|
auth_duration_ms=round(auth_duration_ms, 2),
|
|
76
74
|
)
|
|
77
75
|
except Exception as e:
|
|
@@ -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_email_for_analysis(
|
|
45
|
+
request: Request,
|
|
46
|
+
x_test_password: str | None = Header(None), # noqa: B008
|
|
47
|
+
) -> str:
|
|
48
|
+
"""Extract user email 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 email (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_email = os.getenv("TEST_EMAIL", "test@example.com")
|
|
63
|
+
logger.info("analysis_test_password_used", email=test_email)
|
|
64
|
+
return test_email
|
|
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
|
+
email = auth.get_user_email(token)
|
|
78
|
+
return email
|
|
79
|
+
except HTTPException:
|
|
80
|
+
raise
|
|
81
|
+
except Exception as e:
|
|
82
|
+
logger.error("user_email_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
|
+
email: str = Depends(get_user_email_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
|
+
email: Authenticated user email (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
|
+
email=email,
|
|
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=email,
|
|
88
151
|
)
|
|
89
152
|
|
|
90
153
|
# Log analysis completion
|
|
@@ -35,11 +35,23 @@ async def health_check() -> dict[str, str | bool]:
|
|
|
35
35
|
from kinemotion_backend.database import get_database_client
|
|
36
36
|
|
|
37
37
|
db_client = get_database_client()
|
|
38
|
-
#
|
|
39
|
-
|
|
38
|
+
# Try to access analysis_sessions table with select limit to test connectivity
|
|
39
|
+
# This will return data if accessible, or raise if table doesn't exist or RLS blocks it
|
|
40
|
+
response = db_client.client.table("analysis_sessions").select("id").limit(1).execute()
|
|
41
|
+
# If we get here, the database connection worked
|
|
42
|
+
# Note: response.data could be empty if table is empty, but that's still success
|
|
40
43
|
database_connected = True
|
|
44
|
+
logger.info(
|
|
45
|
+
"database_health_check_succeeded",
|
|
46
|
+
rows_returned=len(response.data or []),
|
|
47
|
+
)
|
|
41
48
|
except Exception as db_error:
|
|
42
|
-
logger.warning(
|
|
49
|
+
logger.warning(
|
|
50
|
+
"database_health_check_failed",
|
|
51
|
+
error=str(db_error),
|
|
52
|
+
error_type=type(db_error).__name__,
|
|
53
|
+
exc_info=True,
|
|
54
|
+
)
|
|
43
55
|
|
|
44
56
|
return {
|
|
45
57
|
"status": "healthy",
|