feat(lifecycle): add pure project lifecycle stage model (stages, progress map, helpers)
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
// src/data/lifecycle.js
|
||||
// The project lifecycle state machine (Master §9). Pure constants + helpers; no React.
|
||||
|
||||
// Ordered linear stages. 'Rework In Progress' is an off-line regression state (entered on a failed
|
||||
// final inspection), so it is NOT in the linear order array — handle it explicitly.
|
||||
export const LIFECYCLE_STAGES = [
|
||||
'Lead',
|
||||
'Damage Inspection Scheduled',
|
||||
'Damage Verified',
|
||||
'Scope Approved',
|
||||
'Contract Signed',
|
||||
'Work In Progress',
|
||||
'Work Complete — Awaiting Inspection',
|
||||
'Final Inspection Scheduled',
|
||||
'Final Inspection In Progress',
|
||||
'Project Completed',
|
||||
'Final Payment Received — Closed',
|
||||
];
|
||||
|
||||
export const REWORK_STAGE = 'Rework In Progress';
|
||||
|
||||
// Stage → canonical progress %. Advancing to a stage sets the project's completionPercentage to this.
|
||||
export const STAGE_PROGRESS = {
|
||||
'Lead': 5,
|
||||
'Damage Inspection Scheduled': 10,
|
||||
'Damage Verified': 20,
|
||||
'Scope Approved': 30,
|
||||
'Contract Signed': 40,
|
||||
'Work In Progress': 55,
|
||||
'Work Complete — Awaiting Inspection': 80,
|
||||
'Final Inspection Scheduled': 85,
|
||||
'Final Inspection In Progress': 90,
|
||||
'Rework In Progress': 75,
|
||||
'Project Completed': 95,
|
||||
'Final Payment Received — Closed': 100,
|
||||
};
|
||||
|
||||
export const stageToPct = (stage) => STAGE_PROGRESS[stage] ?? 0;
|
||||
|
||||
export const nextStage = (stage) => {
|
||||
if (stage === REWORK_STAGE) return 'Final Inspection Scheduled'; // rework re-enters inspection
|
||||
const i = LIFECYCLE_STAGES.indexOf(stage);
|
||||
return i >= 0 && i < LIFECYCLE_STAGES.length - 1 ? LIFECYCLE_STAGES[i + 1] : stage;
|
||||
};
|
||||
|
||||
export const prevStage = (stage) => {
|
||||
const i = LIFECYCLE_STAGES.indexOf(stage);
|
||||
return i > 0 ? LIFECYCLE_STAGES[i - 1] : stage;
|
||||
};
|
||||
|
||||
// Is this stage at/after a reference stage? (for gating UI like "can schedule final inspection")
|
||||
export const isAtOrAfter = (stage, ref) =>
|
||||
LIFECYCLE_STAGES.indexOf(stage) >= LIFECYCLE_STAGES.indexOf(ref);
|
||||
Reference in New Issue
Block a user