1
Endpoint
POST /:publicId/save
Stub
Logic hiện tại
return void — no-op
0
Bảng DB
chưa có bảng SavedPost
0
API lấy saved
chưa có endpoint list
User Perspective
Lưu
Nhấn nút "Lưu" (bookmark icon) trên bài viết → bài được thêm vào danh sách "Bài đã lưu". Nhấn lại → bỏ lưu.
Xem
Vào trang cá nhân → tab "Đã lưu" → xem danh sách bài đã bookmark, sắp xếp theo thời gian lưu.
Riêng tư
Danh sách bài đã lưu chỉ mình người dùng nhìn thấy. Không ai khác biết bạn lưu bài nào.
Proposed Implementation Flow
Đường đứt nét = chưa implement. Hiện tại postService.save() trả về void (no-op).
Implementation Checklist
| # |
Task |
Mô tả chi tiết |
Trạng thái |
| 01 |
Route + Controller POST /:publicId/save
|
Route đã có, controller gọi postService.save() rồi trả { saved: true }. Nhưng service chỉ return void. |
stub |
| 02 |
Tạo bảng SavedPost Prisma migration |
Bảng mới: SavedPost { id, userId, postId, createdAt }. Unique constraint trên (userId, postId) để tránh lưu trùng. |
todo |
| 03 |
Toggle save logic Service layer |
Kiểm tra bài tồn tại → check đã save chưa → nếu chưa thì INSERT, nếu rồi thì DELETE (toggle). |
todo |
| 04 |
API lấy bài đã lưu GET /posts/me/saved
|
Endpoint mới: trả danh sách bài đã lưu của user hiện tại, cursor pagination, sắp xếp theo thời gian lưu. |
todo |
| 05 |
Check isSaved trong feed Feed mapper |
Khi lấy news feed / bài viết, check xem user hiện tại đã save chưa → trả thêm field isSaved: boolean. |
todo |
Implementation Progress
✅ Đã có (sườn)
Route POST /:publicId/save đã đăng ký
Controller gọi service và trả response
Service method save() tồn tại (nhưng no-op)
⏳ Cần implement
Tạo Prisma model SavedPost + migration
Repository: toggle save/unsave
Service: logic check + toggle
Endpoint GET /posts/me/saved
Feed mapper: thêm field isSaved
Design Notes
Toggle
Nên dùng 1 endpoint toggle (giống like) thay vì 2 endpoint save/unsave riêng. FE chỉ cần gọi 1 API.
Riêng tư
Danh sách saved là private. Không ai ngoài chủ account nhìn thấy. Không có API public cho việc này.
Approach
Có thể dùng DB thuần (Prisma) vì save ít tần suất hơn like. Không cần Redis layer cho feature này.