The easiest way to browse your tables visually:
- Open Studio: http://127.0.0.1:54323
- Navigate: Click "Table Editor" in left sidebar
- Explore tables:
products— 1,025 active products across 20 categories (variable size per category)nutrition_facts— nutritional data per 100gproduct_allergen_info— allergen/trace declarations (unified table)
- Run custom queries: Click "SQL Editor" → paste any SQL → click Run
Pro tip: Click on v_master view for a denormalized "master report" with all data joined.
For quick terminal queries, use:
# View top 10 unhealthiest products
echo "SELECT product_name, brand, unhealthiness_score, nutri_score_label FROM v_master ORDER BY unhealthiness_score::int DESC LIMIT 10;" | docker exec -i supabase_db_tryvit psql -U postgres -d postgres
# View all chips
echo "SELECT * FROM v_master WHERE category='Chips' ORDER BY unhealthiness_score::int DESC;" | docker exec -i supabase_db_tryvit psql -U postgres -d postgres -x
# View all żabka products
echo "SELECT * FROM v_master WHERE category='Żabka' ORDER BY unhealthiness_score::int DESC;" | docker exec -i supabase_db_tryvit psql -U postgres -d postgres -x
# View all cereals
echo "SELECT * FROM v_master WHERE category='Cereals' ORDER BY unhealthiness_score::int DESC;" | docker exec -i supabase_db_tryvit psql -U postgres -d postgres -x
# View all drinks
echo "SELECT * FROM v_master WHERE category='Drinks' ORDER BY unhealthiness_score::int DESC;" | docker exec -i supabase_db_tryvit psql -U postgres -d postgres -x
# View all dairy
echo "SELECT * FROM v_master WHERE category='Dairy' ORDER BY unhealthiness_score::int DESC;" | docker exec -i supabase_db_tryvit psql -U postgres -d postgres -x
# Count by category
echo "SELECT category, COUNT(*) FROM products WHERE is_deprecated IS NOT TRUE GROUP BY category;" | docker exec -i supabase_db_tryvit psql -U postgres -d postgresValidates foreign keys, nulls, duplicates, orphaned rows, nutrition sanity, provenance:
Get-Content "db\qa\QA__null_checks.sql" | docker exec -i supabase_db_tryvit psql -U postgres -d postgres --tuples-onlyExpected output: Empty (zero violation rows) = ✅ PASS
Validates v3.2 algorithm correctness, flag logic, NOVA consistency, regression checks:
Get-Content "db\qa\QA__scoring_formula_tests.sql" | docker exec -i supabase_db_tryvit psql -U postgres -d postgres --tuples-onlyExpected output: Empty (zero violation rows) = ✅ PASS
Run all pipelines + QA suites automatically:
.\RUN_LOCAL.ps1 -RunQAExpected output:
================================================
Execution Summary
================================================
Succeeded: 70
Failed: 0
Duration: ~10s
================================================
Running QA Checks
================================================
All QA checks passed (421/421 — zero violation rows).
Database inventory:
active_products | deprecated | nutrition | categories
-----------------+------------+-----------+------------
1025 | 38 | 1032 | 20
Runs all 30 test suites with color-coded output:
.\RUN_QA.ps1Expected output:
ALL TESTS PASSED (421/421 checks across 30 suites)
Verifies the database correctly rejects invalid data:
.\RUN_NEGATIVE_TESTS.ps1Expected output: 29/29 CAUGHT, 0 MISSED
- Top Chips Faliste (palm oil, 16g sat fat) → Score: 51±2
- Naleśniki z jabłkami (healthiest żabka) → Score: 17±2
- Melvit Płatki Owsiane Górskie (whole oats, NOVA 1) → Score: 11±2
- Coca-Cola Zero (zero sugar, high additives) → Score: 8±2
- Piątnica Skyr Naturalny (healthiest dairy) → Score: 9±2
- Mestemacher Pumpernikiel (traditional rye) → Score: 17±2
- Tarczyński Kabanosy Klasyczne (high-fat cured meat) → Score: 55±2
- Knorr Nudle Pomidorowe Pikantne (instant noodle, palm oil) → Score: 21±2
If these products' scores drift outside expected ranges, the tests will flag it.
Get everything in one denormalized view:
SELECT * FROM v_master
ORDER BY unhealthiness_score::int DESC;Columns available (47 columns):
- Identity:
product_id,country,brand,product_name,category,product_type,ean - Qualitative:
prep_method,store_availability,controversies - Scores:
unhealthiness_score,confidence,data_completeness_pct,score_breakdown(JSONB) - Labels:
nutri_score_label,nova_classification,processing_risk(derived from NOVA) - Flags:
high_salt_flag,high_sugar_flag,high_sat_fat_flag,high_additive_load - Nutrition (per 100g):
calories,total_fat_g,saturated_fat_g,trans_fat_g,carbs_g,sugars_g,fibre_g,protein_g,salt_g - Ingredients:
additives_count,ingredients_raw,ingredient_count,additive_names,ingredient_concern_score,has_palm_oil - Dietary:
vegan_status,vegetarian_status - Allergens:
allergen_count,allergen_tags,trace_count,trace_tags - Source:
source_type,source_url,source_ean - Data quality:
ingredient_data_quality,nutrition_data_quality
-
Start Supabase (if not already running):
supabase start
-
Open Studio UI: http://127.0.0.1:54323
-
Run pipelines (if data changed):
.\RUN_LOCAL.ps1 -RunQA -
Explore data visually in Studio → Table Editor
-
Run custom analysis in Studio → SQL Editor
-- Most common ingredients across all products
SELECT name_en, product_count, usage_pct, concern_tier
FROM mv_ingredient_frequency ORDER BY product_count DESC LIMIT 20;
-- High-concern ingredients and where they appear
SELECT name_en, product_count, concern_tier, categories
FROM mv_ingredient_frequency WHERE concern_tier >= 2
ORDER BY product_count DESC;-- Find 5 products most similar to product #42 by ingredient overlap
SELECT * FROM find_similar_products(42);
-- Find 10 similar products
SELECT * FROM find_similar_products(42, 10);-- Find healthier alternatives in the same category
SELECT * FROM find_better_alternatives(42);
-- Find healthier alternatives across ALL categories
SELECT * FROM find_better_alternatives(42, false);
-- Find top 10 healthier alternatives
SELECT * FROM find_better_alternatives(42, true, 10);-- See how a product's score was computed
SELECT product_name, unhealthiness_score,
score_breakdown->'factors' AS factors
FROM v_master WHERE product_id = 42;| Service | URL |
|---|---|
| Supabase Studio (Database UI) | http://127.0.0.1:54323 |
| REST API | http://127.0.0.1:54321/rest/v1 |
| GraphQL API | http://127.0.0.1:54321/graphql/v1 |
| Direct Postgres | postgresql://postgres:postgres@127.0.0.1:54322/postgres |
- All data is local — nothing is uploaded to remote Supabase unless you explicitly push it
- Pipelines are idempotent — safe to run repeatedly
- QA tests run in seconds — should be zero violations
- Test after every schema change — ensures scoring formula integrity