# Sprint 6.5 Pre-Sprint 7 Hardening Review

## 1. Summary

Sprint 6.5 focused on hardening work only, without adding new business features or changing the current database schema.

This round completed four targeted improvements:

- moved notification pagination and type filtering to SQL/Drizzle query level
- added route-level loading and error coverage for announcement pages
- updated RBAC documentation to match the current Auth.js and server-side authorization model
- created a browser smoke test checklist for Chrome and Microsoft Edge before Sprint 7

The changes were intentionally small in scope and kept existing routes, Auth.js, Drizzle ORM, Thai UI, and current responsive behavior intact.

## 2. Files Changed

- [src/features/notifications/server/notification-data.ts](/d:/WY-2569/HRD/training-system-minimal-refactor/src/features/notifications/server/notification-data.ts)
- [src/app/dashboard/announcements/loading.tsx](/d:/WY-2569/HRD/training-system-minimal-refactor/src/app/dashboard/announcements/loading.tsx)
- [src/app/dashboard/announcements/error.tsx](/d:/WY-2569/HRD/training-system-minimal-refactor/src/app/dashboard/announcements/error.tsx)
- [src/app/dashboard/announcements/[id]/loading.tsx](/d:/WY-2569/HRD/training-system-minimal-refactor/src/app/dashboard/announcements/[id]/loading.tsx)
- [src/app/dashboard/announcements/[id]/error.tsx](/d:/WY-2569/HRD/training-system-minimal-refactor/src/app/dashboard/announcements/[id]/error.tsx)
- [docs/nav-rbac.md](/d:/WY-2569/HRD/training-system-minimal-refactor/docs/nav-rbac.md)

## 3. Issues Fixed

### Fixed 1: Notification pagination was inefficient

Previous behavior:

- loaded all matching notifications
- filtered notification type in memory
- sliced the result in memory for pagination

Current behavior:

- applies ownership, status, search, and type filtering in SQL
- uses `WHERE`, `ORDER BY`, `LIMIT`, and `OFFSET`
- preserves unread count behavior
- keeps the same API contract for notification center and header popover

### Fixed 2: Announcement routes lacked route-level loading and error states

Added route-segment coverage for:

- `/dashboard/announcements`
- `/dashboard/announcements/[id]`

### Fixed 3: RBAC documentation was outdated

The old document referenced Clerk and client-side authorization assumptions that no longer match the repository.

The document now reflects:

- Auth.js
- `proxy.ts`
- `requireOrganizationAccess()`
- `requireHRD()`
- `requireEmployeeDashboardAccess()`
- direct URL protection
- API protection
- protected file download behavior

## 4. Notification Pagination Optimization

Implementation summary:

- replaced in-memory type filtering with SQL clauses
- kept organization and user ownership checks
- preserved:
  - search behavior
  - read/unread filtering
  - notification type filtering
  - unread badge accuracy
- computed `total_notifications` from SQL count instead of filtered array length

Primary file:

- [src/features/notifications/server/notification-data.ts](/d:/WY-2569/HRD/training-system-minimal-refactor/src/features/notifications/server/notification-data.ts)

Behavior impact:

- no API route changes required
- no frontend service contract changes required
- notification center page and header notification popover continue to use the same endpoint

## 5. Announcement Loading/Error Coverage

Added route-level files:

- [src/app/dashboard/announcements/loading.tsx](/d:/WY-2569/HRD/training-system-minimal-refactor/src/app/dashboard/announcements/loading.tsx)
- [src/app/dashboard/announcements/error.tsx](/d:/WY-2569/HRD/training-system-minimal-refactor/src/app/dashboard/announcements/error.tsx)
- [src/app/dashboard/announcements/[id]/loading.tsx](/d:/WY-2569/HRD/training-system-minimal-refactor/src/app/dashboard/announcements/[id]/loading.tsx)
- [src/app/dashboard/announcements/[id]/error.tsx](/d:/WY-2569/HRD/training-system-minimal-refactor/src/app/dashboard/announcements/[id]/error.tsx)

These follow the existing dashboard pattern:

- Thai UI text
- `PageContainer`
- skeleton loading state
- resettable route-level error state
- responsive layout

## 6. RBAC Documentation Update

Updated file:

- [docs/nav-rbac.md](/d:/WY-2569/HRD/training-system-minimal-refactor/docs/nav-rbac.md)

The document now explains:

- navigation filtering is UX only
- Auth.js is the authentication source
- proxy-level route protection
- server-side page guards
- organization-based access rules
- employee vs HRD access model
- API protection model
- direct URL protection
- protected file download routes

## 7. Browser Smoke Test Checklist

Target browsers:

- Chrome
- Microsoft Edge

### Employee checklist

1. Sign in with employee account
2. Open dashboard overview and confirm data loads
3. Create a new training record
4. Upload certificate file
5. Open certificate preview and download/open file
6. Edit a pending training record
7. Delete a pending training record
8. Open notification center and verify notification detail link works
9. Open announcement list and announcement detail

### HRD checklist

1. Sign in with HRD account
2. Open dashboard overview and confirm data loads
3. Open pending review queue
4. Approve a training record
5. Reject a training record
6. Create an announcement
7. Open or download announcement attachment
8. Import employee Excel file
9. Approve and reject pending master review items
10. Open audit logs page
11. Export audit log CSV

### Cross-check expectations

1. No unauthorized page should open by direct URL
2. Employee should not see HRD-only data
3. HRD should be able to access organization-wide review flows
4. Protected certificate and announcement files should open only for authorized users
5. Loading and error states should render cleanly on announcement routes

## 8. Validation Result

Validation completed:

- `npx tsc --noEmit` passed
- `npm run lint` passed with existing non-blocking warnings in unrelated files
- `npm run build` passed

Database:

- no migration required
- no table or column changes made

Routes:

- existing routes remained intact
- production build confirmed these routes compile successfully, including:
  - `/api/notifications`
  - `/dashboard/notifications`
  - `/dashboard/announcements`
  - `/dashboard/announcements/[id]`

## 9. Remaining Risks

1. Browser smoke testing has been documented but not fully executed end-to-end in this hardening task
2. Existing unrelated lint warnings remain in legacy or shared UI files outside this scope
3. Protected file delivery still uses local app storage and process memory, which is acceptable for current scale but should be revisited later if file volume grows

## 10. Sprint 7 Readiness Score

- Sprint 7 Readiness Score: **91/100**

Readiness interpretation:

- the repo is in a stronger state for Sprint 7 development
- the main pre-UAT hardening gaps from Sprint 6 review are addressed
- a short manual smoke pass in Chrome and Edge is still recommended before wider business testing
