411 lines
15 KiB
Markdown
411 lines
15 KiB
Markdown
# Prompt: แก้ไขหน้าเจ้าหน้าที่บทเรียนออนไลน์ หลังบันทึกฉบับร่างให้กลับหน้ารายการ
|
|
|
|
## เป้าหมาย
|
|
|
|
ปรับปรุงหน้าเพิ่มหรือแก้ไขบทเรียนออนไลน์ของฝั่งเจ้าหน้าที่ เมื่อผู้ใช้งานกดปุ่ม **“บันทึกฉบับร่าง”** และระบบบันทึกสำเร็จ ให้ระบบนำผู้ใช้งานกลับไปยังหน้ารายการบทเรียนออนไลน์ทันที
|
|
|
|
---
|
|
|
|
## พฤติกรรมปัจจุบัน
|
|
|
|
หลังจากเจ้าหน้าที่กดปุ่ม:
|
|
|
|
```text
|
|
บันทึกฉบับร่าง
|
|
```
|
|
|
|
และบันทึกข้อมูลสำเร็จ ระบบยังคงอยู่ที่หน้าเดิม หรือไม่มีการนำทางกลับไปยังหน้ารายการบทเรียนออนไลน์
|
|
|
|
---
|
|
|
|
## พฤติกรรมที่คาดหวัง
|
|
|
|
เมื่อบันทึกฉบับร่างสำเร็จ ระบบต้อง:
|
|
|
|
1. แสดงข้อความแจ้งเตือนว่าบันทึกฉบับร่างสำเร็จ
|
|
2. อัปเดตหรือ Invalidate ข้อมูลรายการบทเรียนออนไลน์
|
|
3. นำผู้ใช้งานกลับไปยังหน้ารายการบทเรียนออนไลน์ของเจ้าหน้าที่
|
|
4. หน้ารายการต้องแสดงข้อมูลฉบับร่างที่เพิ่งสร้างหรือแก้ไขล่าสุด
|
|
5. รายการใหม่ต้องแสดงตาม Sorting มาตรฐานเดิมของระบบ โดยรายการที่สร้างหรืออัปเดตล่าสุดควรแสดงก่อน หากระบบกำหนดไว้เช่นนั้น
|
|
|
|
ตัวอย่าง Route ปลายทาง:
|
|
|
|
```text
|
|
/dashboard/online-lessons
|
|
```
|
|
|
|
ให้ตรวจสอบ Route จริงจาก Repository ห้ามสมมติหากระบบใช้ Path อื่น
|
|
|
|
---
|
|
|
|
## ขอบเขตการตรวจสอบ
|
|
|
|
ตรวจสอบ Flow ที่เกี่ยวข้องทั้งหมด:
|
|
|
|
```text
|
|
ปุ่มบันทึกฉบับร่าง
|
|
→ Form Submit
|
|
→ Server Action / API Mutation
|
|
→ บันทึกข้อมูลสำเร็จ
|
|
→ Invalidate / Refetch
|
|
→ Toast
|
|
→ Redirect กลับหน้ารายการ
|
|
```
|
|
|
|
ค้นหาไฟล์หรือ Component ที่เกี่ยวข้อง เช่น:
|
|
|
|
```text
|
|
OnlineLessonForm
|
|
OnlineLessonCreateForm
|
|
OnlineLessonEditForm
|
|
CreateOnlineLessonPage
|
|
EditOnlineLessonPage
|
|
useCreateOnlineLesson
|
|
useUpdateOnlineLesson
|
|
```
|
|
|
|
ชื่อจริงอาจแตกต่าง ให้ตรวจสอบจากโครงสร้างปัจจุบัน
|
|
|
|
---
|
|
|
|
## ตรวจสอบ Action ของปุ่ม Submit
|
|
|
|
หาก Form มีหลายปุ่ม เช่น:
|
|
|
|
```text
|
|
บันทึกฉบับร่าง
|
|
บันทึกส่งตรวจสอบ
|
|
```
|
|
|
|
ต้องแยก Action ให้ชัดเจน เช่น:
|
|
|
|
```ts
|
|
type SubmitAction = "draft" | "submit";
|
|
```
|
|
|
|
หรือใช้โครงสร้างเดิมที่ระบบมีอยู่แล้ว เช่น:
|
|
|
|
```ts
|
|
submitActionRef.current;
|
|
```
|
|
|
|
หลังบันทึกสำเร็จ ให้ตรวจสอบ Action ก่อนทำ Redirect
|
|
|
|
ตัวอย่างแนวคิด:
|
|
|
|
```ts
|
|
if (action === "draft") {
|
|
toast.success("บันทึกฉบับร่างเรียบร้อยแล้ว");
|
|
router.push("/dashboard/online-lessons");
|
|
router.refresh();
|
|
}
|
|
```
|
|
|
|
ห้าม Copy ตัวอย่างโดยตรง หากระบบมี Utility, Route Constant หรือ Navigation Pattern อยู่แล้ว ให้ใช้ของเดิม
|
|
|
|
---
|
|
|
|
## รองรับทั้งหน้าเพิ่มและหน้าแก้ไข
|
|
|
|
ตรวจสอบทั้งสองกรณี:
|
|
|
|
### หน้าเพิ่มบทเรียนออนไลน์
|
|
|
|
เมื่อสร้าง Draft สำเร็จ:
|
|
|
|
```text
|
|
Create Draft
|
|
→ กลับหน้ารายการ
|
|
```
|
|
|
|
### หน้าแก้ไขบทเรียนออนไลน์
|
|
|
|
เมื่อแก้ไข Draft และบันทึกสำเร็จ:
|
|
|
|
```text
|
|
Update Draft
|
|
→ กลับหน้ารายการ
|
|
```
|
|
|
|
หากหน้าแก้ไขรองรับการแก้เฉพาะสถานะ Draft ต้องคง Business Rule เดิมไว้
|
|
|
|
---
|
|
|
|
## การอัปเดตข้อมูลหน้ารายการ
|
|
|
|
ก่อนหรือหลัง Redirect ต้องทำให้หน้ารายการแสดงข้อมูลล่าสุด
|
|
|
|
หากใช้ Next.js Server Actions ให้ตรวจสอบการใช้:
|
|
|
|
```ts
|
|
revalidatePath("/dashboard/online-lessons");
|
|
```
|
|
|
|
หากใช้ React Query/TanStack Query ให้ตรวจสอบ:
|
|
|
|
```ts
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["online-lessons"],
|
|
});
|
|
```
|
|
|
|
หากใช้ SWR ให้ตรวจสอบ:
|
|
|
|
```ts
|
|
mutate("/api/online-lessons");
|
|
```
|
|
|
|
ให้ใช้ Pattern จริงของระบบ ไม่ต้องเพิ่มหลายวิธีพร้อมกันโดยไม่จำเป็น
|
|
|
|
---
|
|
|
|
## ลำดับการทำงานที่แนะนำ
|
|
|
|
เมื่อบันทึกสำเร็จ:
|
|
|
|
```text
|
|
1. ยืนยันว่า API หรือ Server Action สำเร็จ
|
|
2. Invalidate หรือ Revalidate หน้ารายการ
|
|
3. แสดง Success Toast
|
|
4. Redirect ไปหน้ารายการ
|
|
```
|
|
|
|
ตัวอย่าง:
|
|
|
|
```ts
|
|
await saveDraft(values);
|
|
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["online-lessons"],
|
|
});
|
|
|
|
toast.success("บันทึกฉบับร่างเรียบร้อยแล้ว");
|
|
|
|
router.push(ONLINE_LESSON_LIST_ROUTE);
|
|
```
|
|
|
|
หากใช้ `router.replace()` ตามมาตรฐานเดิมของระบบ ให้ใช้ Pattern เดิม
|
|
|
|
---
|
|
|
|
## การป้องกัน Redirect เมื่อบันทึกไม่สำเร็จ
|
|
|
|
ห้าม Redirect หาก:
|
|
|
|
- Validation ไม่ผ่าน
|
|
- API ตอบ Error
|
|
- Database บันทึกไม่สำเร็จ
|
|
- Upload File ไม่สำเร็จ
|
|
- Permission ไม่ผ่าน
|
|
- Server Action คืนสถานะ Failure
|
|
|
|
เมื่อเกิด Error ต้อง:
|
|
|
|
- อยู่หน้าเดิม
|
|
- แสดง Error Message
|
|
- รักษาข้อมูลใน Form ไว้
|
|
- ไม่เปลี่ยนสถานะโดยไม่ตั้งใจ
|
|
- ให้ผู้ใช้งานสามารถแก้ไขแล้วบันทึกใหม่ได้
|
|
|
|
ตัวอย่าง:
|
|
|
|
```ts
|
|
try {
|
|
await saveDraft(values);
|
|
|
|
toast.success("บันทึกฉบับร่างเรียบร้อยแล้ว");
|
|
router.push(listRoute);
|
|
} catch (error) {
|
|
toast.error(getErrorMessage(error));
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## ป้องกันการ Submit ซ้ำ
|
|
|
|
ระหว่างบันทึก:
|
|
|
|
- Disable ปุ่มบันทึกฉบับร่าง
|
|
- แสดง Loading State
|
|
- ป้องกัน Double Click
|
|
- ไม่ Redirect ซ้ำ
|
|
- ไม่สร้าง Draft ซ้ำหลายรายการ
|
|
|
|
ตัวอย่าง:
|
|
|
|
```tsx
|
|
<Button type="submit" disabled={form.state.isSubmitting}>
|
|
{form.state.isSubmitting ? "กำลังบันทึก..." : "บันทึกฉบับร่าง"}
|
|
</Button>
|
|
```
|
|
|
|
ให้ใช้ State และ Component เดิมของระบบ
|
|
|
|
---
|
|
|
|
## ไม่กระทบปุ่ม “บันทึกส่งตรวจสอบ”
|
|
|
|
งานนี้ต้องตรวจสอบแยก Action ให้ถูกต้อง
|
|
|
|
ปุ่ม:
|
|
|
|
```text
|
|
บันทึกส่งตรวจสอบ
|
|
```
|
|
|
|
ต้องคงพฤติกรรมเดิม เว้นแต่ระบบกำหนดให้กลับหน้ารายการอยู่แล้ว
|
|
|
|
ห้ามทำให้:
|
|
|
|
- Draft ถูกเปลี่ยนเป็น Pending โดยไม่ตั้งใจ
|
|
- Submit Action ถูกตีความเป็น Draft
|
|
- ทั้งสองปุ่มใช้ Callback เดียวกันโดยไม่ตรวจสอบ Action
|
|
- Validation ของ Draft และ Submit ปะปนกัน
|
|
|
|
---
|
|
|
|
## กรณีมีไฟล์แนบ
|
|
|
|
หากการบันทึกบทเรียนออนไลน์มี:
|
|
|
|
- วิดีโอ
|
|
- Thumbnail
|
|
- เอกสารประกอบ
|
|
- ไฟล์แนบอื่น
|
|
|
|
ต้องรอให้กระบวนการ Upload และบันทึกข้อมูลเสร็จสมบูรณ์ก่อน Redirect
|
|
|
|
ห้าม Redirect ก่อน Upload เสร็จ เพราะอาจทำให้ข้อมูลหรือไฟล์ไม่ครบ
|
|
|
|
---
|
|
|
|
## Permission
|
|
|
|
ตรวจสอบว่าการเปลี่ยนแปลงนี้ใช้เฉพาะหน้าของเจ้าหน้าที่ที่มีสิทธิ์จัดการบทเรียนออนไลน์ เช่น:
|
|
|
|
```text
|
|
Staff
|
|
HRD Staff
|
|
HRD Manager
|
|
IT Admin
|
|
Super Admin
|
|
```
|
|
|
|
ให้ยึด Permission จริงจากระบบ
|
|
|
|
ห้ามเปลี่ยน:
|
|
|
|
- Permission Rule
|
|
- Approval Workflow
|
|
- Publish Workflow
|
|
- Status Transition
|
|
- สิทธิ์ของผู้ใช้งานทั่วไป
|
|
|
|
---
|
|
|
|
## Test Cases
|
|
|
|
### Test Case 1: สร้าง Draft สำเร็จ
|
|
|
|
1. เข้าหน้าเพิ่มบทเรียนออนไลน์
|
|
2. กรอกข้อมูลขั้นต่ำที่ Draft อนุญาต
|
|
3. กด “บันทึกฉบับร่าง”
|
|
4. ตรวจสอบว่าแสดงข้อความสำเร็จ
|
|
5. ตรวจสอบว่ากลับหน้ารายการ
|
|
6. ตรวจสอบว่ารายการ Draft ใหม่แสดงอยู่ในตาราง
|
|
|
|
### Test Case 2: แก้ไข Draft สำเร็จ
|
|
|
|
1. เปิดรายการสถานะ Draft
|
|
2. แก้ไขข้อมูล
|
|
3. กด “บันทึกฉบับร่าง”
|
|
4. ตรวจสอบว่ากลับหน้ารายการ
|
|
5. ตรวจสอบว่าข้อมูลล่าสุดแสดงถูกต้อง
|
|
|
|
### Test Case 3: Validation ไม่ผ่าน
|
|
|
|
1. กรอกข้อมูลไม่ถูกต้อง
|
|
2. กด “บันทึกฉบับร่าง”
|
|
3. ตรวจสอบว่าไม่ Redirect
|
|
4. แสดง Validation Error
|
|
5. ข้อมูลใน Form ไม่หาย
|
|
|
|
### Test Case 4: API Error
|
|
|
|
1. จำลอง API หรือ Database Error
|
|
2. กดบันทึกฉบับร่าง
|
|
3. ตรวจสอบว่าอยู่หน้าเดิม
|
|
4. แสดง Error Toast
|
|
5. ไม่สร้างข้อมูลซ้ำ
|
|
|
|
### Test Case 5: ป้องกันการ Submit ซ้ำ
|
|
|
|
1. กดบันทึกฉบับร่างหลายครั้งอย่างรวดเร็ว
|
|
2. ตรวจสอบว่าสร้างหรืออัปเดตเพียงครั้งเดียว
|
|
3. ปุ่มต้อง Disabled ระหว่าง Pending
|
|
|
|
### Test Case 6: ส่งตรวจสอบ
|
|
|
|
1. กด “บันทึกส่งตรวจสอบ”
|
|
2. ตรวจสอบว่า Workflow เดิมยังทำงานถูกต้อง
|
|
3. สถานะต้องเป็นไปตาม Business Rule เดิม
|
|
4. ไม่ถูกบันทึกเป็น Draft โดยผิดพลาด
|
|
|
|
### Test Case 7: ข้อมูลหน้ารายการล่าสุด
|
|
|
|
1. บันทึก Draft
|
|
2. กลับหน้ารายการ
|
|
3. ตรวจสอบว่าไม่ต้อง Refresh Browser
|
|
4. รายการใหม่หรือรายการที่แก้ไขต้องแสดงทันที
|
|
|
|
---
|
|
|
|
## Acceptance Criteria
|
|
|
|
งานถือว่าเสร็จเมื่อ:
|
|
|
|
- บันทึกฉบับร่างสำเร็จแล้วกลับหน้ารายการบทเรียนออนไลน์
|
|
- รองรับทั้งหน้า Create และ Edit
|
|
- หน้ารายการแสดงข้อมูลล่าสุดทันที
|
|
- มี Success Toast
|
|
- ไม่ Redirect เมื่อเกิด Error
|
|
- ไม่ Redirect เมื่อ Validation ไม่ผ่าน
|
|
- ป้องกัน Double Submit
|
|
- ไม่กระทบปุ่มบันทึกส่งตรวจสอบ
|
|
- ไม่เปลี่ยน Workflow และ Permission เดิม
|
|
- ไม่สร้างข้อมูลซ้ำ
|
|
- Type Check ผ่าน
|
|
- Lint ผ่าน
|
|
- Test ผ่าน
|
|
- Build ผ่าน
|
|
|
|
---
|
|
|
|
## รูปแบบรายงานผล
|
|
|
|
หลังแก้ไขเสร็จ ให้สรุป:
|
|
|
|
1. สาเหตุที่บันทึก Draft แล้วไม่กลับหน้ารายการ
|
|
2. Route หน้ารายการที่ใช้จริง
|
|
3. ไฟล์ที่แก้ไข
|
|
4. วิธีแยก Draft Action กับ Submit Action
|
|
5. วิธี Invalidate หรือ Revalidate ข้อมูล
|
|
6. พฤติกรรมเมื่อสำเร็จ
|
|
7. พฤติกรรมเมื่อเกิด Error
|
|
8. ผลการทดสอบ Create Draft
|
|
9. ผลการทดสอบ Edit Draft
|
|
10. ผล Type Check, Lint, Test และ Build
|
|
|
|
---
|
|
|
|
## ข้อกำหนดสุดท้าย
|
|
|
|
- ตรวจสอบโค้ดเดิมก่อนแก้ไข
|
|
- ใช้ Navigation และ Data Fetching Pattern เดิมของระบบ
|
|
- ห้ามสมมติ Route
|
|
- ห้าม Redirect ก่อนบันทึกและอัปโหลดเสร็จ
|
|
- ห้ามเปลี่ยน Business Rule
|
|
- ห้ามแก้เฉพาะหน้า Create โดยไม่ตรวจสอบหน้า Edit
|
|
- ห้ามรายงานว่าสำเร็จโดยไม่ตรวจสอบว่าหน้ารายการแสดงข้อมูลล่าสุดจริง
|