374 lines
7.8 KiB
Markdown
374 lines
7.8 KiB
Markdown
# Fix Permission Bug: User สามารถเห็น "หมายเหตุการตรวจสอบ" ในหน้ารายละเอียดประกาศ
|
|
|
|
## ปัญหา
|
|
|
|
ปัจจุบันเมื่อผู้ใช้งาน (Employee/User) เปิดดูรายละเอียดประกาศจากหน้า "ประกาศล่าสุด" หรือหน้ารายละเอียดประกาศ
|
|
|
|
ระบบยังแสดง
|
|
|
|
- หมายเหตุการตรวจสอบ (Review Note)
|
|
- ความคิดเห็นของผู้ตรวจสอบ
|
|
|
|
ซึ่งเป็นข้อมูลภายในของ Workflow การอนุมัติ
|
|
|
|
ข้อมูลดังกล่าวควรเห็นได้เฉพาะ
|
|
|
|
- HRD
|
|
- HRD Manager
|
|
- Admin
|
|
- ผู้มีสิทธิ์ตรวจสอบประกาศ
|
|
|
|
ไม่ควรแสดงแก่ผู้ใช้งานทั่วไป
|
|
|
|
ถือเป็นปัญหา Information Disclosure และ Permission Logic
|
|
|
|
---
|
|
|
|
# เป้าหมาย
|
|
|
|
แก้ไขให้ข้อมูล Workflow ภายในไม่สามารถถูกเข้าถึงหรือแสดงผลโดยผู้ใช้งานทั่วไปได้
|
|
|
|
ทั้งในระดับ
|
|
|
|
- Backend API
|
|
- Frontend
|
|
- Permission
|
|
- Component
|
|
- DTO / Response
|
|
|
|
ให้เป็นมาตรฐาน Production Ready
|
|
|
|
---
|
|
|
|
# สิ่งที่ต้องตรวจสอบ
|
|
|
|
## 1. ตรวจสอบ API รายละเอียดประกาศ
|
|
|
|
ค้นหา API ที่ใช้
|
|
|
|
ตัวอย่างเช่น
|
|
|
|
- GET /announcements/:id
|
|
- getAnnouncementById()
|
|
- announcement.service.ts
|
|
- announcement.repository.ts
|
|
|
|
ตรวจสอบ Response ว่าส่งข้อมูลดังนี้หรือไม่
|
|
|
|
- review_note
|
|
- review_comment
|
|
- reviewer
|
|
- reviewer_name
|
|
- reviewer_id
|
|
- approved_by
|
|
- approved_at
|
|
- rejected_reason
|
|
- workflow
|
|
- audit
|
|
- review_status
|
|
|
|
หากส่งให้ User ต้องแก้ไข
|
|
|
|
---
|
|
|
|
## 2. แยก Public Response กับ Admin Response
|
|
|
|
หากใช้ DTO เดียวกัน
|
|
|
|
เช่น
|
|
|
|
AnnouncementDetailDto
|
|
|
|
ให้แยกเป็น
|
|
|
|
AnnouncementPublicDto
|
|
|
|
ประกอบด้วย
|
|
|
|
- id
|
|
- title
|
|
- content
|
|
- attachment
|
|
- published_at
|
|
- expired_at
|
|
- created_by (ถ้าจำเป็น)
|
|
- published_by (ถ้าจำเป็น)
|
|
|
|
เท่านั้น
|
|
|
|
ส่วน
|
|
|
|
AnnouncementAdminDto
|
|
|
|
จึงค่อยมี
|
|
|
|
- review_note
|
|
- reviewer
|
|
- workflow
|
|
- audit
|
|
- rejected_reason
|
|
- review history
|
|
|
|
---
|
|
|
|
## 3. ตรวจสอบ Permission ของ API
|
|
|
|
ถ้า API เดียวใช้ทั้ง Admin และ User
|
|
|
|
ให้ตรวจสอบสิทธิ์
|
|
|
|
ตัวอย่าง
|
|
|
|
```
|
|
if (isAdmin) {
|
|
return fullAnnouncement
|
|
}
|
|
|
|
return publicAnnouncement
|
|
```
|
|
|
|
ห้ามส่งข้อมูล Review กลับไปยัง User แล้วค่อยซ่อนด้วย Frontend
|
|
|
|
ต้องตัดออกจาก Response ตั้งแต่ Backend
|
|
|
|
---
|
|
|
|
## 4. ตรวจสอบ Frontend
|
|
|
|
ค้นหา Component
|
|
|
|
AnnouncementDetail
|
|
|
|
AnnouncementView
|
|
|
|
AnnouncementContent
|
|
|
|
หรือ Component ที่ใช้แสดงรายละเอียดประกาศ
|
|
|
|
ตรวจสอบว่ามีโค้ดลักษณะนี้หรือไม่
|
|
|
|
```
|
|
{announcement.review_note && (
|
|
...
|
|
)}
|
|
```
|
|
|
|
หรือ
|
|
|
|
```
|
|
Review Note
|
|
```
|
|
|
|
หรือ
|
|
|
|
```
|
|
หมายเหตุการตรวจสอบ
|
|
```
|
|
|
|
หากไม่มีการตรวจสอบ Permission
|
|
|
|
ให้เพิ่ม
|
|
|
|
```
|
|
isAdmin
|
|
```
|
|
|
|
หรือ
|
|
|
|
```
|
|
hasPermission(...)
|
|
```
|
|
|
|
ก่อน Render
|
|
|
|
ตัวอย่าง
|
|
|
|
```
|
|
{isAdmin && announcement.review_note && (
|
|
<ReviewNote />
|
|
)}
|
|
```
|
|
|
|
---
|
|
|
|
## 5. ตรวจสอบ Component ที่ใช้ร่วมกัน
|
|
|
|
หาก Admin และ User ใช้ Component เดียวกัน
|
|
|
|
ให้พิจารณา
|
|
|
|
Option A
|
|
|
|
แยกเป็น
|
|
|
|
AnnouncementAdminDetail
|
|
|
|
AnnouncementPublicDetail
|
|
|
|
หรือ
|
|
|
|
Option B
|
|
|
|
ส่ง prop
|
|
|
|
```
|
|
showReviewSection
|
|
```
|
|
|
|
เช่น
|
|
|
|
```
|
|
<AnnouncementDetail
|
|
announcement={announcement}
|
|
showReviewSection={isAdmin}
|
|
/>
|
|
```
|
|
|
|
ภายใน
|
|
|
|
```
|
|
{showReviewSection && (
|
|
...
|
|
)}
|
|
```
|
|
|
|
---
|
|
|
|
## 6. ตรวจสอบทุกหน้าที่เกี่ยวข้อง
|
|
|
|
ตรวจสอบ
|
|
|
|
- Dashboard ล่าสุด
|
|
- Announcement Detail
|
|
- Announcement List
|
|
- Search Result
|
|
- Notification เปิดประกาศ
|
|
|
|
ว่ามีการแสดง
|
|
|
|
Review Note
|
|
|
|
หรือ
|
|
|
|
Workflow
|
|
|
|
โดยไม่ตรวจสอบสิทธิ์หรือไม่
|
|
|
|
---
|
|
|
|
## 7. ตรวจสอบ Serializer / Mapper
|
|
|
|
หากมี
|
|
|
|
```
|
|
mapAnnouncement()
|
|
```
|
|
|
|
หรือ
|
|
|
|
```
|
|
toDto()
|
|
```
|
|
|
|
ตรวจสอบว่าไม่ได้ Mapping
|
|
|
|
```
|
|
review_note
|
|
```
|
|
|
|
ไปยัง Public DTO
|
|
|
|
---
|
|
|
|
## 8. ตรวจสอบ Database Query
|
|
|
|
หากใช้ Prisma
|
|
|
|
ตัวอย่าง
|
|
|
|
```
|
|
select:
|
|
```
|
|
|
|
ให้เลือกเฉพาะ Field ที่จำเป็น
|
|
|
|
ไม่ใช้
|
|
|
|
```
|
|
include: true
|
|
```
|
|
|
|
หรือ
|
|
|
|
```
|
|
select *
|
|
```
|
|
|
|
โดยไม่จำเป็น
|
|
|
|
เพื่อลดการส่งข้อมูลที่ไม่ควรออกจาก Server
|
|
|
|
---
|
|
|
|
# สิ่งที่ต้องแก้ไข
|
|
|
|
Backend
|
|
|
|
- แยก Public DTO
|
|
- ตัดข้อมูล Review ออกจาก Public API
|
|
- ตรวจสอบ Permission ก่อน Response
|
|
- จำกัด Select เฉพาะ Field ที่จำเป็น
|
|
|
|
Frontend
|
|
|
|
- ซ่อน Section Review สำหรับ User
|
|
- Render ตาม Permission
|
|
- แยก Component หากเหมาะสม
|
|
|
|
Architecture
|
|
|
|
- แยกข้อมูล Public และ Internal
|
|
- ลดการส่งข้อมูลเกินความจำเป็น
|
|
- ปรับโครงสร้างให้รองรับการขยาย Workflow ในอนาคต
|
|
|
|
---
|
|
|
|
# Acceptance Criteria
|
|
|
|
✅ ผู้ใช้งานทั่วไปไม่เห็น
|
|
|
|
- หมายเหตุการตรวจสอบ
|
|
- ความคิดเห็นผู้อนุมัติ
|
|
- Reviewer
|
|
- Workflow
|
|
- Audit
|
|
- Reject Reason
|
|
- Approval History
|
|
|
|
✅ HRD/Admin ยังเห็นข้อมูลทั้งหมดได้ตามสิทธิ์
|
|
|
|
✅ Public API ไม่ส่งข้อมูล Review อีกต่อไป
|
|
|
|
✅ Frontend ไม่มีการ Render ข้อมูล Review สำหรับ User
|
|
|
|
✅ ไม่มี Regression กับหน้าประกาศอื่น
|
|
|
|
✅ ผ่าน TypeScript และ ESLint
|
|
|
|
✅ ไม่กระทบ Workflow เดิม
|
|
|
|
---
|
|
|
|
# ผลลัพธ์ที่ต้องการจาก AI
|
|
|
|
1. วิเคราะห์สาเหตุที่แท้จริงของปัญหา
|
|
2. ระบุไฟล์ที่ต้องแก้ไขทั้งหมด
|
|
3. แก้ไข Backend และ Frontend
|
|
4. ปรับ Permission Logic ให้ถูกต้อง
|
|
5. ปรับ DTO/Mapper/Serializer
|
|
6. ปรับ Component ที่เกี่ยวข้อง
|
|
7. ตรวจสอบทุกหน้าที่ใช้รายละเอียดประกาศ
|
|
8. สรุปรายการไฟล์ที่แก้ไข
|
|
9. อธิบายเหตุผลของการแก้ไขแต่ละจุด
|
|
10. ยืนยันว่าไม่มีข้อมูลภายในของ Workflow หลุดไปยังผู้ใช้งานทั่วไปอีก
|