Skip to content

Repository files navigation

FitTrack Pro

FitTrack Pro is a Next.js fitness tracking application that combines Supabase authentication and persistence with AI-generated workout and meal plans.

Features

  • Email and password authentication with email verification
  • Fitness profile and TDEE calculation
  • Daily water intake tracking
  • Personalized workout generation and completed-workout tracking
  • Personalized daily meal-plan generation
  • Weekly progress summaries

Tech Stack

  • Next.js 15, React 19, and TypeScript
  • Tailwind CSS 4
  • Supabase Authentication, Database, and Realtime
  • OpenAI API
  • Node.js built-in test runner

Prerequisites

  • Node.js 20 or newer
  • A Supabase project with the tables expected by the application
  • An OpenAI API key for workout and meal-plan generation

The versioned Supabase schema in supabase/migrations defines the application tables, constraints, indexes, and Row Level Security policies. Browser database access relies on those policies being applied to every environment.

Local Setup

  1. Install dependencies:

    npm install
  2. Create a local environment file from the documented template:

    cp .env.example .env.local
  3. Fill in .env.local with your Supabase project values, application URL, and server-only OpenAI API key.

  4. Start the development server:

    npm run dev
  5. Open http://localhost:3000.

Environment Variables

Variable Scope Purpose
NEXT_PUBLIC_SUPABASE_URL Browser and server Supabase project URL
NEXT_PUBLIC_SUPABASE_ANON_KEY Browser and server Supabase anonymous key; requires appropriate Row Level Security
NEXT_PUBLIC_SITE_URL Browser and server Application origin used for authentication redirects
NEXT_APP_OPENAI_API_KEY Server only OpenAI credential used to generate workouts and meal plans
E2E_AUTH_EMAIL Local/CI test runner only Optional dedicated Supabase test-user email for authenticated Playwright flows
E2E_AUTH_PASSWORD Local/CI test runner only Optional dedicated Supabase test-user password for authenticated Playwright flows
E2E_MOCK_AI Local/CI test runner only Set to 1 to make authenticated generation E2E tests use deterministic workout and meal-plan fixtures instead of OpenAI

Never commit .env.local or real credentials. The checked-in .env.example contains placeholders only.

Validate required local or deployment variables without printing secret values:

npm run env:check

Authentication Redirects

Add the deployed application origin and /auth/confirm callback to the Supabase Authentication URL configuration. Password recovery sends users through /auth/confirm?next=/reset-password; the callback verifies either PKCE codes or email OTP token hashes and only permits local redirect paths.

Observability and Operations

The app exposes lightweight operational endpoints:

  • GET /api/health returns a non-sensitive uptime payload for load balancers and external monitors.
  • GET /api/readiness verifies required environment variable names are configured and returns 503 when configuration is incomplete. It reports missing variable names only and never returns secret values.

Server-side failure paths should use the structured logger in app/lib/logger.ts instead of raw console.error calls. The logger redacts metadata keys that look like credentials, tokens, cookies, or secrets. Keep user-facing messages generic, and put only safe operational context such as route names, action names, booleans, status codes, and error codes into logs.

Generation actions are protected by Supabase authentication, Row Level Security, and a best-effort per-process rate limiter before costly workout or meal-plan generation runs. Production deployments should still enforce durable request rate limits at the hosting edge, API gateway, or Supabase layer to control cost and abuse across serverless instances.

Vercel Deployment Controls

This app includes a vercel.json configuration that applies baseline security headers to every route in Vercel deployments, including HSTS, frame denial, MIME-sniffing protection, a strict referrer policy, and a restrictive permissions policy. Keep these headers enabled for preview and production deployments unless a specific integration requires a reviewed exception.

Because Vercel serverless instances do not share in-memory state, keep the in-app generation limiter as a fast local guard and configure durable abuse controls at the Vercel edge for production. At minimum, add Vercel Firewall or WAF rules that rate-limit authenticated generation POST traffic and alert on repeated generation.rate_limited log events.

Supabase Database

