Skip to content

รายงานการออกแบบและการเชื่อมต่อฐานข้อมูล Supabase (Supabase Integration & Optimization Report)

โครงการวิจัย: TaijiFlow AI - PhD Research (Phase 2 & Phase 3)
ประเภทรายงาน: เอกสารประวัติการเขียนโค้ดและการออกแบบระบบ (System Design & Implementation)


1. วัตถุประสงค์ (Objectives)

ย้ายสถาปัตยกรรมแอปพลิเคชันจากระบบประมวลผลโลคอลทั้งหมดแบบเดิม (Zero-Server Architecture) ซึ่งไม่มีการระบุตัวตนและบันทึกประวัติใดๆ ไปสู่ระบบคลาวด์แบบเซิร์ฟเวอร์เลส (Client-Server / Serverless Architecture) โดยมีวัตถุประสงค์ดังนี้:

  1. จัดเก็บโปรไฟล์ สรีระร่างกาย และสถิติพัฒนาการส่วนบุคคลของผู้เข้าร่วมการทดลอง
  2. บันทึกและบีบอัดข้อมูลพิกัดโครงร่างข้อต่อร่างกาย (Joint Coordinates Dataset) ตลอดช่วงการซ้อมรำ เพื่อนำมาประมวลผลต่อยอดเป็นชุดข้อมูลฝึกสอน (Labeled Training Dataset) สำหรับแบบจำลอง Deep Learning
  3. รับประกันความปลอดภัยและการเข้าถึงข้อมูลส่วนตัวตามนโยบายความเป็นส่วนตัวและสิทธิ์ความปลอดภัยสูงสุด (Data Privacy & RLS Storage)

2. การออกแบบโครงสร้างฐานข้อมูล (Database Schema Design)

เราได้ออกแบบตารางและระบบ Trigger บนระบบฐานข้อมูล PostgreSQL ของ Supabase ดังนี้:

2.1 ตารางประวัติและโปรไฟล์ผู้ใช้ (public.users)

ใช้เก็บข้อมูลโปรไฟล์และกายภาพเริ่มต้นที่จำเป็นสำหรับคำนวณและปรับเทียบอัตราส่วนโครงกระดูก:

  • id (uuid, Primary Key, references auth.users.id on delete cascade)
  • display_name (text) — ชื่อแสดงผล
  • experience_level (text, default: 'beginner') — ระดับทักษะผู้รำ (beginner, intermediate, advanced)
  • height (numeric, nullable) — ส่วนสูง (หน่วยเซนติเมตร) ใช้ปรับสัดส่วนกล้อง
  • weight (numeric, nullable) — น้ำหนัก (หน่วยกิโลกรัม)
  • consent_accepted (boolean, default: false) — สถานะยอมรับข้อตกลงความเป็นส่วนตัวและแพทย์ (IRB Consent)
  • research_group (text, default: 'experimental') — กลุ่มวิจัยสำหรับการทำ RCT (experimental หรือ control)
  • created_at / updated_at (timestamp with time zone)

2.2 ตารางสรุปเซสชันการซ้อมรำ (public.training_sessions)

ใช้บันทึกผลคะแนนและค่าผิดพลาดสะสมรายรอบการรำ เพื่อนำมาแสดงสถิติและดึงพาธไฟล์บันทึก:

  • id (uuid, Primary Key, default: gen_random_uuid())
  • user_id (uuid, references public.users.id on delete cascade)
  • session_id (text, Unique) — รหัสเซสชันเฉพาะที่สร้างฝั่ง Client
  • exercise (text) — ชื่อท่ารำที่ฝึกซ้อม (เช่น cloud_hand, rollback_r)
  • level (text) — ระดับเกณฑ์ความยาก (L1, L2, L3)
  • score (numeric) — คะแนนเฉลี่ยความถูกต้อง (AQA Score, 0-100)
  • grade (text) — เกรดประเมินผลสัมพัทธ์ (A, B, C, D, F)
  • duration (numeric) — ระยะเวลาที่รำจริง (หน่วยวินาที)
  • total_frames (integer) — จำนวนเฟรมทั้งหมดที่บันทึก
  • file_path (text) — ลิงก์ที่อยู่ไฟล์พิกัดละเอียดใน Storage (.json)
  • category_scores (jsonb) — คะแนนเฉลี่ยแยกหลักการไท่จี๋ 6 ด้าน (Path, Balance, Continuity, Synchrony, Stability, Softness)
  • created_at (timestamp with time zone)

2.3 ระบบสร้างโปรไฟล์อัตโนมัติ (Postgres Auto-Trigger)

เพื่อความสะดวกในการเก็บประวัติ ทันทีที่มีการสมัครสมาชิกในระบบ Auth ระบบ Database ของ Supabase จะรัน Function เพื่อสร้างโปรไฟล์เริ่มต้นลงตาราง public.users ทันที:

sql
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS trigger AS $$
BEGIN
  INSERT INTO public.users (id, display_name, experience_level, consent_accepted)
  VALUES (
    new.id,
    COALESCE(new.raw_user_meta_data->>'display_name', 'Taiji Practitioner'),
    'beginner',
    COALESCE((new.raw_user_meta_data->>'consent_accepted')::boolean, false)
  );
  RETURN new;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();

3. นโยบายความปลอดภัยและการเข้าถึงข้อมูล (Row Level Security - RLS)

