kinemotion 0.34.0__tar.gz → 0.35.1__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.35.1/.basic-memory/authentication/supabase-google-oauth-setup-guide.md +118 -0
- kinemotion-0.35.1/.basic-memory/codebase/validation-architecture-visual-hierarchy-after-refactoring.md +202 -0
- kinemotion-0.35.1/.basic-memory/codebase/validation-code-duplication-evidence.md +258 -0
- kinemotion-0.35.1/.basic-memory/codebase/validation-module-architecture-analysis.md +193 -0
- kinemotion-0.35.1/.basic-memory/codebase/validation-refactoring-complete-architecture-improvement.md +142 -0
- kinemotion-0.35.1/.basic-memory/deployment/backend-repository-split-migration-guide.md +935 -0
- kinemotion-0.35.1/.basic-memory/deployment/backend-repository-split-step-by-step-execution-guide.md +938 -0
- kinemotion-0.35.1/.basic-memory/deployment/cloud-run-security-least-privilege-service-account-setup.md +100 -0
- kinemotion-0.35.1/.basic-memory/deployment/frontend-repository-split-migration-guide.md +597 -0
- kinemotion-0.35.1/.basic-memory/deployment/frontend-repository-split-step-by-step-execution-guide.md +849 -0
- kinemotion-0.35.1/.basic-memory/development/backend-kinemotion-decoupling-strategy.md +863 -0
- kinemotion-0.35.1/.basic-memory/development/google-oauth-setup-script-final-review-production-ready.md +135 -0
- kinemotion-0.35.1/.basic-memory/development/google-oauth-setup-script-review-issues-and-recommendations.md +130 -0
- kinemotion-0.35.1/.basic-memory/development/p0-p1-p2-test-suite-fixes-final-report.md +11 -0
- kinemotion-0.35.1/.basic-memory/development/test-coverage-asymmetry-analysis-cmj-vs-drop-jump.md +158 -0
- kinemotion-0.35.1/.basic-memory/development/test-coverage-equivalence-achievement-summary.md +128 -0
- kinemotion-0.35.1/.basic-memory/development/test-suite-comprehensive-review-december-2025.md +304 -0
- kinemotion-0.35.1/.basic-memory/development/test-suite-comprehensive-review-structure-and-gaps.md +258 -0
- kinemotion-0.35.1/.basic-memory/development/test-suite-p0-p1-p2-fixes-complete-report.md +335 -0
- kinemotion-0.35.1/.basic-memory/development/test-suite-p0-p1-p2-fixes-progress-report.md +91 -0
- kinemotion-0.35.1/.basic-memory/development/unused-and-experimental-features-strategy.md +182 -0
- kinemotion-0.35.1/.basic-memory/development/unused-code-detection-prompt-template.md +265 -0
- kinemotion-0.35.1/.basic-memory/development/unused-code-identification-and-decorator-application-december-2025.md +322 -0
- kinemotion-0.35.1/.basic-memory/development/unused-code-verification-final-pass-december-2025.md +342 -0
- kinemotion-0.35.1/.basic-memory/project-management/documentation-audit-december-2025.md +157 -0
- kinemotion-0.35.1/.basic-memory/project-management/project-state-summary-december-2025.md +213 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/settings.local.json +49 -47
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.cursor/mcp.json +15 -2
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/workflows/deploy-backend.yml +1 -11
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/workflows/release.yml +4 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.gitignore +2 -2
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.mcp.json +3 -3
- kinemotion-0.35.1/.serena/memories/current-project-architecture.md +95 -0
- kinemotion-0.35.1/.serena/memories/deployment-checklist-and-known-issues.md +138 -0
- kinemotion-0.35.1/.serena/memories/deployment-setup-complete.md +38 -0
- kinemotion-0.35.1/.serena/memories/mvp-roadmap-and-priorities.md +138 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/memories/project_overview.md +19 -23
- {kinemotion-0.34.0 → kinemotion-0.35.1}/CHANGELOG.md +101 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/CLAUDE.md +72 -14
- {kinemotion-0.34.0 → kinemotion-0.35.1}/PKG-INFO +1 -1
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/Dockerfile +6 -5
- kinemotion-0.35.1/docs/development/test-suite-review-december-2025.md +356 -0
- kinemotion-0.35.1/docs/development/testing-standards.md +908 -0
- kinemotion-0.35.1/docs/guides/cmj-recording-protocol-es.md +147 -0
- kinemotion-0.35.1/docs/guides/cmj-recording-protocol.md +147 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/paper-downloader/download.py +3 -2
- {kinemotion-0.34.0 → kinemotion-0.35.1}/examples/bulk/bulk_processing.py +2 -1
- {kinemotion-0.34.0 → kinemotion-0.35.1}/examples/bulk/simple_example.py +2 -1
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/components/Auth.tsx +45 -1
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/hooks/useAuth.ts +39 -11
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/index.css +45 -0
- kinemotion-0.35.1/frontend/src/lib/supabase.ts +16 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/pyproject.toml +20 -2
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/README.md +54 -0
- kinemotion-0.35.1/scripts/debug_contact_states.py +90 -0
- kinemotion-0.35.1/scripts/debug_detection.py +262 -0
- kinemotion-0.35.1/scripts/find_unused_features.py +141 -0
- kinemotion-0.35.1/scripts/optimize_detection_params.py +380 -0
- kinemotion-0.35.1/scripts/plot_cmj_velocities.py +150 -0
- kinemotion-0.35.1/scripts/plot_velocities.py +127 -0
- kinemotion-0.35.1/scripts/prepare_ground_truth.py +101 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/setup-github-deploy.sh +40 -5
- kinemotion-0.35.1/scripts/setup-google-oauth.sh +335 -0
- kinemotion-0.35.1/scripts/test_acceleration_standing.py +77 -0
- kinemotion-0.35.1/scripts/test_drop_start_debug.py +75 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/validate_known_heights.py +3 -1
- {kinemotion-0.34.0 → kinemotion-0.35.1}/sonar-project.properties +1 -1
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/api.py +8 -5
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/cmj/analysis.py +70 -102
- kinemotion-0.34.0/src/kinemotion/core/cmj_metrics_validator.py → kinemotion-0.35.1/src/kinemotion/cmj/metrics_validator.py +27 -123
- kinemotion-0.34.0/src/kinemotion/core/cmj_validation_bounds.py → kinemotion-0.35.1/src/kinemotion/cmj/validation_bounds.py +1 -58
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/auto_tuning.py +6 -4
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/cli_utils.py +26 -0
- kinemotion-0.35.1/src/kinemotion/core/experimental.py +103 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/filtering.py +7 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/smoothing.py +34 -0
- kinemotion-0.35.1/src/kinemotion/core/validation.py +198 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/dropjump/__init__.py +1 -1
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/dropjump/analysis.py +23 -34
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/dropjump/kinematics.py +7 -1
- kinemotion-0.34.0/src/kinemotion/core/dropjump_metrics_validator.py → kinemotion-0.35.1/src/kinemotion/dropjump/metrics_validator.py +20 -114
- kinemotion-0.34.0/src/kinemotion/core/dropjump_validation_bounds.py → kinemotion-0.35.1/src/kinemotion/dropjump/validation_bounds.py +1 -58
- kinemotion-0.35.1/tests/cli/__init__.py +0 -0
- kinemotion-0.35.1/tests/cli/test_cmj.py +986 -0
- kinemotion-0.34.0/tests/test_cli_dropjump.py → kinemotion-0.35.1/tests/cli/test_dropjump.py +41 -35
- kinemotion-0.35.1/tests/cmj/__init__.py +0 -0
- kinemotion-0.34.0/tests/test_cmj_analysis.py → kinemotion-0.35.1/tests/cmj/test_analysis.py +28 -141
- kinemotion-0.35.1/tests/cmj/test_api.py +451 -0
- kinemotion-0.34.0/tests/test_cmj_kinematics.py → kinemotion-0.35.1/tests/cmj/test_kinematics.py +4 -3
- kinemotion-0.34.0/tests/test_cmj_physiological_bounds.py → kinemotion-0.35.1/tests/cmj/test_physiological_bounds.py +12 -6
- kinemotion-0.35.1/tests/conftest.py +80 -0
- kinemotion-0.35.1/tests/core/__init__.py +0 -0
- kinemotion-0.35.1/tests/core/test_auto_tuning.py +361 -0
- kinemotion-0.35.1/tests/core/test_metadata.py +169 -0
- kinemotion-0.34.0/tests/test_com_estimation.py → kinemotion-0.35.1/tests/core/test_pose.py +102 -2
- kinemotion-0.35.1/tests/core/test_smoothing.py +967 -0
- kinemotion-0.35.1/tests/core/test_validation.py +664 -0
- kinemotion-0.34.0/tests/test_aspect_ratio.py → kinemotion-0.35.1/tests/core/test_video_io.py +108 -1
- kinemotion-0.35.1/tests/dropjump/__init__.py +0 -0
- kinemotion-0.35.1/tests/dropjump/test_analysis.py +559 -0
- {kinemotion-0.34.0/tests → kinemotion-0.35.1/tests/dropjump}/test_api.py +9 -28
- {kinemotion-0.34.0/tests → kinemotion-0.35.1/tests/dropjump}/test_kinematics.py +6 -2
- kinemotion-0.35.1/tests/dropjump/test_physiological_bounds.py +511 -0
- kinemotion-0.34.0/tests/test_dropjump_validation_integration.py → kinemotion-0.35.1/tests/dropjump/test_validation_integration.py +10 -9
- {kinemotion-0.34.0 → kinemotion-0.35.1}/uv.lock +1 -1
- kinemotion-0.34.0/backend/fly.toml +0 -79
- kinemotion-0.34.0/docs/guides/cmj-recording-protocol-es.md +0 -125
- kinemotion-0.34.0/docs/guides/cmj-recording-protocol.md +0 -125
- kinemotion-0.34.0/tests/test_cli_cmj.py +0 -369
- kinemotion-0.34.0/tests/test_joint_angles.py +0 -615
- kinemotion-0.34.0/tests/test_polyorder.py +0 -155
- kinemotion-0.34.0/tests/test_video_io.py +0 -114
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/api/api-reference-quick-commands.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/api/supabase-authentication-setup-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/authentication/auth-provider-comparison-december-2025.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/authentication/auth-providers-comparison-december-2025.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/authentication/supabase-authentication-quick-start.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/authentication/supabase-authentication-setup-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/authentication/supabase-authentication-technical-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/authentication/supabase-production-setup-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/authentication/supabase-quick-start-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/biomechanics/camera-perspective-analysis-45deg-vs-lateral.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/biomechanics/cmj-landing-detection-window-validation.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/biomechanics/cmj-physiological-bounds-for-validation.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/biomechanics/cmj-validation-implementation-complete.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/biomechanics/drop-jump-vs-cmj-key-differences.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/biomechanics/technical-implementation-45deg-perspective-correction.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/codebase/codebase-architecture-overview.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/deployment/automated-deployment-setup-git-hub-actions-with-workload-identity-federation.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/deployment/cors-and-memory-issues-production-debugging-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/deployment/current-kinemotion-architecture-correct-deployment-setup.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/deployment/production-deployment-guide-vercel-google-cloud-run.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/deployment/quick-deployment-commands-vercel-and-cloud-run.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/deployment/vercel-monorepo-deployment-best-practice.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/backend-authentication-and-logging-status.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/backend-code-coverage-analysis.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/backend-code-duplication-analysis.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/backend-sonar-cloud-integration-status.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/basic-memory-naming-hook-analysis.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/ci-caching-issue-investigation-deep-squat-test-failure.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/ci-vs-local-test-failure-investigation.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/claude-code-hook-configuration.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/cmj-phase-detection-testing-gap-analysis.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/development-standards-quality-gates.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/frontend-dependencies-analysis-nov-2025.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/hook-complete-audit-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/hook-configuration-audit.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/hook-quick-reference.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/keyboard-interrupt-test-suite-failure-analysis.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/structured-logging-implementation-complete.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/structured-logging-implementation.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/supabase-dashboard-navigation-december-2025.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/using-multiple-mcp-reasoning-servers-simultaneously.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/development/vercel-authentication-options-for-user-id-tracking.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/project-management/issue-12-mvp-scaffolding-complete.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/project-management/issue-12-unblocked-tasks-breakdown.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/project-management/issue-12-use-real-metrics-now.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/project-management/kinemotion-project-setup-complete.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/project-management/kinemotion-supabase-production-configuration.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/project-management/mcp-sequential-thinking-alternatives-analysis.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/project-management/specialized-subagents-routing-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/project-management/supabase-setup-instructions-for-kinemotion.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/strategy/deployment-decision-analysis-for-kinemotion.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/strategy/mvp-feedback-collection-plan.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/strategy/mvp-first-strategic-direction.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/strategy/mvp-validation-checkpoints.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/strategy/strategic-priority-tasks-current-roadmap.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.basic-memory/strategy/third-party-auth-providers-with-free-tiers-december-2025.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/agents/biomechanics-specialist.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/agents/computer-vision-engineer.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/agents/devops-cicd-engineer.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/agents/frontend-developer.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/agents/ml-data-scientist.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/agents/project-manager.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/agents/python-backend-developer.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/agents/qa-test-engineer.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/agents/technical-writer.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.claude/hooks/fix-basic-memory-names.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.dockerignore +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.gitattributes +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/dependabot.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/pull_request_template.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/workflows/docs.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/workflows/security.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.github/workflows/test.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.pre-commit-config.yaml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.readthedocs.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/.gitignore +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/memories/backend-cors-fastapi-middleware-order.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/memories/camera-perspective-validation-study.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/memories/code_style_and_conventions.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/memories/github-project-setup-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/memories/mvp-first-strategy.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/memories/specialist-agents-routing.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/memories/suggested_commands.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.serena/project.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.tool-versions +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/.vercelignore +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/CODE_OF_CONDUCT.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/CONTRIBUTING.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/Dockerfile +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/GEMINI.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/LICENSE +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/SECURITY.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/.dockerignore +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/.env.example +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/docs/fly-deployment.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/docs/implementation-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/docs/setup.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/docs/tests.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/pyproject.toml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/src/kinemotion_backend/__init__.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/src/kinemotion_backend/app.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/src/kinemotion_backend/auth.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/src/kinemotion_backend/logging_config.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/src/kinemotion_backend/middleware.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/tests/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/tests/__init__.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/tests/conftest.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/tests/test_api_endpoints.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/tests/test_error_handling.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/tests/test_health.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/tests/test_r2_integration.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/tests/test_validation.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/backend/uv.lock +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/api/cmj.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/api/core.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/api/dropjump.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/api/overview.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/development/agents-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/development/errors-findings.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/development/testing.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/development/type-hints.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/development/validation-plan.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/development/validation-roadmap.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/development/wallball-norep-detection.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/guides/bulk-processing.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/guides/camera-setup.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/guides/cloud-run-deployment.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/guides/cmj-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/guides/deployment-checklist.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/guides/local-testing.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/guides/setup-issue-12.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/index.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/quick-start.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/reference/cloud-run-quick-reference.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/reference/json-output-format.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/reference/json-structure-comparison.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/reference/parameters.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/reference/pose-systems.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/paper-downloader/HOW-TO-FIND-DOIS.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/paper-downloader/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/paper-downloader/dois.txt +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/paper-downloader/pyproject.toml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/paper-downloader/uv.lock +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/sports-biomechanics-pose-estimation.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/MANUAL-DOWNLOAD-GUIDE.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/convert_pdfs.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/athlete-monitoring/2018_Ward_Putting-i-in-Team.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/jump-performance/2011_Harper_10-to-5-Jump-Test.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/jump-performance/2014_Samozino_FV-Imbalance.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/jump-performance/2022_Wells_Golf-Clubhead-CMJ.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/running-biomechanics/2016_Moore_Economical-Running-Technique.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/smartphone-technology/2022_Bishop_MyJumpLab-Validation.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/markdown/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/online-references-for-papers.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/athlete-monitoring/2001_Foster_Session-RPE-Training-Monitoring.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/athlete-monitoring/2015_Buchheit_GPS-Accelerometers-Stride-Stiffness.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Flatt_HRV-Recovery-Swimmers.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Saw_Training-Camps-Monitoring.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/athlete-monitoring/2018_Ward_Putting-i-in-Team.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2011_Petersen_Nordic-Hamstring-Prevention.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2011_Wilk_Shoulder-GIRD-Baseball-Pitchers.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2012_Hewit_Multidirectional-Leg-Asymmetry.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2015_Ford_Hip-Neuromuscular-Exercise-Valgus.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2015_Mosler_Hip-Groin-Pain-Factors.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2015_Sconce_Nordic-Hamstring-Validity.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2016_Mendez-Villanueva_Hamstring-MRI-Regional.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2016_Read_Youth-Soccer-Injury-Risk.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mason-Mackay_Ankle-Dorsiflexion-Landing.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2017_Mendiguchia_Hamstring-Treatment-Algorithm.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2018_Balsalobre-Fernandez_Ankle-Dorsiflexion-App.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2018_Bramah_Pathological-Gait-Running-Injuries.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/injury-prevention/2020_Fidai_Fatigue-Knee-Valgus-Youth.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/jump-performance/2011_Harper_10-to-5-Jump-Test.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/jump-performance/2012_Samozino_Optimal-Force-Velocity-Profile.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/jump-performance/2014_Samozino_FV-Imbalance.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/jump-performance/2016_Jimenez-Reyes_Force-Velocity-Training.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/jump-performance/2016_Morin-Samozino_Power-Force-Velocity-Profiles.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/jump-performance/2018_Garcia-Ramos_Two-Point-Method-Optimization.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/jump-performance/2022_Wells_Golf-Clubhead-CMJ.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/running-biomechanics/2005_Morin_Running-Stiffness-Measurement.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/running-biomechanics/2015_Balsalobre-Fernandez_Strength-Training-Running-Economy.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Balsalobre-Fernandez_iPhone-Running-Mechanics.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/running-biomechanics/2016_Moore_Economical-Running-Technique.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Filter_Curve-Sprint-Test-Soccer.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/running-biomechanics/2020_Harper_Horizontal-Deceleration-Radar.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/running-biomechanics/2021_vanOeveren_Running-Biomechanics-Synthesis.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/running-biomechanics/2024_Bramah_Sprint-Mechanics-Assessment-Score.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/smartphone-technology/2015_Balsalobre-Fernandez_iPhone-Vertical-Jump.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/smartphone-technology/2022_Bishop_MyJumpLab-Validation.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/velocity-based-training/2011_Jidovtseff_Load-Velocity-1RM-Prediction.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Conceicao_Movement-Velocity-Lower-Limb.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/velocity-based-training/2016_Pareja-Blanco_Velocity-Loss-Training.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/velocity-based-training/2017_Balsalobre-Fernandez_Barbell-Velocity-1RM.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/velocity-based-training/2020_Balsalobre-Fernandez_Barbell-Trajectory-Snatch.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/research/thirdparty/pdfs/velocity-based-training/2023_Balsalobre-Fernandez_AI-Barbell-Velocity.pdf +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/1-STRATEGIC_SUMMARY.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/2-STRATEGIC_ANALYSIS.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/MVP_FEEDBACK_COLLECTION.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/MVP_VALIDATION_CHECKPOINTS.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/STYLE_GUIDE.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/01-executive-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/02-technical-assessment.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/03-refactoring-roadmap.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/BACKEND_ARCHITECTURE/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/BIOMECHANICS/01-executive-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/BIOMECHANICS/02-technical-assessment.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/BIOMECHANICS/03-reference-guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/BIOMECHANICS/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/COMPUTER_VISION/01-executive-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/COMPUTER_VISION/02-real-time-architecture.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/COMPUTER_VISION/03-implementation-checklist.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/COMPUTER_VISION/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/CONSOLIDATED/01-agent-consensus.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/CONSOLIDATED/02-critical-findings.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/CONSOLIDATED/03-roadmap-adjustments.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/CONSOLIDATED/04-decision-points.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/CONSOLIDATED/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/CONSOLIDATED/risk-register.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/CONSOLIDATED/timeline-roadmap.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/DEVOPS_CI_CD/01-executive-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/DEVOPS_CI_CD/02-infrastructure-assessment.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/DEVOPS_CI_CD/03-implementation-roadmap.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/DEVOPS_CI_CD/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/01-executive-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/02-technical-assessment.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/03-parameter-specifications.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/ML_DATA_SCIENCE/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/QA_TESTING/01-executive-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/QA_TESTING/02-roadmap-assessment.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/QA_TESTING/03-testing-checklists.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/QA_TESTING/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/TECHNICAL_WRITING/01-executive-summary.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/TECHNICAL_WRITING/02-documentation-strategy.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/TECHNICAL_WRITING/03-action-plan.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/strategy/agent-assessments/TECHNICAL_WRITING/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/technical/framerate.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/technical/implementation-details.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/technical/imu-metadata.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/technical/real-time-analysis.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/technical/triple-extension.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/translations/es/camera-setup.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/validation/determinism-test.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/validation/known-height-validation.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/docs/validation-status.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/examples/bulk/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/examples/programmatic_usage.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/.editorconfig +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/.env.example +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/.gitattributes +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/.gitignore +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/.yarn/releases/yarn-4.12.0.cjs +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/.yarnrc.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/index.html +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/package.json +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/App.tsx +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/components/ErrorBoundary.tsx +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/components/ErrorDisplay.tsx +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/components/LoadingSpinner.tsx +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/components/RecentUploads.tsx +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/components/ResultsDisplay.tsx +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/components/ResultsSkeleton.tsx +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/components/UploadForm.tsx +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/hooks/useAnalysis.ts +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/hooks/useRecentUploads.ts +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/main.tsx +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/types/api.ts +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/src/vite-env.d.ts +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/vercel.json +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/vite.config.ts +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/frontend/yarn.lock +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/justfile +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/local_dev.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/mkdocs.yml +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/.gitignore +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/demos/.gitignore +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/demos/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/demos/api_demo.ipynb +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/demos/batch_processing_demo.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/demos/sample_data/.gitkeep +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/presentation_guide.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/revealjs/.gitignore +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/revealjs/Makefile +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/revealjs/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/revealjs/slides.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/presentation/speaker_script.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/requirements-docs.txt +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/samples/cmjs/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/SCRIPTS_QUICKREF.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/analyze_determinism_variance.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/basic-memory-utils.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/generate_test_data.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/plot_validation_results.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/project/README.md +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/project/add-issue.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/project/batch-set-fields.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/project/helpers.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/project/list.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/project/set-field.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/project/set-status.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/project/summary.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/project.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/setup-supabase-local.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/setup-supabase-production.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/scripts/test_determinism.sh +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/__init__.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/cli.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/cmj/__init__.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/cmj/cli.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/cmj/debug_overlay.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/cmj/joint_angles.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/cmj/kinematics.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/__init__.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/debug_overlay_utils.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/formatting.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/metadata.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/pose.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/quality.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/core/video_io.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/dropjump/cli.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/dropjump/debug_overlay.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/src/kinemotion/py.typed +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/tests/__init__.py +0 -0
- /kinemotion-0.34.0/tests/test_cli_imports.py → /kinemotion-0.35.1/tests/cli/test_imports.py +0 -0
- /kinemotion-0.34.0/tests/test_cmj_joint_angles.py → /kinemotion-0.35.1/tests/cmj/test_joint_angles.py +0 -0
- {kinemotion-0.34.0/tests → kinemotion-0.35.1/tests/core}/test_filtering.py +0 -0
- {kinemotion-0.34.0/tests → kinemotion-0.35.1/tests/core}/test_formatting.py +0 -0
- {kinemotion-0.34.0 → kinemotion-0.35.1}/tests/core/test_quality.py +0 -0
- {kinemotion-0.34.0/tests → kinemotion-0.35.1/tests/dropjump}/test_adaptive_threshold.py +0 -0
- {kinemotion-0.34.0/tests → kinemotion-0.35.1/tests/dropjump}/test_contact_detection.py +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Supabase Google OAuth Setup Guide
|
|
3
|
+
type: note
|
|
4
|
+
permalink: authentication/supabase-google-oauth-setup-guide-1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Supabase Google OAuth Setup Guide
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
This guide explains how to enable Google OAuth authentication in Supabase, allowing users to sign in with their Google accounts.
|
|
11
|
+
|
|
12
|
+
## Step 1: Configure Google Cloud Console
|
|
13
|
+
|
|
14
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
15
|
+
2. Create a new project or select an existing one
|
|
16
|
+
3. Navigate to **APIs & Services** → **Credentials**
|
|
17
|
+
4. Click **Create Credentials** → **OAuth client ID**
|
|
18
|
+
5. If prompted, configure the OAuth consent screen:
|
|
19
|
+
- Choose **External** (unless you have a Google Workspace)
|
|
20
|
+
- Fill in app name, support email, developer contact
|
|
21
|
+
- Add scopes: `email`, `profile`, `openid`
|
|
22
|
+
- Add test users if needed (for testing before verification)
|
|
23
|
+
6. Create OAuth client:
|
|
24
|
+
- **Application type**: Web application
|
|
25
|
+
- **Name**: Kinemotion (or your app name)
|
|
26
|
+
- **Authorized JavaScript origins**:
|
|
27
|
+
- `https://kinemotion.vercel.app` (production)
|
|
28
|
+
- `http://localhost:5173` (local development)
|
|
29
|
+
- **Authorized redirect URIs**:
|
|
30
|
+
- Get from Supabase Dashboard → Authentication → Providers → Google
|
|
31
|
+
- Format: `https://<project-id>.supabase.co/auth/v1/callback`
|
|
32
|
+
- For local dev: `http://localhost:3000/auth/v1/callback` (if using Supabase local)
|
|
33
|
+
7. Click **Create** and save:
|
|
34
|
+
- **Client ID** (looks like: `123456789-abc...googleusercontent.com`)
|
|
35
|
+
- **Client Secret** (looks like: `GOCSPX-abc...`)
|
|
36
|
+
|
|
37
|
+
## Step 2: Configure Supabase Dashboard
|
|
38
|
+
|
|
39
|
+
1. Go to your Supabase project dashboard
|
|
40
|
+
2. Navigate to **Authentication** → **Providers**
|
|
41
|
+
3. Find **Google** in the list and click to configure
|
|
42
|
+
4. Enable the provider
|
|
43
|
+
5. Enter:
|
|
44
|
+
- **Client ID**: From Google Cloud Console
|
|
45
|
+
- **Client Secret**: From Google Cloud Console
|
|
46
|
+
6. Click **Save**
|
|
47
|
+
|
|
48
|
+
**Important**: The redirect URI in Google Cloud Console must match:
|
|
49
|
+
- Production: `https://<your-project-id>.supabase.co/auth/v1/callback`
|
|
50
|
+
- Local dev: `http://localhost:3000/auth/v1/callback` (if using Supabase local)
|
|
51
|
+
|
|
52
|
+
## Step 3: Update Frontend Code
|
|
53
|
+
|
|
54
|
+
### Add Google Sign-In Button
|
|
55
|
+
|
|
56
|
+
Update `frontend/src/components/Auth.tsx` to include a Google sign-in button.
|
|
57
|
+
|
|
58
|
+
### Update useAuth Hook
|
|
59
|
+
|
|
60
|
+
Add `signInWithGoogle()` method to `frontend/src/hooks/useAuth.ts`:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
signInWithGoogle: () => Promise<void>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Implementation uses `supabase.auth.signInWithOAuth({ provider: 'google' })`.
|
|
67
|
+
|
|
68
|
+
## Step 4: Update Redirect URLs
|
|
69
|
+
|
|
70
|
+
Ensure your Supabase project has the correct redirect URLs configured:
|
|
71
|
+
|
|
72
|
+
1. Go to **Authentication** → **URL Configuration**
|
|
73
|
+
2. **Site URL**: `https://kinemotion.vercel.app`
|
|
74
|
+
3. **Redirect URLs**:
|
|
75
|
+
- `https://kinemotion.vercel.app/**`
|
|
76
|
+
- `http://localhost:5173/**`
|
|
77
|
+
|
|
78
|
+
## Testing
|
|
79
|
+
|
|
80
|
+
1. Start your frontend: `cd frontend && yarn dev`
|
|
81
|
+
2. Click "Sign in with Google"
|
|
82
|
+
3. You should be redirected to Google's OAuth consent screen
|
|
83
|
+
4. After authorization, you'll be redirected back to your app
|
|
84
|
+
5. Check Supabase Dashboard → Authentication → Users to see the new user
|
|
85
|
+
|
|
86
|
+
## Troubleshooting
|
|
87
|
+
|
|
88
|
+
**Error: "redirect_uri_mismatch"**
|
|
89
|
+
- Ensure the redirect URI in Google Cloud Console exactly matches Supabase callback URL
|
|
90
|
+
- Check for trailing slashes or protocol mismatches (http vs https)
|
|
91
|
+
|
|
92
|
+
**Error: "invalid_client"**
|
|
93
|
+
- Verify Client ID and Client Secret are correct in Supabase Dashboard
|
|
94
|
+
- Ensure Google OAuth consent screen is configured
|
|
95
|
+
|
|
96
|
+
**User not appearing in Supabase**
|
|
97
|
+
- Check browser console for errors
|
|
98
|
+
- Verify redirect URLs are configured correctly
|
|
99
|
+
- Check Supabase logs in Dashboard → Logs → Auth Logs
|
|
100
|
+
|
|
101
|
+
## Security Notes
|
|
102
|
+
|
|
103
|
+
- Never commit Client Secret to git
|
|
104
|
+
- Use environment variables for sensitive values
|
|
105
|
+
- Google OAuth tokens are handled by Supabase automatically
|
|
106
|
+
- JWT tokens from Supabase work the same way for Google-authenticated users
|
|
107
|
+
|
|
108
|
+
## Free Tier Limits
|
|
109
|
+
|
|
110
|
+
- Google OAuth: No additional cost
|
|
111
|
+
- Supabase Auth: 50,000 MAUs/month (free tier)
|
|
112
|
+
- Each Google sign-in counts as one MAU
|
|
113
|
+
|
|
114
|
+
## References
|
|
115
|
+
|
|
116
|
+
- [Supabase Google OAuth Docs](https://supabase.com/docs/guides/auth/social-login/auth-google)
|
|
117
|
+
- [Google Cloud Console](https://console.cloud.google.com/)
|
|
118
|
+
- [Supabase Dashboard](https://supabase.com/dashboard)
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Validation Architecture - Visual Hierarchy After Refactoring
|
|
3
|
+
type: note
|
|
4
|
+
permalink: codebase/validation-architecture-visual-hierarchy-after-refactoring-1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Validation Architecture - After Refactoring
|
|
8
|
+
|
|
9
|
+
## Class Hierarchy
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
13
|
+
│ core/validation.py (SHARED BASE CLASSES) │
|
|
14
|
+
├─────────────────────────────────────────────────────────────┤
|
|
15
|
+
│ │
|
|
16
|
+
│ ┌─ ValidationSeverity (enum) │
|
|
17
|
+
│ │ └─ ERROR, WARNING, INFO │
|
|
18
|
+
│ │ │
|
|
19
|
+
│ ├─ ValidationIssue (dataclass) │
|
|
20
|
+
│ │ └─ severity, metric, message, value, bounds │
|
|
21
|
+
│ │ │
|
|
22
|
+
│ ├─ AthleteProfile (enum) │
|
|
23
|
+
│ │ └─ ELDERLY, UNTRAINED, RECREATIONAL, TRAINED, ELITE │
|
|
24
|
+
│ │ │
|
|
25
|
+
│ ├─ MetricBounds (dataclass) │
|
|
26
|
+
│ │ ├─ absolute/practical/recreational/elite ranges │
|
|
27
|
+
│ │ ├─ contains(value, profile) → bool │
|
|
28
|
+
│ │ └─ is_physically_possible(value) → bool │
|
|
29
|
+
│ │ │
|
|
30
|
+
│ ├─ ValidationResult (dataclass + ABC) │
|
|
31
|
+
│ │ ├─ issues, status, athlete_profile │
|
|
32
|
+
│ │ ├─ add_error(metric, message, value, bounds) │
|
|
33
|
+
│ │ ├─ add_warning(metric, message, value, bounds) │
|
|
34
|
+
│ │ ├─ add_info(metric, message, value) │
|
|
35
|
+
│ │ ├─ finalize_status() → determines PASS/WARNING/FAIL │
|
|
36
|
+
│ │ └─ to_dict() → abstract (subclass implements) │
|
|
37
|
+
│ │ │
|
|
38
|
+
│ └─ MetricsValidator (ABC) │
|
|
39
|
+
│ ├─ __init__(assumed_profile) │
|
|
40
|
+
│ └─ validate(metrics) → abstract │
|
|
41
|
+
│ │
|
|
42
|
+
└─────────────────────────────────────────────────────────────┘
|
|
43
|
+
▲ ▲
|
|
44
|
+
│ │
|
|
45
|
+
┌─────────┴────────┐ ┌───────┴────────┐
|
|
46
|
+
│ │ │ │
|
|
47
|
+
|
|
48
|
+
┌────────────────────────┐ ┌──────────────────────────┐
|
|
49
|
+
│ cmj/ (CMJ-specific) │ │ dropjump/ (DJ-specific) │
|
|
50
|
+
├────────────────────────┤ ├──────────────────────────┤
|
|
51
|
+
│ │ │ │
|
|
52
|
+
│ metrics_validator.py: │ │ metrics_validator.py: │
|
|
53
|
+
│ ┌────────────────────┐ │ │ ┌──────────────────────┐ │
|
|
54
|
+
│ │ CMJMetricsValidator│ │ │ │DropJumpMetricsVali- │ │
|
|
55
|
+
│ │ (extends Metrics- │ │ │ │ dator (extends │ │
|
|
56
|
+
│ │ Validator) │ │ │ │ MetricsValidator) │ │
|
|
57
|
+
│ │ │ │ │ │ │ │
|
|
58
|
+
│ │ CMJValidationResult│ │ │ │ DropJumpValidation- │ │
|
|
59
|
+
│ │ (extends Validation│ │ │ │ Result (extends │ │
|
|
60
|
+
│ │ Result) │ │ │ │ ValidationResult) │ │
|
|
61
|
+
│ └────────────────────┘ │ │ └──────────────────────┘ │
|
|
62
|
+
│ │ │ │
|
|
63
|
+
│ validation_bounds.py: │ │ validation_bounds.py: │
|
|
64
|
+
│ ┌────────────────────┐ │ │ ┌──────────────────────┐ │
|
|
65
|
+
│ │ CMJBounds │ │ │ │ DropJumpBounds │ │
|
|
66
|
+
│ │ └─ FLIGHT_TIME │ │ │ │ └─ CONTACT_TIME │ │
|
|
67
|
+
│ │ └─ JUMP_HEIGHT │ │ │ │ └─ FLIGHT_TIME │ │
|
|
68
|
+
│ │ └─ ... │ │ │ │ └─ JUMP_HEIGHT │ │
|
|
69
|
+
│ │ │ │ │ │ └─ RSI │ │
|
|
70
|
+
│ │ TripleExtension- │ │ │ │ │ │
|
|
71
|
+
│ │ Bounds (hip/knee/ │ │ │ │ estimate_athlete_ │ │
|
|
72
|
+
│ │ ankle angles) │ │ │ │ profile() │ │
|
|
73
|
+
│ │ │ │ │ │ │ │
|
|
74
|
+
│ │ RSIBounds (CMJ- │ │ │ └──────────────────────┘ │
|
|
75
|
+
│ │ specific RSI ranges)│ │ │ │
|
|
76
|
+
│ │ │ │ │ │
|
|
77
|
+
│ │ MetricConsistency │ │ │ │
|
|
78
|
+
│ │ (cross-validation │ │ │ │
|
|
79
|
+
│ │ tolerances) │ │ │ │
|
|
80
|
+
│ │ │ │ │ │
|
|
81
|
+
│ │ estimate_athlete_ │ │ │ │
|
|
82
|
+
│ │ profile() │ │ │ │
|
|
83
|
+
│ └────────────────────┘ │ │ │
|
|
84
|
+
│ │ │ │
|
|
85
|
+
└────────────────────────┘ └──────────────────────────┘
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Data Flow Example
|
|
89
|
+
|
|
90
|
+
### CMJ Validation Flow
|
|
91
|
+
```
|
|
92
|
+
metrics_dict (CMJ data)
|
|
93
|
+
│
|
|
94
|
+
▼
|
|
95
|
+
api.py or test imports CMJMetricsValidator()
|
|
96
|
+
│
|
|
97
|
+
▼
|
|
98
|
+
validator.validate(metrics_dict)
|
|
99
|
+
│
|
|
100
|
+
├─ Estimate profile from jump_height
|
|
101
|
+
│
|
|
102
|
+
├─ Check individual bounds (flight_time, jump_height, etc.)
|
|
103
|
+
│ └─ Each uses MetricBounds.contains(value, profile)
|
|
104
|
+
│
|
|
105
|
+
├─ Cross-validation checks
|
|
106
|
+
│ └─ Uses MetricConsistency tolerances
|
|
107
|
+
│
|
|
108
|
+
└─ Finalize status
|
|
109
|
+
└─ Calls ValidationResult.finalize_status()
|
|
110
|
+
│
|
|
111
|
+
▼
|
|
112
|
+
CMJValidationResult
|
|
113
|
+
├─ status: "PASS" / "PASS_WITH_WARNINGS" / "FAIL"
|
|
114
|
+
├─ issues: list[ValidationIssue]
|
|
115
|
+
├─ athlete_profile: AthleteProfile
|
|
116
|
+
├─ rsi: float
|
|
117
|
+
├─ height_flight_time_consistency: float
|
|
118
|
+
└─ [CMJ-specific fields]
|
|
119
|
+
│
|
|
120
|
+
▼
|
|
121
|
+
result.to_dict() → JSON-serializable dictionary
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Import Structure After Refactoring
|
|
125
|
+
|
|
126
|
+
### Old (Duplicated)
|
|
127
|
+
```python
|
|
128
|
+
# api.py
|
|
129
|
+
from .core.cmj_metrics_validator import CMJMetricsValidator
|
|
130
|
+
from .core.dropjump_metrics_validator import DropJumpMetricsValidator
|
|
131
|
+
|
|
132
|
+
# tests/test_cmj_physiological_bounds.py
|
|
133
|
+
from kinemotion.core.cmj_metrics_validator import CMJMetricsValidator
|
|
134
|
+
from kinemotion.core.cmj_validation_bounds import CMJBounds, AthleteProfile
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### New (Refactored)
|
|
138
|
+
```python
|
|
139
|
+
# api.py
|
|
140
|
+
from .cmj.metrics_validator import CMJMetricsValidator
|
|
141
|
+
from .dropjump.metrics_validator import DropJumpMetricsValidator
|
|
142
|
+
|
|
143
|
+
# tests/test_cmj_physiological_bounds.py
|
|
144
|
+
from kinemotion.cmj.metrics_validator import CMJMetricsValidator
|
|
145
|
+
from kinemotion.cmj.validation_bounds import CMJBounds
|
|
146
|
+
from kinemotion.core.validation import AthleteProfile, ValidationSeverity
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Key Improvements
|
|
150
|
+
|
|
151
|
+
| Aspect | Before | After |
|
|
152
|
+
|--------|--------|-------|
|
|
153
|
+
| Shared code location | core/ with jump prefixes | core/validation.py (no prefixes) |
|
|
154
|
+
| CMJ validator location | core/cmj_metrics_validator.py | cmj/metrics_validator.py |
|
|
155
|
+
| Drop jump validator location | core/dropjump_metrics_validator.py | dropjump/metrics_validator.py |
|
|
156
|
+
| Code duplication | 137 lines (7.7%) | ~10 lines (< 1%) |
|
|
157
|
+
| Base class definition | None (duplicated) | core/validation.py (single source) |
|
|
158
|
+
| AthleteProfile enum copies | 2 (CMJ + drop jump) | 1 (shared in core/validation.py) |
|
|
159
|
+
| MetricBounds class copies | 2 (CMJ + drop jump) | 1 (shared in core/validation.py) |
|
|
160
|
+
| Validator coupling | Tight (no inheritance) | Loose (via inheritance) |
|
|
161
|
+
| Extensibility | Requires copying all code | Extend base classes |
|
|
162
|
+
| Maintenance effort | 2x (update both files) | 1x (fix base class) |
|
|
163
|
+
|
|
164
|
+
## Co-location Benefits
|
|
165
|
+
|
|
166
|
+
All validation code now co-located with its jump type:
|
|
167
|
+
```
|
|
168
|
+
cmj/
|
|
169
|
+
├── analysis.py ← CMJ analysis algorithms
|
|
170
|
+
├── kinematics.py ← CMJ metrics calculation
|
|
171
|
+
├── metrics_validator.py ← ✨ NEW: CMJ validation
|
|
172
|
+
├── validation_bounds.py ← ✨ NEW: CMJ bounds
|
|
173
|
+
└── joint_angles.py ← CMJ-specific angles
|
|
174
|
+
|
|
175
|
+
dropjump/
|
|
176
|
+
├── analysis.py ← Drop jump algorithms
|
|
177
|
+
├── kinematics.py ← Drop jump metrics
|
|
178
|
+
├── metrics_validator.py ← ✨ NEW: Drop jump validation
|
|
179
|
+
└── validation_bounds.py ← ✨ NEW: Drop jump bounds
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
This makes it easier to:
|
|
183
|
+
1. **Understand the jump type** - All related code in one folder
|
|
184
|
+
2. **Add new jump types** - Copy the pattern from an existing type
|
|
185
|
+
3. **Modify jump-specific logic** - Find everything you need in one place
|
|
186
|
+
4. **Maintain shared infrastructure** - core/validation.py is the single source
|
|
187
|
+
|
|
188
|
+
## Next Jump Type Example
|
|
189
|
+
|
|
190
|
+
To add a new jump type (e.g., Standing Jump):
|
|
191
|
+
```
|
|
192
|
+
1. Create standingjump/ folder
|
|
193
|
+
2. Copy structure from cmj/ or dropjump/
|
|
194
|
+
3. Create standingjump/metrics_validator.py
|
|
195
|
+
└─ Extend MetricsValidator from core/validation.py
|
|
196
|
+
4. Create standingjump/validation_bounds.py
|
|
197
|
+
└─ Define StandingJumpBounds, estimate_athlete_profile()
|
|
198
|
+
5. Update api.py imports
|
|
199
|
+
6. All base classes already available in core/validation.py ✅
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
No more code duplication needed!
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Validation Code Duplication Evidence
|
|
3
|
+
type: note
|
|
4
|
+
permalink: codebase/validation-code-duplication-evidence-1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Validation Code Duplication Evidence
|
|
8
|
+
|
|
9
|
+
## Side-by-Side Comparison of Duplicated Code
|
|
10
|
+
|
|
11
|
+
### 1. ValidationSeverity Enum (100% Identical)
|
|
12
|
+
|
|
13
|
+
**CMJ Validator (lines 24-30):**
|
|
14
|
+
```python
|
|
15
|
+
class ValidationSeverity(Enum):
|
|
16
|
+
"""Severity level for validation issues."""
|
|
17
|
+
ERROR = "ERROR"
|
|
18
|
+
WARNING = "WARNING"
|
|
19
|
+
INFO = "INFO"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Drop Jump Validator (lines 20-26):**
|
|
23
|
+
```python
|
|
24
|
+
class ValidationSeverity(Enum):
|
|
25
|
+
"""Severity level for validation issues."""
|
|
26
|
+
ERROR = "ERROR"
|
|
27
|
+
WARNING = "WARNING"
|
|
28
|
+
INFO = "INFO"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Duplication:** 7 lines, 100% identical
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
### 2. ValidationIssue Dataclass (100% Identical)
|
|
36
|
+
|
|
37
|
+
**CMJ Validator (lines 32-41):**
|
|
38
|
+
```python
|
|
39
|
+
@dataclass
|
|
40
|
+
class ValidationIssue:
|
|
41
|
+
"""Single validation issue."""
|
|
42
|
+
severity: ValidationSeverity
|
|
43
|
+
metric: str
|
|
44
|
+
message: str
|
|
45
|
+
value: float | None = None
|
|
46
|
+
bounds: tuple[float, float] | None = None
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Drop Jump Validator (lines 28-37):**
|
|
50
|
+
```python
|
|
51
|
+
@dataclass
|
|
52
|
+
class ValidationIssue:
|
|
53
|
+
"""Single validation issue."""
|
|
54
|
+
severity: ValidationSeverity
|
|
55
|
+
metric: str
|
|
56
|
+
message: str
|
|
57
|
+
value: float | None = None
|
|
58
|
+
bounds: tuple[float, float] | None = None
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Duplication:** 10 lines, 100% identical
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### 3. ValidationResult Methods (100% Identical)
|
|
66
|
+
|
|
67
|
+
**add_error() - CMJ (lines 56-72) vs Drop Jump (lines 50-66):**
|
|
68
|
+
```python
|
|
69
|
+
def add_error(
|
|
70
|
+
self,
|
|
71
|
+
metric: str,
|
|
72
|
+
message: str,
|
|
73
|
+
value: float | None = None,
|
|
74
|
+
bounds: tuple[float, float] | None = None,
|
|
75
|
+
) -> None:
|
|
76
|
+
"""Add error-level issue."""
|
|
77
|
+
self.issues.append(
|
|
78
|
+
ValidationIssue(
|
|
79
|
+
severity=ValidationSeverity.ERROR,
|
|
80
|
+
metric=metric,
|
|
81
|
+
message=message,
|
|
82
|
+
value=value,
|
|
83
|
+
bounds=bounds,
|
|
84
|
+
)
|
|
85
|
+
)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Duplication:** 17 lines × 3 methods (add_error, add_warning, add_info) = 51 lines
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
**finalize_status() - CMJ (lines 108-122) vs Drop Jump (lines 102-116):**
|
|
93
|
+
```python
|
|
94
|
+
def finalize_status(self) -> None:
|
|
95
|
+
"""Determine final pass/fail status based on issues."""
|
|
96
|
+
has_errors = any(
|
|
97
|
+
issue.severity == ValidationSeverity.ERROR for issue in self.issues
|
|
98
|
+
)
|
|
99
|
+
has_warnings = any(
|
|
100
|
+
issue.severity == ValidationSeverity.WARNING for issue in self.issues
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
if has_errors:
|
|
104
|
+
self.status = "FAIL"
|
|
105
|
+
elif has_warnings:
|
|
106
|
+
self.status = "PASS_WITH_WARNINGS"
|
|
107
|
+
else:
|
|
108
|
+
self.status = "PASS"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Duplication:** 15 lines, 100% identical
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
### 4. AthleteProfile Enum (100% Identical)
|
|
116
|
+
|
|
117
|
+
**CMJ Bounds (lines 22-30):**
|
|
118
|
+
```python
|
|
119
|
+
class AthleteProfile(Enum):
|
|
120
|
+
"""Athlete performance categories for metric bounds."""
|
|
121
|
+
ELDERLY = "elderly"
|
|
122
|
+
UNTRAINED = "untrained"
|
|
123
|
+
RECREATIONAL = "recreational"
|
|
124
|
+
TRAINED = "trained"
|
|
125
|
+
ELITE = "elite"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Drop Jump Bounds (lines 22-30):**
|
|
129
|
+
```python
|
|
130
|
+
class AthleteProfile(Enum):
|
|
131
|
+
"""Athlete performance categories for metric bounds."""
|
|
132
|
+
ELDERLY = "elderly"
|
|
133
|
+
UNTRAINED = "untrained"
|
|
134
|
+
RECREATIONAL = "recreational"
|
|
135
|
+
TRAINED = "trained"
|
|
136
|
+
ELITE = "elite"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Duplication:** 9 lines, 100% identical
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### 5. MetricBounds Dataclass (100% Identical)
|
|
144
|
+
|
|
145
|
+
**CMJ Bounds (lines 32-76):**
|
|
146
|
+
```python
|
|
147
|
+
@dataclass
|
|
148
|
+
class MetricBounds:
|
|
149
|
+
"""Physiological bounds for a single metric."""
|
|
150
|
+
absolute_min: float
|
|
151
|
+
practical_min: float
|
|
152
|
+
recreational_min: float
|
|
153
|
+
recreational_max: float
|
|
154
|
+
elite_min: float
|
|
155
|
+
elite_max: float
|
|
156
|
+
absolute_max: float
|
|
157
|
+
unit: str
|
|
158
|
+
|
|
159
|
+
def contains(self, value: float, profile: AthleteProfile) -> bool:
|
|
160
|
+
"""Check if value is within bounds for athlete profile."""
|
|
161
|
+
if profile == AthleteProfile.ELDERLY:
|
|
162
|
+
return self.practical_min <= value <= self.recreational_max
|
|
163
|
+
elif profile == AthleteProfile.UNTRAINED:
|
|
164
|
+
return self.practical_min <= value <= self.recreational_max
|
|
165
|
+
elif profile == AthleteProfile.RECREATIONAL:
|
|
166
|
+
return self.recreational_min <= value <= self.recreational_max
|
|
167
|
+
elif profile == AthleteProfile.TRAINED:
|
|
168
|
+
trained_min = (self.recreational_min + self.elite_min) / 2
|
|
169
|
+
trained_max = (self.recreational_max + self.elite_max) / 2
|
|
170
|
+
return trained_min <= value <= trained_max
|
|
171
|
+
elif profile == AthleteProfile.ELITE:
|
|
172
|
+
return self.elite_min <= value <= self.elite_max
|
|
173
|
+
return False
|
|
174
|
+
|
|
175
|
+
def is_physically_possible(self, value: float) -> bool:
|
|
176
|
+
"""Check if value is within absolute physiological limits."""
|
|
177
|
+
return self.absolute_min <= value <= self.absolute_max
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Drop Jump Bounds (lines 32-76):**
|
|
181
|
+
```python
|
|
182
|
+
@dataclass
|
|
183
|
+
class MetricBounds:
|
|
184
|
+
"""Physiological bounds for a single metric."""
|
|
185
|
+
absolute_min: float
|
|
186
|
+
practical_min: float
|
|
187
|
+
recreational_min: float
|
|
188
|
+
recreational_max: float
|
|
189
|
+
elite_min: float
|
|
190
|
+
elite_max: float
|
|
191
|
+
absolute_max: float
|
|
192
|
+
unit: str
|
|
193
|
+
|
|
194
|
+
def contains(self, value: float, profile: AthleteProfile) -> bool:
|
|
195
|
+
"""Check if value is within bounds for athlete profile."""
|
|
196
|
+
if profile == AthleteProfile.ELDERLY:
|
|
197
|
+
return self.practical_min <= value <= self.recreational_max
|
|
198
|
+
elif profile == AthleteProfile.UNTRAINED:
|
|
199
|
+
return self.practical_min <= value <= self.recreational_max
|
|
200
|
+
elif profile == AthleteProfile.RECREATIONAL:
|
|
201
|
+
return self.recreational_min <= value <= self.recreational_max
|
|
202
|
+
elif profile == AthleteProfile.TRAINED:
|
|
203
|
+
trained_min = (self.recreational_min + self.elite_min) / 2
|
|
204
|
+
trained_max = (self.recreational_max + self.elite_max) / 2
|
|
205
|
+
return trained_min <= value <= trained_max
|
|
206
|
+
elif profile == AthleteProfile.ELITE:
|
|
207
|
+
return self.elite_min <= value <= self.elite_max
|
|
208
|
+
return False
|
|
209
|
+
|
|
210
|
+
def is_physically_possible(self, value: float) -> bool:
|
|
211
|
+
"""Check if value is within absolute physiological limits."""
|
|
212
|
+
return self.absolute_min <= value <= self.absolute_max
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Duplication:** 45 lines, 100% identical
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Duplication Summary
|
|
220
|
+
|
|
221
|
+
| Component | Lines | Duplication % | Status |
|
|
222
|
+
|-----------|-------|---------------|--------|
|
|
223
|
+
| ValidationSeverity | 7 | 100% | \u274c Duplicate |
|
|
224
|
+
| ValidationIssue | 10 | 100% | \u274c Duplicate |
|
|
225
|
+
| ValidationResult.add_error() | 17 | 100% | \u274c Duplicate |
|
|
226
|
+
| ValidationResult.add_warning() | 17 | 100% | \u274c Duplicate |
|
|
227
|
+
| ValidationResult.add_info() | 17 | 100% | \u274c Duplicate |
|
|
228
|
+
| ValidationResult.finalize_status() | 15 | 100% | \u274c Duplicate |
|
|
229
|
+
| AthleteProfile | 9 | 100% | \u274c Duplicate |
|
|
230
|
+
| MetricBounds (full class) | 45 | 100% | \u274c Duplicate |
|
|
231
|
+
|
|
232
|
+
**Total Duplication:** ~137 lines of identical code across 4 files
|
|
233
|
+
|
|
234
|
+
**File sizes:**
|
|
235
|
+
- cmj_metrics_validator.py: 831 lines
|
|
236
|
+
- cmj_validation_bounds.py: 395 lines
|
|
237
|
+
- dropjump_metrics_validator.py: 347 lines
|
|
238
|
+
- dropjump_validation_bounds.py: 197 lines
|
|
239
|
+
- **Combined:** 1,770 lines
|
|
240
|
+
|
|
241
|
+
**Duplication percentage:** 137 / 1770 = **7.7% duplication**
|
|
242
|
+
|
|
243
|
+
**Project standard:** < 3%
|
|
244
|
+
**Status:** \u26a0\ufe0f **Violates quality standard by 2.6x**
|
|
245
|
+
|
|
246
|
+
## Impact
|
|
247
|
+
|
|
248
|
+
1. **Maintenance burden:** Bug fixes must be applied twice
|
|
249
|
+
2. **Inconsistency risk:** Changes to one validator may not propagate to the other
|
|
250
|
+
3. **Extensibility:** Adding new jump types requires copying all base code again
|
|
251
|
+
4. **Code smell:** Indicates architectural debt that should be refactored
|
|
252
|
+
|
|
253
|
+
## Resolution Path
|
|
254
|
+
|
|
255
|
+
Extract shared abstractions to `core/validation.py` as base classes, then:
|
|
256
|
+
- CMJMetricsValidator extends base in `cmj/metrics_validator.py`
|
|
257
|
+
- DropJumpMetricsValidator extends base in `dropjump/metrics_validator.py`
|
|
258
|
+
- Estimated duplication after refactor: < 1% (only jump-specific validation logic remains)
|