# Auto Refresh Implementation Report

## 1. Executive Summary

Implemented a shared TanStack Query invalidation layer for CRUD and workflow mutations that affect multiple dashboard modules. The change keeps existing URL search params, filters, sorting, pagination, dialogs, and route-handler architecture intact while making related client-side caches stale after successful actions.

## 2. Modules Audited

- Users
- Employees
- Employee Directory
- Courses
- Training Records
- Training Record Reviews
- Training Record Certificates
- Training Matrix
- Online Lessons
- Announcements
- Training Policies
- Permission Management
- Employee Import and Master Review
- Organizers
- Notifications
- Products legacy feature

## 3. Problems Found

- Several mutations invalidated only their own feature list even when the action changed data used by other pages.
- Certificate upload/delete refreshed the certificate list but not the training record detail/list cache that can show certificate preview data.
- Course mutations refreshed Course Master but not course option consumers used by training records and matrix screens.
- People mutations refreshed users or employees separately, but related directory, permission, and training-record option caches could remain stale.
- Content workflow actions could create notifications while only refreshing the content module.

## 4. Root Causes

- Cache invalidation lived inside each feature mutation file with no shared dependency map.
- Query keys were consistent, but related keys were not grouped by domain.
- The app uses server-prefetch plus hydrated TanStack Query; after a client mutation, stale hydrated data needs explicit query invalidation.

## 5. Files Changed

- `src/lib/query-invalidation.ts`
  - Added shared invalidation helpers grouped by domain: people, courses, training records, training matrix, content workflow, permissions, organizers, imports, and policies.
  - Reason: centralizes related cache dependencies without introducing a new library or changing page architecture.
  - Impact: mutations can refresh all affected query groups consistently.
  - Test: lint and TypeScript compile.

- `src/features/users/api/mutations.ts`
  - Switched create/update/delete to `invalidatePeopleData()`.
  - Reason: user changes affect users, employee-facing selectors, directory consumers, and permission assignment screens.
  - Impact: user-related pages update after CRUD.
  - Test: lint and TypeScript compile.

- `src/features/employees/api/mutations.ts`
  - Switched create/update/delete to `invalidatePeopleData()`.
  - Reason: employee changes affect Employee Directory and training-record participant options.
  - Impact: employee data consumers refresh after employee CRUD.
  - Test: lint and TypeScript compile.

- `src/features/courses/api/mutations.ts`
  - Switched create/update/delete to `invalidateCourseData()`.
  - Reason: course changes affect Course Master, training-record course options, and matrix option/compliance consumers.
  - Impact: course selectors and matrix-dependent data are refreshed after course CRUD.
  - Test: lint and TypeScript compile.

- `src/features/training-records/api/mutations.ts`
  - Switched create/update/delete/import to `invalidateTrainingRecordData()`.
  - Reason: training records affect record lists, employee directory summaries, and training matrix compliance.
  - Impact: list and related summaries refresh after record actions.
  - Test: lint and TypeScript compile.

- `src/features/training-records/api/review-mutations.ts`
  - Added related training record invalidation plus detail invalidation for the reviewed record.
  - Reason: review actions affect pending/approved lists and the detail page.
  - Impact: pending review and training record views refresh after review actions.
  - Test: lint and TypeScript compile.

- `src/features/training-records/api/certificate-mutations.ts`
  - Added record list/detail invalidation alongside certificate list invalidation.
  - Reason: certificate changes can affect preview data shown on record views.
  - Impact: attachment and record UI update together.
  - Test: lint and TypeScript compile.

- `src/features/training-matrix/api/mutations.ts`
  - Switched create/update/delete to `invalidateTrainingMatrixData()`.
  - Reason: matrix target changes affect matrix pages, employee target summaries, and training-record compliance consumers.
  - Impact: matrix-related screens update after matrix CRUD.
  - Test: lint and TypeScript compile.

- `src/features/employee-directory/api/mutations.ts`
  - Added matrix/record related invalidation after target upsert while keeping target detail invalidation.
  - Reason: employee target edits affect matrix compliance and employee-directory views.
  - Impact: target detail and related summaries refresh after save.
  - Test: lint and TypeScript compile.

- `src/features/online-lessons/api/mutations.ts`
  - Added content workflow invalidation for lesson CRUD/workflow actions.
  - Reason: lesson submit/publish/delete can affect lesson lists/details and notifications.
  - Impact: content and notification data refresh after lesson actions.
  - Test: lint and TypeScript compile.

