Workorder job duration shows unbounded decimal places for partial-hour service combos

Objective

  • Show scheduled job duration on the workorder in a consistent, human-readable form so teams are not confused by long decimal strings (for example 1.8333333333333333h) when services combine to partial hours.
  • Align display across workorder surfaces that surface duration today, without changing scheduling behavior unless product decides stored values should also be normalized.
  • Reduce support friction when modifier-driven time adjustments stack across multiple services on a single job.

Background

  • Product feedback and internal triage confirm the main workorder header can show more than one decimal place (and sometimes floating-point noise) for certain service combinations that yield partial hours.
  • inspection.duration is an optional Number on the inspection document (attik-backend/src/models/inspectionSchema.ts); the backend PATCH path in attik-backend/src/routes/inspection.ts persists whatever number the client sends with no rounding on write.
  • On the workorder shell, attik-frontend/src/app/tools/inspections/[id]/components/InspectionDateChip.tsx renders {inspection.duration}h directly in JSX (lines 30–34) with no display formatting — whatever is stored is stringified as-is.
  • Partial-hour totals are expected when services stack: per-service duration in attik-frontend/src/util/functions/schedulingHelpers/calculateServicePrices.ts sums base hours (duration / durationAsPrimary) plus modifier time from attik-frontend/src/util/functions/data/modifierPriceAdjFn.ts, where time modifiers convert accumulated minutes to hours via / 60 without rounding the per-service result.
  • Rounding is inconsistent across the codebase today:
  • attik-frontend/src/util/functions/inspection/buildDurationEndtimePatch.ts rounds to two decimals when persisting duration + endtime from workorder/reschedule flows.
  • computeTotalJobDurationHours in attik-frontend/src/util/functions/schedulingHelpers/recalculateChargesForRequiredInfo.ts uses round2 (two decimals) when recalculating from required-info changes.
  • Initial job/quote creation paths (for example attik-frontend/src/components/scheduling/NewSchedulingForm.tsx saving priceData.totalDuration) and usePriceCalculation totals do not consistently round before save.
  • Other workorder UI surfaces also differ: attik-frontend/src/app/tools/inspections/[id]/components/WorkorderPriceChangeConfirmModal.tsx shows duration with .toFixed(2), while attik-frontend/src/app/tools/inspections/[id]/components/EditChargesModal.tsx footer shows raw {totalDuration} Hour(s). Reschedule duration inputs use 0.5-hour steps (RescheduleJobModal.tsx, RescheduleManualPanel.tsx) but still display/store whatever number results from calculation.
  • Related narrower issue: ATT-1654 (chip-only display, one-decimal target). This ticket captures the broader rounding/display inconsistency and partial-hour root cause from modifier stacking.

Scope

Frontend

  • Primary display: attik-frontend/src/app/tools/inspections/[id]/components/InspectionDateChip.tsx — workorder header chip next to date/time; confirmed render path for user-reported behavior.
  • Secondary display: attik-frontend/src/app/tools/inspections/[id]/components/EditChargesModal.tsx (footer total duration), WorkorderPriceChangeConfirmModal.tsx (already two-decimal preview — align or reuse formatter).
  • Duration calculation / persistence touchpoints: calculateServicePrices.ts, modifierPriceAdjFn.ts, usePriceCalculation.ts, buildDurationEndtimePatch.ts, recalculateChargesForRequiredInfo.ts (computeTotalJobDurationHours), and scheduler save paths (NewSchedulingForm.tsx, attik-frontend/src/app/scheduler/hooks/useDraftSaveOrchestrator.ts, attik-frontend/src/app/scheduler/SchedulerContext.tsx).
  • Reschedule flows: RescheduleJobModal.tsx derives totalDuration from charge service definitions and allows manual 0.5-hour edits — regression-check after any formatter or rounding change.

Backend

  • attik-backend/src/models/inspectionSchema.tsduration field type only; no precision constraint.
  • attik-backend/src/routes/inspection.ts — reschedule/PATCH assigns inspection.duration from request body without normalization.
  • Decision needed: display-only rounding vs. canonical rounding on write (create + PATCH + Spectora sync paths) so stored values match what users see.

Product / architecture decisions (for the implementer)

  • Decision needed: Target precision — one decimal (e.g. 3.5h), two decimals (matches confirm modal / some save paths), or integers when whole (e.g. 3h vs 3.5h).
  • Decision needed: Scope of fix — display formatter only vs. normalize at calculation and save so downstream scheduling, calendar blocks, and exports stay consistent.
  • Decision needed: Whether to introduce a shared duration formatter under attik-frontend/src/util/... reused by chip, Edit Charges, and confirm modal.

References

  • Related: ATT-1654 — Duration shows too many decimal places
  • Display site: attik-frontend/src/app/tools/inspections/[id]/components/InspectionDateChip.tsx
  • Modifier time math: attik-frontend/src/util/functions/data/modifierPriceAdjFn.ts
  • Stored field: attik-backend/src/models/inspectionSchema.ts (duration)

Please authenticate to join the conversation.

Upvoters
Status

Planned

Board
🏠

Main App

Date

6 days ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.