ตารางความสามารถ
ขอบเขตตามซอร์สของรุ่นรวมที่ยังไม่เผยแพร่ ตรวจซอร์สเมื่อ 2026-10-18 แต่ละแถวระบุการทำงานและเทสต์ที่เกี่ยวข้อง การระบุเทสต์ไม่ได้หมายความว่าผ่านการรับรองรุ่นสุดท้ายแล้ว ความสามารถเพิ่มเติมและเงื่อนไขการรับรองที่เหลืออยู่แสดงไว้ด้านล่าง
คำศัพท์:
- CMS — admin API และ API อ่านสาธารณะ (
/v1) - Generated — standalone backend ที่สร้างด้วย
npm run backend:generateหรือnpm run backend:deliver - Presentation only — หน้าผู้ดูแลใช้ค่านี้ ไม่มีเซิร์ฟเวอร์ใดบังคับใช้
รูปแบบโมเดล
หัวข้อที่มีชื่อว่า “รูปแบบโมเดล”| ความสามารถ | CMS | Generated | จุดที่พบปัญหา | หลักฐาน |
|---|---|---|---|---|
| โมเดลแบบรายการเดียว (มีได้แค่หนึ่งรายการ) | โมเดลเป็น collection หรือ single (content_model.kind) โมเดล single มีรายการเชิงตรรกะได้ไม่เกินหนึ่งรายการ นับรวมถังขยะ การสร้างครั้งที่สองถูกปฏิเสธ (409 single_entry_exists) และระบุรายการที่มีอยู่ การสร้างพร้อมกันสองครั้งจะสำเร็จเพียงครั้งเดียว การเพิ่มภาษาเป็นการเพิ่มให้รายการเดิม รายการในถังขยะยังถือที่ไว้และปล่อยที่เมื่อลบถาวรเท่านั้น collection เปลี่ยนเป็น single ได้เฉพาะเมื่อมีไม่เกินหนึ่งรายการ นับรวมถังขยะ (single_entry_conflict) การเปลี่ยนนี้ทำให้ข้อกำหนดโมเดลเปลี่ยนไป การสร้างที่วางแผนไว้ตามชนิดเดิมจึงถูกยกเลิก สำเนาไซต์พกชนิดไปด้วย dry run ของสำเนาจะถูกบล็อกเมื่อปลายทางมีรายการอยู่แล้ว รวมถึงในถังขยะ (single_entry_taken) หรือเมื่อสำเนามีมากกว่าหนึ่งรายการสำหรับโมเดลนั้น Strapi single type นำเข้าเป็นโมเดล single |
โมเดลถูกทำเครื่องหมายใน schema การสร้างครั้งที่สองถูกปฏิเสธตามชื่อ และฐานข้อมูลจำกัดตารางไว้ที่หนึ่งแถว ตั้งแต่ migration แรกและเมื่อชนิดเปลี่ยน | ทุกการสร้าง การนำเข้า และการเปลี่ยนชนิด | backend/src/lib/lifecycle/single-entry.ts. backend/test/single-entry-model.test.ts. backend/test/single-entry-import.test.ts. backend/test/graduate-private-and-single.test.ts. backend/test/import-strapi-components.test.ts |
| โฟลเดอร์เนื้อหา (การจัดกลุ่มนำทางในหน้าแอดมิน) | โมเดลมีป้ายโฟลเดอร์ที่ไม่บังคับ content_model.nav_folder: ยาว 1 ถึง 40 ตัวอักษรหลังตัดช่องว่าง จัดกลุ่มโดยไม่สนตัวพิมพ์เล็กใหญ่ ไม่มีโฟลเดอร์ย่อย และมีอยู่โดยปริยายตราบที่มีโมเดลใช้ ตั้งค่าผ่านคำขอแยกต่างหาก PUT /api/models/:id/folder ภายใต้ model:apply ไม่ใช่ด้วย Apply จึงไม่เปลี่ยน revision ของโมเดลหรือบล็อกการบันทึก รายการ เนื้อหา แสดงโมเดลที่ไม่มีโฟลเดอร์ก่อน แล้วโฟลเดอร์ตามชื่อ แต่ละโฟลเดอร์เป็นปุ่มที่มี aria-expanded เบราว์เซอร์จำว่าโฟลเดอร์ใดถูกพับไว้ และโฟลเดอร์ที่มีโมเดลที่เปิดอยู่จะเปิด ไม่เป็นส่วนของอินพุตการสร้าง แบ็กเอนด์ที่สร้าง หรือการอ่านสาธารณะ สำเนาไซต์พกโฟลเดอร์ไปยังโมเดลที่สร้าง management API ตั้งด้วย setModelFolder และแสดงเป็น folder |
ไม่เป็นส่วนหนึ่งของแบ็กเอนด์ที่สร้าง | การเปลี่ยนโฟลเดอร์ของโมเดลและการคัดลอกไซต์ | backend/src/lib/model-folder.ts. backend/src/api/model-folder.ts. backend/test/model-folder-route.test.ts. backend/test/model-folder-site-copy.test.ts. backend/test/management-models.test.ts. frontend/src/lib/content/model-folders.ts. frontend/src/routes/content/components/ModelFolderGroups.svelte. frontend/cypress/e2e/journey-model-nav-folders.cy.ts |
| ฟิลด์ unique ที่ผู้เขียนกำหนดเอง | กำหนดค่าไม่ซ้ำให้ช่องข้อความหรือตัวเลขแต่ละช่อง หรือชุดชื่อที่รวมสองถึงสี่ช่องได้สูงสุดแปดชุด ช่องในชุดต้องใช้ค่าร่วมกันทั้งหมดหรือแปลแยกภาษาทั้งหมด ขอบเขตเป็นทั้งโมเดลหรือแต่ละภาษา ชุดที่กรอกไม่ครบไม่จองค่า การบันทึก นำเข้า กู้คืน เผยแพร่ และแก้โครงสร้างตรวจแบบอะตอมมิก ดู ชุดค่าที่ไม่ซ้ำ | ดัชนีไม่ซ้ำแบบช่องเดียวและหลายช่อง ขอบเขตภาษารวม lang |
ความพร้อมในการสร้างและการบิลด์ปฏิเสธค่าซ้ำที่เผยแพร่แล้วและเป้าหมายหนึ่งต่อหนึ่งที่ใช้ร่วมกันก่อนสร้างสิ่งใด | backend/src/lib/lifecycle/unique-values.ts. backend/src/lib/graduate/unique-values.ts. backend/test/field-uniqueness.test.ts. backend/test/graduate-uniqueness.test.ts |
| ฟิลด์ส่วนตัว (ซ่อนจากการอ่านสาธารณะ) | ต่อฟิลด์ (custom_field.private) และต่อฟิลด์ภายในคอมโพเนนต์ ฟิลด์ส่วนตัวไม่ถูกให้บริการโดยรายการหรือ item สาธารณะเลย รวมถึงความสัมพันธ์หรือสื่อของฟิลด์ ฟีด การค้นหาในไซต์ หรือ public client ที่สร้าง ตัวกรอง การเรียง การเลือก หรือการขยายสาธารณะที่ระบุฟิลด์นี้ถูกปฏิเสธเหมือนฟิลด์ที่ไม่รู้จักทุกประการ คีย์แคชพกชุดฟิลด์ส่วนตัว ฟิลด์ที่เพิ่งเป็นส่วนตัวจึงไม่เจอเนื้อหาที่แคชไว้ก่อน การทำให้ฟิลด์เป็นส่วนตัวจะทำดัชนีแถวค้นหาของโมเดลใหม่ ฟิลด์คอมโพเนนต์ที่อ่านคลังไม่ได้จะถูกตัดออกทั้งฟิลด์ saved query บน route สาธารณะระบุคอลัมน์ส่วนตัวไม่ได้ รวมถึงผ่านคอลัมน์คอมโพเนนต์ที่มีฟิลด์ส่วนตัว (422 private_field_on_public_route เมื่อผูกหรือแก้ไข saved_query_private_field ตอนสร้าง) การมองเห็น private ระดับโมเดลยังต้องใช้ read token ที่อยู่ในขอบเขต |
คอลัมน์ส่วนตัวไม่อยู่ในคำตอบของ reader และการเขียนทุกครั้ง และเก็บไว้สำหรับ editor ตารางเชื่อมของความสัมพันธ์แบบรายการที่เป็นส่วนตัวให้บริการเฉพาะ editor ไซต์ที่สร้างไม่แสดงค่า ความสัมพันธ์ หรือสื่อที่เป็นส่วนตัว และตัดฟิลด์ส่วนตัวของคอมโพเนนต์ออกจากค่าภายใน นโยบายการเข้าถึงต่อโมเดลต่อการดำเนินการ (anonymous, session, service) ไม่เปลี่ยน |
การอ่านสาธารณะและการสร้าง | backend/src/lib/private-fields.ts. backend/test/private-fields.test.ts. backend/test/public-feed.test.ts. backend/test/graduate-private-and-single.test.ts. backend/test/saved-query-graduation.test.ts. backend/test/public-private-routes.test.ts. backend/test/backend-policy.test.ts |
| การแสดงฟิลด์แบบมีเงื่อนไข | เงื่อนไขชนิดข้อมูลสำหรับค่าจริงหรือเท็จ ตัวเลือก ข้อความ ตัวเลข และวันที่ รวมด้วยกลุ่ม AND/OR ได้ไม่เกินสี่เงื่อนไขและสามระดับ ตัวแก้ไข การบันทึก และการตรวจโมเดลใช้กฎเดียวกัน ค่าที่ซ่อนยังถูกเก็บไว้ การแสดงผลไม่เปลี่ยนสิทธิ์เข้าถึง ดู แสดงเมื่อ | ใช้เงื่อนไขเดียวกันเพื่อตรวจช่องที่บังคับกรอก | การบันทึกโมเดล | frontend/src/lib/eav/field-condition.ts. backend/test/field-conditions.test.ts. backend/test/mixed-components-site-copy.test.ts |
| ฟิลด์คอมโพเนนต์แบบผสม | คอมโพเนนต์ธรรมดาและแบบผสมสามารถเลิกใช้และเก็บโครงสร้างเดิมไว้ได้ อินสแตนซ์เดิมยังแก้ไขตามเวอร์ชันโครงสร้างที่ใช้อยู่ แต่เพิ่มหรือทำสำเนาชนิดที่เลิกใช้แล้วไม่ได้ การอัปเกรดต้องสั่งอย่างชัดเจน ID อินสแตนซ์ สถานะแสดงผล และรายการชนิดที่อนุญาตยังคงอยู่ ดู เวอร์ชันโครงสร้างคอมโพเนนต์ | การสร้างแบ็กเอนด์อ่านแต่ละบล็อกตามคอมโพเนนต์ของตัวเองและประกาศ path ของสื่อต่อคอมโพเนนต์ บล็อกของคอมโพเนนต์ที่ฟิลด์ไม่อนุญาต คีย์ที่คอมโพเนนต์ไม่ได้ประกาศ และบล็อกเดี่ยวในที่ที่ต้องเป็นรายการ จะถูกปฏิเสธ บล็อกที่ซ่อนยังอยู่ในแถวและถูกตัดออกจากคำตอบของ reader ทุกครั้งและจากไซต์ที่สร้าง | การบันทึก การบันทึกโมเดล และการสร้าง | backend/src/lib/component-contract.ts. backend/src/lib/hidden-blocks.ts. backend/test/mixed-components.test.ts. backend/test/mixed-components-site-copy.test.ts. backend/test/hidden-blocks.test.ts |
| การอนุญาตระดับฟิลด์ | limits ของบทบาทระบุฟิลด์ที่อ่านและเขียนได้ ต่อโมเดลหรือสำหรับทุกโมเดล (*) บทบาทที่ไม่มีข้อจำกัดเข้าถึงทุกฟิลด์ ฟิลด์ที่อ่านไม่ได้ถูกตัดออกจากการอ่านอินสแตนซ์ รายการค่าและยอดรวม การค้นหา เนื้อหาเวอร์ชัน การอ่านหน้า และคลังหน้า และพรีวิวพกขอบเขตการอ่านของผู้สร้าง การบันทึกเก็บทุกค่าที่บทบาทมองไม่เห็นไว้ การกู้คืนที่จะเขียนทับฟิลด์ที่บทบาทเขียนไม่ได้ถูกปฏิเสธ (field_denied) การส่งออกทั้งไซต์ถูกปฏิเสธสำหรับบทบาทที่จำกัดการอ่าน (export_limited_role) บุคคลที่มีหลายบทบาทได้ผลรวมต่อการดำเนินการ ผู้จัดการบทบาทมอบได้เฉพาะสิ่งที่ตนมี และข้อมูลรับรอง management คงข้อจำกัดของบุคคลนั้น การเปลี่ยนชื่อคีย์ฟิลด์จะเขียนรายการฟิลด์ของทุกบทบาทสำหรับโมเดลนั้นใหม่ |
ไม่รองรับ ทำได้เฉพาะผ่าน hook ของคุณเองใน src/owned/backend.ts |
การบันทึก การกู้คืน การอ่าน และการบันทึกบทบาท | backend/src/lib/permission-limits.ts. backend/test/permission-limits.test.ts. backend/test/permission-limits-routes.test.ts. backend/test/permission-limits-lifecycle.test.ts. backend/test/permission-limits-pages.test.ts. backend/test/management-roles.test.ts |
| การอนุญาตระดับภาษา | limits ยังระบุภาษาต่อการกระทำ: อ่าน สร้าง แก้ไข ลบ กู้คืน ตรวจทาน เผยแพร่ และยกเลิกการเผยแพร่ การบันทึก ชุดงานแบบกลุ่ม การย้าย workflow การเผยแพร่ หรือการยกเลิกการเผยแพร่ที่แตะภาษานอกบทบาทถูกปฏิเสธทั้งหมด (locale_denied) และไม่เขียนอะไร การบังคับเผยแพร่หรือยกเลิกเผยแพร่ ทั้งแบบรายการเดียวและแบบกลุ่ม นับเฉพาะภาษาที่เวอร์ชันที่เผยแพร่อยู่จะเปลี่ยน และการปฏิเสธจะระบุภาษาเหล่านั้น การกู้คืนเวอร์ชันเก่าของหนึ่งภาษาต้องมี restore สำหรับภาษานั้นเท่านั้น และเปลี่ยนฟิลด์ รายการความสัมพันธ์ของภาษานั้นเอง และที่อยู่ของภาษานั้น ไม่เปลี่ยนค่าร่วมหรือภาษาอื่น การกู้คืนทั้งรายการต้องมีทุกภาษา ฟิลด์ร่วมที่เปลี่ยนต้องมีสิทธิ์แก้ไขภาษาหลัก ฟิลด์ร่วมที่ไม่เปลี่ยนไม่ต้อง หากบทบาทไม่มีสิทธิ์ลบในภาษาอื่นของรายการ บทบาทนั้นย้ายเฉพาะเวอร์ชันภาษาที่มีสิทธิ์ลบไปถังขยะแยกได้ แต่ย้ายทั้งรายการไม่ได้ พรีวิวไม่สลับไปใช้ภาษาที่ผู้สร้างอ่านไม่ได้ คีย์ :own ขยายภาษาเฉพาะแถวของบุคคลนั้นเอง superadmin ไม่ถูกจำกัด |
ไม่รองรับ | การบันทึก workflow ถังขยะ การอ่าน และพรีวิว | backend/src/lib/permission-limits.ts. backend/test/permission-limits-lifecycle.test.ts. backend/test/permission-limits-routes.test.ts. backend/test/permission-limits-preview.test.ts. backend/test/permission-limits.test.ts |
ความสัมพันธ์
หัวข้อที่มีชื่อว่า “ความสัมพันธ์”| ส่วน | หนึ่งต่อหนึ่ง | หลายต่อหนึ่ง | หนึ่งต่อหลาย | หลายต่อหลาย |
|---|---|---|---|---|
| เอดิเตอร์โมเดล | มีให้เลือก พร้อมคำอธิบาย “แต่ละรายการที่ลิงก์เป็นของ <owner> เพียงรายการเดียว” |
มีให้เลือก | มีให้เลือก พร้อมคำอธิบาย “แต่ละรายการที่ลิงก์เป็นของ <owner> เพียงรายการเดียว” ฟิลด์ของ component ไม่มีตัวเลือกนี้ (relation_type_not_authorable) |
มีให้เลือก |
| เชื่อมโยงจาก (เอดิเตอร์ของเป้าหมาย) | เป้าหมายแสดงรายการที่มีฟิลด์ชี้มาหา แยกตามโมเดลและฟิลด์ต้นทาง พร้อมป้าย “เฉพาะที่เผยแพร่”, “เฉพาะฉบับร่าง” และ “ดูได้อย่างเดียว” เอดิเตอร์ที่อ่านเป้าหมายได้และแก้ไขต้นทางได้สามารถเพิ่มหรือนำลิงก์ออก การเปลี่ยนนี้คือเวอร์ชันร่างใหม่ของต้นทาง บันทึกภายใต้สิทธิ์ การตรวจเวอร์ชัน กฎฟิลด์ จำนวนความสัมพันธ์ กฎเจ้าของเดียว และกฎลำดับชั้นของต้นทางเอง และไม่ถูกเผยแพร่ การแทนที่เป้าหมายอื่นของต้นทางต้องยืนยันโดยระบุทั้งสองรายการ (409 related_from_replace_unconfirmed) ฝั่งเป้าหมายไม่มีอะไรถูกเก็บ |
เหมือนกัน | เหมือนกัน แต่ไม่มีขั้นตอนแทนที่ | เหมือนกัน แต่ไม่มีขั้นตอนแทนที่ |
| การเขียนใน CMS | เป้าหมายเดียว | เป้าหมายเดียว | หลายเป้าหมาย | หลายเป้าหมาย |
| รูปแบบการเขียนใน CMS | รายการธรรมดาหรือ { set } แทนที่รายการตามลำดับของฟิลด์ { connect, disconnect, move } ลบออกก่อน แล้วเชื่อมตามลำดับที่ให้ (id ธรรมดาไปที่ท้าย { id, position } วางตามตำแหน่ง) แล้วจึงย้ายรายการที่เกี่ยวข้อง ตำแหน่งคือ before, after, start, end บนฟิลด์เป้าหมายเดียว ตำแหน่งหรือ move ถูกปฏิเสธ (relation_position_not_ordered) |
เหมือนกัน | เหมือนกัน | เหมือนกัน |
| การตรวจการเขียนใน CMS | เมื่อรายการเปลี่ยน: เป้าหมายมีอยู่ในเว็บไซต์ เป็นของโมเดลเป้าหมายที่ประกาศ (หนึ่งในโมเดลที่รับ เมื่อฟิลด์รับหลายโมเดล) ผู้เขียนอ่านได้ (รวมการอ่านแบบ :own) ปรากฏครั้งเดียว และฟิลด์แบบ to-one มีเป้าหมายเดียว รายการที่เท่ากับที่เก็บไว้จะไม่ถูกตรวจซ้ำ การกู้คืนผ่านการตรวจเดียวกัน เป้าหมายที่รายการอื่นชี้ไปในฟิลด์นี้ (ทั้งที่เผยแพร่และฉบับร่าง) ถูกปฏิเสธ (409 relation_target_taken) |
เหมือนกัน แต่ไม่มีการปฏิเสธตามกฎเจ้าของเดียว | เหมือนแบบหนึ่งต่อหนึ่ง | เหมือนกัน แต่ไม่มีการปฏิเสธตามกฎเจ้าของเดียว |
| การอ่านสาธารณะของ CMS | รายการ { instance_id, model, slug, display } ใน snapshot เป้าหมายของโมเดลที่แปลแล้วแสดงด้วยที่อยู่และชื่อของภาษาที่รายการแสดง แล้วตามลำดับภาษาสำรอง ในนโยบายแบบเข้มงวด เป้าหมายที่ไม่มีภาษานั้นจะไม่แสดง ตัวกรอง tag เทียบกับที่อยู่เดียวกันนั้น |
เหมือนกัน | เหมือนกัน | เหมือนกัน |
| สคีมาที่สร้าง | คอลัมน์ <key>_id, @unique มี foreign key |
คอลัมน์ <key>_id มี foreign key |
ตาราง junction ของโมเดลที่ประกาศฟิลด์ คอลัมน์เป้าหมายไม่ซ้ำ มี foreign key | ตาราง junction มี foreign key |
| การอ่านที่สร้าง | คอลัมน์ id | คอลัมน์ id | route junction แบบอ่านอย่างเดียว | route junction แบบอ่านอย่างเดียว |
| การเขียนที่สร้าง | ตั้งค่าคอลัมน์ id หลังตรวจว่าแถวเป้าหมายมีอยู่ มิฉะนั้นตอบ 422 relation_target_missing และไม่เขียนอะไร ผลลัพธ์แบบโมเดลเดียวไม่มีตารางเป้าหมาย จึงปฏิเสธ id ที่ไม่ใช่ null ทุกค่า |
เหมือนกัน | PUT /api/<owner>/relations/<field> ด้วย set, connect, disconnect ตรวจด้วยกฎของ CMS ใน batch เดียว เป้าหมายที่เจ้าของอื่นถืออยู่ได้ 409 relation_target_taken |
PUT /api/<owner>/relations/<field> กฎเดียวกัน |
| การลบเป้าหมายในแบ็กเอนด์ที่สร้าง | คอลัมน์ที่ไม่บังคับกลายเป็น null คอลัมน์ที่บังคับปฏิเสธการลบ (409 relation_target_referenced) |
เหมือนกัน | ลิงก์ถูกลบ | ลิงก์ถูกลบ |
- เป้าหมายที่ไม่มีอยู่ เป้าหมายของโมเดลอื่น และเป้าหมายที่ผู้เขียนไม่มีสิทธิ์อ่าน ถูกปฏิเสธแบบเดียวกัน (422
relation_target_not_found) การปฏิเสธระบุ id ที่ถูกปฏิเสธ คำตอบจึงไม่เปิดเผยว่า id ใดมีอยู่ - แถวที่เขียนไว้ก่อนมีการตรวจเหล่านี้ยังอ่านได้ การบันทึกครั้งถัดไปที่เปลี่ยนฟิลด์นั้นต้องผ่านการตรวจ
- ฟิลด์ที่แปลได้เขียนผ่าน route คำแปลที่สร้างขึ้น สร้างแถวคำแปลได้เพียงหนึ่งแถวต่อแถวต้นทางและภาษาที่มีอยู่ในข้อมูลที่ใช้สร้างไซต์ (
unknown_locale,translation_row_missing,locale_exists) การ update เปลี่ยนเฉพาะค่าที่แปล - การลบ: แถวความสัมพันธ์ถูกลบเมื่อรายการฝั่งใดถูกลบถาวร การย้ายรายการไปถังขยะยังเก็บแถวไว้ และการกู้คืนนำกลับมา รายการในถังขยะเลือกเป็นลิงก์ใหม่ไม่ได้ รายการอีกฝั่งยังอยู่ ไม่มีการตั้งค่าต่อฟิลด์ ในแบ็กเอนด์ทั้งไซต์ที่สร้างขึ้น ID ความสัมพันธ์ทุกตัวเป็น foreign key ตามพฤติกรรมด้านบน ID ความสัมพันธ์ภายในค่า JSON ของ component ไม่ใช่ key
- ลิงก์ต่างกันในแต่ละภาษา (
localizedMembershipเฉพาะโมเดลที่แปล ไม่ใช่ภายในคอมโพเนนต์): แต่ละภาษามีรายการตามลำดับของตนในแถว เวอร์ชัน และเอดิเตอร์ และกฎความสัมพันธ์ทุกข้อ (ชี้ไปที่หนึ่ง เจ้าของเดียว ลำดับชั้น ขีดจำกัดจำนวน) ถูกตรวจสอบแยกตามภาษา การอ่านสาธารณะให้บริการรายการของแต่ละภาษาเอง ภาษาสำรองให้บริการรายการของตน ไม่ใช่ของภาษาอื่น การกู้คืนนำรายการของแต่ละภาษากลับมา รวมถึงจากเวอร์ชันที่เขียนก่อนเปลี่ยนตัวเลือก การเปิดตัวเลือกคัดลอกรายการร่วมไปทุกภาษา การปิดเก็บรายการภาษาหลักและถูกบล็อกเมื่อสองรายการจะใช้เป้าหมายแบบเจ้าของเดียวร่วมกัน หรือ parent ของภาษาหลักจะวน การลบภาษาถาวรจะลบรายการของภาษานั้น สำเนาไซต์พกรายการของแต่ละภาษา backend ที่สร้างเก็บฟิลด์แบบนี้ รวมถึงแบบชี้ไปที่หนึ่ง เป็นแถวตารางเชื่อมที่มี locale และ route ความสัมพันธ์อ่านและเขียนรายการทีละภาษา หลักฐาน:backend/src/lib/lifecycle/relation-sets.ts.backend/test/relation-localized-membership.test.ts.backend/test/relation-localized-membership-site-copy.test.ts.backend/test/graduate-localized-membership.test.ts.
หลักฐาน: backend/src/lib/lifecycle/service.ts (planRelations, checkRelationLists, resolveRelationWrites) backend/src/api/models.ts backend/src/lib/relation-type.ts backend/src/lib/graduate/templates.ts (relationTargetsExist) backend/test/relation-writes.test.ts backend/test/lifecycle-atomicity.test.ts backend/test/models-apply.test.ts backend/test/graduate-relation-writes-worker.test.ts backend/test/graduate-relation-load.test.ts backend/test/graduate-relation-schema.test.ts backend/test/relation-cardinality.test.ts backend/test/graduate-junction-http.test.ts frontend/src/routes/model-builder/[id]/tabs/config-types/RelationConfig.svelte.test.ts.
แสดงผลอย่างเดียวเทียบกับบังคับใช้
หัวข้อที่มีชื่อว่า “แสดงผลอย่างเดียวเทียบกับบังคับใช้”| การควบคุม | เซิร์ฟเวอร์บังคับใช้หรือไม่ |
|---|---|
| ฟิลด์ “hidden” ในเอดิเตอร์ | ไม่ ค่ายังถูกเก็บและให้บริการอยู่ |
เงื่อนไขการแสดง (ui.showWhen) |
บางส่วน ค่าที่ซ่อนยังถูกเก็บและให้บริการ เซิร์ฟเวอร์บังคับฟิลด์เฉพาะขณะที่เงื่อนไขทำให้แสดง และปฏิเสธเงื่อนไขที่ทำตามไม่ได้ |
| ฟิลด์ “read-only” | ถูกนำออกจากเอดิเตอร์โมเดลแล้ว ค่าที่เก็บไว้ของการตั้งค่าเก่าถูกเพิกเฉย |
| การตรวจค่าฟิลด์: required, ความยาว, pattern, ช่วงและขั้นของตัวเลข, จำนวนรายการ, วันที่, ตัวเลือกของ select ทั้งฟิลด์ของโมเดลและทุกฟิลด์ภายในค่าของคอมโพเนนต์ | ตรวจค่าที่ส่งมาเมื่อบันทึกด้วยโมดูลเดียวกับเอดิเตอร์ โดยค่าเริ่มต้นฉบับร่างเว้นค่าที่บังคับได้ หรือเลือกโหมดเข้มงวดให้ครบตั้งแต่บันทึก การเผยแพร่ตรวจ snapshot ที่จะเผยแพร่จริงรวมถึงค่าที่บังคับทั้งหมด (422 field_validation_failed ระบุแต่ละฟิลด์ด้วยพาธเต็ม: seo.meta_title, faqs[2].question) ค่าของคอมโพเนนต์ถูกตรวจตามนิยามที่ฟิลด์ของมันอ้างถึง รายการในที่ที่ควรมีอินสแตนซ์เดียว อินสแตนซ์ที่ไม่ใช่อ็อบเจกต์ หรือคีย์ที่นิยามไม่ได้ประกาศไว้ (นอกจาก variant_id, enabled, id, _id) จะถูกปฏิเสธ มีเดียภายในคอมโพเนนต์รับได้ทุกรูปแบบที่ standalone backend ที่สร้างขึ้นอ่านได้ (id, { media_id, url }, รายการของสิ่งเหล่านี้ และรายการหนึ่งรายการในฟิลด์เดี่ยว) และถูกเก็บเป็น id หรือรายการ id คอมโพเนนต์เดี่ยวที่ไม่บังคับซึ่งมีแต่ค่าว่างนับว่าไม่ได้กรอก ฟิลด์ที่ซ่อน ฟิลด์ derived ที่ไม่มีใครแก้ได้ และฟิลด์ของหน้าที่ composer เป็นเจ้าของจะถูกข้าม เหมือนในเอดิเตอร์ การกู้คืนเวอร์ชันถูกตรวจตามโมเดลปัจจุบันและถูกปฏิเสธด้วย 422 เดียวกันโดยไม่เขียนอะไรเลย การนำเข้าถูกตรวจตามค่าที่แต่ละเฟสเขียน โดยที่งานวางแผนลิงก์ความสัมพันธ์และมีเดีย จำนวนจะถูกตรวจจากลิงก์ที่วางแผนไว้ การ dry run รายงานแต่ละปัญหาเป็นแถวที่บล็อกตามพาธและภาษาก่อนมีการเขียนใดๆ การตรวจสเปรดชีตตรวจแต่ละแถวที่แก้แบบเดียวกันก่อนการบันทึกครั้งแรก |
| พฤติกรรมการลบของความสัมพันธ์ | ถูกนำออกจากเอดิเตอร์โมเดลแล้ว การลบเป็นแบบตายตัว (ดูความสัมพันธ์) |
กฎการครอบตัดสื่อบนฟิลด์ (aspectRatio, minWidth, minHeight) |
ใช่ สำหรับการครอบตัดที่ผู้แก้ไขส่งมา กฎที่เปลี่ยนภายหลังไม่ขวางการบันทึกที่ไม่เกี่ยวข้อง การนำเข้าไม่ถูกตรวจซ้ำ |
settings.permissions, draft, versioning และการเรียงลำดับเริ่มต้นของโมเดล |
ลบการตั้งค่าเดิมแล้ว แต่รองรับ settings.validation_mode: draft เป็นค่าเริ่มต้น หรือ strict ให้กรอกค่าที่บังคับครบตั้งแต่บันทึก |
สิทธิ์ของบทบาทต่อโมเดล ความเป็นเจ้าของ :own สิทธิ์การเปลี่ยนสถานะ workflow สิทธิ์เผยแพร่และยกเลิกเผยแพร่ |
ใช่ |
การมองเห็นของโมเดล (public / private) บน API สาธารณะของ CMS |
ใช่ |
| ขนาด rich text (256 KiB) | ใช่ |
หลักฐาน: backend/src/lib/lifecycle/field-rules.ts frontend/src/lib/eav/content-validator.ts backend/src/lib/import/rule-findings.ts backend/test/field-rules.test.ts backend/test/field-rules-save.test.ts backend/test/component-rules-route.test.ts backend/test/import-field-rules.test.ts backend/test/import-strapi-field-rules.test.ts backend/test/spreadsheet-import.test.ts frontend/src/routes/content/[id]/component-rules.svelte.test.ts backend/test/media-framing.test.ts backend/test/transition-requires-write.test.ts backend/test/ownership-enforcement.test.ts backend/test/rich-field-contract.test.ts.
การดำเนินการด้านบรรณาธิการ
หัวข้อที่มีชื่อว่า “การดำเนินการด้านบรรณาธิการ”| ความสามารถ | CMS | หลักฐาน |
|---|---|---|
| การเผยแพร่ต่อภาษา | แต่ละภาษามีขั้น workflow และเวอร์ชันที่เผยแพร่อยู่ของตัวเอง เผยแพร่ ยกเลิกเผยแพร่ หรือรีวิวภาษาเดียวได้จากแผง เวิร์กโฟลว์ การกระทำแบบกลุ่มที่เผยแพร่หรือยกเลิกเผยแพร่จะย้ายทุกภาษา การย้ายแบบกลุ่มระหว่างสองขั้นที่ไม่ได้เผยแพร่ (เช่น อนุมัติ · ทุกภาษา หรือ ส่งกลับ · ทุกภาษา) จะคงภาษาที่เผยแพร่อยู่แล้วให้ยังออนไลน์และอยู่ในสถานะ เผยแพร่แล้ว และ เลิกเผยแพร่{language} ใช้นำภาษานั้นออก การอ่านสาธารณะ preview ที่อยู่ redirect และไซต์ที่สร้างขึ้นเป็นไปตามเวอร์ชันที่เผยแพร่ของแต่ละภาษาเอง ไซต์ที่สร้างขึ้นส่งออกแต่ละภาษาจากเวอร์ชันและที่อยู่ของภาษานั้นเอง เมื่อภาษาหลักไม่ได้เผยแพร่อยู่ การสร้างจะส่งออกรายการจากภาษาที่เผยแพร่อยู่ภายใต้ id เดียวกัน โดยใช้ค่าที่ใช้ร่วมกันจากเวอร์ชันที่เผยแพร่ของภาษาแรกที่เผยแพร่อยู่ตามลำดับของไซต์ (ภาษาเริ่มต้นก่อน) สำเนาไซต์พกตัวชี้ของแต่ละภาษาไปด้วย และการนำเข้า บันทึกผลการนำเข้า และการ undo คืนค่านั้น การตั้งเวลาภาษาเดียวต้องมีความสามารถของปลั๊กอิน workflow:locale |
backend/test/locale-publication.test.ts, backend/test/locale-publication-route.test.ts |
| การค้นหา การแชร์ การเปลี่ยนเส้นทาง และแผนผังเว็บไซต์ | ค่าการค้นหาและการแชร์ต่อภาษาอยู่ในแต่ละเวอร์ชัน พร้อมประเภทหน้าสำหรับข้อมูลแบบมีโครงสร้าง Site Chrome เก็บค่าเริ่มต้น ผู้ดูแลเว็บไซต์ รหัสยืนยันกับเครื่องมือค้นหา นโยบายแผนผังเว็บไซต์และ robots และการเปลี่ยนเส้นทางได้สูงสุด 256 ที่อยู่และ 32 รูปแบบ ซึ่งตอบ 301, 302, 307, 308, 410 หรือ 451 บริการเปลี่ยนเส้นทางเดียวปฏิเสธการวนซ้ำผ่านกฎทุกแบบ รูปแบบที่กำกวม ที่อยู่ที่สงวนไว้และที่อยู่ที่ใช้งานจริง รูปแบบที่เปลี่ยนต้องตรวจหน้าที่ใช้งานจริงที่ครอบคลุม การเผยแพร่ที่ที่อยู่ซึ่งการเปลี่ยนเส้นทางถือไว้จะถูกปฏิเสธพร้อมระบุกฎ renderer ทั้งสองใช้ตัวจับคู่เดียว ตัวเขียนแผนผังเว็บไซต์เดียว (ดัชนีของส่วนละ 5,000 ที่อยู่พร้อมรูปภาพ) และตัวแปลง JSON-LD เดียว | backend/test/redirect-service.test.ts, backend/test/redirect-runtime-parity.test.ts, backend/test/redirect-lifecycle.test.ts, backend/test/sitemap-runtime-parity.test.ts, backend/test/sitemap-public-route.test.ts, backend/test/structured-data.test.ts |
| การค้นหาสดของไซต์ | ปิดอยู่จนกว่าจะเปิดใน การตั้งค่า → ซอร์สโค้ดและการเผยแพร่ → การค้นหาของไซต์ (site:infra) GET /v1/_search ตอบด้วยหน้าที่เผยแพร่ โพสต์บนไซต์บล็อก และโมเดลสาธารณะที่เลือกได้สูงสุด 16 โมเดล ในภาษาที่ขอตามลำดับภาษาสำรองของไซต์ ร่าง โมเดลส่วนตัว รายการในถังขยะ และภาษาที่ตั้งให้ซ่อนจากเครื่องมือค้นหาจะไม่ปรากฏ ทุกคำต้องตรงตามการจับคู่ของประเภท: ทั้งคำ (ค่าเริ่มต้น) รูปคำภาษาอังกฤษ (stemming แบบ Porter2 ทั้งข้อความที่เก็บและคำค้น ใช้ได้กับทุกไซต์ ตัดสินต่อผลลัพธ์ตามภาษาที่ให้บริการ: en, en-* และ en_* จับคู่ด้วยรูปคำ ภาษาอื่นจับคู่ทั้งคำ ในคำค้นเดียว) หรือบางส่วนของคำ รายการที่ตรงในชื่อเรื่องมาก่อน จากนั้นเป็นรายการใหม่สุด รูปแบบการจับคู่ทั้งหมดถูกเก็บพร้อมแต่ละเวอร์ชัน การเปลี่ยนการจับคู่จึงไม่ต้องสร้างอะไรใหม่ และ cursor กับ cache key รวมการจับคู่และลำดับภาษาสำรองไว้ด้วย ในส่วนการจับคู่และการจัดอันดับ ประเภทหนึ่งสามารถค้นหาจากฟิลด์ที่เลือกได้สูงสุด 16 ฟิลด์แทน แต่ละฟิลด์มีน้ำหนัก 1–10 (ชื่อเรื่อง 10 ฟิลด์อื่น 1 เป็นค่าเริ่มต้น) ผลลัพธ์จัดอันดับตามน้ำหนักสูงสุดในบรรดาฟิลด์ที่เลือกซึ่งมีทุกคำ จากนั้นตามความใหม่ น้ำหนักถูกอ่านตอนค้นหา จึงไม่ต้องสร้างอะไรใหม่ คำของแต่ละเวอร์ชันถูกเก็บใน batch เดียวกับที่บันทึกเวอร์ชันนั้น ส่วนการที่แถวเผยแพร่อยู่หรือไม่และที่อยู่ของแถวจะตัดสินตอนค้นหา การเผยแพร่ การเลิกเผยแพร่ ถังขยะ และการย้ายที่อยู่จึงมีผลทันที เมื่อปิดการค้นหาจะตอบ 404 search_off ไซต์แบบ managed และไซต์ที่สร้างขึ้นใช้สิ่งนี้แสดง /search, /<language>/search และส่วน ค้นหาในเว็บไซต์ ตอนมีคำขอ ไม่ต้องบิลด์ใหม่เพื่ออัปเดตการค้นหา GET /v1/_search/suggest ตอบรายการที่ตรงได้สูงสุด 10 รายการ โดยให้ชื่อเรื่องมาก่อน จากแถวเดียวกัน ใช้การจับคู่ cache tag และการล้างแบบเดียวกัน คำสุดท้ายตรงกับส่วนต้นของคำ ช่องค้นหาทุกช่องแสดงรายการเหล่านี้ขณะผู้เข้าชมพิมพ์ (combobox สำหรับคีย์บอร์ดและโปรแกรมอ่านหน้าจอ และเป็นฟอร์ม GET ธรรมดาเมื่อไม่มี JavaScript) และไม่บันทึกสิ่งใดเกี่ยวกับคำค้น |
backend/src/lib/search/public-search.ts. backend/src/lib/search/projection.ts. backend/src/lib/search/suggest-script.ts. backend/src/lib/search/english-stem.ts. backend/test/public-search.test.ts. backend/test/search-projection.test.ts. backend/test/english-stem.test.ts. frontend/src/lib/sites/search-suggest-script.test.ts |
| ถังขยะ | การลบย้ายรายการทั้งหมดทุกภาษาไปถังขยะ เนื้อหาที่เผยแพร่อยู่ถูกปฏิเสธจนกว่าจะยกเลิกเผยแพร่ รายการในถังขยะหายไปจากรายการปกติ การค้นหา ตัวเลือกความสัมพันธ์ แดชบอร์ด การส่งออก และ preview รายการเนื้อหาและหน้าแต่ละรายการมีถังขยะอยู่ข้าง ๆ จำกัดเฉพาะโมเดลที่บุคคลนั้นอ่านได้ การกู้คืนต้องมีสิทธิ์ delete บนโมเดล คืนรายการเป็นฉบับร่างพร้อมเวอร์ชัน คำแปล ลิงก์ และสื่อ และแสดงก่อนว่าที่อยู่ใดถูกใช้แล้วและลิงก์ใดใช้ไม่ได้ การลบถาวรเป็นการกระทำแยกที่ต้องยืนยัน รายการถูกลบถาวร 30 วันหลังย้ายไปถังขยะ ภาษาหนึ่งที่ไม่ได้เก็บประวัติย้ายไปถังขยะแยกได้ (“ย้ายภาษานี้ไปถังขยะ”): หายไปจากเวอร์ชันปัจจุบัน ตัวสลับภาษา และการอ่านสาธารณะ ส่วนที่เหลือยังแก้ไขและเผยแพร่ได้ การเพิ่มภาษานั้นอีกถูกปฏิเสธ (language_in_trash) และการกู้คืนนำกลับเป็นฉบับร่าง โพสต์มีถังขยะของตัวเองข้างรายการ เนื้อหาในถังขยะที่ลิงก์ไปยังรายการไม่ขวางการยกเลิกเผยแพร่รายการนั้น และแสดงว่าอยู่ในถังขยะ การนำเข้าปฏิเสธรายการที่ที่อยู่เป็นของรายการในถังขยะ การนำเข้าซ้ำไปยังรายการที่อยู่ในถังขยะ และลิงก์ไปยังรายการนั้น |
backend/src/lib/lifecycle/trash.ts backend/src/api/content_lifecycle.ts backend/test/content-trash.test.ts |
| การกระทำแบบกลุ่ม | ย้ายไปยังขั้นของ workflow เผยแพร่หรือยกเลิกเผยแพร่แบบ override หรือย้าย id ที่ระบุชัดไปถังขยะ กู้คืน หรือลบถาวร request หนึ่งรับ id ได้ไม่เกิน 25 แต่ละรายการผ่านการตรวจของ route เดี่ยวของมัน รวมถึง revision ของตัวเองและรายการที่ขึ้นกับมันซึ่งผ่านการตรวจแล้ว ผลลัพธ์เรียงตามลำดับที่ส่งเข้า การลองใหม่ด้วย key เดิมจะคืนผลของรายการที่ commit แล้วแทนการรันใหม่ แม้หลัง request ที่หยุดกลางทาง key ผูกกับบุคคล route ทั่วไป /many และ /bulk ตอบ 410 relate เพิ่มหรือนำออกรายการที่ลิงก์ได้สูงสุด 10 รายการในฟิลด์ many-to-many หนึ่งฟิลด์ของแต่ละรายการ (โพสต์ → หมวดหมู่และแท็ก) เป็นการบันทึกของรายการนั้นเองพร้อมการตรวจเวอร์ชัน ไม่เผยแพร่อะไร รายการที่มีการเปลี่ยนนั้นอยู่แล้วได้ unchanged และฟิลด์ one-to-many ถูกปฏิเสธ (batch_relation_exclusive) |
backend/src/api/content_lifecycle.ts (/batch) backend/test/content-batch.test.ts backend/test/content-batch-relate.test.ts |
| การถือสิทธิ์แก้ไข | ผู้แก้ไขคนแรกของรายการและภาษาถือ lease การแก้ไข คนอื่นที่เปิดจะเห็นว่าใครถืออยู่ ดูการแก้ไขผ่านฟอร์มอ่านอย่างเดียวที่อัปเดตตามฉบับร่างร่วมของผู้ถือสิทธิ์ และ รับช่วงแก้ไข ได้ในการกระทำเดียว lease ย้ายทันที: ผู้ถือคนก่อนได้รับแจ้งว่าใครรับช่วง การบันทึกหรือการย้ายครั้งถัดไปของเขาถูกปฏิเสธ 423 lock_lost และสิ่งที่พิมพ์ไว้แต่ยังไม่บันทึกถูกเก็บเป็น draft กู้คืนของเขาเอง และเสนอกลับเมื่อเขาถือ lease อีกครั้ง การเข้าร่วมหรือรับช่วง lease ของภาษาใดต้องมีสิทธิ์เปลี่ยนแปลงในภาษานั้น (หรือสิทธิ์สร้าง เมื่อภาษานั้นยังไม่มีแถว มิฉะนั้น locale_denied) และบทบาทที่มีสิทธิ์เฉพาะของตนเองต้องเป็นเจ้าของแถวของภาษานั้น (not_owner) การบันทึก การเพิ่มภาษา การย้าย workflow การมอบหมาย การกู้คืนเวอร์ชัน การบังคับเผยแพร่ ถังขยะ และการลบถาวรของรายการและภาษานั้นจาก session อื่นใดถูกปฏิเสธ 423 locked ชุดงานจากรายการปฏิเสธเฉพาะรายการที่ถูกถือ รายการเนื้อหาและข้อมูลรับรอง management ของบุคคลเดียวกันไม่ถูกบล็อกโดยเอดิเตอร์ที่ตนเปิดอยู่ แต่ของบุคคลอื่นถูกบล็อก ปลั๊กอิน การนำเข้า การเผยแพร่ตามเวลา และการใช้สเปรดชีตไม่ถูกบล็อกเลย การตรวจเวอร์ชันยังปกป้องเอดิเตอร์ lease ถูกตรวจเมื่อวางแผนการเขียนและอีกครั้งภายในชุดงานของการเขียนนั้นเอง take over ที่แข่งกับการบันทึกจึงปฏิเสธการบันทึกนั้น lease มีอายุสองนาทีหลังต่ออายุครั้งล่าสุด หยุดต่ออายุในแท็บที่ซ่อน สิ้นสุดเมื่อปิดแท็บ และ lease ที่หมดอายุไม่บล็อกเลย ขณะตาม lease ของคนอื่น เอดิเตอร์ถามทุก 10 วินาที (ไม่ถามจากแท็บที่ซ่อน) และแสดง draft ร่วมที่ใหม่กว่าของเขา คนที่เปิดภาษาอื่นของรายการเดียวกันแสดงในบรรทัดเดียว ไม่มีการบันทึก log นับ หรือเก็บในประวัติ เปิดเอดิเตอร์ได้สูงสุด 20 ตัวต่อคนต่อไซต์ การเขียนหรือทิ้ง draft ร่วมที่เสีย lease ก่อน commit ถูกปฏิเสธ 423 lock_lost และไม่เปลี่ยนอะไร การบันทึกอัตโนมัติที่ถูกปฏิเสธถูกเก็บเป็น draft กู้คืนของบุคคลนั้นเอง ส่วนการทิ้งที่ถูกปฏิเสธจะแสดงข้อความ ไม่ได้ทิ้ง — มีคนรับช่วงแก้ไข งานของคุณยังเก็บไว้ และงานบนหน้าจอถูกเก็บเป็น draft กู้คืน page composer ทำงานแบบเดียวกัน: อ่านอย่างเดียวขณะที่คนอื่นถือหน้าและภาษา Take over ครั้งเดียว และชุดการเปลี่ยนแปลงถูกเก็บเป็น draft ของบุคคลนั้นเมื่อเสีย lease |
backend/src/lib/presence.ts. backend/src/lib/lifecycle/editing-lease.ts. backend/src/api/presence.ts. backend/test/editing-ownership.test.ts. backend/test/editor-presence.test.ts. frontend/src/lib/presence/presence.svelte.test.ts. frontend/src/lib/drafts/draft-discard-refused.svelte.test.ts. frontend/cypress/e2e/journey-editor-presence.cy.ts |
| Draft ร่วม | งานที่ยังไม่บันทึกของรายการบันทึกอัตโนมัติหลังหยุดพักสั้น ๆ เป็น draft ร่วมหนึ่งชุดต่อรายการและภาษา: ผู้ถือ lease เป็นผู้เขียน ทุกคนที่อ่านรายการได้อ่านได้ ส่วนบทบาทที่มีสิทธิ์เฉพาะของตนเองต้องเป็นเจ้าของแถวของภาษานั้น (มิฉะนั้น not_owner) ทุกคำตอบที่มี draft รวมถึงกรณีขัดแย้ง แสดงเฉพาะฟิลด์และภาษาที่บุคคลนั้นอ่านได้ สิทธิ์อ่านตัดสินจากสิทธิ์อ่านเท่านั้น แยกจากสิทธิ์เขียน บุคคลที่เขียน draft ได้แต่อ่านแถวหรือภาษานั้นไม่ได้จึงไม่เคยเห็น draft (current: null ในกรณีขัดแย้ง และ draft: null จาก take over ผ่าน management API) ผู้ถือที่อ่านไม่ได้ทุกฟิลด์เขียนเฉพาะฟิลด์ที่อ่านได้ และฟิลด์อื่นถูกเก็บไว้ draft ของหน้ามีชื่อเรื่องว่างสำหรับบทบาทที่อ่านชื่อเรื่องไม่ได้ และถูกปฏิเสธ (field_denied) สำหรับบทบาทที่อ่านส่วนต่าง ๆ ของหน้าไม่ได้ draft แสดงบนอุปกรณ์ใดก็ได้หลัง reload การเขียนแต่ละครั้งระบุ revision ที่แทนที่ เมื่อเขียนโดยอ้างอิงรีวิชันเก่า ระบบจะหยุดและให้เลือกว่าจะใช้ฉบับใด เอดิเตอร์แสดง กำลังบันทึกฉบับร่าง…, บันทึกฉบับร่างแล้ว, ออฟไลน์ — เก็บไว้ที่นี่ (เก็บไว้บนอุปกรณ์นี้และส่งเมื่อเชื่อมต่อใหม่หรือกด ลองอีกครั้ง), มีการเปลี่ยนแปลงบนอุปกรณ์อื่น หรือ ยังไม่ได้บันทึกฉบับร่าง draft ไม่ใช่เวอร์ชัน การบันทึกยกระดับ draft: เขียนเวอร์ชันและล้าง draft ในชุดงานเดียว การย้าย workflow หรือการบังคับเผยแพร่บันทึกงานที่ยังไม่บันทึกก่อน แต่การบังคับยกเลิกเผยแพร่ไม่บันทึกก่อน draft ร่วมถูกเก็บไว้ 30 วันหลังการเปลี่ยนแปลงครั้งล่าสุด page composer เก็บชุดการเปลี่ยนแปลงเป็น draft ร่วมของหน้าแบบเดียวกัน รายการใหม่เก็บ draft ส่วนตัวของบุคคลนั้น |
backend/src/lib/working-drafts.ts. backend/src/api/presence.ts. backend/test/editing-ownership.test.ts. frontend/src/lib/drafts/draft-sync.svelte.test.ts. frontend/src/lib/drafts/DraftStatus.svelte.test.ts. frontend/cypress/e2e/journey-cross-device-drafts.cy.ts |
| การมอบหมายผู้รีวิว | ผู้รับมอบหมาย workflow หนึ่งคนและวันครบกำหนดที่ไม่บังคับต่อทั้งรายการ ตรวจสิทธิ์จากขั้นปัจจุบัน เจ้าของแต่ละภาษาและงานบรรณาธิการหลายคนมีการมอบหมาย สถานะและ revision ของตนเอง ไม่แทนผู้รับมอบหมาย workflow revision ที่ล้าสมัยตอบ 409 มีเหตุการณ์การมอบหมายในการเขียนเดียวกัน การย้ายขั้นจะล้างการมอบหมาย เว้นแต่ระบุผู้รับมอบหมายคนถัดไป UI ระบุผู้รับมอบหมายที่ไม่ active และผู้รับมอบหมายที่ไม่มีสิทธิ์เข้าถึง ใช้ assigned=me บนคิวรีวิว การมอบหมายแจ้งเตือนผู้รับมอบหมายคนใหม่ งานที่บังคับต้องเสร็จสำหรับ snapshot ที่จะเผยแพร่ การแก้ภาษาอื่นไม่ล้างการอนุมัติภาษานี้ แต่การเปลี่ยนค่าที่ตรวจทานหรือค่าร่วมต้องรีวิวใหม่ |
backend/src/lib/lifecycle/assignment.ts backend/test/workflow-assignment.test.ts |
| การแจ้งเตือนรีวิว | การสนทนาผูกกับเวอร์ชัน ภาษา และพาธฟิลด์ รองรับคำตอบ การกล่าวถึงผู้ใช้หรือทีม และการปิดหรือเปิดทั้งเธรดอีกครั้ง ตรวจสิทธิ์ฟิลด์ ภาษา และผู้รับตามปัจจุบัน การแจ้งเตือนในแอดมินเมื่อมอบหมาย ขอรีวิว และส่งกลับให้แก้ไข เขียนใน batch เดียวกับการย้ายขั้น workflow คีย์ไม่ซ้ำ (ชนิด รายการ ภาษา revision ของ workflow ผู้รับ) ทำให้การย้ายที่ลองใหม่หรือแข่งกันเขียนการแจ้งเตือนหนึ่งรายการต่อผู้รับ และการย้ายที่ถูกปฏิเสธไม่เขียนเลย การย้ายจาก editor, management API และปลั๊กอินใช้เส้นทางเดียว (reviewNoticesFor) ผู้รับทุกคน รวมถึงผู้รับมอบหมายที่ระบุชื่อ ต้องเป็นสมาชิกที่ active ซึ่งอ่าน model ได้ (ขอบเขตแถวของตัวเองนับกับทุกแถวที่เกี่ยวข้อง) และอ่านภาษาที่เกี่ยวข้องได้ สิทธิ์แก้ไขหรือรีวิวอย่างเดียวไม่พอ การย้ายเฉพาะภาษาแจ้งเฉพาะผู้ที่รีวิวได้ทุกภาษาที่ย้ายด้วย ผู้เขียนที่ถูกส่งกลับหรือผู้รับมอบหมายต้องอ่านได้อย่างน้อยหนึ่งภาษา การอ่านตรวจสิทธิ์รายการและภาษาอีกครั้ง ลิงก์ไปยังรายการของภาษานั้นและแสดงขั้นปัจจุบัน การนำเข้าเงียบโดยค่าเริ่มต้น งานนำเข้าเก็บ review_notify (quiet หรือ notify เปลี่ยนได้ด้วย data:import จนกว่างานจะจบ) และการนำเข้าที่แจ้งเตือนเขียนเฉพาะการแจ้งเตือนในแอดมิน ประวัติที่ย้ายมาไม่แจ้งเตือนเลย ผู้รับไม่เกิน 50 คนต่อการแจ้งเตือน อีเมลเป็นตัวเลือก |
backend/src/lib/review/context.ts backend/src/lib/review/notifications.ts backend/src/lib/review/notification-read.ts backend/test/review-feedback-notifications.test.ts backend/test/review-locale-notifications.test.ts backend/test/import-notify-policy.test.ts |
| ตัวกรองและการเรียงตามฟิลด์ในรายการ | ใช้ค่าที่บันทึกล่าสุดรวมฉบับร่างของโมเดลเดียว field_filters มีได้สูงสุดสี่เงื่อนไขในกลุ่ม AND/OR ลึกสามระดับ การเทียบค่า scalar การมีหรือไม่มีความสัมพันธ์ และฟิลด์แสดงผลของความสัมพันธ์ภายในไซต์ที่ตั้งไว้ ตรวจสิทธิ์เป้าหมายปัจจุบัน field_sort เรียงหนึ่งฟิลด์ scalar หรือฟิลด์แสดงผลของความสัมพันธ์ค่าเดียวที่มีโมเดลเป้าหมายเดียว ค่าที่ว่างหรืออ่านไม่ได้อยู่ท้าย ใช้ ID ตัดสินเมื่อเท่ากัน จุดรองรับรัศมี กรอบพื้นที่ และระยะใกล้สุดอย่างแม่นยำ ข้อความจัดรูปแบบ สื่อ คอมโพเนนต์ และ JSON ยังไม่รองรับ แถว จำนวน ID ที่ตรง มุมมอง และการตรึงงานกลุ่มใช้แผน SQL เดียวกันโดยไม่จำกัดจำนวนแถวที่นำมาค้น cursor ผูกกับ query ทั้งหมด และปฏิเสธพารามิเตอร์ที่เกินขีดจำกัด |
backend/src/lib/content-fields/ backend/src/lib/scoped-crud.ts backend/test/content-field-query.test.ts backend/test/content-views.test.ts backend/test/content-bulk.test.ts |
| การครอบตัดและจุดโฟกัส | ต่อการอ้างอิงสื่อ เป็นสัดส่วนของภาพที่เก็บไว้ บนฟิลด์สื่อระดับบนสุด จัดเฟรมแยกตามการใช้ภาพแต่ละครั้ง (per occurrence): รูปเดียวกันสองครั้งในฟิลด์เดียวเก็บการจัดเฟรมของแต่ละครั้ง ไบต์ไม่เปลี่ยนเลย คงอยู่เมื่อบันทึกที่ไม่เกี่ยวข้อง บันทึกไว้ในเวอร์ชัน ส่งต่อโดยการกู้คืนและการย้าย bundle คงไว้เมื่อแทนที่ไฟล์ (พร้อมคำเตือนเรื่องรูปทรง) ให้บริการโดย API สาธารณะของ CMS และส่งเข้าอินพุตของการสร้าง จุดโฟกัสเริ่มต้นต่อภาพใช้กับการใช้ภาพครั้งใหม่เท่านั้น และสำเนาไซต์ส่งค่านี้ไปด้วย สื่อในคอมโพเนนต์จัดเฟรมต่อการใช้แต่ละครั้งภายในค่า ({ media_id, crop?, focal? } หรือ id เปล่าเมื่อไม่จัดเฟรม) สำเนาไซต์และการส่งมอบ standalone backend เก็บไว้ ไซต์ที่สร้างแล้วส่งสำเนาที่ย่อขนาดและครอบตัดแล้วผ่าน Cloudflare Image Transformations บนโฮสต์ที่เจ้าของประกาศไว้ และส่ง URL เดิมพร้อมการจัดเฟรมด้วย CSS ในกรณีอื่น ภาพในส่วนของหน้าจัดเฟรมได้ทีละช่อง (ข้อกำหนดข้อมูลหน้า เวอร์ชัน 4) ตัวเรนเดอร์แบบ managed วาดภาพด้วยกฎเดียวกันตั้งแต่ built-in template เวอร์ชัน 4 โดยกำหนดโฮสต์สำหรับแปลงภาพตอนติดตั้ง (MANAGED_IMAGE_TRANSFORM_ORIGINS) |
backend/src/lib/lifecycle/media-framing.ts backend/src/lib/graduate/site-media-presentation.ts backend/test/media-framing.test.ts backend/test/media-default-focal.test.ts backend/test/component-media-framing.test.ts backend/test/media-default-focal-bundle.test.ts backend/test/image-delivery.test.ts backend/test/media-mime.test.ts backend/test/import-bundle-spine.test.ts |
| แท็กสื่อ | แท็กแบบแบนของคลังสื่อที่เป็นของไซต์ แท็กเป็นอิสระจากโฟลเดอร์ ชื่อไม่ซ้ำกันในไซต์โดยไม่สนตัวพิมพ์เล็กใหญ่ ยาวได้ถึง 64 ตัวอักษร กล่องสื่อที่ใช้ร่วมกันกรองตามทุกแท็กที่เลือก หรือตาม “ไม่มีแท็ก” ร่วมกับการค้นหา ใช้ติดแท็กให้ภาพที่เลือก เปลี่ยนชื่อแท็ก และลบแท็กได้ การลบแท็กไม่ลบภาพเลย แท็กที่ใช้อยู่จะลบได้หลังยืนยันซึ่งบอกจำนวนภาพที่มีแท็กนั้น การอ่านเป็นไปตามสิทธิ์อ่านสื่อ การแก้ไขต้องมี media:update สำเนาไซต์พกชื่อแท็กของแต่ละภาพไปด้วย แท็กที่ไม่มีภาพจะไม่ถูกพกไป การนำเข้าจาก Strapi ไม่สร้างแท็ก ไม่มี API สาธารณะใดให้บริการแท็ก |
backend/src/api/media-tags.ts. backend/src/lib/media/tags.ts. backend/test/media-tags-route.test.ts. backend/test/media-tags-bundle.test.ts |
| โฟลเดอร์สื่อ | โฟลเดอร์แบบตรรกะของคลังสื่อที่เป็นของไซต์ โฟลเดอร์ไม่เคยย้ายหรือเปลี่ยนชื่อไฟล์ที่เก็บไว้หรือที่อยู่ของไฟล์ ไฟล์แต่ละไฟล์อยู่ในโฟลเดอร์เดียวหรือใน ไม่มีโฟลเดอร์ โฟลเดอร์ซ้อนกันได้สูงสุด 5 ระดับ ไซต์หนึ่งมีได้สูงสุด 500 โฟลเดอร์ และชื่อยาว 1–80 ตัวอักษร ไม่ซ้ำภายใต้โฟลเดอร์แม่โดยไม่สนตัวพิมพ์เล็กใหญ่ กล่องสื่อที่ใช้ร่วมกัน ทั้งในคลังสื่อและในตัวเลือกทุกตัว แสดง สื่อทั้งหมด, ไม่มีโฟลเดอร์ และต้นไม้โฟลเดอร์พร้อมจำนวน มุมมองโฟลเดอร์แสดงไฟล์ของโฟลเดอร์นั้นเอง ไม่รวมไฟล์ในโฟลเดอร์ย่อย ไฟล์ที่อัปโหลดใหม่และภาพที่สร้างแล้วบันทึกจะเข้าไปในโฟลเดอร์ที่แสดงอยู่ ไฟล์ที่เลือก (สูงสุด 200) ย้ายไปพร้อมกัน การเปลี่ยนชื่อและการย้ายส่ง revision ที่อ่านมา revision ที่ล้าสมัยถูกปฏิเสธด้วย media_folder_changed การย้ายเข้าไปในโฟลเดอร์ตัวเองหรือที่ต่ำกว่าถูกปฏิเสธ (media_folder_cycle) เช่นเดียวกับการย้ายที่เกิน 5 ระดับ (media_folder_too_deep) การลบโฟลเดอร์จะลบทั้งต้นไม้ย่อยหลังการยืนยันหนึ่งครั้งที่บอกจำนวนโฟลเดอร์และไฟล์ ไม่มีไฟล์ใดถูกลบ ทุกไฟล์จะไปอยู่ใน ไม่มีโฟลเดอร์ การลบถูกปฏิเสธหากจำนวนใดจำนวนหนึ่งเปลี่ยนไป การอ่านเป็นไปตามสิทธิ์อ่านสื่อ การแก้ไขต้องมี media:update ส่วน API การจัดการใช้บริการเดียวกันภายใต้ media:write สำเนาไซต์และการโอนพร้อมประวัติพกทั้งต้นไม้ รวมโฟลเดอร์ว่าง ไปใน media-folders.json (bundle 1.10) และแต่ละไฟล์ระบุโฟลเดอร์ของตัวเอง การนำเข้าสร้างต้นไม้ใหม่ด้วย id ใหม่ โฟลเดอร์แม่ก่อน โดยมีบันทึกผลการนำเข้าหนึ่งรายการต่อโฟลเดอร์ และใช้โฟลเดอร์ที่มีอยู่แล้วในพาธเดียวกันซ้ำโดยไม่สนตัวพิมพ์เล็กใหญ่ การ undo ลบโฟลเดอร์ที่การนำเข้าสร้างไว้เฉพาะเมื่อโฟลเดอร์นั้นยังไม่เปลี่ยนและไม่มีไฟล์หรือโฟลเดอร์อยู่ข้างใน มิฉะนั้นจะเก็บไว้ เหมือนแท็ก การนำเข้าจาก Strapi 4 หรือ 5 สร้างต้นไม้โฟลเดอร์ใหม่จากเอนทิตีโฟลเดอร์ของไฟล์เก็บถาวรและลิงก์แม่กับลิงก์ไฟล์ถึงโฟลเดอร์ที่ระบุชัด เฉพาะโฟลเดอร์ที่ไฟล์ที่เลือกอยู่ และไม่เคยจากพาธไฟล์ โฟลเดอร์ที่สร้างภายใต้ขีดจำกัดเหล่านี้ไม่ได้บล็อกการรันทดลองและไม่ถูกเปลี่ยนชื่อ (ดู โฟลเดอร์สื่อของ Strapi) ไม่มี API สาธารณะ ไซต์ที่สร้างขึ้น หรือ standalone backend ที่สร้างขึ้นใดพกโฟลเดอร์ไป |
backend/src/lib/media/folders.ts. backend/src/api/media-folders.ts. backend/test/media-folders.test.ts. backend/test/media-folders-transfer.test.ts. backend/src/lib/import/media-folder-apply.ts. backend/src/lib/import/undo-media-folder.ts. backend/test/management-media-folders.test.ts. frontend/src/lib/components/custom-ui/image-select/MediaFolders.svelte.test.ts |
| ไฟล์สื่อ | แต่ละไซต์เลือกชนิดรูปภาพ เอกสาร เสียง วิดีโอ และไฟล์ดาวน์โหลดที่รับได้ SVG เป็นรูปภาพเมื่อผ่านการตรวจโครงสร้างแบบคงที่ที่รองรับ สคริปต์ ทรัพยากรภายนอก และมาร์กอัปที่ไม่รองรับจะถูกปฏิเสธ รูปภาพแรสเตอร์และการทำงานที่อ่านทั้งไฟล์ยังใช้ขีดจำกัดตามเอกสาร ไฟล์ขนาดใหญ่ที่ไซต์รับได้ถ่ายโอนเป็นส่วนผ่านรูปแบบของ Dee Wan ดู สื่อ และขนาดไฟล์ | backend/src/lib/page-contract/media-kinds.ts. backend/src/lib/media/media-type.ts. backend/src/lib/media/duplicate.ts. backend/src/lib/media/media-settings.ts. backend/test/media-type.test.ts. backend/test/media-files.test.ts. backend/test/media-asset-renderers.test.ts. backend/test/management-api.test.ts. backend/test/plugin-operations.test.ts. backend/test/media-formats.test.ts. backend/test/media-stream-upload.test.ts |
| การแก้ไขรูปภาพ | คลังสื่อ → แก้ไข → ครอบตัดและหมุน: หมุนครั้งละ 90 องศาและครอปอิสระ ด้วยเมาส์ (ที่จับมุม 44px) การแตะ หรือคีย์บอร์ด (ลูกศรเลื่อน Alt+ลูกศรปรับขนาด R หมุน Enter บันทึก) บันทึกเป็นสำเนา อัปโหลดไบต์ที่แก้ไขผ่านการอัปโหลดปกติเป็นไฟล์ใหม่ที่มี digest ขนาดไฟล์ ขนาดภาพ และข้อมูลการใช้งานของตัวเอง บันทึก edited_from รับแท็ก alt text และโฟลเดอร์ของต้นฉบับ และถูกเลือกทันที ต้นฉบับถูกเก็บไว้ แทนที่ต้นฉบับ (อยู่หลัง ⋯) แสดงก่อนว่ารูปภาพถูกใช้ที่ไหน แล้วแทนที่ผ่านการแทนที่ที่มีอยู่เมื่อยืนยันครั้งเดียว การแปลงรูปแบบที่บันทึกก็เป็นการแทนที่และแสดงการตรวจทานเดียวกัน management API และการอัปโหลดแบบสตรีมรับ edited_from การส่งออก การนำเข้า และสำเนาไซต์พกค่านี้ไปด้วย โดยลิงก์ใหม่ไปยังต้นฉบับที่คัดลอก หรือตัดทิ้งเมื่อต้นฉบับไม่อยู่ใน bundle |
frontend/src/lib/components/custom-ui/image-select/ImageEditor.svelte. frontend/src/lib/components/custom-ui/image-select/image-edit.ts. backend/src/lib/media/upload.ts. frontend/src/lib/components/custom-ui/image-select/ImageEditor.svelte.test.ts. backend/test/media-files.test.ts. backend/test/management-media.test.ts. frontend/cypress/e2e/journey-media-edit.cy.ts |
| สื่อส่วนตัวและสิทธิ์ด้านสื่อ | ไฟล์ส่วนตัวอยู่ในพื้นที่จัดเก็บส่วนตัว ข้อความจัดรูปแบบที่ป้องกันการเข้าถึงใส่รูปภาพและไฟล์แนบส่วนตัวได้ โดยตรวจสิทธิ์ปัจจุบันของผู้อ่าน รูปภาพขนาดต่าง ๆ ที่ตั้งชื่อไว้ใช้การตรวจเดียวกัน บริบทสาธารณะปฏิเสธไฟล์ส่วนตัว การถ่ายโอนของ Dee Wan เก็บไฟล์และรูปภาพขนาดต่าง ๆ เป็นส่วนตัว ดู ไฟล์ส่วนตัว | backend/src/lib/media/private-storage.ts. backend/src/lib/media/visibility.ts. backend/src/lib/media/capability.ts. backend/src/lib/media/delivery.ts. backend/src/api/private-media.ts. backend/test/media-private.test.ts. backend/test/media-private-content.test.ts. backend/test/media-private-stream.test.ts. backend/test/media-private-transfer.test.ts. backend/test/media-private-protected.test.ts. backend/test/graduate-media-private.test.ts. backend/test/graduate-private-files-worker.test.ts. backend/test/graduate-private-files-node.test.ts. backend/test/media-private-placement-race.test.ts. backend/test/media-permissions.test.ts. frontend/cypress/e2e/journey-media-private.cy.ts |
| แหล่งสื่อภายนอก | ปลั๊กอิน remote ที่ได้รับ media:source ประกาศ media_sources ได้สูงสุดสี่รายการ หน้าต่างสื่อร่วมจะแสดง แหล่งที่มา ข้างคลัง (ปุ่มลูกศรสลับ ตัวควบคุม 44px บนโทรศัพท์): เลือกแหล่ง ค้นหา เปลี่ยนหน้าด้วย แสดงเพิ่ม และ เพิ่ม ไฟล์ พรีวิวโหลดจาก origin ของปลั๊กอินโดยไม่มี referrer แต่ละแหล่งประกาศ modes (copy, reference หรือทั้งสอง) และคำขอเพิ่มระบุหนึ่งโหมด ไม่เคยเดา (media_source_mode_unsupported, 422 สำหรับโหมดที่แหล่งไม่ได้ประกาศ) แหล่งที่มีทั้งสองแสดง เพิ่ม และ ลิงก์โดยไม่คัดลอก แหล่งโหมดเดียวแสดงหนึ่งการกระทำ การเพิ่มสำเนาคัดลอกไฟล์เข้าไซต์: core อ่าน item อีกครั้งผ่านการแลก invocation ดึงจาก origin เดียวของปลั๊กอินโดยไม่มีข้อมูลรับรองและไม่มี redirect และใช้กฎการอัปโหลดปกติ (ชนิด รูปแบบ ขีดจำกัดขนาดของไซต์ และการตรวจไฟล์ซ้ำ) ไฟล์ใหม่คงเครดิตและที่มาจากแหล่ง (media.attribution: ชื่อแหล่ง ผู้สร้าง สัญญาอนุญาต ลิงก์ ปลั๊กอิน id ของแหล่งและ item) แสดงในรายละเอียดของไฟล์ เนื้อหาที่เผยแพร่ไม่โหลดจากปลั๊กอินเลยสำหรับสำเนา การลิงก์ (reference) ไม่ดึงอะไร: แถวมี storage provider เป็น external ที่อยู่ของมันคือ delivery_url ของ item บนหนึ่งใน delivery_origins ที่แหล่งประกาศ รายการในบัญชีวัตถุของมันไม่มี checksum และปลั๊กอิน แหล่ง และ item เดียวกันทำตาม on_duplicate เมทาดาทา แท็ก โฟลเดอร์ และ framing ของไฟล์ที่ลิงก์แก้ไขได้เหมือนไฟล์ใดก็ได้ แต่แทนที่หรือแก้ไขไบต์ไม่ได้ (media_external_bytes_unavailable) การลบเอาออกเฉพาะแถวในคลัง และกฎ in-use ยังคงอยู่ หน้าที่เผยแพร่ การอ่านสาธารณะ managed renderer และเฟรมพรีวิว (ซึ่งนโยบายรูปภาพรวม origin การส่งมอบ) ใช้ URL การส่งมอบ แบ็กเอนด์อิสระที่สร้างและไซต์ที่สร้างไม่คัดลอกมัน manifest สื่อบันทึกเป็น external พร้อม URL ตามที่เป็น สำเนาไซต์และประวัติพกตัวตน URL และเมทาดาทาโดยไม่มีไบต์ และการนำเข้าสร้างลิงก์ใหม่ เนื้อหาที่มีอยู่ยังแสดง URL ที่เก็บไว้เมื่อปลั๊กอินถูกถอนการติดตั้งหรือปิด รายละเอียดบอกว่าแหล่งใช้ไม่ได้ และลิงก์ใหม่จากแหล่งถูกปฏิเสธ สถานะกำลังโหลด ว่าง offline ถูกปฏิเสธ ใช้ไม่ได้ และสิทธิ์ แสดงในหน้าต่าง การเรียกดูต้องมี media:upload และไม่ถูก audit management API, CLI และ MCP มี listMediaSources, browseMediaSource และ importMediaSourceItem (media:write) การส่งออก การนำเข้า และสำเนาไซต์พก attribution ในแต่ละบรรทัดสื่อ การบันทึกเก็บ credit แบบอ่านอย่างเดียวของไฟล์ ({ author, source, license, url } ไม่รวม id ของปลั๊กอิน แหล่ง หรือ item) ในเวอร์ชัน การอ่านสาธารณะ (response schema r8) และไซต์ที่สร้างให้บริการค่านี้ และ renderer แบบ managed และแบบที่สร้างในตัวแสดงบรรทัดเครดิตเล็ก ๆ ใต้รูปภาพ |
backend/src/lib/plugins/media-sources.ts. backend/src/lib/media/sources.ts. backend/src/lib/media/external.ts. backend/src/api/media-sources.ts. frontend/src/lib/components/custom-ui/image-select/MediaSources.svelte. plugins/media-source-reference. backend/test/media-sources.test.ts. backend/test/media-sources-reference.test.ts. backend/test/media-sources-reference-roundtrip.test.ts. backend/test/media-sources-bundle.test.ts. backend/test/media-credit.test.ts. frontend/src/lib/components/custom-ui/image-select/MediaSources.svelte.test.ts. frontend/cypress/e2e/journey-media-sources.cy.ts |
| ความคิดเห็น | โมเดลสาธารณะใดก็ได้รับความคิดเห็นได้ (content_model.settings.comments) โพสต์ของ Blog เป็นโมเดลหนึ่งในลักษณะนี้ เธรดเป็นของภาษาหนึ่งของรายการและมีการตอบกลับระดับเดียว ความคิดเห็นของผู้เยี่ยมชมมาผ่าน intake Worker เป็น JSON หรือการส่งฟอร์มธรรมดา มี key ต้องให้ความยินยอม อีเมลไม่บังคับและเก็บแบบส่วนตัว และรอการกลั่นกรอง ขณะที่โมเดลไม่รับความคิดเห็น หน้ารายการของโมเดลแสดงฟอร์มที่ปิด ไม่รับอะไร ความคิดเห็นที่มีอยู่ถูกซ่อนจากการอ่านสาธารณะแต่ยังแสดงสำหรับการกลั่นกรอง การกลั่นกรอง (/api/comments) แสดงรายการ อนุมัติ ปฏิเสธ ทำเครื่องหมายสแปม และลบ ต้องมีสิทธิ์เผยแพร่ (การลบต้องมีสิทธิ์ลบในโมเดลของความคิดเห็น) รายงานความคิดเห็นที่ผู้กลั่นกรองคนอื่นย้ายไปแล้วเป็นความขัดแย้ง และไม่เข้าถึงไซต์อื่นเลย reaction: ชนิดเดียว helpful หนึ่งครั้งต่อผู้กระทำและความคิดเห็น เฉพาะความคิดเห็นที่อนุมัติแล้ว ผู้เยี่ยมชมถูกระบุด้วย digest ที่มี key ซึ่งไม่ซ้ำกับความคิดเห็นอื่น บุคคลที่ลงชื่อเข้าใช้ถูกระบุด้วยบัญชีและต้องมีสิทธิ์อ่านโมเดล ลำดับสาธารณะคือ oldest (ค่าเริ่มต้น) newest หรือ best (reaction helpful แล้วอายุ แล้ว id) แต่ละแบบแบ่งหน้าด้วย cursor ของตัวเอง management API, CLI และ MCP แสดงรายการ อ่าน กลั่นกรอง เผยแพร่ความคิดเห็นที่นำเข้า ลบ และเปลี่ยนว่าโมเดลใดรับความคิดเห็น สำเนาไซต์พกความคิดเห็นพร้อมสถานะและอีเมล และความคิดเห็นที่เผยแพร่จะมาถึงเป็นรอดำเนินการ การ undo ลบความคิดเห็นเหล่านั้น managed renderer และไซต์ที่สร้างวาดคอมโพเนนต์ความคิดเห็นบนทุกหน้ารายการของโมเดลที่รับความคิดเห็น โดยอ่านตอนรับคำขอ |
backend/src/lib/comments/service.ts. backend/src/lib/comments/reactions.ts. backend/src/api/comments.ts. backend/test/comments-models.test.ts. backend/test/comments-route.test.ts. backend/test/comments-contract.test.ts. backend/test/comments-site-copy.test.ts. backend/test/blog-comments.test.ts. backend/test/graduate-site-comments.test.ts |
| รีลีสแบบประสานกัน (ปลั๊กอิน Scheduling) | ส่งคำสั่งสำหรับรายการและภาษาในไซต์เดียวได้สูงสุด 25 คำสั่งที่ขอบเขตไม่ทับซ้อนกัน CMS ใช้ชุดคำสั่งฐานข้อมูลเดียว ภายในขีดจำกัด SQL ที่รองรับ และตรวจสถานะที่จะเกิดขึ้นหลังเผยแพร่ทั้งหมด หากถูกปฏิเสธหรือย้อนกลับ จะไม่มีตัวชี้เวอร์ชันเผยแพร่ใดเปลี่ยน ต่างภาษาของรายการเดียวกันอยู่ในรีลีสเดียวได้ Scheduling ส่งคำสั่งเดียวพร้อมเวอร์ชันและ revision ที่ตรึงไว้และรหัสสำหรับลองซ้ำ หากไม่ทราบผลจะส่งคำสั่งเดิม การส่งเว็บฮุก การล้างแคช และการเปลี่ยนเส้นทางอัตโนมัติเป็นผลลัพธ์แยกต่างหาก ยังรอการปรับใช้และการตรวจรับขั้นสุดท้าย | backend/src/lib/lifecycle/service.ts; backend/test/coordinated-release-events.test.ts; plugins/scheduling/src/release-runner.ts |
| นโยบายปลั๊กอินที่เปลี่ยนเนื้อหา | นโยบายการบันทึกหรือการกู้คืนอาจตอบ transform โดยระบุเฉพาะฟิลด์ เนื้อหาที่เสนอให้บันทึกที่ถูกแปลงผ่านการตรวจแบบเดียวกับการบันทึกของเอดิเตอร์ (กฎฟิลด์ rich text แบบ canonical ลิงก์ สื่อ การตั้งค่าการค้นหา) และถูกเก็บพร้อมบันทึกว่านโยบายใดเปลี่ยนอะไร คำตอบที่เท่ากับเนื้อหาที่เสนอให้บันทึกเดิมคือการอนุญาตธรรมดา สองนโยบายที่เปลี่ยนฟิลด์เดียวกันต่างกันถูกปฏิเสธ (plugin_policy_transform_conflict) ฟิลด์ที่โมเดลไม่มี ส่วนลิงก์หรือสื่อในฟิลด์ที่ผิด รายการอื่น หรือ transform สำหรับการทำงานที่ไม่บันทึกเนื้อหา ไม่ถูกต้อง (plugin_policy_transform_invalid) การปฏิเสธจากนโยบายอื่นยังคงปฏิเสธ เมื่อใช้ key เดิมซ้ำ ระบบจะคืนผลลัพธ์ที่แปลงไว้โดยไม่ถามอีก transform ของการกู้คืนเปลี่ยนได้เฉพาะค่าและการตั้งค่าการค้นหา นโยบายการลบถูกถามก่อนถังขยะและการลบถาวร นโยบายการกู้คืนเมื่อออกจากถังขยะ นโยบายการเปลี่ยนสถานะในทุกการย้าย คำสั่งเผยแพร่ของปลั๊กอิน และการนำเข้าที่เผยแพร่ นโยบายการยกเลิกการเผยแพร่เมื่อเนื้อหาออฟไลน์ การบันทึกผ่าน management API ตอบพร้อมการแปลงและแสดงชนิดนโยบายใหม่ |
backend/test/plugin-policy-transforms.test.ts. backend/test/plugin-policy-fixture.test.ts |
| พรีวิวที่ลิงก์ฟิลด์ | เอดิเตอร์เปิดหน้าไซต์ข้างช่องข้อมูล managed renderer ปัจจุบันและ renderer บล็อกที่สร้างและดูแลอยู่เปิดช่องข้อความหรือข้อความจัดรูปแบบทับค่าที่เลือก การเปลี่ยนแปลงยังเป็นฉบับร่างจนกว่าจะบันทึก ช่องชนิดอื่นและ renderer รุ่นเก่าเปิดช่องที่ตรงกันในฟอร์ม bridge ตรวจ origin, source, nonce, การผูกช่องและสิทธิ์เขียน หน้าที่เผยแพร่ไม่มี bridge ของเอดิเตอร์ ดู การแก้ไขจากพรีวิว. | backend/src/lib/page-contract/field-links.ts. backend/src/lib/field-link-runtime.ts. backend/test/preview-field-links.test.ts. frontend/src/routes/content/[id]/EntryPreviewPane.svelte.test.ts |
| ความถูกต้องของ management API | คำสั่งที่มี key จอง key ก่อน: คำสั่งซ้ำที่ส่งมาขณะคำสั่งแรกทำงานจะได้ 409 idempotency_in_progress พร้อม Retry-After เมื่อส่งซ้ำหลังคำสั่งแรกเสร็จ ระบบจะคืนคำตอบแรกทุกประการ (รวมถึงการแก้ metadata ของสื่อ) body อื่นภายใต้ key เดียวกันคือ key ที่ใช้ซ้ำ คำสั่งที่ถูกปฏิเสธปล่อย key การจองที่คำขอหยุดไปแล้วไม่มีวันถูกยึดต่อเพียงเพราะเวลาผ่านไป แต่ละคำสั่งตัดสินด้วยหลักฐานของตัวเอง (ชุดเดียวกับคำตอบ บันทึกของตัวเอง หรือตำแหน่งของงานที่บันทึกไว้) มิฉะนั้นการจองจะค้างอยู่ การเปลี่ยนการตั้งค่าและข้อเสนอถูกเขียนและ audit ครั้งเดียวเมื่อมีคำสั่งซ้ำ ส่วนของการนำเข้าถูกผูกกับ SHA-256 ของไบต์แรกก่อนเก็บสิ่งใด ไบต์อื่นสำหรับส่วนนั้นถูกปฏิเสธ (import_part_conflict) การส่งออกเนื้อหาเก็บเป็นหน้าที่เปลี่ยนไม่ได้ รวมเป็นไฟล์เดียวพร้อม digest และขนาด แล้วจึงลบหน้า การเดินหน้าสองครั้งที่แข่งกันไม่ทำให้หน้าหายหรือซ้ำ การอ่านเป็นช่วงไบต์และมีขอบเขต และไฟล์ที่เก็บซึ่งไม่ใช่ไฟล์ที่บันทึกไว้ถูกปฏิเสธ |
backend/src/lib/management/keyed.ts. backend/src/lib/management/idempotency.ts. backend/test/management-integrity.test.ts. backend/test/management-idempotency.test.ts. backend/test/management-data-transfer-export.test.ts. backend/test/management-data-transfer.test.ts |
| การนำเข้า WordPress | หน้า WordPress เก็บลำดับหัวข้อ โค้ด ตาราง และเนื้อหาที่มีโครงสร้างยาวขึ้นได้ ข้อมูลเพิ่มเติมและ SEO ที่แหล่งข้อมูลส่งมาและระบบรองรับใช้การจับคู่ที่ระบุไว้ ข้อมูลที่ขาดหรือไม่รองรับจะแสดงในรายงาน WXR และการเชื่อมต่อแหล่งข้อมูลใช้การตรวจนำเข้าและใบรับรองเดียวกัน ดู นำเข้า WordPress | backend/src/lib/import/wordpress-models.ts. backend/src/lib/import/wordpress-acf.ts. backend/src/lib/import/wordpress-seo.ts. backend/test/import-wordpress-fidelity.test.ts. backend/test/import-wordpress-real-plugins.test.ts. backend/test/import-wordpress.test.ts. backend/test/import-wordpress-source.test.ts |
| โฟลเดอร์สื่อของ Strapi | เอนทิตี plugin::upload.folder ของไฟล์เก็บถาวร Strapi 4 หรือ 5 ลิงก์ parent ของมัน และลิงก์ folder ของแต่ละไฟล์ เป็นข้อมูลอ้างอิงเพียงชุดเดียวที่ใช้ตัดสินโครงสร้างโฟลเดอร์ การตรวจดูแสดงต้นไม้พร้อมความลึกและจำนวนไฟล์ ไฟล์ที่ folderPath ระบุโฟลเดอร์แต่ไม่มีลิงก์ จะนำเข้าโดยไม่จัดเข้าโฟลเดอร์ (ไม่อยู่ในโฟลเดอร์) และถูกรายงาน (media_folder_link_missing) ลิงก์ไปยังโฟลเดอร์ที่ไฟล์เก็บถาวรไม่มีบล็อกการรันทดลอง (media_folder_missing) การรันทดลองบล็อกโฟลเดอร์ที่ชื่อใช้ไม่ได้ (media_folder_name_invalid, 1–80 ตัวอักษร) ไม่มีโฟลเดอร์แม่ (media_folder_parent_missing) วงวน (media_folder_cycle) ลึกเกิน 5 ระดับ (media_folder_too_deep) โฟลเดอร์ระดับเดียวกันที่ชื่อต่างกันเพียงตัวพิมพ์เล็กใหญ่ (media_folder_name_collision) หรือขีดจำกัดโฟลเดอร์ที่ 500 (media_folders_limit) และลูกของโฟลเดอร์ที่ถูกบล็อก (media_folder_ancestor_blocked) ไม่มีการเปลี่ยนชื่อหรือย้ายแม่ สร้างเฉพาะโฟลเดอร์ที่ไฟล์ที่เลือกต้องการ พร้อมโฟลเดอร์แม่ทุกระดับ ผ่านบริการโฟลเดอร์ของคลัง พร้อมบันทึกผลการนำเข้าหนึ่งรายการต่อโฟลเดอร์ โฟลเดอร์ที่พาธเดียวกันมีอยู่แล้วถูกใช้ซ้ำและไม่มีบันทึกผลการนำเข้า และการรันซ้ำไม่สร้างเพิ่ม ไฟล์ใหม่แต่ละไฟล์ถูกจัดเข้าโฟลเดอร์ของมันเมื่อสร้าง การ undo ทำตามกฎสำเนาไซต์ข้างต้น บทบาทและสิทธิ์ไม่เปลี่ยน พิสูจน์บนไฟล์เก็บถาวรโฟลเดอร์ Strapi 4.25.9 และ 5.51.1 ที่บันทึกไว้ |
backend/src/lib/import/strapi-folders.ts. backend/test/import-strapi-media-folders.test.ts. backend/test/fixtures/strapi/v5-folders |
| คอมโพเนนต์และ single type ของ Strapi | คอมโพเนนต์ Strapi กลายเป็นนิยามคอมโพเนนต์ที่ไซต์เป็นเจ้าของ (slug category-name) นิยามของไซต์ที่เหมือนกันถูกใช้ซ้ำ และสิ่งอื่นที่ครอง slug อยู่ถูกปฏิเสธตามชื่อ dynamic zone กลายเป็นรายการคอมโพเนนต์แบบผสมตามลำดับต้นทาง โดยตัด id แถวของ Strapi และจับคู่สื่อและความสัมพันธ์ภายในใหม่ single type กลายเป็นโมเดลรายการเดียว แต่ละภาษาเป็นคอมโพเนนต์ที่แปลของตัวเอง นิยามถูกวางแผนและตรวจก่อนเขียนนิยามใด การนำเข้าซ้ำเป็นแบบสร้างหรือข้าม สำเนาไซต์พกนิยาม จับคู่ความสัมพันธ์ภายในใหม่ และปฏิเสธความสัมพันธ์ที่ระบุรายการที่สำเนาไม่ได้พกมา การ undo ลบนิยามเฉพาะเมื่อไม่มีสิ่งใดใช้แล้ว พิสูจน์แล้วกับไฟล์เก็บถาวร Strapi 4.25.9 และ 5.51.1 ที่บันทึกไว้ |
backend/src/lib/import/strapi-components.ts. backend/test/import-strapi-components.test.ts |
| การโอนไซต์พร้อมประวัติ | รูปแบบ .deewan (dee-wan-transfer เวอร์ชัน 1) ถ่ายโอนเนื้อหาเป็นส่วน และเลือกนำประวัติ เหตุการณ์เวิร์กโฟลว์ ถังขยะ ผู้รับผิดชอบ ป้ายชื่อผู้เขียน โฟลเดอร์ และสื่อที่ใช้อยู่ไปด้วยได้ รอบส่งออกประมวลผลไม่เกิน 100 ระเบียน รอบเตรียมไม่เกิน 80 ระเบียน และรอบประกอบไฟล์ไม่เกิน 32 MiB ส่วนไฟล์ขนาด 5 MiB ระเบียนไม่เกิน 8 MiB และไฟล์ถ่ายโอนรวมไม่เกิน 50,000 MiB (52,428,800,000 ไบต์) ยังตรวจผลรวม การจับคู่ พื้นที่ส่วนตัว และใบรับรอง ขีดจำกัดเดิม 64 MiB และ 20,000 แถวใช้กับรูปแบบเก่าที่อ่านเข้าหน่วยความจำ ดู นำเข้าและย้ายข้อมูล |
backend/src/lib/export/site-history.ts backend/src/lib/import/bundle-history-handlers.ts backend/src/lib/lifecycle/imported-history.ts backend/test/site-history-transfer.test.ts backend/test/principal-mapping.test.ts |
| ตัวกรองฟิลด์สาธารณะ | รองรับการเท่ากันบนฟิลด์ text, select, boolean, ตัวเลข และวันที่ รองรับ gt และ lt (ไม่รวมขอบ) และ gte และ lte (รวมขอบ) บนฟิลด์ตัวเลขและวันที่ รับ sort หนึ่งตัวและ fields แบบเลือกบางส่วน รับฟิลด์ที่กรองได้ไม่เกิน 4 ฟิลด์ ค่ายาวไม่เกิน 255 ตัวอักษร การใส่ filter[field]= ซ้ำให้ทางเลือกได้สูงสุด 10 ค่าต่อฟิลด์: OR ภายในฟิลด์เดียว AND ระหว่างฟิลด์ expand= ระบุฟิลด์ relation ได้สูงสุด 3 ฟิลด์ ลึกหนึ่งระดับ: แต่ละรายการมีเป้าหมายที่เผยแพร่แล้วและอ่านได้สูงสุด 25 รายการต่อฟิลด์ และ GET /v1/_related/:model แบ่งหน้าส่วนที่เหลือด้วย cursor ที่ผูกกับต้นทาง ฟิลด์ ภาษา และ token API ปฏิเสธอินพุตที่เกินและไม่เคยตัดให้แคบลง cursor เก็บ query ของตัวเองและถูกปฏิเสธเมื่อใช้กับ query อื่น ไม่อ้างและไม่เคยวัดเพดานจำนวนแถวบน D1 ฟิลด์จุดรองรับรัศมีและระยะใกล้สุดด้วย Haversine รวมถึงกรอบพื้นที่ที่นับขอบและข้ามเส้นแบ่งวันสากลได้ โดยใช้กฎสิทธิ์ จำนวน และ cursor เดียวกัน |
backend/src/public/index.ts backend/src/lib/public-read/relation-expansion.ts backend/test/public-field-filters.test.ts backend/test/public-filter-alternatives.test.ts backend/test/public-relation-expand.test.ts |
รูปแบบที่รับไว้ก่อนการสร้างจะปฏิเสธ
หัวข้อที่มีชื่อว่า “รูปแบบที่รับไว้ก่อนการสร้างจะปฏิเสธ”การสร้างอ่านทุกโมเดลและปฏิเสธกรณีเหล่านี้โดยระบุชื่อ ตอนนี้ การตั้งค่า → ซอร์สโค้ดและการเผยแพร่ → ขั้นสูง — build webhook และการ deploy → แบ็กเอนด์ Standalone แสดงรายการเหล่านี้ก่อนบิลด์ (GET /api/sites/:siteId/generation-readiness) การปฏิเสธระดับเนื้อหาจะเห็นได้ก่อนบิลด์ด้วย: GET /api/sites/:siteId/generation-readiness/content จะเดินไปตามคอนเทนต์ที่เผยแพร่ทีละหน้าแบบจำกัด และระบุสิ่งที่บิลด์จะปฏิเสธ ตัวบิลด์ยังเป็นขั้นตอนที่ตัดสินข้อขัดแย้งที่ต้องตรวจทั้งไซต์
| การปฏิเสธ | เหตุที่ CMS รับไว้ |
|---|---|
relation_type_unsupported |
ชนิดความสัมพันธ์นอกเหนือสี่แบบ เข้าถึงได้ผ่าน API หรือการนำเข้า |
relation_bounds_unsatisfiable |
ขีดจำกัดการเลือกที่ไม่มีรายการใดผ่าน เช่น อย่างน้อย 3 และมากที่สุด 1 |
relation_required_cycle |
ความสัมพันธ์หนึ่งเป้าหมายแบบบังคับที่วนกลับมาที่โมเดลตัวเอง รายการแรกสร้างไม่ได้เลย |
ambiguous_relation, ambiguous_component |
บันทึกความสัมพันธ์หรือคอมโพเนนต์ที่ไม่มีเป้าหมายได้ |
unsupported_field_type |
การบันทึกรับชื่อชนิดใดก็ได้ เข้าถึงได้ผ่าน API หรือการนำเข้า |
invalid_field_config, empty_model |
การบันทึกไม่ตรวจ JSON การตั้งค่าฟิลด์ และไม่บังคับให้มีฟิลด์ |
column_name_collision, model_name_collision |
เอดิเตอร์สงวนไว้แค่ id, created_at และ updated_at slug เช่น blog-post กับ blog_post ชนกัน |
relation_target_absent |
เป้าหมายความสัมพันธ์ระบุโมเดลนอกเว็บไซต์ได้ |
relation_arity_unsupported, relation_target_model_mismatch, duplicate_row_identity |
ระดับเนื้อหา: แถวที่เขียนก่อนมีการตรวจความสัมพันธ์ใน CMS หรือเขียนโดยการนำเข้า |
required_value_missing, unsupported_value_type, unpublished_reference |
ระดับเนื้อหา: การนำเข้าและเนื้อหาที่บันทึกก่อนเซิร์ฟเวอร์บังคับใช้กฎของฟิลด์ |
หลักฐาน: backend/src/lib/graduate/preflight.ts backend/test/graduate-preflight.test.ts backend/test/generation-readiness-route.test.ts backend/test/graduate-plan.test.ts.
Rich text
หัวข้อที่มีชื่อว่า “Rich text”ฟิลด์ rich text เก็บ rich document หนึ่งฉบับเป็น HTML แบบ canonical สูงสุด 256 KiB: ย่อหน้า หัวข้อ รายการ คำพูดอ้างอิง บล็อกโค้ด เส้นคั่น ตัวหนา ตัวเอียง ขีดเส้นใต้ ขีดฆ่า inline code ตัวห้อยและตัวยก ลิงก์ รูปภาพ ตาราง (ไม่เกิน 12 คอลัมน์และ 200 แถว มีแถวหัวตาราง หัวแถว และคำบรรยายได้ตามต้องการ) แกลเลอรีรูปภาพ (รูปจากคลัง 2–24 รูป) บล็อกเสียง วิดีโอ และไฟล์ที่อ้างถึงสื่อในคลัง และการฝังที่เก็บเป็น id ผู้ให้บริการ ที่อยู่ https แบบ canonical และชื่อ: YouTube และ Vimeo มีในตัว และ origin https แบบตรงตัวอีกไม่เกิน 20 แห่งที่ผู้ดูแลอนุญาตใน การตั้งค่า → การเชื่อมต่อ (origin ของการฝัง) ทุกการเขียน (การบันทึกในเอดิเตอร์ การกู้คืน management API ปลั๊กอิน การนำเข้าสเปรดชีต การคัดลอกไซต์) อ่านค่าอย่างเข้มงวดและปฏิเสธสิ่งอื่นโดยระบุชื่อ ได้แก่ ฟิลด์ ภาษา element หรือ attribute และไม่เคยสะท้อนเนื้อหากลับ บล็อกแกลเลอรี เสียง วิดีโอ หรือไฟล์ต้องอ้างถึงรายการสื่อของไซต์นี้ที่เป็นประเภทนั้น การนำเข้าจาก Strapi แปลง Markdown (รวมตาราง GFM) เป็น HTML แบบเดียวกัน คง HTML ดิบไว้เท่าที่ document รองรับ และรายงานสิ่งที่ตัดทิ้งเป็น finding rich_markup_dropped
ปลั๊กอินที่ใช้งานอยู่อาจประกาศ rich_blocks: ชุดตัวควบคุมแบบปิด (text, textarea, rich, number, boolean, select, url, media, relation และกลุ่มซ้ำ ลึกไม่เกิน 3 ระดับ กลุ่มละไม่เกิน 50 รายการ) พร้อมกฎ render tree แบบประกาศ และขั้นตอน migration ไม่มี HTML, CSS หรือสคริปต์ บล็อกถูกเก็บเป็น <figure data-block="plugin" data-type data-version data-values> การบันทึกปฏิเสธบล็อกที่เพิ่มซึ่งไม่มีปลั๊กอินที่ใช้งานอยู่ประกาศ (rich_block_unregistered) เวอร์ชันที่ใหม่กว่า (rich_block_version_unknown) และค่าที่คำประกาศปฏิเสธ (rich_block_values_invalid) เวอร์ชันที่เก่ากว่าถูกรับเมื่อค่าที่ migrate แล้วผ่าน และบล็อกที่ไม่เปลี่ยนถูกเก็บไว้หลังลบปลั๊กอิน สื่อของบล็อกนับในการตรึงเวอร์ชัน และถ้อยคำเข้าสู่การค้นหา GET /v1/_rich-blocks ให้บริการนิยามที่ใช้งานอยู่ และหยุดเมื่อปลั๊กอินถูกปิด render adapter ของโฮสต์ escape ทุกค่าที่ผูก ปฏิเสธที่อยู่ที่ไม่ปลอดภัย migrate บล็อกเก่า ไม่วาดอะไรแบบสาธารณะสำหรับบล็อกที่ไม่มี adapter วาด และวาด placeholder ที่มีชื่อในพรีวิว สำเนาไซต์เก็บเวอร์ชันบล็อกและจับคู่ ID สื่อกับ relation ใหม่ผ่านรายการ rich-relations.json ที่นับจำนวนและตรวจ checksum การคัดลอกและย้ายประวัติต้องมีคำประกาศต้นทางที่ตรงกัน หากพบ export_rich_relation_schema_unavailable ให้คืนคำประกาศแล้ว export อีกครั้ง ไม่ย้ายการติดตั้งหรือสิทธิ์ plugin ไปปลายทาง เมื่อประกาศ inline: true จะเก็บองค์ประกอบแบบมีโครงสร้างเป็น <span data-block="plugin"> ภายในย่อหน้า โดยใช้ฟิลด์ เวอร์ชัน การอ้างอิง และกฎการแสดงผลเดียวกัน
| จุดที่แสดง rich text | สิ่งที่ป้องกัน |
|---|---|
| เอดิเตอร์ rich text ในหน้าผู้ดูแล | เอดิเตอร์ส่งออก document แบบ canonical สร้างได้ทั้งย่อหน้า หัวข้อระดับ 1–6 ตัวหนา ตัวเอียง ขีดเส้นใต้ ขีดฆ่า inline code ตัวห้อยและตัวยก บล็อกโค้ด คำพูดอ้างอิง รายการ เส้นคั่น การขึ้นบรรทัด ลิงก์ รูปภาพในบรรทัด ตาราง (ไม่เกิน 12 คอลัมน์และ 200 แถวในตัวตาราง แถวหัวตาราง หัวแถว คำบรรยาย) แกลเลอรีรูปจากคลัง 2–24 รูป บล็อกไฟล์ เสียง และวิดีโอจากคลังสื่อ และการฝังจากลิงก์ YouTube, Vimeo หรือ https ที่อนุญาตที่วางลงไป แสดงเป็นตัวแทนการฝัง โดยปุ่มดูตัวอย่างจะเปิดแท็บใหม่ เก็บการจัดแนวย่อหน้าและหัวข้อแบบซ้าย กลาง ขวา และเต็มบรรทัดในข้อมูล canonical ส่วน vendor snippet ใช้ frame แยก ปฏิเสธ frame, style และ class อิสระใน document แม่ สิ่งที่เอดิเตอร์มีแต่ document รองรับไม่ได้จะถูกตัดออกก่อนบันทึก และเซิร์ฟเวอร์ปฏิเสธสิ่งอื่นทั้งหมด |
| เว็บไซต์ Astro ที่สร้างและ managed renderer | ส่วนต่าง ๆ ของหน้าไม่มี markup: ข้อกำหนดข้อมูลหน้า ปฏิเสธ markup ย่อหน้าหนึ่งมี run แบบมีโครงสร้างที่เป็นตัวหนา ตัวเอียง ลิงก์ และรายการได้ (การจัดรูปแบบภายในข้อความ) และ Astro escape ข้อความของ run เหล่านั้น เนื้อหาของบทความ Blog และ summary ของ รายการล่าสุด ถูก render ด้วย renderRichDocument ของ ข้อกำหนดข้อมูลหน้า (backend/src/lib/page-contract/rich-document.ts) ซึ่งเป็นฟังก์ชันเดียวกันใน renderer ทั้งสอง ตารางเลื่อนภายในกล่องของตัวเอง แกลเลอรีจัดเป็นกริด เสียงและวิดีโอเล่นพร้อมลิงก์ดาวน์โหลด และการฝังเป็น frame เดียวที่ CMS เป็นเจ้าของ (sandbox, รายการ allow, นโยบาย referrer, โหลดแบบ lazy, 16:9) จาก youtube-nocookie.com, player.vimeo.com หรือ origin ที่ไซต์อนุญาตอยู่ในขณะนั้น (GET /v1/_embeds) การฝังจาก origin ที่ไม่ได้รับอนุญาตจะแสดงเป็นลิงก์ธรรมดา frame-src ของหน้าในไซต์ managed ระบุเฉพาะตัวเล่นทั้งสองและ origin ที่อนุญาต |
| ตัวอย่างโครงสร้าง ของเอดิเตอร์หน้า | summary ของ รายการล่าสุด แสดงเป็นข้อความที่ได้จาก document เดียวกัน |
| API สาธารณะของ CMS, API ของแบ็กเอนด์ที่สร้าง และไคลเอนต์ TypeScript | HTML แบบ canonical ที่ตรวจแล้ว บล็อกสื่อและการฝังเป็นข้อมูล (<figure data-block=…>) ไม่ใช่ตัวเล่น: ให้ render ค่าด้วย renderRichDocument หรือ renderer ของคุณเองสำหรับ document เดียวกัน ส่ง origin จาก GET /v1/_embeds เพื่อแสดง frame ของการฝังที่ตั้งค่าไว้ |
หลักฐาน: backend/test/rich-document-contract.test.ts. backend/test/rich-plugin-blocks.test.ts. backend/test/rich-plugin-blocks-bundle.test.ts. backend/test/rich-document-render.test.ts. backend/test/rich-renderer-parity.test.ts. backend/test/rich-field-contract.test.ts. backend/test/rich-blocks-bundle.test.ts. backend/test/version-media-pins.test.ts. backend/test/rich-text-boundaries.test.ts. backend/test/import-strapi-markdown.test.ts. frontend/src/lib/components/custom-ui/rich-editor/rich-editor-adversarial.svelte.test.ts. backend/test/graduate-site-build.test.ts (หน้า escaping)
ไม่มีใน 1.0
หัวข้อที่มีชื่อว่า “ไม่มีใน 1.0”public API ยังไม่มีตัวกรองฟิลด์ที่ลิงก์แบบอิสระ $or การค้นหาข้อความ และผู้รับมอบหมาย workflow หลายคนต่อทั้งรายการ รายการใน CMS กรองฟิลด์แสดงผลชนิด scalar ของ relation ภายในไซต์ที่ตั้งค่าไว้ได้ ดูส่วนเพิ่มด้านล่าง ขอบเขตผลิตภัณฑ์ 1.0 เป็นแหล่งอ้างอิงหลัก
ซอร์สที่เพิ่มในเดือนตุลาคม 2026
หัวข้อที่มีชื่อว่า “ซอร์สที่เพิ่มในเดือนตุลาคม 2026”การเปลี่ยนแปลงเหล่านี้อยู่ในซอร์สปัจจุบันและผ่านการตรวจเฉพาะส่วนในเครื่องแล้ว ยังรอ browser integration และการตรวจภาพจริงขั้นสุดท้าย ไม่ใช่การยอมรับ production มีซอร์สโฟลเดอร์รายการพร้อมการตรวจ service/transfer เฉพาะส่วนแล้ว แต่ยังรอ integration acceptance ขั้นสุดท้าย ส่วนโฟลเดอร์ model ด้านบนเป็นคนละความสามารถ
| ความสามารถ | พฤติกรรมในซอร์สปัจจุบัน | หลักฐาน |
|---|---|---|
| Operation ของ plugin สำหรับเนื้อหาและสื่อ | การอ่านรายการ/เวอร์ชัน การสร้าง/แก้ไข/ถังขยะ relation แบบมีชนิด และ metadata/bytes ของสื่อ ใช้ lifecycle เดิมและสิทธิ์ปัจจุบันของผู้ใช้ | backend/test/plugin-operations.test.ts; backend/test/management-plugin-operations.test.ts |
| กลุ่มตัวกรองและตัวเลือกตามบริบท | สี่เงื่อนไขปลายทาง AND/OR ลึกสามระดับ ใช้ความหมายร่วมกับรายการ จำนวน view และ bulk ตัวเลือก relation/select ขึ้นกับฟิลด์ข้างเคียง ผู้ใช้ และรายการได้ ตรวจ dependency ซ้ำเมื่อบันทึก | backend/src/lib/content-fields/contract.ts; backend/test/content-field-query.test.ts; backend/test/contextual-choices.test.ts |
| Rich text | จัดแนวย่อหน้า/หัวข้อ control relation และกลุ่มซ้ำของ plugin ส่วน vendor snippet HTML/CSS/JavaScript แบบมีชนิดทำงานใน frame แยกใน admin และ renderer ทั้งสอง | backend/test/rich-editorial-completion.test.ts; backend/test/rich-plugin-blocks.test.ts; backend/test/rich-snippets-route.test.ts |
| การดูแลบัญชี | ยืนยันกล่องจดหมายใหม่ก่อนเปลี่ยน email ของบัญชีเดิม เก็บตัวตน สมาชิก credential และประวัติ พร้อมจบ session คำขอ reset ใช้ claim อีเมลอายุสั้นครั้งเดียว และตอบเหมือนกันทั้งที่อยู่ที่รู้จัก/ไม่รู้จัก | backend/test/account-maintenance.test.ts |
| Update และ UI ของ plugin | เปรียบเทียบ manifest/version/สิทธิ์ก่อนยืนยัน upgrade ยังไม่มอบสิทธิ์ใหม่ เฟรมที่ไม่แนบข้อมูลรับรอง ที่ตรวจ origin แล้วใช้ operation ที่ประกาศกับช่องข้อความที่ผูกไว้ ไม่มี credential ของ admin | backend/test/plugin-schema.test.ts; backend/test/plugin-ui-extensions.test.ts |
| ขอบเขตรายการ | กฎ role ต่อ model สำหรับ read/create/update/delete แบบมีขอบเขต รวมบริบทผู้ใช้ รายการ จำนวน การอ่านรายการที่เกี่ยวข้อง เวอร์ชัน export การเลือก bulk ที่ตรงเงื่อนไข และ atomic write ใช้กฎปัจจุบันร่วมกับสิทธิ์ model เจ้าของ ฟิลด์ และภาษา | backend/src/lib/document-rules.ts; backend/test/document-scopes.test.ts |
| ตารางข้อมูลที่มีโครงสร้าง | CSV/XLSX เลือกสร้าง อัปเดต หรือสร้าง/อัปเดตได้ ผ่านกลไกตรวจทานเดียวกับ JSON collection ค่าเริ่มต้นคืออัปเดต จับคู่ด้วย ID รายการหรือฟิลด์ไม่ซ้ำที่รองรับ ตรวจรายการเพิ่ม การเปลี่ยนแปลง และแถวที่ถูกปฏิเสธก่อนนำไปใช้ ความสัมพันธ์ สื่อ และคอมโพเนนต์ซ้อนผ่านการตรวจสิทธิ์ ค่า นิยาม และเวอร์ชันตามปกติ เซลล์โครงสร้างที่ว่างเก็บค่าเดิม JSON null ล้างฟิลด์ที่ไม่บังคับ | backend/test/spreadsheet-scope.test.ts; backend/test/spreadsheet-collection.test.ts; backend/test/spreadsheet-xlsx-import.test.ts |
| WordPress แบบเชื่อมต่อและค่าตั้ง | ดึง HTTPS REST origin เดียวแบบมีขอบเขตเพื่อสร้าง WXR ปกติ การแทนค่าที่ตรวจชัดเจนครอบคลุมชื่อ tagline logo icon คำอธิบาย SEO และค่าการทำดัชนีที่ส่งมา พร้อม revision ปลายทาง receipt และสิทธิ์ undo | backend/test/wordpress-connect.test.ts; backend/src/lib/import/wordpress-site-configuration.ts; backend/src/lib/import/site-configuration-carry.ts |
| ตัวช่วย AI | Vision model ได้ bytes ภาพที่ผู้ใช้มีสิทธิ์ ผู้เขียนตรวจ/แก้ alt กับ caption ก่อนบันทึก หลังบันทึกข้อความต้นทาง อัปเดตเฉพาะภาษาที่เลือกและยินยอมแทนค่า รวมถึงคำแปลที่เขียนเอง | backend/test/ai-media-descriptions.test.ts; frontend/src/lib/ai/translate-saved.test.ts |
| โฟลเดอร์รายการ | โฟลเดอร์ไซต์ซ้อนกัน มีหนึ่งตำแหน่งต่อกลุ่มภาษา รายการ/จำนวนตามสิทธิ์ และประวัติย้ายแยก การเปลี่ยนตำแหน่งไม่สร้าง version เนื้อหา Copy/history จับคู่ตำแหน่งใหม่พร้อม receipt และ undo | backend/src/lib/entry-folders.ts; backend/src/lib/entry-folder-transfer.ts; backend/test/entry-folders.test.ts |
ส่วนเพิ่มเติมวันที่ 17 ตุลาคม: การเชื่อมต่อระบบและงานบรรณาธิการ
หัวข้อที่มีชื่อว่า “ส่วนเพิ่มเติมวันที่ 17 ตุลาคม: การเชื่อมต่อระบบและงานบรรณาธิการ”ความสามารถต่อไปนี้มีในซอร์สแล้ว แต่ยังตรวจการทำงานร่วมกันของโค้ดชุดนี้ไม่ครบ การอ้างถึงไฟล์ทดสอบแสดงขอบเขตที่ทดสอบ ไม่ได้หมายความว่าโค้ดชุดนี้ผ่านแล้ว
| ความสามารถ | ขอบเขต | ซอร์ส |
|---|---|---|
| เหตุการณ์เว็บฮุก | การเปลี่ยนเนื้อหา ขั้นตอนงาน รีลีส ไฟล์ และโมเดลที่สำเร็จจะเข้าคิวส่งเดิม การปฏิเสธและการเล่นผลคำสั่งเดิมซ้ำไม่สร้างเหตุการณ์ใหม่ | backend/src/lib/outbound-events.ts; backend/src/lib/lifecycle/events.ts |
| ความสัมพันธ์หลายโมเดลในคอมโพเนนต์ | คอมโพเนนต์แบบซ้อน แบบซ้ำ และแบบผสมเก็บโมเดลและรหัสรายการที่เลือกไว้ตลอดการบันทึก กู้คืน ย้ายข้อมูล และแสดงผล | backend/src/lib/component-relations.ts |
| หน้าปลั๊กอิน | เส้นทาง เมนู และส่วนบนแดชบอร์ดที่ประกาศไว้ใช้เฟรมแยกเดิมและคำสั่งที่ตรวจสิทธิ์ | backend/src/lib/plugins/ui-surfaces.ts |
| การจัดการฟอร์ม | อ่านคำตอบที่ยังเก็บอยู่ตามสิทธิ์ ตั้งปลายทางและเทมเพลตเฉพาะฟอร์ม และส่งอีเมลยืนยันเมื่อผู้ส่งยินยอม โดยใช้ระบบเก็บ ลบ และลองส่งซ้ำเดิม | backend/src/api/forms.ts; backend/src/lib/forms/delivery.ts |
| คลังสื่อและฟิลด์ไฟล์ | เปิดคลังได้โดยตรง ฟิลด์มีชนิดข้อมูลและเป็นส่วนตัวโดยค่าเริ่มต้น มีประวัติแยก และต้องเลือกให้เผยแพร่ผ่าน API | backend/src/lib/media/asset-metadata.ts |
| ลำดับคอลเลกชัน | เลือกใช้ลำดับร่วมกันทุกภาษา การย้ายอ้างอิงรายการที่มองเห็นและรักษาลำดับระหว่างรายการที่ซ่อนอยู่ ไคลเอนต์สาธารณะขอลำดับด้วย order=manual |
backend/src/lib/manual-order.ts |
| บริการ CMS สำหรับปลั๊กอิน | ความคิดเห็นและการกลั่นกรอง การเปลี่ยนเส้นทาง การกู้คืนจากถังขยะ การลบไฟล์ที่ลบได้ และเทมเพลตอีเมลที่อนุมัติ ยังคงผ่านการตรวจของบริการเดิม | backend/src/api/plugin-v1-services.ts; backend/src/api/plugin-v1-mail.ts |
| เมทาดาทาจากปลั๊กอิน | เมทาแท็ก ลิงก์ และ JSON-LD ที่ประกาศไว้เก็บกับเวอร์ชันเนื้อหา SEO หลักมีลำดับความสำคัญสูงกว่า และไม่ต้องเรียกปลั๊กอินขณะแสดงหน้า | backend/src/lib/plugins/renderer-metadata.ts; backend/src/lib/seo/head-runtime.ts |
| องค์ประกอบในข้อความแบบมีโครงสร้าง | ปลั๊กอินประกาศองค์ประกอบแบบอินไลน์ได้ ข้อมูลอยู่ในย่อหน้าและใช้ระบบเวอร์ชัน การอ้างอิง และการแสดงผลเดิม | backend/src/lib/page-contract/rich-document.ts |
| ลำดับชั้นที่เผยแพร่แล้ว | รายการบรรพบุรุษและเส้นทางนำทางใช้ชื่อที่เผยแพร่ เส้นทางที่ยอมรับ และกฎภาษาของไซต์ การแก้ฉบับร่างไม่แทนชื่อที่ใช้งานจริง | backend/src/lib/public-read/published-list.ts |
| โปรเจกต์ Astro เริ่มต้น | คำสั่งสร้างซอร์สที่ผู้พัฒนาเป็นเจ้าของ เชื่อมต่อ public API ปัจจุบัน และระบุข้อกำหนดหน้ากับ renderer รุ่นปัจจุบัน | backend/src/lib/managed-renderer/reference-starter.ts |
| รีลีสที่รองรับ | ยังต้องมีรีลีสพร้อมแท็ก การปรับใช้ Scheduling และหลักฐานจริงบน Cloudflare สำหรับการเผยแพร่ พรีวิว สื่อ อีเมล และการกู้คืน การมีซอร์สในเครื่องยังไม่ผ่านเกณฑ์เหล่านี้ | ขอบเขตผลิตภัณฑ์ |
ซอร์สส่วนนี้เพิ่มฟิลด์อัปโหลดไฟล์ในแบบฟอร์ม และการเลือกผู้รับอีเมลของปลั๊กอินจากรายการที่มีสิทธิ์เข้าถึง ไฟล์เก็บแบบส่วนตัว การดาวน์โหลดต้องมีสิทธิ์ และใช้ระยะเวลาเก็บกับการลบเดียวกับคำตอบในแบบฟอร์ม เทมเพลตที่ผู้ดูแลอนุมัติเลือกส่งถึงผู้สร้างรายการหรือผู้ตรวจทานที่ได้รับมอบหมายได้ ยังต้องทดสอบการทำงานและตรวจรับกับบริการจริง
ความสามารถของรุ่นรวมปัจจุบัน
หัวข้อที่มีชื่อว่า “ความสามารถของรุ่นรวมปัจจุบัน”ความสามารถเหล่านี้อยู่ในซอร์สของรุ่นรวมที่ยังไม่เผยแพร่ การทดสอบเบราว์เซอร์ทั้งหมด การตรวจหน้าใช้งานจริงบนมือถือและเดสก์ท็อป และการรับรองบริการภายนอกยังเป็นเงื่อนไขแยกต่างหาก
- การถ่ายโอนไซต์และประวัติเป็นส่วนรองรับไฟล์สื่อขนาดใหญ่ที่ไซต์รับได้ พร้อมผลรวมและการทำต่อ
- การแปลงหน้า WordPress เก็บหัวข้อ โค้ด ตาราง เนื้อหายาว และข้อมูลแหล่งที่จับคู่ไว้อย่างชัดเจน
- ข้อความจัดรูปแบบที่ป้องกันการเข้าถึงรองรับรูปภาพและไฟล์แนบส่วนตัว รวมถึงรูปภาพขนาดต่าง ๆ ที่ตรวจสิทธิ์
- ที่อยู่รองรับตัวอักษร ตัวเลข และเครื่องหมายผสม Unicode และสร้างจากชื่อภาษาไทยหรือภาษาอื่นได้
- ชุดค่าที่ไม่ซ้ำแบบมีชื่อรวมช่องสองถึงสี่ช่องและตรวจการเขียนแบบอะตอมมิก
- ข้อมูลร่วมของบล็อกใช้ข้อมูลผู้เขียน หมวดหมู่ และแท็กปัจจุบันได้ โดยยังเลือกโหมดสแนปช็อตได้อย่างชัดเจน
- คอมโพเนนต์ธรรมดาและแบบผสมเลิกใช้ชนิดเดิม เก็บโครงสร้างเดิม และอัปเกรดอินสแตนซ์ตามที่ผู้เขียนเลือกได้
- บล็อกปลั๊กอินมีช่องข้อความจัดรูปแบบของตัวแก้ไขหลักซ้อนอยู่ภายในได้ภายใต้ขีดจำกัดความลึก
- คอลัมน์ความสัมพันธ์ของระบบแสดงชื่อ จำนวน และค่าที่เกี่ยวข้องตามสิทธิ์
- เงื่อนไขการแสดงผลตามชนิดข้อมูลรวม AND/OR ได้สูงสุดสี่เงื่อนไขและสามระดับ
- ช่องแปลที่ไม่บังคับกรอกใช้ค่าที่ไม่มีจากภาษาสำรองที่เผยแพร่แล้วได้ แต่ค่าว่างโดยตั้งใจยังคงว่าง ดู ภาษาสำรองของช่อง
- SVG แบบคงที่ที่ผ่านการตรวจใช้เป็นรูปภาพได้
- แอปที่สร้างขึ้นรองรับบทบาทแบบมีชื่อสูงสุด 32 บทบาทพร้อมสิทธิ์การทำงานแต่ละโมเดล บทบาทเริ่มต้นสำหรับผู้สมัครที่ไม่ใช่ผู้ดูแล และบทบาท admin/user เดิม
- DeepInfra ยังเป็นผู้ให้บริการ AI เริ่มต้น ผู้ดูแลการติดตั้งเลือกปลายทางที่เข้ากันได้กับ OpenAI และรายการโมเดลข้อความ การอ่านภาพ และการสร้างภาพได้
- พรีวิวฉบับร่างที่เกี่ยวข้อง แสดงฉบับร่างที่บันทึกแล้วตามสิทธิ์ของผู้ใช้ การอ่านสาธารณะยังต้องใช้เนื้อหาที่เผยแพร่แล้ว
- การค้นหาเนื้อหา ค้นข้อความจัดรูปแบบที่บันทึกแล้ว รวมถึงฉบับร่าง พร้อมชื่อช่องที่ตรงกันและข้อความย่อ โดยตรวจสิทธิ์ก่อนแสดงผลและนับจำนวน
- ต้นทางของคำขอจากเบราว์เซอร์ กำหนด CORS, preflight และส่วนหัวที่อนุญาตสำหรับ API สาธารณะแยกตามไซต์
- การแทนที่สื่อผ่าน API การจัดการ เปลี่ยนไฟล์ผ่านบริการเดิม โดยคง ID สื่อและการอ้างอิงไว้
- การจัดการบัญชีของแอปที่สร้างขึ้น สร้างบัญชีพร้อมบทบาทที่เลือกและลบบัญชีที่ไม่มีข้อมูลแอปอ้างถึงได้ การลบเพิกถอนเซสชันและไม่อนุญาตให้ลบผู้ดูแลคนสุดท้าย
- การแก้ไขจากพรีวิว เปิดช่องข้อความและข้อความจัดรูปแบบทับตำแหน่งที่แสดงใน renderer ที่รองรับ ส่วน renderer รุ่นเก่ายังเปิดช่องที่ตรงกันในฟอร์ม
- การนำเข้าจาก WordPress เก็บกลุ่มและรายการซ้ำของ ACF ที่ตรวจทานแล้วเป็น JSON ที่แก้ไขได้ และให้เลือกเก็บกำหนดเผยแพร่ในอนาคตหรือเก็บเจตนาไว้ในฉบับร่างอย่างชัดเจน
- การอัปเดตเนื้อหาที่เลือก ให้ตรวจรายการเพิ่ม แก้ไข และลบในโมเดลที่มีข้อมูลแล้ว คงข้อมูลนอกขอบเขตและไฟล์สื่อเวอร์ชันเดิม และปฏิเสธเมื่อข้อมูลปลายทางเปลี่ยน งานทำต่อหรือยกเลิกได้ แต่ไม่มีการเลิกทำการแทนที่โดยอัตโนมัติ
ส่วนเพิ่มการส่งข้อมูล
หัวข้อที่มีชื่อว่า “ส่วนเพิ่มการส่งข้อมูล”| Capability | Source contract |
|---|---|
| คำค้นค่าแสดงผล relation | ฟิลด์ scalar ที่ตั้งค่าไว้ ใช้ค่าบันทึกและสิทธิ์เป้าหมาย SQL เดียวกับรายการ จำนวน view และ bulk ฟิลด์ข้ามไซต์คืน field_shared_display_unsupported แต่ยังกรอง ID และค่าว่างได้ |
| ต้นฉบับตามภาษา | ID สื่อเดียว ไฟล์ปัจจุบันต่อภาษา fallback และไฟล์เก่าที่เวอร์ชันตรึงไว้ ตัวแก้ไข API จัดการและการโอนเก็บภาษา |
| ลิงก์ร่วมแบบชัดเจน | ข้อมูลสาธารณะที่เผยแพร่ของต้นทาง revision สิทธิ์ปัจจุบัน และตรวจฐานต้นทางทุกคำตอบ ถอนสิทธิ์หรือเลิกเผยแพร่ได้ null |
| คำค้น point | ละติจูด/ลองจิจูดแบบเข้ม ระยะ Haversine ตรงใน SQL กรอบรวมขอบที่ข้ามแอนติเมอริเดียนและ cursor ผูกคำค้น |
| ซิงก์ส่วนเปลี่ยนแปลง | รายการที่เผยแพร่ตามสิทธิ์และสื่อสาธารณะ snapshot แบ่งหน้า replay/ลบตามลำดับ checkpoint ลงลายเซ็นและ reset ชัดเจน |
backend/test/delivery-query.test.ts; delivery-originals.test.ts; delivery-shared-content.test.ts; delivery-sync.test.ts; delivery-sync-triggers.test.ts.
ยังไม่เปิดตัว (pre-MVP) และยังไม่มีเวอร์ชันเสถียร
คอมมิตซอร์สโค้ด: fe23db481c422b40e317b92fc98116b4c0c26a87 (มีการแก้ไขที่ยังไม่คอมมิต)
วันที่สร้างเอกสาร (UTC): 2026-10-18T09:22:34.630Z
คอมมิตสำหรับอัปเกรด: ระบุไม่ได้: มีการแก้ไขที่ยังไม่คอมมิต. บันทึกการเปลี่ยนแปลง