ฟอร์ม (Form Builder)
ภาพรวม
Form builder ให้แอดมินสร้างฟอร์มเก็บข้อมูลลูกค้า เช่น งาน lead generation หรือการลงทะเบียน สมาชิก แล้วเปิดให้กรอกผ่าน LIFF หรือลิงก์สาธารณะ คำตอบที่ได้สามารถ เขียนกลับเป็น attribute ของเพื่อน LINE และเปลี่ยนสถานะผู้ใช้จาก guest เป็น member ได้
จุดที่ควรทราบเกี่ยวกับการออกแบบคือ โครงสร้างคำถามทั้งฟอร์มถูกเก็บเป็น JSONB ก้อนเดียว
ไม่มีตารางคำถามหรือตัวเลือกแยกออกมา โดยมี form_builder_rule ทำหน้าที่เป็น master
ของกติกา validate สำหรับฟิลด์แต่ละชนิด
โครงสร้างข้อมูลหลัก
form_builder (model FormBuilder)
title,description,questionsJSONB,themeJSONBthank_youJSONB (nullable) — ค่าNULLมีความหมายเทียบเท่า{"mode":"default"}คือใช้หน้าขอบคุณมาตรฐานภาษาไทยform_hashVARCHAR(50) unique — คีย์สาธารณะที่ใช้ในลิงก์ และเป็นเป้าหมายของ FK จากฝั่ง submissionstatus(enumFormBuilderStatus) —active/inactive/draft/delete- ช่วงเวลาเปิดรับ
start_date/end_dateและตัวนับresponses_count - พฤติกรรมของฟอร์ม
require_line_login(default true),one_time_submissionและconvert_to_member field_attribute_mappingsJSONB — map คำถามไปยัง attribute ของline_userprofile_mappingJSONB (เพิ่มด้วย manual SQL) — เติมข้อมูลอัตโนมัติจากฐานลูกค้า และเก็บคีย์ย่อยotpว่าฟิลด์ใดต้องยืนยันตัวตนline_oa_idFK (nullable)
form_submission (model FormSubmission)
form_hashFK →form_builder.form_hash(ON DELETE CASCADE) — สังเกตว่าอ้างด้วย hash ไม่ใช่ idanswerJSONB และmetadataJSONBline_user_id,ip_address,user_agent,submitted_dateis_submitted— แถวถูกสร้างตั้งแต่ผู้ใช้เริ่มกรอก แล้วจึงตั้งเป็น true เมื่อกดส่งจริง
form_builder_rule (model FormBuilderRule)
ตาราง master ของกติกา validate แยกตามชนิดฟิลด์
typeเช่นshort_text,paragraph,email,phone,number,file_upload,date,date_of_birthnameและpropertiesJSONB ซึ่งเก็บ regex, ค่า min/max และข้อความ error ทั้งภาษาไทยและอังกฤษ
otp_config (model OtpConfig, PK UUID)
หนึ่งแถวต่อหนึ่ง OA (line_oa_id unique)
thaibulksms_keyและthaibulksms_secret_encซึ่งเข้ารหัสด้วย AES โดยใช้APP_ENCRYPT_SECRETไม่มีการเก็บค่า plaintextsms_enabled,email_enabled,email_subject,email_body
Trigger
form_submission_notify (AFTER INSERT OR UPDATE) เรียก notify_form_submitted()
เพื่อยิง pg_notify('form_submitted', ...) เมื่อ is_submitted เปลี่ยนเป็น true
ตัวฟังก์ชันจะ join form_builder ไปยัง line_oa เพื่อประกอบ lineOaId
และ organizationId ลงใน payload
ไฟล์ที่เกี่ยวข้อง
prisma/schema.prisma:916— modelFormBuilderprisma/schema.prisma:948— modelFormSubmissionprisma/schema.prisma:904— modelFormBuilderRuleprisma/schema.prisma:802— modelOtpConfigprisma/migrations/20260725090000_add_form_builder_thank_you/migration.sqlprisma/migrations/20260726100000_add_otp_config/migration.sqlmanual-sql/6.customer_database.sql— เพิ่มคอลัมน์form_builder.profile_mappingmanual-sql/2.notify_attribute_change.sqlและmanual-sql/5.sql— triggerform_submittedseed-data/16.form_builder_rule.sql— seed กติกา validate ครบทุกชนิดฟิลด์schema-dumps/2026-07-24/schema.sql:1749,:1832,:1797
จุดเชื่อมต่อกับ Service อื่น
- client-api-go — โหลดฟอร์มจาก
form_hashvalidate ด้วยform_builder_ruleส่ง OTP บันทึก submission และเปลี่ยน rich menu หลังส่งสำเร็จ - cms-api-go — สร้างและแก้ไขฟอร์ม ดูคำตอบ ตั้งค่า OTP และ profile mapping
- worker-go — listen ช่อง
form_submittedเพื่อเขียน attribute จัดเข้ากลุ่ม audience และจุด workflow
โดเมนที่เกี่ยวข้อง: เพื่อน LINE, Attribute Master, ฐานข้อมูลลูกค้า, Rich Menu