Skip to content

Sync-Co/CalorieIntake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CalorieIQ

A web-based calorie and nutrition tracking app with macro insights, activity logging, and 7-day trends.

Stack: Next.js 14 · TypeScript · Tailwind · Prisma · Supabase Auth · PostgreSQL · Upstash Redis · Recharts · TanStack Query · Zustand


Quick Start

1. Prerequisites

  • Node.js 20+
  • Docker Desktop (for local Postgres + Redis)
  • Supabase account (free tier) — for Auth
  • Upstash account (optional) — for Redis caching

2. Clone & Install

git clone <repo-url> calorieiq
cd calorieiq
npm install

3. Start Local Services

docker compose up -d

This starts:

  • PostgreSQL 16 on localhost:5432 (db: calorieiq, user/pass: postgres/postgres)
  • Redis 7 on localhost:6379

4. Configure Environment

cp .env.example .env.local

Then fill in:

  • NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY — from your Supabase project dashboard
  • UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKENoptional; leave empty to disable Redis caching
  • DATABASE_URL and DIRECT_URL — point at your local Postgres (default values in .env.example work with the Docker compose)

5. Set Up the Database

npm run db:push        # Push the Prisma schema to your local DB
npm run db:seed        # Seed 75+ foods + 50+ activities

6. Configure Supabase Auth

In your Supabase dashboard:

  1. Authentication → Providers → Email — enable email/password
  2. Authentication → Providers → Google — enable Google OAuth and add a client ID
  3. Authentication → URL Configuration → Site URL — set to http://localhost:3000
  4. Authentication → URL Configuration → Redirect URLs — add http://localhost:3000/auth/callback

7. Run It

npm run dev

Open http://localhost:3000.


Project Structure

calorieiq/
├── prisma/
│   ├── schema.prisma              # Complete database schema
│   └── seed.ts                    # 75+ foods + 50+ activities
├── src/
│   ├── app/
│   │   ├── (auth)/                # /login, /register
│   │   ├── (app)/                 # /dashboard, /history, /settings (protected)
│   │   ├── api/                   # All backend routes
│   │   ├── auth/callback/         # OAuth callback
│   │   ├── layout.tsx             # Root with Providers
│   │   └── page.tsx               # Landing
│   ├── components/
│   │   ├── ui/                    # Button, Card, Dialog, etc.
│   │   ├── auth/                  # Login + Register forms
│   │   ├── dashboard/             # Calorie ring, macro bars, meal sections
│   │   ├── food/                  # Food search modal + portion dialog
│   │   ├── activity/              # Activity logger
│   │   ├── history/               # Charts (Recharts)
│   │   ├── profile/               # Setup wizard
│   │   ├── settings/              # Settings view
│   │   └── layout/                # AppShell with sidebar + bottom nav
│   ├── contexts/                  # auth.context.tsx
│   ├── stores/                    # ui.store.ts (Zustand)
│   ├── hooks/                     # useDashboard, useDebounce
│   ├── lib/
│   │   ├── calculations/          # tdee.ts, streak.ts (pure functions)
│   │   ├── food/                  # search orchestrator + OFF client
│   │   ├── api/                   # response helpers + createHandler
│   │   ├── auth/session.ts        # getAuthUser
│   │   ├── prisma.ts              # singleton client
│   │   ├── supabase.ts            # browser + server + admin clients
│   │   └── redis.ts               # lazy Upstash client
│   └── validation/schemas.ts      # All Zod schemas
├── tests/
│   └── unit/                      # Vitest tests for tdee, streak, schemas
├── middleware.ts                  # Edge auth guard
└── docker-compose.yml             # Local Postgres + Redis

Available Scripts

Command What it does
npm run dev Start Next.js dev server
npm run build Production build
npm run start Start production server
npm run lint Run ESLint
npm run type-check TypeScript check
npm run test Run Vitest unit tests
npm run test:watch Watch mode
npm run db:push Push Prisma schema (no migration files)
npm run db:migrate Create and apply migration
npm run db:seed Seed foods + activities
npm run db:studio Open Prisma Studio at localhost:5555

Golden Path

  1. Visit / → click Get Started
  2. Register with email + password → Supabase creates auth user → row inserted into users table
  3. Redirected to /profile/setup → 3-step wizard (basic info → goal → activity level)
  4. TDEE calculated and stored in user_profiles.calorie_target
  5. Lands on /dashboard showing calorie ring (empty), macro bars, 4 empty meal sections
  6. Click + Add in Breakfast → Food Search Modal opens
  7. Search "oats" → tap result → adjust quantity → confirm
  8. Dashboard updates immediately (optimistic) → ring fills → macros progress
  9. Click + Add Activity → search "running" → enter duration → log
  10. Dashboard now shows net calories with burn applied
  11. Visit /history → 7-day charts (will be empty for first day, fills out across days)
  12. Visit /settings → adjust macros, change weight, override calorie target

Architecture Highlights

  • Optimistic mutations for food/activity logging via TanStack Query — UI updates instantly with snapshot rollback on error
  • Multi-layer food search — Redis (60s TTL) → Postgres ILIKE → Open Food Facts API in parallel (400ms hard timeout)
  • Pure TDEE engine in lib/calculations/tdee.ts — Mifflin-St Jeor BMR + activity multiplier + goal adjustment, 1,200 kcal floor
  • Edge middleware guards /dashboard, /log, /history, /profile, /settings — redirects unauth users
  • Cascade deletes on User enable GDPR right-to-erasure with a single DELETE FROM users WHERE id = ?

Health Check

GET /api/health returns 200 if Postgres + Redis are reachable, 503 otherwise. Use for uptime monitors.

Reference Documents

Troubleshooting

Error: Environment variable not found: DATABASE_URL Make sure .env.local exists. Restart the dev server after editing.

Auth redirects loop or 401 on every API call Verify your Supabase URL + keys, and that the Site URL in Supabase auth settings matches http://localhost:3000. Clear cookies and try again.

Food search returns nothing The seed script needs to have run. Check npm run db:studio — the foods table should have ~75 rows. Re-run npm run db:seed.

Open Food Facts results never appear The OFF client has a hard 400ms timeout — slow networks fall back to local-only. This is intentional. To verify OFF is reachable, hit https://world.openfoodfacts.org/cgi/search.pl?search_terms=apple&json=true in your browser.

About

CalorieIQ - Full-stack calorie tracking app

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages