143 lines
4.0 KiB
Markdown
143 lines
4.0 KiB
Markdown
# 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.
|