๐Ÿ—„๏ธ ื—ืœืง 1, Supabase
Database Schema
ื”ืขืชืง ื•ื”ื“ื‘ืง ืœ-Supabase SQL Editor. ื›ื•ืœืœ RLS ืžืœื, ื›ืœ ืžืฉืชืžืฉ ืจื•ืื” ืจืง ืืช ื”ื ืชื•ื ื™ื ืฉืœื•.
๐Ÿ“‹ supabase-schema.sql SQL
ื”ืขืชืง
-- โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
-- Longevix Database Schema, Supabase PostgreSQL
-- ื”ืคืขืœ ืงื•ื“ ื–ื” ื‘-SQL Editor ืฉืœ Supabase
-- ื›ืœ ื˜ื‘ืœื” ืžื•ื’ื ืช ื‘-Row Level Security (RLS)
-- โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

-- ื”ืคืขืœ ื”ืจื—ื‘ื•ืช ื ื“ืจืฉื•ืช
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
-- ื˜ื‘ืœื” 1: profiles, ืคืจื˜ื™ ืžืฉืชืžืฉ ื‘ืกื™ืกื™ื™ื
-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
CREATE TABLE profiles (
 id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
 full_name TEXT, -- ืฉื ืžืœื
 age INTEGER, -- ื’ื™ืœ
 gender TEXT CHECK (gender IN ('male','female','other')),
 weight_kg DECIMAL(5,1), -- ืžืฉืงืœ ื‘ืง"ื’
 height_cm INTEGER, -- ื’ื•ื‘ื” ื‘ืก"ืž
 vitality_score INTEGER DEFAULT 0, -- ืฆื™ื•ืŸ Longevity (0-100)
 active_protocol TEXT, -- ืฉื ื”ืคืจื•ื˜ื•ืงื•ืœ ื”ืคืขื™ืœ
 stripe_customer_id TEXT, -- ืžื–ื”ื” ืœืงื•ื— ื‘-Stripe
 subscription_status TEXT DEFAULT 'free', -- ืกื˜ื˜ื•ืก ืžื ื•ื™: free/active/cancelled
 gdpr_consent BOOLEAN DEFAULT FALSE, -- ืื™ืฉื•ืจ GDPR, ื—ื•ื‘ื”!
 created_at TIMESTAMPTZ DEFAULT NOW()
);

-- ื”ื’ื ืช RLS, ื”ืžืฉืชืžืฉ ืจื•ืื” ืจืง ืืช ืขืฆืžื•
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
CREATE POLICY "users_own_profile" ON profiles
 FOR ALL USING (auth.uid() = id);

-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
-- ื˜ื‘ืœื” 2: biomarker_logs, ื‘ื“ื™ืงื•ืช ื“ื
-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
CREATE TABLE biomarker_logs (
 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 user_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
 marker_name TEXT NOT NULL, -- ืฉื ื”ืžื“ื“ (ื•ื™ื˜ืžื™ืŸ D, Ferritin...)
 value DECIMAL(10,3) NOT NULL, -- ื”ืขืจืš ื”ืžื“ื•ื“
 unit TEXT NOT NULL, -- ื™ื—ื™ื“ื•ืช (ng/ml, %...)
 normal_min DECIMAL(10,3), -- ืขืจืš ืžื™ื ื™ืžื•ื ืชืงื™ืŸ
 normal_max DECIMAL(10,3), -- ืขืจืš ืžืงืกื™ืžื•ื ืชืงื™ืŸ
 status TEXT GENERATED ALWAYS AS ( -- ืžื—ื•ืฉื‘ ืื•ื˜ื•ืžื˜ื™ืช!
 CASE
 WHEN value < normal_min THEN 'low'
 WHEN value > normal_max THEN 'high'
 ELSE 'normal'
 END
 ) STORED,
 is_critical BOOLEAN DEFAULT FALSE, -- ื“ื’ืœ ืื“ื•ื, ืขืจืš ืžืกื•ื›ืŸ
 test_date DATE DEFAULT CURRENT_DATE, -- ืชืืจื™ืš ื”ื‘ื“ื™ืงื”
 created_at TIMESTAMPTZ DEFAULT NOW()
);

ALTER TABLE biomarker_logs ENABLE ROW LEVEL SECURITY;
CREATE POLICY "users_own_biomarkers" ON biomarker_logs
 FOR ALL USING (auth.uid() = user_id);

-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
-- ื˜ื‘ืœื” 3: quiz_responses, ืชืฉื•ื‘ื•ืช ืฉืืœื•ืŸ
-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
CREATE TABLE quiz_responses (
 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 user_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
 answers JSONB NOT NULL, -- ื›ืœ ื”ืชืฉื•ื‘ื•ืช ื›-JSON
 primary_goal TEXT, -- ืžื˜ืจื” ืขื™ืงืจื™ืช
 energy_level INTEGER CHECK (energy_level BETWEEN 1 AND 10),
 sleep_quality INTEGER CHECK (sleep_quality BETWEEN 1 AND 10),
 stress_level INTEGER CHECK (stress_level BETWEEN 1 AND 10),
 focus_level INTEGER CHECK (focus_level BETWEEN 1 AND 10),
 vitality_score INTEGER, -- ืฆื™ื•ืŸ ืฉื—ื•ืฉื‘ ืœืื—ืจ ืฉืืœื•ืŸ
 version INTEGER DEFAULT 1, -- ื’ืจืกืช ื”ืฉืืœื•ืŸ
 created_at TIMESTAMPTZ DEFAULT NOW()
);

ALTER TABLE quiz_responses ENABLE ROW LEVEL SECURITY;
CREATE POLICY "users_own_quiz" ON quiz_responses
 FOR ALL USING (auth.uid() = user_id);

