โครงสร้างข้อมูล

ดีไซน์ฐานข้อมูล — event-driven, multi-tenant และ config-driven เพื่อให้ข้อมูลนำไปใช้ต่อได้จริง

📝
Event-driven

ทุกพฤติกรรมเขียนเป็น Event — วิเคราะห์ทั้งหมดต่อยอดจากตรงนี้ ไม่ต้องย้อนเติมข้อมูลทีหลัง

🏢
Multi-tenant

ทุกตารางมี orgId ทุก query ผ่าน forOrg(orgId) ข้อมูลข้ามองค์กรไม่หลุดหากัน

🧩
Config-driven

ความต่างของแต่ละองค์กรอยู่ใน settings และ FieldDefinition JSONB — รับลูกค้าใหม่ = ตั้งค่า ไม่ใช่ fork โค้ด

📒
บัญชีแต้ม

PointTransaction คือแหล่งความจริง Member.points เป็นแคชที่ sync ตลอด

🔒
พร้อม PDPA

ประวัติ Consent มีเวอร์ชัน + ความลับเข้ารหัส (LineChannel) ตั้งแต่วันแรก

Organizationรากของ tenant

องค์กร (MST Golf) — พฤติกรรมปรับผ่าน settings JSONB ไม่ต้องแก้โค้ด

idcuidPK
slugstringunique
planenumSTARTER/GROWTH/PRO
settingsjsonbแต้ม ระดับ ฟีเจอร์ ข้อความ crm
Memberลูกค้า

ลูกค้า 1 คน — โปรไฟล์กอล์ฟเก็บใน attributes JSONB (ไม่มีคอลัมน์ตายตัว)

idcuidPK
orgIdcuid→ Organization
lineUserIdstringunique ต่อ org
attributesjsonbแฮนดิแคป แบรนด์ ความสนใจ…
pointsintแคชของ ledger
tierstring
consentAtdatetimeธงย่อ PDPA
Eventบันทึกพฤติกรรม

ทุกพฤติกรรม — RFM กรวย churn cohort คำนวณจากตรงนี้ทั้งหมด

idcuidPK
orgIdcuid→ Organization
memberIdcuid→ Member
typeenumREGISTER, PURCHASE, VISIT…
payloadjsonbPURCHASE = {amount, currency, items}
occurredAtdatetime
PointTransactionบัญชีแต้ม

แหล่งความจริงของแต้ม — Member.points เป็นแค่แคชของตารางนี้

idcuidPK
orgIdcuid→ Organization
memberIdcuid→ Member
deltaint+/- แต้ม
reasonstringsignup_bonus, purchase…
FieldDefinitionconfig

ขับฟอร์มสมัครแบบ dynamic — เพิ่มฟิลด์ได้โดยไม่ต้องแก้โค้ด

orgIdcuid→ Organization
keystringคีย์ใน attributes
typeenumTEXT/NUMBER/SELECT/MULTISELECT…
requiredbool
optionsjsonb
ConsentPDPA

ประวัติความยินยอมแบบมีเวอร์ชัน — ตรวจสอบย้อนหลังและสิทธิ์ขอลบข้อมูล

orgIdcuid→ Organization
memberIdcuid→ Member
purposestring
versionstring
textSnapshotstringข้อความที่แสดง
LineChannelความลับ

credential LINE ต่อ org เข้ารหัส AES-256-GCM ตอนเก็บ

orgIdcuid→ Organization
channelSecretEncstringเข้ารหัส
channelAccessTokenEncstringเข้ารหัส
Userพนักงาน

บัญชีล็อกอิน dashboard (OWNER/ADMIN/STAFF)

orgIdcuid→ Organization
emailstringunique ต่อ org
roleenum