Files
alla-tms/plans/fix-attachment-view.md
2026-07-16 09:53:14 +07:00

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 ผ่านทั้งหมด