# Announcement Pin Action Enhancement Report

## 1. Existing Structure Review

- Reused the existing `announcements` feature structure under `src/features/announcements/` with the current `api/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.ts` for publish/archive gating.
- Reused the existing audit infrastructure in `src/features/audit-logs/server/audit-service.ts` and `src/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.ts`
- `src/features/announcements/api/service.ts`
- `src/features/announcements/api/mutations.ts`
- `src/features/announcements/schemas/announcement.ts`
- `src/features/announcements/components/announcement-form.tsx`
- `src/features/announcements/components/announcements-page.tsx`
- `src/features/announcements/components/announcement-view-page.tsx`
- `src/features/announcements/server/announcement-data.ts`
- `src/features/announcements/lib/pin.ts`
- `src/app/api/announcements/route.ts`
- `src/app/api/announcements/[id]/route.ts`
- `src/app/api/announcements/[id]/pin/route.ts`
- `src/app/api/announcements/[id]/unpin/route.ts`
- `src/features/audit-logs/server/audit-service.ts`
- `src/features/audit-logs/server/audit-log-data.ts`
- `src/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:publish` as the permission for managing pin/unpin actions.
- Client-side checks use `canManageAnnouncementPin(...)` to hide unavailable actions.
- Server-side checks in `/api/announcements/[id]/pin` and `/api/announcements/[id]/unpin` enforce the same permission and eligibility rules.

## 6. Database and API Changes

- No schema migration was added because the existing `isPin` field already supports the feature.
- Create now defaults pin state to `false`.
- Create/edit payloads no longer send `isPin` from the form.
- Added dedicated endpoints:
  - `POST /api/announcements/:id/pin`
  - `POST /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: `lint` and `build` should 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_pin` when announcements expire, not only filter them out.
- Add a dedicated `announcement:pin` permission if pin management needs to diverge from publish authority later.
- Consider a dropdown action menu if the announcement action area grows further.
