[{"data":1,"prerenderedAt":628},["ShallowReactive",2],{"search-api":3},[4,18,31,41,48,55,62,76,86,98,112,120,127,134,141,148,156,163,171,178,185,193,200,207,217,224,231,241,250,257,264,271,278,285,292,303,310,320,327,336,347,355,361,369,378,388,405,420,433,445,457,468,479,491,500,514,521,535,550,559,567,574,581,589,597,605,612],{"id":5,"path":6,"dir":7,"title":8,"description":9,"keywords":10,"body":17},"content:0.index.md","\u002F","","Overview","Welcome to the comprehensive documentation for SparkyFitness, a self-hosted alternative to MyFitnessPal with AI-powered nutrition assistance.",[11,12,13,14,15,16],"What is SparkyFitness?","Key Features","Architecture","Documentation Sections","Getting Help","License","  Overview  Welcome to the comprehensive documentation for   SparkyFitness , a self-hosted alternative to MyFitnessPal with AI-powered nutrition assistance.    Disclaimer : While we strive to keep this documentation as accurate and up-to-date as possible, some sections may occasionally become outdated. If you encounter any issues or have questions, please reach out via our   GitHub Discussions  or join our   Discord community  where others can help you.  What is SparkyFitness?  SparkyFitness is a full-stack fitness tracking application that helps you monitor nutrition, exercise, body measurements, and achieve your health goals. Built with modern web technologies and designed for self-hosting, it provides complete control over your fitness data.  Key Features    🍎 Nutrition Tracking  - Log meals, create custom foods, analyze trends   💪 Exercise Logging  - Record workouts, browse exercise database   📏 Body Measurements  - Track weight, measurements, visualize progress   🤖 AI Nutrition Coach  - Chat-based food logging with image recognition   🎯 Goal Setting  - Set and track fitness and nutrition goals   📊 Comprehensive Reports  - Detailed analytics and progress tracking   🔒 Privacy-First  - Self-hosted with complete data control  Architecture  SparkyFitness is built with:    Frontend : React 18 + TypeScript + Vite + Tailwind CSS   Backend : Node.js + Express + PostgreSQL   AI Integration : Multi-provider support (OpenAI, Anthropic, Google)   Deployment : Docker containers with development and production configurations   Security : Row Level Security, JWT authentication, encrypted API keys  Documentation Sections     Getting Started  - Complete setup guide for development and production    Development Workflow  - Developer guide and coding standards    Features Overview  - Complete feature documentation    Database Schema  - Database structure and design    Architecture  - High-level architecture  Getting Help    💬 Discord Community :   Join our Discord   📋 GitHub Discussions : Ask questions and share ideas   🐛 Issues : Report bugs and request features   📚 Documentation : Comprehensive guides in this docs site  License  SparkyFitness is open source software. Please check the repository for license details.",{"id":19,"path":20,"dir":21,"title":22,"description":23,"keywords":24,"body":30},"content:1.install:1.docker-compose.md","\u002Finstall\u002Fdocker-compose","install","Docker Compose Recommended","This page provides instructions for installing and running SparkyFitness using Docker Compose. This method is recommended for most users as it simplifies the setup process.",[25,26,27,28,29],"Prerequisites","Installation Steps","Services Overview","Accessing the Application","Stopping and Removing Services","  Docker Compose   Recommended  This page provides instructions for installing and running SparkyFitness using Docker Compose. This method is recommended for most users as it simplifies the setup process.  Prerequisites  Before you begin, ensure you have the following installed:    Docker Desktop : Includes Docker Engine, Docker Compose, and Docker CLI.\n    Download Docker Desktop  Installation Steps    Create a new folder and download Docker files :\nCreate a new directory for SparkyFitness and navigate into it. Then, download the necessary   docker-compose.yml  and   .env  files.     mkdir   sparkyfitness   &&   cd   sparkyfitness\n   curl   -o   docker-compose.yml   https:\u002F\u002Fgithub.com\u002FCodeWithCJ\u002FSparkyFitness\u002Freleases\u002Flatest\u002Fdownload\u002Fdocker-compose.prod.yml      \n   curl   -L   -o   .env   https:\u002F\u002Fgithub.com\u002FCodeWithCJ\u002FSparkyFitness\u002Freleases\u002Flatest\u002Fdownload\u002Fdefault.env.example\n   Configure Environment Variables :\nThe   docker-compose.yml  file relies on environment variables defined in a   .env  file.\nOpen the downloaded   .env  file in a text editor and update the variables to customize your setup. It's crucial to configure these variables correctly for the application to function as expected.  For a complete list of all available variables and their detailed descriptions, please refer to the example environment file:\n   .env.example  on GitHub  For a comprehensive list of all available environment variables and their detailed descriptions, please refer to the   Environment Variables documentation .   Start the Application :\nFrom within the   sparkyfitness  directory (where   docker-compose.yml  is located), pull the latest images and start the application services:     docker   compose   pull   &&   docker   compose   up   -d\n    docker compose pull : Downloads the latest Docker images for the services.   docker compose up -d : Starts the services defined in the   docker-compose.yml  file in detached mode (in the background).  Services Overview  The   docker-compose.prod.yml  file defines three main services:     sparkyfitness-db :    Image :   postgres:15-alpine   Purpose : The PostgreSQL database server for storing application data.   Data Persistence : Data is persisted in a Docker volume mapped to   ..\u002Fpostgresql  on your host, ensuring your data is not lost if containers are removed.    sparkyfitness-server :    Image :   codewithcj\u002Fsparkyfitness_server:latest   Purpose : The backend Node.js application server.   Environment Variables : Configured with necessary database connection details, logging level, API encryption key, JWT secret, and frontend URL.   Dependencies : Depends on   sparkyfitness-db  to ensure the database is running before the server starts.    sparkyfitness-frontend :    Image :   codewithcj\u002Fsparkyfitness:latest   Purpose : The frontend React application served by Nginx.   Ports : Maps host port   3004  to container port   80  (Nginx), making the frontend accessible via   http:\u002F\u002Flocalhost:3004  (or your configured domain).   Dependencies : Depends on   sparkyfitness-server  to ensure the backend is running.  Optional Services (Commented out by default)  To enable these services, open your   docker-compose.yml  file and uncomment the relevant blocks.     sparkyfitness-mcp :    Image :   codewithcj\u002Fsparkyfitness_mcp:latest   Purpose : The Model Context Protocol (MCP) server. Enable this if you want to connect AI assistants (like Claude Desktop or Cursor) to your health data for advanced pattern detection, automated coaching, and custom insights.   Ports : Exposes port   3001  (by default) for the AI client to connect via HTTP.    sparkyfitness-garmin :    Image :   codewithcj\u002Fsparkyfitness_garmin:latest   Purpose : A dedicated microservice for syncing data directly from Garmin Connect.  Accessing the Application  Once all services are up and running, you can access the SparkyFitness frontend in your web browser at the URL you configured for   SPARKY_FITNESS_FRONTEND_URL  (e.g.,   http:\u002F\u002Flocalhost:3004 ).  Stopping and Removing Services  To stop the running services without removing their data volumes:     docker   compose   stop\n  To stop and remove all services, networks, and volumes (this will delete your database data!):     docker   compose   down   -v\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":32,"path":33,"dir":21,"title":34,"description":35,"keywords":36,"body":40},"content:1.install:2.portainer.md","\u002Finstall\u002Fportainer","Portainer Installation Guide","This guide provides step-by-step instructions on how to install and deploy SparkyFitness using Portainer. Portainer simplifies Docker management through a user-friendly web interface.",[25,37,38,39],"Step 1: Create a New Stack in Portainer","Step 2: Deploy the Stack","Step 3: Access SparkyFitness","  Portainer Installation Guide  This guide provides step-by-step instructions on how to install and deploy SparkyFitness using Portainer. Portainer simplifies Docker management through a user-friendly web interface.  Prerequisites  Before you begin, ensure you have:    A running Docker environment : Portainer requires Docker to be installed on your server.   Portainer installed and configured : Access to your Portainer instance. If you haven't installed Portainer yet, follow the official Portainer documentation.  Step 1: Create a New Stack in Portainer    Log in to Portainer .  Navigate to   Stacks  in the left sidebar.  Click   Add stack .   Name your stack  (e.g.,   sparkyfitness ).  Select   Upload  for the build method.   Upload File : Download the   docker-compose.prod.yml  from the latest release and upload it here.  (Optional) You can also use the   Web editor  method and copy-paste the content if you prefer.   Environment variables : For a comprehensive list of all available environment variables and their detailed descriptions, please refer to the   Environment Variables documentation . You will need to add these environment variables directly in Portainer.  Step 2: Deploy the Stack   After configuring the stack, click the   Deploy the stack  button.  Portainer will now pull the necessary Docker images and create the containers for SparkyFitness. This process may take a few minutes depending on your internet connection.  Step 3: Access SparkyFitness  Once the stack is successfully deployed and all containers are running, you can access the SparkyFitness frontend in your web browser.   Open your web browser and navigate to the URL you configured for   SPARKY_FITNESS_FRONTEND_URL  in your environment variables (e.g.,   http:\u002F\u002Fyour-server-ip:3004 ).  You should now see the SparkyFitness login\u002Fsignup page.",{"id":42,"path":43,"dir":21,"title":44,"description":45,"keywords":46,"body":47},"content:1.install:3.synology.md","\u002Finstall\u002Fsynology","Synology Community Guide","This guide provides instructions for installing SparkyFitness on your Synology NAS, provided by the community.",[],"  Synology Community Guide  This guide provides instructions for installing SparkyFitness on your Synology NAS, provided by the community.  For detailed instructions, please refer to the external guide:   How to Install SparkyFitness on your Synology NAS by MariusHosting",{"id":49,"path":50,"dir":21,"title":51,"description":52,"keywords":53,"body":54},"content:1.install:4.proxmox.md","\u002Finstall\u002Fproxmox","Proxmox Installation Guide","This guide provides instructions for installing SparkyFitness on Proxmox VE using a script provided by the community.",[],"  Proxmox Installation Guide  This guide provides instructions for installing SparkyFitness on Proxmox VE using a script provided by the community.   Note: This script is provided via community contribution and is not maintained directly by the SparkyFitness.  For installation instructions and to use the script, please refer to the Proxmox VE Helper-Scripts website:   SparkyFitness Proxmox VE Helper-Script  If you encounter issues related to the Proxmox installation, please report them using the \"Report Issue\" option on the page above.  Since I do not personally use Proxmox, I may not be able to provide much help with this installation method, but the script maintainers and community there should be able to assist.",{"id":56,"path":57,"dir":21,"title":58,"description":7,"keywords":59,"body":61},"content:1.install:5.kubernetes.md","\u002Finstall\u002Fkubernetes","Kubernetes",[60],"Quick Start (Kubernetes)","    Community Contribution:  The Kubernetes and Helm chart support are community-provided. The SparkyFitness maintainers do not currently use Kubernetes and cannot provide full review or official support for this installation method.  Quick Start (Kubernetes)  Deploy SparkyFitness on Kubernetes using the Helm chart directly from the repository.     # 1. Install with default settings (bundled PostgreSQL, no ingress)\n   helm   install   sparkyfitness   oci:\u002F\u002Fghcr.io\u002Fcodewithcj\u002Fcharts\u002Fsparkyfitness\n   \n   # -- OR install directly from source --\n   git   clone   https:\u002F\u002Fgithub.com\u002FCodeWithCJ\u002FSparkyFitness.git\n   helm   install   sparkyfitness   .\u002FSparkyFitness\u002Fhelm\u002Fchart\n   \n   # 2. (Optional) Customize values\n   helm   install   sparkyfitness   .\u002FSparkyFitness\u002Fhelm\u002Fchart   -f   my-values.yaml\n   \n   # 3. Access the application in browser via Ingress or HTTPRoute you've specified in values\n  For all configuration options (external database, ingress, OIDC, email, etc.) see the   Helm chart README .  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":63,"path":64,"dir":21,"title":65,"description":66,"keywords":67,"body":75},"content:1.install:6.build-from-source.md","\u002Finstall\u002Fbuild-from-source","Build from Source","Run SparkyFitness directly on your machine without Docker. You will need Node.js, pnpm, and a running PostgreSQL instance.",[25,68,69,70,71,72,73,74],"1. Clone the repository","2. Install dependencies","3. Configure environment variables","4. Set up PostgreSQL","5. Start the backend server","6. Start the frontend","Port summary","  Build from Source  Run SparkyFitness directly on your machine without Docker. You will need Node.js, pnpm, and a running PostgreSQL instance.  Prerequisites    Node.js  24 or later   pnpm  — install with   npm install -g pnpm   PostgreSQL  17 or later  1. Clone the repository     git   clone   https:\u002F\u002Fgithub.com\u002FCodeWithCJ\u002FSparkyFitness.git\n   cd   SparkyFitness\n  2. Install dependencies     pnpm   install\n  3. Configure environment variables  Copy the example env file to the repo root and fill in your values:   Linux \u002F macOS     cp   docker\u002F.env.example   .env\n   Windows (PowerShell)     Copy-Item docker\\.env.example .env\n  Required values to set in   .env :     Variable  Description     SPARKY_FITNESS_DB_HOST  PostgreSQL host — use   localhost  for local installs    SPARKY_FITNESS_DB_NAME  Database name (e.g.   sparkyfitness_db )    SPARKY_FITNESS_DB_USER  Superuser used for migrations (e.g.   sparky )    SPARKY_FITNESS_DB_PASSWORD  Superuser password    SPARKY_FITNESS_APP_DB_USER  App user with limited privileges (e.g.   sparky_app )    SPARKY_FITNESS_APP_DB_PASSWORD  App user password    SPARKY_FITNESS_FRONTEND_URL  Set to   http:\u002F\u002Flocalhost:8080  for local builds    SPARKY_FITNESS_API_ENCRYPTION_KEY  64-character hex string — generate with   openssl rand -hex 32  or   node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"    BETTER_AUTH_SECRET  Strongly recommended — auto-generated if absent but sessions will not survive server restarts. Signs sessions and encrypts 2FA\u002FTOTP data.   Never change after users have enabled 2FA or they will be locked out.    Note:  The default   SPARKY_FITNESS_DB_HOST  in the example file is set to a Docker service name. Change it to   localhost  for a local install.  4. Set up PostgreSQL  Create the superuser and database that match your   .env  values.   Linux     sudo   -u   postgres   createuser   --pwprompt   sparky\n   sudo   -u   postgres   createdb   sparkyfitness_db   --owner   sparky\n   macOS (Homebrew)  — drop the   sudo -u postgres  prefix if your current user already has PostgreSQL superuser rights:     createuser   --pwprompt   sparky\n   createdb   sparkyfitness_db   --owner   sparky\n   Windows  — open a terminal and use   psql  as the   postgres  user (adjust the path to match your PostgreSQL install):     psql -U postgres -c \"CREATE ROLE sparky WITH LOGIN PASSWORD 'yourpassword';\"\n   psql -U postgres -c \"CREATE DATABASE sparkyfitness_db OWNER sparky;\"\n  The   sparky_app  application user is created automatically by the server on first startup — you do not need to create it manually. Database migrations also run automatically on server start.  5. Start the backend server     cd   SparkyFitnessServer\n   pnpm   start\n  The API server starts on port   3010  by default. On first run it applies all migrations and creates the app database user. API docs are available at   http:\u002F\u002Flocalhost:3010\u002Fapi\u002Fapi-docs\u002Fswagger .  6. Start the frontend  Open a second terminal from the repo root:     cd   SparkyFitnessFrontend\n   pnpm   dev\n  The web app starts on port   8080  by default. Open   http:\u002F\u002Flocalhost:8080  in your browser.  Port summary     Service  Default URL    Backend API   http:\u002F\u002Flocalhost:3010   Frontend   http:\u002F\u002Flocalhost:8080   API Docs   http:\u002F\u002Flocalhost:3010\u002Fapi\u002Fapi-docs\u002Fswagger  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":77,"path":78,"dir":21,"title":79,"description":80,"keywords":81,"body":85},"content:1.install:7.environment-variables.md","\u002Finstall\u002Fenvironment-variables","Environment Variables","This document provides a comprehensive list and detailed descriptions of all environment variables used by SparkyFitness. Proper configuration of these variables is crucial for the application to function as expected.",[82,83,84],"Essential Configuration","Mandatory Volume Paths","Optional Configuration","  Environment Variables  This document provides a comprehensive list and detailed descriptions of all environment variables used by SparkyFitness. Proper configuration of these variables is crucial for the application to function as expected.  For a complete list of all available variables and their detailed descriptions, please refer to the example environment file:\n   .env.example  on GitHub    Important Note for Docker Compose Users: \nFor an environment variable defined in your   .env  file to be recognized by the application running inside a Docker container, it   must  be explicitly passed to that service in your   docker-compose.yml  file. If you add a new variable to your   .env  file that is not already present in the   environment:  section of the   sparkyfitness-server  (or   sparkyfitness-garmin ) service, the application will not see it.  Essential Configuration  The following environment variables are   mandatory  and must be supplied for the application to start correctly. Failure to provide these will result in the server failing to launch.     SPARKY_FITNESS_DB_NAME : Your desired PostgreSQL database name (e.g.,   sparkyfitness_db ).    SPARKY_FITNESS_DB_USER : Your desired PostgreSQL database user (e.g.,   sparky ). This user is used for DB initialization and migrations.    SPARKY_FITNESS_DB_PASSWORD : A strong password for your PostgreSQL database. This shouldn't be changed after initial setup. If you need to change it, you will need to update the password in the database and update this env variable.    SPARKY_FITNESS_APP_DB_USER : Application database user with limited privileges. It can be changed any time after initialization.    SPARKY_FITNESS_APP_DB_PASSWORD : Password for the application database user.    SPARKY_FITNESS_FRONTEND_URL : The public URL of your frontend (e.g.,   http:\u002F\u002Flocalhost:8080  for local testing, or your domain like   https:\u002F\u002Ffitness.example.com  for production). This is crucial for CORS security.    SPARKY_FITNESS_API_ENCRYPTION_KEY : A 64-character hex string for data encryption. You can generate one using:\n    openssl rand -hex 32   node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"    SPARKY_FITNESS_API_ENCRYPTION_KEY_FILE : (Optional) Path to a file containing the encryption key. Useful for Docker Swarm\u002FKubernetes secrets. When this variable is set, the application will read the encryption key from the specified file path, allowing for more secure secret management in containerized environments.    BETTER_AUTH_SECRET : A secret key used by Better Auth to sign sessions and tokens. Make this a long, random, and secure string. You can generate one using:\n    openssl rand -hex 32   node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"     !CAUTION  CRITICAL for 2FA\u002FTOTP:  This secret is used to encrypt Two-Factor Authentication (2FA) data in the database. If you change this variable after users have enabled 2FA, the server will lose access to their codes, and   all 2FA users will be locked out  of their accounts. This variable must be set to a persistent value during initial setup and should never be changed.   If you must change it, you must ensure that ALL users have disabled Two-Factor Authentication (TOTP) first.  Mandatory Volume Paths  These paths define where Docker volumes will store persistent data on your host. These are   mandatory  to prevent data loss if containers are removed. You can either define them in the   .env  file or directly in the   docker-compose.yml .     DB_PATH : Path for PostgreSQL database data (e.g.,   ..\u002Fpostgresql ).    SERVER_BACKUP_PATH : Path for server backups (e.g.,   .\u002Fbackup ).    SERVER_UPLOADS_PATH : Path for profile pictures and exercise images (e.g.,   .\u002Fuploads ).  Optional Configuration  The following variables are optional and can be used to customize your SparkyFitness installation.  Front End Variables  These variables control frontend behavior and should be passed to the   sparkyfitness-frontend  service\nin your   docker-compose.yml .     SPARKY_FITNESS_SERVER_HOST : Hostname of the backend server.    SPARKY_FITNESS_SERVER_PORT : Port on which the backend serer is running.    SPARKY_FITNESS_FRONTEND_URL : The frontend URL on which the server will be accessible, useful for reverse proxies.    NGINX_LISTEN_PORT : The port on which nginx should listen. Defaults to   80  when running as root and\n  8080  when running as non-root.    NGINX_ACCESS_LOG : The access log path for nginx. Defaults to   \u002Fvar\u002Flog\u002Fnginx\u002Faccess.log  when running\nas root and   \u002Fdev\u002Fstdout  when running as non-root.    NGINX_ERROR_LOG : The error log path for nginx. Defaults to   \u002Fvar\u002Flog\u002Fnginx\u002Ferror.log  when running\nas root and   \u002Fdev\u002Fstderr  when running as non-root.    NGINX_DUMP_CONFIG : Always dump the complete nginx configuration on startup. The configuration should\nalways be dumped if it's invalid. Defaults to \"false\".   The container will automatically detect if it's running as root and switch defaults as necessary.  Server Side Variables  These variables control backend behavior and should be passed to the   sparkyfitness-server  service in your   docker-compose.yml .     SPARKY_FITNESS_DISABLE_EMAIL_LOGIN : Set to   true  to disable email\u002Fpassword login on the login page (overridden by   SPARKY_FITNESS_FORCE_EMAIL_LOGIN ).    SPARKY_FITNESS_LOG_LEVEL : Logging level for the server (e.g.,   INFO ,   DEBUG ,   WARN ,   ERROR ).    NODE_ENV : Node.js environment mode (e.g.,   development ,   production ,   test ). Set to   production  for deployment to ensure optimal performance and security.    TZ : Server timezone. Use a TZ database name (e.g.,   America\u002FNew_York ,   Etc\u002FUTC ).    SPARKY_FITNESS_DISABLE_SIGNUP : Set to   true  to disable new user registrations.    SPARKY_FITNESS_ADMIN_EMAIL : Set the email of a user to automatically grant admin privileges on server startup. If not set, no admin user will be created automatically.    SPARKY_FITNESS_FORCE_EMAIL_LOGIN : Set to   true  to force email\u002Fpassword login to be enabled, overriding any in-app settings. This is a fail-safe to prevent being locked out if OIDC is misconfigured.    ALLOW_PRIVATE_NETWORK_CORS : Set to   true  to allow Cross-Origin Resource Sharing (CORS) from private network addresses (e.g.,   192.168.x.x ,   10.x.x.x ,   127.0.0.1 ,   localhost ). Use with caution.    SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS : A comma-separated list of additional URLs that Better Auth should trust (e.g.,   http:\u002F\u002F192.168.1.175:8080 ). Use this if you are accessing the app from specific local IPs and   ALLOW_PRIVATE_NETWORK_CORS  is enabled.    SPARKY_FITNESS_DB_HOST : The hostname of the PostgreSQL database. For Docker Compose, this defaults to   sparkyfitness-db  (the service name). Only change this if you are using an external database server.    SPARKY_FITNESS_DB_PORT : Controls the   host port  exposed for external database access (e.g., pgAdmin).   Important:  Inside Docker, containers always communicate on port   5432 . Changing this value in   .env  will   not  affect container-to-container communication unless you are using an external database server.\nTo use this, you must also uncomment the   ports  section under the   sparkyfitness-db  service in your   docker-compose.yml  file.    SPARKY_FITNESS_SERVER_HOST : The hostname or IP of the backend server. Primarily used by the internal Nginx proxy (not to be confused with your proxy manager) in the frontend container to route API requests. For Docker Compose, this defaults to   sparkyfitness-server .    SPARKY_FITNESS_SERVER_PORT : The server port (e.g.,   3010 ). Defaults to   3010 . This is also used by the internal Nginx proxy (not to be confused with your proxy manager) in the frontend container.  Email Settings (Server Side)  Configure these variables to enable email notifications (e.g., for password resets). If not configured, email functionality will be disabled.     SPARKY_FITNESS_EMAIL_HOST : SMTP host (e.g.,   smtp.example.com ).    SPARKY_FITNESS_EMAIL_PORT : SMTP port (e.g.,   587 ).    SPARKY_FITNESS_EMAIL_SECURE : Use   true  for TLS\u002FSSL,   false  for plain text.    SPARKY_FITNESS_EMAIL_USER : Your email username.    SPARKY_FITNESS_EMAIL_PASS : Your email password.    SPARKY_FITNESS_EMAIL_FROM : The 'from' email address.  Rate Limiting (Server Side)  API keys are rate-limited to prevent abuse. These must be passed to   sparkyfitness-server .     SPARKY_FITNESS_API_KEY_RATELIMIT_WINDOW_MS : Time window in milliseconds. Defaults to   60000  (1 minute).    SPARKY_FITNESS_API_KEY_RATELIMIT_MAX_REQUESTS : Maximum number of requests allowed per window. Defaults to   100 .  OIDC Configuration (Server Side)  These variables configure the environment-based OIDC provider and must be passed to the   sparkyfitness-server  service.  When the following are set, an OIDC provider is created or updated at startup and used with the existing SSO flow.     SPARKY_FITNESS_DISABLE_EMAIL_LOGIN : Set to   true  to disable email\u002Fpassword login on the login page (overridden by   SPARKY_FITNESS_FORCE_EMAIL_LOGIN ).    SPARKY_FITNESS_OIDC_AUTH_ENABLED : Set to   true  to enable OIDC login, overriding the value from Admin > Authentication Settings.    SPARKY_FITNESS_OIDC_ISSUER_URL : Issuer URL (e.g.   https:\u002F\u002Fauth.example.com ). Discovery URL is derived as issuer +   \u002F.well-known\u002Fopenid-configuration . Required for env provider upsert.    SPARKY_FITNESS_OIDC_CLIENT_ID ,    SPARKY_FITNESS_OIDC_CLIENT_SECRET : Client credentials from your IdP. Required for env provider upsert.    SPARKY_FITNESS_OIDC_PROVIDER_SLUG : URL-safe provider id (e.g.   authentik ). Required for env provider upsert.    SPARKY_FITNESS_OIDC_PROVIDER_NAME : Display name for the provider (optional; defaults to slug).    SPARKY_FITNESS_OIDC_SCOPE : Space-separated OIDC scopes (optional; defaults to   openid email profile ).    SPARKY_FITNESS_OIDC_AUTO_REGISTER : Set to   true  to automatically create a new user account on first OIDC login (optional; defaults to   true ).    SPARKY_FITNESS_OIDC_LOGO_URL : URL to a custom logo for the provider (optional).    SPARKY_FITNESS_OIDC_DOMAIN : Organization domain for restricted access (optional; defaults to   slug.env ).    SPARKY_FITNESS_OIDC_TOKEN_AUTH_METHOD : Authentication method for the token endpoint (optional; defaults to   client_secret_post ).    SPARKY_FITNESS_OIDC_ID_TOKEN_SIGNED_ALG : Algorithm used to sign the ID token (optional; defaults to   RS256 ).    SPARKY_FITNESS_OIDC_USERINFO_SIGNED_ALG : Algorithm used to sign the UserInfo response (optional; defaults to   none ).    SPARKY_FITNESS_OIDC_TIMEOUT : Request timeout in milliseconds (optional; defaults to   30000 ).    SPARKY_FITNESS_OIDC_AUTO_REDIRECT : Set to   true  to allow auto-redirect to the single OIDC provider when email login is disabled.    SPARKY_FITNESS_OIDC_ADMIN_GROUP : Group\u002Fclaim value from your IdP for admin role mapping. Configure your IdP to send this in token claims; it is used to automatically grant admin privileges.    ALLOW_PRIVATE_NETWORK_CORS : Set to   true  to allow Cross-Origin Resource Sharing (CORS) from private network addresses (e.g.,   192.168.x.x ,   10.x.x.x ,   127.0.0.1 ,   localhost ). This allows standard browser requests from local IPs. Use with caution.    SPARKY_FITNESS_EXTRA_TRUSTED_ORIGINS : A comma-separated list of additional URLs that Better Auth should trust (e.g.,   http:\u002F\u002F192.168.1.175:8080,http:\u002F\u002F10.0.0.5:8080 ). Use this if you are accessing the app from specific local IPs on your network and   ALLOW_PRIVATE_NETWORK_CORS  is enabled.  Garmin Integration  If you require Garmin integration, ensure   GARMIN_MICROSERVICE_URL  is passed to both the   sparkyfitness-server  and   sparkyfitness-garmin  services. The other two variables are for the   sparkyfitness-garmin  service.     GARMIN_MICROSERVICE_URL : The URL for the Garmin microservice (e.g.,   http:\u002F\u002Fsparkyfitness-garmin:8000 ).    GARMIN_SERVICE_PORT : Used for Garmin Connect synchronization. Must match   GARMIN_MICROSERVICE_URL .    GARMIN_SERVICE_IS_CN : Set to   true  for China region. Defaults to   false .  MCP Server Configuration  If you are running the optional Model Context Protocol (MCP) server to connect AI assistants to your health data, the following variables are relevant. The MCP server shares the core database variables with the main server.     MCP_TRANSPORT : The transport protocol used by the MCP server. Defaults to   http  for Docker deployments (where the AI client talks to the server over an HTTP stream), but can also be set to   stdio  for local binary execution.    DEV_TOOLS_ENABLED : (Optional) Set to   true  to enable deep database inspection tools for the AI.   Requires the authenticated user to be an admin.  Do not enable this in production unless you are actively debugging schema issues.",{"id":87,"path":88,"dir":21,"title":89,"description":90,"keywords":91,"body":97},"content:1.install:8.external-database.md","\u002Finstall\u002Fexternal-database","External Database Setup","If you are using your own PostgreSQL instance (e.g., AWS RDS, Azure Database, or a local installation) instead of the provided Docker Compose setup, follow these steps to ensure the database is correctly configured.",[92,93,94,95,96],"1. Database and Users","2. PostgreSQL Extensions","3. Row Level Security (RLS)","4. Environment Configuration","5. Security Hardening","  External Database Setup  If you are using your own PostgreSQL instance (e.g., AWS RDS, Azure Database, or a local installation) instead of the provided Docker Compose setup, follow these steps to ensure the database is correctly configured.    !WARNING  Community Supported Only \nExternal and managed database configurations are not officially tested or supported by the core application maintainers. Use this guide at your own risk.  1. Database and Users  The application uses two database roles:    SPARKY_FITNESS_DB_USER : Used for migrations and schema management.   SPARKY_FITNESS_APP_DB_USER : Used by the application components with restricted permissions.  Steps to Configure  Run the following as a database superuser:     -- 1. Create the Database\n   CREATE DATABASE sparkyfitness_db;\n   \n   -- 2. Create the DB Owner user (referenced in .env as SPARKY_FITNESS_DB_USER)\n   CREATE USER sparky_admin WITH PASSWORD 'your_secure_password';\n   \n   -- 3. Grant database ownership\n   ALTER DATABASE sparkyfitness_db OWNER TO sparky_admin;\n   \n   -- 4. Grant Role Creation privilege\n   -- This allows the DB Owner to automatically create the App User during setup\n   ALTER USER sparky_admin CREATEROLE;\n   \n   -- 5. Special Note for PostgreSQL 15+\n   -- Since PG 15, the default 'public' schema permissions have changed.\n   -- You may need to explicitly grant create permissions to the owner:\n   GRANT ALL ON SCHEMA public TO sparky_admin;\n  2. PostgreSQL Extensions  The application requires specific extensions. If your DB Owner user is not a superuser (common in managed environments like AWS RDS), you must pre-install these extensions as an administrator:     \\c sparkyfitness_db\n   \n   -- Standard extensions\n   CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";\n   CREATE EXTENSION IF NOT EXISTS \"pgcrypto\";\n   \n   -- Performance monitoring\n   CREATE EXTENSION IF NOT EXISTS \"pg_stat_statements\";\n   \n   -- Grant with grant to functions that extensions add as they are still owned by postgres\n   GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO \"sparky_admin\" WITH GRANT OPTION;\n  3. Row Level Security (RLS)  The   sparky_admin  user must be the   Owner  of the tables to enable and manage RLS policies. By setting the   ALTER DATABASE ... OWNER TO sparky_admin , most systems will automatically make   sparky_admin  the owner of any tables it creates during migrations.  4. Environment Configuration  In your   .env  file, ensure you point to your external database:     SPARKY_FITNESS_DB_HOST  =  your-db-host\n   SPARKY_FITNESS_DB_NAME  =  sparkyfitness_db\n   SPARKY_FITNESS_DB_USER  =  sparky_admin\n   SPARKY_FITNESS_DB_PASSWORD  =  your_secure_password\n   SPARKY_FITNESS_DB_PORT  =  5432\n    !IMPORTANT \nThe application will automatically create the restricted   App User  (defined in   SPARKY_FITNESS_APP_DB_USER ) and grant it necessary permissions during the first startup, provided the   SPARKY_FITNESS_DB_USER  has the   CREATEROLE  privilege.  5. Security Hardening  For users requiring maximum security, the   CREATEROLE  privilege is only strictly necessary during the   initial installation  or when new structural roles are added in application updates.  Revoking CREATEROLE  Once the application has successfully started for the first time and you see the log   Successfully created role , you can revoke this privilege:     ALTER USER sparky_admin NOCREATEROLE;\n    !CAUTION  Potential Issues with NOCREATEROLE \nIf you revoke this privilege, future application updates that require creating new specialized database roles will fail. If you encounter a \"Permission Denied\" error during a future upgrade, you may need to temporarily re-grant   CREATEROLE  or manually create the required roles as a superuser.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":99,"path":100,"dir":21,"title":101,"description":102,"keywords":103,"body":111},"content:1.install:9.postgres-upgrade.md","\u002Finstall\u002Fpostgres-upgrade","PostgreSQL Upgrade (15 to 18.3)","This guide provides a step-by-step tutorial for upgrading your SparkyFitness PostgreSQL database from version 15-alpine to 18.3-alpine.",[25,104,105,106,107,108,109,110],"Default Paths","Assumptions","Part 1: Backup and Shutdown","Part 2: Configuration Update","Update postgres, server, frontend and garmin(if using garmin) section in your compose file to include 1000 for PUID and GUID\nPUID: 1000\nGUID: 1000","Part 3: Restore and Restart","Troubleshooting","  PostgreSQL Upgrade (15 to 18.3)  This guide provides a step-by-step tutorial for upgrading your SparkyFitness PostgreSQL database from version 15-alpine to 18.3-alpine.    !IMPORTANT  Warning : PostgreSQL does NOT automatically upgrade its data. Changing the image version alone will cause the database to fail to start. Follow these steps carefully.  Prerequisites   SparkyFitness installed via Docker Compose.  Basic knowledge of Docker commands.  Things can go wrong and you don't blame me :)  You have a backup of your data before starting the upgrade.  You have a backup of your .env file before starting the upgrade.  You have a backup of your docker-compose.yml file before starting the upgrade.  Default Paths  This guide assumes you are using the default SparkyFitness directory structure. If you have custom paths, replace\n  .\u002Fpostgresql  with your actual path.  Assumptions    Base path : Your SparkyFitness installation directory (where   docker-compose.yml  is located).   Default Database Path :   .\u002Fpostgresql  (relative to the compose file).   Database Username :   sparky  (Verify this in your   .env  file. This is your SPARKY_FITNESS_DB_USER).  **Database Name:   sparkyfitness_db  (this is your SPARKY_FITNESS_DB_NAME. default is sparkyfitness_db)   Part 1: Backup and Shutdown  1. Perform a Full Data Backup  Run this on your host terminal to export all your data into a single SQL file. Replace   [OLD_CONTAINER_NAME]  with your actual container name (e.g.,   sparkyfitness-db  or   postgres15-alpine ):\nrun \"docker ps \" to find the old container name. in the below command sparky is your SPARKY_FITNESS_DB_USER     docker   exec   -i   [OLD_CONTAINER_NAME] pg_dumpall -U sparky   >   .\u002Ffull_backup.sql\n  2. Stop All Containers  Stop the services to prevent any new data from being written during the upgrade.     docker   compose   down\n  3. Backup and Move Old Volume (Host Side)  We'll rename the old volume as a safety measure and create a fresh one for the new version.     cd   your_sparkyfitness_directory\n   # Move old v15 data to a backup folder\n   sudo   mv   .\u002Fpostgresql   .\u002Fpostgresql_v15\n   # Create a fresh folder for the new version\n   sudo   mkdir   -p   .\u002Fpostgresql\n   # Set the correct permissions for the Postgres process (UID 70)\n   sudo   chown   -R   1000:1000   .\u002F  *\n   Part 2: Configuration Update  4. Update your   docker-compose.yml  Modify the   sparkyfitness-db  service to use the new image and the corrected mount point structure required for version 18.3.\nWe are updating the container name to sparkyfitness-db and image to postgres:18.3     version  :   \"3.9\"\n   services  :\n     sparkyfitness-db  :\n       image  :   postgres:18.3-alpine\n       container_name  :   sparkyfitness-db\n  Update the   volumes  section of the   sparkyfitness-db  service to:           -   ${DB_PATH:-.\u002Fpostgresql}:\u002Fvar\u002Flib\u002Fpostgresql\n  4. Update your   docker-compose.yml  Update postgres, server, frontend and garmin(if using garmin) section in your compose file to include 1000 for PUID and GUID\nPUID: 1000\nGUID: 1000  Part 3: Restore and Restart  5. Bring Up All Containers  Start the sparkyfitness db container     docker   compose   up   -d   sparkyfitness-db\n    !IMPORTANT \nWait   30 seconds  for all services to fully initialize before proceeding. If you restore before the app finishes initializing, the app will overwrite your restored data.  6. Restore the Data  Once the db container is running and initialized, run the restore.     cat   .\u002Ffull_backup.sql   |   docker   exec   -i   sparkyfitness-db   psql   -U   sparky\n  if a restore fails try this     cat   .\u002Ffull_backup.sql   |   docker   exec   -i   sparkyfitness-db   psql   -U   sparky   -d   sparkyfitness_db\n  7. Restart All Containers  Restart the services so the app picks up the restored data.     docker   compose   restart\n   Troubleshooting    Permission Denied : If the container fails to start with a permission error, re-run:\n  sudo chown -R 1000:1000 .\u002Fpostgresql  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":113,"path":114,"dir":115,"title":116,"description":117,"keywords":118,"body":119},"content:2.features:1.diary:daily-calorie-goal.md","\u002Ffeatures\u002Fdiary\u002Fdaily-calorie-goal","diary","Daily Calorie Goal","SparkyFitness allows you to set and track your daily calorie goals, providing insights into your nutritional intake. Details on how to configure and monitor your calorie goals will be added in the future.",[],"  Daily Calorie Goal  SparkyFitness allows you to set and track your daily calorie goals, providing insights into your nutritional intake. Details on how to configure and monitor your calorie goals will be added in the future.    Calorie goals can be configured under the goals section:\n ",{"id":121,"path":122,"dir":115,"title":123,"description":124,"keywords":125,"body":126},"content:2.features:1.diary:exercise.md","\u002Ffeatures\u002Fdiary\u002Fexercise","Exercise Tracking","SparkyFitness allows you to easily track your exercise routines, including details like duration, intensity, and calories burned. Comprehensive guides on logging and managing your workouts will be added in the future.",[],"  Exercise Tracking  SparkyFitness allows you to easily track your exercise routines, including details like duration, intensity, and calories burned. Comprehensive guides on logging and managing your workouts will be added in the future.",{"id":128,"path":129,"dir":115,"title":130,"description":131,"keywords":132,"body":133},"content:2.features:1.diary:meals.md","\u002Ffeatures\u002Fdiary\u002Fmeals","Meals","This section provides an overview of meal-related features in SparkyFitness.\nCustom meals can be created and consist of previously added foods. That way, you can group foods together and don't have to add them one by one. An example of how this might look like is provided below:",[],"  Meals  This section provides an overview of meal-related features in SparkyFitness.\nCustom meals can be created and consist of previously added foods. That way, you can group foods together and don't have to add them one by one. An example of how this might look like is provided below:  Meal Management:\n   Adding a meal:\n ",{"id":135,"path":136,"dir":115,"title":137,"description":138,"keywords":139,"body":140},"content:2.features:1.diary:nutrition-summary.md","\u002Ffeatures\u002Fdiary\u002Fnutrition-summary","Nutrition Summary","SparkyFitness provides a comprehensive nutrition summary, allowing you to view your daily intake of macronutrients. Your micronutrients and an overview about Trends for the last week, month or a custom time range can be found under reports.\n",[],"  Nutrition Summary  SparkyFitness provides a comprehensive nutrition summary, allowing you to view your daily intake of macronutrients. Your micronutrients and an overview about Trends for the last week, month or a custom time range can be found under reports.\n ",{"id":142,"path":143,"dir":115,"title":144,"description":145,"keywords":146,"body":147},"content:2.features:1.diary:water-intake.md","\u002Ffeatures\u002Fdiary\u002Fwater-intake","Water Intake","SparkyFitness allows you to easily track your daily water intake, helping you stay hydrated and meet your health goals. Details on how to log and monitor your water consumption will be added in the future.",[],"  Water Intake  SparkyFitness allows you to easily track your daily water intake, helping you stay hydrated and meet your health goals. Details on how to log and monitor your water consumption will be added in the future.",{"id":149,"path":150,"dir":151,"title":152,"description":153,"keywords":154,"body":155},"content:2.features:2.check-in.md","\u002Ffeatures\u002Fcheck-in","features","Check-In","The Check-In feature in SparkyFitness allows you to quickly log your daily progress, including meals, exercises, and other key metrics. Detailed instructions on using the Check-In feature will be provided in the future.",[],"  Check-In  The Check-In feature in SparkyFitness allows you to quickly log your daily progress, including meals, exercises, and other key metrics. Detailed instructions on using the Check-In feature will be provided in the future.",{"id":157,"path":158,"dir":151,"title":159,"description":160,"keywords":161,"body":162},"content:2.features:3.reports.md","\u002Ffeatures\u002Freports","Reports","SparkyFitness provides powerful reporting tools to visualize your progress, analyze trends, and gain insights into your fitness journey.\nYour reports page might look like this:\n",[],"  Reports  SparkyFitness provides powerful reporting tools to visualize your progress, analyze trends, and gain insights into your fitness journey.\nYour reports page might look like this:\n   Metrics synced through the Android App or the ios shortcut will appear at the bottom of the reports page:\n ",{"id":164,"path":165,"dir":166,"title":167,"description":168,"keywords":169,"body":170},"content:2.features:4.food:1.food-database-manager.md","\u002Ffeatures\u002Ffood\u002Ffood-database-manager","food","Food Database Manager","This page will explain how to use the Food Database Manager in SparkyFitness.\nThe Food and exercise providers can be configured under Settings. There, you can add, modify or delete food data or exercise data providers. It might look like this for example:\n",[],"  Food Database Manager  This page will explain how to use the Food Database Manager in SparkyFitness.\nThe Food and exercise providers can be configured under Settings. There, you can add, modify or delete food data or exercise data providers. It might look like this for example:\n ",{"id":172,"path":173,"dir":166,"title":174,"description":175,"keywords":176,"body":177},"content:2.features:4.food:2.custom-food-form.md","\u002Ffeatures\u002Ffood\u002Fcustom-food-form","Custom Food Form","This page will explain how to use the Custom Food Form in SparkyFitness.\nWhen you add a food, you'll have the option to add a custom food like here:\n",[],"  Custom Food Form  This page will explain how to use the Custom Food Form in SparkyFitness.\nWhen you add a food, you'll have the option to add a custom food like here:\n   Choosing Custom Food will open a window where you can input a name, brand and both macronutrients and micronutrients\n ",{"id":179,"path":180,"dir":166,"title":181,"description":182,"keywords":183,"body":184},"content:2.features:4.food:3.food-search.md","\u002Ffeatures\u002Ffood\u002Ffood-search","Food Search","This page will explain how to search for food items in SparkyFitness.\nWhen you click on Add food, you'll have the option to search for recent foods:\n",[],"  Food Search  This page will explain how to search for food items in SparkyFitness.\nWhen you click on Add food, you'll have the option to search for recent foods:\n   You'll also have the option to search for Food online using your configured Food data providers or even scan a Barcode:\n ",{"id":186,"path":187,"dir":188,"title":189,"description":190,"keywords":191,"body":192},"content:2.features:5.exercises:exercise-database-manager.md","\u002Ffeatures\u002Fexercises\u002Fexercise-database-manager","exercises","Exercise Database Manager","This page will explain how to use the Exercise Database Manager in SparkyFitness.",[],"  Exercise Database Manager  This page will explain how to use the Exercise Database Manager in SparkyFitness.",{"id":194,"path":195,"dir":188,"title":196,"description":197,"keywords":198,"body":199},"content:2.features:5.exercises:exercise-search.md","\u002Ffeatures\u002Fexercises\u002Fexercise-search","Exercise Search","This page will explain how to search for exercises in SparkyFitness.",[],"  Exercise Search  This page will explain how to search for exercises in SparkyFitness.",{"id":201,"path":202,"dir":151,"title":203,"description":204,"keywords":205,"body":206},"content:2.features:6.goals.md","\u002Ffeatures\u002Fgoals","Goals","SparkyFitness allows you to set and track various fitness and nutrition goals, helping you stay motivated and monitor your progress. Details on how to set up and manage your goals will be provided in the future.",[],"  Goals  SparkyFitness allows you to set and track various fitness and nutrition goals, helping you stay motivated and monitor your progress. Details on how to set up and manage your goals will be provided in the future.",{"id":208,"path":209,"dir":210,"title":211,"description":212,"keywords":213,"body":216},"content:2.features:7.settings:external-providers.md","\u002Ffeatures\u002Fsettings\u002Fexternal-providers","settings","External Providers","SparkyFitness supports integration with external health and fitness data providers to automatically sync your activity and measurements.",[214,215],"Supported Providers","Contributing Mock Data","  External Providers  SparkyFitness supports integration with external health and fitness data providers to automatically sync your activity and measurements.   Supported Providers  SparkyFitness supports integration with the following health and fitness data providers:   Apple Health (iOS)  Google Health Connect (Android)  Fitbit  Garmin Connect  Withings  Polar Flow (partially tested)  Hevy (not tested)  OpenFoodFacts  USDA  Fatsecret  Nutritioninx  Mealie  Tandori  Strava (partially tested)   Contributing Mock Data  We are constantly working to improve these integrations. If you notice data missing or incorrect, you can help by providing anonymized mock data.  Join the   CodeWithCJ  community on   Discord  and reach out if you'd like to share your mock data to help us improve the sync logic!",{"id":218,"path":219,"dir":210,"title":220,"description":221,"keywords":222,"body":223},"content:2.features:7.settings:login-management.md","\u002Ffeatures\u002Fsettings\u002Flogin-management","Login Management","This page will explain how to manage login settings in SparkyFitness.",[],"  Login Management  This page will explain how to manage login settings in SparkyFitness.",{"id":225,"path":226,"dir":210,"title":227,"description":228,"keywords":229,"body":230},"content:2.features:7.settings:nutrient-display-settings.md","\u002Ffeatures\u002Fsettings\u002Fnutrient-display-settings","Nutrient Display Settings","This page will explain how to configure nutrient display settings in SparkyFitness.",[],"  Nutrient Display Settings  This page will explain how to configure nutrient display settings in SparkyFitness.",{"id":232,"path":233,"dir":210,"title":234,"description":235,"keywords":236,"body":240},"content:2.features:7.settings:polar.md","\u002Ffeatures\u002Fsettings\u002Fpolar","Polar Flow Integration","The Polar integration allows you to sync workouts, physical measurements, and daily activity metrics from your Polar account directly to SparkyFitness.",[237,238,239,215],"Setup Instructions","Data Synchronized","Important Limitations","  Polar Flow Integration  The Polar integration allows you to sync workouts, physical measurements, and daily activity metrics from your Polar account directly to SparkyFitness.   Setup Instructions  To connect Polar Flow, follow these steps:    Register as a Developer : Visit the   Polar AccessLink Admin  portal and create a new client.   Configure Callback URL : In the Polar Admin portal, set your   Callback URL  to:\nDirectly get from External Providers page in SparkyFitness   Enter Credentials : In SparkyFitness Settings, navigate to   External Providers  and add a new \"Polar\" provider.   Enter Client ID and Client Secret : Copy these from your Polar Admin dashboard into the SparkyFitness form.   Authorize : Click \"Connect\" and you will be redirected to Polar to authorize the connection.  Data Synchronized  SparkyFitness pulls the following data from Polar:    Workouts (Exercises) : Automatically logs cardio training sessions into your Diary, including duration, calories burned, and sport type.   Physical Info : Syncs your latest   Weight  and   Height  from your Polar profile.   Daily Activity : Syncs your daily   Steps ,   Active Calories , and   Total Calories  as custom measurements.  Important Limitations    !IMPORTANT  Polar API Restrictions :    No Historical Backfill : Polar only allows access to data uploaded   after  you have authorized the SparkyFitness integration. Workouts recorded before you linked your account will not sync.   Manual Exercises : Manually added exercises in Polar Flow may have limited support or availability depending on the Polar API version.   Contributing Mock Data  We are constantly working to improve these integrations. If you notice data missing or incorrect, you can help by providing anonymized mock data.  Join the   CodeWithCJ  community on   Discord  and reach out if you'd like to share your Polar mock data to help us improve the sync logic!",{"id":242,"path":243,"dir":210,"title":244,"description":245,"keywords":246,"body":249},"content:2.features:7.settings:preferences.md","\u002Ffeatures\u002Fsettings\u002Fpreferences","Preferences","This page explains how to manage preference settings in SparkyFitness.",[247,248],"Autoscaling OpenFoodFacts","Complete Import Process","  Preferences  This page explains how to manage preference settings in   SparkyFitness .   Autoscaling OpenFoodFacts  The   Auto-scale OpenFoodFacts imports  option scales measurements and nutrition values from OpenFoodFacts to their   serving size .  This allows imports to be scaled automatically without manually entering a serving size, or when the serving size is unknown.   Comparison  Without Import Autoscaling (Default)   With Import Autoscaling    Complete Import Process  Using OpenFoodFacts Import Autoscaling  1. Add Food  Add food as normal via   “Online”  or   “Scan Barcode” .   Results are now based on the   serving size , rather than   100g    2. Edit and Add  It may still be useful to keep a   gram-based Unit Variant , especially for cases where weight-based measurements are needed.    Note:   “Auto-scale”  in the   Edit Food Details  dialog scales measurements   for that specific variant only .  \nThis is   not related  to OpenFoodFacts import scaling.  \nIt is a SparkyFitness feature that allows users to change serving sizes while automatically adjusting nutrition values.  A. Duplicate the gram measurement   B. Edit unit type and optionally set it as the default   C. Save the Food  Click   “Add Food”  or   “Update Food” .   3. Using the New Entry  A. Defaults to your Unit Variant (no more math!)   B. Referencing grams if needed  You can switch the unit back to   grams  and adjust the quantity accordingly. ",{"id":251,"path":252,"dir":151,"title":253,"description":254,"keywords":255,"body":256},"content:2.features:9.partner-sharing.md","\u002Ffeatures\u002Fpartner-sharing","Partner Sharing","This section will provide details on the partner sharing feature in SparkyFitness, allowing users to share their fitness journey with others. This feature is planned for future development.",[],"  Partner Sharing  This section will provide details on the partner sharing feature in SparkyFitness, allowing users to share their fitness journey with others. This feature is planned for future development.",{"id":258,"path":259,"dir":151,"title":260,"description":261,"keywords":262,"body":263},"content:2.features:10.searching.md","\u002Ffeatures\u002Fsearching","Searching","SparkyFitness provides robust searching capabilities to help you quickly find foods, exercises, and other data within the application. Details on how to effectively use the search features will be added in the future.",[],"  Searching  SparkyFitness provides robust searching capabilities to help you quickly find foods, exercises, and other data within the application. Details on how to effectively use the search features will be added in the future.",{"id":265,"path":266,"dir":151,"title":267,"description":268,"keywords":269,"body":270},"content:2.features:11.sharing.md","\u002Ffeatures\u002Fsharing","Sharing","SparkyFitness may offer various ways to share your fitness data, including exporting data or sharing with other applications. Details on these sharing functionalities will be added in the future.",[],"  Sharing  SparkyFitness may offer various ways to share your fitness data, including exporting data or sharing with other applications. Details on these sharing functionalities will be added in the future.",{"id":272,"path":273,"dir":151,"title":274,"description":275,"keywords":276,"body":277},"content:2.features:12.user-settings.md","\u002Ffeatures\u002Fuser-settings","User Settings","SparkyFitness provides comprehensive user settings to personalize your experience, manage preferences, and configure various aspects of the application. Details on available settings will be added in the future.",[],"  User Settings  SparkyFitness provides comprehensive user settings to personalize your experience, manage preferences, and configure various aspects of the application. Details on available settings will be added in the future.",{"id":279,"path":280,"dir":151,"title":281,"description":7,"keywords":282,"body":284},"content:2.features:13.ai-assistant.md","\u002Ffeatures\u002Fai-assistant","Ai Assistant",[283],"Sparky Buddy (AI Assistant)","  Sparky Buddy (AI Assistant)  Core AI Features    Food Recognition : Analyze food photos for automatic logging and nutrition extraction   Nutrition Analysis : Intelligent nutrition information extraction from text and images   Meal Suggestions : AI-powered meal recommendations and recipe generation   Question Answering : General nutrition and fitness guidance, personalized advice   Exercise Logging : Log exercises with duration, distance, and calorie estimates   Measurement Logging : Log standard and custom body measurements   Water Intake Logging : Track daily water consumption  Chat Interface    Image Upload : Send photos for food analysis   Text Input : Natural language food descriptions, questions, and commands   History : Persistent chat conversation history with session grouping   Metadata Storage : Stores structured data like food options, exercise suggestions within chat history   Settings : Direct access to AI service configuration  Food Integration    Auto-Logging : Directly add recognized foods to diary with confirmation   Nutrition Confirmation : Review and edit AI suggestions before logging   Meal Context : Understand meal timing and context for accurate logging   Brand Recognition : Identify specific food brands and products",{"id":286,"path":287,"dir":151,"title":288,"description":7,"keywords":289,"body":291},"content:2.features:14.measurements.md","\u002Ffeatures\u002Fmeasurements","Measurements",[290],"Measurements Tab","  Measurements Tab  Historical Data    Trend Charts : Interactive charts showing measurement trends over time   Date Range Selection : Custom time period analysis   Multiple Metrics : Compare different measurements on same chart   Goal Overlays : Show target measurements vs actual progress  Analytics    Progress Calculation : Automatic progress percentages   Milestone Tracking : Achievement notifications   Trend Analysis : Identify patterns and plateaus   Correlation Analysis : Relationship between different metrics",{"id":293,"path":294,"dir":151,"title":295,"description":296,"keywords":297,"body":302},"content:2.features:15.mcp-server.md","\u002Ffeatures\u002Fmcp-server","AI Assistant & MCP Server","SparkyFitness includes a powerful Model Context Protocol (MCP) server. This allows you to connect advanced AI assistants (like Claude Desktop, Cursor, or custom AI clients) directly to your personal health data securely.",[298,299,300,301],"🛠 Available Tools & Capabilities","🕵️ AI Personalization (The \"Health Detective\")","🔐 Security & Privacy","🚀 Getting Started","  AI Assistant & MCP Server  SparkyFitness includes a powerful   Model Context Protocol (MCP)  server. This allows you to connect advanced AI assistants (like Claude Desktop, Cursor, or custom AI clients) directly to your personal health data securely.  When you enable the MCP Server, your AI assistant transforms into a   Personal Health Intelligence  layer that can read your health logs, track your progress, and provide hyper-personalized coaching based on your actual data.   🛠 Available Tools & Capabilities  The AI assistant can perform the following actions across different health domains. All tools automatically respect your   Unit Preferences  (e.g., converting lbs to kg or kcal to kJ).  🥗 Nutrition & Food  Track your diet, manage meals, and analyze your nutritional intake.     Feature  Tool Action  Example Prompt     Log Food   log_food  \"I just had a 250g steak and a salad.\"    Meal Templates   log_meal  \"Log my 'Standard Breakfast' for today.\"    Water Tracking   log_water  \"I drank 500ml of water.\"    Daily Diary   list_diary  \"What have I eaten today?\"    Copy Entries   copy_from_yesterday  \"Copy my breakfast from yesterday to today.\"    Nutrition Analysis   get_nutritional_summary  \"Give me a breakdown of my macros for the last 7 days.\"  🏋️ Exercise & Fitness  Manage your workouts, track strength progress, and use presets.     Feature  Tool Action  Example Prompt     Log Workout   log_exercise  \"Log 3 sets of Bench Press at 80kg for 10 reps.\"    Workout Presets   log_workout_preset  \"Start my 'Leg Day' workout.\"    Exercise Details   get_exercise_details  \"How do I perform a Bulgarian Split Squat?\"    Progress Tracking   get_exercise_progress  \"Show me my Bench Press progress over the last month.\"    Search Library   search_exercises  \"Find some advanced chest exercises using dumbbells.\"  📈 Biometrics & Check-ins  Monitor your weight, sleep, mood, and daily habits.     Feature  Tool Action  Example Prompt     Daily Wizard   sparky_daily_checkin_wizard  \"I'm ready for my daily check-in.\"    Weight & Body   log_biometrics  \"My weight is 185 lbs today.\"    Sleep & Mood   log_sleep ,   log_mood  \"I slept 7 hours and feel like an 8\u002F10.\"    Fasting Status   get_fasting_status  \"Am I still in my fasting window?\"    Weight History   get_biometrics_history  \"Show me my weight trend for the last 30 days.\"    Custom Metrics   log_custom_metric  \"My blood pressure was 120\u002F80 today.\"  📋 Goals, Habits & Reports  Set targets and get consolidated performance reviews.    Habit Tracking  (  sparky_manage_habits ): \"Did I take my vitamins today?\"   Goal Management  (  sparky_manage_goals ): \"Set a new weight goal of 175 lbs by July.\"   Weekly Reports  (  sparky_get_report ): \"Give me a weekly performance summary.\"   Profile Settings  (  sparky_manage_profile ): \"Change my energy unit to kJ.\"   🕵️ AI Personalization (The \"Health Detective\")  Because the AI has access to all these tools, it can do things a standard app cannot:    Correlation Detection : \"I noticed your sleep quality is 20% better on days you finish your last meal before 7 PM.\"   Smart Planning : \"Based on your current weight trend and yesterday's activity, I recommend increasing your protein by 20g today.\"   Inventory Logic : \"You've logged Greek Yogurt 5 times this week. Should I add it to your high-protein shopping list?\"   🔐 Security & Privacy    Isolated Connection : The MCP server uses a dedicated application pool. It cannot perform admin-level database operations.   User Isolation (RLS) : The AI is physically restricted by PostgreSQL   Row Level Security . It can   only  see data belonging to the user authenticated by the API key.   Local First : If you run SparkyFitness locally, your data never leaves your infrastructure until you send it to your chosen AI provider (e.g., Anthropic or OpenAI).  🚀 Getting Started    Generate API Key : Go to your User Profile in SparkyFitness and generate a   Personal API Key .   Configure Client : Add the SparkyFitness MCP server to your AI client (Claude Desktop, Cursor, etc.).   Authentication : Pass your API key as a   Bearer Token  in the   Authorization  header.  Example Config (Claude Desktop)     {\n     \"mcpServers\"  : {\n       \"sparky-fitness\"  : {\n         \"serverURL\"  :   \"http:\u002F\u002Flocalhost:3001\u002Fmcp\"  ,\n         \"headers\"  : {\n           \"Authorization\"  :   \"Bearer YOUR_SPARKY_FITNESS_API_KEY\"\n         }\n       }\n     }\n   }\n   Note: If running via Docker, use the HTTP transport URL as described in the   Docker Compose Guide .  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":304,"path":305,"dir":7,"title":306,"description":307,"keywords":308,"body":309},"content:2.features:index.md","\u002Ffeatures","Features Overview","This section provides an overview of the key features available in SparkyFitness.",[],"  Features Overview  This section provides an overview of the key features available in SparkyFitness.",{"id":311,"path":312,"dir":313,"title":314,"description":315,"keywords":316,"body":319},"content:3.administration:1.oauth-authentication.md","\u002Fadministration\u002Foauth-authentication","administration","OAuth Authentication (OpenID Connect)","SparkyFitness supports OpenID Connect (OIDC) for user authentication, allowing integration with various identity providers. This guide outlines how to configure OIDC within your SparkyFitness instance.",[8,317,318,110],"Configuration Steps","OIDC Flow","  OAuth Authentication (OpenID Connect)  SparkyFitness supports OpenID Connect (OIDC) for user authentication, allowing integration with various identity providers. This guide outlines how to configure OIDC within your SparkyFitness instance.  Overview  SparkyFitness leverages the   openid-client  library to facilitate secure OIDC authentication. OIDC settings are stored in the database and can be managed via the application's administrative interface. You can configure multiple OIDC providers, allowing users to choose their preferred login method.  Configuration Steps  To set up OIDC authentication, you will need to configure the following settings, typically found in the administration section of your SparkyFitness application:    Issuer URL : The URL of your OIDC Identity Provider (IdP). This is where SparkyFitness will discover the IdP's configuration (e.g.,   https:\u002F\u002Faccounts.google.com ).   Client ID : The unique identifier for your SparkyFitness application registered with the OIDC IdP.   Client Secret : The secret key provided by your OIDC IdP for your SparkyFitness application. This should be kept confidential.   Scope : Set this to   openid profile email . While customization might be possible, it has not been tested to work properly.   Redirect URI : The URL where the OIDC IdP will redirect the user after authentication. You should take this URI directly from the administration interface in the app. It is highly recommended to use the default redirect URI suggested by the frontend. While customization might be possible, it has not been tested to work properly.   Auto-Register Users : (Optional) If enabled, new users who successfully authenticate via OIDC but do not have an existing SparkyFitness account will be automatically registered.   Enable Email\u002FPassword Login : (Optional) If OIDC is enabled, this setting determines whether traditional email\u002Fpassword login is still permitted.  Advanced Settings (Optional)  The application is tested with the default values for these settings. Customization is not tested and may not work properly.    Token Endpoint Auth Method : The method used to authenticate the SparkyFitness application with the OIDC token endpoint.   ID Token Signed Response Algorithm : The algorithm used to sign the ID Token (e.g.,   RS256 ,   ES256 ).   Userinfo Signed Response Algorithm : The algorithm used to sign the UserInfo response.   Request Timeout : The timeout in milliseconds for OIDC requests. The default is 3500ms. If you are on a slow network or your OIDC provider is slow to respond, you may need to increase this value.  OIDC Flow  When a user attempts to log in via OIDC:   SparkyFitness redirects the user to the configured OIDC Identity Provider.  The user authenticates with the IdP.  Upon successful authentication, the IdP redirects the user back to the SparkyFitness   oidc-callback  endpoint with an authorization code.  SparkyFitness exchanges the authorization code for an ID Token and Access Token with the IdP.  User information is extracted from the ID Token and\u002For UserInfo endpoint.  If auto-registration is enabled and the user is new, a new SparkyFitness account is created. Otherwise, the existing account is linked or the user is logged in.  Troubleshooting    Invalid Redirect URI : Ensure the Redirect URI configured in SparkyFitness exactly matches the one registered with your OIDC Identity Provider.   Incorrect Client ID\u002FSecret : Double-check that the Client ID and Client Secret are correct and match the values from your IdP.   Issuer URL Issues : Verify that the Issuer URL is correct and accessible from your SparkyFitness server.   Algorithm Mismatches : If you see errors related to \"invalid signature\" or \"algorithm mismatch,\" verify that the \"ID Token Signed Response Algorithm\" and \"Userinfo Signed Response Algorithm\" settings in SparkyFitness match the requirements of your OIDC provider.",{"id":321,"path":322,"dir":313,"title":323,"description":324,"keywords":325,"body":326},"content:3.administration:2.reverse-proxy.md","\u002Fadministration\u002Freverse-proxy","Reverse Proxy","This page will provide details on configuring a reverse proxy for SparkyFitness.",[],"  Reverse Proxy  This page will provide details on configuring a reverse proxy for SparkyFitness.  If using a proxy like Nginx Proxy Manager, ensure the following headers are configured:     proxy_set_header Host $host;\n   proxy_set_header X-Real-IP $remote_addr;\n   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n   proxy_set_header X-Forwarded-Proto $scheme;\n   add_header X-Content-Type-Options \"nosniff\";\n   proxy_set_header X-Forwarded-Ssl on;\n  This sample can be found under   sample  If you want to rely on docker networking instead, choose the scheme   http , enter the container name   sparkyfitness-frontend \nand port   80 .Note: In order for docker networking to work, the Nginx Proxy Manager network has to be connected to the   sparkyfitness-frontend  container. You can find the name of your networks using   docker network ls , find the container name using   docker container ls  and connect them using   docker network connect network container .  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":328,"path":329,"dir":313,"title":330,"description":331,"keywords":332,"body":335},"content:3.administration:3.manual_backup_restore.md","\u002Fadministration\u002Fmanual_backup_restore","Manual Backup and Restore for SparkyFitness","This document provides instructions for performing manual backup and restore operations for SparkyFitness, primarily for disaster recovery scenarios where the in-app restore might not be feasible.",[333,334],"1. Manual Backup","2. Manual Restore (Disaster Recovery)","  Manual Backup and Restore for SparkyFitness  This document provides instructions for performing manual backup and restore operations for SparkyFitness, primarily for disaster recovery scenarios where the in-app restore might not be feasible.  1. Manual Backup  While the application provides scheduled backups, you can manually trigger a backup if needed. The in-app backup process creates a combined archive containing the PostgreSQL database dump and the   uploads  directory.   Important Note:  This backup functionality is new and should be used with caution. While it creates a backup, it's highly recommended to create additional backups independently of this application. Always follow the 3-2-1 backup strategy (3 copies of your data, on 2 different media, with 1 copy offsite) to ensure data safety. The functionality of restore may not work properly in all scenarios, so do not rely solely on this in-app backup.   Location of Backups: \nAll backup files are stored in a Docker volume mounted to the   SparkyFitnessServer  service. The default path within the container is   \u002Fapp\u002FSparkyFitnessServer\u002Fbackup . You will need to access this volume from your Docker host.  2. Manual Restore (Disaster Recovery)  This process is for situations where the SparkyFitness application or its Docker containers are not functioning correctly, or if you need to restore to a completely new environment.   WARNING:  This process will   permanently delete all existing data  in your PostgreSQL database and   uploads  directory before restoring from the backup. Ensure you have chosen the correct backup file.  Prerequisites:   Access to your Docker host machine.  The   docker-compose.yml  file used to deploy SparkyFitness.  The full backup archive (  sparkyfitness_full_backup_YYYYMMDD_HHMMSS.tar.gz ) you wish to restore.   docker  and   docker-compose  (or   docker compose ) installed on your host.   psql  and   tar  utilities available on your host or within a temporary container.  Steps:    Stop SparkyFitness Services: \nNavigate to the directory containing your   docker-compose.yml  file and stop the SparkyFitness services.     docker   compose   down\n   Identify and Access the Backup Volume: \nFind the Docker volume associated with the   SparkyFitnessServer 's backup directory. You can inspect your   docker-compose.yml  for volume definitions or use   docker volume ls  and   docker volume inspect \u003Cvolume_name> .\nThe volume will likely be mounted to a path like   \u002Fvar\u002Flib\u002Fdocker\u002Fvolumes\u002F\u003Cvolume_name>\u002F_data  on Linux hosts.  Let's assume your backup volume is named   sparkyfitness_server_backup_data  and it's mounted to   \u002Fvar\u002Flib\u002Fdocker\u002Fvolumes\u002Fsparkyfitness_server_backup_data\u002F_data .   Prepare the Backup File: \nCopy your chosen   sparkyfitness_full_backup_YYYYMMDD_HHMMSS.tar.gz  file into the backup volume's data directory on your host.     cp   \u002Fpath\u002Fto\u002Fyour\u002Fbackup\u002Fsparkyfitness_full_backup_YYYYMMDD_HHMMSS.tar.gz   \u002Fvar\u002Flib\u002Fdocker\u002Fvolumes\u002Fsparkyfitness_server_backup_data\u002F_data\u002F\n  Replace   \u002Fpath\u002Fto\u002Fyour\u002Fbackup\u002F  with the actual path to your backup file.   Extract the Backup Archive: \nYou'll need to extract the combined archive to get the database dump and uploads archive. You can do this directly on the host if   tar  is available, or use a temporary Docker container.   Option A: Using host   tar  (if available):     cd   \u002Fvar\u002Flib\u002Fdocker\u002Fvolumes\u002Fsparkyfitness_server_backup_data\u002F_data\u002F\n   tar   -xzf   sparkyfitness_full_backup_YYYYMMDD_HHMMSS.tar.gz\n   Option B: Using a temporary Docker container:     docker   run   --rm   -v   sparkyfitness_server_backup_data:\u002Fbackup_volume   ubuntu:latest   tar   -xzf   \u002Fbackup_volume\u002Fsparkyfitness_full_backup_YYYYMMDD_HHMMSS.tar.gz   -C   \u002Fbackup_volume\n  This will extract   sparkyfitness_db_backup_YYYYMMDD_HHMMSS.sql.gz  and   sparkyfitness_uploads_backup_YYYYMMDD_HHMMSS.tar.gz  into the backup volume.   Clear Existing Database and Uploads Data:  This step is destructive.  Ensure you have stopped the services and are confident in your backup.    Clear   uploads  directory: \nIdentify the Docker volume for your   SparkyFitnessServer 's   uploads  directory (e.g.,   sparkyfitness_server_uploads_data ).     # Example: Assuming uploads volume is sparkyfitness_server_uploads_data\n   docker   run   --rm   -v   sparkyfitness_server_uploads_data:\u002Fuploads_volume   ubuntu:latest   rm   -rf   \u002Fuploads_volume\u002F  *\n   Clear PostgreSQL Database: \nYou need to drop and recreate the database. You can use a temporary PostgreSQL client container.\nFirst, get the database connection details from your   docker-compose.yml  or   .env  file (DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME).     # Example: Replace with your actual DB details\n   DB_HOST  =  \"sparkyfitness-db\"   # Or localhost if connecting directly to host DB\n   DB_PORT  =  \"5432\"\n   DB_USER  =  \"sparkyfitness\"\n   DB_PASSWORD  =  \"your_db_password\"\n   DB_NAME  =  \"sparkyfitness\"\n   \n   # Drop database\n   docker   run   --rm   -e   PGPASSWORD=  ${DB_PASSWORD}   postgres:latest   dropdb   -h   ${DB_HOST}   -p   ${DB_PORT}   -U   ${DB_USER} ${DB_NAME}\n   \n   # Create database\n   docker   run   --rm   -e   PGPASSWORD=  ${DB_PASSWORD}   postgres:latest   createdb   -h   ${DB_HOST}   -p   ${DB_PORT}   -U   ${DB_USER} ${DB_NAME}\n   Note: If your   sparkyfitness-db  container is not running, you might need to start it temporarily or adjust   DB_HOST  to   localhost  if PostgreSQL is directly accessible on the host.   Restore Database from Dump: \nUse the   psql  command to restore the database from the extracted   .sql.gz  file.     # Example: Replace with your actual DB details and backup file name\n   DB_HOST  =  \"sparkyfitness-db\"\n   DB_PORT  =  \"5432\"\n   DB_USER  =  \"sparkyfitness\"\n   DB_PASSWORD  =  \"your_db_password\"\n   DB_NAME  =  \"sparkyfitness\"\n   DB_DUMP_FILE  =  \"\u002Fvar\u002Flib\u002Fdocker\u002Fvolumes\u002Fsparkyfitness_server_backup_data\u002F_data\u002Fsparkyfitness_db_backup_YYYYMMDD_HHMMSS.sql.gz\"\n   \n   gunzip   -c   ${DB_DUMP_FILE}   |   docker   run   --rm   -i   -e   PGPASSWORD=  ${DB_PASSWORD}   postgres:latest   psql   -h   ${DB_HOST}   -p   ${DB_PORT}   -U   ${DB_USER}   -d   ${DB_NAME}\n   Restore Uploads Directory: \nExtract the   uploads  tar archive into the   SparkyFitnessServer 's   uploads  volume.     # Example: Assuming uploads volume is sparkyfitness_server_uploads_data\n   UPLOADS_TAR_FILE  =  \"\u002Fvar\u002Flib\u002Fdocker\u002Fvolumes\u002Fsparkyfitness_server_backup_data\u002F_data\u002Fsparkyfitness_uploads_backup_YYYYMMDD_HHMMSS.tar.gz\"\n   \n   docker   run   --rm   -v   sparkyfitness_server_uploads_data:\u002Fuploads_volume   ubuntu:latest   tar   -xzf   ${UPLOADS_TAR_FILE}   -C   \u002Fuploads_volume\n   Clean Up Temporary Files: \nRemove the extracted database dump and uploads tar files from your backup volume.     cd   \u002Fvar\u002Flib\u002Fdocker\u002Fvolumes\u002Fsparkyfitness_server_backup_data\u002F_data\u002F\n   rm   sparkyfitness_db_backup_YYYYMMDD_HHMMSS.sql.gz\n   rm   sparkyfitness_uploads_backup_YYYYMMDD_HHMMSS.tar.gz\n   rm   sparkyfitness_full_backup_YYYYMMDD_HHMMSS.tar.gz\n   Start SparkyFitness Services:     docker   compose   up   -d\n  Your SparkyFitness instance should now be restored to the state of your chosen backup.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":337,"path":338,"dir":339,"title":340,"description":341,"keywords":342,"body":346},"content:4.mobile-app:1.mobile-app.md","\u002Fmobile-app\u002Fmobile-app","mobile-app","Mobile App","The Mobile App is available for both iOS and Android devices. It allows you to sync your data from Apple Health or Android Health Connect. It also provides a convenient way to access Sparky Fitness on the go.\nMobile App requires HTTPS, though support for self-signed certificate is added, not activetely tested for every release.",[343,344,345],"iOS","Android","Screenshot (iOS)","  Mobile App  The Mobile App is available for both iOS and Android devices. It allows you to sync your data from Apple Health or Android Health Connect. It also provides a convenient way to access Sparky Fitness on the go.\n  Mobile App requires HTTPS , though support for self-signed certificate is added, not activetely tested for every release.  iOS  The iOS version of the Sparky Fitness app is available on the App Store.   Get it here  Testflight  Join the Testflight beta program to get early access to new features and updates:   Join Testflight  Android  Install APK  You can download the latest APK from our   GitHub releases page . Look for the latest release and download the   SparkyFitnessMobile.apk  file. Then transfer it to your android device for installation.  Google Play Beta  The Android version is available as a google play store beta. You can join the beta program to get early access to new features and updates:   First, join the   Google Play beta group  Then you will have access to closed testing and can   download the beta here  Screenshot (iOS)  ",{"id":348,"path":349,"dir":339,"title":350,"description":351,"keywords":352,"body":354},"content:4.mobile-app:2.proxy-setup.md","\u002Fmobile-app\u002Fproxy-setup","Proxy Tunnel Setup","If you use a proxy tunnel such as Cloudflare or Pangolin, you will need to configure the app to send a special header.",[353],"Pangolin","  Proxy Tunnel Setup  If you use a proxy tunnel such as Cloudflare or Pangolin, you will need to configure the app to send a special header.  Pangolin   Open your Pangolin dashboard click \"Links\" in the sidebar  Click Create Share Link  Choose your resource, enter a title, and an expiration date. Click Create Link  Underneath the QR code, click \"Usage Examples\" to see how your token will be sent as a header. Copy this down.     In the Sparky Fitness app, navigate to the settings screen  Click on your server to edit it or add a new server.  Enter in the header information that you copied from the Pangolin dashboard. You may need to click the + button to add another field.  ",{"id":356,"path":357,"dir":339,"title":110,"description":7,"keywords":358,"body":360},"content:4.mobile-app:3.troubleshooting.md","\u002Fmobile-app\u002Ftroubleshooting",[359],"Getting a Diagnostic Report","  Troubleshooting  Getting a Diagnostic Report  If you encounter issues with SparkyFitness, you can generate a diagnostic report to help identify the problem. This report includes logs, configuration details, and system information. No personal data is included, that includes all health, food and exercise related data.  You can find the Diagnostic Report tool on the settings screen by scrolling all the way to the bottom. You will be able to save the report or you can share it directly with the developers on Discord or in a GitHub issue.  ",{"id":362,"path":363,"dir":7,"title":364,"description":365,"keywords":366,"body":368},"content:5.community-guides.md","\u002Fcommunity-guides","Community Guides","This section highlights community-contributed guides and resources for SparkyFitness. These guides are created by users like you to share knowledge, tips, and best practices.",[367],"How to Contribute or Find Guides","  Community Guides  This section highlights community-contributed guides and resources for SparkyFitness. These guides are created by users like you to share knowledge, tips, and best practices.  How to Contribute or Find Guides  If you have a guide you'd like to share, or if you're looking for specific community-driven content, here's how you can engage:    Share your knowledge : Write a guide and share it with the community. You can submit it as a pull request to the documentation repository.   Join our Discord : Engage with other community members, ask questions, and find answers in our Discord server. Many community guides and tips are shared there informally.   GitHub Discussions : Check the GitHub Discussions for ongoing conversations, shared solutions, and requests for new guides.   Contribute to the documentation : If you see a gap in the documentation or have a guide that would benefit others, consider contributing directly to this documentation site.",{"id":370,"path":371,"dir":7,"title":372,"description":373,"keywords":374,"body":377},"content:6.faq.md","\u002Ffaq","Frequently Asked Questions (FAQ)","This section provides answers to common questions about SparkyFitness.",[375,376,110,15],"General Questions","Technical Questions","  Frequently Asked Questions (FAQ)  This section provides answers to common questions about SparkyFitness.  General Questions    What is SparkyFitness? \nSparkyFitness is a comprehensive fitness tracking and management application designed to help users monitor their nutrition, exercise, and body measurements. It provides tools for daily progress tracking, goal setting, and insightful reports to support a healthy lifestyle.   Is SparkyFitness free? \nSparkyFitness is open-source software. Please check the project's GitHub repository for licensing details.  Technical Questions    How do I install SparkyFitness? \nPlease refer to the   Installation Guide  for detailed instructions on how to install SparkyFitness using various methods.   What are the system requirements? \nSystem requirements vary depending on your chosen installation method (Docker, local development, etc.). Generally, you will need Docker, Node.js, and PostgreSQL. Refer to the   Installation Guide  for specifics.  Troubleshooting    \"Invalid key length\" error during setup \nThis error typically indicates that your   SPARKY_FITNESS_API_ENCRYPTION_KEY  in your   .env  file is not correctly configured. Ensure it is a 64-character hexadecimal string, as mentioned in the example   .env  file and installation guides. You can generate a valid key using   openssl rand -hex 32  or   node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\" .  Getting Help  If you can't find the answer to your question here, please consider:    Joining our Discord community : A great place to ask questions and get help from other users and developers.   Checking GitHub Discussions : Look for existing discussions or start a new one to get support.   Reporting an issue : If you believe you've found a bug, please report it on our   GitHub Issues page .",{"id":379,"path":380,"dir":7,"title":381,"description":382,"keywords":383,"body":387},"content:7.help-me.md","\u002Fhelp-me","Help Me!","This page provides resources and guidance for getting help with SparkyFitness.",[384,385,386],"Community Support","Reporting Issues","Documentation","  Help Me!  This page provides resources and guidance for getting help with SparkyFitness.  Community Support    Discord Community : Join our vibrant Discord community to connect with other users and developers. It's a great place to ask questions, share tips, and get real-time support.    Join our Discord server   GitHub Discussions : For more in-depth questions, feature requests, or to share your ideas, visit our GitHub Discussions forum.    Go to GitHub Discussions  Reporting Issues  If you encounter a bug, unexpected behavior, or have a technical problem, please report it on our GitHub Issues page. Providing detailed information helps us resolve issues faster.    Report a Bug or Issue  Documentation    Search the Documentation : Use the search bar at the top of this documentation site to find answers to your questions.   Browse Sections : Explore the various sections of this documentation for detailed guides and overviews.  Your contributions and feedback are highly valued and help improve SparkyFitness for everyone.",{"id":389,"path":390,"dir":391,"title":392,"description":393,"keywords":394,"body":404},"content:8.developer:1.getting-started.md","\u002Fdeveloper\u002Fgetting-started","developer","Getting Started","SparkyFitness is a comprehensive fitness tracking application built with React 18 + TypeScript + Vite frontend and Node.js\u002FExpress backend, using PostgreSQL with Row Level Security.",[25,395,396,397,398,79,399,400,401,402,403],"Quick Start (Docker Recommended)","Docker Helper Script","Environment Setup","Local Development (without Docker)","Manual Docker Compose","Configuration Files","Code Quality","Next Steps","Common Issues","  Getting Started  SparkyFitness is a comprehensive fitness tracking application built with React 18 + TypeScript + Vite frontend and Node.js\u002FExpress backend, using PostgreSQL with Row Level Security.  Prerequisites  Before you begin, ensure you have the following installed:  For Docker Deployment (Recommended)    Docker & Docker Compose : Essential for running SparkyFitness in containerized environments.   Git : For cloning the SparkyFitness repository.  For Local Development (without Docker)    Node.js 18+  and   npm : The JavaScript runtime and package manager.   PostgreSQL 15+ : The database server.   Git : For version control.  Quick Start (Docker Recommended)  The fastest way to get SparkyFitness running is using our Docker helper script:     # Clone the repository\n   git   clone   https:\u002F\u002Fgithub.com\u002FCodeWithCJ\u002FSparkyFitness.git\n   cd   SparkyFitness\n   \n   # Copy environment template\n   cp   docker\u002F.env.example   .env\n   \n   # Start development environment (with live reloading)\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   up\n   \n   # Access the application at http:\u002F\u002Flocalhost:8080\n  Docker Helper Script  The Docker helper script provides an easy interface for managing your development and production environments:     # Show all available commands and help\n   .\u002Fdocker\u002Fdocker-helper.sh   help\n   \n   # Start development environment\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   up\n   \n   # Start production environment  \n   .\u002Fdocker\u002Fdocker-helper.sh   prod   up\n   \n   # View logs\n   .\u002Fdocker\u002Fdocker-helper.sh   logs\n   \n   # Stop services\n   .\u002Fdocker\u002Fdocker-helper.sh   down\n   \n   # Clean up everything\n   .\u002Fdocker\u002Fdocker-helper.sh   clean\n  Available Commands    dev up  - Start development environment with live reloading   prod up  - Start production environment with optimized builds   down  - Stop all services   logs [service]  - View logs for all services or specific service   clean  - Remove all containers, networks, and volumes   build  - Rebuild all images   restart [service]  - Restart all services or specific service  Environment Setup  Development Environment  Perfect for active development with live reloading:     # Start development stack\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   up\n   \n   # Services available:\n   # - Frontend: http:\u002F\u002Flocalhost:8080 (live reload)\n   # - Backend: http:\u002F\u002Flocalhost:3010 (direct access)\n   # - Database: localhost:5432 (direct access)\n  Development Features    Live Reloading : Both frontend and backend automatically reload on file changes   Volume Mounts : Your local code is mounted into containers for instant updates   Direct Database Access : Connect directly to PostgreSQL for debugging   Development Dependencies : All dev tools and debugging capabilities enabled  Production Environment  Optimized builds for deployment testing:     # Start production stack\n   .\u002Fdocker\u002Fdocker-helper.sh   prod   up\n   \n   # Service available:\n   # - Application: http:\u002F\u002Flocalhost:3004 (nginx proxy)\n  Production Features    Optimized Builds : Minified frontend and production-ready backend   Nginx Proxy : Single entry point with load balancing and static file serving   Environment Isolation : Separate network and security configurations   DockerHub Images : Uses pre-built images for faster deployment  Local Development (without Docker)  If you prefer to run the application locally without Docker:  Database Setup    Install PostgreSQL 15+   Create database :\n     CREATE DATABASE sparkyfitness;\n   CREATE USER sparky WITH PASSWORD 'your_password';\n   GRANT ALL PRIVILEGES ON DATABASE sparkyfitness TO sparky;\n  Backend Setup     # Navigate to server directory\n   cd   SparkyFitnessServer\n   \n   # Install dependencies\n   npm   install\n   \n   # Copy and configure environment\n   cp   .env.example   .env\n   # Edit .env with your database credentials\n   \n   # Run database migrations\n   npm   run   migrate\n   \n   # Start development server\n   npm   run   dev\n  Frontend Setup     # Navigate to project root\n   cd   ..\n   \n   # Install dependencies\n   npm   install\n   \n   # Start development server\n   npm   run   dev\n  Environment Variables  Copy the environment template and configure according to your setup:     cp   docker\u002F.env.example   .env\n  Key variables to configure:  Database Configuration    DATABASE_URL  - PostgreSQL connection string   DB_HOST ,   DB_PORT ,   DB_NAME ,   DB_USER ,   DB_PASSWORD  - Individual database settings  Application Settings    PORT  - Backend server port (default: 3010)   NODE_ENV  - Environment mode (development\u002Fproduction)   JWT_SECRET  - Secret key for JWT token signing  Frontend Configuration    SPARKY_FITNESS_SERVER_HOST  - Backend service connection   SPARKY_FITNESS_SERVER_PORT  - Backend service port  AI Integration    OPENAI_API_KEY  - OpenAI API key for AI features   GOOGLE_AI_API_KEY  - Google Gemini API key   ANTHROPIC_API_KEY  - Anthropic Claude API key  Manual Docker Compose  If you prefer to use Docker Compose directly:     # Production deployment\n   docker-compose   -f   docker\u002Fdocker-compose.prod.yml   up   -d\n   \n   # Development with live reloading\n   docker-compose   -f   docker\u002Fdocker-compose.dev.yml   up\n   \n   # Stop services\n   docker-compose   down\n   \n   # View logs\n   docker-compose   logs   -f   [service_name]\n  Configuration Files  The Docker setup includes several configuration files:  Dockerfiles    Dockerfile.frontend  - Multi-stage frontend build   Dockerfile.backend  - Backend Node.js application   docker\u002Fnginx.conf.template  - Nginx configuration template  Compose Files    docker-compose.dev.yml  - Development environment   docker-compose.prod.yml  - Production environment  Configuration    docker\u002F.env.example  - Environment variables template   docker\u002Fdocker-entrypoint.sh  - Environment variable substitution script   docker\u002Fdocker-helper.sh  - Management script with validation  Code Quality  To maintain code consistency and prevent errors, it's crucial to adhere to the project's code quality standards. Before committing any changes, ensure that your code passes the linting and formatting checks for the frontend.    Linting : Run   npm run lint  in the   SparkyFitnessFrontend  directory to check for potential errors and enforce coding style.   Formatting : Run   npx prettier . --check  in the   SparkyFitnessFrontend  directory to verify consistent code formatting. If you need to fix formatting issues, use   npm run format .  Next Steps  Once you have the application running:    Explore the Application : Visit   http:\u002F\u002Flocalhost:8080  (dev) or   http:\u002F\u002Flocalhost:3004  (prod)   Create an Account : Register a new user account   Check the API : Backend API is available at   http:\u002F\u002Flocalhost:3010\u002Fapi  (dev only)   Review the Architecture : See our   Architecture Guide   Start Contributing : Check out our   Contributing Guide  Common Issues  Port Conflicts  If you encounter port conflicts, check what's using the required ports:     # Check port usage\n   lsof   -i   :8080    # Frontend\n   lsof   -i   :3010    # Backend  \n   lsof   -i   :5432    # Database\n  Database Connection Issues  Ensure PostgreSQL is running and credentials are correct in your   .env  file.  Permission Issues  Make sure Docker has proper permissions and your user is in the   docker  group:     sudo   usermod   -aG   docker   $USER\n   # Log out and back in\n  For more detailed troubleshooting, see our   Troubleshooting Guide .  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":406,"path":407,"dir":391,"title":13,"description":408,"keywords":409,"body":419},"content:8.developer:2.architecture.md","\u002Fdeveloper\u002Farchitecture","SparkyFitness is built with a modern, full-stack architecture designed for scalability, maintainability, and performance.",[410,411,412,413,414,415,416,417,418],"High-Level Overview","Technology Stack","Directory Structure","Key Directories Explained","Core Application Features","Security Architecture","Performance Considerations","Deployment Architecture","Integration Points","  Architecture  SparkyFitness is built with a modern, full-stack architecture designed for scalability, maintainability, and performance.  High-Level Overview  The application follows a client-server model, with a clear separation of concerns between the frontend, backend, and database.   ┌─────────────────────────────────────────────────────────────────┐\n│                     SparkyFitness Architecture                  │\n└─────────────────────────────────────────────────────────────────┘\n\n                              User\n                               │\n                               ▼\n                    ┌─────────────────────┐\n                    │   React Frontend    │\n                    │  (Vite + TypeScript)│\n                    └──────────┬──────────┘\n                               │ HTTP\u002FAPI\n                               ▼\n                    ┌─────────────────────┐\n                    │ Node.js\u002FExpress API │\n                    │     (Backend)       │\n                    └──────────┬──────────┘\n                               │\n              ┌────────────────┼────────────────┐\n              │                │                │\n              ▼                ▼                ▼\n    ┌─────────────────┐ ┌─────────────┐ ┌─────────────────┐\n    │  PostgreSQL     │ │ AI Services │ │  External APIs  │\n    │   Database      │ │             │ │                 │\n    │   (with RLS)    │ │ • OpenAI    │ │ • Nutritionix   │\n    └─────────────────┘ │ • Google    │ │ • OpenFoodFacts │\n                        │ • Anthropic │ │ • FatSecret     │\n                        └─────────────┘ │ • Wger          │\n                                        └─────────────────┘\n  Technology Stack  Frontend (src\u002F)    Framework : React 18 with TypeScript   Build Tool : Vite for fast development and optimized builds   UI Components : shadcn\u002Fui built on Tailwind CSS   State Management & Data Fetching : React Context for global state, and TanStack Query for server state management (with hooks in   src\u002Fhooks\u002F  and API functions\u002Fkeys in   src\u002Fapi\u002F ).   Routing : React Router v6   HTTP Client : Fetch API (utilized by TanStack Query)  Backend (SparkyFitnessServer\u002F)    Runtime : Node.js with Express.js framework   Database : PostgreSQL with Row Level Security (RLS)   Authentication : JWT-based authentication   Architecture Pattern : Repository pattern for data access   AI Integration : Multi-provider support (OpenAI, Anthropic, Google, etc.)   External Integrations : Food providers, Exercise data, Health data  Database    Primary Database : PostgreSQL 15+   Security : Row Level Security (RLS) for data isolation   Schema Management : Migration-based schema updates   Connection : Connection pooling with transaction management  Directory Structure  Root Directory (  SparkyFitness\u002F )   SparkyFitness\u002F\n├── src\u002F                          # Frontend React application\n│   ├── components\u002F               # Reusable UI components\n│   ├── contexts\u002F                 # React Context providers\n│   ├── hooks\u002F                    # Custom React hooks\n│   ├── pages\u002F                    # Page-level components\n│   ├── services\u002F                 # API service layer\n│   └── utils\u002F                    # Shared utilities\n├── SparkyFitnessServer\u002F          # Backend Node.js application\n│   ├── models\u002F                   # Repository pattern (database layer)\n│   ├── routes\u002F                   # Express route handlers\n│   ├── integrations\u002F             # External API integrations\n│   ├── ai\u002F                       # AI provider configurations\n│   ├── middleware\u002F               # Express middleware\n│   └── utils\u002F                    # Backend utilities\n├── docker\u002F                       # Docker configuration files\n└── docs\u002F                         # Documentation site (Nuxt Content)\n  Key Directories Explained   src\u002F  (Frontend)  The frontend follows a component-based architecture with clear separation of concerns:     components\u002F : Reusable UI components built with shadcn\u002Fui    contexts\u002F : React Context providers for global state (user preferences, auth, etc.)    hooks\u002F : Custom hooks for data fetching, local storage, and business logic    layouts\u002F : Reusable page structures and layout components    pages\u002F : Top-level page components that compose smaller components    services\u002F : API integration layer with type-safe interfaces    utils\u002F : Shared utility functions and constants   SparkyFitnessServer\u002F  (Backend)  The backend implements a layered architecture with repository pattern:     models\u002F : Repository pattern implementations for data access    routes\u002F : Express route handlers organized by feature    integrations\u002F : External service integrations (food providers, AI services)    middleware\u002F : Express middleware for authentication, logging, error handling    ai\u002F : AI provider configurations and routing logic    utils\u002F : Backend utilities including database migrations   docker\u002F  Contains all Docker-related configuration:    Docker Compose files : Separate configurations for development and production   Dockerfiles : Multi-stage builds for frontend and backend   Configuration templates : Nginx configuration with environment variable substitution   Helper scripts : Management scripts for easy Docker operations   docs\u002F  Documentation site built with Nuxt Content and Docus theme:    Content-driven : All documentation in Markdown with frontmatter   Auto-generated navigation : Based on file structure and numbering   Live editing : Supports Nuxt Studio for visual editing  Frontend Data Management with TanStack Query  For new developers, understanding data fetching and state management in the frontend is crucial. SparkyFitness leverages   TanStack Query  (formerly React Query) for managing server state, which can be a new concept if you're used to simpler global state management solutions.   What is TanStack Query? \nTanStack Query is a powerful library for managing, caching, and synchronizing server state in your React applications. It handles the complexities of data fetching, including caching, background updates, stale-while-revalidate logic, retries, and error handling, allowing you to focus on your UI.   Why do we use it?    Simplified Data Fetching : Reduces boilerplate for data fetching logic.   Performance : Aggressive caching and background refetching make the UI feel faster and more responsive.   Robustness : Built-in retry mechanisms, error handling, and data synchronization ensure a stable user experience.   Developer Experience : Provides powerful hooks (  useQuery ,   useMutation ) that integrate seamlessly with React components, abstracting away complex asynchronous logic.   Core Concepts:    Queries (  useQuery ) : Used for fetching data (GET requests). They are associated with unique   Query Keys  (e.g.,   ['todos', todoId] ) which TanStack Query uses for caching and invalidation.   Mutations (  useMutation ) : Used for creating, updating, or deleting data on the server (POST, PUT, DELETE requests). Mutations often invalidate relevant queries to ensure the UI reflects the latest server data.   Query Keys : Arrays used to uniquely identify queries. They are fundamental for TanStack Query's caching and data synchronization mechanisms.   Integration in SparkyFitness:    API Functions : Located in   src\u002Fapi\u002F . These functions define how data is fetched or mutated from the backend. They typically return promises.   Query Keys : Also defined in   src\u002Fapi\u002F  alongside their respective API functions, ensuring consistency.   Custom Hooks : You'll find   useQuery  and   useMutation  implementations wrapped in custom hooks within   src\u002Fhooks\u002F . These custom hooks abstract the TanStack Query logic, providing a clean interface for components to consume data or trigger server-side changes.   Example (Conceptual): \nInstead of:     \u002F\u002F Component.tsx\n   useEffect  (()   =>   {\n     const   fetchData   =   async   ()   =>   {\n       const   response   =   await   fetch  (  '\u002Fapi\u002Fusers'  );\n       const   data   =   await   response.  json  ();\n       \u002F\u002F ... set state\n     };\n     fetchData  ();\n   }, []);\n  You'll typically use:     \u002F\u002F src\u002Fapi\u002FuserApi.ts\n   import   { api }   from   '@\u002Fservices\u002Fapi'  ;\n   \n   const   userKeys   =   {\n     all: [  'users'  ]   as   const  ,\n     details  : (  id  :   string  )   =>   [  ...  userKeys.all, id]   as   const  ,\n   };\n   \n   const   getUsers   =   ()   =>   {\n     return   api.  get  (  '\u002Fusers'  );\n   };\n   \n   \u002F\u002F src\u002Fhooks\u002FuseUsers.ts\n   import   { useQuery }   from   '@tanstack\u002Freact-query'  ;\n   import   { userKeys, getUsers }   from   '@\u002Fapi\u002FuserApi'  ;\n   \n   export   const   useUsers   =   ()   =>   {\n     return   useQuery  ({\n       queryKey: userKeys.all,\n       queryFn: getUsers,\n     });\n   };\n   \n   \u002F\u002F Component.tsx\n   import   { useUsers }   from   '@\u002Fhooks\u002FuseUsers'  ;\n   \n   const   UserList   =   ()   =>   {\n     const   {   data  :   users  ,   isLoading  ,   isError   }   =   useUsers  ();\n   \n     if   (isLoading)   return   \u003C  div  >Loading users  ...\u003C\u002F  div  >  ;\n     if   (isError)   return   \u003C  div  >Error fetching users  \u003C\u002F  div  >  ;\n   \n     return   (\n       \u002F\u002F ... render users\n     );\n   };\n  This structured approach helps manage data flow efficiently and predictably throughout the application.  Core Application Features  User Authentication & Access Control    Individual Users : Full access to their own data   Family Sharing : Granular permission system for family members   Row Level Security : Database-enforced data isolation   JWT Authentication : Secure token-based authentication  Data Management Architecture    Repository Pattern : All database operations use repository pattern   Transaction Management : Multi-table operations wrapped in transactions   External Provider Integration : Modular system for food, exercise, and health data   Audit Fields :   created_at ,   updated_at  on all tables  AI Integration Architecture  Multi-provider AI system supporting various use cases:                              AI Integration Flow\n         \nUser ──► Chat Interface ──► AI Router ──┬──► OpenAI GPT\n                                        ├──► Google Gemini  \n                                        └──► Anthropic Claude\n                                              │\n                                              ▼\n                                          Database\n                                              │\n                                    ┌─────────┼─────────┐\n                                    ▼         ▼         ▼\n                              Food Diary  Measurements  Goals &\n                                                       Progress\n  AI Capabilities:    Food Logging : Natural language food entry and nutrition analysis   Image Analysis : Photo-based food recognition and logging   Progress Tracking : Intelligent progress analysis and recommendations   Goal Management : AI-assisted goal setting and tracking   Measurement Logging : Conversational body measurement entry  External Integrations  Food Providers    OpenFoodFacts : Open food database with extensive product information   Nutritionix : Commercial nutrition database with restaurant chains   FatSecret : Food database with recipe and meal planning features  Exercise Data    Wger : Open exercise database with detailed exercise information   Custom Exercise Library : User-created and community exercises  Health Data    Apple Health : Integration for importing health and fitness data   Manual Entry : Direct input for measurements and health metrics  Security Architecture  Database Security    Row Level Security (RLS) : PostgreSQL RLS policies ensure users only access their data   Encrypted Connections : All database connections use SSL\u002FTLS   API Key Encryption : All external API keys encrypted at rest  Application Security    JWT Tokens : Secure authentication with configurable expiration   Input Validation : Comprehensive input validation and sanitization   Rate Limiting : API rate limiting to prevent abuse   CORS Configuration : Properly configured CORS for frontend access  Performance Considerations  Frontend Optimization    Code Splitting : Route-based code splitting with React.lazy   State Optimization : TanStack Query for server state caching   Component Optimization : Memoization and efficient re-rendering   Bundle Optimization : Vite's optimized production builds  Backend Optimization    Connection Pooling : PostgreSQL connection pooling   Query Optimization : Efficient database queries with proper indexing   Caching Strategy : Response caching for external API calls   Error Handling : Comprehensive error handling and logging  Database Optimization    Indexing Strategy : Proper indexing on frequently queried columns   Query Performance : Optimized queries with explain plans   Transaction Efficiency : Minimal transaction scope and duration  Deployment Architecture  Docker-based Deployment    Multi-stage Builds : Optimized Docker images with minimal size   Environment Separation : Clear separation between development and production   Service Orchestration : Docker Compose for service coordination   Health Checks : Container health monitoring and automatic restarts  Production Considerations    Reverse Proxy : Nginx for load balancing and static file serving   SSL Termination : SSL\u002FTLS termination at the proxy level   Environment Variables : Secure configuration management   Logging Strategy : Centralized logging with structured log formats  Integration Points  Frontend-Backend Communication    RESTful API : Clean REST API design with consistent response formats   Type Safety : Shared TypeScript types between frontend and backend   Error Handling : Standardized error response format   Authentication : JWT token-based authentication with automatic refresh  Database Integration    Migration System : Automated database migrations on startup   Connection Management : Pool-based connection management   Transaction Patterns : Consistent transaction handling across operations   Data Validation : Both application-level and database-level validation  This architecture provides a solid foundation for the SparkyFitness application, ensuring scalability, maintainability, and a great user experience.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":421,"path":422,"dir":391,"title":423,"description":424,"keywords":425,"body":432},"content:8.developer:3.contributing.md","\u002Fdeveloper\u002Fcontributing","Contributing to SparkyFitness","We welcome contributions of all kinds! Whether you're fixing bugs, adding features, improving documentation, or helping other users, your contributions make SparkyFitness better for everyone.",[426,427,428,429,430,15,431],"Quick Start","Development Workflow","Coding Standards","Pull Request Process","Types of Contributions","Recognition","  Contributing to SparkyFitness  We welcome contributions of all kinds! Whether you're fixing bugs, adding features, improving documentation, or helping other users, your contributions make SparkyFitness better for everyone.  Quick Start     # Fork and clone the repository\n   git   clone   https:\u002F\u002Fgithub.com\u002FCodeWithCJ\u002FSparkyFitness.git\n   cd   SparkyFitness\n   \n   # Copy environment template\n   cp   docker\u002F.env.example   .env\n   \n   # Start development environment\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   up\n  Development Workflow  Setting Up Your Development Environment    Fork the repository  on GitHub   Clone your fork  locally:\n     git   clone   https:\u002F\u002Fgithub.com\u002FYOUR_USERNAME\u002FSparkyFitness.git\n   cd   SparkyFitness\n   Add the upstream remote :\n     git   remote   add   upstream   https:\u002F\u002Fgithub.com\u002FCodeWithCJ\u002FSparkyFitness.git\n   Set up your development environment  using our   Getting Started Guide  Development Process  Branch Management    Main Branch : The   main  branch contains the latest stable code   Feature Branches : Create feature branches from   main  for new work   Naming Convention : Use descriptive branch names like   feature\u002Fadd-exercise-tracking  or   fix\u002Flogin-validation  Making Changes    Create a feature branch  from   main :     git   checkout   main\n   git   pull   upstream   main\n   git   checkout   -b   feature\u002Fyour-feature-name\n   Make your changes  following our coding standards:   Follow existing code patterns and conventions  Write clear, self-documenting code  Add comments for complex logic  Ensure your changes don't break existing functionality   Test your changes thoroughly :   Test in the development environment  Verify both frontend and backend functionality  Test edge cases and error scenarios  Ensure mobile responsiveness for UI changes   Commit your changes :     git   add   .\n   git   commit   -m   \"feat: add exercise tracking functionality\"\n  Coding Standards  General Principles    Clean Code : Write self-documenting, readable code   DRY (Don't Repeat Yourself) : Avoid code duplication   SOLID Principles : Follow object-oriented design principles   Separation of Concerns : Keep different aspects of the application separate  Frontend Standards (React\u002FTypeScript)  Component Structure     \u002F\u002F Use functional components with hooks\n   const   ExampleComponent  :   React  .  FC  \u003C  ExampleProps  >   =   ({   prop1  ,   prop2   })   =>   {\n     \u002F\u002F Hooks at the top\n     const   [  state  ,   setState  ]   =   useState  \u003C  StateType  >(  ''  );\n     const   {   data  ,   isLoading   }   =   useQuery  ([  'key'  ], fetchFn);\n     \n     \u002F\u002F Event handlers\n     const   handleSubmit   =   useCallback  ((  e  :   React  .  FormEvent  )   =>   {\n       e.  preventDefault  ();\n       \u002F\u002F Handle submission\n     }, [dependencies]);\n     \n     \u002F\u002F Early returns for loading\u002Ferror states\n     if   (isLoading)   return   \u003C  LoadingSpinner   \u002F>;\n     \n     return   (\n       \u003C  div className  =  \"component-container\"  >\n         {  \u002F* Component JSX *\u002F  }\n       \u003C\u002F  div  >\n     );\n   };\n  TypeScript Guidelines    Strict typing : Use TypeScript strictly, avoid   any  type   Interface definitions : Define clear interfaces for props and data   Type exports : Export types that are used across components   Generic components : Use generics for reusable components  Styling Conventions    Tailwind CSS : Use Tailwind utility classes for styling   shadcn\u002Fui : Prefer shadcn\u002Fui components over custom components   Responsive Design : Use responsive classes (  sm: ,   md: ,   lg: )   Dark Mode : Support both light and dark themes  Backend Standards (Node.js\u002FExpress)  TypeScript First    New Files : All new backend files must be written in TypeScript   Strict Mode : Enable strict TypeScript checking   Type Safety : Avoid   any  type, use proper types and interfaces   Existing JavaScript : You may maintain existing JavaScript files as JavaScript. New files must be TypeScript, and conversion is encouraged when adding significant functionality.  Zod Schema Validation    Required for New Endpoints : All new API endpoints must define Zod schemas for validation   Request Validation : Validate request body, params, and query parameters   Response Schemas : Define expected response shapes   Error Handling : Use Zod's error formatting for client-friendly validation errors  Example:     import   { z }   from   'zod'  ;\n   \n   \u002F\u002F Define schemas\n   const   createUserSchema   =   z.  object  ({\n     email: z.  string  ().  email  (),\n     name: z.  string  ().  min  (  1  ),\n     password: z.  string  ().  min  (  8  )\n   });\n   \n   \u002F\u002F Use in route\n   app.  post  (  '\u002Fapi\u002Fusers'  ,   async   (  req  ,   res  )   =>   {\n     const   validated   =   createUserSchema.  parse  (req.body);\n     \u002F\u002F ... rest of handler\n   });\n  Testing Requirements    New Endpoints Must Have Tests : All new API endpoints require automated tests   Test Coverage : Include happy path, error cases, and edge cases   Integration Tests : Test database interactions and external dependencies   Run Before PR : Execute   pnpm run typecheck && pnpm run lint && pnpm run test  and ensure all checks pass  Repository Pattern     \u002F\u002F All database operations use repository pattern\n   const   userRepository   =   {\n     async   createUser  (  userData  ) {\n       const   client   =   await   pool.  connect  ();\n       try   {\n         await   client.  query  (  'BEGIN'  );\n         \u002F\u002F Database operations\n         await   client.  query  (  'COMMIT'  );\n         return   result;\n       }   catch   (error) {\n         await   client.  query  (  'ROLLBACK'  );\n         throw   error;\n       }   finally   {\n         client.  release  ();\n       }\n     }\n   };\n  API Design    RESTful endpoints : Follow REST conventions   Consistent responses : Use standard response format   Error handling : Implement comprehensive error handling   Input validation : Validate all inputs with Zod schemas  Security Practices    SQL injection prevention : Use parameterized queries   Authentication : Verify JWT tokens on protected routes   Input sanitization : Sanitize all user inputs   Error messages : Don't expose sensitive information  Database Standards  Migration Guidelines    Version control : All schema changes through migrations   Backwards compatibility : Ensure migrations don't break existing data   Transaction wrapping : Wrap migrations in transactions   Rollback scripts : Provide rollback capabilities  Naming Conventions    Tables : Snake case, plural (e.g.,   food_diary_entries )   Columns : Snake case (e.g.,   created_at ,   user_id )   Indexes : Descriptive names (e.g.,   idx_food_diary_user_date )  Pull Request Process  Before Submitting    Update your branch  with the latest changes:     git   checkout   main\n   git   pull   upstream   main\n   git   checkout   your-feature-branch\n   git   merge   main\n   Run the full test suite :     # Test the application thoroughly\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   up\n   # Test your changes manually\n   # Run any automated tests\n   Review your changes :     git   diff   main...your-feature-branch\n  Pull Request Checklist       Branch is up to date  with the latest   main  branch      Changes have been tested  thoroughly in development environment      Code follows project conventions  and standards      No console errors or warnings  introduced      Mobile responsiveness  verified for UI changes      Database migrations  included if schema changes      Documentation updated  if new features or API changes      Environment variables  documented if new ones added      Backend Code Standards  (if applicable):\n     New backend files are written in TypeScript    New endpoints include Zod schemas for validation    New endpoints include automated tests      Quality Checks Passed :\n     Frontend:   pnpm run validate  in   SparkyFitnessFrontend\u002F    Backend:   pnpm run typecheck && pnpm run lint && pnpm run test  in   SparkyFitnessServer\u002F    Mobile:   pnpm run lint && pnpm run test:run -- --watchman=false --runInBand  in   SparkyFitnessMobile\u002F  Submitting Your PR    Push your changes :     git   push   origin   your-feature-branch\n   Create a Pull Request  on GitHub with:    Clear title : Concise description of the change   Detailed description : What problem does this solve and how?   Screenshots : For UI changes, include before\u002Fafter screenshots   Testing notes : How to test the changes   Breaking changes : Note any breaking changes   Related issues : Reference any related issues (e.g.,   Fixes #123 )  PR Template     ## Description\n   Brief description of changes and the problem they solve.\n   \n   ## Type of Change\n   -   [ ] Bug fix (non-breaking change which fixes an issue)\n   -   [ ] New feature (non-breaking change which adds functionality)\n   -   [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)\n   -   [ ] Documentation update\n   \n   ## Testing\n   -   [ ] Changes have been tested locally\n   -   [ ] No console errors or warnings\n   -   [ ] Mobile responsiveness verified (for UI changes)\n   \n   ## Screenshots (if applicable)\n   Include screenshots for UI changes.\n   \n   ## Additional Notes\n   Any additional information or context about the changes.\n  Review Process    Automated Validation : PR validation workflow checks that required checkboxes are checked\n   Detects Frontend, Backend, Mobile, and UI changes automatically  Validates mandatory checkboxes based on change type  Posts validation results as a comment on your PR   Important : Do not remove checkboxes from the PR template - the validation will fail   Automated Tests : CI tests run for changed components (Frontend, Backend, Mobile)   Code Review : Address feedback from reviewers promptly   Testing : Reviewers will test your changes   Approval : Get approval from maintainers   Merge : Maintainers will merge your PR  Automated PR Validation  Our PR validation workflow automatically checks your submission:   What it validates:   ✅ Integrity & License checkbox (MANDATORY for all PRs)  ✅ Alignment checkbox (MANDATORY for new features)  ✅ Frontend Quality checkbox (MANDATORY for Frontend changes)  ✅ Backend Code Quality checkbox (MANDATORY for Backend changes)  ✅ Screenshots checkbox (MANDATORY for UI changes)  ⚠️ PR type selection (Issue\u002FFeature\u002FDocumentation)  ⚠️ Linked issue reference  ⚠️ Description completeness   How it works:   The workflow runs when you open or edit a PR  It detects which parts of the codebase you changed  It validates that appropriate checkboxes are checked  It posts a comment with validation results and guidance  The PR check will fail if required checkboxes are missing   Common issues:    Don't remove checkboxes : Keep all checkboxes in the PR template   Check the right boxes : Make sure to check boxes that apply to your changes   Backend changes : Must confirm TypeScript, Zod schemas, and tests for new code   UI changes : Must include before\u002Fafter screenshots  After Your PR is Merged    Delete your feature branch :     git   checkout   main\n   git   pull   upstream   main\n   git   branch   -d   your-feature-branch\n   git   push   origin   --delete   your-feature-branch\n   Update your local main :     git   pull   upstream   main\n  Types of Contributions  Bug Fixes    Report issues : Use GitHub issues to report bugs   Provide details : Include steps to reproduce, expected vs actual behavior   Include environment : OS, browser, version information   Screenshots : Visual bugs should include screenshots  New Features    Discuss first : Open an issue to discuss new features before implementing   Small increments : Break large features into smaller, reviewable chunks   Documentation : Include documentation for new features   Tests : Ensure new features are properly tested  Documentation    Keep it current : Update documentation when code changes   Clear examples : Provide clear examples and use cases   User-focused : Write from the user's perspective   Technical accuracy : Ensure technical information is accurate  Code Quality    Refactoring : Improve code structure and readability   Performance : Optimize slow operations   Security : Address security vulnerabilities   Dependencies : Keep dependencies up to date  Getting Help  Community Support    GitHub Issues : Ask questions using GitHub issues   Discussions : Use GitHub Discussions for general questions   Documentation : Check the documentation first  Maintainer Support    Complex Issues : Tag maintainers for complex technical issues   Feature Requests : Discuss significant feature requests with maintainers   Architecture Questions : Get guidance on architectural decisions  Recognition  Contributors are recognized in several ways:    Contributors list : All contributors are listed in the project   Release notes : Significant contributions are mentioned in release notes   Community recognition : Active contributors may be invited to join the core team  Thank you for contributing to SparkyFitness! Your efforts help make fitness tracking better for everyone.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":434,"path":435,"dir":391,"title":436,"description":437,"keywords":438,"body":444},"content:8.developer:4.database.md","\u002Fdeveloper\u002Fdatabase","Database Schema & Migrations","This document covers the database structure, schema design, and migration process for SparkyFitness.",[439,440,441,442,443],"Database Overview","Schema Design Principles","Core Tables","Database Migrations","Database Maintenance","  Database Schema & Migrations  This document covers the database structure, schema design, and migration process for SparkyFitness.  Database Overview  SparkyFitness uses PostgreSQL 15+ with Row Level Security (RLS) to ensure data isolation between users. The database follows a normalized design with clear relationships between entities.  Schema Design Principles  Naming Conventions    Tables : Snake case, plural (e.g.,   food_diary_entries ,   user_preferences )   Columns : Snake case (e.g.,   created_at ,   user_id ,   total_calories )   Foreign Keys :   {table_name}_id  format (e.g.,   user_id ,   food_item_id )   Indexes : Descriptive names (e.g.,   idx_food_diary_user_date ,   idx_measurements_user_type )  Standard Fields  All tables include these audit fields:    id  - UUID primary key using   gen_random_uuid()   created_at  - Timestamp with timezone, defaults to   NOW()   updated_at  - Timestamp with timezone, updated via triggers  Row Level Security (RLS)  Every user-specific table has RLS policies to ensure users only access their own data:     -- Example RLS policy\n   ALTER TABLE food_diary ENABLE ROW LEVEL SECURITY;\n   CREATE POLICY food_diary_user_policy ON food_diary\n     FOR ALL USING (user_id = auth.uid());\n  Core Tables  User Management   users  Central user information and authentication.     CREATE TABLE users (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     email VARCHAR(255) UNIQUE NOT NULL,\n     password_hash VARCHAR(255) NOT NULL,\n     full_name VARCHAR(255),\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n   user_preferences  User-specific application preferences and settings.     CREATE TABLE user_preferences (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     theme VARCHAR(20) DEFAULT 'system',\n     ai_provider VARCHAR(50) DEFAULT 'openai',\n     units_system VARCHAR(10) DEFAULT 'metric',\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n  Food Tracking   food_items  Master catalog of food items from various sources.     CREATE TABLE food_items (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     name VARCHAR(255) NOT NULL,\n     brand VARCHAR(255),\n     barcode VARCHAR(50),\n     source VARCHAR(50), -- 'user', 'nutritionix', 'openfoodfacts', etc.\n     source_id VARCHAR(255),\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n   nutrition_data  Nutritional information for food items.     CREATE TABLE nutrition_data (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     food_item_id UUID NOT NULL REFERENCES food_items(id) ON DELETE CASCADE,\n     serving_size DECIMAL(10,2),\n     serving_unit VARCHAR(50),\n     calories DECIMAL(10,2),\n     protein DECIMAL(10,2),\n     carbohydrates DECIMAL(10,2),\n     fat DECIMAL(10,2),\n     fiber DECIMAL(10,2),\n     sugar DECIMAL(10,2),\n     sodium DECIMAL(10,2),\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n   food_diary  User's daily food intake entries.     CREATE TABLE food_diary (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     food_item_id UUID NOT NULL REFERENCES food_items(id),\n     quantity DECIMAL(10,2) NOT NULL,\n     unit VARCHAR(50) NOT NULL,\n     meal_type VARCHAR(20) NOT NULL, -- 'breakfast', 'lunch', 'dinner', 'snack'\n     consumed_at TIMESTAMP WITH TIME ZONE NOT NULL,\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n  Exercise Tracking   exercises  Master catalog of exercises.     CREATE TABLE exercises (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     name VARCHAR(255) NOT NULL,\n     category VARCHAR(100),\n     muscle_groups TEXT[],\n     equipment VARCHAR(100),\n     instructions TEXT,\n     source VARCHAR(50) DEFAULT 'user',\n     source_id VARCHAR(255),\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n   exercise_diary  User's exercise session entries.     CREATE TABLE exercise_diary (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     exercise_id UUID NOT NULL REFERENCES exercises(id),\n     duration_minutes INTEGER,\n     sets INTEGER,\n     reps INTEGER,\n     weight DECIMAL(10,2),\n     distance DECIMAL(10,2),\n     notes TEXT,\n     performed_at TIMESTAMP WITH TIME ZONE NOT NULL,\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n  Measurements & Progress   measurements  User body measurements and health metrics.     CREATE TABLE measurements (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     type VARCHAR(50) NOT NULL, -- 'weight', 'body_fat', 'muscle_mass', etc.\n     value DECIMAL(10,2) NOT NULL,\n     unit VARCHAR(20) NOT NULL,\n     measured_at TIMESTAMP WITH TIME ZONE NOT NULL,\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n  Goals & Planning   goals  User fitness and nutrition goals.     CREATE TABLE goals (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     type VARCHAR(50) NOT NULL, -- 'weight_loss', 'muscle_gain', 'calorie_target'\n     target_value DECIMAL(10,2),\n     target_unit VARCHAR(20),\n     target_date DATE,\n     current_value DECIMAL(10,2),\n     status VARCHAR(20) DEFAULT 'active', -- 'active', 'completed', 'paused'\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n   meal_plan_templates  Reusable meal plan templates.     CREATE TABLE meal_plan_templates (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     name VARCHAR(255) NOT NULL,\n     description TEXT,\n     target_calories DECIMAL(10,2),\n     is_active BOOLEAN DEFAULT true,\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n  Family & Sharing   family_access  Permissions for family members to access each other's data.     CREATE TABLE family_access (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     grantor_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     grantee_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     access_type VARCHAR(50) NOT NULL, -- 'calorie', 'checkin', 'reports', 'food_list'\n     granted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     UNIQUE(grantor_user_id, grantee_user_id, access_type)\n   );\n  AI & Chat   chat_history  AI chatbot conversation history.     CREATE TABLE chat_history (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     message TEXT NOT NULL,\n     response TEXT NOT NULL,\n     ai_provider VARCHAR(50),\n     model_used VARCHAR(100),\n     tokens_used INTEGER,\n     response_time_ms INTEGER,\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n  Database Migrations  SparkyFitness uses a custom migration system that runs automatically on server startup.  Migration Process  The migration system:    Checks current database version  on startup   Applies pending migrations  in order   Tracks applied migrations  in the   migrations  table   Logs migration results  for debugging  Migration Structure  Migrations are stored in   SparkyFitnessServer\u002Fdb\u002Fmigrations\u002F  with the naming pattern:   YYYY_MM_DD_HH_MM_description.sql\n  Example:   2024_03_15_10_30_add_exercise_tracking.sql  Creating a New Migration    Create the migration file  in the migrations directory:     cd   SparkyFitnessServer\u002Fdb\u002Fmigrations\u002F\n   touch   2024_03_15_14_20_add_meal_planning.sql\n   Write the migration SQL :     -- Migration: Add meal planning functionality\n   -- Version: 2024_03_15_14_20\n   \n   BEGIN;\n   \n   -- Create meal plans table\n   CREATE TABLE meal_plans (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,\n     name VARCHAR(255) NOT NULL,\n     planned_date DATE NOT NULL,\n     total_calories DECIMAL(10,2),\n     created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n     updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n   );\n   \n   -- Enable RLS\n   ALTER TABLE meal_plans ENABLE ROW LEVEL SECURITY;\n   \n   -- Create RLS policy\n   CREATE POLICY meal_plans_user_policy ON meal_plans\n     FOR ALL USING (user_id = auth.uid());\n   \n   -- Create indexes\n   CREATE INDEX idx_meal_plans_user_date ON meal_plans(user_id, planned_date);\n   \n   -- Update migration version\n   INSERT INTO migrations (version, applied_at) \n   VALUES ('2024_03_15_14_20', NOW());\n   \n   COMMIT;\n  Migration Best Practices  Backwards Compatibility    Add columns  with default values to avoid breaking existing code   Create new tables  rather than modifying existing ones when possible   Use transactions  to ensure atomic migrations   Test migrations  on development data first  Transaction Management     BEGIN;\n   -- All migration statements here\n   -- If any statement fails, entire migration rolls back\n   COMMIT;\n  Index Creation     -- Create indexes concurrently to avoid blocking\n   CREATE INDEX CONCURRENTLY idx_food_diary_user_date \n   ON food_diary(user_id, consumed_at);\n  Data Migration     -- Example: Migrating data to new structure\n   BEGIN;\n   \n   -- Create new table\n   CREATE TABLE new_nutrition_data (\n     id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n     food_item_id UUID NOT NULL REFERENCES food_items(id),\n     calories_per_100g DECIMAL(10,2),\n     -- other columns\n   );\n   \n   -- Migrate existing data\n   INSERT INTO new_nutrition_data (food_item_id, calories_per_100g)\n   SELECT food_item_id, calories * 100 \u002F serving_size\n   FROM old_nutrition_data\n   WHERE serving_size > 0;\n   \n   -- Drop old table (after verifying migration)\n   -- DROP TABLE old_nutrition_data;\n   \n   COMMIT;\n  Rollback Strategy  While not automated, rollback migrations can be created:    Document rollback steps  in migration comments   Create rollback scripts  for complex migrations   Test rollback procedures  in development   Backup database  before applying production migrations  Troubleshooting Migrations  Migration Fails    Check migration logs  in application startup   Verify database connection  and permissions   Check for syntax errors  in migration SQL   Ensure migration dependencies  are met  Migration Tracking Issues     -- Check applied migrations\n   SELECT * FROM migrations ORDER BY applied_at;\n   \n   -- Manually mark migration as applied (if needed)\n   INSERT INTO migrations (version, applied_at) \n   VALUES ('2024_03_15_14_20', NOW());\n  Database State Issues     -- Check table structure\n   \\d table_name\n   \n   -- Check RLS policies\n   SELECT * FROM pg_policies WHERE tablename = 'table_name';\n   \n   -- Check indexes\n   SELECT indexname, indexdef FROM pg_indexes \n   WHERE tablename = 'table_name';\n  Database Maintenance  Performance Monitoring    Query performance : Use   EXPLAIN ANALYZE  for slow queries   Index usage : Monitor index usage with   pg_stat_user_indexes   Connection monitoring : Track connection pool usage  Regular Maintenance    VACUUM : Regular vacuuming for performance   ANALYZE : Update table statistics   Index maintenance : Rebuild indexes if needed   Log rotation : Rotate and archive database logs  This database design provides a robust foundation for SparkyFitness, ensuring data integrity, security, and performance while supporting all application features.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":446,"path":447,"dir":391,"title":448,"description":449,"keywords":450,"body":456},"content:8.developer:5.api-reference.md","\u002Fdeveloper\u002Fapi-reference","API Reference","This document provides comprehensive information about the SparkyFitness API, including OpenAPI specification, endpoints, and integration guidelines.",[451,452,453,454,455],"OpenAPI Specification","Purpose in SparkyFitness","Key Elements of SparkyFitness's API (as described by OpenAPI)","Accessing the API Documentation","Detailed API Endpoints","  API Reference  This document provides comprehensive information about the SparkyFitness API, including OpenAPI specification, endpoints, and integration guidelines.  OpenAPI Specification  The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to RESTful APIs. It allows both humans and computers to discover and understand the capabilities of a service without access to source code, documentation, or network traffic inspection.  Purpose in SparkyFitness  For SparkyFitness, an OpenAPI specification would serve several key purposes:    API Documentation : Provides clear and interactive documentation for all backend API endpoints, including request parameters, response structures, and authentication methods.   Client Code Generation : Enables automatic generation of client SDKs (Software Development Kits) in various programming languages, simplifying integration for third-party applications or mobile clients.   API Testing : Facilitates automated testing of API endpoints, ensuring consistency and correctness.   Design and Collaboration : Serves as a single source of truth for API design, improving collaboration between frontend and backend developers.  Key Elements of SparkyFitness's API (as described by OpenAPI)  An OpenAPI specification for SparkyFitness would detail:    Endpoints : All available API routes (e.g.,   \u002Fapi\u002Ffood ,   \u002Fapi\u002Fusers ,   \u002Fapi\u002Fexercises ).   Operations : HTTP methods supported for each endpoint (GET, POST, PUT, DELETE).   Parameters : Input parameters for each operation, including their types, formats, and whether they are required.   Responses : The structure of successful and error responses, including status codes and data models.   Authentication : How clients authenticate with the API (e.g., JWT tokens).   Data Models (Schemas) : Definitions of the data structures used in requests and responses (e.g.,   FoodItem ,   UserProfile ,   ExerciseEntry ).  Accessing the API Documentation  While a live, interactive OpenAPI documentation (like Swagger UI) might be available in development environments, the core API is consumed by the SparkyFitness frontend and can be explored by examining the backend routes in   SparkyFitnessServer\u002Froutes\u002F  and the service definitions in   SparkyFitnessServer\u002Fservices\u002F .   Detailed API Endpoints  Authentication    API Key : Used for specific endpoints like   \u002Fapi\u002Fhealth-data . The API Key should be sent in the   Authorization  header as   Bearer \u003CAPI_KEY>  or in the   X-API-Key  header. The API Key must have the necessary permissions (e.g.,   health_data_write ).   JWT Token : Used for most authenticated endpoints. The JWT token should be sent in the   Authorization  header as   Bearer \u003CJWT_TOKEN> .  Error Handling  General error responses follow a consistent structure:    400 Bad Request : Indicates invalid input or missing required fields.   401 Unauthorized : Occurs when authentication credentials are missing or invalid.   403 Forbidden : Occurs when the authenticated user does not have the necessary permissions.   404 Not Found : The requested resource could not be found.   500 Internal Server Error : An unexpected error occurred on the server.  Example Error Response:     {\n     \"error\"  :   \"Error message describing the issue.\"\n   }\n  Endpoints  1.   \u002Fapi\u002Fhealth-data    Path :   \u002Fapi\u002Fhealth-data   Method :   POST   Description : Submits various health data points (e.g., weight, steps, active calories, custom measurements) to the system. This endpoint is crucial for integrating SparkyFitness with external health tracking services like iOS Shortcuts and Android mobile apps, allowing seamless data submission.   Authentication : API Key (sent via   Authorization  header as   Bearer \u003CAPI_KEY>  or   X-API-Key  header). The API Key must have   health_data_write  permission.   Request Body : An array of health data objects, or a single health data object.\n    Structure :\n     [\n     {\n       \"value\"  :   \u003Cnumber>  ,\n       \"type\"  :   \"\u003Cstring>\"  ,\n       \"date\"  :   \"\u003CYYYY-MM-DD>\"  ,\n       \"timestamp\"  :   \"\u003CISO 8601 string, optional>\"\n     },\n     ...\n   ]\n   Fields :\n    value  (required, number): The measurement value.   type  (required, string): The type of health data. This field is case-sensitive. Supported types include:\n    weight : Records body weight.   step : Records the number of steps taken.   water : Records water intake in milliliters.   Active Calories : Records calories burned through physical activity.  Any other string: Will be treated as a custom measurement category. If a category with this name does not exist, it will be automatically created.   date  (required, string): The date of the measurement in   YYYY-MM-DD  format (e.g., \"2025-08-19\").   timestamp  (optional, string): The exact timestamp of the measurement in ISO 8601 format (e.g., \"2025-08-19T08:30:00Z\"). If provided, the   entryHour  will be extracted for more granular tracking.   Examples :\n    Weight :\n     [\n     {\n       \"value\"  :   70.5  ,\n       \"type\"  :   \"weight\"  ,\n       \"date\"  :   \"2025-08-19\"\n     }\n   ]\n   Steps :\n     [\n     {\n       \"value\"  :   10000  ,\n       \"type\"  :   \"step\"  ,\n       \"date\"  :   \"2025-08-19\"\n     }\n   ]\n   Water Intake :\n     [\n     {\n       \"value\"  :   500  ,\n       \"type\"  :   \"water\"  ,\n       \"date\"  :   \"2025-08-19\"\n     }\n   ]\n   Active Calories :\n     [\n     {\n       \"value\"  :   500  ,\n       \"type\"  :   \"Active Calories\"  ,\n       \"date\"  :   \"2025-08-19\"\n     }\n   ]\n   Custom Measurement (e.g., \"Blood Pressure Systolic\") :\n     [\n     {\n       \"value\"  :   120  ,\n       \"type\"  :   \"Blood Pressure Systolic\"  ,\n       \"date\"  :   \"2025-08-19\"  ,\n       \"timestamp\"  :   \"2025-08-19T08:30:00Z\"\n     }\n   ]\n   Responses :\n    200 OK :\n     {\n     \"message\"  :   \"All health data successfully processed.\"  ,\n     \"processed\"  : [\n       {\n         \"type\"  :   \"weight\"  ,\n         \"status\"  :   \"success\"  ,\n         \"data\"  : {   \"id\"  :   \"uuid\"  ,   \"user_id\"  :   \"uuid\"  ,   \"entry_date\"  :   \"2025-08-19\"  ,   \"weight\"  :   70.5   }\n       }\n     ]\n   }\n   400 Bad Request :\n     {\n     \"error\"  :   \"Invalid JSON array format.\"\n   }\n \nor\n     {\n     \"message\"  :   \"Some health data entries could not be processed.\"  ,\n     \"processed\"  : [],\n     \"errors\"  : [\n       {\n         \"error\"  :   \"Missing required fields: value, type, date in one of the entries\"  ,\n         \"entry\"  : {   \"value\"  :   null  ,   \"type\"  :   \"weight\"  ,   \"date\"  :   \"2025-08-19\"   }\n       }\n     ]\n   }\n   401 Unauthorized :\n     {\n     \"error\"  :   \"Unauthorized: Missing API Key\"\n   }\n \nor\n     {\n     \"error\"  :   \"Unauthorized: Invalid or inactive API Key\"\n   }\n   403 Forbidden :\n     {\n     \"error\"  :   \"Forbidden: API Key does not have health_data_write permission\"\n   }\n  2.   \u002Fapi\u002Fmeasurements\u002Fcheck-in    Path :   \u002Fapi\u002Fmeasurements\u002Fcheck-in   Method :   POST   Description : Upserts (inserts or updates) daily check-in measurements for the authenticated user. Only one check-in entry is allowed per day.   Authentication : JWT Token (sent via   Authorization  header as   Bearer \u003CJWT_TOKEN> ).   Request Body :    Structure :\n     {\n     \"entry_date\"  :   \"\u003CYYYY-MM-DD>\"  ,\n     \"weight\"  :   \u003Cnumber  ,   optional>,\n     \"body_fat\"  :   \u003Cnumber  ,   optional>,\n     \"bmi\"  :   \u003Cnumber  ,   optional>,\n     \"neck\"  :   \u003Cnumber  ,   optional>,\n     \"chest\"  :   \u003Cnumber  ,   optional>,\n     \"waist\"  :   \u003Cnumber  ,   optional>,\n     \"hips\"  :   \u003Cnumber  ,   optional>,\n     \"thigh\"  :   \u003Cnumber  ,   optional>,\n     \"calf\"  :   \u003Cnumber  ,   optional>,\n     \"bicep\"  :   \u003Cnumber  ,   optional>,\n     \"forearm\"  :   \u003Cnumber  ,   optional>,\n     \"steps\"  :   \u003Cnumber  ,   optional>\n   }\n   Fields :\n    entry_date  (required, string): The date of the check-in in   YYYY-MM-DD  format.  Other fields (optional, number): Various measurement values.   Responses :    200 OK :\n     {\n     \"message\"  :   \"Check-in measurements upserted successfully.\"  ,\n     \"data\"  : {   \"id\"  :   \"uuid\"  ,   \"user_id\"  :   \"uuid\"  ,   \"entry_date\"  :   \"2025-08-19\"  ,   \"weight\"  :   70.5   }\n   }\n   400 Bad Request :\n     {\n     \"error\"  :   \"Entry date is required.\"\n   }\n   401 Unauthorized : (If JWT is missing or invalid)   403 Forbidden : (If user is not authorized)   Path :   \u002Fapi\u002Fmeasurements\u002Fcheck-in\u002F:date   Method :   GET   Description : Retrieves daily check-in measurements for a specific date for the authenticated user.   Authentication : JWT Token.   Path Parameters :    date  (required, string): The date of the check-in in   YYYY-MM-DD  format.   Responses :    200 OK :\n     {\n     \"id\"  :   \"uuid\"  ,\n     \"user_id\"  :   \"uuid\"  ,\n     \"entry_date\"  :   \"2025-08-19\"  ,\n     \"weight\"  :   70.5  ,\n     \"body_fat\"  :   15.2\n   }\n \nor   {}  if no entry found for the date.   400 Bad Request :\n     {\n     \"error\"  :   \"Date is required.\"\n   }\n   401 Unauthorized :   403 Forbidden :   Path :   \u002Fapi\u002Fmeasurements\u002Fcheck-in\u002F:entry_date   Method :   PUT   Description : Updates an existing daily check-in measurement entry for a specific date.   Authentication : JWT Token.   Path Parameters :    entry_date  (required, string): The date of the check-in in   YYYY-MM-DD  format.   Request Body :    Structure : Same as POST request for   \u002Fapi\u002Fmeasurements\u002Fcheck-in , but   entry_date  is provided in the path.   Fields : Any of the optional measurement fields (e.g.,   weight ,   body_fat ,   neck , etc.) to update.   Responses :    200 OK :\n     {\n     \"id\"  :   \"uuid\"  ,\n     \"user_id\"  :   \"uuid\"  ,\n     \"entry_date\"  :   \"2025-08-19\"  ,\n     \"weight\"  :   71.0  ,\n     \"body_fat\"  :   15.2\n   }\n   400 Bad Request :\n     {\n     \"error\"  :   \"Entry date is required.\"\n   }\n   401 Unauthorized : (If JWT is missing or invalid)   403 Forbidden : (If user is not authorized)   404 Not Found :\n     {\n     \"error\"  :   \"Check-in measurement not found or not authorized to update.\"\n   }\n   Path :   \u002Fapi\u002Fmeasurements\u002Fcheck-in\u002F:id   Method :   DELETE   Description : Deletes a daily check-in measurement entry.   Authentication : JWT Token.   Path Parameters :    id  (required, string): The ID of the check-in entry to delete.   Responses :    200 OK :\n     {\n     \"message\"  :   \"Check-in measurement deleted successfully.\"\n   }\n   400 Bad Request :\n     {\n     \"error\"  :   \"Check-in Measurement ID is required.\"\n   }\n   401 Unauthorized :   403 Forbidden :   404 Not Found :\n     {\n     \"error\"  :   \"Check-in measurement not found or not authorized to delete.\"\n   }\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":458,"path":459,"dir":391,"title":460,"description":461,"keywords":462,"body":467},"content:8.developer:6.troubleshooting.md","\u002Fdeveloper\u002Ftroubleshooting","Troubleshooting & Debugging","This comprehensive guide provides solutions to common issues and debugging techniques for SparkyFitness developers.",[463,464,465,466,15],"Common Issues and Solutions","Debugging Techniques","Development Environment Issues","Advanced Debugging","  Troubleshooting & Debugging  This comprehensive guide provides solutions to common issues and debugging techniques for SparkyFitness developers.  Common Issues and Solutions  Port Conflicts  If you encounter errors indicating that a port is already in use, another application is likely using one of the ports required by SparkyFitness (e.g., 8080 for frontend, 3010 for backend, 5432 for PostgreSQL).   Solution:    Identify the conflicting process :\n   On Linux\u002FmacOS:   lsof -i :\u003Cport_number>  (e.g.,   lsof -i :8080 )  On Windows:   netstat -ano | findstr :\u003Cport_number>  followed by   taskkill \u002FPID \u003CPID> \u002FF   Stop the conflicting service  or   change the port  in your   .env  file.  Database Connection Issues  Problems connecting to the PostgreSQL database can arise from incorrect credentials, the database not running, or network issues.   Solution:    Check database logs :\n     .\u002Fdocker\u002Fdocker-helper.sh   dev   logs   sparkyfitness-db\n   Verify   .env  settings : Ensure   SPARKY_FITNESS_DB_NAME ,   SPARKY_FITNESS_DB_USER , and   SPARKY_FITNESS_DB_PASSWORD  are correct.   Reset database (Development only!) : If data integrity is not critical, you can perform a destructive reset.\n     .\u002Fdocker\u002Fdocker-helper.sh   dev   down\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   clean\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   up\n  Build Failures  Issues during the build process (e.g.,   npm install  or Docker image builds) can be caused by corrupted caches or dependency problems.   Solution:    Clean rebuild :\n     .\u002Fdocker\u002Fdocker-helper.sh   dev   build   --no-cache\n   Full reset :\n     .\u002Fdocker\u002Fdocker-helper.sh   dev   clean\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   up\n  Permission Issues (Linux\u002FWSL)  On Linux or Windows Subsystem for Linux (WSL), you might encounter permission errors related to Docker volumes, especially for the PostgreSQL data directory.   Solution:    Fix volume permissions :\n     sudo   chown   -R   $USER  :  $USER   .\u002Fpostgresql\n  \"Invalid key length\" error  This error typically indicates that your   SPARKY_FITNESS_API_ENCRYPTION_KEY  in your   .env  file is not correctly configured. Ensure it is a 64-character hexadecimal string.   Solution: \nGenerate a valid key using:     openssl   rand   -hex   32\n   # or\n   node   -e   \"console.log(require('crypto').randomBytes(32).toString('hex'))\"\n  Rate Limiting Issues  SparkyFitness implements rate limiting at the Nginx reverse proxy layer to prevent brute-force attacks and DoS attempts.   Common Rate Limiting Errors:    429 Too Many Requests  on login\u002Fsignup endpoints  Connection refused during high traffic   Solution:    Check rate limit configuration  in   docker\u002Fnginx.conf.template :\n     limit_req_zone $binary_remote_addr zone=login_signup_zone:10m rate=5r\u002Fs;\n   Temporary bypass for development :\n     # Edit nginx.conf.template and increase rate limits\n   # Then restart containers\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   restart\n   Production tuning : Adjust rate limits based on actual usage patterns  Authentication & JWT Issues   Common symptoms:    401 Unauthorized  errors  Token expired messages  Login session not persisting   Solution:    Check JWT secret configuration :\n     # Ensure JWT_SECRET is properly set in .env\n   grep   JWT_SECRET   .env\n   Clear browser storage :\n     \u002F\u002F In browser console\n   localStorage.  clear  ();\n   sessionStorage.  clear  ();\n   Verify token expiration settings  in backend configuration  Debugging Techniques  Application Logs   View all service logs:     .\u002Fdocker\u002Fdocker-helper.sh   dev   logs\n   Follow specific service logs:     .\u002Fdocker\u002Fdocker-helper.sh   dev   logs   -f   sparkyfitness-frontend\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   logs   -f   sparkyfitness-server\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   logs   -f   sparkyfitness-db\n   Backend debugging logs:     # Enable debug logging in .env\n   LOG_LEVEL  =  debug\n   \n   # View structured logs\n   docker   exec   -it   sparkyfitness-server-1   tail   -f   \u002Fapp\u002Flogs\u002Fapp.log\n  Container Inspection   List running containers:     .\u002Fdocker\u002Fdocker-helper.sh   dev   ps\n   Execute commands in containers:     # Frontend container\n   docker   exec   -it   sparkyfitness-frontend-1   sh\n   \n   # Backend container\n   docker   exec   -it   sparkyfitness-server-1   sh\n   \n   # Database container\n   docker   exec   -it   sparkyfitness-db-1   psql   -U   sparky   -d   sparkyfitness_db\n   Inspect container resources:     # Check resource usage\n   docker   stats\n   \n   # Inspect container configuration\n   docker   inspect   sparkyfitness-server-1\n  Database Debugging   Connect to PostgreSQL:     docker   exec   -it   sparkyfitness-db-1   psql   -U   sparky   -d   sparkyfitness_db\n   Common database queries:     -- Check table structure\n   \\dt\n   \n   -- View recent logs\n   SELECT * FROM logs ORDER BY created_at DESC LIMIT 10;\n   \n   -- Check user data\n   SELECT id, email, created_at FROM users LIMIT 5;\n   \n   -- Monitor active connections\n   SELECT * FROM pg_stat_activity;\n   Database migration issues:     # Check migration status\n   docker   exec   -it   sparkyfitness-server-1   npm   run   migrate:status\n   \n   # Force migration reset (DANGEROUS)\n   docker   exec   -it   sparkyfitness-server-1   npm   run   migrate:reset\n  Network Debugging   Check container networking:     # List Docker networks\n   docker   network   ls\n   \n   # Inspect network configuration\n   docker   network   inspect   \u003C  network_nam  e  >\n   \n   # Test connectivity between containers\n   docker   exec   -it   sparkyfitness-frontend-1   ping   sparkyfitness-server\n   API endpoint testing:     # Test backend health endpoint\n   curl   http:\u002F\u002Flocalhost:3010\u002Fapi\u002Fhealth\n   \n   # Test with authentication\n   curl   -H   \"Authorization: Bearer \u003Ctoken>\"   http:\u002F\u002Flocalhost:3010\u002Fapi\u002Fusers\u002Fprofile\n  Performance Debugging   Monitor resource usage:     # Real-time resource monitoring\n   docker   stats   --format   \"table {{.Container}}\\t{{.CPUPerc}}\\t{{.MemUsage}}\"\n   \n   # System resource usage\n   htop    # or top on basic systems\n   Database performance:     -- Check slow queries\n   SELECT query, calls, total_time, mean_time \n   FROM pg_stat_statements \n   ORDER BY mean_time DESC \n   LIMIT 10;\n   \n   -- Check locks\n   SELECT * FROM pg_locks WHERE NOT GRANTED;\n  Development Environment Issues  Hot Reload Not Working   Frontend hot reload issues:     # Check Vite configuration\n   cat   vite.config.ts\n   \n   # Restart with clean cache\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   down\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   up   --build\n  Environment Variable Issues   Debug environment variables:     # Check .env file is loaded\n   docker   exec   -it   sparkyfitness-server-1   env   |   grep   SPARKY\n   \n   # Verify frontend environment variables\n   docker   exec   -it   sparkyfitness-frontend-1   env   |   grep   VITE\n  TypeScript Compilation Issues   Common TypeScript errors:     # Check TypeScript configuration\n   cat   tsconfig.json\n   \n   # Run type checking manually\n   docker   exec   -it   sparkyfitness-frontend-1   npm   run   type-check\n   \n   # Clear TypeScript cache\n   rm   -rf   node_modules\u002F.cache\n  Advanced Debugging  Memory Leaks   Identify memory leaks:     # Monitor memory usage over time\n   watch   -n   1   'docker stats --no-stream'\n   \n   # Use Node.js heap dumps\n   docker   exec   -it   sparkyfitness-server-1   node   --inspect=0.0.0.0:9229   server.js\n  Performance Profiling   Backend profiling:     \u002F\u002F Add to backend code for profiling\n   const   profiler   =   require  (  'v8-profiler-next'  );\n   \n   \u002F\u002F Start profiling\n   profiler.  startProfiling  (  'API_PROFILE'  );\n   \n   \u002F\u002F End profiling and save\n   const   profile   =   profiler.  stopProfiling  (  'API_PROFILE'  );\n   profile.  export  ().  pipe  (fs.  createWriteStream  (  'profile.cpuprofile'  ));\n  Security Debugging   Check for security vulnerabilities:     # NPM audit\n   npm   audit\n   \n   # Docker security scanning\n   docker   scan   sparkyfitness-server:latest\n  Getting Help  When troubleshooting fails, reach out to the community:    Discord Community :   https:\u002F\u002Fdiscord.gg\u002FvcnMT5cPEA   GitHub Discussions : Post detailed questions with logs   Documentation : Search this comprehensive documentation site   Issue Templates : Use provided GitHub issue templates for bug reports  Creating Effective Bug Reports  Include the following information:    Environment details : OS, Docker version, Node.js version   Steps to reproduce : Clear, numbered steps   Expected vs. actual behavior : What should happen vs. what happens   Logs : Relevant log excerpts (use code blocks)   Configuration : Relevant parts of .env or config files (sanitized)   Screenshots : For UI issues   Log collection command:     # Collect all relevant logs\n   .\u002Fdocker\u002Fdocker-helper.sh   dev   logs   >   debug-logs-  $(  date   +%Y%m%d-%H%M%S  )  .txt\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":469,"path":470,"dir":391,"title":471,"description":7,"keywords":472,"body":478},"content:8.developer:7.testing.md","\u002Fdeveloper\u002Ftesting","Testing",[8,473,474,475,476,477],"Running Tests Locally","CI Workflow","Test File Locations","Writing Frontend Tests","Coverage Reports","  Testing  Overview  SparkyFitness uses   Jest  for JavaScript\u002FTypeScript testing across the frontend, backend, and mobile projects, and   pytest  for the Garmin microservice.  Running Tests Locally  Each component has its own test scripts:     # Frontend (Vite + React)\n   cd   SparkyFitnessFrontend\n   pnpm   test            # Run tests in watch mode\n   pnpm   test:ci         # Run tests once with coverage (CI mode)\n   \n   # Backend (Node.js + Express)\n   cd   SparkyFitnessServer\n   pnpm   test            # Run tests in watch mode\n   pnpm   test:ci         # Run tests once with coverage (CI mode)\n   \n   # Mobile (React Native + Expo)\n   cd   SparkyFitnessMobile\n   npm   run   test:run     # Run tests once\n   npm   run   test:ci      # Run tests once with coverage (CI mode)\n   \n   # Garmin Microservice (Python)\n   cd   SparkyFitnessGarmin\n   pytest   --cov=.   --cov-report=html\n  CI Workflow  The CI pipeline (  .github\u002Fworkflows\u002Fci-tests.yml ) runs on pull requests and pushes to   main . It uses   path-based change detection  via   dorny\u002Fpaths-filter  so that only the affected component's tests run.     Component  Trigger Path  Package Manager  Test Command    Frontend   SparkyFitnessFrontend\u002F**  pnpm   pnpm run test:ci   Mobile   SparkyFitnessMobile\u002F**  npm   npm run test:ci   Server   SparkyFitnessServer\u002F**  pnpm   pnpm run test:ci   Garmin   SparkyFitnessGarmin\u002F**  pip   pytest  Test File Locations   SparkyFitnessFrontend\u002F\n  src\u002Ftests\u002F\n    setupTests.ts              # Global test setup (jest-dom, polyfills)\n    components\u002F                # Component tests\n      MealBuilder.test.tsx\n      MealManagement.test.tsx\n      MealPlanCalendar.test.tsx\n\nSparkyFitnessServer\u002F\n  __tests__\u002F                   # Backend unit and integration tests\n\nSparkyFitnessMobile\u002F\n  __tests__\u002F                   # Mobile app tests\n  Writing Frontend Tests  Mock Pattern  All frontend component tests follow a consistent mocking strategy:     \u002F\u002F 1. Mock i18n — return fallback string or key\n   jest.  mock  (  'react-i18next'  , ()   =>   ({\n     useTranslation  : ()   =>   ({\n       t  : (  key  :   string  ,   defaultValueOrOpts  ?:   string   |   Record  \u003C  string  ,   unknown  >)   =>   {\n         if   (  typeof   defaultValueOrOpts   ===   'string'  )   return   defaultValueOrOpts;\n         if   (defaultValueOrOpts   &&   typeof   defaultValueOrOpts   ===   'object'   &&   'defaultValue'   in   defaultValueOrOpts) {\n           return   defaultValueOrOpts.defaultValue   as   string  ;\n         }\n         return   key;\n       },\n     }),\n   }));\n   \n   \u002F\u002F 2. Mock contexts\n   jest.  mock  (  '@\u002Fcontexts\u002FActiveUserContext'  , ()   =>   ({\n     useActiveUser  : ()   =>   ({ activeUserId:   'test-user-id'   }),\n   }));\n   jest.  mock  (  '@\u002Fcontexts\u002FPreferencesContext'  , ()   =>   ({\n     usePreferences  : ()   =>   ({ loggingLevel:   'debug'  , foodDisplayLimit:   100   }),\n   }));\n   \n   \u002F\u002F 3. Mock toast\n   jest.  mock  (  '@\u002Fhooks\u002Fuse-toast'  , ()   =>   ({ toast: jest.  fn  () }));\n   \n   \u002F\u002F 4. Mock logging\n   jest.  mock  (  '@\u002Futils\u002Flogging'  , ()   =>   ({\n     debug: jest.  fn  (), info: jest.  fn  (), warn: jest.  fn  (), error: jest.  fn  (),\n   }));\n   \n   \u002F\u002F 5. Mock services with trackable fns\n   const   mockGetMeals   =   jest.  fn  ();\n   jest.  mock  (  '@\u002Fservices\u002FmealService'  , ()   =>   ({\n     getMeals  : (  ...  args  :   unknown  [])   =>   mockGetMeals  (  ...  args),\n   }));\n  Conventions   Test files live alongside their component domain in   src\u002Ftests\u002Fcomponents\u002F  Use   @testing-library\u002Freact  for rendering and assertions  Mock complex child components as simple stubs to isolate the component under test  Use   waitFor  for async operations (API calls, state updates)  Use   initialFoods  or similar props to inject data without needing interactive sub-components  Coverage Reports  Coverage reports are generated in the   coverage\u002F  directory of each component when running   test:ci . In CI, they are uploaded as build artifacts and retained for 7 days.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":480,"path":481,"dir":482,"title":483,"description":7,"keywords":484,"body":490},"content:8.developer:8.advanced:1.ai-command-patterns.md","\u002Fdeveloper\u002Fadvanced\u002Fai-command-patterns","advanced","AI Command Patterns & Context Guide",[485,486,487,488,489,418],"Common User Interaction Patterns","Database Context for AI Operations","AI Response Templates","Error Handling Patterns","Context Optimization","  AI Command Patterns & Context Guide  Common User Interaction Patterns  Food Logging Commands   User Intent : Log food intake\n  Common Phrases :   \"I ate 2 slices of pizza\"  \"Add 1 cup of rice to lunch\"  \"Log breakfast: 2 eggs and toast\"  \"I had dominos chicken pizza\"   Expected AI Response :   Extract food items with quantities  Determine meal type (breakfast\u002Flunch\u002Fdinner\u002Fsnacks)  Get nutrition data from database or AI knowledge  Present confirmation dialog with nutrition summary  Add to food diary upon confirmation   Context Date Extraction :   \"today\" → current date  \"yesterday\" → previous date  \"last Sunday\" → specific past date  No date mentioned → assume today  Measurement Logging Commands   User Intent : Record body measurements\n  Common Phrases :   \"My weight is 70kg today\"  \"Waist measurement: 32 inches\"  \"I weighed 154 pounds this morning\"   Expected AI Response :   Extract measurement type and value  Convert units if necessary  Save to appropriate measurement table  Provide confirmation with trend information  Goal Setting Commands   User Intent : Update nutrition or fitness goals\n  Common Phrases :   \"Set my calorie goal to 1800\"  \"I want to consume 120g protein daily\"  \"Change my water goal to 10 glasses\"   Expected AI Response :   Identify goal type and target value  Update user_goals table  Apply to future dates using goal timeline function  Confirm changes with previous vs new goals  Progress Inquiry Commands   User Intent : Get progress information\n  Common Phrases :   \"How am I doing today?\"  \"Show my calorie progress\"  \"What's my weight trend this week?\"   Expected AI Response :   Query relevant data based on request type  Calculate progress percentages  Provide trend analysis  Suggest improvements if applicable  Database Context for AI Operations  Food Operations   Tables : foods, food_entries, food_variants\n  Key Operations :   Search foods by name\u002Fbrand  Create custom foods when not found  Calculate nutrition based on quantity  Handle different serving units   Nutrition Calculation :   final_nutrition = (food_nutrition \u002F food_serving_size) * user_quantity\n  Measurement Operations   Tables : check_in_measurements, custom_measurements, custom_categories\n  Key Operations :   Record standard measurements (weight, waist, etc.)  Handle custom measurement categories  Convert between units (kg\u002Flbs, cm\u002Finches)  Track trends over time  Goal Operations   Tables : user_goals\n  Key Operations :   Retrieve current goals for date  Update goals with timeline management  Handle historical vs future goal changes  Calculate progress percentages  Family Access Context   Tables : family_access\n  Permission Checks :   Always check   can_access_user_data()  before operations  Respect permission levels (read vs write)  Handle permission inheritance rules  AI Response Templates  Food Logging Success   \"Great! I've analyzed your [meal_type] and found:\n\n**[quantity] [food_name]:**\n• [calories] calories\n• [protein]g protein, [carbs]g carbs, [fat]g fat\n• [fiber]g fiber, [sodium]mg sodium\n\nWould you like me to add this to your [meal_type] for [date]?\"\n  Progress Summary   \"Here's your progress for today:\n\n**Calories:** [consumed]\u002F[goal] ([percentage]%)\n**Protein:** [consumed]g\u002F[goal]g ([percentage]%)\n**Carbs:** [consumed]g\u002F[goal]g ([percentage]%)\n**Fat:** [consumed]g\u002F[goal]g ([percentage]%)\n\n[motivational message based on progress]\"\n  Measurement Confirmation   \"Recorded your [measurement_type]: [value] [unit]\n\n[Trend information if available]\n[Encouragement or suggestions]\"\n  Error Handling Patterns  Food Not Found   Search for similar foods in database  Offer to create custom food  Ask for more specific information (brand, preparation)  Provide nutrition estimation if possible  Invalid Measurements   Check for reasonable ranges  Confirm unusual values with user  Suggest unit conversion if needed  Provide context about normal ranges  Permission Denied   Explain family access limitations  Suggest contacting data owner  Offer alternative accessible features  Maintain privacy without revealing restricted data  Context Optimization  Essential Context (Always Load)   User's current goals  Today's food entries  Active family access permissions  Basic app navigation structure  On-Demand Context (Load Based on Query)    Food queries : Food database, nutrition facts, meal history   Measurement queries : Historical measurements, trends, goals   Report queries : Analytics data, progress calculations   Settings queries : User preferences, AI configuration  Performance Considerations   Cache frequently accessed nutrition data  Limit historical data queries to reasonable ranges  Use database functions for complex calculations  Batch related operations when possible  Integration Points  Direct Database Operations   Food entries creation\u002Fmodification  Measurement logging  Goal updates  Custom food creation  UI Refresh Triggers   Dispatch 'foodDiaryRefresh' event after food logging  Update measurement charts after new entries  Refresh progress bars after goal changes  Update family access status after permission changes  Notification Patterns   Success toasts for completed operations  Error alerts for failed operations  Confirmation dialogs for destructive actions  Progress notifications for long operations",{"id":492,"path":493,"dir":482,"title":494,"description":495,"keywords":496,"body":499},"content:8.developer:8.advanced:2.chatbot-workflow.md","\u002Fdeveloper\u002Fadvanced\u002Fchatbot-workflow","Sparky Chatbot Workflow (Refined)","This document outlines the refined workflow for how the Sparky chatbot processes user messages, identifies intent, extracts data, interacts with the database, and provides responses, incorporating improvements for robustness, multi-item handling, context, and error management.",[497,498],"Overall Process","Detailed Workflow by Intent","  Sparky Chatbot Workflow (Refined)  This document outlines the refined workflow for how the Sparky chatbot processes user messages, identifies intent, extracts data, interacts with the database, and provides responses, incorporating improvements for robustness, multi-item handling, context, and error management.  Overall Process    User Input:  The user sends a message to the chatbot in natural language, potentially including text and\u002For an image.   AI Intent Recognition & Data Extraction:  The chatbot sends the user's message to the AI model along with recent conversation history (e.g., the last 5 messages) and a detailed system prompt. The system prompt will instruct the AI to:\n    Prioritize the current user message  when determining intent and extracting data.  Use the conversation history primarily for   context  (e.g., understanding follow-ups like \"add another one\", clarifying ambiguous terms, or referencing previous items).   Avoid re-processing requests  that appear to have been completed in the recent history.   Application Logic (SparkyNutritionCoach):  Based on the   intent  provided by the AI, the application logic routes the request to the appropriate handler function.   Database Interaction:  The handler function interacts with the Supabase database to log data (food entries, exercise entries, measurements) or retrieve information.   Response Generation:  Based on the success or failure of the database operation, or if the intent was conversational, a user-friendly response message is generated.   User Output:  The generated response message is displayed to the user in the chat interface.  Detailed Workflow by Intent  The AI is designed to identify one of the following intents:    Log Food (  log_food )    AI Data:    food_name  (string),   quantity  (number, inferred or default 1),   unit  (string, inferred or default \"g\"),   meal_type  (string, inferred or default \"snack\"),   date  (string, ISO format, inferred or null).   Application Logic:    Validation:  Check if   food_name  is present and is a string.  Search for the extracted   food_name  in the   foods  table (user's custom first, then public).   If Food Found:  Log a new entry in the   food_entries  table using the found   food_id , extracted   quantity ,   unit ,   meal_type , and the extracted   date  (defaulting to today if null). Validate the date to prevent logging future entries.   If Food Not Found:  Send a secondary request to the AI specifically asking it to generate 3 realistic food options similar to the requested   food_name , including estimated nutritional details and serving information. Include context like the original input and potentially user preferences (e.g., dietary restrictions) in the prompt.   AI Options Response:  AI returns JSON with   food_options  array.   Application Logic (Options):  Display the generated food options to the user in a numbered list. Guide the user to reply with a number to select an option OR provide manual nutrition details (e.g., \"If none fit, reply with 'manual: 100 cal, 5g protein...'\"). Store the options data (including original request details) in the chat message's metadata for handling the user's subsequent selection or manual entry.   Log Exercise (  log_exercise )    AI Data:    exercise_name  (string),   duration_minutes  (number, inferred or null),   distance  (number, inferred or null),   distance_unit  (string, inferred or null),   date  (string, ISO format, inferred or null).   Application Logic:    Validation:  Check if   exercise_name  is present and is a string.  Search the   exercises  table for the extracted   exercise_name .   If Exercise Found:  Log a new entry in the   exercise_entries  table with extracted details (  exercise_id ,   duration_minutes  - using AI value or default from DB,   calories_burned  - calculated,   distance ,   distance_unit , extracted   date ). Validate the date.   If Exercise Not Found:  Send a secondary request to the AI specifically asking it to generate 3 exercise options similar to the requested exercise, including estimated   calories_per_hour .   AI Options Response:  AI returns JSON with   exercise_options  array.   Application Logic (Options):  Display the generated exercise options to the user in a numbered list. Guide the user on how to provide manual details if needed. Store options data in metadata.   Log Body Measurements (  log_measurement  - standard types)    AI Data:    measurements  (array of objects), each with   type  (\"weight\", \"neck\", \"waist\", \"hips\", \"steps\"),   value  (number),   unit  (string, inferred or null, except for steps which defaults to \"steps\"),   date  (string, ISO format, inferred or null).   Application Logic:    Validation:  Check if   measurements  is an array and each object has   type  and   value .  For each measurement in the   measurements  array:\n   If   type  is standard: Upsert into the   check_in_measurements  table for the user and the extracted   date  (defaulting to today). Validate the date.  Generate a confirmation message listing the measurements that were successfully logged.   Log Custom Measurements (  log_measurement  - custom type)    AI Data:    measurements  (array of objects), each with   type  (\"custom\"),   name  (string),   value  (number),   unit  (string, inferred or null),   date  (string, ISO format, inferred or null).   Application Logic:    Validation:  Check if   measurements  is an array and each custom object has   type ,   name , and   value .  For each custom measurement in the   measurements  array:\n   Search for a category with the extracted   name  in the   custom_categories  for the user.   If Category Found:  Use the found   category_id .   If Category Not Found:  Create a new entry in   custom_categories  with the extracted   name , defaulting   frequency  to 'daily' and   measurement_type  to 'numeric'. Use the new   category_id .  Insert a new entry in the   custom_measurements  with user ID,   category_id , extracted   value , and extracted   date \u002Ftimestamp (defaulting to now). Validate the date.  Generate a confirmation message listing the custom measurements that were successfully logged.   Log Water Intake (  log_water )    AI Data:    glasses_consumed  (number, inferred or default 1),   date  (string, ISO format, inferred or null).   Application Logic:    Validation:  Check if   glasses_consumed  is a number or null.  Get the current water intake for the user for the extracted   date  (defaulting to today).  Calculate the new total by adding the extracted   glasses_consumed  (or default 1) to the current total.  Upsert the new total into the   water_intake  table for the user and the extracted   date . Validate the date.  Generate a confirmation message showing the added glasses and the new total for the day.   Ask Question (  ask_question ) \u002F General Chat (  chat )    AI Data:  Empty   data  object,   response  (string containing the AI's conversational reply).   Application Logic:   Display the   response  provided directly by the AI.  3. Post-Logging Actions & User Interaction    After successful logging (any type):   Trigger a refresh of relevant data displays (e.g., food diary, measurements charts).   Refined Progress Updates:  Batch progress updates for multi-item inputs (display one summary after all items are processed). For single item logs, update immediately. The update message should include a summary of today's relevant data (nutrition, exercise, measurements) and a coaching tip. Tailor the summary slightly based on the type of item just logged.   Handling Option Selection:   If the user's next message is a number and the previous bot message contained options metadata:\n    Validation:  Check if the number is a valid index for the options stored in the metadata and if the metadata is still valid\u002Fpresent.   If Valid Selection:  Process the selected option using the stored data (e.g., call   addFoodOption  or   addExerciseOption ).   If Invalid Selection:  Return a   CoachResponse  with   action: 'none'  and a message guiding the user (e.g., \"Please select a valid option number or tell me what you'd like to do.\").  If the user's next message is not a number but matches the format for manual data entry (e.g., \"manual: ...\"), process the manual entry.  If the user's next message is unrelated, process it as a new input using the standard AI workflow.  Relevant Database Tables  Here are the schemas for the relevant database tables for context:     -- check_in_measurements table\n   create table public.check_in_measurements (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     entry_date date not null default CURRENT_DATE,\n     weight numeric null,\n     neck numeric null,\n     waist numeric null,\n     hips numeric null,\n     steps integer null,\n     created_at timestamp with time zone not null default now(),\n     updated_at timestamp with time zone not null default now(),\n     constraint check_in_measurements_pkey primary key (id),\n     constraint check_in_measurements_user_date_unique unique (user_id, entry_date)\n   ) TABLESPACE pg_default;\n     -- custom_categories table\n   create table public.custom_categories (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     name character varying(50) not null,\n     measurement_type character varying(50) not null, -- e.g., 'numeric', 'text'\n     frequency text not null, -- e.g., 'Daily', 'Weekly', 'Monthly', 'All'\n     created_at timestamp with time zone not null default now(),\n     updated_at timestamp with time zone not null default now(),\n     constraint custom_categories_pkey primary key (id),\n     constraint custom_categories_user_id_fkey foreign KEY (user_id) references auth.users (id),\n     constraint custom_categories_frequency_check check (\n       (\n         frequency = any (array['All'::text, 'Daily'::text, 'Hourly'::text, 'Weekly'::text, 'Monthly'::text]) -- Added Weekly, Monthly based on common use cases\n       )\n     )\n   ) TABLESPACE pg_default;\n     -- custom_measurements table\n   create table public.custom_measurements (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     category_id uuid not null,\n     value numeric not null,\n     entry_date date not null,\n     entry_hour integer null, -- For hourly frequency\n     entry_timestamp timestamp with time zone not null default now(),\n     created_at timestamp with time zone not null default now(),\n     constraint custom_measurements_pkey primary key (id),\n     constraint custom_measurements_unique_entry unique (user_id, category_id, entry_date, entry_hour), -- Ensure uniqueness based on frequency\n     constraint custom_measurements_category_id_fkey foreign KEY (category_id) references custom_categories (id) on delete CASCADE,\n     constraint custom_measurements_user_id_fkey foreign KEY (user_id) references auth.users (id)\n   ) TABLESPACE pg_default;\n     -- food_entries table\n   create table public.food_entries (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     food_id uuid not null,\n     meal_type character varying(50) not null, -- e.g., 'breakfast', 'lunch', 'dinner', 'snack'\n     quantity numeric not null,\n     unit character varying(50) null, -- e.g., 'g', 'oz', 'piece'\n     entry_date date not null,\n     created_at timestamp with time zone not null default now(),\n     variant_id uuid null, -- Link to food_variants if applicable\n     constraint food_entries_pkey primary key (id),\n     constraint food_entries_food_id_fkey foreign KEY (food_id) references foods (id),\n     constraint food_entries_user_id_fkey foreign KEY (user_id) references auth.users (id),\n     constraint food_entries_variant_id_fkey foreign KEY (variant_id) references food_variants (id)\n   ) TABLESPACE pg_default;\n     -- foods table\n   create table public.foods (\n     id uuid not null default gen_random_uuid (),\n     name character varying(255) not null,\n     calories numeric null,\n     protein numeric null,\n     carbs numeric null,\n     fat numeric null,\n     serving_size numeric null, -- Default serving size in grams or standard unit\n     serving_unit character varying(50) null, -- e.g., 'g', 'ml', 'piece'\n     is_custom boolean null default false, -- True if created by a user\n     user_id uuid null, -- Creator user_id if is_custom is true\n     created_at timestamp with time zone null default now(),\n     updated_at timestamp with time zone null default now(),\n     barcode character varying(255) null, -- For scanning\n     openfoodfacts_id character varying(255) null, -- Link to external databases\n     shared_with_public boolean null default false,\n     saturated_fat numeric null, -- Added for comprehensive nutrition\n     polyunsaturated_fat numeric null,\n     monounsaturated_unsaturated numeric null,\n     trans_fat numeric null,\n     cholesterol numeric null,\n     sodium numeric null,\n     potassium numeric null,\n     dietary_fiber numeric null,\n     sugars numeric null,\n     vitamin_a numeric null,\n     vitamin_c numeric null,\n     calcium numeric null,\n     iron numeric null,\n     constraint foods_pkey primary key (id),\n     constraint foods_user_id_fkey foreign KEY (user_id) references auth.users (id)\n   ) TABLESPACE pg_default;\n     -- exercise_entries table\n   create table public.exercise_entries (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     exercise_id uuid not null,\n     duration_minutes integer not null,\n     calories_burned integer not null,\n     entry_date date null,\n     notes text null,\n     created_at timestamp with time zone null default now(),\n     constraint exercise_entries_pkey primary key (id),\n     constraint exercise_entries_exercise_id_fkey foreign KEY (exercise_id) references exercises (id),\n     constraint exercise_entries_user_id_fkey foreign KEY (user_id) references auth.users (id)\n   ) TABLESPACE pg_default;\n     -- exercises table\n   create table public.exercises (\n     id uuid not null default gen_random_uuid (),\n     name character varying(255) not null,\n     category character varying(50) null, -- e.g., 'cardio', 'strength'\n     calories_per_hour integer null, -- Estimated calories burned per hour\n     description text null,\n     is_custom boolean null default false,\n     user_id uuid null, -- Creator user_id if is_custom is true\n     created_at timestamp with time zone null default now(),\n     updated_at timestamp with time zone null default now(),\n     shared_with_public boolean null default false,\n     constraint exercises_pkey primary key (id),\n     constraint exercises_user_id_fkey foreign KEY (user_id) references auth.users (id)\n   ) TABLESPACE pg_default;\n     -- water_intake table\n   create table public.water_intake (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     entry_date date not null,\n     glasses_consumed integer not null,\n     created_at timestamp with time zone not null default now(),\n     updated_at timestamp with time zone not null default now(),\n     constraint water_intake_pkey primary key (id),\n     constraint water_intake_user_date_unique unique (user_id, entry_date),\n     constraint water_intake_user_id_fkey foreign KEY (user_id) references auth.users (id)\n   ) TABLESPACE pg_default;\n     -- ai_service_settings table\n   create table public.ai_service_settings (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     service_name character varying(255) not null, -- e.g., 'OpenAI', 'Google Gemini'\n     service_type character varying(50) not null, -- e.g., 'openai', 'google'\n     api_key text not null,\n     is_active boolean not null default true,\n     model_name character varying(255) null, -- Specific model used\n     system_prompt text null, -- Custom system prompt for the AI\n     custom_url text null, -- For custom or compatible services\n     created_at timestamp with time zone not null default now(),\n     updated_at timestamp with time zone not null default now(),\n     constraint ai_service_settings_pkey primary key (id),\n     constraint ai_service_settings_user_id_fkey foreign KEY (user_id) references auth.users (id)\n   ) TABLESPACE pg_default;\n     -- sparky_chat_history table\n   create table public.sparky_chat_history (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     session_id uuid not null default gen_random_uuid (), -- To group messages by session\n     message_type character varying(50) not null, -- 'user' or 'assistant'\n     content text not null, -- The message content\n     created_at timestamp with time zone not null default now(),\n     metadata jsonb null, -- To store additional data like food options, image URLs, etc.\n     -- Deprecated fields, kept for history but not actively used in new workflow:\n     message text null,\n     response text null,\n     image_url text null,\n     constraint sparky_chat_history_pkey primary key (id),\n     constraint sparky_chat_history_user_id_fkey foreign KEY (user_id) references auth.users (id)\n   ) TABLESPACE pg_default;\n     -- user_preferences table\n   create table public.user_preferences (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     date_format character varying(50) not null default 'yyyy-MM-dd',\n     default_weight_unit character varying(50) not null default 'kg',\n     default_measurement_unit character varying(50) not null default 'cm',\n     auto_clear_history text null default 'never', -- 'never', 'session', '7days', '30days'\n     system_prompt text null, -- User-specific override for AI system prompt\n     created_at timestamp with time zone not null default now(),\n     updated_at timestamp with time zone not null default now(),\n     constraint user_preferences_pkey primary key (id),\n     constraint user_preferences_user_id_fkey foreign KEY (user_id) references auth.users (id) on delete CASCADE,\n     constraint user_preferences_auto_clear_history_check check (\n       (\n         auto_clear_history = any (array['never'::text, 'session'::text, '7days'::text, '30days'::text])\n       )\n     )\n   ) TABLESPACE pg_default;\n     -- user_goals table\n   create table public.user_goals (\n     id uuid not null default gen_random_uuid (),\n     user_id uuid not null,\n     goal_date date null, -- Null for default goal\n     calories numeric null,\n     protein numeric null,\n     carbs numeric null,\n     fat numeric null,\n     water_goal integer null,\n     created_at timestamp with time zone null default now(),\n     updated_at timestamp with time zone null default now(),\n     saturated_fat numeric null, -- Added for comprehensive nutrition goals\n     polyunsaturated_fat numeric null,\n     monounsaturated_fat numeric null,\n     trans_fat numeric null,\n     cholesterol numeric null,\n     sodium numeric null,\n     potassium numeric null,\n     dietary_fiber numeric null,\n     sugars numeric null,\n     vitamin_a numeric null,\n     vitamin_c numeric null,\n     calcium numeric null,\n     iron numeric null,\n     constraint user_goals_pkey primary key (id),\n     constraint user_goals_user_id_fkey foreign KEY (user_id) references auth.users (id),\n     constraint user_goals_unique_user_date unique (user_id, goal_date) -- Ensure only one goal per user per date\n   ) TABLESPACE pg_default;\n  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":501,"path":502,"dir":482,"title":503,"description":504,"keywords":505,"body":513},"content:8.developer:8.advanced:3.rate-limiting.md","\u002Fdeveloper\u002Fadvanced\u002Frate-limiting","Rate Limiting Implementation","This document outlines the rate limiting strategy implemented for the SparkyFitness application, focusing on protecting sensitive authentication endpoints.",[506,507,508,509,510,511,512],"Purpose","Implementation Layer","Nginx Configuration","Endpoints Protected","Configuration","API Key Rate Limiting","Testing the Rate Limiting","  Rate Limiting Implementation  This document outlines the rate limiting strategy implemented for the SparkyFitness application, focusing on protecting sensitive authentication endpoints.  Purpose  Rate limiting is crucial for:    Preventing Brute-Force Attacks : Limiting the number of login attempts from a single IP address within a given time frame.   Mitigating Denial-of-Service (DoS) Attacks : Restricting the rate of requests to prevent server overload.   Preventing Account Creation Spam : Limiting the rate of new user registrations.   Protecting Password Reset Flows : Preventing abuse of email-based recovery mechanisms.   Securing MFA Endpoints : Limiting attempts to bypass multi-factor authentication.  Implementation Layer  Rate limiting is implemented at the   Nginx reverse proxy layer . This is the most efficient approach as it blocks malicious requests before they reach the backend Node.js application, conserving server resources.  Nginx Configuration  The rate limiting is configured in the   nginx.conf  file.  1. Client IP Detection  To correctly identify clients behind proxies or CDNs like Cloudflare, the configuration uses a chain of IP detection mechanisms:     # Trust docker gateway and Cloudflare IPs for real IP detection\n   set_real_ip_from 172.16.0.0\u002F12;  # Docker networks\n   set_real_ip_from 10.0.0.0\u002F8;      # Private networks\n   real_ip_header CF-Connecting-IP;\n   real_ip_recursive on;\n   \n   map $http_cf_connecting_ip $client_ip_from_cf {\n       \"\"      $binary_remote_addr;\n       default $http_cf_connecting_ip;\n   }\n   \n   map $http_x_real_ip $rate_limit_key {\n       \"\"      $client_ip_from_cf;\n       default $http_x_real_ip;\n   }\n  The detection priority is:    CF-Connecting-IP  header (Cloudflare)   X-Real-IP  header (other proxies)  Direct connection IP (  $binary_remote_addr )  2. Defining a Rate Limiting Zone  A shared memory zone named   auth_zone  is defined to track request rates based on client IP addresses:     limit_req_zone $rate_limit_key zone=auth_zone:10m rate=${NGINX_RATE_LIMIT};\n   limit_req_status 429;\n    $rate_limit_key : Uses the detected client IP address for tracking.   zone=auth_zone:10m : Defines a 10-megabyte shared memory zone.   rate=${NGINX_RATE_LIMIT} : Configurable rate limit (default:   5r\u002Fs ). Set to   10000r\u002Fs  to effectively disable rate limiting.   limit_req_status 429 : Explicitly returns HTTP 429 (Too Many Requests) when rate limited.  3. Applying the Rate Limit to Endpoints  The   limit_req  directive is applied to specific authentication endpoints within the   server  block.   Exact match endpoints:     # Apply rate limit to login endpoint\n   location = \u002Fapi\u002Fauth\u002Flogin {\n       limit_req zone=auth_zone burst=5 nodelay;\n       proxy_pass http:\u002F\u002F${SPARKY_FITNESS_SERVER_HOST}:${SPARKY_FITNESS_SERVER_PORT}\u002Fauth\u002Flogin;\n       # ... other proxy settings ...\n   }\n   \n   # Apply rate limit to register endpoint\n   location = \u002Fapi\u002Fauth\u002Fregister {\n       limit_req zone=auth_zone burst=5 nodelay;\n       proxy_pass http:\u002F\u002F${SPARKY_FITNESS_SERVER_HOST}:${SPARKY_FITNESS_SERVER_PORT}\u002Fauth\u002Fregister;\n       # ... other proxy settings ...\n   }\n   Regex match for MFA endpoints:     # Apply rate limit to all MFA endpoints\n   location ~ ^\u002Fapi\u002Fauth\u002Fmfa(\u002F.*)?$ {\n       limit_req zone=auth_zone burst=5 nodelay;\n       rewrite ^\u002Fapi\u002F(.*)$ \u002F$1 break;\n       proxy_pass http:\u002F\u002F${SPARKY_FITNESS_SERVER_HOST}:${SPARKY_FITNESS_SERVER_PORT};\n       # ... other proxy settings ...\n   }\n  Configuration parameters:    limit_req zone=auth_zone : Refers to the defined rate limiting zone.   burst=5 : Allows a burst of up to 5 requests beyond the defined rate.   nodelay : Requests exceeding the burst limit are immediately rejected with a   429 Too Many Requests  error, rather than being delayed.  Endpoints Protected  The following authentication endpoints are protected by Nginx rate limiting:     Endpoint  Purpose     \u002Fapi\u002Fauth\u002Flogin  User login    \u002Fapi\u002Fauth\u002Fregister  New user registration    \u002Fapi\u002Fauth\u002Fforgot-password  Password reset request    \u002Fapi\u002Fauth\u002Freset-password  Password reset completion    \u002Fapi\u002Fauth\u002Frequest-magic-link  Magic link request    \u002Fapi\u002Fauth\u002Fmagic-link-login  Magic link authentication    \u002Fapi\u002Fauth\u002Fmfa\u002F*  All MFA-related endpoints  Configuration  The rate limit can be configured via the   NGINX_RATE_LIMIT  environment variable in your Docker Compose configuration:     environment  :\n     -   NGINX_RATE_LIMIT=5r\u002Fs    # Default: 5 requests per second\n  To effectively disable rate limiting (e.g., for testing), set a very high value:     environment  :\n     -   NGINX_RATE_LIMIT=10000r\u002Fs\n  API Key Rate Limiting  In addition to Nginx rate limiting on auth endpoints,   API key authentication  has its own per-key rate limit enforced at the application layer by Better Auth.  Defaults     Setting  Value    Time window  60,000 ms (1 minute)   Max requests  100 per window  These defaults apply to all newly created API keys.  Configuration  The limits can be overridden via environment variables:     Variable  Description  Default     SPARKY_FITNESS_API_KEY_RATELIMIT_WINDOW_MS  Time window in milliseconds   60000    SPARKY_FITNESS_API_KEY_RATELIMIT_MAX_REQUESTS  Max requests per window   100  Behavior  When the rate limit is exceeded, the server returns:    HTTP 429  with   {\"error\": \"Rate limit exceeded.\"}  A   Retry-After  header indicating seconds until the window resets (at most 60s with default settings)  This rate limit is per API key, not per IP. Cookie-based browser sessions are not affected.  Testing the Rate Limiting  To test the rate limiting, ensure your Docker Compose environment is running with the updated   nginx.conf . Then, use   curl  to send a high volume of requests to the protected endpoints.  Example   curl  command (replace with your domain and adjust payload):     for   i   in   $(  seq   1   15  );   do   curl   -k   -s   -o   \u002Fdev\u002Fnull   -w   \"%{http_code}\\n\"   -X   POST   -H   \"Content-Type: application\u002Fjson\"   -d   '{\"email\":\"test@example.com\", \"password\":\"password\"}'   https:\u002F\u002Fyour-domain.com\u002Fapi\u002Fauth\u002Flogin   &   done\n  You should observe   429 Too Many Requests  HTTP status codes for requests exceeding the defined rate and burst limits.  Note on 503 Errors During Testing  During initial testing,   503 Service Unavailable  errors might be observed instead of   429 s. This indicates that Nginx is indeed applying the rate limit (as confirmed by Nginx error logs showing   limiting requests ), but it's also encountering issues connecting to or receiving timely responses from the backend server. While the rate limiting itself is functional, consistent   503 s suggest an underlying issue with the backend's stability or readiness under load, which is outside the scope of the rate limiting implementation itself.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":515,"path":516,"dir":482,"title":517,"description":518,"keywords":519,"body":520},"content:8.developer:8.advanced:4.translations.md","\u002Fdeveloper\u002Fadvanced\u002Ftranslations","Translations","This section will provide details on translations within SparkyFitness. This feature is planned for future development.",[],"  Translations  This section will provide details on translations within SparkyFitness. This feature is planned for future development.",{"id":522,"path":523,"dir":482,"title":524,"description":7,"keywords":525,"body":534},"content:8.developer:8.advanced:5.wger-integration-plan.md","\u002Fdeveloper\u002Fadvanced\u002Fwger-integration-plan","Wger Exercise Database Integration Plan",[526,527,528,529,530,531,532,533],"1. Introduction","2. Chosen Approach: Direct Wger API Integration","3. Architecture","4. Data Flow and Logic","5. Security Considerations","6. Refactoring Existing Data Providers","7. UI\u002FUX Considerations","8. Implementation Steps (High-Level)","  Wger Exercise Database Integration Plan  1. Introduction  This document outlines the plan for integrating the   wger  exercise database into the SparkyFitness application. The goal is to provide users with the ability to search for exercises from a comprehensive external database and add them to their personal exercise catalog, similar to how food data providers are integrated.  2. Chosen Approach: Direct Wger API Integration  After evaluating several options, direct integration with the   wger  REST API is the chosen approach due to its API-driven nature, potential for calorie information, rich data, and maintainability. This avoids the complexities of importing static data files and managing local copies of a large external database.  3. Architecture  The integration will involve modifications to the backend services, API routes, and frontend components.     graph TD\n       A[User Interface] --> B(Exercise Search Component)\n       B --> C{SparkyFitness Backend API}\n       C --> D[Existing Exercise Service]\n       C --> E[New Wger Exercise Service]\n       D --> F[SparkyFitness DB: User Exercises]\n       E --> G(Wger REST API)\n       E -- Cache Wger Responses --> H[Server-Side Cache]\n       B -- Add Selected Exercise --> D\n   Explanation of Components:    User Interface : The user interacts with an enhanced Exercise Search Component.   Exercise Search Component : This component will query the SparkyFitness Backend API for exercise search results.   SparkyFitness Backend API : This acts as a central point, routing requests to the appropriate services. It will handle authentication and authorization.   Existing Exercise Service : Handles operations related to exercises already in the user's personal database (  public.exercises  table).   New Wger Exercise Service : This service will be responsible for:\n   Making API calls to the   wger  REST API.  Handling search queries and fetching detailed exercise information.  Implementing server-side caching for   wger  API responses to improve performance and reduce redundant external calls.  Mapping   wger  data to SparkyFitness's   public.exercises  schema.   Wger REST API : The external source of exercise data (  https:\u002F\u002Fwger.de\u002Fapi\u002Fv2\u002F ).   Server-Side Cache : A mechanism (e.g., Redis, in-memory cache) to store   wger  API responses temporarily.   SparkyFitness DB: User Exercises : The existing   public.exercises  table, which will store user-specific exercises, including those imported from   wger .  4. Data Flow and Logic  4.1. Exercise Search   User types a search query in the frontend Exercise Search Component.  The frontend sends the query to a new backend API endpoint (e.g.,   \u002Fapi\u002Fexercises\u002Fsearch-external ).  The backend endpoint calls the   New Wger Exercise Service .  The   New Wger Exercise Service  queries the   wger  API (checking cache first).   wger  API returns exercise search results.  The   New Wger Exercise Service  processes the results, potentially filtering or reformatting them.  The backend API combines results from   wger  and potentially existing user exercises.  Results are returned to the frontend for display.  4.2. Adding a Wger Exercise to User's Catalog   User selects a   wger  exercise from the search results and clicks \"Add\".  The frontend sends a request to an existing or new backend API endpoint (e.g.,   \u002Fapi\u002Fexercises\u002Fadd-external ).  The backend endpoint calls the   Existing Exercise Service  (or a dedicated function within it).  The   Existing Exercise Service  retrieves the full details of the selected   wger  exercise from the   New Wger Exercise Service  (which may involve another   wger  API call or cache lookup).  The   Existing Exercise Service  maps the   wger  exercise data to the   public.exercises  table schema.    name : Mapped directly from   wger.name .   category : Mapped from   wger.category  (or a suitable default\u002Fderived category).   description : Mapped from   wger.description  or a summary of   wger.instructions .   is_custom : Set to   TRUE .   user_id : Extracted from the authenticated JWT.   source_external_id : A new column in   public.exercises  will store the   wger  exercise's unique ID. This will be a   TEXT  field.   calories_per_hour : Calculated using   wger 's MET value.  4.3. Calories Per Hour Calculation  The   wger  API provides a   met  (Metabolic Equivalent of Task) value for exercises. The   calories_per_hour  will be calculated using the following formula:   Calories Burned per Minute = (METs * 3.5 * Body Weight in kg) \u002F 200  Calories Burned per Hour = Calories Burned per Minute * 60   Body Weight Source Priority:    User's Latest Check-in Weight : The system will attempt to retrieve the user's most recent weight from the   public.check_in_measurements  table.   Standard Average Body Weight : If the user has no recorded check-in weight, a standard average body weight (e.g., 70 kg or 154 lbs) will be used as a fallback.  5. Security Considerations    Authentication : All new backend API endpoints will be protected by JWT authentication. The   user_id  will always be extracted from the authenticated token and will   not  be passed directly as a parameter in requests.   Authorization : Ensure that only authenticated users can add exercises to their catalog.  6. Refactoring Existing Data Providers  To generalize the concept of external data sources, the existing   food_data_providers  will be refactored.    Renaming : The   food_data_providers  table, related files, and code references will be renamed to a more generic term, such as   external_data_providers  or   api_integrations .   Scope : This refactoring will encompass both backend and frontend codebases to ensure consistency.   Impact : This change will allow the system to manage various types of external data providers (food, exercise, etc.) under a unified structure.  7. UI\u002FUX Considerations   The frontend exercise search component will be enhanced to display results from both existing user exercises and   wger  exercises.  The UI will follow existing patterns, particularly those established by the food search and add components (e.g.,   EnhancedFoodSearch.tsx ), to ensure a consistent and intuitive user experience.  8. Implementation Steps (High-Level)   Create   docs\u002Fwger-integration-plan.md  (this document).  Analyze existing food provider architecture for generalization.  Plan refactoring of   food_data_providers  to a generic name.  Execute refactoring of data providers (rename tables, files, update code).  Add   source_external_id  column to   public.exercises  table.  Implement new backend service to interact with the   wger  API (search, fetch details, caching).  Create new API endpoint for   wger  exercise search (ensuring JWT for user_id).  Enhance frontend exercise search component (to query both existing and   wger  exercises).  Implement logic to add   wger  exercise to user's   public.exercises  table (mapping fields including calories, using user's latest weight or average if not available).  Test end-to-end functionality.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":536,"path":537,"dir":391,"title":538,"description":539,"keywords":540,"body":549},"content:8.developer:9.translations.md","\u002Fdeveloper\u002Ftranslations","Internationalization (i18n) Setup in SparkyFitnessFrontend","This document outlines the setup for internationalization (i18n) in the SparkyFitnessFrontend application using i18next and react-i18next.",[541,542,543,544,545,546,547,548],"1. Core Libraries","2. Translation File Structure","3. i18next Configuration (src\u002Fi18n.ts)","4. Integration into React Application (src\u002Fmain.tsx)","5. Language Handling Component (src\u002Fcomponents\u002FLanguageHandler.tsx)","6. Using Translations in Components","7. Language Switcher in Settings (src\u002Fcomponents\u002FSettings.tsx)","8. Adding New Languages","  Internationalization (i18n) Setup in SparkyFitnessFrontend  This document outlines the setup for internationalization (i18n) in the SparkyFitnessFrontend application using   i18next  and   react-i18next .  1. Core Libraries  The following npm packages are used for i18n:    i18next : The core i18n library.   react-i18next : Integration for React applications.   i18next-browser-languagedetector : Detects the user's language from the browser.   i18next-http-backend : Loads translation files over HTTP.  These dependencies are installed in the   SparkyFitnessFrontend  directory.  2. Translation File Structure  Translation files are stored in the   public\u002Flocales  directory, following the format   public\u002Flocales\u002F{{languageCode}}\u002Ftranslation.json .    public\u002Flocales\u002Fen\u002Ftranslation.json : Contains English translations.   public\u002Flocales\u002Fta\u002Ftranslation.json : Contains Tamil translations.  Each   translation.json  file is a simple JSON object where keys represent translation identifiers and values are the translated strings. Nested objects can be used to organize translations (e.g.,   \"nav.diary\" ).  Example (  translation.json ):     {\n     \"nav\"  : {\n       \"diary\"  :   \"Diary\"  ,\n       \"checkin\"  :   \"Check-In\"\n     },\n     \"settings\"  : {\n       \"profileInformation\"  : {\n         \"title\"  :   \"Profile Information\"\n       }\n     }\n   }\n  3. i18next Configuration (  src\u002Fi18n.ts )  The   i18next  instance is configured in    SparkyFitnessFrontend\u002Fsrc\u002Fi18n.ts .     import   i18n   from   'i18next'  ;\n   import   { initReactI18next }   from   'react-i18next'  ;\n   import   LanguageDetector   from   'i18next-browser-languagedetector'  ;\n   import   HttpApi   from   'i18next-http-backend'  ;\n   \n   i18n\n     .  use  (HttpApi)\n     .  use  (LanguageDetector)\n     .  use  (initReactI18next)\n     .  init  ({\n       supportedLngs: [  'en'  ,   'ta'  ],   \u002F\u002F List of supported languages\n       fallbackLng:   'en'  ,   \u002F\u002F Fallback language if a translation is missing\n       detection: {\n         order: [  'localStorage'  ,   'querystring'  ,   'cookie'  ,   'sessionStorage'  ,   'navigator'  ,   'htmlTag'  ],\n         caches: [  'localStorage'  ,   'cookie'  ],\n       },\n       backend: {\n         loadPath:   '\u002Flocales\u002F{{lng}}\u002F{{ns}}.json'  ,   \u002F\u002F Path to load translation files\n       },\n       react: {\n         useSuspense:   false  ,   \u002F\u002F Set to true if you want to use React.Suspense for loading translations\n       },\n     });\n   \n   export   default   i18n;\n   Key Configuration Details:    supportedLngs : An array of language codes that your application supports.   fallbackLng : The language to use if a translation for the current language is missing.   detection.order : Specifies the order in which   i18next  tries to detect the user's language.   localStorage  is prioritized to use the user's saved preference.   backend.loadPath : The URL pattern to fetch translation files.   {{lng}}  is replaced by the current language code, and   {{ns}}  by the namespace (defaulting to   translation ).   react.useSuspense : Set to   false  to avoid using React's Suspense feature for translations, simplifying initial setup.  4. Integration into React Application (  src\u002Fmain.tsx )  The   i18next  instance is initialized and provided to the React application in    SparkyFitnessFrontend\u002Fsrc\u002Fmain.tsx .     import   { createRoot }   from   'react-dom\u002Fclient'\n   import   App   from   '.\u002FApp.tsx'\n   import   '.\u002Findex.css'\n   import   { BrowserRouter }   from   'react-router-dom'  ;\n   import   { AuthProvider }   from   '.\u002Fhooks\u002FuseAuth.tsx'  ;\n   import   '.\u002Fi18n'  ;   \u002F\u002F Import the i18n configuration\n   import   { Suspense }   from   'react'  ;\n   \n   createRoot  (document.  getElementById  (  \"root\"  )  !  ).  render  (\n     \u003C  Suspense fallback  =  \"loading\"  >\n       \u003C  BrowserRouter  >\n         \u003C  AuthProvider  >\n           \u003C  App   \u002F>\n         \u003C\u002F  AuthProvider  >\n       \u003C\u002F  BrowserRouter  >\n     \u003C\u002F  Suspense  >\n   );\n  The   Suspense  component is used to display a fallback (e.g., \"loading\") while translations are being loaded.  5. Language Handling Component (  src\u002Fcomponents\u002FLanguageHandler.tsx )  A dedicated component,    SparkyFitnessFrontend\u002Fsrc\u002Fcomponents\u002FLanguageHandler.tsx , is used to synchronize the   i18next  language with the user's preference stored in the   PreferencesContext .     import   { useEffect }   from   'react'  ;\n   import   { useTranslation }   from   'react-i18next'  ;\n   import   { usePreferences }   from   '@\u002Fcontexts\u002FPreferencesContext'  ;\n   \n   const   LanguageHandler   =   ()   =>   {\n     const   {   i18n   }   =   useTranslation  ();\n     const   {   language   }   =   usePreferences  ();\n   \n     useEffect  (()   =>   {\n       if   (language) {\n         i18n.  changeLanguage  (language);\n       }\n     }, [language, i18n]);\n   \n     return   null  ;   \u002F\u002F This component doesn't render anything\n   };\n   \n   export   default   LanguageHandler;\n  This component ensures that when the   language  preference changes (e.g., via the language switcher in settings),   i18next  updates its active language.  6. Using Translations in Components  To use translations in any React component, import the   useTranslation  hook from   react-i18next .     import   { useTranslation }   from   'react-i18next'  ;\n   \n   const   MyComponent   =   ()   =>   {\n     const   {   t   }   =   useTranslation  ();\n   \n     return   (\n       \u003C  div  >\n         \u003C  h1  >{  t  (  'nav.diary'  )}  \u003C\u002F  h1  >\n         \u003C  p  >{  t  (  'settings.profileInformation.description'  )}  \u003C\u002F  p  >\n       \u003C\u002F  div  >\n     );\n   };\n  The   t  function takes a translation key (e.g.,   \"nav.diary\" ) and returns the corresponding translated string for the currently active language.  7. Language Switcher in Settings (  src\u002Fcomponents\u002FSettings.tsx )  The language switcher is integrated into the   Preferences  section of the   Settings  component. It uses the   language  state and   setLanguage  function from   PreferencesContext  to update the user's preferred language.     \u002F\u002F Inside Settings.tsx\n   import   { useTranslation }   from   \"react-i18next\"  ;\n   import   { usePreferences }   from   \"@\u002Fcontexts\u002FPreferencesContext\"  ;\n   \u002F\u002F ... other imports\n   \n   const   Settings  :   React  .  FC  \u003C  SettingsProps  >   =   ({   onShowAboutDialog   })   =>   {\n     const   {   t   }   =   useTranslation  ();\n     const   {   language  ,   setLanguage   }   =   usePreferences  ();\n     \u002F\u002F ... other state and functions\n   \n     \u002F\u002F Inside the Preferences AccordionContent\n     \u003C  div  >\n       \u003C  Label htmlFor  =  \"language\"  >  {  t  (  'settings.preferences.language'  )}  \u003C\u002F  Label  >\n       \u003C  Select\n         value  =  {language}\n         onValueChange  =  {setLanguage}\n       >\n         \u003C  SelectTrigger  >\n           \u003C  SelectValue   \u002F>\n         \u003C\u002F  SelectTrigger  >\n         \u003C  SelectContent  >\n           \u003C  SelectItem value  =  \"en\"  >  English  \u003C\u002F  SelectItem  >\n           \u003C  SelectItem value  =  \"ta\"  >  தமிழ்  \u003C\u002F  SelectItem  >\n         \u003C\u002F  SelectContent  >\n       \u003C\u002F  Select  >\n     \u003C\u002F  div  >\n     \u002F\u002F ...\n   };\n  8. Adding New Languages  To add a new language (e.g., Spanish -   es ):    Create Translation File:  Create a new JSON file:   public\u002Flocales\u002Fes\u002Ftranslation.json .   Add Translations:  Populate   translation.json  with Spanish translations for all keys used in the application.   Update   i18n.ts :  Add   'es'  to the   supportedLngs  array in    SparkyFitnessFrontend\u002Fsrc\u002Fi18n.ts .   Update Language Switcher:  Add a new   SelectItem  for Spanish in the language switcher within    SparkyFitnessFrontend\u002Fsrc\u002Fcomponents\u002FSettings.tsx .   Backend Update (if applicable):  If you want to store the language preference in the backend, ensure the   user_preferences  table and associated API endpoints can handle the new language code.  By following these steps, you can easily extend the application to support additional languages.  html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"id":551,"path":552,"dir":553,"title":554,"description":555,"keywords":556,"body":558},"content:8.developer:10.mcp:0.dev.md","\u002Fdeveloper\u002Fmcp\u002Fdev","mcp","Development and Debugging Tools","Utility tools for developers to inspect the database, check server status, and run internal tests.",[557],"Tools within Development","  Development and Debugging Tools (  devTools )  The   devTools  are a collection of utility functions designed to aid developers in inspecting the system, debugging issues, and performing internal tasks. These tools provide access to database schema, user information, and server stats.   Tool Name:    devTools  (Note: This is a collection of tools, not a single one)  Tools within Development   inspect_schema    Description:  Inspect the database schema to understand available tables and columns.   Parameters:    table  (string): Name of the table to inspect (e.g.,   foods ,   exercise_entries ).   get_user_info    Description:  Get information about the current test user being used by MCP.   Parameters:  None.   get_db_stats    Description:  Get current database connection stats (DB Name, User, Search Path).   Parameters:  None.   log_food_direct    Description:  Emergency tool to log food by bypassing internal configuration. This is primarily for direct debugging and data insertion.   Parameters:    userId  (string or number): The ID of the user.   foodName  (string): The name of the food.   mealType  (string, optional): The meal type (e.g., 'dinner').   run_project_tests    Description:  Run the project's test suite to verify changes.   Parameters:  None.",{"id":560,"path":561,"dir":553,"title":562,"description":563,"keywords":564,"body":566},"content:8.developer:10.mcp:1.food.md","\u002Fdeveloper\u002Fmcp\u002Ffood","Food Management Tool","Comprehensive tool for tracking and managing dietary intake.",[565],"Actions","  Food Management Tool (  manage_food )  The   manage_food  tool is the primary interface for all nutrition tracking and management within SparkyFitness. It allows users and AI agents to search for food, log meals, create custom food items, and manage their daily food diary.   Tool Name:    manage_food   Description:  Primary tool for nutrition tracking. Use this to search for food, log meals, create custom food items, and manage your daily diary. Supports multi-turn conversations where you provide details one by one.  Actions  The   manage_food  tool supports the following actions:   search_food    Description:  Search for existing food items in the database.   Parameters:    food_name  (string): The name of the food item to search for.   search_type  (enum: \"exact\", \"broad\"): The type of search to perform.   log_food    Description:  Logs a food item to your daily diary. Handles both existing and new food items.   Parameters:    food_name  (string): The name of the food item.   food_id  (string, optional): UUID of the food item (if known).   variant_id  (string, optional): UUID of the food variant (if known).   quantity  (number): The amount consumed.   unit  (string): The unit of measurement (e.g., 'g', 'piece', 'serving').   meal_type  (string): The meal timeframe (e.g., 'breakfast', 'lunch', 'dinner', 'snacks').   entry_date  (string, YYYY-MM-DD): The date of the record.   Special Handling for Unknown Foods:  If   food_name  is not found, the AI will be instructed to infer nutritional details and create the food via   create_food  before re-attempting to log.   create_food    Description:  Creates a new custom food item in the database with its nutritional information.   Parameters:    food_name  (string): The name of the new food item.   brand  (string, optional): The brand name of the food.   macros  (object): Nutritional information for the food.\n    calories  (number)   protein  (number)   carbs  (number)   fat  (number)   saturated_fat  (number)   polyunsaturated_fat  (number)   monounsaturated_fat  (number)   trans_fat  (number)   cholesterol  (number)   sodium  (number)   potassium  (number)   fiber  (number)   sugar  (number)   vitamin_a  (number)   vitamin_c  (number)   calcium  (number)   iron  (number)   gi  (string, enum: \"None\", \"Very Low\", \"Low\", \"Medium\", \"High\", \"Very High\")   quantity  (number, optional): The default serving size value.   unit  (string, optional): The default serving size unit.   search_meal    Description:  Search for existing meal templates.   Parameters:    meal_name  (string): The name of the meal template to search for.   log_meal    Description:  Logs a predefined meal template to your daily diary.   Parameters:    meal_id  (string, optional): UUID of the meal template (if known).   meal_name  (string, optional): Name of the meal template (alternative to ID).   meal_type  (string): The meal timeframe.   entry_date  (string, YYYY-MM-DD): The date of the record.   quantity  (number, optional): Multiplier for the meal template.   unit  (string, optional): Unit for the meal template multiplier.   list_diary    Description:  Retrieves all logged food and meal entries for a specific date.   Parameters:    entry_date  (string, YYYY-MM-DD, optional): The date to retrieve the diary for. Defaults to today.   delete_entry    Description:  Deletes a specific food or meal entry from the diary.   Parameters:    entry_id  (string): UUID of the entry to delete.   entry_type  (enum: \"food_entry\", \"food_entry_meal\"): The type of entry.   update_entry    Description:  Updates the quantity or unit of an existing food or meal entry.   Parameters:    entry_id  (string): UUID of the entry to update.   entry_type  (enum: \"food_entry\", \"food_entry_meal\"): The type of entry.   quantity  (number): The new amount.   unit  (string): The new unit of measurement.   copy_from_yesterday    Description:  Copies all food entries from a source date (defaults to yesterday) to a target date (defaults to today) for a specific meal type.   Parameters:    target_date  (string, YYYY-MM-DD, optional): The date to copy entries to.   source_date  (string, YYYY-MM-DD, optional): The date to copy entries from.   meal_type  (string, optional): The specific meal type to copy (e.g., 'breakfast').   save_as_meal_template    Description:  Saves a set of food entries from a specific date and meal type as a new reusable meal template.   Parameters:    entry_date  (string, YYYY-MM-DD): The date from which to save entries.   meal_type  (string): The meal type to save (e.g., 'lunch').   meal_name  (string): The name for the new meal template.   description  (string, optional): A description for the meal template.",{"id":568,"path":569,"dir":553,"title":570,"description":571,"keywords":572,"body":573},"content:8.developer:10.mcp:2.exercise.md","\u002Fdeveloper\u002Fmcp\u002Fexercise","Exercise Management Tool","Tool for tracking fitness activities and managing workouts.",[565],"  Exercise Management Tool (  manage_exercise )  The   manage_exercise  tool is designed for comprehensive fitness tracking. It allows users and AI agents to search for exercises, log workouts (with multi-set support), manage routines, and view exercise history. If an exercise is not found, it can be automatically created.   Tool Name:    manage_exercise   Description:  Primary tool for fitness tracking. Use this to search for exercises, log workouts (multi-set support), manage routines, and view your exercise history. If an exercise is missing, it will be automatically created. Supports providing details across multiple turns.  Actions  The   manage_exercise  tool supports the following actions:   search_exercises    Description:  Searches for existing exercise definitions.   Parameters:    searchTerm  (string): Name or part of exercise name.   muscleGroup  (string, optional): Muscle group to filter by (e.g., \"Chest\", \"Biceps\").   equipment  (string, optional): Equipment to filter by (e.g., \"Dumbbell\", \"None\").   create_exercise    Description:  Creates a new exercise definition.   Parameters:    name  (string): Full name for a new exercise.   category  (string, optional): Category (e.g., \"Strength\", \"Cardio\").   calories_per_hour  (number, optional): Estimated calories burned per hour.   description  (string, optional): Description of the exercise.   log_exercise    Description:  Logs an exercise performed by the user, including sets and reps if applicable.   Parameters:    exercise_id  (string, optional): UUID of the exercise.   exercise_name  (string, optional): Name of the exercise to log (alternative to ID).   entry_date  (string, YYYY-MM-DD): The date the exercise was performed.   duration_minutes  (number, optional): Duration of the exercise in minutes.   calories_burned  (number, optional): Calories burned during the exercise.   notes  (string, optional): Any additional notes for the exercise.   sets  (array of objects, optional): Details for multiple sets (e.g., for strength training).\n   Each set object includes:   reps  (number),   weight  (number, kg),   duration  (number, seconds),   rest_time  (number, seconds),   set_type  (enum: \"Working Set\", \"Warmup\", \"Drop Set\", \"Failure\").   list_exercise_diary    Description:  Retrieves all logged exercise entries for a specific date, representing the user's exercise history.   Parameters:    entry_date  (string, YYYY-MM-DD): The date to retrieve the exercise diary for.   get_workout_presets    Description:  Retrieves a list of available workout presets\u002Froutines.   Parameters:  None.   log_workout_preset    Description:  Logs a predefined workout preset to the user's exercise diary.   Parameters:    preset_id  (string, optional): UUID of the workout preset.   preset_name  (string, optional): Name of the preset to log (alternative to ID).   entry_date  (string, YYYY-MM-DD): The date the preset was performed.   delete_exercise_entry    Description:  Deletes a specific exercise entry from the user's diary.   Parameters:    entry_id  (string): UUID of the exercise entry to delete.",{"id":575,"path":576,"dir":553,"title":577,"description":578,"keywords":579,"body":580},"content:8.developer:10.mcp:3.checkin.md","\u002Fdeveloper\u002Fmcp\u002Fcheckin","Health Check-in Management Tool","Tool for logging and tracking various health metrics including biometrics, mood, sleep, and fasting.",[565],"  Health Check-in Management Tool (  manage_checkin )  The   manage_checkin  tool is a primary interface for logging and tracking various health metrics. It allows users and AI agents to record biometrics (weight, steps, measurements), custom health metrics, mood, sleep, and fasting windows.   Tool Name:    manage_checkin   Description:  Primary tool for health tracking. Use this to log your WEIGHT, daily step count, height, body measurements (waist, neck, hips), mood, sleep duration\u002Fquality, and fasting windows. Supports providing health details across multiple turns.  Actions  The   manage_checkin  tool supports the following actions:   log_biometrics    Description:  Logs or updates various biometric measurements for a given date.   Parameters:    entry_date  (string, YYYY-MM-DD): The date of the record.   weight  (number, optional): Weight value.   weight_unit  (enum: \"kg\", \"lbs\", \"lb\", \"g\", optional): Unit for weight (defaults to kg).   steps  (number, optional): Daily step count.   height  (number, optional): Height value.   height_unit  (enum: \"cm\", \"in\", \"inch\", \"ft\", optional): Unit for height.   neck  (number, optional): Neck measurement.   waist  (number, optional): Waist measurement.   hips  (number, optional): Hips measurement.   measurements_unit  (enum: \"cm\", \"in\", \"inch\", optional): Unit for body measurements.   body_fat  (number, optional): Body fat percentage.   log_custom_metric    Description:  Logs a value for a user-defined custom health category.   Parameters:    category_name  (string): Name of the custom category (e.g., \"Blood Pressure\").   value  (string or number): The value to record.   unit  (string, optional): Unit for the recorded value.   notes  (string, optional): Optional notes for the entry.   entry_date  (string, YYYY-MM-DD): The date of the record.   list_categories    Description:  Lists all user-defined custom health categories.   Parameters:  None.   create_category    Description:  Creates a new custom health category for logging.   Parameters:    category_name  (string): Name of the custom category.   unit  (string, optional): Unit for the new category.   log_mood    Description:  Logs the user's mood for a specific date.   Parameters:    mood_value  (number): Mood score (typically 1-10).   notes  (string, optional): Optional notes about the mood.   entry_date  (string, YYYY-MM-DD): The date of the record.   log_fasting    Description:  Logs a fasting window.   Parameters:    start_time  (string, ISO 8601): Start timestamp of the fasting window.   end_time  (string, ISO 8601, optional): End timestamp of the fasting window.   fasting_status  (enum: \"ACTIVE\", \"COMPLETED\", \"CANCELLED\", optional): Current status of the fast.   fasting_type  (string, optional): Type of fasting (e.g., \"Intermittent\").   log_sleep    Description:  Logs sleep details for a given date.   Parameters:    entry_date  (string, YYYY-MM-DD): The date of the sleep entry.   duration_seconds  (number, optional): Total sleep duration in seconds.   sleep_score  (number, optional): Sleep quality score (0-100).   bedtime  (string, ISO 8601, optional): Bedtime timestamp.   wake_time  (string, ISO 8601, optional): Wake up timestamp.   source  (string, optional): Source of data (e.g., \"manual\", \"Garmin\", \"Fitbit\").   list_checkin_diary    Description:  Retrieves all logged health check-in entries (biometrics, mood, sleep, custom metrics) for a specific date.   Parameters:    entry_date  (string, YYYY-MM-DD, optional): The date to retrieve the diary for. Defaults to today.",{"id":582,"path":583,"dir":553,"title":584,"description":585,"keywords":586,"body":588},"content:8.developer:10.mcp:4.coach.md","\u002Fdeveloper\u002Fmcp\u002Fcoach","Coaching and Trends Tool","Provides health summaries and analyzes long-term trends for coaching insights.",[587],"Tools within Coach","  Coaching and Trends Tool (  coachTools )  The   coachTools  are designed to provide high-level insights into a user's health status and long-term trends. It aggregates data from various sources (food, exercise, check-ins) to offer summaries and identify patterns relevant for health coaching.   Tool Name:    coachTools  (Note: This is a collection of tools, not a single one)  Tools within Coach   get_health_summary    Description:  Get a summary of the user's health status (Nutrition, Fitness, Vitals) for a specific date range.   Parameters:    start_date  (string, YYYY-MM-DD): Start date for the summary.   end_date  (string, YYYY-MM-DD, optional): End date for the summary. Defaults to   start_date  if not provided.   analyze_trends    Description:  Analyze weight trends vs. calorie intake to identify plateaus or progress. (Feature coming in full Phase 3 implementation!)   Parameters:    days  (number, optional): Number of days to analyze. Defaults to 7.   get_30_day_trends    Description:  Get comprehensive trends for the last 30 days including food, exercise, mood, sleep, and biometrics. This tool gathers aggregated data across these domains to provide a holistic view of the user's progress and patterns.   Parameters:    end_date  (string, YYYY-MM-DD, optional): End date for the 30-day period. Defaults to today.",{"id":590,"path":591,"dir":553,"title":592,"description":593,"keywords":594,"body":596},"content:8.developer:10.mcp:5.engagement.md","\u002Fdeveloper\u002Fmcp\u002Fengagement","Engagement and Nudge Tool","Tools for proactive user engagement, streak tracking, and contextual nudges.",[595],"Tools within Engagement","  Engagement and Nudge Tool (  proactiveTools )  The   proactiveTools  are designed to enhance user engagement through automated triggers, streak tracking, and context-aware nudges. These tools help to motivate users and provide timely, relevant feedback.   Tool Name:    proactiveTools  (Note: This is a collection of tools, not a single one)  Tools within Engagement   check_engagement_triggers    Description:  Scans the user's data for moments that require a proactive nudge (e.g., missed workout, plateau, achievement).   Parameters:    user_id  (string): The ID of the user to check. Defaults to   MOCK_USER_ID .   get_logging_streak    Description:  Retrieves the user's current consecutive logging streak for any health or fitness data.   Parameters:  None. (Note: Logic for streak calculation is a feature coming soon!)   get_contextual_nudge    Description:  Generates a context-aware nudge based on recent user activity or inactivity.   Parameters:  None. (Note: Logic for contextual nudge generation is a feature coming soon!)",{"id":598,"path":599,"dir":553,"title":600,"description":601,"keywords":602,"body":604},"content:8.developer:10.mcp:6.vision.md","\u002Fdeveloper\u002Fmcp\u002Fvision","Vision Integration Tools","Tools for analyzing images, such as food photos and nutrition labels.",[603],"Tools within Vision","  Vision Integration Tools (  visionTools )  The   visionTools  are designed to integrate computer vision capabilities into the SparkyFitness platform. These tools will enable the analysis of images, such as food photos for nutritional estimation and nutrition labels for data extraction.   Tool Name:    visionTools  (Note: This is a collection of tools, not a single one)  Tools within Vision   analyze_food_image    Description:  Analyzes an image of food to estimate its nutritional content. This tool will connect with advanced vision models (e.g., Gemini\u002FGPT-4o Vision) to provide macro and calorie estimations from visual data.   Parameters:    image_url  (string): Base64 encoded image data or a URL of the food image to be analyzed.   scan_label    Description:  Scans a nutrition label from an image to extract detailed nutritional information. This tool will utilize OCR and structured data extraction techniques to parse data from food packaging labels.   Parameters:    image_url  (string): Base64 encoded image data or a URL of the nutrition label image to be scanned.",{"id":606,"path":607,"dir":7,"title":608,"description":609,"keywords":610,"body":611},"content:8.support-the-project.md","\u002Fsupport-the-project","Support The Project","You can support the SparkyFitness project by actively engaging with it. This includes:",[],"  Support The Project  You can support the SparkyFitness project by actively engaging with it. This includes:    Raising Enhancement Requests : Share your ideas for new features or improvements to existing ones. Your suggestions help us evolve the product.   Reporting Issues : If you encounter any bugs or unexpected behavior, please report them. Detailed issue reports are crucial for identifying and fixing problems, ensuring a better experience for everyone.  You can submit both enhancement requests and bug reports on our GitHub Issues page:   https:\u002F\u002Fgithub.com\u002FCodeWithCJ\u002FSparkyFitness\u002Fissues  Your feedback is invaluable in helping us improve SparkyFitness for the entire community.",{"id":613,"path":614,"dir":7,"title":615,"description":616,"keywords":617,"body":627},"content:9.privacy_policy.md","\u002Fprivacy_policy","Privacy Policy","SparkyFitness is committed to protecting your privacy. This Privacy Policy explains how information is handled when you use the SparkyFitness mobile application.",[8,618,619,620,621,622,623,624,625,626],"Data Collection and Handling","How Your Information Is Used","Data Storage and Security","Data Retention and Deletion","Third-Party Services","Children’s Privacy","Limitation of Liability","Changes to This Privacy Policy","Contact Us","  Privacy Policy  SparkyFitness is committed to protecting your privacy. This Privacy Policy explains how information is handled when you use the SparkyFitness mobile application.  Overview  SparkyFitness is designed with a privacy-first architecture. The app does not collect, store, or process personal or health data on SparkyFitness-operated servers. All data remains under your control on your device and, if configured by you, on your own self-hosted SparkyFitness server.  Data Collection and Handling  Information You Provide and Control    Self-Hosted Server Connection Information:  If you choose to enable synchronization with a self-hosted SparkyFitness server, the app stores your server URL and authentication token   locally on your device . This information is used only to connect to your server and is never transmitted to SparkyFitness or any third party.   Health Data:  With your explicit permission, the app may access health data provided by platform services such as Apple Health or Google Health Connect. This data is:   Accessed only for app functionality  Stored locally on your device  Synced only to your self-hosted SparkyFitness server, if configured  SparkyFitness does not receive, store, or process this data.   Camera:  Sparky accesses your device's camera for two purposes: (1) scanning barcodes on food packaging, which is decoded entirely on your device — no image is transmitted, and (2) capturing nutrition label photos, which are transmitted to your Sparky server only when you have enabled this optional feature.   AI-Powered Nutrition Label Scanning:  This feature is disabled by default. When you enable it, nutrition label images are sent from your device to your Sparky server, which then forwards them to a cloud AI provider you have configured on the server (e.g., OpenAI, Google, Anthropic). Your AI provider credentials are never stored on your mobile device. The mobile app has no knowledge of which AI provider is configured.   Your Server is Yours:  Because Sparky is self-hosted, your server's data handling, retention, and AI provider choices are governed by your own configuration and the privacy policies of any AI provider you choose to integrate. We do not have access to your server or its data.  Information We Do Not Collect    Personal identifiers  (name, email, address, etc.)   Health or fitness data  on SparkyFitness servers   Usage analytics  or tracking data   Advertising identifiers   Device or network identifiers  How Your Information Is Used  All data handled by the app is used solely to provide core functionality, including displaying fitness information and synchronizing with your self-hosted server. We do not sell, rent, share, or monetize user data in any way.  Data Storage and Security   Data is stored   locally on your device  using platform-provided security mechanisms.  If enabled, data is transmitted directly to your   self-hosted server .  SparkyFitness does not operate or have access to these servers.  Data Retention and Deletion  SparkyFitness does not retain user data on developer-operated servers.  On-device data   Health data and configuration data are stored locally on the user’s device.  This data is retained only for as long as the app remains installed or until the user deletes it.  Deleting data   Users can delete all locally stored data at any time by clearing the app’s data or uninstalling the SparkyFitness app from their device.  Once the app is uninstalled, all locally stored data is permanently removed from the device.  User Self-hosted server data   If the user enables synchronization, health data is stored on the user’s own self-hosted SparkyFitness server.  Data retention and deletion on the self-hosted server are fully controlled by the user.  Users can delete their server-side data at any time by removing it from their self-hosted SparkyFitness server.  SparkyFitness does not have access to, cannot delete, and does not retain any user data stored on user-managed servers.  Third-Party Services  SparkyFitness does not use third-party analytics, advertising, or tracking services. Any data stored on your self-hosted server is governed by your own server configuration and security practices.  Children’s Privacy  SparkyFitness is not intended for children under the age of 13. We do not knowingly collect personal information from children.  Limitation of Liability  The SparkyFitness mobile application is provided \"as is,\" without warranty of any kind, express or implied. The developer of SparkyFitness shall not be liable for any damages, direct or indirect, arising from the use or inability to use the application, including but not limited to data loss, system errors, or any other issues that may arise.  Users are solely responsible for the security and integrity of their self-hosted SparkyFitness server and any data stored thereon. The developer is not responsible for any breaches, data loss, or other security incidents that may occur on a user's self-hosted server.  Changes to This Privacy Policy  Developer reserves the right to change or modify this Privacy Policy at any time, and any changes will be effective upon being posted unless otherwise indicated. You are encouraged to periodically review this policy for the latest information on privacy practices. If you do not accept the terms of this Privacy Policy, you are asked to discontinue using SparkyFitness.  Contact Us  If you have any questions about this Privacy Policy, please contact us at:   codewithcj001@gmail.com",1779989344945]