- `src/features/announcements/api/mutations.ts`
  - Added content workflow invalidation for announcement CRUD, workflow, pin, and unpin actions.
  - Reason: announcement actions can affect lists/details and notifications.
  - Impact: announcement and notification data refresh after content actions.
  - Test: lint and TypeScript compile.

- `src/features/training-policy/api/mutations.ts`
  - Switched policy actions to `invalidateTrainingPolicyData()`.
  - Reason: policy changes may affect matrix-related policy views.
  - Impact: policy and related matrix data refresh after policy actions.
  - Test: lint and TypeScript compile.

- `src/features/import-employees/api/mutations.ts`
  - Switched import/review actions to `invalidateEmployeeImportData()`.
  - Reason: imports and master review can change employees, directory data, and participant options.
  - Impact: employee-facing data refreshes after import and review actions.
  - Test: lint and TypeScript compile.

- `src/features/organizers/api/mutations.ts`
  - Switched organizer CRUD to `invalidateOrganizerData()`.
  - Reason: organizer changes can affect user/employee organization context data.
  - Impact: organizer and related people data refresh after organizer actions.
  - Test: lint and TypeScript compile.

- `src/features/permission-management/api/mutations.ts`
  - Switched template and user-permission mutations to `invalidatePermissionData()` plus user detail invalidation where needed.
  - Reason: permission mutations affect template/catalog/user/audit views and user lists.
  - Impact: permission screens update more consistently after save/clone/activate/deactivate/delete.
  - Test: lint and TypeScript compile.

- `src/features/products/api/mutations.ts`
  - Added product detail invalidation after update.
  - Reason: legacy detail view can otherwise show stale data after update.
  - Impact: product detail cache refreshes after update.
  - Test: lint and TypeScript compile.

## 6. Refresh Strategy by Module

- People data: invalidate users, employees, employee directory, training-record user options, and permission-management users.
- Course data: invalidate courses, training-record course options, training matrix options, and training matrix lists.
- Training record data: invalidate training records, employee directory, and training matrix compliance.
- Training matrix data: invalidate matrix, employee directory, and training record data.
- Content workflow data: invalidate announcements, online lessons, and notifications.
- Permission data: invalidate permission-management root keys and users.
- Import data: invalidate master review, employees, employee directory, and training-record user options.
- Organizer data: invalidate organizers, users, employees, and employee directory.
- Training policy data: invalidate training policies and training matrix.

## 7. Cache Keys Updated

- `['users']`
- `['employees']`
- `['employee-directory']`
- `['courses']`
- `['training-records']`
- `['training-records', 'course-options']`
- `['training-records', 'user-options']`
- `['training-matrix']`
- `['announcements']`
- `['online-lessons']`
- `['notifications']`
- `['permission-management']`
- `['master-review']`
- `['organizers']`
- `['training-policies']`
- `['products']`

## 8. Pagination Handling

Existing pagination, search, filter, and sort state remains URL-driven through current table components and `nuqs`. The implementation invalidates query prefixes instead of rewriting search params, so existing table state is preserved.

## 9. Related Data Revalidation

Related data is now grouped by domain in `src/lib/query-invalidation.ts`. Mutations call the relevant domain helper rather than refreshing only the immediate feature.

## 10. Full Page Reloads Removed

No `window.location.reload()` usage was found in the audited app code. Existing `router.refresh()` calls remain only where the surrounding component/page still uses server component refresh behavior after a mutation.

## 11. Test Results

- `npm run lint -- src/lib/query-invalidation.ts ...`: passed.
- `npx tsc --noEmit --pretty false`: passed.

## 12. Remaining Risks

- Some server-rendered dashboard summary/report widgets may use direct server data without a client query key; those still depend on navigation or `router.refresh()` unless migrated to TanStack Query.
- The current working tree already had unrelated edits in `src/app/dashboard/courses/page.tsx` and `src/features/courses/components/course-tables/columns.tsx`; this implementation did not revert or normalize those changes.
- Manual browser testing was not completed in this pass.

## 13. Recommendations

- Add query keys for dashboard/report summary widgets if they need live client refresh after related mutations.
- Keep future mutation files thin by using the shared domain invalidation helpers instead of adding one-off invalidate lists.
- Add a small integration test for high-risk flows: training record review, certificate upload/delete, course create/update, and employee import review.