The supabase directory contains the local project configuration and versioned database migrations. The empty 20260611155633_remote_baseline.sql marker represents the existing dashboard-managed schema already recorded remotely. The following reconciliation migration safely hardens those existing tables, preserves food_logs, enables consistent Row Level Security, prevents duplicate daily records, and defines the atomic save_profile_with_tde database function.

Before applying the reconciliation migration, run supabase/preflight/20260611170000_reconcile_fitness_schema.sql in the linked project and verify every query returns no rows. Do not restore or push the removed empty-database initial migration against the existing project.

Install the Supabase CLI. This migration history is currently based on an existing dashboard-managed project: the empty baseline marker aligns remote history, while the reconciliation migration assumes the existing tables are present. Do not run supabase db reset against this history until the committed remote schema snapshot has been promoted into a reproducible baseline migration.

After reviewing the pending reconciliation migration, inspect and apply it to the linked remote project with:

supabase link --project-ref <project-ref>
supabase migration list --linked
supabase db push --dry-run
supabase db push

After changing the database schema, generate a temporary contract from the linked project and compare it with the checked-in TypeScript database contract:

supabase gen types typescript --linked > supabase/remote-database.types.ts

Windows PowerShell 5.1 writes redirected output as UTF-16, which causes ESLint to report that the generated TypeScript file appears to be binary. Use an explicit UTF-8 encoding instead:

npx supabase gen types typescript --linked | Out-File -Encoding utf8 supabase/remote-database.types.ts

The temporary supabase/remote-database.types.ts comparison artifact is ignored by Git and ESLint. The checked-in database types intentionally include more specific JSON-column shapes used by the current application, so review regenerated JSON fields before replacing app/lib/database.types.ts and keep application validation aligned with the database contract.

Quality Checks

Run the complete local quality gate:

npm run env:check
npm run check
npm run build
npm run test:e2e

Or run checks individually:

npm run lint
npm run typecheck
npm test

The test command compiles the selected TypeScript source and tests into the ignored .test-dist directory, then runs them with Node's built-in test runner. The baseline suite covers authentication and profile schemas, TDEE calculations, generated workout and meal-plan validation, Supabase client contracts, and the required migration contract.

Playwright always runs the public authentication journeys. Authenticated protected-flow tests are included automatically only when both E2E_AUTH_EMAIL and E2E_AUTH_PASSWORD are set. Use a dedicated non-production Supabase user, keep those values in .env.local or CI secrets, and never commit real credentials. The authenticated setup stores browser state under the ignored playwright/.auth/ directory. Set E2E_MOCK_AI=1 with the authenticated credentials to run deterministic meal-plan and workout-generation E2E coverage without making real OpenAI requests.

Available Scripts

Command Description
npm run dev Start the development server with Turbopack
npm run build Create an optimized production build
npm run start Start a previously built production application
npm run lint Lint the repository with ESLint
npm run typecheck Run the TypeScript compiler without emitting files
npm run env:check Validate required environment variable names without printing values
npm test Compile and run the baseline unit tests
npm run check Run lint, type-checking, and unit tests
npm run test:e2e Run Playwright public journeys and, when E2E credentials are configured, authenticated protected-flow checks in Chromium
npm run ci Run checks, production build, and end-to-end tests

Current Productionization Status

This repository is being hardened incrementally. The current baseline includes deterministic builds, explicit quality scripts, validated authentication recovery, profile and TDEE domains, user-local daily tracking, versioned Supabase schema and Row Level Security policies, documented environment setup, observability endpoints, and release controls. AI-generated workout and meal-plan output is now validated before persistence and regeneration is non-destructive. Public authentication journeys run in CI, authenticated Supabase protected-flow smoke tests run whenever dedicated E2E credentials are configured, and deterministic mocked-AI E2E coverage verifies generated workout and meal-plan persistence without spending model tokens. Upcoming work should focus on enabling Vercel Firewall/WAF rate-limit rules in production and wiring those events into broader abuse monitoring.

Deployment and rollback steps are documented in docs/release.md.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages