A database-level guarantee. The planned duration on a live stage becomes read-only at start, while the start date stays movable because rescheduling is what a delay is. Actual days and variance days are derived by trigger on every write rather than sent by the client, so no future write path can omit them.
Also called: what we said it would take · baseline days · estimate can't move after start · variance against the original plan
- 1baseline_days is set once when a project starts and is frozen from then on.
- 2planned_start_day stays editable — the schedule can move even though the estimate cannot.
- 3actual_days and variance_days are computed in the database from the stored start and end dates.
- 4Variance is always measured against baseline_days, not planned_days.
Migration 142 states the rule: 'once a project is started, what you SAID it would take is history. What actually happens is free to move. You cannot measure "we ran 3 days over" if the estimate silently follows the actual around.' Migration 143 documents the bug it fixed, verified in production: 'of 57 crew_stage_logs rows, actual_days and variance_days are NULL on ALL 11 completed rows and all 14 in_progress rows' — the client computed both, wrote them into local state, then omitted them from the save, so 'the numbers exist on screen for one session and are gone on reload.' Deriving them in the database meant 'the 11 completed rows become measurable RETROACTIVELY'.
- Editing a stage duration mid-build silently rewrote history and erased overruns.
- The headline performance metric was never actually saved.
- Any new write path could omit the derived fields again.
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →