// Auteur : Simon-Pierre Boucher — contact@spboucher.ai /** * Taxonomie de la méthode du coût : divisions MasterFormat, catégories UX, * qualités, conditions, matériaux normalisés, métiers, règles de dépréciation. * Module PUR (client + serveur). */ import type { Condition, Quality, UxCategory, BuildingType, IndirectParams, CostParams } from "./types"; export const METHOD_VERSION = "1.0.0"; /** Divisions CSI MasterFormat retenues. */ export const MASTERFORMAT: Record = { "01": { fr: "Exigences générales", en: "General Requirements" }, "02": { fr: "Conditions existantes", en: "Existing Conditions" }, "03": { fr: "Béton", en: "Concrete" }, "04": { fr: "Maçonnerie", en: "Masonry" }, "05": { fr: "Métaux", en: "Metals" }, "06": { fr: "Bois, plastiques et composites", en: "Wood, Plastics and Composites" }, "07": { fr: "Isolation et étanchéité", en: "Thermal and Moisture Protection" }, "08": { fr: "Ouvertures", en: "Openings" }, "09": { fr: "Finitions", en: "Finishes" }, "10": { fr: "Ouvrages spéciaux", en: "Specialties" }, "11": { fr: "Équipement", en: "Equipment" }, "12": { fr: "Ameublement", en: "Furnishings" }, "21": { fr: "Protection incendie", en: "Fire Suppression" }, "22": { fr: "Plomberie", en: "Plumbing" }, "23": { fr: "CVCA", en: "HVAC" }, "26": { fr: "Électricité", en: "Electrical" }, "31": { fr: "Terrassement", en: "Earthwork" }, "32": { fr: "Aménagements extérieurs", en: "Exterior Improvements" }, "33": { fr: "Services publics", en: "Utilities" }, }; export const UX_CATEGORIES: { key: UxCategory; fr: string; en: string; order: number }[] = [ { key: "site", fr: "Préparation du site", en: "Site preparation", order: 1 }, { key: "excavation", fr: "Excavation", en: "Excavation", order: 2 }, { key: "foundation", fr: "Fondations", en: "Foundations", order: 3 }, { key: "structure", fr: "Structure", en: "Structure", order: 4 }, { key: "roofing", fr: "Toiture", en: "Roofing", order: 5 }, { key: "envelope", fr: "Enveloppe", en: "Envelope", order: 6 }, { key: "openings", fr: "Portes et fenêtres", en: "Doors and windows", order: 7 }, { key: "insulation", fr: "Isolation", en: "Insulation", order: 8 }, { key: "finishes_ext", fr: "Revêtements", en: "Cladding", order: 9 }, { key: "interior", fr: "Finition intérieure", en: "Interior finishes", order: 10 }, { key: "kitchen", fr: "Cuisine", en: "Kitchen", order: 11 }, { key: "bathroom", fr: "Salle de bain", en: "Bathroom", order: 12 }, { key: "plumbing", fr: "Plomberie", en: "Plumbing", order: 13 }, { key: "hvac", fr: "Chauffage / ventilation", en: "HVAC", order: 14 }, { key: "electrical", fr: "Électricité", en: "Electrical", order: 15 }, { key: "garage", fr: "Garage", en: "Garage", order: 16 }, { key: "basement", fr: "Sous-sol", en: "Basement", order: 17 }, { key: "exterior", fr: "Aménagement extérieur", en: "Exterior improvements", order: 18 }, ]; export const categoryLabel = (key: UxCategory, fr: boolean): string => { const c = UX_CATEGORIES.find((x) => x.key === key); return c ? (fr ? c.fr : c.en) : key; }; export const QUALITIES: { key: Quality; fr: string; en: string }[] = [ { key: "economy", fr: "Économique", en: "Economy" }, { key: "standard", fr: "Standard", en: "Standard" }, { key: "superior", fr: "Supérieur", en: "Superior" }, { key: "prestige", fr: "Prestige", en: "Prestige" }, ]; export const CONDITIONS: { key: Condition; fr: string; en: string; effectiveAgeRatio: number }[] = [ { key: "poor", fr: "Mauvais", en: "Poor", effectiveAgeRatio: 0.85 }, { key: "below_average", fr: "Sous la moyenne", en: "Below average", effectiveAgeRatio: 0.7 }, { key: "average", fr: "Moyen", en: "Average", effectiveAgeRatio: 0.55 }, { key: "good", fr: "Bon", en: "Good", effectiveAgeRatio: 0.35 }, { key: "very_good", fr: "Très bon", en: "Very good", effectiveAgeRatio: 0.2 }, { key: "excellent", fr: "Excellent", en: "Excellent", effectiveAgeRatio: 0.1 }, { key: "renovated", fr: "Rénové", en: "Renovated", effectiveAgeRatio: 0.12 }, { key: "new", fr: "Neuf", en: "New", effectiveAgeRatio: 0.0 }, ]; /** * Règles condition → âge effectif d'une composante (component_condition_rules, * §144). L'âge effectif = ratio × vie économique de la composante. Hypothèses * documentées, modifiables en base (table `component_condition_rules`). */ export const CONDITION_GROUPS: { key: string; fr: string; en: string; economicLife: number }[] = [ { key: "structure", fr: "Structure et fondations", en: "Structure and foundations", economicLife: 75 }, { key: "roof", fr: "Toiture", en: "Roof", economicLife: 22 }, { key: "exterior", fr: "Enveloppe et revêtements", en: "Envelope and cladding", economicLife: 40 }, { key: "windows", fr: "Portes et fenêtres", en: "Doors and windows", economicLife: 30 }, { key: "interior", fr: "Finition intérieure", en: "Interior finishes", economicLife: 25 }, { key: "kitchen", fr: "Cuisine", en: "Kitchen", economicLife: 20 }, { key: "bathroom", fr: "Salles de bain", en: "Bathrooms", economicLife: 22 }, { key: "mechanical", fr: "Mécanique (plomberie, CVCA)", en: "Mechanical (plumbing, HVAC)", economicLife: 22 }, { key: "electrical", fr: "Électricité", en: "Electrical", economicLife: 35 }, { key: "site", fr: "Site et extérieur", en: "Site and exterior", economicLife: 25 }, ]; export const BUILDING_TYPES: { key: BuildingType; fr: string; en: string; economicLife: number }[] = [ { key: "detached", fr: "Maison unifamiliale détachée", en: "Detached single-family", economicLife: 60 }, { key: "semi_detached", fr: "Jumelé", en: "Semi-detached", economicLife: 60 }, { key: "row", fr: "Maison en rangée", en: "Row house", economicLife: 60 }, { key: "plex", fr: "Plex (2-5 logements)", en: "Plex (2-5 units)", economicLife: 60 }, { key: "condo", fr: "Condo (unité)", en: "Condo (unit)", economicLife: 60 }, { key: "chalet", fr: "Chalet", en: "Cottage", economicLife: 50 }, { key: "mobile", fr: "Maison mobile", en: "Mobile home", economicLife: 35 }, { key: "other", fr: "Autre", en: "Other", economicLife: 55 }, ]; /** Métiers (codes internes) ↔ libellés APCHQ/CCQ. */ export const TRADES: { code: string; fr: string; en: string; apchq: string[] }[] = [ { code: "charpentier", fr: "Charpentier-menuisier", en: "Carpenter", apchq: ["Charpentier-menuisier"] }, { code: "briqueteur", fr: "Briqueteur-maçon", en: "Bricklayer-mason", apchq: ["Briqueteur-maçon"] }, { code: "carreleur", fr: "Carreleur", en: "Tile setter", apchq: ["Carreleur"] }, { code: "cimentier", fr: "Cimentier-applicateur", en: "Cement finisher", apchq: ["Cimentier-applicateur"] }, { code: "coffreur", fr: "Coffreur à béton", en: "Concrete formworker", apchq: ["Coffreur à béton"] }, { code: "couvreur", fr: "Couvreur", en: "Roofer", apchq: ["Couvreur"] }, { code: "electricien", fr: "Électricien", en: "Electrician", apchq: ["Électricien", "Electricien"] }, { code: "plombier", fr: "Tuyauteur (plombier)", en: "Pipefitter (plumber)", apchq: ["Tuyauteur", "Plombier"] }, { code: "ferblantier", fr: "Ferblantier", en: "Sheet-metal worker", apchq: ["Ferblantier"] }, { code: "frigoriste", fr: "Frigoriste", en: "Refrigeration mechanic", apchq: ["Frigoriste"] }, { code: "peintre", fr: "Peintre", en: "Painter", apchq: ["Peintre"] }, { code: "platrier", fr: "Plâtrier (tireur de joints)", en: "Plasterer (taper)", apchq: ["Plâtrier", "Platrier"] }, { code: "poseur_systemes", fr: "Poseur de systèmes intérieurs", en: "Interior systems installer", apchq: ["Poseur de systèmes intérieurs", "Poseur de systemes interieurs"] }, { code: "poseur_revetements", fr: "Poseur de revêtements souples", en: "Floor-covering installer", apchq: ["Poseur de revêtements souples", "Poseur de revetements souples"] }, { code: "calorifugeur", fr: "Calorifugeur", en: "Insulator", apchq: ["Calorifugeur"] }, { code: "ferrailleur", fr: "Ferrailleur", en: "Rebar worker", apchq: ["Ferrailleur"] }, { code: "vitrier", fr: "Monteur-mécanicien (vitrier)", en: "Glazier", apchq: ["Monteur-mécanicien (vitrier)", "Vitrier"] }, { code: "manoeuvre", fr: "Manœuvre", en: "Labourer", apchq: ["Manœuvre", "Manoeuvre"] }, { code: "operateur", fr: "Opérateur de pelles mécaniques", en: "Excavator operator", apchq: ["Opérateur de pelles mécaniques", "Operateur de pelles mecaniques", "Opérateur de pelles"] }, { code: "poseur_bardeaux", fr: "Poseur de bardeaux", en: "Shingle installer", apchq: ["Couvreur"] }, ]; export const tradeLabel = (code: string | null, fr: boolean): string => { const t = TRADES.find((x) => x.code === code); return t ? (fr ? t.fr : t.en) : (code ?? "—"); }; /** * Paramètres par défaut — HYPOTHÈSES DOCUMENTÉES (aucun pourcentage n'est * universel) : visibles, modifiables et expliqués dans l'interface. */ export const DEFAULT_INDIRECT: IndirectParams = { plansPct: 3.0, permitsPct: 0.8, inspectionPct: 0.5, insurancePct: 1.5, mobilizationPct: 1.5, siteManagementPct: 3.0, financingPct: 2.0, adminPct: 1.0, }; export const DEFAULT_PARAMS: CostParams = { indirect: DEFAULT_INDIRECT, overheadPct: 7.0, profitPct: 8.0, contingencyPct: 3.0, }; export const INDIRECT_LABELS: Record = { plansPct: { fr: "Plans et professionnels", en: "Plans and professionals", noteFr: "Architecte/technologue, ingénieur, arpenteur — hypothèse 3 % du coût direct." }, permitsPct: { fr: "Permis", en: "Permits", noteFr: "Permis de construction municipal — hypothèse 0,8 %." }, inspectionPct: { fr: "Inspection et essais", en: "Inspection and testing", noteFr: "Inspections, essais de sol/béton — hypothèse 0,5 %." }, insurancePct: { fr: "Assurances chantier", en: "Builder's insurance", noteFr: "Assurance chantier et responsabilité — hypothèse 1,5 %." }, mobilizationPct: { fr: "Mobilisation", en: "Mobilization", noteFr: "Roulotte, clôture, installations temporaires — hypothèse 1,5 %." }, siteManagementPct: { fr: "Gestion de chantier", en: "Site management", noteFr: "Surintendant, coordination — hypothèse 3 %." }, financingPct: { fr: "Financement", en: "Financing", noteFr: "Intérêts intercalaires pendant la construction — hypothèse 2 %." }, adminPct: { fr: "Administration", en: "Administration", noteFr: "Frais administratifs du projet — hypothèse 1 %." }, }; /** Matériaux normalisés (taxonomie canonique renvoyée par l'IA et l'UI). */ export const MATERIALS = [ "quartz", "granite", "laminate", "butcher_block", "solid_surface", "marble", "hardwood", "engineered_wood", "vinyl_plank", "laminate_floor", "ceramic_tile", "porcelain_tile", "carpet", "concrete_floor", "brick", "stone", "vinyl_siding", "fiber_cement", "wood_siding", "stucco", "aluminum_siding", "steel_siding", "asphalt_shingle", "metal_roof", "elastomeric_membrane", "epdm", "cedar_shake", "pvc_window", "hybrid_window", "aluminum_window", "wood_window", "poured_concrete", "concrete_block", "stone_foundation", "melamine", "thermofoil", "painted_mdf", "wood_veneer", "solid_wood", ] as const; export type Material = (typeof MATERIALS)[number]; /** Économie de lecture des cuisines : pieds linéaires d'armoires typiques par qualité. */ export const KITCHEN_LINEAR_FT: Record = { economy: 20, standard: 26, superior: 32, prestige: 40 };