'use strict' // ───────────────────────────────────────────────────────────────────────────── // Install chain templates for Service Contracts. // // Each template is an ordered array of steps. Steps chain via `depends_on_step` // (index into the same array, or null for "run as soon as chain starts"). // `null` → the step is born "open" immediately; otherwise born "On Hold" // until the parent step completes (see dispatch.unblockDependents). // // Multiple steps with depends_on_step=null run in PARALLEL (tech sees both // at once, either can be completed first). Likewise multiple steps pointing // at the same parent run in parallel after the parent. The terminal-node // detector (_isChainTerminal) only fires when ALL siblings are Completed. // ───────────────────────────────────────────────────────────────────────────── const TEMPLATES = { // ── Production templates ──────────────────────────────────────────────── fiber_install: [ { subject: 'Vérification pré-installation (éligibilité & OLT)', job_type: 'Autre', priority: 'medium', duration_h: 0.5, assigned_group: 'Admin', depends_on_step: null }, { subject: 'Installation fibre chez le client', job_type: 'Installation', priority: 'high', duration_h: 3, assigned_group: 'Tech Targo', depends_on_step: 0 }, { subject: 'Activation du service & configuration ONT', job_type: 'Installation', priority: 'high', duration_h: 0.5, assigned_group: 'Admin', depends_on_step: 1 }, { subject: 'Test de débit & validation client', job_type: 'Dépannage', priority: 'medium', duration_h: 0.5, assigned_group: 'Tech Targo', depends_on_step: 2 }, ], phone_service: [ { subject: 'Importer le numéro de téléphone', job_type: 'Autre', priority: 'medium', duration_h: 0.5, assigned_group: 'Admin', depends_on_step: null }, { subject: 'Installation fibre (pré-requis portage)', job_type: 'Installation', priority: 'high', duration_h: 2, assigned_group: 'Tech Targo', depends_on_step: 0 }, { subject: 'Portage du numéro vers Gigafibre', job_type: 'Autre', priority: 'medium', duration_h: 0.5, assigned_group: 'Admin', depends_on_step: 1 }, { subject: 'Validation et test du service téléphonique', job_type: 'Dépannage', priority: 'medium', duration_h: 0.5, assigned_group: 'Tech Targo', depends_on_step: 2 }, ], move_service: [ { subject: 'Préparation déménagement (vérifier éligibilité nouveau site)', job_type: 'Autre', priority: 'medium', duration_h: 0.5, assigned_group: 'Admin', depends_on_step: null }, { subject: 'Retrait équipement ancien site', job_type: 'Retrait', priority: 'medium', duration_h: 1, assigned_group: 'Tech Targo', depends_on_step: 0 }, { subject: 'Installation au nouveau site', job_type: 'Installation', priority: 'high', duration_h: 3, assigned_group: 'Tech Targo', depends_on_step: 1 }, { subject: 'Transfert abonnement & mise à jour adresse', job_type: 'Autre', priority: 'medium', duration_h: 0.5, assigned_group: 'Admin', depends_on_step: 2 }, ], repair_service: [ { subject: 'Diagnostic à distance', job_type: 'Dépannage', priority: 'high', duration_h: 0.5, assigned_group: 'Admin', depends_on_step: null }, { subject: 'Intervention terrain', job_type: 'Réparation', priority: 'high', duration_h: 2, assigned_group: 'Tech Targo', depends_on_step: 0 }, { subject: 'Validation & suivi client', job_type: 'Dépannage', priority: 'medium', duration_h: 0.5, assigned_group: 'Admin', depends_on_step: 1 }, ], // ── Test templates ────────────────────────────────────────────────────── // For end-to-end testing the contract → chain → activation → invoice // lifecycle without running through a 4-step production chain. // One-step: tech completes one job, subscription activates immediately. // Fastest path to verify the full lifecycle. test_single: [ { subject: 'Test — Activation immédiate', job_type: 'Installation', priority: 'medium', duration_h: 0.25, assigned_group: 'Admin', depends_on_step: null }, ], // Three steps with a parallel middle: step 0 → (step 1 ∥ step 2). // Both middle jobs are born "open" after step 0 completes (same depends_on). // Tech picks either one first; subscription activates when BOTH are Completed. // Exercises _isChainTerminal's sibling-completion check. test_parallel: [ { subject: 'Test — Étape initiale', job_type: 'Autre', priority: 'medium', duration_h: 0.25, assigned_group: 'Admin', depends_on_step: null }, { subject: 'Test — Branche A (parallèle)', job_type: 'Installation', priority: 'medium', duration_h: 0.25, assigned_group: 'Admin', depends_on_step: 0 }, { subject: 'Test — Branche B (parallèle)', job_type: 'Installation', priority: 'medium', duration_h: 0.25, assigned_group: 'Admin', depends_on_step: 0 }, ], } // Pick a template by explicit id, then by contract_type mapping, else fall back // to the universal fiber_install safety net. // // chooseTemplate({ install_template: 'test_single' }) → test_single // chooseTemplate({ contract_type: 'Résidentiel' }) → fiber_install // chooseTemplate({ contract_type: 'Test-Simple' }) → test_single // chooseTemplate({ contract_type: 'Test-Parallèle' }) → test_parallel // chooseTemplate({}) → fiber_install function chooseTemplate (contract = {}) { const explicit = contract.install_template if (explicit && TEMPLATES[explicit]) return explicit const byType = { 'Résidentiel': 'fiber_install', 'Commercial': 'fiber_install', 'Déménagement': 'move_service', 'Téléphonie': 'phone_service', 'Réparation': 'repair_service', 'Test-Simple': 'test_single', 'Test-Parallèle': 'test_parallel', 'Test-Parallele': 'test_parallel', // tolerate missing accent } const mapped = byType[contract.contract_type] return mapped || 'fiber_install' } function getTemplateSteps (templateId) { return TEMPLATES[templateId] || [] } module.exports = { TEMPLATES, getTemplateSteps, chooseTemplate }