MacroMath
Architecture

Backend & Supabase

The Supabase backend — Edge Functions, database migrations and setup.

The entire backend runs on Supabase: PostgreSQL with Row-Level Security, Auth, Storage, and a set of Edge Functions that keep secrets off the device and wrap external APIs. The website and the app share the same project.

Edge Functions

Server-side logic lives in supabase/functions/. Each function is a small Deno handler:

FunctionWhat it does
geminiProxies calls to Google Gemini so the API key never ships in the app.
fatsecretWraps FatSecret's OAuth so food search / barcode lookups stay secure.
send-emailSends transactional email (OTP codes) over SMTP.
delete-accountDeletes a user and all their data on request.
stripe-checkoutCreates a Stripe Checkout session for Premium.
stripe-webhookReceives Stripe events and updates subscription state.

Moving these to the server means the client never holds the Gemini, FatSecret or Stripe secrets, and gives a single place to enforce rules.

Database migrations

The schema is built incrementally through thirteen migrations (001013) plus a base setup_supabase.sql:

MigrationAdds
001_add_diet_and_weight_tablesDiet plans and weight history.
002_pantry_items_self_containedSelf-contained pantry items.
003_water_logDaily hydration log.
004_shopping_listShopping list.
005_meal_slots_and_shopping_checkCustom meal slots + shopping check-off.
006_users_rls_and_ensure_rpcUser RLS policies and an ensure-user RPC.
007_pantry_fat_secret_idFatSecret id on pantry items.
008_rename_fat_secret_id_to_food_ref_idRenames it to the canonical food_ref_id.
009_avatars_storage_bucketStorage bucket for avatars.
010_add_missing_users_columnsExtra user columns.
011_premium_subscriptionPremium-subscription columns.
012_stripe_columnsStripe customer / subscription columns.
013_meal_items_unidadeUnit field on meal items.

The tables and their relationships are documented in Data model. The food_ref_id (migration 008) is the canonical food identifier used across the Pantry, Diet and Foods.

Security

Every table is protected by Row-Level Security (user_id = auth.uid()), so a user can only ever read their own rows. Passwords use bcrypt, transport uses TLS 1.3, and data at rest is AES-256. Full detail in Security.

Setup

Provisioning a backend means: create a Supabase project, run setup_supabase.sql, then apply migrations 001013, deploy the Edge Functions, and set the function secrets (Gemini, FatSecret, SMTP, Stripe). See the app repo's docs/ for the Stripe and GitHub Actions setup guides.

On this page