เพื่อป้องกันความเสี่ยงด้านความเป็นส่วนตัวของข้อมูลผู้ป่วย/อาสาสมัคร ระบบได้เปิดใช้งาน RLS ในทุกตารางและโฟลเดอร์เก็บไฟล์:

  1. สิทธิ์ตาราง public.users:
    • เลือกดูข้อมูล: เฉพาะผู้ใช้ที่ล็อกอินแล้วและเป็นเจ้าของบัญชีเท่านั้น (auth.uid() = id)
    • ปรับปรุงข้อมูล: เฉพาะเจ้าของบัญชีเท่านั้น (auth.uid() = id)
  2. สิทธิ์ตาราง public.training_sessions:
    • เลือกดูข้อมูล: ดึงข้อมูลประวัติเฉพาะที่เป็นของตนเองเท่านั้น (auth.uid() = user_id)
    • บันทึกข้อมูล: บันทึกประวัติเฉพาะของตนเองเท่านั้น (auth.uid() = user_id)
  3. สิทธิ์จัดเก็บไฟล์พิกัดละเอียด (Supabase Storage Bucket: training-sessions):
    • กำหนดสิทธิ์ให้โฟลเดอร์ไฟล์มีรูปแบบ training-sessions/{user_id}/{session_id}.json
    • กำหนดนโยบาย RLS ให้ตรวจสอบสิทธิ์เข้าถึงโดยตรวจชื่อโฟลเดอร์แรกให้แมตช์กับ UID ของผู้ที่เข้าถึงเท่านั้น:
      sql
      -- Policy สำหรับอัปเดตและอ่านไฟล์
      (storage.foldername(name))[1] = auth.uid()::text

4. ท่อส่งข้อมูลและการบีบอัดระดับเฟรม (Data Pipeline & Minimization)

เพื่อรองรับการดึงข้อมูลดิบไปประมวลผลต่อด้วย Machine Learning ระบบได้พัฒนาการลดรูปพิกัดและการสร้าง Pipeline ที่เสถียรดังนี้:

4.1 การบีบอัดข้อมูลร่างกาย (Landmark Minimization)

พิกัด MediaPipe Landmarks ทั้งหมด 33 จุด ประกอบด้วยแกน x, y, z และความน่าเชื่อถือ visibility ทศนิยมเดิมมีความยาวถึง 15 ตำแหน่ง ซึ่งกินพื้นที่มาก ไฟล์ซ้อม 5 นาทีจะมีขนาดมากกว่า 6-8 MB ระบบจึงแก้ไขดังนี้:

  1. ลดรูปทศนิยมเหลือ 4 ตำแหน่ง: ปรับลดโดยปัดเศษผ่าน Math helper:
    javascript
    const round4 = (num) => Math.round(num * 10000) / 10000;
    ส่งผลให้ขนาดไฟล์ JSON สุทธิลดลงทันที 20-30% (เหลือเฉลี่ย ~1.2 MB ต่อรอบการซ้อม 5 นาที)
  2. การบันทึกเวลาสัมพัทธ์แบบมิลลิวินาที (t): แทนที่จะเก็บเวลาจริง (Epoch Timestamp) ระบบได้คำนวณระยะเวลาต่างตั้งแต่ออกตัวเริ่มรำในหน่วยมิลลิวินาที ทำให้ข้อมูลมีความเสถียร เหมาะกับการรันโมเดลอนุกรมเวลา (Temporal Sequence Model) เช่น LSTM และ Transformer
  3. การคลีนป้ายข้อมูลความผิดพลาด (Heuristics Labeling): นำฟีดแบ็กความผิดพลาดรายเฟรมมาถอดรหัสลบอักขระพิเศษ บันทึกเป้นอาเรย์ labels ในไฟล์พิกัด เพื่อทำหน้าที่เป็นชุดข้อมูลที่มีคำตอบเฉลยสำเร็จรูป (Labeled Dataset) ในตัว

4.2 ระบบอัปโหลดอัตโนมัติและ Asynchronous Loop

แอปพลิเคชันจะรวบรวมประวัติและพิกัดลงใน RAM ระหว่างเล่น เมื่อผู้ฝึกสิ้นสุดการซ้อม:

  1. ข้อมูลทั้งหมดจะถูกประกอบเข้าชุด (Dataset Assembly)
  2. ระบบเรียก Asynchronous fetch เพื่ออัปโหลดไฟล์ JSON ขึ้น Supabase Storage และแทรกแถวสถิติลงตาราง Database ไปพร้อมๆ กัน โดยไม่ล็อกหน้าอินเตอร์เฟสผู้ใช้
  3. ระบบจะแสดงแถบข้อความ Toast Notification สีเขียวแจ้งเมื่ออัปโหลดคลาวด์สำเร็จ
  4. ระบบสำรอง (CORS / Network Fallback): หากขาดการเชื่อมต่ออินเทอร์เน็ตหรือติดปัญหาเครือข่าย ระบบจะเปลี่ยนเป็นแจ้งเตือนข้อความเตือน และดาวน์โหลดไฟล์ JSON บันทึกตรงลงโฟลเดอร์เครื่องคอมพิวเตอร์ของผู้ใช้ เพื่อรับประกันว่าข้อมูลวิจัยของอาสาสมัครจะไม่สูญหายเด็ดขาด

TaijiFlow AI Research & Development Project (Chán Sī Jìng Biomechanics)