19 KiB
Prompt: Move Announcement Pin Action Out of Create/Edit Form
Objective
ปรับปรุงการจัดการฟังก์ชัน ปักหมุดประกาศ โดยนำตัวเลือกปักหมุดออกจากหน้าสร้างและหน้าแก้ไขประกาศ แล้วเปลี่ยนให้เป็น Action ที่ใช้งานหลังจากประกาศได้รับการเผยแพร่แล้ว
เป้าหมายคือ:
- ลดความซับซ้อนของแบบฟอร์มสร้างประกาศ
- แยกการจัดการเนื้อหาออกจากการจัดลำดับการแสดงผล
- ทำให้ Workflow ของประกาศชัดเจน
- จำกัดการปักหมุดตามสถานะและ Permission
- ใช้โครงสร้างเดิมของระบบให้มากที่สุด
Existing Structure Review
ก่อนเริ่มแก้ไข ให้ตรวจสอบโครงสร้างเดิมที่เกี่ยวข้องทั้งหมด เช่น:
- Announcement database schema
is_pinned,pinned_at,pinned_byหรือ Field ที่มีความหมายใกล้เคียง- Create/Edit announcement form
- Announcement list
- Announcement detail
- Action menu
- API routes
- Server actions
- Query และ Sorting
- Permission
- Audit log
- Publish workflow
หากระบบมีโครงสร้างรองรับการปักหมุดอยู่แล้ว ให้ Reuse และปรับเฉพาะ UI/Workflow ตามความเหมาะสม
ใช้หลัก:
Reuse > Extend > Refactor > Create New
ห้ามสร้าง Field, API หรือ Business Logic ซ้ำโดยไม่จำเป็น
Scope
ดำเนินการดังนี้:
- นำตัวเลือกปักหมุดออกจากหน้าสร้างประกาศ
- นำตัวเลือกปักหมุดออกจากหน้าแก้ไขประกาศ
- เพิ่ม Action ปักหมุดในหน้า Announcement List
- เพิ่ม Action ปักหมุดในหน้า Announcement Detail หากเหมาะสม
- จำกัด Action ตาม Status และ Permission
- ปรับ Query การเรียงประกาศ
- เพิ่ม Audit Log หากระบบรองรับ
- ตรวจสอบ Regression ของ Workflow เดิม
Create Announcement Form
นำ Section หรือ Field ต่อไปนี้ออกจากหน้าสร้างประกาศ:
ปักหมุดประกาศ
ประกาศที่ปักหมุดจะแสดงด้านบนของรายการ
หน้าสร้างประกาศควรมีเฉพาะ:
- หัวข้อประกาศ
- รายละเอียดประกาศ
- วันเริ่มแสดง
- วันสิ้นสุดการแสดง
- ไฟล์แนบ
- ยกเลิก
- บันทึกร่าง
- ส่งตรวจสอบ
ห้ามส่งค่า isPinned หรือค่าที่เกี่ยวข้องจาก Create Form เว้นแต่โครงสร้าง API เดิมกำหนดเป็น Required ให้ปรับเป็นค่า Default ที่ปลอดภัย เช่น false
ประกาศใหม่ต้องมีค่าเริ่มต้น:
is_pinned = false
Edit Announcement Form
นำตัวเลือกปักหมุดออกจากหน้าแก้ไขประกาศเช่นเดียวกัน
หน้า Edit ใช้สำหรับแก้ไขเนื้อหาและช่วงเวลาการแสดงผลเท่านั้น
ห้ามให้การบันทึกหน้า Edit เปลี่ยนสถานะการปักหมุดโดยไม่ได้ตั้งใจ
Announcement List
เพิ่มสถานะการปักหมุดให้มองเห็นได้ในรายการ เช่น:
- ไอคอน Pin ข้างชื่อประกาศ
- Badge
ปักหมุด - คอลัมน์การแสดงผล หากเหมาะกับ Layout เดิม
ตัวอย่าง:
📌 ประกาศวันหยุดประจำปี
หรือ:
[ปักหมุด] ประกาศวันหยุดประจำปี
หลีกเลี่ยงการเพิ่มคอลัมน์ใหม่ หากทำให้ตารางกว้างเกินไป ให้ใช้ไอคอนหรือ Badge ภายในคอลัมน์ชื่อประกาศแทน
Action Menu
ใน Action Menu ของแต่ละประกาศ เพิ่มคำสั่งตามสถานะ:
หากยังไม่ปักหมุด:
ปักหมุดประกาศ
หากปักหมุดอยู่แล้ว:
ยกเลิกการปักหมุด
ใช้ไอคอนที่สื่อความหมาย เช่น:
PinPinOff
Action ต้องมี aria-label และข้อความภาษาไทยที่ชัดเจน
Announcement Detail
หากหน้า Detail มีชุด Action อยู่แล้ว ให้เพิ่ม:
ปักหมุดประกาศ
หรือ:
ยกเลิกการปักหมุด
ไม่จำเป็นต้องเพิ่ม หากจะทำให้ Action ซ้ำซ้อนและหน้า List รองรับการใช้งานครบถ้วนแล้ว
ให้เลือกแนวทางที่สอดคล้องกับ Pattern ของระบบเดิม
Status Rules
อนุญาตให้ปักหมุดเฉพาะประกาศที่มีสถานะ:
Published
และควรอยู่ในเงื่อนไข:
- วันเริ่มแสดงมาถึงแล้ว หรือระบบอนุญาตให้ปักหมุดล่วงหน้าอย่างชัดเจน
- วันสิ้นสุดยังไม่ผ่านมา
- ไม่ถูก Archive
- ไม่ถูก Soft Delete
ห้ามปักหมุดประกาศสถานะ:
- Draft
- Pending Review
- Rejected
- Approved but not Published
- Inactive
- Archived
- Deleted
- Expired
หากระบบใช้ชื่อ Status ต่างจากนี้ ให้ Mapping กับ Enum เดิมของโปรเจกต์ ห้ามสร้าง Enum ซ้ำ
Automatic Unpin Rules
ระบบต้องยกเลิกการปักหมุดอัตโนมัติ หรือไม่นำประกาศนั้นมาแสดงเป็นปักหมุด เมื่อ:
- ประกาศถูก Unpublish
- ประกาศถูก Archive
- ประกาศถูก Soft Delete
- ประกาศหมดอายุ
- วันสิ้นสุดการแสดงผลผ่านไปแล้ว
เลือกแนวทางให้สอดคล้องกับ Architecture เดิม:
- อัปเดต
is_pinned = falseเมื่อสถานะเปลี่ยน - หรือ Filter ออกจาก Pinned Query โดยไม่เปลี่ยนข้อมูลเดิม
ควรเลือกวิธีที่ลดความเสี่ยงของข้อมูลไม่สอดคล้องกัน และอธิบายไว้ในรายงาน
Multiple Pinned Announcements
รองรับการปักหมุดหลายประกาศ
ลำดับการแสดงผล:
- ประกาศที่ปักหมุดก่อน
- ภายในกลุ่มปักหมุด เรียงตาม
pinned_at DESC - หากไม่มี
pinned_atให้ใช้published_at DESC - ประกาศทั่วไปเรียงตามมาตรฐานเดิมของระบบ
ตัวอย่าง Query Logic:
is_pinned DESC
pinned_at DESC
published_at DESC
created_at DESC
ให้ปรับตาม Field ที่มีอยู่จริงในระบบ
Confirmation Dialog
ก่อนปักหมุด แสดง Dialog:
ยืนยันการปักหมุดประกาศ
ประกาศนี้จะแสดงอยู่ด้านบนของรายการประกาศ
คุณต้องการดำเนินการต่อหรือไม่
ปุ่ม:
ยกเลิก
ปักหมุดประกาศ
ก่อนยกเลิกการปักหมุด แสดง Dialog:
ยืนยันการยกเลิกปักหมุด
ประกาศนี้จะกลับไปเรียงตามลำดับประกาศทั่วไป
คุณต้องการดำเนินการต่อหรือไม่
ปุ่ม:
ยกเลิก
ยกเลิกการปักหมุด
หาก Pattern เดิมของระบบไม่ใช้ Confirm Dialog กับ Action ลักษณะนี้ สามารถใช้ Action ทันทีพร้อม Toast ได้ แต่ต้องรักษามาตรฐานเดียวกับ Feature อื่น
Permission
ใช้ Permission-first Architecture เท่านั้น
เพิ่มหรือ Reuse Permission:
announcement:pin
Permission นี้ครอบคลุม:
- ปักหมุดประกาศ
- ยกเลิกการปักหมุด
ทุก API หรือ Server Action ต้องตรวจสอบ Permission ฝั่ง Server
ห้ามตรวจสอบเฉพาะฝั่ง Client
ผู้ไม่มี Permission:
- ไม่เห็น Action
- เรียก API โดยตรงไม่ได้
- ได้รับ Response ที่เหมาะสม เช่น
403 Forbidden
หากมี Permission เดิมที่มีความหมายตรงกัน ให้ Reuse และไม่สร้างซ้ำ
API and Server Action
หากมี API เดิมรองรับ ให้ขยายของเดิม
หากไม่มี ให้เพิ่มเฉพาะ Endpoint หรือ Server Action ที่จำเป็น เช่น:
POST /api/announcements/:id/pin
POST /api/announcements/:id/unpin
หรือใช้รูปแบบ Mutation ตาม Architecture เดิม
การปักหมุดต้องอัปเดต:
is_pinned = true
pinned_at = current timestamp
pinned_by = current user
การยกเลิกปักหมุดต้องอัปเดต:
is_pinned = false
pinned_at = null
pinned_by = null
หาก Schema เดิมไม่มี pinned_at หรือ pinned_by ให้ประเมินก่อนเพิ่ม โดยเพิ่มเฉพาะเมื่อจำเป็นต่อ Sorting และ Audit เท่านั้น
Audit Log
หากระบบมี Audit Log อยู่แล้ว ให้บันทึก Action:
ANNOUNCEMENT_PINNED
ANNOUNCEMENT_UNPINNED
ข้อมูลควรประกอบด้วย:
- Announcement ID
- Announcement title
- Actor
- Action
- Previous value
- New value
- Timestamp
ห้ามสร้างระบบ Audit ใหม่ หากมีโครงสร้างกลางอยู่แล้ว
Toast Messages
ปักหมุดสำเร็จ:
ปักหมุดประกาศเรียบร้อยแล้ว
ยกเลิกสำเร็จ:
ยกเลิกการปักหมุดเรียบร้อยแล้ว
กรณีสถานะไม่รองรับ:
สามารถปักหมุดได้เฉพาะประกาศที่เผยแพร่แล้วเท่านั้น
กรณีประกาศหมดอายุ:
ไม่สามารถปักหมุดประกาศที่หมดอายุแล้วได้
กรณีไม่มีสิทธิ์:
คุณไม่มีสิทธิ์จัดการการปักหมุดประกาศ
Loading State
ขณะดำเนินการ:
- Disable Action ที่กำลังประมวลผล
- ป้องกันการกดซ้ำ
- แสดง Loading Indicator ตามมาตรฐานระบบ
- ไม่ปิดเมนูหรือ Dialog แบบทำให้ผู้ใช้ไม่ทราบผลลัพธ์
หลังสำเร็จ:
- Refresh หรือ Invalidate Query เฉพาะข้อมูลที่เกี่ยวข้อง
- ห้าม Reload ทั้งหน้าโดยไม่จำเป็น
Accessibility
ตรวจสอบ:
- Action มีชื่อที่ Screen Reader เข้าใจได้
- ไอคอนไม่เป็นตัวสื่อความหมายเพียงอย่างเดียว
- Dialog Focus Management ถูกต้อง
- Keyboard Navigation ใช้งานได้
- Badge และสถานะไม่ใช้สีเพียงอย่างเดียว
Responsive
หน้า List และ Action Menu ต้องใช้งานได้บน:
- Desktop
- Tablet
- Mobile
ห้ามให้ Badge หรือไอคอนปักหมุดทำให้ชื่อประกาศถูกบีบจนอ่านไม่ได้
Business Logic Restrictions
ห้ามเปลี่ยน:
- Approval workflow
- Draft workflow
- Submit for review workflow
- Publish workflow
- Schedule publish workflow
- Versioning ของเนื้อหา
- File attachment logic
- Existing validation ที่ไม่เกี่ยวข้อง
- Existing permission ที่ไม่เกี่ยวข้อง
งานนี้ต้องเปลี่ยนเฉพาะ Workflow และ UI ของการปักหมุดประกาศ
Testing
เพิ่มหรือปรับ Test Cases ให้ครอบคลุม:
Functional
- Create announcement แล้ว
is_pinnedเป็นfalse - หน้า Create ไม่มีตัวเลือกปักหมุด
- หน้า Edit ไม่มีตัวเลือกปักหมุด
- Published announcement สามารถปักหมุดได้
- Pinned announcement สามารถยกเลิกได้
- Draft ไม่สามารถปักหมุดได้
- Pending Review ไม่สามารถปักหมุดได้
- Archived ไม่สามารถปักหมุดได้
- Expired ไม่สามารถปักหมุดได้
- Unpublished announcement ไม่ถูกแสดงเป็นปักหมุด
- หลายประกาศปักหมุดเรียงถูกต้อง
Permission
- มี
announcement:pinเห็นและใช้ Action ได้ - ไม่มี Permission ไม่เห็น Action
- เรียก Server Action โดยไม่มี Permission ต้องถูกปฏิเสธ
UI
- Badge หรือ Pin icon แสดงถูกต้อง
- Loading State ทำงาน
- Toast ถูกต้อง
- Confirm Dialog ถูกต้อง
- Mobile ใช้งานได้
Regression
- Create Draft ยังทำงาน
- Submit Review ยังทำงาน
- Approve ยังทำงาน
- Publish ยังทำงาน
- Schedule Publish ยังทำงาน
- Edit Announcement ยังทำงาน
- Pagination/Search/Filter ยังทำงาน
Deliverables
เมื่อดำเนินการเสร็จ ให้สร้างเอกสาร:
docs/announcement-pin-action-enhancement-report.md
ประกอบด้วย:
1. Existing Structure Review
- โครงสร้างเดิมที่พบ
- Field เดิมที่ Reuse
- API/Action เดิมที่ Reuse
- Component เดิมที่ Reuse
- ส่วนที่ต้อง Refactor หรือ Extend
2. Files Changed
ระบุไฟล์ทั้งหมดที่แก้ไข
3. UI Changes
- สิ่งที่นำออกจาก Create/Edit
- Action ที่เพิ่มใน List/Detail
- Badge หรือสถานะที่เพิ่ม
4. Business Rules
- Status ที่ปักหมุดได้
- Automatic Unpin
- Sorting
- Multiple Pinned Announcements
5. Permission
- Permission ที่ใช้
- การตรวจสอบ Client/Server
6. Database and API Changes
- Field ที่เพิ่มหรือปรับ
- Migration
- Endpoint หรือ Server Action
7. Audit Log
Action ที่บันทึก
8. Testing Result
- Functional
- Permission
- Responsive
- Regression
9. Remaining Improvements
เช่น:
- Pin expiration
- Pin priority
- Scheduled pinning
- Limit maximum pinned announcements
- Drag-and-drop pinned ordering
Success Criteria
งานถือว่าเสร็จเมื่อ:
- หน้าสร้างไม่มีตัวเลือกปักหมุด
- หน้าแก้ไขไม่มีตัวเลือกปักหมุด
- ปักหมุดจากหน้า List หรือ Detail ได้
- ปักหมุดได้เฉพาะประกาศที่เผยแพร่แล้ว
- Permission-first ทำงานครบ
- Server-side authorization ทำงาน
- Sorting ของประกาศปักหมุดถูกต้อง
- Automatic Unpin หรือ Filtering ทำงานถูกต้อง
- ไม่มีผลกระทบต่อ Approval/Publish Workflow
- TypeScript ไม่มี Error
- ESLint ผ่าน
- Build ผ่าน
- Tests ผ่าน
- ไม่มี Regression
- รายงานถูกสร้างเรียบร้อย