343 lines
6.1 KiB
Markdown
343 lines
6.1 KiB
Markdown
# Prompt: Fix Attachment View & Download Behavior (Production Ready)
|
|
|
|
## Background
|
|
|
|
ปัจจุบันหน้าแสดงรายละเอียดบทเรียนออนไลน์ (Online Lesson Detail) ในส่วน **เอกสารแนบ** มีปุ่ม
|
|
|
|
- เปิดไฟล์
|
|
- ดาวน์โหลด
|
|
|
|
แต่เมื่อกด **เปิดไฟล์** ระบบกลับดาวน์โหลดไฟล์ทันที ซึ่งไม่ใช่พฤติกรรมที่ต้องการ
|
|
|
|
---
|
|
|
|
## ปัญหาที่พบ
|
|
|
|
ปัจจุบันทั้งสองปุ่มใช้งานผ่าน URL เดียวกัน
|
|
|
|
ตัวอย่าง
|
|
|
|
```tsx
|
|
<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
|
|
|
|
ต้องรองรับ
|
|
|
|
### PDF
|
|
|
|
เปิดใน 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
|
|
|
|
ดำเนินการดังนี้
|
|
|
|
1. วิเคราะห์โครงสร้างเดิม
|
|
2. อธิบายสาเหตุของปัญหา
|
|
3. แก้ไข Backend
|
|
4. แก้ไข Frontend
|
|
5. ตรวจสอบ Security
|
|
6. ตรวจสอบ UX
|
|
7. ตรวจสอบ Regression
|
|
8. สรุปรายการไฟล์ที่แก้ไข
|
|
9. สรุปผลการทดสอบ
|
|
10. ยืนยันว่า Build / Type Check / ESLint ผ่านทั้งหมด
|