# 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
- ห้ามรายงานว่าสำเร็จโดยไม่ตรวจสอบว่าหน้ารายการแสดงข้อมูลล่าสุดจริง
