6.1 KiB
Prompt: Fix Attachment View & Download Behavior (Production Ready)
Background
ปัจจุบันหน้าแสดงรายละเอียดบทเรียนออนไลน์ (Online Lesson Detail) ในส่วน เอกสารแนบ มีปุ่ม
- เปิดไฟล์
- ดาวน์โหลด
แต่เมื่อกด เปิดไฟล์ ระบบกลับดาวน์โหลดไฟล์ทันที ซึ่งไม่ใช่พฤติกรรมที่ต้องการ
ปัญหาที่พบ
ปัจจุบันทั้งสองปุ่มใช้งานผ่าน URL เดียวกัน
ตัวอย่าง
<Button asChild variant="outline">
<Link href={lesson.attachment_url}>
เปิดไฟล์
</Link>
</Button>
<Button asChild>
<Link href={lesson.attachment_url}>
ดาวน์โหลด
</Link>
</Button>
ทำให้
- เปิดไฟล์ = ดาวน์โหลด
- ดาวน์โหลด = ดาวน์โหลด
สาเหตุหลักเกิดจาก Response Header ของไฟล์เป็น
Content-Disposition: attachment
Browser จึงบังคับ Download
Objective
แยกการทำงานของ
- View Attachment
- Download Attachment
ให้เป็นคนละ Endpoint
และรองรับการทำงานแบบ Production
Requirements
1. สร้าง API สำหรับ View Attachment
เช่น
GET
/api/online-lessons/[id]/attachment/view
หรือ Route ที่เหมาะสมกับโครงสร้างโปรเจกต์
หน้าที่
- ตรวจสอบสิทธิ์การเข้าถึง
- ตรวจสอบว่าบทเรียนมีไฟล์แนบ
- อ่านไฟล์จาก Storage
- ส่งไฟล์กลับด้วย
Content-Disposition: inline
ไม่ใช่
attachment
พร้อมส่ง
Content-Type
ตาม Mime Type จริงของไฟล์
ตัวอย่าง
application/pdf
image/png
image/jpeg
2. สร้าง API สำหรับ Download
เช่น
GET
/api/online-lessons/[id]/attachment/download
ส่ง Response
Content-Disposition: attachment
เพื่อให้ Browser ดาวน์โหลดไฟล์
3. Frontend
ปรับปุ่ม
จากเดิม
lesson.attachment_url
ให้เรียก API ใหม่
เปิดไฟล์
/attachment/view
ดาวน์โหลด
/attachment/download
4. ใช้ Anchor แทน Next Link
สำหรับไฟล์
ไม่ควรใช้
next/link
ให้ใช้
<a>
ร่วมกับ
Button asChild
ตัวอย่าง
<Button asChild variant="outline">
<a
href="..."
target="_blank"
rel="noopener noreferrer"
>
เปิดไฟล์
</a>
</Button>
และ
<Button asChild>
<a href="...">
ดาวน์โหลด
</a>
</Button>
5. Browser Behavior
ต้องรองรับ
เปิดใน Tab ใหม่
Image
เปิดใน Browser
Text
เปิดใน Browser
Office File
หาก Browser เปิดไม่ได้
ให้ Browser ดาวน์โหลดตามปกติ
6. Security
ตรวจสอบสิทธิ์ก่อนเปิดไฟล์
ห้ามใช้ Public URL โดยตรง
Route ต้องตรวจสอบ
- Authentication
- Authorization
เหมือนการเปิดรายละเอียดบทเรียน
7. Error Handling
หาก
- ไม่พบไฟล์
- ไม่มีสิทธิ์
- Storage Error
ต้องส่ง Status Code ที่เหมาะสม
เช่น
404
403
500
Frontend ต้องแสดงข้อความแจ้งผู้ใช้
8. Logging
บันทึก Error ผ่านระบบ Logging ของโปรเจกต์
ไม่ใช้
console.log
9. UX
ส่วนเอกสารแนบควรเป็น
เอกสารแนบ
📄 คู่มือการใช้งาน.pdf
[เปิดไฟล์] [ดาวน์โหลด]
หากไม่มีไฟล์
เอกสารแนบ
ไม่มีไฟล์แนบ
ไม่ต้องแสดง Dropzone
10. Coding Standard
ต้องสอดคล้องกับมาตรฐานของโปรเจกต์
- Next.js App Router
- TypeScript Strict
- Server Component / Route Handler
- shadcn/ui
- TailwindCSS
- ไม่ใช้ any
- ESLint ผ่าน
- Type Check ผ่าน
Acceptance Criteria
- เปิดไฟล์สามารถเปิดใน Browser ได้ (PDF / Image)
- ดาวน์โหลดทำงานแยกจากเปิดไฟล์
- ไม่ใช้ URL Storage ตรง ๆ บน Frontend
- ใช้ API กลางของระบบ
- ตรวจสอบ Permission ก่อนทุกครั้ง
- ไม่มี Regression
- ผ่าน Build
- ผ่าน Type Check
- ผ่าน ESLint
Deliverables
ดำเนินการดังนี้
- วิเคราะห์โครงสร้างเดิม
- อธิบายสาเหตุของปัญหา
- แก้ไข Backend
- แก้ไข Frontend
- ตรวจสอบ Security
- ตรวจสอบ UX
- ตรวจสอบ Regression
- สรุปรายการไฟล์ที่แก้ไข
- สรุปผลการทดสอบ
- ยืนยันว่า Build / Type Check / ESLint ผ่านทั้งหมด