4.4 KiB
4.4 KiB
Announcement Pin Action Enhancement Report
1. Existing Structure Review
- Reused the existing
announcementsfeature structure undersrc/features/announcements/with the currentapi/service/mutations/types, route handlers, React Query, and form workflow. - Reused the existing database field
isPin/is_pin; no new pin table or parallel state model was introduced. - Reused the current content workflow helpers from
src/features/content-approval/lib/workflow.tsfor publish/archive gating. - Reused the existing audit infrastructure in
src/features/audit-logs/server/audit-service.tsandsrc/features/audit-logs/server/audit-log-data.ts. - Extended the existing announcements list/detail UI instead of creating a new action framework.
- Refactored create/edit form behavior so pin state is no longer part of form submission.
2. Files Changed
src/features/announcements/api/types.tssrc/features/announcements/api/service.tssrc/features/announcements/api/mutations.tssrc/features/announcements/schemas/announcement.tssrc/features/announcements/components/announcement-form.tsxsrc/features/announcements/components/announcements-page.tsxsrc/features/announcements/components/announcement-view-page.tsxsrc/features/announcements/server/announcement-data.tssrc/features/announcements/lib/pin.tssrc/app/api/announcements/route.tssrc/app/api/announcements/[id]/route.tssrc/app/api/announcements/[id]/pin/route.tssrc/app/api/announcements/[id]/unpin/route.tssrc/features/audit-logs/server/audit-service.tssrc/features/audit-logs/server/audit-log-data.tssrc/features/audit-logs/constants/audit-log-options.ts
3. UI Changes
- Removed the pin checkbox/section from both create and edit announcement forms.
- Added pin status badge on announcement list cards and detail header.
- Added pin/unpin actions to the announcement list action area.
- Added pin/unpin actions to the announcement detail action area.
- Kept the existing responsive card layout and action button patterns.
4. Business Rules
- Only published announcements that have already started and are not expired can be pinned.
- Archived announcements are automatically unpinned in the existing workflow update route.
- Expired or otherwise ineligible pinned announcements are filtered out from pinned-first behavior and pinned-only filtering.
- Announcement ordering now prioritizes only active pinned announcements instead of every row with
is_pin = true. - Multiple pinned announcements remain supported; ordering among them still follows existing recency ordering.
5. Permission
- Reused
announcement:publishas the permission for managing pin/unpin actions. - Client-side checks use
canManageAnnouncementPin(...)to hide unavailable actions. - Server-side checks in
/api/announcements/[id]/pinand/api/announcements/[id]/unpinenforce the same permission and eligibility rules.
6. Database and API Changes
- No schema migration was added because the existing
isPinfield already supports the feature. - Create now defaults pin state to
false. - Create/edit payloads no longer send
isPinfrom the form. - Added dedicated endpoints:
POST /api/announcements/:id/pinPOST /api/announcements/:id/unpin
- Kept the existing workflow route focused on content state transitions instead of pin state changes.
7. Audit Log
- Added
ANNOUNCEMENT_PINNED - Added
ANNOUNCEMENT_UNPINNED - Added formatted Thai audit messages and filter options for both actions.
8. Testing Result
- Functional: implemented and code-reviewed against the requested workflow.
- Permission: client/server checks were added for restricted pin management.
- Responsive: list/detail changes follow existing flex-wrap action layouts and badge patterns.
- Regression: create/edit/workflow logic was kept on the same route and helper stack, with pin logic isolated into dedicated endpoints.
- Validation status:
lintandbuildshould be used as final verification for this change set.
9. Remaining Improvements
- Add explicit pin priority if the business wants manual ordering among multiple pinned announcements.
- Add optional automatic cleanup to clear
is_pinwhen announcements expire, not only filter them out. - Add a dedicated
announcement:pinpermission if pin management needs to diverge from publish authority later. - Consider a dropdown action menu if the announcement action area grows further.