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

การนำเข้าไม่ค่อยล้มเหลวเพราะว่าโค้ด "ผิด" เสมอไป แต่ล้มเพราะข้อมูลจริงมักจะยุ่ง ไม่สอดคล้อง และมาจากคนที่ไม่เคยเห็นสมมติฐานของคุณ
ปัญหา CSV มักเกี่ยวกับรูปร่างและการฟอร์แมต ส่วนปัญหา JSON มักเกี่ยวกับความหมายและชนิดข้อมูล ทั้งสองอย่างสามารถพังในวิธีที่ดูเหมือนเล็กน้อยแต่สร้างผลลัพธ์ที่สับสนได้
ปัญหาเหล่านี้มักโผล่ในบัตรสนับสนุนซ้ำ ๆ:
ความถูกต้องไม่ได้หมายถึงแค่ “นำเข้าได้ไหม” แต่ต้องตัดสินใจว่าผลลัพธ์ใดอนุญาต เพราะผู้ใช้สังเกตข้อผิดพลาดเงียบมากกว่าความล้มเหลวที่ดัง
ทีมส่วนใหญ่สามารถตกลงกันได้สามผลลัพธ์:
กรณีพิกัดมุมกลายเป็นงานซ้ำเมื่อคนไม่รู้ว่ามีอะไรผิดหรือจะแก้ยังไงอย่างรวดเร็ว สถานการณ์ทั่วไป: ลูกค้าอัปโหลด 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 ของสัญญาที่คุณสามารถวางในสเปคได้:
ตัวอย่าง: การนำเข้า “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 (เพื่อให้ตัวอักษรที่ดูเหมือนกันเท่ากันเมื่อเปรียบเทียบ), และการฟอร์แมตหมายเลขโทรศัพท์เป็นรูปแบบเดียวสำหรับเก็บ
โครงสร้างที่อ่านง่าย:
เวอร์ชันกฎของคุณ ใส่ 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 หลายตัวต้องการ "แถว 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 ของคุณควรตอบสองคำถาม: เกิดอะไรขึ้น และผู้ใช้ควรทำอะไรต่อ
แม้เมื่อมีข้อผิดพลาด ให้คืนสรุปที่สม่ำเสมอเพื่อ UI และเครื่องมือสนับสนุนจะจัดการการนำเข้าทุกแบบได้เหมือนกัน
รวม:
created, updated, skipped, failed\n- totalRows (หรือ totalRecords สำหรับ JSON)\n- mode (เช่น: "createOnly", "upsert", หรือ "updateOnly")\n- เวลา startedAt และ finishedAt\n- correlationId ที่ทีมสนับสนุนสามารถขอได้correlationId มีประโยชน์มาก เมื่อใครสักคนรายงาน "มันไม่ถูกนำเข้า" คุณจะหาการรันนั้นในล็อกและรายงานข้อผิดพลาดโดยไม่ต้องเดา
อย่าส่งข้อผิดพลาด 10,000 แถวในการตอบกลับ ให้คืนตัวอย่างเล็ก (เช่น 20) ที่แสดงรูปแบบ และให้วิธีแยกต่างหากเพื่อดึงรายงานฉบับเต็มเมื่อจำเป็น
ทำให้แต่ละข้อผิดพลาดเฉพาะเจาะจงและเสถียร:
ตัวอย่างรูปทรงการตอบ (สำเร็จแต่มีข้อผิดพลาดบางแถว):
{
"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: ยอมรับ idempotencyKey (หรือคำนวณแฮชไฟล์) และคืนค่า importId เดิมหากคำขอซ้ำ หากโหมดเป็น upsert ให้กำหนดกฎการจับคู่ (เช่น email เป็นคีย์เอกลักษณ์) หากเป็น create-only ให้คืนค่า "skipped" สำหรับรายการซ้ำ ไม่ใช่ "created again"
หากคำขอทั้งหมดไม่ถูกต้อง (auth ผิด, content type ผิด, ไฟล์อ่านไม่ได้) ให้ล้มเร็วและคืนค่า status: \"rejected\" พร้อมรายการข้อผิดพลาดสั้น ๆ หากไฟล์ถูกต้องแต่มีปัญหาระดับแถว ให้จัดการเป็นงานที่เสร็จสิ้นโดยมี failed > 0 เพื่อผู้ใช้จะแก้และอัปโหลดใหม่ได้โดยไม่เสียสรุป
นิสัยที่มีประโยชน์: ให้โมเดลเขียนสัญญาในรูปแบบมีโครงสร้าง ไม่ใช่เป็นย่อหน้าบรรยาย "ย่อหน้าช่วยเหลือ" มักข้ามรายละเอียดเช่นกฎการตัดช่องว่าง ค่าเริ่มต้น และว่าเซลล์ว่างหมายถึง "หายไป" หรือ "ว่าง"
ใช้พรอมต์ที่บังคับให้สร้างตารางที่มนุษย์รีวิวได้เร็วและนักพัฒนาสามารถแปลงเป็นโค้ดได้ ขอให้สำหรับกฎของแต่ละฟิลด์ มีตัวอย่างผ่านและล้ม และบันทึกชัดเจนสำหรับสิ่งที่คลุมเครือ (เช่น 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 หยุดไม่ให้ "ไฟล์แปลก" กลายเป็นบัตรสนับสนุน เริ่มจากชุดไฟล์ดีเล็ก ๆ แล้วสร้างความแปรปรวนเล็ก ๆ นับพันครั้งและตรวจว่าตัวนำเข้าตอบสนองอย่างปลอดภัยและชัดเจน
เริ่มจากชุดเมล็ดของตัวอย่างที่ถูกต้องซึ่งแทนการใช้งานจริง: ไฟล์ขนาดเล็กสุดที่ถูกต้อง, ไฟล์ทั่วไป, และไฟล์ขนาดใหญ่ สำหรับ JSON ให้รวมอ็อบเจ็กต์เดียว หลายอ็อบเจ็กต์ และโครงสร้างซ้อนถ้าคุณรองรับ
แล้วเพิ่มมิวเทเตอร์อัตโนมัติที่แก้ไขทีละอย่าง เก็บการกลายพันธุ์ให้ทำซ้ำได้โดยบันทึกค่า seed แบบสุ่มเพื่อให้คุณสามารถเล่นซ้ำความล้มเหลวได้
มิติการฟัซซ์ที่จับปัญหาโลกจริงได้มากที่สุด:
อย่าหยุดที่ไวยากรณ์ เพิ่ม fuzz ทางความหมายด้วย: สลับฟิลด์ที่คล้ายกัน (email vs username), วันที่สุดขั้ว, ID ซ้ำ, จำนวนติดลบ, หรือค่าที่ละเมิด enum
การทดสอบ fuzz มีประโยชน์เมื่อเกณฑ์ผ่านเข้มงวด ตัวนำเข้าของคุณไม่ควรล่มหรือค้าง และข้อผิดพลาดควรคงที่และสามารถใช้งานได้
ชุดกฎผ่านที่ใช้งานได้จริง:
รันการทดสอบเหล่านี้ใน 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 เมื่อจำเป็นจริง ๆ
กับดักที่ควรป้องกันตั้งแต่ต้น:
ตัวอย่าง: ลูกค้าส่งออก CSV จาก Excel ที่ใส่ BOM และฟอร์แมตวันที่เป็น 03/04/2026 ตัวนำเข้าของคุณเดา MM/DD แต่ลูกค้าคาด DD/MM หากรายงานข้อผิดพลาดของคุณรวมรูปแบบที่ตรวจพบ ฟิลด์ที่ผิด และคำแนะนำแก้ไข ผู้ใช้จะแก้เองโดยไม่ต้องคุยกันหลายรอบ
ปัญหาการนำเข้าเกือบทั้งหมดคือความไม่ตรงกันเล็กน้อยระหว่างสิ่งที่ผู้ใช้คิดว่าไฟล์หมายถึงกับสิ่งที่ระบบของคุณยอมรับ ถือเป็นประตูปล่อย
การทดสอบที่ใช้งานได้: ใช้ไฟล์หนึ่งไฟล์ที่เจตนาให้ยุ่ง ตัวอย่าง: 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 ไม่คาดคิด
ขั้นตอนต่อไปที่ทำให้ซ้ำได้:
ส่วนใหญ่การล้มเหลวมาจากข้อมูลโลกจริงที่ยุ่งเหยิง ไม่ใช่จาก "โค้ดผิด" ปัญหา CSV มักเกี่ยวกับรูปทรง (headers, delimiter, quoting, encoding) ส่วนปัญหา JSON มักเกี่ยวกับความหมาย (ชนิดข้อมูล, null vs empty, การซ้อนวัตถุที่ไม่คาดคิด) จงถือทั้งคู่เป็นข้อมูลที่ไม่ไว้วางใจและตรวจสอบตามสัญญาที่ชัดเจน。
ตั้งค่าเป็นรูปแบบเดียวที่ไม่กำกวมต่อฟิลด์ เช่น วันเป็น YYYY-MM-DD หากยอมรับรูปแบบอื่น ให้ระบุชัดเจนและคาดเดาได้ (เช่น ยอมรับ true/false/1/0 แต่ไม่ยอมให้ทุกการเดาของสเปรดชีต) หลีกเลี่ยงการเดาวันที่ที่กำกวมอย่าง 01/02/03 — ให้ต้องเป็น ISO หรือปฏิเสธพร้อมข้อความข้อผิดพลาดที่ชัดเจน。
ตัดสินใจให้ชัดเจน:\n\n- อะไรถือเป็นข้อมูลซ้ำ (email, external_id หรือคอมโพสิต)\n- ขอบเขตการตรวจจับ (ภายในไฟล์, เทียบกับข้อมูลที่มีอยู่, หรือทั้งสอง)\n- การกระทำเมื่อพบ (เก็บรายการแรก, เก็บรายการสุดท้าย, รวม, หรือปฏิเสธ)\n\nผสานกับ idempotency เมื่อผู้ใช้สามารถลองอัปโหลดซ้ำได้ เพื่อหลีกเลี่ยงการสร้างซ้ำโดยไม่ตั้งใจ。
ใช้เลเยอร์แทนที่จะมีฟังก์ชัน validate() เบิ้มเดียว:\n\n- Normalize: แปลงอินพุตให้เป็นรูปทรงมาตรฐาน\n- Field-level rules: type, ช่วง, enum\n- Cross-field rules: ข้อตรวจสอบข้ามฟิลด์ (เช่น start < end)\n- File-level rules: headers ที่จำเป็น, คีย์ที่ไม่ซ้ำ, เวอร์ชันที่รองรับ\n\nกฎย่อยที่มีชื่อทำให้ง่ายต่อการทดสอบและปลอดภัยเมื่อเปลี่ยนแปลง。
คืนค่ารูปทรงข้อผิดพลาดที่เสถียร:\n\n- code (ตัวระบุที่คงที่)\n- message (อ่านเข้าใจสำหรับคน)\n- path/field (ชื่อคอลัมน์หรือ JSON pointer)\n- / (สำหรับ CSV)\n- ( vs )\n\nทำให้สามารถดำเนินการได้โดยใส่สิ่งที่คาดหวังและสิ่งที่ได้รับเมื่อเป็นไปได้。
คืนค่าสรุปที่สอดคล้องกันเสมอ แม้เมื่อมีข้อผิดพลาด:\n\n- จำนวน: created, , , และ \n- (success, rejected, completed_with_errors)\n- timestamps (, )\n- สำหรับการสนับสนุนและการดีบัก\n\nสำหรับไฟล์ใหญ่ ให้ระบุ ขนาดเล็กและวิธีดึงรายงานฉบับเต็มในภายหลัง。
รองรับการลองใหม่:\n\n- ยอมรับ idempotencyKey (หรือใช้แฮชไฟล์)\n- คืนค่า importId เดิมหากคำขอซ้ำ\n- กำหนดกฎการจับคู่สำหรับ upsert (เช่น email เป็นคีย์เอกลักษณ์)\n\nถ้าไม่ทำเช่นนี้ การลองอัปโหลดซ้ำอาจสร้างข้อมูลซ้ำได้โดยไม่ตั้งใจ。
เริ่มจากไฟล์ตัวอย่างดีไม่กี่ไฟล์ แล้วสร้างการกลายพันธุ์ทีละน้อย:\n\n- encoding (UTF-8 BOM, ไบต์ไม่ถูกต้อง)\n- โครงสร้าง (ขาด header, คอลัมน์เกิน, delimiter ผิด)\n- quoting/newlines (เครื่องหมายคำพูดไม่ปิด, newlines ฝังในช่อง)\n- edge ของชนิดข้อมูล (ตัวเลขใหญ่, empty vs null, NaN/Infinity ใน JSON)\n- ขีดจำกัดขนาด (ฟิลด์ยาวมาก, ซ้อนลึก)\n\nการทดสอบ fuzz "ผ่าน" เมื่อ importer ไม่ล้มเหลว/ค้าง และคืนค่าข้อผิดพลาดที่ทำซ้ำได้และใช้แก้ไขได้.
rowlineseverityerrorwarningupdatedskippedfailedtotalRows/totalRecordsstatusstartedAtfinishedAtcorrelationIderrorsSample