Files
familysync/.planning/milestones/v1.0-phases/06-ux-polish/06-01-SUMMARY.md
T
Lucas Berger 982438dc10 style(13-03): apply Prettier formatting across repo
Mechanical reformat — no logic changes. 398 files changed, 19125
insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc
(singleQuote:true, semi:true, tabWidth:2, trailingComma:all,
printWidth:100). Isolated per D-13-08 for reviewability.
2026-06-11 20:35:18 -04:00

4.4 KiB

phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
06-ux-polish 01 pwa/lib
tdd
date-math
event-form
d-04
requires provides affects
computeNewTimedEnd (apps/pwa/src/lib/eventDateTime.ts)
computeNewAllDayEnd (apps/pwa/src/lib/eventDateTime.ts)
Plan 06-06 (EventForm wires these helpers into onChange handlers)
added patterns
Local Date accessors (WR-05)
getFullYear/getMonth/getDate/getHours/getMinutes — never toISOString().slice
TDD RED→GREEN with Vitest in apps/pwa
created modified
apps/pwa/src/lib/eventDateTime.ts
apps/pwa/src/lib/eventDateTime.test.ts
WR-05 enforced
all new date formatting uses local accessors; toISOString().slice banned for date strings
Private helpers (localDateISO, localTimeHHMM, dateDiffDays, addDaysISO) added to eventDateTime.ts to support the two exports
duration_minutes completed_date tasks_completed files_changed
2 2026-06-10 2 2

Phase 06 Plan 01: End-Tracking Duration Math (D-04) Summary

One-liner: Pure duration-preservation helpers (computeNewTimedEnd + computeNewAllDayEnd) with 1h/same-day floor rules, TDD RED→GREEN in eventDateTime.ts.

Tasks Completed

Task Name Commit Files
1 (RED) Failing tests for computeNewTimedEnd / computeNewAllDayEnd 16cdbf3 eventDateTime.test.ts
2 (GREEN) Implement the two end-tracking helpers 605f543 eventDateTime.ts

What Was Built

Two exported pure functions added to apps/pwa/src/lib/eventDateTime.ts:

  • computeNewTimedEnd(newStartDate, newStartTime, oldStartDate, oldStartTime, oldEndDate, oldEndTime) — preserves a timed event's duration when the start moves. Returns { endDate: 'YYYY-MM-DD', endTime: 'HH:MM' }. If the old end was already behind the old start (stale state), floors to newStart + 1 hour.
  • computeNewAllDayEnd(newStartDate, oldStartDate, oldEndDate) — preserves an all-day event's inclusive day-span when the start moves. Returns 'YYYY-MM-DD'. If the old span was negative (stale state), floors to 0 days (same day as newStart).

Four private helpers added to the same file: localDateISO, localTimeHHMM, dateDiffDays, addDaysISO. All use local Date accessors (WR-05 compliance).

Test Coverage

Six new unit tests in apps/pwa/src/lib/eventDateTime.test.ts:

Test Behavior
preserves a 1-hour timed delta old 09:00→10:00; new start 11:00 → new end 12:00
preserves a multi-day timed delta (26h) old 08:00→+26h; new start same offset → correct
floors to 1h when old end was behind start stale end → snaps to newStart+1h
preserves a 0-day span (single day all-day) oldStart=oldEnd → newEnd=newStart
preserves a 3-day span newEnd = newStart + 3 days
floors to same day when old end behind start negative span → 0 → same day

Full suite: 166/166 tests pass. Pre-existing serializeEventDateTime / localWallClockToUtcIso tests unaffected.

TDD Gate Compliance

  • RED commit (test(06-01): ...): 16cdbf3 — 6 tests failing with TypeError: computeNewTimedEnd is not a function
  • GREEN commit (feat(06-01): ...): 605f543 — all 166 tests pass
  • RED→GREEN order confirmed via git log

Deviations from Plan

None — plan executed exactly as written.

Threat Flags

None. Pure client-side date arithmetic on already-trusted local form state. No network boundary, no new attack surface. T-06-01 accepted per threat model.

Self-Check: PASSED

  • apps/pwa/src/lib/eventDateTime.ts — FOUND (modified)
  • apps/pwa/src/lib/eventDateTime.test.ts — FOUND (modified)
  • Commit 16cdbf3 — FOUND (RED: test(06-01))
  • Commit 605f543 — FOUND (GREEN: feat(06-01))
  • computeNewTimedEnd export — FOUND in eventDateTime.ts
  • computeNewAllDayEnd export — FOUND in eventDateTime.ts
  • No toISOString().slice in helper code — CONFIRMED