Skip to content

feat: add MyFitnessPal integration and external provider settings UI#1101

Open
serjsv87 wants to merge 2 commits intoCodeWithCJ:mainfrom
serjsv87:feature/fitnesspal-clean
Open

feat: add MyFitnessPal integration and external provider settings UI#1101
serjsv87 wants to merge 2 commits intoCodeWithCJ:mainfrom
serjsv87:feature/fitnesspal-clean

Conversation

@serjsv87
Copy link
Copy Markdown

@serjsv87 serjsv87 commented Apr 7, 2026

  • Add MyFitnessPalService for MFP data sync via Garmin integration
  • Add mfpRoutes (/api/integrations/myfitnesspal/sync, /status)
  • Add mfpSyncService for syncing daily food totals
  • Extend externalProviderRepository with MFP-aware queries
  • Add ExternalProviderSettings UI with ProviderCard, AddExternalProviderForm, EditProviderForm, ProviderSpecificFields components
  • Add useIntegrations hook and externalProviderService API client
  • Add myfitnesspal provider type to settings

Tip

Help us review and merge your PR faster!
Please ensure you have completed the Checklist below.
For Frontend changes, please run pnpm run validate to check for any errors.
PRs that include tests and clear screenshots are highly preferred!
Note: AI-generated descriptions must be manually edited for conciseness. Do not paste raw AI summaries.

Description

What problem does this PR solve?
Adds MyFitnessPal integration for syncing food diary data via Garmin, and introduces a redesigned External Provider Settings UI that makes managing all third-party integrations consistent and user-friendly.

How did you implement the solution?
Added myFitnessPalService.ts (MFP API client), mfpSyncService.ts (daily totals sync), and mfpRoutes.ts (POST /api/integrations/myfitnesspal/sync, GET /status). Extended externalProviderRepository.ts with MFP-aware queries. On the frontend, refactored provider settings into reusable components: ExternalProviderSettings, ProviderCard, AddExternalProviderForm, EditProviderForm, and ProviderSpecificFields. Added useIntegrations hook and externalProviderService API client.

Linked Issue: #

How to Test

  1. Check out this branch and run pnpm run validate
  2. Start the server
  3. Navigate to Settings → External Providers
  4. Add a MyFitnessPal provider with your credentials
  5. Trigger a sync via POST /api/integrations/myfitnesspal/sync
  6. Verify food entries appear in the food log for the synced dates

PR Type

  • Issue (bug fix)
  • New Feature
  • Refactor
  • Documentation

Checklist

All PRs:

  • [MANDATORY - ALL] Integrity & License: I certify this is my own work, free of malicious code, and I agree to the License terms.

New features only:

  • [MANDATORY for new feature] Alignment: I have raised a GitHub issue and it was reviewed/approved by maintainers or it was approved on Discord.

Frontend changes (SparkyFitnessFrontend/ or src/):

  • [MANDATORY for Frontend changes] Quality: I have run pnpm run validate and it passes.
  • [MANDATORY for Frontend changes] Translations: I have only updated the English (en) translation file.

Backend changes (SparkyFitnessServer/):

  • [MANDATORY for Backend changes] Code Quality: I have run typecheck, lint, and tests. New files use TypeScript, new endpoints have Zod schemas, and new endpoints include tests.
  • [MANDATORY for Backend changes] Database Security: I have updated rls_policies.sql for any new user-specific tables. (Note: No new tables added; uses existing external_data_providers table).

UI changes (components, screens, pages):

  • [MANDATORY for UI changes] Screenshots: I have attached Before/After screenshots below.

Screenshots

Click to expand

Before

(add screenshot of old provider settings)
before

After

(add screenshot of new ExternalProviderSettings UI)
after

Notes for Reviewers

Optional — use this for anything that doesn't fit above: known tradeoffs, areas you'd like specific feedback on, qustions you have or context that helps reviewers.

- Add MyFitnessPalService for MFP data sync via Garmin integration
- Add mfpRoutes (/api/integrations/myfitnesspal/sync, /status)
- Add mfpSyncService for syncing daily food totals
- Extend externalProviderRepository with MFP-aware queries
- Add ExternalProviderSettings UI with ProviderCard, AddExternalProviderForm,
  EditProviderForm, ProviderSpecificFields components
- Add useIntegrations hook and externalProviderService API client
- Add myfitnesspal provider type to settings
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive integration with MyFitnessPal (MFP), enabling users to sync their nutrition data from SparkyFitness to their MFP diary. The changes span the entire stack, including frontend UI for credential management (CSRF tokens and session cookies), manual sync triggers, and status monitoring. The backend implementation features a new MFP service that handles complex authentication flows, data mapping, and an idempotent sync process that clears existing entries before pushing new totals. Additionally, the PR adds Ukrainian language support and refactors some provider settings. Review feedback highlights opportunities to improve type safety by replacing any with specific interfaces or unknown, optimizing sequential network requests during the deletion phase of the sync, and addressing potential scalability issues with the in-memory sync lock.

- myFitnessPalService: add MFPProvider interface, remove all `as any` casts
- myFitnessPalService: parallel entry deletion with DELETE_CONCURRENCY=5
  limit instead of sequential loop (avoids rate limiting on large diaries)
- myFitnessPalService: fix calories skip check (< 0 not <= 0) so zero-calorie
  entries (supplements, water) are still synced
- myFitnessPalService: use `unknown` + type narrowing in all catch blocks
- mfpSyncService: add SyncResult return type, replace `any` with typed interfaces
- mfpSyncService: document that activeSyncs is a single-process lock and
  note distributed lock requirement for horizontal scaling
@serjsv87 serjsv87 force-pushed the feature/fitnesspal-clean branch from 87c25af to 07293ac Compare April 8, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant