Claude Code สำหรับความถูกต้องของการนำเข้า/ส่งออกข้อมูล: ขั้นตอนปฏิบัติ
Claude Code สำหรับความถูกต้องการนำเข้า/ส่งออกข้อมูล: กำหนดกฎการตรวจสอบ รูปแบบข้อผิดพลาดที่สอดคล้อง และการทดสอบ fuzz สำหรับการนำเข้า CSV/JSON เพื่อลดบัตรสนับสนุนจากมุมขอบ

ปัญหาที่เกิดขึ้นกับการนำเข้า CSV และ JSON
การนำเข้าไม่ค่อยล้มเหลวเพราะว่าโค้ด "ผิด" เสมอไป แต่ล้มเพราะข้อมูลจริงมักจะยุ่ง ไม่สอดคล้อง และมาจากคนที่ไม่เคยเห็นสมมติฐานของคุณ
ปัญหา CSV มักเกี่ยวกับรูปร่างและการฟอร์แมต ส่วนปัญหา JSON มักเกี่ยวกับความหมายและชนิดข้อมูล ทั้งสองอย่างสามารถพังในวิธีที่ดูเหมือนเล็กน้อยแต่สร้างผลลัพธ์ที่สับสนได้
ปัญหาเหล่านี้มักโผล่ในบัตรสนับสนุนซ้ำ ๆ:
- ฟิลด์ที่จำเป็นหายไป (email, id, country) หรือคอลัมน์ถูกเปลี่ยนชื่อโดยคนที่ “ทำความสะอาด” ไฟล์
- วันที่แปลก ๆ (01/02/03, 2024-13-01, เลข serial ของ Excel, โซนเวลาผสมกัน)
- คอลัมน์เพิ่มหรือวัตถุ JSON ที่ซ้อนกันไม่คาดคิดถูกเพิ่มโดยเครื่องมืออื่น
- การไหลของชนิดข้อมูล ("00123" กลายเป็น 123, true/false กลายเป็น "yes"/"no")
- ข้อมูลซ้ำและเกือบซ้ำ (id เดียวกันสองครั้ง หรือคนเดียวกันแต่ตัวพิมพ์ต่างกัน)
ความถูกต้องไม่ได้หมายถึงแค่ “นำเข้าได้ไหม” แต่ต้องตัดสินใจว่าผลลัพธ์ใดอนุญาต เพราะผู้ใช้สังเกตข้อผิดพลาดเงียบมากกว่าความล้มเหลวที่ดัง
ทีมส่วนใหญ่สามารถตกลงกันได้สามผลลัพธ์:
- Accepted: แถวหรือระเบียนทั้งหมดถูกต้องและถูกนำเข้า
- Rejected: ไม่มีอะไรถูกนำเข้าเพราะไฟล์ไม่น่าเชื่อถือ (headers ผิด, encoding ผิด, JSON อ่านไม่ออก)
- Partially accepted: ระเบียนที่ถูกต้องถูกนำเข้า ระเบียนที่ไม่ถูกต้องถูกข้ามพร้อมเหตุผลที่ชัดเจน
กรณีพิกัดมุมกลายเป็นงานซ้ำเมื่อคนไม่รู้ว่ามีอะไรผิดหรือจะแก้ยังไงอย่างรวดเร็ว สถานการณ์ทั่วไป: ลูกค้าอัปโหลด CSV 5,000 แถว ตัวนำเข้าบอก "รูปแบบไม่ถูกต้อง" แล้วเขาลองใหม่สามครั้งด้วยการแก้แบบสุ่ม นั่นกลายเป็นหลายบัตรและคนในทีมของคุณต้องพยายามทำซ้ำไฟล์นั้นท้องถิ่น
ตั้งเป้าลดวงจร: ลดการลองใหม่, แก้ไขเร็วขึ้น, ผลลัพธ์ที่คาดเดาได้ ก่อนเขียนกฎ ให้ตัดสินใจว่า "partial" หมายถึงอะไร (และอนุญาตหรือไม่), คุณจะรายงานปัญหาระดับแถวอย่างไร และผู้ใช้ควรทำอะไรต่อ (แก้ไฟล์, ทำการจับคู่ฟิลด์, หรือส่งออกเวอร์ชันที่แก้แล้ว) หากคุณใช้แพลตฟอร์มสร้างโค้ดอย่าง Koder.ai (koder.ai) เพื่อสร้างตัวตรวจสอบและทดสอบเร็ว ๆ สัญญาการนำเข้าก็ยังคงเป็นสิ่งที่ทำให้พฤติกรรมคงที่เมื่อผลิตภัณฑ์วิวัฒนาการ
ตัดสินใจสัญญาการนำเข้าก่อนเขียนกฎ
ก่อนเขียนกฎการตรวจสอบตัวเดียว ให้ตัดสินใจว่า "อินพุตที่ถูกต้อง" หมายถึงอะไรสำหรับสินค้า คุณจะพบบั๊กการนำเข้าส่วนใหญ่เกิดจากความคาดหวังไม่ตรงกันระหว่างสิ่งที่ผู้ใช้อัปโหลดกับสิ่งที่ระบบของคุณสมมติอย่างเงียบ ๆ
เริ่มจากรูปแบบ และระบุให้ชัดเจน "CSV" อาจหมายถึง comma หรือ semicolon, มี header row หรือไม่, เป็น UTF-8 หรือ "ไฟล์ที่ Excel ผลิต" สำหรับ JSON ให้ตัดสินใจว่ารับอ็อบเจ็กต์เดียว, อาร์เรย์ของเรคคอร์ด, หรือ JSON Lines (หนึ่งวัตถุ JSON ต่อบรรทัด) หรือไม่ หากยอมรับ JSON ที่ซ้อนกัน ให้กำหนดเส้นทางที่คุณอ่านและเส้นทางที่คุณละเว้น
จากนั้นล็อกสัญญาฟิลด์ สำหรับทุกฟิลด์ ให้ตัดสินใจว่าจำเป็น, เป็นตัวเลือก, หรือเป็นตัวเลือกพร้อมค่าเริ่มต้น ค่าเริ่มต้นเป็นส่วนหนึ่งของสัญญา ไม่ใช่รายละเอียดการใช้งาน หาก country หายไป คุณจะตั้งเป็นค่าว่าง, เลือกประเทศเฉพาะ, หรือตัดแถวทิ้ง?
พฤติกรรมการแยกวิเคราะห์เป็นจุดที่การนำเข้าที่"ยืดหยุ่น"สร้างปัญหาระยะยาว ตัดสินใจก่อนว่าคุณจะเข้มงวดแค่ไหนเกี่ยวกับการตัดช่องว่าง, ทำให้ตัวพิมพ์ปกติ, และยอมรับค่าหลากหลายเช่น "yes"/"true"/"1" ความทนได้โอเคถ้ามันคาดเดาได้และมีเอกสาร
การซ้ำซ้อนเป็นอีกการตัดสินใจในสัญญาที่ส่งผลต่อความถูกต้องและความเชื่อถือ กำหนดว่าอะไรถือเป็นซ้ำ (same email, same external_id, หรือการรวมกันของฟิลด์), คุณตรวจจับที่ไหน (ภายในไฟล์, เทียบกับข้อมูลที่มีอยู่, หรือทั้งสอง), และคุณจะทำอย่างไรเมื่อเจอ (เก็บรายการแรก, เก็บรายการสุดท้าย, รวม, หรือปฏิเสธ)
Checklist ของสัญญาที่คุณสามารถวางในสเปคได้:
- รูปแบบและการเข้ารหัสที่ยอมรับ (delimiter ของ CSV, JSON vs JSON Lines, รองรับการซ้อน)
- กฎฟิลด์ (required/optional/defaults, ค่าที่อนุญาต)
- กฎการทำให้เป็นมาตรฐาน (trim, ตัวพิมพ์, รูปแบบวันที่/ตัวเลข)
- นิยามการซ้ำและการจัดการ (ขอบเขตการตรวจจับ, พฤติกรรมที่เลือก)
- ตำแหน่งการตรวจสอบ (client, server, หรือทั้งสอง)
ตัวอย่าง: การนำเข้า “customers.” หาก email เป็นคีย์เอกลักษณ์ ให้ตัดสินใจว่า \" [email protected] \" เท่ากับ \"[email protected]\" หรือไม่, การขาด email ยอมรับได้เมื่อ external_id มีอยู่หรือไม่, และไฟล์ที่มีข้อมูลซ้ำภายในควรถูกปฏิเสธหรือไม่ แม้ว่าในฐานข้อมูลจะยังไม่มีการจับคู่ เมื่อสัญญานี้ถูกยืนยัน พฤติกรรมที่สอดคล้องกันทั้ง UI และ API จะง่ายขึ้น ไม่ว่าจะนำไปใช้งานใน Koder.ai หรือที่อื่น
กฎการตรวจสอบที่อ่านง่ายและทดสอบได้
การนำเข้าที่ยุ่งมักเริ่มจากฟังก์ชัน validate() ขนาดยักษ์ วิธีที่สะอาดกว่าคือกฎเป็นชั้น ๆ พร้อมชื่อชัดเจนและฟังก์ชันเล็ก ๆ นั่นทำให้การเปลี่ยนแปลงตรวจสอบได้ง่ายขึ้น และทำให้เขียนเทสต์ได้ง่ายขึ้น
เริ่มจากกฎระดับฟิลด์: การเช็คค่าหนึ่งค่าที่ผ่านหรือล้มได้ด้วยตัวเอง (ชนิด, ช่วง, ความยาว, ค่าที่อนุญาต, regex) ทำให้มันน่าเบื่อและคาดเดาได้ ตัวอย่าง: email ตรงกับรูปแบบอีเมลพื้นฐาน, age เป็นจำนวนเต็มระหว่าง 0 ถึง 120, status เป็นหนึ่งใน active|paused|deleted
เพิ่มกฎข้ามฟิลด์เฉพาะที่จำเป็น เช็คพวกนี้ขึ้นกับหลายฟิลด์และบั๊กมักซ่อนที่นี่ ตัวอย่างคลาสสิก: startDate ต้องอยู่ก่อน endDate, หรือ total เท่ากับ subtotal + tax - discount เขียนกฎเหล่านี้ให้สามารถชี้ไปยังฟิลด์เฉพาะได้ ไม่ใช่แค่ "record invalid"
แยกกฎระดับเรคคอร์ดจากกฎระดับไฟล์ กฎระดับเรคคอร์ดเช็คหนึ่งแถว (CSV) หรือหนึ่งอ็อบเจ็กต์ (JSON) กฎระดับไฟล์เช็คการอัปโหลดทั้งหมด: headers ที่จำเป็นมีไหม, คีย์เอกลักษณ์ไม่ซ้ำกันในแถวหรือไม่, จำนวนคอลัมน์ตรงกับที่คาดไหม, หรือไฟล์ประกาศเวอร์ชันที่รองรับหรือเปล่า
การทำให้เป็นมาตรฐานควรชัดเจน ไม่ใช่ "เวทมนตร์" ตัดสินใจว่าคุณทำให้เป็นมาตรฐานอะไรล่วงหน้าก่อนตรวจสอบ และจดไว้ ตัวอย่างที่พบบ่อยคือการตัดช่องว่าง, การทำ Unicode normalization (เพื่อให้ตัวอักษรที่ดูเหมือนกันเท่ากันเมื่อเปรียบเทียบ), และการฟอร์แมตหมายเลขโทรศัพท์เป็นรูปแบบเดียวสำหรับเก็บ
โครงสร้างที่อ่านง่าย:
- Normalize: แปลงอินพุตดิบเป็นรูปทรงมาตรฐาน
- Validate fields: เช็คย่อยที่นำกลับมาใช้ได้ต่อฟิลด์
- Validate relationships: เช็คข้ามฟิลด์ที่มีเป้าหมายชัดเจน
- Validate file rules: headers, การซ้ำ, และการรองรับเวอร์ชัน
- Test each layer: เทสต์หน่วยสำหรับกฎแต่ละตัว และตัวอย่าง end-to-end สักสองสามรายการ
เวอร์ชันกฎของคุณ ใส่ schemaVersion (หรือโปรไฟล์การนำเข้า) ในไฟล์หรือคำขอ API เมื่อคุณเปลี่ยนความหมายของ "ถูกต้อง" คุณยังสามารถนำเข้าการส่งออกเก่าโดยใช้เวอร์ชันเก่า การเลือกนี้ช่วยป้องกันบัตร "มันเคยใช้ได้เมื่อวาน"
ออกแบบรูปแบบรายงานข้อผิดพลาดที่ผู้คนทำอะไรต่อได้
ตัวนำเข้าที่ดีล้มลงอย่างมีประโยชน์ ข้อผิดพลาดกำกวมทำให้ลองซ้ำแบบสุ่มและงานสนับสนุนที่หลีกเลี่ยงได้ รายงานข้อผิดพลาดที่ชัดเจนช่วยให้ผู้ใช้แก้ไฟล์ได้เร็ว และช่วยให้คุณปรับปรุงการตรวจสอบโดยไม่ทำลายลูกค้า
เริ่มจากรูปทรงวัตถุข้อผิดพลาดที่เสถียรและรักษาความสม่ำเสมอทั้ง CSV และ JSON คุณสามารถใช้ Claude Code เพื่อเสนอสคีมาและตัวอย่างที่สมจริง แล้วยึดไว้เป็นส่วนหนึ่งของสัญญาการนำเข้า
วัตถุข้อผิดพลาดที่เสถียร
ถือแต่ละข้อผิดพลาดเป็นเรคคอร์ดเล็ก ๆ ที่มีฟิลด์ไม่เปลี่ยนแปลง ข้อความอาจพัฒนา แต่ code และ path ควรคงที่
code: ตัวระบุสั้นและเสถียร เช่นREQUIRED_MISSINGหรือINVALID_DATE\n-message: ประโยคที่อ่านเข้าใจได้สำหรับ UI\n-path: ที่ที่ปัญหาเกิด (JSON pointer เช่น/customer/email, หรือชื่อคอลัมน์ เช่นemail)\n-rowหรือline: สำหรับ CSV ให้รวมหมายเลขแถวที่เริ่มจาก 1 (และอ็อปชันคือบรรทัดเดิม)\n-severity: อย่างน้อยerrorและwarning
ทำให้ข้อผิดพลาดสามารถดำเนินการได้ ใส่สิ่งที่คาดหวังและสิ่งที่เห็นจริง และเมื่อเป็นไปได้แสดงตัวอย่างที่จะผ่าน เช่น: คาด YYYY-MM-DD, ได้ 03/12/24
การจัดกลุ่มสำหรับ UI และการดีบัก
แม้ว่าคุณจะส่งรายการแบน ให้ใส่ข้อมูลพอที่จะจัดกลุ่มข้อผิดพลาดตามแถวและฟิลด์ UI หลายตัวต้องการ "แถว 12 มีปัญหา 3 อย่าง" แล้วไฮไลต์แต่ละคอลัมน์ ทีมสนับสนุนชอบการจัดกลุ่มเพราะรูปแบบจะชัดเจน (เช่น ทุกแถวขาด country)
ตัวอย่างการตอบกลับกะทัดรัดอาจออกมาเป็น:
{
"importId": "imp_123",
"status": "failed",
"errors": [
{
"code": "INVALID_DATE",
"message": "Signup date must be in YYYY-MM-DD.",
"path": "signup_date",
"row": 12,
"severity": "error",
"expected": "YYYY-MM-DD",
"actual": "03/12/24"
},
{
"code": "UNKNOWN_FIELD",
"message": "Column 'fav_colour' is not recognized.",
"path": "fav_colour",
"row": 1,
"severity": "warning"
}
]
}
วางแผนการแปลข้อความโดยไม่เปลี่ยน code ให้ code เป็นกลางทางภาษาและทนทาน และจัดการ message เป็นข้อความที่เปลี่ยนได้ หากต่อมาคุณเพิ่ม messageKey หรือข้อความแปลแล้ว ลูกค้าเก่าจะยังพึ่งพา code เดิมสำหรับการกรอง การจัดกลุ่ม และการวิเคราะห์ได้
API การนำเข้าควรคืนค่าอะไรเมื่อสำเร็จและเมื่อล้มเหลว
เพื่อหลีกเลี่ยง "การนำเข้าลึกลับ" การตอบ API ของคุณควรตอบสองคำถาม: เกิดอะไรขึ้น และผู้ใช้ควรทำอะไรต่อ
คืนสรุปการนำเข้าอย่างชัดเจน (ทุกครั้ง)
แม้เมื่อมีข้อผิดพลาด ให้คืนสรุปที่สม่ำเสมอเพื่อ UI และเครื่องมือสนับสนุนจะจัดการการนำเข้าทุกแบบได้เหมือนกัน
รวม:
- จำนวน
created,updated,skipped,failed\n-totalRows(หรือtotalRecordsสำหรับ JSON)\n-mode(เช่น: "createOnly", "upsert", หรือ "updateOnly")\n- เวลาstartedAtและfinishedAt\n-correlationIdที่ทีมสนับสนุนสามารถขอได้
correlationId มีประโยชน์มาก เมื่อใครสักคนรายงาน "มันไม่ถูกนำเข้า" คุณจะหาการรันนั้นในล็อกและรายงานข้อผิดพลาดโดยไม่ต้องเดา
รวมข้อผิดพลาดที่ใช้งานได้ และวิธีดึงรายงานฉบับเต็ม
อย่าส่งข้อผิดพลาด 10,000 แถวในการตอบกลับ ให้คืนตัวอย่างเล็ก (เช่น 20) ที่แสดงรูปแบบ และให้วิธีแยกต่างหากเพื่อดึงรายงานฉบับเต็มเมื่อจำเป็น
ทำให้แต่ละข้อผิดพลาดเฉพาะเจาะจงและเสถียร:
- ตำแหน่ง: หมายเลขแถว (CSV) หรือ JSON pointer-like path (JSON)\n- ชื่อฟิลด์\n- รหัสข้อผิดพลาด (อ่านโดยเครื่อง)\n- ข้อความ (อ่านโดยคน)\n- ค่าที่ถูกปฏิเสธ (ระวังข้อมูลที่อ่อนไหว)
ตัวอย่างรูปทรงการตอบ (สำเร็จแต่มีข้อผิดพลาดบางแถว):
{
"importId": "imp_01HZY...",
"correlationId": "c_9f1f2c2a",
"status": "completed_with_errors",
"summary": {
"totalRows": 1200,
"created": 950,
"updated": 200,
"skipped": 10,
"failed": 40
},
"errorsSample": [
{
"row": 17,
"field": "email",
"code": "invalid_format",
"message": "Email must contain '@'.",
"value": "maria.example.com"
}
],
"report": {
"hasMore": true,
"nextPageToken": "p_002"
},
"next": {
"suggestedAction": "review_errors"
}
}
สังเกตฟิลด์ next แม้ payload ขั้นต่ำควรช่วยให้ผลิตภัณฑ์ก้าวต่อ: แสดงหน้าตรวจทาน, เสนอการลองใหม่, หรือเปิดคอลเล็กชันที่นำเข้าแล้ว
กำหนด idempotency ให้ถูกต้องเพื่อการอัปโหลดซ้ำไม่สร้างซ้ำ
ผู้คนจะลองใหม่ เครือข่ายอาจล้ม หากไฟล์เดียวกันถูกนำเข้าสองครั้ง คุณต้องการผลลัพธ์ที่คาดเดาได้
ชัดเจนเรื่อง idempotency: ยอมรับ idempotencyKey (หรือคำนวณแฮชไฟล์) และคืนค่า importId เดิมหากคำขอซ้ำ หากโหมดเป็น upsert ให้กำหนดกฎการจับคู่ (เช่น email เป็นคีย์เอกลักษณ์) หากเป็น create-only ให้คืนค่า "skipped" สำหรับรายการซ้ำ ไม่ใช่ "created again"
ใช้สถานะที่เหมาะสมสำหรับความล้มเหลว แต่รักษารูปทรงให้คงที่
หากคำขอทั้งหมดไม่ถูกต้อง (auth ผิด, content type ผิด, ไฟล์อ่านไม่ได้) ให้ล้มเร็วและคืนค่า status: \"rejected\" พร้อมรายการข้อผิดพลาดสั้น ๆ หากไฟล์ถูกต้องแต่มีปัญหาระดับแถว ให้จัดการเป็นงานที่เสร็จสิ้นโดยมี failed > 0 เพื่อผู้ใช้จะแก้และอัปโหลดใหม่ได้โดยไม่เสียสรุป
วิธีใช้ Claude Code เพื่อสร้างกฎและตัวอย่าง
นิสัยที่มีประโยชน์: ให้โมเดลเขียนสัญญาในรูปแบบมีโครงสร้าง ไม่ใช่เป็นย่อหน้าบรรยาย "ย่อหน้าช่วยเหลือ" มักข้ามรายละเอียดเช่นกฎการตัดช่องว่าง ค่าเริ่มต้น และว่าเซลล์ว่างหมายถึง "หายไป" หรือ "ว่าง"
ใช้พรอมต์ที่บังคับให้สร้างตารางที่มนุษย์รีวิวได้เร็วและนักพัฒนาสามารถแปลงเป็นโค้ดได้ ขอให้สำหรับกฎของแต่ละฟิลด์ มีตัวอย่างผ่านและล้ม และบันทึกชัดเจนสำหรับสิ่งที่คลุมเครือ (เช่น empty string vs null)
You are helping design an importer for CSV and JSON.
Output a Markdown table with columns:
Field | Type | Required? | Normalization | Validation rules | Default | Pass examples | Fail examples
Rules must be testable (no vague wording).
Then output:
1) A list of edge cases to test (CSV + JSON).
2) Proposed test names with expected result (pass/fail + error code).
Finally, list any contradictions you notice (required vs default, min/max vs examples).
หลังร่างแรก ให้บีบให้มีตัวอย่างบวกหนึ่งและลบหนึ่งต่อกฎ นั่นจะผลักให้ครอบคลุมมุมที่ยุ่งเช่นสตริงว่าง, ค่าว่างที่มีแค่ช่องว่าง, คอลัมน์ที่หาย, null vs "null", จำนวนเต็มใหญ่, เลขวิทยาศาสตร์, ID ซ้ำ, และฟิลด์ JSON เกิน
สำหรับสถานการณ์จริง สมมติการนำเข้า “customers” จาก CSV: email จำเป็น, phone เป็นอ็อปชัน, และ signup_date ตั้งเป็นวันนี้ถ้าหาย โมเดลควรชี้ความขัดแย้งถ้าคุณบอกว่า "signup_date จำเป็น" มันควรเสนอทดสอบเช่น import_customers_missing_email_returns_row_error และระบุรหัสข้อผิดพลาดและรูปทรงข้อความที่คุณคืน
ทำรอบตรวจทานอีกครั้งก่อนนำไปทำจริง: ขอให้โมเดลสรุปกฎเป็นเช็คลิสต์และชี้จุดที่ค่าเริ่มต้น, ฟิลด์ที่จำเป็น, และการทำให้เป็นมาตรฐานอาจขัดแย้ง ตรวจสอบขั้นตอนนี้จับพฤติกรรมที่ก่อให้เกิดบัตรได้มาก
ขั้นตอนทีละขั้น: การทดสอบ fuzz สำหรับการนำเข้า CSV และ JSON
การทดสอบ fuzz หยุดไม่ให้ "ไฟล์แปลก" กลายเป็นบัตรสนับสนุน เริ่มจากชุดไฟล์ดีเล็ก ๆ แล้วสร้างความแปรปรวนเล็ก ๆ นับพันครั้งและตรวจว่าตัวนำเข้าตอบสนองอย่างปลอดภัยและชัดเจน
สร้างชุดเมล็ด แล้วกลายพันธุ์
เริ่มจากชุดเมล็ดของตัวอย่างที่ถูกต้องซึ่งแทนการใช้งานจริง: ไฟล์ขนาดเล็กสุดที่ถูกต้อง, ไฟล์ทั่วไป, และไฟล์ขนาดใหญ่ สำหรับ JSON ให้รวมอ็อบเจ็กต์เดียว หลายอ็อบเจ็กต์ และโครงสร้างซ้อนถ้าคุณรองรับ
แล้วเพิ่มมิวเทเตอร์อัตโนมัติที่แก้ไขทีละอย่าง เก็บการกลายพันธุ์ให้ทำซ้ำได้โดยบันทึกค่า seed แบบสุ่มเพื่อให้คุณสามารถเล่นซ้ำความล้มเหลวได้
มิติการฟัซซ์ที่จับปัญหาโลกจริงได้มากที่สุด:
- ปัญหา encoding: UTF-8 พร้อม BOM, ลำดับไบต์ไม่ถูกต้อง, การปรับมาตรฐาน Unicode ผสม\n- ปัญหาโครงสร้าง: ขาด header, คอลัมน์/ฟิลด์เกิน, delimiter ผิด, จุหมายจุลภาคที่ตามหลัง\n- การอ้างอิงเครื่องหมายคำพูดและ newline: เครื่องหมายคำพูดไม่ปิด, newlines ฝังในช่อง, CRLF vs LF, escaping ไม่สอดคล้อง\n- ขอบของชนิดข้อมูล: จำนวนเต็มใหญ่, NaN/Infinity (JSON), สตริงว่าง vs null, การเติมช่องว่าง\n- ขนาดและขีดจำกัด: ฟิลด์ยาวมาก, แถวจำนวนมาก, คีย์ซ้ำซ้อน, อาร์เรย์ซ้อนลึก
อย่าหยุดที่ไวยากรณ์ เพิ่ม fuzz ทางความหมายด้วย: สลับฟิลด์ที่คล้ายกัน (email vs username), วันที่สุดขั้ว, ID ซ้ำ, จำนวนติดลบ, หรือค่าที่ละเมิด enum
กำหนดว่า "ผ่าน" หมายถึงอะไร แล้วล็อกมัน
การทดสอบ fuzz มีประโยชน์เมื่อเกณฑ์ผ่านเข้มงวด ตัวนำเข้าของคุณไม่ควรล่มหรือค้าง และข้อผิดพลาดควรคงที่และสามารถใช้งานได้
ชุดกฎผ่านที่ใช้งานได้จริง:
- ไม่มีการล้ม ไทม์เอาท์ หรือการใช้หน่วยความจำเกินขอบเขตของคุณ\n- ข้อผิดพลาดที่ชัดเจนพร้อมชี้แถว/ฟิลด์ (CSV) หรือ path ของ JSON\n- รหัสข้อผิดพลาดคงที่สำหรับความล้มเหลวแบบเดียวกันข้ามการรัน\n- ไม่มีการเขียนบางส่วนเว้นแต่คุณสนับสนุน partial success อย่างชัดเจน\n- การนำเข้าที่สำเร็จให้ผลเหมือนกันไม่ว่าจะมีการฟอร์แมตที่ไม่เป็นอุปสรรค (เช่น ช่องว่าง)
รันการทดสอบเหล่านี้ใน CI ทุกครั้งที่มีการเปลี่ยนแปลง เมื่อพบความล้มเหลว ให้เก็บไฟล์นั้นเป็น fixture และเพิ่มเทสต์ regression เพื่อไม่ให้มันกลับมาอีก
หากคุณใช้ Claude Code งานนี้ให้มันสร้างไฟล์เมล็ดที่ตรงตามสัญญาของคุณ แผนการกลายพันธุ์ และผลข้อผิดพลาดที่คาดหวัง คุณยังเลือกกฎ แต่จะได้พื้นผิวการทดสอบกว้างเร็ว โดยเฉพาะมุมของ quoting ใน CSV และมุม JSON
กับดักที่พบบ่อยซึ่งทำให้เกิดบัตรสนับสนุนซ้ำ
บัตรการนำเข้าส่วนใหญ่เกิดจากกฎไม่ชัดเจนและฟีดแบ็กที่ไม่เป็นประโยชน์
กับดักที่พบบ่อยคือการแยกวิเคราะห์แบบ "best effort" ที่ไม่ได้เขียนลงเอกสาร หากตัวนำเข้าของคุณตัดช่องว่างเงียบ ๆ, ยอมรับทั้ง comma และ semicolon, หรือเดารูปแบบวันที่ ผู้ใช้จะสร้างเวิร์กโฟลว์บนการเดาเหล่านั้น แล้วการเปลี่ยนเล็กน้อยหรือเครื่องมือสร้างไฟล์ที่ต่างออกไปจะแตก ทุกอย่าง: เลือกพฤติกรรม ลงเอกสาร และทดสอบมัน
อีกผู้ร้ายคือข้อความข้อผิดพลาดทั่วไป "Invalid CSV" หรือ "Bad request" บังคับให้ผู้ใช้เดา พวกเขาอัปโหลดไฟล์เดิมห้าครั้ง ทีมสนับสนุนต้องขอไฟล์อยู่ดี ข้อผิดพลาดควรชี้แถว ฟิลด์ เหตุผลชัดเจน และมีรหัสเสถียร
การปฏิเสธทั้งไฟล์เพราะแถวเดียวก็เป็นปัญหาบ่อย บางกรณีต้องเช่นการนำเข้าทางการเงินที่ข้อมูลบางส่วนอันตราย แต่การนำเข้าธุรกิจส่วนใหญ่สามารถดำเนินต่อและรายงานสรุปได้ ตราบใดที่คุณเสนอทางเลือกชัดเจนเช่น strict mode vs partial import
ปัญหา encoding ของข้อความสร้างบัตรดื้อรั้น UTF-8 เป็นดีฟอลต์ แต่ CSV จริงมักมี BOM, เครื่องหมายคำพูดแบบโค้ง, หรือช่องว่างไม่แบ่งที่คัดลอกจากสเปรดชีต จัดการสิ่งเหล่านี้อย่างสอดคล้องและรายงานสิ่งที่ตรวจจับเพื่อให้ผู้ใช้แก้การตั้งค่า export ของพวกเขา
สุดท้าย การเปลี่ยนรหัสข้อผิดพลาดระหว่างการปล่อยทำลายลูกค้าและการทำงานอัตโนมัติ ปรับปรุงคำถ้าต้องการ แต่เก็บ code และความหมายให้คงที่ ยกเว้นจะ version เมื่อจำเป็นจริง ๆ
กับดักที่ควรป้องกันตั้งแต่ต้น:
- การแยกวิเคราะห์ "best effort" ที่ไม่มีเอกสารและเปลี่ยนแปลงไปตามเวลา\n- ข้อความข้อผิดพลาดไม่มีชี้แถว/ฟิลด์และรหัสข้อผิดพลาดที่เสถียร\n- การนำเข้าทั้งหมดหรือไม่มีเลยโดยไม่มีตัวเลือก strict vs partial\n- UTF-8, BOM, และอักขระที่มองไม่เห็นไม่ได้รับการจัดการอย่างสอดคล้อง\n- การเปลี่ยนรหัสข้อผิดพลาดที่ทำให้การจัดการฝั่งไคลเอนต์เสียหาย
ตัวอย่าง: ลูกค้าส่งออก CSV จาก Excel ที่ใส่ BOM และฟอร์แมตวันที่เป็น 03/04/2026 ตัวนำเข้าของคุณเดา MM/DD แต่ลูกค้าคาด DD/MM หากรายงานข้อผิดพลาดของคุณรวมรูปแบบที่ตรวจพบ ฟิลด์ที่ผิด และคำแนะนำแก้ไข ผู้ใช้จะแก้เองโดยไม่ต้องคุยกันหลายรอบ
เช็คลิสต์ด่วนก่อนปล่อยตัวนำเข้า
ปัญหาการนำเข้าเกือบทั้งหมดคือความไม่ตรงกันเล็กน้อยระหว่างสิ่งที่ผู้ใช้คิดว่าไฟล์หมายถึงกับสิ่งที่ระบบของคุณยอมรับ ถือเป็นประตูปล่อย
- Headers และชื่อฟิลด์: ยืนยันคอลัมน์ที่จำเป็นมีอยู่ ชื่อตรงตามกฎ และปฏิเสธคอลัมน์ที่ซ้ำ เลือกว่าจะทำอย่างไรกับคอลัมน์เกิน (ละเลย, เตือน, ปฏิเสธ) และรักษาความสม่ำเสมอ
- ชนิดข้อมูลและรูปแบบ: ล็อกการแยกวิเคราะห์จำนวนเต็ม vs ทศนิยม, boolean (true/false, 0/1, yes/no), วันที่ และ timestamp (กฎโซนเวลา) ยอมรับรูปแบบเดียวต่อฟิลด์
- ค่า null และค่าที่หายไป: กำหนดว่า empty string แปลว่าอะไรต่อแต่ละฟิลด์ แยกระหว่างฟิลด์หายไป, null ชัดเจน, และข้อความว่าง
- ขีดจำกัดขนาดและความปลอดภัย: ตั้งขีดจำกัดขนาดไฟล์, จำนวนแถวสูงสุด, และความยาวฟิลด์สูงสุด ปฏิเสธตั้งแต่ต้นพร้อมข้อความชัดเจน
- ข้อผิดพลาดที่กำหนดได้: อินพุตไม่ดีแบบเดียวกันต้องให้รหัสข้อผิดพลาดและรูปทรงข้อความเหมือนกันทุกครั้ง
การทดสอบที่ใช้งานได้: ใช้ไฟล์หนึ่งไฟล์ที่เจตนาให้ยุ่ง ตัวอย่าง: CSV ที่ header ปรากฏสองครั้ง (มีสองคอลัมน์ "email"), ฟิลด์ boolean ใช้ "Y", และวันที่เป็น "03/04/05" ตัวนำเข้าของคุณไม่ควรเดา ควรใช้กฎการแมปที่มีเอกสารหรือปฏิเสธพร้อมข้อผิดพลาดเฉพาะ
สองการตรวจสอบที่ทีมมักข้าม:
ประการแรก ยืนยันว่าตัวนำเข้ารายงานข้อผิดพลาดด้วยรายละเอียดตำแหน่งพอที่จะแก้ไฟล์ต้นทางได้ "Invalid date" ไม่สามารถใช้งานได้ "Row 42, column start_date: expected YYYY-MM-DD, got 03/04/05" ใช้งานได้
ประการที่สอง รันไฟล์ที่ไม่ถูกต้องเดียวกันสองครั้งแล้วเปรียบเทียบผล หากลำดับข้อผิดพลาดเปลี่ยน รหัสเปลี่ยน หรือตัวเลขแถวเพี้ยน ผู้ใช้จะสูญเสียความเชื่อถือ พฤติกรรมที่ตัดสินได้และคงที่คือสิ่งที่ต้องการ
ตัวอย่างสถานการณ์จริงและขั้นตอนต่อไป
การนำเข้าจริงทั่วไปคือคำสั่งซื้อจากสเปรดชีต ใครบางคนส่งออก CSV จากระบบเก่า แก้ไขใน Excel แล้วอัปโหลด ข้อร้องทุกข์ส่วนใหญ่เกิดเมื่อ importer แก้ข้อมูลเงียบ ๆ หรือข้อความข้อผิดพลาดไม่บอกว่าจะแก้อย่างไร
จินตนาการไฟล์ชื่อ orders.csv ที่มีคอลัมน์: order_id,customer_email,order_date,currency,total_amount.
นี่คือสามแถวไม่ดีที่สมจริง (ตามที่ผู้ใช้จะเห็น):
order_id,customer_email,order_date,currency,total_amount
A-1001,[email protected],2026-01-05,USD,129.99
A-1002,not-an-email,01/06/2026,USD,49.00
,[email protected],2026-01-07,US, -10
แถวที่ 2 มีอีเมลไม่ถูกต้องและวันที่กำกวม แถวที่ 3 ขาด order_id, มีรหัสสกุลเงินที่ไม่รองรับ (US แทน USD), และจำนวนติดลบ
ถ้า API ของคุณคืนข้อผิดพลาด ให้รักษารูปทรงให้คงที่และเฉพาะเจาะจง นี่คือตัวอย่างการตอบที่รองรับ partial success:
{
"correlation_id": "imp_20260109_7f3a9d",
"import_id": "ord_01HZZ...",
"status": "partial_success",
"summary": {
"total_rows": 3,
"imported_rows": 1,
"failed_rows": 2
},
"errors": [
{
"row_number": 2,
"field": "customer_email",
"code": "invalid_email",
"message": "Email must contain a valid domain.",
"value": "not-an-email"
},
{
"row_number": 2,
"field": "order_date",
"code": "invalid_date_format",
"message": "Use ISO-8601 (YYYY-MM-DD).",
"value": "01/06/2026"
},
{
"row_number": 3,
"field": "order_id",
"code": "required",
"message": "order_id is required.",
"value": ""
},
{
"row_number": 3,
"field": "currency",
"code": "unsupported_currency",
"message": "Allowed values: USD, EUR, GBP.",
"value": "US"
},
{
"row_number": 3,
"field": "total_amount",
"code": "must_be_positive",
"message": "total_amount must be greater than 0.",
"value": " -10"
}
],
"retry": {
"mode": "upload_failed_only",
"failed_row_numbers": [2, 3]
}
}
Partial success สำคัญเพราะผู้ใช้ไม่ควรต้องอัปโหลดทั้งไฟล์อีกครั้ง โฟลว์ลองใหม่ง่าย ๆ คือ: แก้เฉพาะแถวที่ล้ม ส่งออก CSV เล็ก ๆ ที่มีแถว 2 และ 3 แล้วอัปโหลดใหม่ ตัวนำเข้าของคุณควรปฏิบัติเช่น idempotent เมื่อ order_id มีอยู่ เพื่อให้การลองใหม่จะอัปเดตเรคคอร์ดเดิมแทนการสร้างซ้ำ
สำหรับการสนับสนุน correlation_id คือเส้นทางที่เร็วที่สุดไปสู่การวินิจฉัย เจ้าหน้าที่สนับสนุนสามารถขอค่านั้น หาการรันนำเข้าในล็อก และยืนยันว่าพาร์เซอร์เห็นคอลัมน์เกิน, delimiter ผิด, หรือ encoding ไม่คาดคิด
ขั้นตอนต่อไปที่ทำให้ซ้ำได้:
- ใช้ Claude Code เพื่อสร้างกฎการตรวจสอบ, แถวตัวอย่างที่ไม่ถูกต้อง, และรหัส/ข้อความข้อผิดพลาดที่คุณต้องการให้เป็นมาตรฐาน\n- เปลี่ยนตัวอย่างเหล่านั้นเป็นเทสต์อัตโนมัติ (รวมถึงการทดสอบ fuzz) เพื่อให้มุมขอบใหม่กลายเป็นเทสต์ที่ล้ม ไม่ใช่บัตรใหม่\n- หากคุณสร้างด้วย Koder.ai ใช้โหมดวางแผนเพื่อร่างสัญญาการนำเข้า สร้างตัวตรวจสอบและเทสต์ แล้ววนจนผลข้อผิดพลาดคงที่ข้าม CSV และ JSON
คำถามที่พบบ่อย
ทำไมการนำเข้า CSV และ JSON ถึงล้มเหลวแม้โค้ดดูถูกต้อง?
ส่วนใหญ่การล้มเหลวมาจากข้อมูลโลกจริงที่ยุ่งเหยิง ไม่ใช่จาก "โค้ดผิด" ปัญหา CSV มักเกี่ยวกับรูปทรง (headers, delimiter, quoting, encoding) ส่วนปัญหา JSON มักเกี่ยวกับความหมาย (ชนิดข้อมูล, null vs empty, การซ้อนวัตถุที่ไม่คาดคิด) จงถือทั้งคู่เป็นข้อมูลที่ไม่ไว้วางใจและตรวจสอบตามสัญญาที่ชัดเจน。
ควรให้ตัวนำเข้าปฏิเสธทั้งไฟล์หรืออนุญาตการนำเข้าบางส่วน?
- Accepted: นำเข้าทั้งหมดสำเร็จ
- Rejected: ไม่ได้นำเข้าทั้งหมดเพราะไฟล์ไม่น่าเชื่อถือ (headers ผิด, JSON อ่านไม่ได้, encoding ผิด)
- Partially accepted: บันทึกที่ถูกต้องนำเข้าได้ ขณะที่รายการที่ไม่ถูกต้องถูกข้ามพร้อมเหตุผลที่ชัดเจน
เลือกสถานะเริ่มต้น (หลายระบบเลือก partial) และทำให้สอดคล้องทั้ง UI และ API。
สัญญาการนำเข้าควรประกอบด้วยอะไรบ้าง?
- รูปแบบที่ยอมรับ (delimiter ของ CSV, ต้องมี header หรือไม่, การจัดการ UTF-8/BOM; JSON แบบ array vs object vs JSON Lines)
- กฎฟิลด์ (required/optional/defaults)
- การทำให้เป็นมาตรฐาน (trim, กฎตัวพิมพ์, รูปแบบวันที่)
- นิยามและการจัดการข้อมูลซ้ำ
- ที่ที่จะทำการตรวจสอบ (client, server, หรือทั้งสองฝ่าย)
เขียน สัญญาการนำเข้า ก่อนเริ่มเขียนกฎการตรวจสอบ เพื่อป้องกันความประหลาดใจว่า "เมื่อวานมันใช้งานได้" เมื่อพฤติกรรมเปลี่ยนไป。
ทำอย่างไรกับวันที่แปลกและการเปลี่ยนแปลงชนิดข้อมูล (เช่น "00123" → 123, yes/no)?
ตั้งค่าเป็นรูปแบบเดียวที่ไม่กำกวมต่อฟิลด์ เช่น วันเป็น YYYY-MM-DD หากยอมรับรูปแบบอื่น ให้ระบุชัดเจนและคาดเดาได้ (เช่น ยอมรับ true/false/1/0 แต่ไม่ยอมให้ทุกการเดาของสเปรดชีต) หลีกเลี่ยงการเดาวันที่ที่กำกวมอย่าง 01/02/03 — ให้ต้องเป็น ISO หรือปฏิเสธพร้อมข้อความข้อผิดพลาดที่ชัดเจน。
วิธีที่ดีที่สุดในการจัดการกับข้อมูลซ้ำระหว่างการนำเข้าคืออะไร?
ตัดสินใจให้ชัดเจน:
- อะไรถือเป็นข้อมูลซ้ำ (email, external_id หรือคอมโพสิต)
- ขอบเขตการตรวจจับ (ภายในไฟล์, เทียบกับข้อมูลที่มีอยู่, หรือทั้งสอง)
- การกระทำเมื่อพบ (เก็บรายการแรก, เก็บรายการสุดท้าย, รวม, หรือปฏิเสธ)
ผสานกับ idempotency เมื่อผู้ใช้สามารถลองอัปโหลดซ้ำได้ เพื่อหลีกเลี่ยงการสร้างซ้ำโดยไม่ตั้งใจ。
ควรจัดโครงสร้างกฎการตรวจสอบอย่างไรให้ยังอ่านง่ายและทดสอบได้?
ใช้เลเยอร์แทนที่จะมีฟังก์ชัน validate() เบิ้มเดียว:
- Normalize: แปลงอินพุตให้เป็นรูปทรงมาตรฐาน
- Field-level rules: type, ช่วง, enum
- Cross-field rules: ข้อตรวจสอบข้ามฟิลด์ (เช่น start < end)
- File-level rules: headers ที่จำเป็น, คีย์ที่ไม่ซ้ำ, เวอร์ชันที่รองรับ
กฎย่อยที่มีชื่อทำให้ง่ายต่อการทดสอบและปลอดภัยเมื่อเปลี่ยนแปลง。
รูปแบบการรายงานข้อผิดพลาดควรเป็นอย่างไร?
คืนค่ารูปทรงข้อผิดพลาดที่เสถียร:
code(ตัวระบุที่คงที่)message(อ่านเข้าใจสำหรับคน)path/field(ชื่อคอลัมน์หรือ JSON pointer)row/line(สำหรับ CSV)severity(errorvswarning)
ทำให้สามารถดำเนินการได้โดยใส่สิ่งที่คาดหวังและสิ่งที่ได้รับเมื่อเป็นไปได้。
API การนำเข้าควรคืนค่าอะไรบ้างเมื่อสำเร็จและเมื่อล้มเหลว?
คืนค่าสรุปที่สอดคล้องกันเสมอ แม้เมื่อมีข้อผิดพลาด:
- จำนวน:
created,updated,skipped,failedและtotalRows/totalRecords status(success, rejected, completed_with_errors)- timestamps (
startedAt,finishedAt) correlationIdสำหรับการสนับสนุนและการดีบัก
สำหรับไฟล์ใหญ่ ให้ระบุ errorsSample ขนาดเล็กและวิธีดึงรายงานฉบับเต็มในภายหลัง。
จะทำให้การนำเข้าเป็น idempotent เพื่อไม่ให้การลองซ้ำสร้างซ้ำได้อย่างไร?
รองรับการลองใหม่:
- ยอมรับ
idempotencyKey(หรือใช้แฮชไฟล์) - คืนค่า
importIdเดิมหากคำขอซ้ำ - กำหนดกฎการจับคู่สำหรับ upsert (เช่น email เป็นคีย์เอกลักษณ์)
ถ้าไม่ทำเช่นนี้ การลองอัปโหลดซ้ำอาจสร้างข้อมูลซ้ำได้โดยไม่ตั้งใจ。
จะทดสอบ fuzz สำหรับการนำเข้า CSV/JSON โดยไม่ทำให้ชุดทดสอบไม่สามารถจัดการได้อย่างไร?
เริ่มจากไฟล์ตัวอย่างดีไม่กี่ไฟล์ แล้วสร้างการกลายพันธุ์ทีละน้อย:
- encoding (UTF-8 BOM, ไบต์ไม่ถูกต้อง)
- โครงสร้าง (ขาด header, คอลัมน์เกิน, delimiter ผิด)
- quoting/newlines (เครื่องหมายคำพูดไม่ปิด, newlines ฝังในช่อง)
- edge ของชนิดข้อมูล (ตัวเลขใหญ่, empty vs null,
NaN/Infinityใน JSON) - ขีดจำกัดขนาด (ฟิลด์ยาวมาก, ซ้อนลึก)
การทดสอบ fuzz "ผ่าน" เมื่อ importer ไม่ล้มเหลว/ค้าง และคืนค่าข้อผิดพลาดที่ทำซ้ำได้และใช้แก้ไขได้.