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

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

สำหรับไฟล์

ไม่ควรใช้

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