This commit is contained in:
2026-07-16 09:53:14 +07:00
parent 0fc112a2e8
commit 29cec708a3
1236 changed files with 212848 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
# Management Change Duration Minutes Review
## 1. Summary
This round starts the migration of training duration handling from decimal hours to total minutes with backward compatibility. The core `training-records` create/edit/review flow now accepts minute-based values, stores both minute and legacy decimal fields, and displays Thai duration text in the main training record UI.
## 2. Database Changes
Added new nullable minute-based fields:
- `training_records.submitted_minutes`
- `training_records.approved_minutes`
- `training_policies.total_target_minutes`
- `training_policies.k_target_minutes`
- `training_policies.s_target_minutes`
- `training_policies.a_target_minutes`
- `employee_training_targets.total_target_minutes`
- `employee_training_targets.k_target_minutes`
- `employee_training_targets.s_target_minutes`
- `employee_training_targets.a_target_minutes`
Migration file:
- `drizzle/0012_change_duration_minutes.sql`
## 3. Migration Strategy
The migration keeps legacy decimal columns and backfills new minute columns using:
- `ROUND(hours * 60)`
- `ROUND(approved_hours * 60)`
- `ROUND(total_hours * 60)`
- `ROUND(k_hours * 60)`
- `ROUND(s_hours * 60)`
- `ROUND(a_hours * 60)`
This allows old code paths to keep working while new UI/API paths move to minutes.
## 4. Duration Picker UI
Added:
- `src/components/ui/duration-picker.tsx`
Behavior:
- two dropdowns: `ชั่วโมง` and `นาที`
- hour range `00` to `30`
- minute step `00`, `15`, `30`, `45`
- no AM/PM
- no `Date` storage
- helper display in `HH:MM`
## 5. Storage Behavior
Updated the training record flow so that:
- form submit sends `submittedMinutes`
- review submit sends `approvedMinutes`
- route handlers write new minute fields
- route handlers still write decimal `hours` and `approved_hours` for compatibility
The compatibility helper is:
- `getDurationMinutes(minutesField, legacyHoursField)`
## 6. Display Formatting
Added shared helpers in:
- `src/features/training-records/utils/time-utils.ts`
Helpers:
- `formatDurationThai(minutes)`
- `formatDurationHHMM(minutes)`
- `decimalHoursToMinutes(hours)`
- `minutesToDecimalHours(minutes)`
- `getDurationMinutes(minutesField, legacyHoursField)`
Main updated displays:
- training record form
- training record review page
- training record table
- pending review table
## 7. Dashboard Impact
Not fully migrated yet.
Current state:
- the training record source data now exposes `submitted_minutes` and `approved_minutes`
- dashboard aggregate logic in `src/features/overview/server/overview-data.ts` still sums legacy decimal hour columns
Required next step:
- switch aggregate expressions to minute-first calculations with decimal fallback only when minute fields are null
## 8. Reports Impact
Not fully migrated yet.
Current state:
- training record API now exposes minute fields
- report dataset and exports still primarily rely on decimal hour aggregations
Required next step:
- update `src/features/reports/server/report-data.ts` and export formatters to sum/display minutes consistently
## 9. Backward Compatibility
Compatibility is preserved by:
- keeping old decimal DB columns
- still writing `hours` / `approved_hours`
- deriving minute display from minute columns first, then decimal fallback
This reduces breakage during staged migration.
## 10. Manual Test Checklist
- [ ] `00:15` saves `15` minutes.
- [ ] `01:45` saves `105` minutes.
- [ ] `02:00` saves `120` minutes.
- [ ] `30:00` saves `1800` minutes.
- [ ] `00:00` is blocked.
- [ ] More than `30:00` is blocked.
- [ ] Training history shows `1 ชั่วโมง 45 นาที`.
- [ ] Dashboard sums minutes correctly.
- [ ] Reports export minutes correctly.
- [ ] Legacy decimal hours still display correctly.
- [ ] No AM/PM appears anywhere.
## 11. Known Limitations
- Overview, reports, employee directory, notifications, and audit log text are not fully migrated to minute-first calculations yet.
- Training policy and employee target UI still use hour-based contracts even though DB minute columns are prepared.
- Export Excel/PDF paths were not updated in this round.