Sequence: BIM steps first, and default flow matches the field spec

- enableBIM() prepends the BIM steps (BIM precedes construction) instead
  of appending them.
- Default construction sequence updated to the agreed flow (2D sheets /
  spool drawings -> conduit -> tray -> QC hold -> wire pull -> device ->
  termination -> QC hold -> commissioning -> as-built), with QC-hold gates.
- Sample project now enables BIM/VDC so it demonstrates the full
  BIM -> construction sequence.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 10:49:11 -07:00
parent 0e698438a2
commit ca4176ac00

View File

@@ -179,11 +179,10 @@ const BIM_CONSTRAINTS = [
{name:'Issued-For-Fabrication (IFF) Granted', description:'Model approved for field use — EN06-SOP §9.4'}
];
const BIM_SEQUENCE = [
'Project start — gather required docs', 'Kick-off (LOD, schedule, cost code)',
'Kick-off (LOD, schedule, cost code)', 'Project start — gather required docs',
'Field coordination / laser scan', 'Model racks, instruments & panels',
'Model conduit (after schedule + redlines)', 'BIM coordination / clash with GC & trades',
'Constructability review (CRS)', 'GC submission & sign-off (IFF)',
'2D installation sheets', 'As-built (scan / redlines)'
'Constructability review (CRS)', 'GC submission & sign-off (IFF)'
];
const BIM_SOURCES = [
{label:'IO List (Point Matrix DB)', ph:'controls.dev / SharePoint'},
@@ -223,7 +222,9 @@ function enableBIM(){
// BIM sign-off roles (optional), reference sources, and process steps (idempotent).
BIM_TEMPLATE_ROLES.forEach(r => { if(!state.signoffRoles.some(x => x.role === r)) state.signoffRoles.push({role:r, name:'', bim:true}); });
renderOptionalRoles();
BIM_SEQUENCE.forEach(lbl => { if(!state.sequence.some(s => s.label === lbl)) state.sequence.push({label:lbl, kind:'step', bim:true}); });
// BIM work precedes construction, so put the BIM steps at the FRONT of the sequence.
const bimSteps = BIM_SEQUENCE.filter(lbl => !state.sequence.some(s => s.label === lbl)).map(lbl => ({label:lbl, kind:'step', bim:true}));
state.sequence = [...bimSteps, ...state.sequence];
renderSequenceSteps();
BIM_SOURCES.forEach(s => { if(!state.sources.some(x => x.label === s.label)) state.sources.push({label:s.label, system:'', notes:'', link:'', ph:s.ph, preset:true, bim:true}); });
renderSources();
@@ -303,9 +304,7 @@ function loadSampleData(){
document.getElementById('proj_cm').value = 'K. Boyd';
document.getElementById('proj_qm').value = 'D. Nguyen';
// Step 3 — standard required roles (sample is an install-only project)
state.bimEnabled = false;
const beEl = document.getElementById('bim_enabled'); if(beEl) beEl.checked = false;
// Step 3 — standard required roles
if(state.signoffRoles[0]) state.signoffRoles[0].role = 'Superintendent';
if(state.signoffRoles[1]) state.signoffRoles[1].role = 'Foreman';
const stEl = document.getElementById('role_super_title'); if(stEl) stEl.value = 'Superintendent';
@@ -327,6 +326,12 @@ function loadSampleData(){
// Step 7 already has defaults
// The Micron FMCS sample includes BIM/VDC — enable it so the sequence shows the
// full BIM → construction flow (BIM steps first) and the Creator offers IWP/EWP.
state.bimEnabled = true;
const beEl = document.getElementById('bim_enabled'); if(beEl) beEl.checked = true;
enableBIM();
// Collect all data
collectStepData();
track('sample_loaded');
@@ -674,13 +679,27 @@ function addCustomConstraintText(){
renderStandardConstraints();
}
const DEFAULT_SEQUENCE = ['Layout','Conduit Install','Tray Install','Wire Pull','Device Install','Termination','QC Inspection','Commissioning'];
// Default construction flow (used when BIM is off; the BIM steps are prepended when
// the project includes BIM/VDC). Includes QC-hold gates. Items may be strings or
// {label, kind} objects.
const DEFAULT_SEQUENCE = [
{label:'2D installation sheets / Spool Drawings', kind:'step'},
{label:'Conduit Install', kind:'step'},
{label:'Tray Install', kind:'step'},
{label:'QC Hold', kind:'gate'},
{label:'Wire Pull', kind:'step'},
{label:'Device Install', kind:'step'},
{label:'Termination', kind:'step'},
{label:'QC Hold', kind:'gate'},
{label:'Commissioning', kind:'step'},
{label:'As-built (scan / redlines)', kind:'step'}
];
let seqDragIndex = null;
function renderSequenceSteps(){
const container = document.getElementById('sequence-list');
if(!container) return;
if(!state.sequence.length) state.sequence = DEFAULT_SEQUENCE.map(s=>({label:s,kind:'step'}));
if(!state.sequence.length) state.sequence = DEFAULT_SEQUENCE.map(s=> typeof s==='string' ? {label:s,kind:'step'} : {label:s.label, kind:s.kind||'step'});
container.innerHTML = '';
let stepNo = 0;
state.sequence.forEach((item,i)=>{