# Sprint 5 Review: Employee Import, Master Review, and Thai UI Localization ## 1. Summary - Added the HRD-only Employee Import page at `/dashboard/import-employees`. - Added Excel template download and `.xlsx` import flow. - Added row validation, duplicate detection, and Thai import result summary. - Imported employee runtime data into existing `users` and `memberships` tables. - Added the HRD-only Master Review page at `/dashboard/master-review`. - Added pending review handling for: - companies - departments - positions - Added approve/reject actions for pending master data. - Converted visible TMS UI text in the implemented modules and shared dashboard surfaces to Thai. - Centralized repeated Thai labels in `src/constants/thai-labels.ts`. ## 2. Files changed ### Employee Import - `src/app/api/import-employees/route.ts` - `src/app/api/import-employees/template/route.ts` - `src/app/dashboard/import-employees/page.tsx` - `src/app/dashboard/import-employees/loading.tsx` - `src/app/dashboard/import-employees/error.tsx` - `src/features/import-employees/api/types.ts` - `src/features/import-employees/api/service.ts` - `src/features/import-employees/api/queries.ts` - `src/features/import-employees/api/mutations.ts` - `src/features/import-employees/components/employee-import-page.tsx` ### Master Review - `src/app/api/master-review/route.ts` - `src/app/dashboard/master-review/page.tsx` - `src/app/dashboard/master-review/loading.tsx` - `src/app/dashboard/master-review/error.tsx` - `src/features/import-employees/components/master-review-page.tsx` ### Thai localization and shared UI - `src/constants/thai-labels.ts` - `src/lib/api-client.ts` - `src/config/nav-config.ts` - `src/components/layout/app-sidebar.tsx` - `src/components/layout/user-nav.tsx` - `src/components/org-switcher.tsx` - `src/components/search-input.tsx` - `src/components/modal/alert-modal.tsx` - `src/components/ui/table/data-table.tsx` - `src/components/ui/table/data-table-pagination.tsx` - `src/components/ui/table/data-table-toolbar.tsx` ### Training records and pending review localization - `src/app/dashboard/training-records/loading.tsx` - `src/app/dashboard/training-records/[trainingRecordId]/review/page.tsx` - `src/app/dashboard/training-records/[trainingRecordId]/review/loading.tsx` - `src/app/dashboard/training-records/[trainingRecordId]/review/error.tsx` - `src/app/dashboard/pending-review/page.tsx` - `src/app/dashboard/pending-review/loading.tsx` - `src/app/dashboard/pending-review/error.tsx` - `src/features/training-records/constants/training-record-options.ts` - `src/features/training-records/schemas/training-record.ts` - `src/features/training-records/components/pending-review-columns.tsx` - `src/features/training-records/components/pending-review-table.tsx` - `src/features/training-records/components/training-record-form.tsx` - `src/features/training-records/components/training-record-review-form.tsx` - `src/features/training-records/components/training-record-review-page.tsx` - `src/features/training-records/components/training-record-certificate-manager.tsx` - `src/features/training-records/components/training-record-tables/columns.tsx` - `src/features/training-records/components/training-record-tables/index.tsx` - `src/features/training-records/components/training-record-view-page.tsx` ### Courses, reports, overview, and training policy localization - `src/app/dashboard/courses/page.tsx` - `src/app/dashboard/courses/loading.tsx` - `src/app/dashboard/courses/error.tsx` - `src/app/dashboard/reports/page.tsx` - `src/app/dashboard/reports/loading.tsx` - `src/app/dashboard/reports/error.tsx` - `src/app/dashboard/training-policy/page.tsx` - `src/app/dashboard/training-policy/loading.tsx` - `src/app/dashboard/training-policy/error.tsx` - `src/app/dashboard/overview/layout.tsx` - `src/app/dashboard/overview/error.tsx` - `src/features/courses/components/course-form.tsx` - `src/features/courses/components/course-tables/columns.tsx` - `src/features/overview/server/overview-data.ts` - `src/features/overview/components/bar-graph.tsx` - `src/features/overview/components/area-graph.tsx` - `src/features/overview/components/pie-graph.tsx` - `src/features/overview/components/recent-sales.tsx` - `src/features/reports/components/report-table-card.tsx` - `src/features/reports/components/reports-page-content.tsx` - `src/features/reports/server/report-data.ts` - `src/features/training-policy/components/training-policy-form.tsx` - `src/features/training-policy/components/training-policy-page.tsx` ### Dependency change - `package.json` - lockfile updated by `npm install xlsx` ## 3. Database changes - No schema migration was added in Sprint 5. - No table names were changed. - No column names were changed. - Employee import reuses existing runtime tables: - `users` - `memberships` - Master review reuses existing flags and master tables: - `organizations.pending_master_review` - `departments.pending_master_review` - `positions.pending_master_review` ## 4. Routes added - `POST /api/import-employees` - `GET /api/import-employees/template` - `GET /api/master-review` - `PATCH /api/master-review` - `/dashboard/import-employees` - `/dashboard/master-review` ## 5. Thai localization changes - Sidebar labels changed to Thai. - Page titles and descriptions changed to Thai. - Form labels and placeholders changed to Thai. - Table headers and filter labels changed to Thai. - Buttons and action labels changed to Thai. - Status badges changed to Thai. - Toast messages changed to Thai. - Validation messages changed to Thai. - Empty, loading, and error states changed to Thai. - Dashboard overview cards and chart labels changed to Thai. - CSV export headers changed to Thai. - Import template headers changed to Thai. ## 6. Label mapping added - Added central mapping file: `src/constants/thai-labels.ts` - Reused helper functions: - `getTrainingStatusLabel()` - `getTrainingTypeLabel()` - `getTrainingCategoryLabel()` - `getRoleLabel()` - `getActiveStatusLabel()` - Added Thai import template header constants and import status normalization. ## 7. Import template format Required Thai headers: 1. `รหัสพนักงาน` 2. `ชื่อพนักงาน` 3. `อีเมล` 4. `บริษัท` 5. `แผนก` 6. `ตำแหน่ง` 7. `สถานะ` Supported file type: - `.xlsx` Supported status values: - `ใช้งาน` - `ไม่ใช้งาน` - `active` - `inactive` ## 8. Validation rules ### Employee import - File is required. - File must be `.xlsx`. - Worksheet must exist. - File must contain rows. - Headers must match the Thai template headers. - Required fields per row: - employee code - employee name - company - department - position - status - Email is optional, but when present it must be valid. - Duplicate employee codes in the same file are rejected. - Duplicate emails in the same file are rejected. - Status must normalize to active or inactive. ### Training record review localization - Approved hours must be at least `0.5`. - Reject reason is required when rejecting. - Thai validation messages are returned through the existing form flow. ## 9. Permission rules - Employee Import page and APIs require HRD access through existing Auth.js session helpers. - Master Review page and APIs require HRD access through existing Auth.js session helpers. - Employee users cannot access `/dashboard/import-employees`. - Employee users cannot access `/dashboard/master-review`. - Imported records stay scoped to the active organization. - Master review approve/reject updates are scoped to the active organization. ## 10. Manual test checklist - [ ] HRD can open Employee Import page. - [ ] Employee cannot open Employee Import page. - [ ] HRD can download Thai Excel template. - [ ] HRD can upload employee Excel. - [ ] System validates required fields. - [ ] System shows import result in Thai. - [ ] New company/department/position becomes pending master review. - [ ] HRD can open Master Review page. - [ ] HRD can approve pending master data. - [ ] HRD can reject pending master data. - [ ] Sidebar menu is displayed in Thai. - [ ] Training status badges are displayed in Thai. - [ ] Training type labels are displayed in Thai. - [ ] Form validation messages are displayed in Thai. - [ ] Toast messages are displayed in Thai. - [ ] Dashboard labels are displayed in Thai. - [ ] Existing routes still work. ## 11. Known limitations - There is no dedicated company master table in the current schema. - Company review is therefore handled by comparing imported `users.company_name` values against the active organization name. - Approving a pending company updates `organizations.name` for the active organization. - Rejecting a pending company normalizes affected imported users back to the current organization name. - Imported users are created with generated password hashes so the runtime user row is valid, but credential onboarding or password reset flow is still a separate operational step. - Employee import currently supports `.xlsx` only; `.xls` and `.csv` are not included in this sprint. ## 12. Next recommended sprint - Add audit log entries for employee import and master review actions. - Add import history detail page from `import_jobs`. - Add downloadable error report for failed import rows. - Add a dedicated company master entity if company approval becomes a first-class workflow. - Complete Thai localization for remaining non-TMS template/demo pages if those pages will stay in active use. ## 13. Migration command - No new database migration is required for Sprint 5. - If your environment has not installed the new Excel dependency yet, run: ```bash npm install ```