-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
-- ื˜ื‘ืœื” 4: evidence_library, ืžืื’ืจ ืžื—ืงืจื™ื
-- ื˜ื‘ืœื” ืฆื™ื‘ื•ืจื™ืช, ื’ืœื™ืช ืžื•ืกื™ืคื” ื›ืืŸ ืžื—ืงืจื™ื ื—ื“ืฉื™ื
-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
CREATE TABLE evidence_library (
 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 ingredient_name TEXT NOT NULL UNIQUE, -- ืฉื ื”ืจื›ื™ื‘ (Magnesium Glycinate)
 name_hebrew TEXT, -- ืฉื ื‘ืขื‘ืจื™ืช
 indication TEXT[], -- ืื™ื ื“ื™ืงืฆื™ื•ืช [sleep, stress, energy]
 mechanism_he TEXT, -- ื”ืกื‘ืจ ืžื ื’ื ื•ืŸ ื‘ืขื‘ืจื™ืช
 pubmed_id TEXT, -- ืžืกืคืจ PMID
 evidence_url TEXT, -- ืงื™ืฉื•ืจ ืœ-PubMed
 evidence_grade TEXT CHECK (evidence_grade IN ('A','B','C','D')),
 dose_default INTEGER, -- ืžื™ื ื•ืŸ ื‘ืจื™ืจืช ืžื—ื“ืœ (mg)
 dose_max INTEGER, -- ืžื™ื ื•ืŸ ืžืงืกื™ืžืœื™ ื‘ื˜ื•ื—
 timing TEXT, -- ื–ืžืŸ ื ื˜ื™ืœื”: morning/afternoon/evening
 galit_approved BOOLEAN DEFAULT FALSE, -- ืื•ืฉืจ ืข"ื™ ื’ืœื™ืช ืคืจืฅ
 active BOOLEAN DEFAULT TRUE, -- ื”ืื ื”ืจื›ื™ื‘ ืคืขื™ืœ ื‘ืคืœื˜ืคื•ืจืžื”
 updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- ื›ื•ืœื ื™ื›ื•ืœื™ื ืœืงืจื•ื, ืจืง admins ื™ื›ื•ืœื™ื ืœื›ืชื•ื‘
ALTER TABLE evidence_library ENABLE ROW LEVEL SECURITY;
CREATE POLICY "public_read_evidence" ON evidence_library
 FOR SELECT USING (true);

-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
-- ื˜ื‘ืœื” 5: daily_logs, ืฆ'ืง-ืื™ืŸ ื™ื•ืžื™
-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
CREATE TABLE daily_logs (
 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 user_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE,
 log_date DATE DEFAULT CURRENT_DATE,
 energy INTEGER CHECK (energy BETWEEN 1 AND 5), -- 1-5
 sleep_quality INTEGER CHECK (sleep_quality BETWEEN 1 AND 5), -- 1-5
 focus INTEGER CHECK (focus BETWEEN 1 AND 5), -- 1-5
 mood INTEGER CHECK (mood BETWEEN 1 AND 5), -- 1-5
 protocol_adherence INTEGER CHECK (protocol_adherence BETWEEN 0 AND 100), -- % ืขืžื™ื“ื”
 supplement_ratings JSONB, -- ื“ื™ืจื•ื’ ื›ืœ ืชื•ืกืฃ {mag: 4, coq10: 5}
 notes TEXT, -- ื”ืขืจื•ืช ื—ื•ืคืฉื™ื•ืช
 vitality_score INTEGER, -- ืฆื™ื•ืŸ ื™ื•ืžื™ ืžื—ื•ืฉื‘
 UNIQUE(user_id, log_date) -- ืจืง ืจืฉื•ืžื” ืื—ืช ืœื™ื•ื
);

ALTER TABLE daily_logs ENABLE ROW LEVEL SECURITY;
CREATE POLICY "users_own_logs" ON daily_logs
 FOR ALL USING (auth.uid() = user_id);

-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
-- ืื™ื ื“ืงืกื™ื ืœื‘ื™ืฆื•ืขื™ื ื˜ื•ื‘ื™ื
-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
CREATE INDEX idx_biomarker_user_date ON biomarker_logs(user_id, test_date);
CREATE INDEX idx_daily_user_date ON daily_logs(user_id, log_date);
CREATE INDEX idx_evidence_indication ON evidence_library USING GIN(indication);
โš™๏ธ ื—ืœืง 2, JavaScript
Evidence Engine
ื”ืคื•ื ืงืฆื™ื” ื”ืจืืฉื™ืช ืฉืžื—ื‘ืจืช ืฉืืœื•ืŸ + ื‘ื“ื™ืงื•ืช ื“ื โ†’ ืคืจื•ื˜ื•ืงื•ืœ ืžื•ืชืื. ื›ืœ ืฉื•ืจื” ืžืชื•ืขื“ืช ื‘ืขื‘ืจื™ืช.
โš™๏ธ evidence-engine.js JavaScript
ื”ืขืชืง
/**
 * โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
 * Longevix Evidence Engine, ื”ืœื‘ ืฉืœ ื”ืคืœื˜ืคื•ืจืžื”
 * ืžื—ื‘ืจ: ื ืชื•ื ื™ ืฉืืœื•ืŸ + ื‘ื“ื™ืงื•ืช ื“ื โ†’ ืคืจื•ื˜ื•ืงื•ืœ ืžื‘ื•ืกืก ืžื—ืงืจ
 *
 * ืฉื™ืžื•ืฉ:
 * const protocol = await calculateProtocol(quizData, biomarkers);
 * console.log(protocol.recommendations);
 * โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
 */

// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// ืžืื’ืจ ื”ืจืื™ื•ืช ื”ืžื“ืขื™ื•ืช, ื›ืœ ืชื•ืกืฃ ืขื ื”ื•ื›ื—ื” ืงืœื™ื ื™ืช
// ื–ื” ืžื’ื™ืข ืž-Supabase ื‘ืคืจื•ื“ืงืฉืŸ; ื›ืืŸ ืœื”ื“ื’ืžื” ื‘ืœื‘ื“
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const EVIDENCE_LIBRARY = {

 "magnesium_glycinate": {
 name: "Magnesium Glycinate",
 nameHe: "ืžื’ื ื–ื™ื•ื ื’ืœื™ืฆื™ื ืื˜",
 // ืื™ื ื“ื™ืงืฆื™ื•ืช: ืžืชื™ ืžืžืœื™ืฆื™ื ืขืœ ืชื•ืกืฃ ื–ื”
 indications: ["sleep", "stress", "anxiety", "muscle_recovery"],
 // ืกืคื™ ื”ืคืขืœื”: ืžื” ืฆืจื™ืš ืœื”ื™ื•ืช ื ืžื•ืš/ื’ื‘ื•ื” ื›ื“ื™ ืœื”ืžืœื™ืฅ
 thresholds: { sleep: <= 5, stress: >= 6 },
 // ื”ืกื‘ืจ ื”ืžื ื’ื ื•ืŸ ื‘ืขื‘ืจื™ืช, ื™ื•ืคื™ืข ืœืžืฉืชืžืฉ
 mechanismHe: "ืžื’ื ื–ื™ื•ื ืžืคืขื™ืœ ืงื•ืœื˜ื ื™ GABA, ื”ืžืฉื“ืจ ื”ืขืฆื‘ื™ ื”ืจืืฉื™ ืœื”ืจื’ืขื”. ืžืคื—ื™ืช ื–ืžืŸ ื”ื™ืจื“ืžื•ืช ื‘-17 ื“ืงื•ืช ื‘ืžืžื•ืฆืข.",
 stat: "ื”ืคื—ืชืช ื–ืžืŸ ื”ื™ืจื“ืžื•ืช ื‘-17 ื“ืงื•ืช",
 pmid: "33600070",
 pubmedUrl: "https://pubmed.ncbi.nlm.nih.gov/33600070",
 evidenceGrade: "A",
 dose: { default: 400, highStress: 500, max: 600 },
 timing: "evening",
 timingHe: "ืขืจื‘, 30 ื“ืงื•ืช ืœืคื ื™ ืฉื™ื ื”"
 },

 "omega3": {
 name: "Omega-3 EPA/DHA", nameHe: "ืื•ืžื’ื”-3",
 indications: ["energy", "focus", "inflammation", "cardiovascular", "longevity"],
 thresholds: { focus: <= 5, biomarker_omega3_index: < 8 },
 mechanismHe: "EPA/DHA ื‘ื•ื ื™ื ืคื•ืกืคื•ืœื™ืคื™ื“ื™ื ื‘ืงืจื•ื ืชื ืžื•ื—ื™ ื•ืžืฉืคื™ืขื™ื ืขืœ ืกืจื•ื˜ื•ื ื™ืŸ ื•ื“ื•ืคืžื™ืŸ.",
 stat: "ื”ืคื—ืชืช 25% ืกื™ื›ื•ืŸ ืงืจื“ื™ื•-ื•ืกืงื•ืœืจื™",
 pmid: "30415628",
 pubmedUrl: "https://pubmed.ncbi.nlm.nih.gov/30415628",
 evidenceGrade: "A",
 dose: { default: 2000, athlete: 3000, max: 4000 },
 timing: "morning", timingHe: "ื‘ื•ืงืจ, ืขื ืืจื•ื—ื” ืฉื•ืžื ื™ืช"
 },

 "vitamin_d3": {
 name: "Vitamin D3 + K2", nameHe: "ื•ื™ื˜ืžื™ืŸ D3 + K2",
 indications: ["energy", "immunity", "mood", "longevity"],
 thresholds: { biomarker_vitamin_d: < 30 }, // ng/ml
 mechanismHe: "D3 ืžื•ื•ืกืช ื™ื™ืฆื•ืจ ืกืจื•ื˜ื•ื ื™ืŸ ื•ืžืคืขื™ืœ 900+ ื’ื ื™ื. ื—ืกืจ ื‘-85% ืžืžืงืจื™ ืขื™ื™ืคื•ืช ื›ืจื•ื ื™ืช.",
 stat: "ืงืฉืจ ืœ-85% ืžืžืงืจื™ ืขื™ื™ืคื•ืช ื›ืจื•ื ื™ืช",
 pmid: "29343734",
 pubmedUrl: "https://pubmed.ncbi.nlm.nih.gov/29343734",
 evidenceGrade: "A",
 dose: { default: 2000, deficient: 4000, severe_deficient: 5000, max: 10000 },
 timing: "morning", timingHe: "ื‘ื•ืงืจ, ืขื ืืจื•ื—ืช ืฉืžื ื™ื"
 },

 "ashwagandha": {
 name: "Ashwagandha KSM-66", nameHe: "ืืฉื•ื•ื’ื ื“ื” KSM-66",
 indications: ["stress", "anxiety", "energy", "sleep"],
 thresholds: { stress: >= 6 },
 mechanismHe: "Withanolides ืžื•ื•ืกืชื™ื ืฆื™ืจ HPA, ืžืคื—ื™ืชื™ื ืงื•ืจื˜ื™ื–ื•ืœ ื‘-27.9% ืชื•ืš 8 ืฉื‘ื•ืขื•ืช.",
 stat: "ื”ืคื—ืชืช ืงื•ืจื˜ื™ื–ื•ืœ ื‘-27.9%",
 pmid: "23439798",
 pubmedUrl: "https://pubmed.ncbi.nlm.nih.gov/23439798",
 evidenceGrade: "A",
 dose: { default: 300, highStress: 600, max: 600 },
 timing: "morning", timingHe: "ื‘ื•ืงืจ, ืขื ืืจื•ื—ื”"
 },

 "coq10": {
 name: "CoQ10 Ubiquinol", nameHe: "ืงื•-ืื ื–ื™ื Q10",
 indications: ["energy", "longevity", "mitochondria"],
 thresholds: { energy: <= 5, age: >= 35 },
 mechanismHe: "ื—ื™ื•ื ื™ ืœืฉืจืฉืจืช ื”ื ืฉื™ืžื” ื”ืžื™ื˜ื•ื›ื•ื ื“ืจื™ืืœื™ืช. ื™ื•ืจื“ ื‘-49% ืขื“ ื’ื™ืœ 60.",
 stat: "ื™ืจื™ื“ื” ืฉืœ 49% ื‘ื’ื•ืฃ ืขื“ ื’ื™ืœ 60",
 pmid: "25625898",
 pubmedUrl: "https://pubmed.ncbi.nlm.nih.gov/25625898",
 evidenceGrade: "A",
 dose: { default: 200, over50: 300, over60: 400, max: 600 },
 timing: "afternoon", timingHe: "ืื—ืจ ื”ืฆื”ืจื™ื™ื, ืขื ืืจื•ื—ื”"
 }
};

/**
 * calculateProtocol, ื”ืคื•ื ืงืฆื™ื” ื”ืจืืฉื™ืช
 *
 * @param {Object} quizData - ืชืฉื•ื‘ื•ืช ื”ืฉืืœื•ืŸ
 * { energy: 1-10, sleep: 1-10, stress: 1-10, focus: 1-10,
 * goal: string, age: number, activity: string }
 * @param {Array} biomarkers - ื‘ื“ื™ืงื•ืช ื“ื
 * [{ marker_name: string, value: number, status: string }]
 * @returns {Object} - ื”ืžืœืฆื•ืช ืžื•ืชืืžื•ืช ืื™ืฉื™ืช
 */
async function calculateProtocol(quizData, biomarkers = []) {

 // ืฉืœื‘ 1: ื™ืฆื™ืจืช ืžืคืช ื‘ื“ื™ืงื•ืช ื“ื ืœื—ื™ืคื•ืฉ ืžื”ื™ืจ
 const biomarkerMap = {};
 biomarkers.forEach(bm => {
 // ืžืคืชื— ืžื ื•ืจืžืœ: "Vitamin D" โ†’ "vitamin_d"
 const key = bm.marker_name.toLowerCase().replace(/\s+/g, '_');
 biomarkerMap[key] = bm.value;
 });

 // ืฉืœื‘ 2: ื”ืคืขืœืช ืืœื’ื•ืจื™ืชื ื”ื ื™ืงื•ื“ ืœื›ืœ ืชื•ืกืฃ
 const scored = [];

 for (const [id, ingredient] of Object.entries(EVIDENCE_LIBRARY)) {
 let score = 0;
 const triggers = []; // ืžื” ื”ืคืขื™ืœ ืืช ื”ื”ืžืœืฆื”

 // ื‘ื“ื™ืงื” 1: ื”ืื ื”ืžื˜ืจื” ืชื•ืืžืช ืœืื™ื ื“ื™ืงืฆื™ื”
 if (ingredient.indications.includes(quizData.goal)) {
 score += 3;
 triggers.push({ type: 'goal', text: `ืชื•ืื ืœืžื˜ืจืช "${quizData.goal}"` });
 }

 // ื‘ื“ื™ืงื” 2: ืฆืœื™ื‘ื” ืขื ืกืคื™ ื”ืฉืืœื•ืŸ
 for (const [metric, threshold] of Object.entries(ingredient.thresholds || {})) {

 if (metric.startsWith('biomarker_')) {
 // โ”€โ”€โ”€ ืกืคื™ ื‘ื“ื™ืงื•ืช ื“ื โ”€โ”€โ”€
 const bmKey = metric.replace('biomarker_', '');
 const bmValue = biomarkerMap[bmKey];
 if (bmValue !== undefined && bmValue < threshold) {
 score += 3;
 triggers.push({
 type: 'biomarker',
 text: `${bmKey} ื ืžื•ืš: ${bmValue} (ืกืฃ: ${threshold})`
 });
 }
 } else {
 // โ”€โ”€โ”€ ืกืคื™ ืฉืืœื•ืŸ โ”€โ”€โ”€
 const val = quizData[metric];
 if (val !== undefined) {
 const triggered = (metric === 'stress' || metric === 'age')
 ? val >= threshold : val <= threshold;
 if (triggered) {
 score += 2;
 triggers.push({ type: 'quiz', text: `${metric}: ${val}` });
 }
 }
 }
 }

 // ืžื™ื ื™ืžื•ื ืฆื™ื•ืŸ ืœื”ื›ื ืกื” ืœืคืจื•ื˜ื•ืงื•ืœ
 if (score >= 2) {
 scored.push({ id, ingredient, score, triggers });
 }
 }

 // ืฉืœื‘ 3: ืžื™ื•ืŸ ืœืคื™ ืฆื™ื•ืŸ โ†’ top 6
 scored.sort((a, b) => b.score - a.score);
 const selected = scored.slice(0, 6);

 // ืฉืœื‘ 4: ื‘ื ื™ื™ืช ืื•ื‘ื™ื™ืงื˜ ื”ื”ืžืœืฆื•ืช ื”ืกื•ืคื™
 const recommendations = selected.map(({ id, ingredient, triggers }) => {

 // ื—ื™ืฉื•ื‘ ืžื™ื ื•ืŸ ื“ื™ื ืžื™ ืœืคื™ ื’ื™ืœ ื•ืจืžืช ืกื˜ืจืก
 let dose = ingredient.dose.default;
 if (quizData.stress >= 7 && ingredient.dose.highStress) dose = ingredient.dose.highStress;
 if (quizData.age >= 60 && ingredient.dose.over60) dose = ingredient.dose.over60;
 if (quizData.age >= 50 && ingredient.dose.over50) dose = ingredient.dose.over50;

 // ื‘ื ื™ื™ืช ื”ืกื‘ืจ ืื™ืฉื™ ื‘ืขื‘ืจื™ืช
 const triggerTexts = triggers.map(t => {
 if (t.type === 'quiz') return `ืฆื™ื™ื ืช ${t.text}`;
 if (t.type === 'biomarker') return `ื‘ื“ื™ืงืช ื”ื“ื ื”ืจืืชื” ${t.text}`;
 return t.text;
 }).join(' ื•-');

 const personalJustification = `ื”ื•ืกืคื ื• ${ingredient.nameHe} ื›ื™ ${triggerTexts}. `
 + ingredient.mechanismHe + ` ืžื—ืงืจื™ื ืžืจืื™ื: ${ingredient.stat}.`;

 return {
 id,
 name: ingredient.name,
 nameHe: ingredient.nameHe,
 dose: `${dose}mg`,
 timing: ingredient.timing,
 timingHe: ingredient.timingHe,
 justificationHe: personalJustification, // โ† ื–ื” ืžื” ืฉืžื•ืฆื’ ืœืžืฉืชืžืฉ
 pmid: ingredient.pmid,
 pubmedUrl: ingredient.pubmedUrl,
 evidenceGrade: ingredient.evidenceGrade,
 triggers
 };
 });

 // ืฉืœื‘ 5: ื—ื™ืฉื•ื‘ Vitality Score
 const vitalityScore = calculateVitalityScore(quizData, biomarkers);

 // ื”ื—ื–ืจืช ื”ืื•ื‘ื™ื™ืงื˜ ื”ืกื•ืคื™
 return {
 recommendations, // ื”ืžืœืฆื•ืช ืขื ื”ืกื‘ืจ ืื™ืฉื™
 vitalityScore, // ืฆื™ื•ืŸ 0-100
 protocolName: getProtocolName(quizData.goal),
 generatedAt: new Date().toISOString(),
 totalIngredients: recommendations.length
 };
}

// โ”€โ”€โ”€ ืคื•ื ืงืฆื™ื™ืช ืขื–ืจ: ื—ื™ืฉื•ื‘ Vitality Score โ”€โ”€โ”€
function calculateVitalityScore(quiz, biomarkers) {
 let score = 55;
 if (quiz.energy >= 7) score += 8; else if (quiz.energy <= 3) score -= 6;
 if (quiz.sleep >= 7) score += 7; else if (quiz.sleep <= 3) score -= 8;
 if (quiz.stress <= 3) score += 8; else if (quiz.stress >= 8) score -= 10;
 if (quiz.focus >= 7) score += 6;
 if (quiz.activity === 'athlete') score += 8;
 else if (quiz.activity === 'sedentary') score -= 5;
 biomarkers.forEach(bm => {
 if (bm.status === 'low') score -= 4;
 if (bm.is_critical) score -= 10;
 });
 return Math.min(Math.max(score, 20), 95);
}

function getProtocolName(goal) {
 const names = {
 energy: 'Energy & Focus Protocol', sleep: 'Sleep Recovery Protocol',
 stress: 'Calm & Resilience Protocol', longevity: 'Longevity Core Protocol',
 weight: 'Metabolic Balance Protocol'
 };
 return names[goal] || 'Personal Health Protocol';
}

// โ”€โ”€โ”€ ื™ื™ืฆื•ื (ืœืฉื™ืžื•ืฉ ื‘-React/Next.js) โ”€โ”€โ”€
export { calculateProtocol, calculateVitalityScore, EVIDENCE_LIBRARY };
๐Ÿ“ฑ ื—ืœืง 3, React Component
Biomarker Entry UI
ืžืžืฉืง ื”ื–ื ืช ื‘ื“ื™ืงื•ืช ื“ื, ืžื•ืชืื ืžื•ื‘ื™ื™ืœ. ื ืกื” ืื•ืชื• ื›ืืŸ ืœืžื˜ื”, ืื—ืจ ื›ืš ื”ืขืชืง ืืช ื”ืงื•ื“.
๐Ÿงช ื”ื–ื ืช ื‘ื“ื™ืงืช ื“ื, ื“ืžื• ื—ื™
Live Demo
๐Ÿ” ืฉื ื”ืžื“ื“
๐Ÿ“Š ืขืจืš
1
2
3
4
5
6
7
8
9
.
0
โŒซ
๐Ÿ“ฑ BiomarkerEntry.jsx React
ื”ืขืชืง
/**
 * BiomarkerEntry.jsx, ืจื›ื™ื‘ ื”ื–ื ืช ื‘ื“ื™ืงื•ืช ื“ื
 * Mobile-First, ืžืงืœื“ืช ื ื•ืžืจื™ืช, ื•ืœื™ื“ืฆื™ื” ื•ื™ื–ื•ืืœื™ืช
 * ื—ื™ื‘ื•ืจ ืœ-Supabase ืขื ื”ืฆืคื ื”
 */
import { useState, useCallback } from 'react';
import { supabase } from '../lib/supabase';

// โ”€โ”€โ”€ ืžืื’ืจ ื”ืžื“ื“ื™ื ื”ืจืคื•ืื™ื™ื ืขื ื˜ื•ื•ื—ื™ ื ื•ืจืžื” โ”€โ”€โ”€
const BIOMARKERS_DB = [
 { name: 'Vitamin D', nameHe: 'ื•ื™ื˜ืžื™ืŸ D', unit: 'ng/ml', min: 30, max: 100 },
 { name: 'Ferritin', nameHe: 'ืคืจื™ื˜ื™ืŸ', unit: 'ng/ml', min: 30, max: 300 },
 { name: 'Hemoglobin', nameHe: 'ื”ืžื•ื’ืœื•ื‘ื™ืŸ', unit: 'g/dL', min: 12, max: 17 },
 { name: 'TSH', nameHe: 'TSH ืชื™ืจื•ืื™ื“', unit: 'mU/L', min: 0.4, max: 4 },
 { name: 'HbA1c', nameHe: 'ืกื•ื›ืจ ืžื•ืฆืžื“', unit: '%', min: 0, max: 5.6 },
 { name: 'Glucose', nameHe: 'ื’ืœื•ืงื•ื–', unit: 'mg/dL', min: 70, max: 99 },
 { name: 'Cholesterol', nameHe: 'ื›ื•ืœืกื˜ืจื•ืœ', unit: 'mg/dL', min: 0, max: 200 },
 { name: 'Testosterone', nameHe: 'ื˜ืกื˜ื•ืกื˜ืจื•ืŸ', unit: 'ng/dL', min: 350, max: 1000 },
 { name: 'Omega-3 Index',nameHe: 'ืื™ื ื“ืงืก ืื•ืžื’ื”',unit: '%', min: 8, max: 12 },
 { name: 'CRP', nameHe: 'CRP ื“ืœืงืช', unit: 'mg/L', min: 0, max: 1 },
];

// โ”€โ”€โ”€ ืคื•ื ืงืฆื™ื™ืช ืขื–ืจ: ืงื‘ื™ืขืช ืกื˜ื˜ื•ืก ื”ืขืจืš โ”€โ”€โ”€
const getStatus = (value, min, max) => {
 if (value < min * 0.7) return { label: 'ื ืžื•ืš ืžืื•ื“ โš ๏ธ', color: '#ef4444', critical: true };
 if (value < min) return { label: 'ื ืžื•ืš ืžื”ื ื•ืจืžื”', color: '#f59e0b', critical: false };
 if (value > max * 1.3) return { label: 'ื’ื‘ื•ื” ืžืื•ื“ โš ๏ธ', color: '#ef4444', critical: true };
 if (value > max) return { label: 'ื’ื‘ื•ื” ืžื”ื ื•ืจืžื”', color: '#f59e0b', critical: false };
 return { label: 'ืชืงื™ืŸ โœ“', color: '#10b981', critical: false };
};

export default function BiomarkerEntry({ userId, onSaved }) {
 const [selectedMarker, setSelectedMarker] = useState(null);
 const [value, setValue] = useState('');
 const [searchQuery, setSearchQuery] = useState('');
 const [saving, setSaving] = useState(false);

 // โ”€โ”€โ”€ AutoComplete: ื—ื™ืคื•ืฉ ืžื“ื“ื™ื โ”€โ”€โ”€
 const filteredMarkers = BIOMARKERS_DB.filter(m =>
 m.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
 m.nameHe.includes(searchQuery)
 );

 // โ”€โ”€โ”€ ื—ื™ืฉื•ื‘ ืกื˜ื˜ื•ืก ื”ืขืจืš ื”ื ื•ื›ื—ื™ โ”€โ”€โ”€
 const currentValue = parseFloat(value);
 const status = selectedMarker && !isNaN(currentValue)
 ? getStatus(currentValue, selectedMarker.min, selectedMarker.max)
 : null;

 // โ”€โ”€โ”€ ืฉืžื™ืจื” ืžื•ืฆืคื ืช ืœ-Supabase โ”€โ”€โ”€
 const handleSave = async () => {
 if (!selectedMarker || !value) return;
 setSaving(true);

 try {
 // Supabase ืžืฆืคื™ืŸ ืื•ื˜ื•ืžื˜ื™ืช ื‘ืชืขื‘ื•ืจื” (TLS)
 // ื”ืฆืคื ืช ืฉื“ื•ืช ืกืคืฆื™ืคื™ื™ื ื‘ืจืžืช DB, ืจืื” platform.html
 const { error } = await supabase
 .from('biomarker_logs')
 .insert({
 user_id: userId,
 marker_name: selectedMarker.name,
 value: currentValue,
 unit: selectedMarker.unit,
 normal_min: selectedMarker.min,
 normal_max: selectedMarker.max,
 is_critical: status?.critical || false,
 test_date: new Date().toISOString().split('T')[0]
 });

 if (error) throw error;

 // ืื ืขืจืš ืงืจื™ื˜ื™, ืฉืœื— ื”ืชืจืื” ืœืจื•ืคื (Safety Layer)
 if (status?.critical) {
 await triggerSafetyAlert(userId, selectedMarker.name, currentValue);
 }

 onSaved?.(); // callback ืœื”ื•ืจื”
 setValue('');
 setSelectedMarker(null);

 } catch (err) {
 console.error('ืฉื’ื™ืื” ื‘ืฉืžื™ืจื”:', err);
 } finally {
 setSaving(false);
 }
 };

 return (
 <div className="biomarker-entry">
 {/* โ”€โ”€โ”€ ื—ื™ืคื•ืฉ ืžื“ื“ โ”€โ”€โ”€ */}
 <input value={searchQuery} onChange={e => setSearchQuery(e.target.value)}
 placeholder="ื—ืคืฉ ืžื“ื“: ื•ื™ื˜ืžื™ืŸ D, ื‘ืจื–ืœ..." inputMode="text" />

 {/* โ”€โ”€โ”€ Autocomplete โ”€โ”€โ”€ */}
 {searchQuery && filteredMarkers.map(m => (
 <div key={m.name} onClick={() => { setSelectedMarker(m); setSearchQuery(m.nameHe); }}>
 <span>{m.nameHe}</span><span>{m.min}-{m.max} {m.unit}</span>
 </div>
 ))}

 {/* โ”€โ”€โ”€ ืงืœื˜ ื ื•ืžืจื™ โ”€โ”€โ”€ */}
 <input value={value} readOnly inputMode="numeric" placeholder="ื”ื–ืŸ ืขืจืš" />

 {/* โ”€โ”€โ”€ ืกืงืืœื” ื•ื™ื–ื•ืืœื™ืช โ”€โ”€โ”€ */}
 {status && (
 <div style={{ color: status.color }}>
 {status.critical && <span>โš ๏ธ ืคื ื” ืœืจื•ืคื</span>}
 <span>{status.label}</span>
 </div>
 )}

 <button onClick={handleSave} disabled={saving || !selectedMarker || !value}>
 {saving ? 'ืฉื•ืžืจ...' : '๐Ÿ”’ ืฉืžื•ืจ ืžื•ืฆืคืŸ'}
 </button>
 </div>
 );
}
๐Ÿ›ก๏ธ ื—ืœืง 4, Safety
Safety Layer
ื”ืžื ื’ื ื•ืŸ ืฉืกื•ืจืง ืขืจื›ื™ื ืงื™ืฆื•ื ื™ื™ื ื•ืขื•ืฆืจ ื”ืคืงืช ืคืจื•ื˜ื•ืงื•ืœ. ื—ื•ื‘ื” ืžื‘ื—ื™ื ื” ืžืฉืคื˜ื™ืช ื•ืจืคื•ืื™ืช.
๐Ÿšจ ื“ืžื• Safety Alerts
Live Demo
๐Ÿšจ
ื“ื’ืœ ืื“ื•ื, ืขืจืš ืงืจื™ื˜ื™
ื”ืคืงืช ื”ืคืจื•ื˜ื•ืงื•ืœ ื”ื•ืคืกืงื”. ืขืจืš ื—ืจื™ื’ ืžืกื•ื›ืŸ ื–ื•ื”ื”.
Glucose: 48 mg/dL (ื ื•ืจืžื”: 70-99) ื”ื™ืคื•ื’ืœื™ืงืžื™ื”!
๐Ÿ“‹ ื”ื•ื“ืขื” ืœืžืฉืชืžืฉ: "ื ื ืœืคื ื•ืช ืœืจื•ืคื ื‘ื“ื—ื™ืคื•ืช, ื”ืขืจืš ื—ื•ืจื’ ืžื”ื˜ื•ื•ื— ื”ื‘ื˜ื•ื—. ืœื ื ื™ืชืŸ ืœื”ืคื™ืง ืคืจื•ื˜ื•ืงื•ืœ ืชื•ืกืคื™ื."
๐Ÿ“ง ื”ืชืจืื” ื ืฉืœื—ื” ืœืจื•ืคื ื”ืžืœื•ื•ื”
โš ๏ธ
ืื–ื”ืจื”, ืขืจืš ื’ื‘ื•ืœื™
ื”ืคืจื•ื˜ื•ืงื•ืœ ื”ื•ืคืง ืืš ื ื•ืกืฃ Disclaimer. ืžื•ืžืœืฅ ืœื”ืชื™ื™ืขืฅ ืขื ืจื•ืคื.
Vitamin D: 18 ng/ml (ื ื•ืจืžื”: 30-100) ื—ืกืจ ืžืฉืžืขื•ืชื™
โœ…
ืชืงื™ืŸ, ืคืจื•ื˜ื•ืงื•ืœ ื”ื•ืคืง
ื›ืœ ื”ืขืจื›ื™ื ื‘ื˜ื•ื•ื— ื”ื‘ื˜ื•ื—. ื”ืคืจื•ื˜ื•ืงื•ืœ ื”ื•ืคืง ื‘ื”ืฆืœื—ื”.
ื›ืœ 14 ื”ืžื“ื“ื™ื ืชืงื™ื ื™ื, ืื™ืŸ ื“ื’ืœื™ื ืื“ื•ืžื™ื
๐Ÿ›ก๏ธ safety-layer.js Safety Critical
ื”ืขืชืง
/**
 * โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
 * Longevix Safety Layer, ืฉื›ื‘ืช ื”ื‘ื˜ื™ื—ื•ืช
 * โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
 *
 * โš ๏ธ CRITICAL: ืงื•ื“ ื–ื” ืื—ืจืื™ ืขืœ ื‘ื˜ื™ื—ื•ืช ื”ืžืฉืชืžืฉื™ื
 * ื›ืœ ืฉื™ื ื•ื™ ื—ื™ื™ื‘ ืœืขื‘ื•ืจ ื‘ื“ื™ืงื” ืฉืœ ื’ืœื™ืช ืคืจืฅ!
 *
 * ื”ืœื•ื’ื™ืงื”:
 * 1. ืกื•ืจืง ื›ืœ ืขืจื›ื™ ื‘ื“ื™ืงื•ืช ื”ื“ื
 * 2. ืžืฉื•ื•ื” ืœืขืจื›ื™ ืงื™ืฆื•ืŸ ืžืกื•ื›ื ื™ื
 * 3. ืขื•ืฆืจ ืคืจื•ื˜ื•ืงื•ืœ / ืฉื•ืœื— ื”ืชืจืื•ืช ืœืคื™ ื—ื•ืžืจื”
 */

// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// ืกืฃ ื”ืขืจื›ื™ื ื”ืงืจื™ื˜ื™ื™ื, ื›ืœ ืขืจืš ืžื—ื•ืฅ ืœื˜ื•ื•ื— = ืขืฆื™ืจื” ืžืœืื”
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const CRITICAL_THRESHOLDS = {
 'Glucose': { min: 54, max: 400, reason: 'ื”ื™ืคื•ื’ืœื™ืงืžื™ื” / ื”ื™ืคืจื’ืœื™ืงืžื™ื” ืงื™ืฆื•ื ื™ืช' },
 'Hemoglobin': { min: 7, max: 20, reason: 'ืื ืžื™ื” ืงืฉื” / ืคื•ืœื™ืฆื™ืชืžื™ื”' },
 'TSH': { min: 0.1, max: 10, reason: 'ืชืช/ื™ืชืจ-ืคืขื™ืœื•ืช ื‘ืœื•ื˜ืช ืชืจื™ืก ืงื™ืฆื•ื ื™ืช' },
 'Potassium': { min: 3.0, max: 6.0, reason: 'ื”ืคืจืขืช ืืœืงื˜ืจื•ืœื™ื˜ื™ื ืžืกื›ื ืช ื—ื™ื™ื' },
 'Sodium': { min: 125, max: 155, reason: 'ื”ื™ืคื•/ื”ื™ืคืจ ื ื˜ืจืžื™ื” ืงื™ืฆื•ื ื™ืช' },
 'Creatinine': { min: 0, max: 4, reason: 'ืื™-ืกืคื™ืงืช ื›ืœื™ื•ืช' },
 'Calcium': { min: 7.5, max: 12, reason: 'ื”ืคืจืขืช ืกื™ื“ืŸ ืงื™ืฆื•ื ื™ืช' },
 'Testosterone': { min: 50, max: 2000, reason: 'ืจืžื•ืช ืงื™ืฆื•ื ื™ื•ืช, ื‘ื“ื™ืงื” ื ื“ืจืฉืช' },
};

// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// ืขืจื›ื™ ืื–ื”ืจื” (warning) ืคืจื•ื˜ื•ืงื•ืœ ื™ื•ืคืง ืืš ืขื ื”ืขืจื”
// โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
const WARNING_THRESHOLDS = {
 'Vitamin D': { min: 20, max: 150, reason: 'ื—ืกืจ ื•ื™ื˜ืžื™ืŸ D, ืžื™ื ื•ืŸ ื’ื‘ื•ื” ื ื“ืจืฉ' },
 'Ferritin': { min: 15, max: 400, reason: 'ืžื—ืกื•ืจ ื‘ืจื–ืœ' },
 'HbA1c': { min: 0, max: 6.5, reason: 'ืคืจื”-ืกื•ื›ืจืช / ืกื•ื›ืจืช' },
 'Cholesterol': { min: 0, max: 240, reason: 'ื›ื•ืœืกื˜ืจื•ืœ ื’ื‘ื•ื”' },
 'CRP': { min: 0, max: 3, reason: 'ื“ืœืงืช ืžื•ื’ื‘ืจืช' },
};

/**
 * scanBiomarkersForAlerts, ื”ืกื•ืจืง ื”ืจืืฉื™
 *
 * @param {Array} biomarkers - ืžืขืจืš ื‘ื“ื™ืงื•ืช ื“ื
 * @returns {Object} { canProceed, level, alerts, blockers }
 */
function scanBiomarkersForAlerts(biomarkers) {
 const criticalAlerts = [];
 const warnings = [];

 for (const bm of biomarkers) {

 // โ”€โ”€โ”€ ื‘ื“ื™ืงืช ืขืจื›ื™ื ืงืจื™ื˜ื™ื™ื โ”€โ”€โ”€
 const critThreshold = CRITICAL_THRESHOLDS[bm.marker_name];
 if (critThreshold) {
 if (bm.value < critThreshold.min || bm.value > critThreshold.max) {
 criticalAlerts.push({
 marker: bm.marker_name,
 value: bm.value,
 threshold: critThreshold,
 reason: critThreshold.reason,
 // ื”ื•ื“ืขื” ืฉืชื•ืฆื’ ืœืžืฉืชืžืฉ
 userMessage: `ื ื ืœืคื ื•ืช ืœืจื•ืคื, ืขืจืš ${bm.marker_name} (${bm.value}) ื—ื•ืจื’ ืžื”ื˜ื•ื•ื— ื”ื‘ื˜ื•ื—`
 });
 }
 }

 // โ”€โ”€โ”€ ื‘ื“ื™ืงืช ืขืจื›ื™ ืื–ื”ืจื” โ”€โ”€โ”€
 const warnThreshold = WARNING_THRESHOLDS[bm.marker_name];
 if (warnThreshold) {
 if (bm.value < warnThreshold.min || bm.value > warnThreshold.max) {
 warnings.push({
 marker: bm.marker_name,
 value: bm.value,
 reason: warnThreshold.reason,
 userMessage: `${bm.marker_name}: ${warnThreshold.reason} ืžื•ืžืœืฅ ืœื”ืชื™ื™ืขืฅ ืขื ืจื•ืคื`
 });
 }
 }
 }

 return {
 canProceed: criticalAlerts.length === 0, // false = ืขืฆื•ืจ ื”ื›ืœ!
 level: criticalAlerts.length > 0 ? 'CRITICAL' : warnings.length > 0 ? 'WARNING' : 'SAFE',
 criticalAlerts,
 warnings
 };
}

/**
 * generateSafeProtocol, ืžืขื˜ืคืช ื‘ื˜ื•ื—ื” ืœ-calculateProtocol
 * โ”€โ”€โ”€ ืชืžื™ื“ ืœื”ืฉืชืžืฉ ื‘ื–ื”, ืœื ื‘-calculateProtocol ื™ืฉื™ืจื•ืช! โ”€โ”€โ”€
 */
async function generateSafeProtocol(userId, quizData, biomarkers) {

 // ืฉืœื‘ 1: ืกืจื™ืงืช ื‘ื˜ื™ื—ื•ืช, ื—ื•ื‘ื” ืœืคื ื™ ื›ืœ ื“ื‘ืจ
 const safetyResult = scanBiomarkersForAlerts(biomarkers);

 // ืฉืœื‘ 2: ืขืจื›ื™ื ืงืจื™ื˜ื™ื™ื, ืขืฆื•ืจ ื”ื›ืœ!
 if (!safetyResult.canProceed) {
 // ืฉืœื— ื”ืชืจืื” ืœืจื•ืคื ื“ืจืš Supabase
 await notifyDoctor(userId, safetyResult.criticalAlerts);

 // ื”ื—ื–ืจ ืฉื’ื™ืื”, ืืœ ืชืžืฉื™ืš ืœืคืจื•ื˜ื•ืงื•ืœ!
 return {
 success: false,
 blocked: true,
 level: 'CRITICAL',
 userMessage: `โš ๏ธ ืœื ื ื™ืชืŸ ืœื”ืคื™ืง ืคืจื•ื˜ื•ืงื•ืœ. ` +
 safetyResult.criticalAlerts.map(a => a.userMessage).join('. '),
 doctorAlerted: true
 };
 }

 // ืฉืœื‘ 3: ื™ืฆื™ืจืช ืคืจื•ื˜ื•ืงื•ืœ (ืจืง ืื ืขื‘ืจ ื‘ื˜ื™ื—ื•ืช)
 const protocol = await calculateProtocol(quizData, biomarkers);

 // ืฉืœื‘ 4: ื”ื•ืกืคืช ืื–ื”ืจื•ืช ืœืคืจื•ื˜ื•ืงื•ืœ ืื ื™ืฉ
 if (safetyResult.warnings.length > 0) {
 protocol.warnings = safetyResult.warnings;
 protocol.disclaimer = "โš ๏ธ ื–ื•ื”ื• ืขืจื›ื™ื ื’ื‘ื•ืœื™ื™ื, ืžื•ืžืœืฅ ืœื”ืชื™ื™ืขืฅ ืขื ืจื•ืคื ืœืคื ื™ ื”ืชื—ืœืช ื”ืคืจื•ื˜ื•ืงื•ืœ";
 }

 return { success: true, blocked: false, level: safetyResult.level, protocol };
}

// โ”€โ”€โ”€ ืฉืœื™ื—ืช ื”ืชืจืื” ืœืจื•ืคื ื“ืจืš Supabase โ”€โ”€โ”€
async function notifyDoctor(userId, criticalAlerts) {
 await supabase.from('doctor_alerts').insert({
 user_id: userId,
 alert_type: 'CRITICAL_BIOMARKER',
 alerts: criticalAlerts,
 created_at: new Date().toISOString(),
 resolved: false
 });
 // ืฉืœื— ื’ื ืื™ืžื™ื™ืœ/SMS ืœืจื•ืคื ื“ืจืš Supabase Edge Function
}

export { generateSafeProtocol, scanBiomarkersForAlerts, CRITICAL_THRESHOLDS };
โœ… ืฆ'ืง-ืœื™ืกื˜ ื ื™ื”ื•ืœื™
ืžืขืงื‘ ืคื™ืชื•ื—
ืœื—ืฅ ืขืœ ื›ืœ ืžืฉื™ืžื” ื›ืฉื”ื™ื ื”ื•ืฉืœืžื”. ื”ืกื˜ื˜ื•ืก ื ืฉืžืจ ื‘ื“ืคื“ืคืŸ.
โœ“
๐Ÿ’ณ ื—ื™ื‘ื•ืจ Stripe, ืชืฉืœื•ื ืœืคื ื™ ื—ืฉื™ืคืช ืชื•ื‘ื ื•ืชStripe Elements โ† ื”ื˜ืžืขื” ื‘ืชื•ืš ื”ืืชืจ (ืœื redirect). ืฉื“ืจื•ื’ ื”ืžืจื” ื‘-20%.
ื“ื—ื•ืฃ ืจืืฉื•ืŸ
โœ“
๐Ÿ‘ฉโ€๐Ÿ”ฌ ืžืžืฉืง ื’ืœื™ืช, ื”ื•ืกืคืช ืžื—ืงืจื™ื ืœ-DBื“ืฃ Admin ืคืฉื•ื˜: ื”ื•ืกืฃ ืฉื ืชื•ืกืฃ, PMID, ืžื™ื ื•ืŸ, ื•ืœื—ืฅ ืฉืžื•ืจ. ื’ืœื™ืช ืžื ื”ืœืช ืžืžื ื• ืืช ื”-Evidence Library.
ืฉื‘ื•ืข 1
โœ“
๐Ÿ“ฑ PWA, ื•ื“ื ืฉื ื™ืชืŸ ืœื”ืชืงื™ืŸ ื›ืืคืœื™ืงืฆื™ื”manifest.json + sw.js ื›ื‘ืจ ืžื•ื›ื ื™ื. ื‘ื“ื•ืง Chrome โ†’ Install button ืžื•ืคื™ืข.
ื›ื‘ืจ ืžื•ื›ืŸ
โœ“
๐Ÿ”’ ื”ืฆืคื ื”, ืฉื“ื•ืช ืจืคื•ืื™ื™ื ื‘-Supabaseื”ืคืขืœ pgcrypto. ืฉื“ื•ืช email + quiz_answers โ†’ BYTEA ืžื•ืฆืคืŸ. ื‘ื“ื•ืง ื‘-Supabase Dashboard โ†’ Vault.
ื—ื•ื‘ื” HIPAA
โœ“
๐Ÿšจ ื”ืชืจืื•ืช ืจื•ืคื, Safety Layerื˜ื‘ืœืช doctor_alerts ื‘-Supabase + Edge Function ืœืฉืœื™ื—ืช SMS/ืื™ืžื™ื™ืœ ืœืจื•ืคื ื›ืฉื™ืฉ ืขืจืš ืงืจื™ื˜ื™.
ื‘ื˜ื™ื—ื•ืช
โœ“
โœ… ื’ืœื™ืช ืžืืฉืจืช, ื›ืœ ื”ืชื•ื›ืŸ ื”ืจืคื•ืื™ืฉืœื— ืืช evidence-engine.html ืœื’ืœื™ืช ืœืื™ืฉื•ืจ ืžื™ื ื•ื ื™ื ื•ืžื ื’ื ื•ื ื™ื. ืœืœื ืื™ืฉื•ืจื” ืืœ ืชืคืจืกื.
ืงืจื™ื˜ื™
โœ“
โš–๏ธ ืขื•"ื“, ืฉืขืช ื™ื™ืขื•ืฅ ืœืคื ื™ Launchืœืืฉืจ Privacy Policy, Disclaimer ืจืคื•ืื™, ื•ืื—ืจื™ื•ืช ื’ืœื™ืช. ืขื•ืœื” ~โ‚ช500, ื—ื•ืกืš ื”ืจื‘ื”.
ืœืคื ื™ Launch
โœ“
๐Ÿ“ง ืžื™ื™ืœ ืื•ื˜ื•ืžื˜ื™, ืื—ืจื™ ืฉืืœื•ืŸBrevo/Mailchimp. ื ื•ืฉื: "ื”ืฆื™ื•ืŸ ืฉืœืš ื”ื•ื 64, ื”ื ื” ืื™ืš ืžื’ื™ืขื™ื ืœ-90". ื”ื‘ืจื–ืœ ื”ื›ื™ ื—ื.
Retention
โœ“
๐ŸŒ longevix.co.il, DNS ืžื—ื•ื‘ืจthriving-seahorse-86e17d.netlify.app ื›ื‘ืจ ืขื•ื‘ื“. DNS ืžืชืคืฉื˜ ืขื“ 48 ืฉืขื•ืช.
ืคืขื™ืœ
โœ