{"spec_version": "1.0", "engine": "mission", "determinism": "Pure function of the inputs and this configuration: identical inputs always produce identical amounts. No randomness, no time dependence, no external call.", "currency": "EUR", "profile_name": "Profil souverain — référence Paris", "constants": {"base_daily_ttc": 900.0, "vat_rate_pct": 20.0, "hours_per_day": 7.0, "hourly_factor": 1.05, "travel_day_cap_factor": 0.75, "recovery_day_factor": 0.5, "change_management_factor": 0.2, "onsite_priority_premium_factor": 0.04, "facility_management_factor": 0.12, "deposit_rate": 0.3}, "specialty_factors": {"agentic_ai": 1.08, "data_engineering": 0.94, "ai_security": 1.06, "blockchain": 1.08, "training": 1.0, "marketing_engineering": 0.88, "reg_csv": 1.18, "cdm": 1.0, "pv": 1.02, "healthtech": 1.08}, "complexity_factors": {"standard": 1.0, "advanced": 1.08, "regulated": 1.16, "critical": 1.25}, "factor_tables": {"duration_factors": {"spot": 1.0, "3m": 0.888889, "6m": 0.833333, "12m": 0.777778}, "onsite_premium_factors": {"spot": 0.133333, "3m": 0.111111, "6m": 0.1, "12m": 0.1}, "onsite_mix_tjm_factors": {"remote_only": 0.96, "light_onsite_under_10": 0.98, "balanced_under_25": 1.0, "onsite_heavy_under_50": 1.03, "onsite_majority_under_80": 1.06, "onsite_almost_full": 1.09}, "confirmation_tjm_factors": {"30_plus_days": 0.98, "15_29_days": 1.0, "7_14_days": 1.025, "under_7_days": 1.06, "under_72h": 1.1}, "regularity_factors": {"isolated": 1.0, "2_consecutive": 0.85, "3_4_consecutive": 0.7, "5_9_consecutive": 0.55, "10_plus_consecutive": 0.45, "fixed_site_3m": 0.7, "3_days_week_3m": 0.55}, "regularity_curve": {"onsite_half_life_days": 6.0, "total_half_life_days": 45.0, "minimum_strength": 0.35, "onsite_volume_weight": 0.6, "total_volume_weight": 0.3, "density_weight": 0.1}, "stability_factors": {"same_address": 1.0, "same_city_multiple_sites": 1.15, "same_region_multiple_cities": 1.35, "multiple_countries": 1.6, "daily_city_change": 1.8}, "reservation_urgency_factors": {"30_plus_days": 1.0, "15_29_days": 1.1, "7_14_days": 1.2, "under_7_days": 1.35, "under_72h": 1.5}, "zone_mobility_factors": {"Z0": 0.133333, "Z1": 0.177778, "Z2": 0.244444, "Z3": 0.311111, "Z4": 0.422222, "Z5": 0.611111, "Z6": 0.722222, "Z7": 0.888889}, "travel_coefficients": {"productive_train": 0.5, "taxi_chauffeur": 0.5, "airport_connections": 0.75, "flight_non_productive": 0.75, "night": 1.0, "weekend_holiday": 1.0}}, "schedule_optimizer": {"max_preferred_streak": 5, "mobilization_cost": 1.0, "mode_switch_cost": 0.15, "fatigue_cost": 0.35}, "promotions": {"supported": true, "application": "promo_discount = subtotal_ttc * promo_rate; total_ttc = subtotal_ttc - promo_discount", "codes_public": false, "note_fr": "Les codes promotionnels et leurs taux sont des remises commerciales privées, volontairement non publiées. Un code inconnu est ignoré (remise 0).", "note_en": "Promotional codes and their rates are private commercial discounts, deliberately unpublished. An unknown code is ignored (0 discount)."}, "inputs": {"specialty": {"type": "enum", "keys": ["agentic_ai", "data_engineering", "ai_security", "blockchain", "training", "marketing_engineering", "reg_csv", "cdm", "pv", "healthtech"], "labels": {"agentic_ai": {"fr": "Agentic AI Engineering", "en": "Agentic AI Engineering"}, "data_engineering": {"fr": "Data Engineering", "en": "Data Engineering"}, "ai_security": {"fr": "AI Security & DevSecOps", "en": "AI Security & DevSecOps"}, "blockchain": {"fr": "Blockchain & Verifiable Computing", "en": "Blockchain & Verifiable Computing"}, "training": {"fr": "AI Training & Adoption", "en": "AI Training & Adoption"}, "marketing_engineering": {"fr": "Marketing Engineering", "en": "Marketing Engineering"}, "reg_csv": {"fr": "Regulatory Technology & CSV", "en": "Regulatory Technology & CSV"}, "cdm": {"fr": "Clinical Data Management", "en": "Clinical Data Management"}, "pv": {"fr": "Pharmacovigilance Data Engineering", "en": "Pharmacovigilance Data Engineering"}, "healthtech": {"fr": "HealthTech / PharmaTech Product Engineering", "en": "HealthTech / PharmaTech Product Engineering"}}, "required": false, "default": "agentic_ai", "desc_fr": "Spécialité (multiplicateur du TJM de base).", "desc_en": "Specialty (base day-rate multiplier)."}, "complexity": {"type": "enum", "keys": ["standard", "advanced", "regulated", "critical"], "labels": {"standard": {"fr": "Standard", "en": "Standard"}, "advanced": {"fr": "Avancée", "en": "Advanced"}, "regulated": {"fr": "Régulée", "en": "Regulated"}, "critical": {"fr": "Critique", "en": "Critical"}}, "required": false, "default": "standard", "desc_fr": "Complexité (multiplicateur du TJM de base).", "desc_en": "Complexity (base day-rate multiplier)."}, "duration_tier": {"type": "enum", "keys": ["spot", "3m", "6m", "12m"], "labels": {"spot": {"fr": "Ponctuel", "en": "Spot"}, "3m": {"fr": "3 mois et plus", "en": "3+ months"}, "6m": {"fr": "6 mois et plus", "en": "6+ months"}, "12m": {"fr": "12 mois et plus", "en": "12+ months"}}, "required": false, "desc_fr": "Horizon d'engagement (remise de durée).", "desc_en": "Engagement horizon (duration discount)."}, "zone": {"type": "enum", "keys": ["Z0", "Z1", "Z2", "Z3", "Z4", "Z5", "Z6", "Z7"], "labels": {"Z0": {"fr": "Z0 · Paris", "en": "Z0 · Paris"}, "Z1": {"fr": "Z1 · Île-de-France", "en": "Z1 · Greater Paris"}, "Z2": {"fr": "Z2 · France", "en": "Z2 · France"}, "Z3": {"fr": "Z3 · Europe proche", "en": "Z3 · Near Europe"}, "Z4": {"fr": "Z4 · Europe étendue", "en": "Z4 · Wider Europe"}, "Z5": {"fr": "Z5 · Intercontinental", "en": "Z5 · Intercontinental"}, "Z6": {"fr": "Z6 · Long courrier", "en": "Z6 · Long haul"}, "Z7": {"fr": "Z7 · Très long courrier", "en": "Z7 · Ultra long haul"}}, "required": false, "desc_fr": "Zone géographique (unité de mobilité).", "desc_en": "Geographic zone (mobility unit)."}, "stability": {"type": "enum", "keys": ["same_address", "same_city_multiple_sites", "same_region_multiple_cities", "multiple_countries", "daily_city_change"], "labels": {"same_address": {"fr": "Même adresse", "en": "Same address"}, "same_city_multiple_sites": {"fr": "Plusieurs sites, même ville", "en": "Multiple sites, same city"}, "same_region_multiple_cities": {"fr": "Plusieurs villes", "en": "Multiple cities"}, "multiple_countries": {"fr": "Plusieurs pays", "en": "Multiple countries"}, "daily_city_change": {"fr": "Changement de ville quotidien", "en": "Daily city change"}}, "required": false, "desc_fr": "Stabilité des sites (facteur de mobilité).", "desc_en": "Site stability (mobility factor)."}, "reservation_urgency": {"type": "enum", "keys": ["30_plus_days", "15_29_days", "7_14_days", "under_7_days", "under_72h"], "labels": {"30_plus_days": {"fr": "30 jours ou plus", "en": "30 days or more"}, "15_29_days": {"fr": "15 à 29 jours", "en": "15–29 days"}, "7_14_days": {"fr": "7 à 14 jours", "en": "7–14 days"}, "under_7_days": {"fr": "Moins de 7 jours", "en": "Under 7 days"}, "under_72h": {"fr": "Moins de 72 heures", "en": "Under 72 hours"}}, "required": false, "desc_fr": "Délai de confirmation (facteur TJM et mobilité).", "desc_en": "Confirmation delay (day-rate and mobility factor)."}, "travel_type": {"type": "enum", "keys": ["productive_train", "taxi_chauffeur", "airport_connections", "flight_non_productive", "night", "weekend_holiday"], "labels": {"productive_train": {"fr": "Train productif", "en": "Productive train"}, "taxi_chauffeur": {"fr": "Taxi ou chauffeur", "en": "Taxi or chauffeur"}, "airport_connections": {"fr": "Correspondances aéroport", "en": "Airport connections"}, "flight_non_productive": {"fr": "Vol non productif", "en": "Non-productive flight"}, "night": {"fr": "Trajet de nuit", "en": "Night travel"}, "weekend_holiday": {"fr": "Week-end ou jour férié", "en": "Weekend or public holiday"}}, "required": false, "desc_fr": "Nature du trajet (pondération du temps de trajet).", "desc_en": "Travel nature (travel-time weighting)."}, "facility_responsibility": {"type": "enum", "keys": ["client_provided", "consultant_rents"], "default": "client_provided", "required": false, "desc_fr": "Qui fournit les locaux. « consultant_rents » active les frais de salle et la gestion logistique.", "desc_en": "Who provides the venue. 'consultant_rents' enables venue costs and the logistics management fee."}, "destination": {"type": "string", "required": false, "desc_fr": "Clé d'un préréglage logistique public (voir /api/destinations). Ne remplit que les frais laissés vides.", "desc_en": "Key of a public logistics preset (see /api/destinations). Only fills expense fields left blank."}, "promo_code": {"type": "string", "required": false, "desc_fr": "Code promotionnel privé. Un code inconnu est ignoré sans erreur (remise 0).", "desc_en": "Private promotional code. An unknown code is ignored silently (0 discount)."}, "total_days": {"type": "number", "min": 1, "max": 260, "required": true, "desc_fr": "Nombre total de jours de la mission.", "desc_en": "Total number of mission days."}, "onsite_days": {"type": "number", "min": 0, "max": 260, "required": true, "desc_fr": "Jours réalisés sur site (≤ jours totaux).", "desc_en": "Days delivered on site (≤ total days)."}, "consecutive_days": {"type": "number", "min": 0, "max": 60, "required": false, "desc_fr": "Jours consécutifs sur site envisagés (détermine la régularité).", "desc_en": "Planned consecutive on-site days (drives the regularity tier)."}, "travel_hours": {"type": "number", "min": 0, "max": 80, "required": false, "desc_fr": "Temps de trajet total facturable, en heures.", "desc_en": "Total billable travel time, in hours."}, "travel_days": {"type": "number", "min": 0, "max": 40, "required": false, "desc_fr": "Journées de trajet (plafonne le temps de trajet). Défaut : nombre de blocs sur site recommandés par l'optimiseur.", "desc_en": "Travel days (caps billed travel time). Default: the on-site block count recommended by the optimiser."}, "recovery_days": {"type": "number", "min": 0, "max": 40, "required": false, "desc_fr": "Journées de récupération après trajet long.", "desc_en": "Recovery days after long-distance travel."}, "transport": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Transport longue distance TTC (remboursable).", "desc_en": "Long-distance transport incl. tax (reimbursable)."}, "nights": {"type": "number", "min": 0, "max": 365, "required": false, "desc_fr": "Nombre de nuits d'hébergement.", "desc_en": "Number of accommodation nights."}, "hotel_nightly": {"type": "number", "min": 0, "max": 5000, "required": false, "desc_fr": "Coût d'une nuit d'hôtel TTC.", "desc_en": "Cost of one hotel night incl. tax."}, "local_transport": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Transport local TTC (remboursable).", "desc_en": "Local transport incl. tax (reimbursable)."}, "meals": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Repas TTC (remboursable).", "desc_en": "Meals incl. tax (reimbursable)."}, "visa_baggage": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Visa et bagages TTC (remboursable).", "desc_en": "Visa and baggage incl. tax (reimbursable)."}, "other_costs": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Autres frais déclarés TTC (remboursable).", "desc_en": "Other declared costs incl. tax (reimbursable)."}, "facility_rental_daily": {"type": "number", "min": 0, "max": 20000, "required": false, "desc_fr": "Location de salle par jour TTC (uniquement si consultant_rents).", "desc_en": "Venue rental per day incl. tax (only when consultant_rents)."}, "facility_rental_days": {"type": "number", "min": 0, "max": 260, "required": false, "desc_fr": "Nombre de jours de location de salle.", "desc_en": "Number of venue rental days."}, "facility_setup": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Installation et aménagement TTC (si consultant_rents).", "desc_en": "Venue setup incl. tax (when consultant_rents)."}, "training_equipment": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Équipement TTC (si consultant_rents).", "desc_en": "Equipment incl. tax (when consultant_rents)."}, "training_materials": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Supports et matériel TTC (si consultant_rents).", "desc_en": "Materials incl. tax (when consultant_rents)."}, "specialty_costs": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Frais spécifiques TTC (si consultant_rents).", "desc_en": "Specialty costs incl. tax (when consultant_rents)."}, "catering": {"type": "number", "min": 0, "max": null, "required": false, "desc_fr": "Restauration TTC (si consultant_rents).", "desc_en": "Catering incl. tax (when consultant_rents)."}, "extra_mobilisations": {"type": "number", "min": 0, "max": 50, "required": false, "desc_fr": "Remobilisations supplémentaires (nombre).", "desc_en": "Additional remobilisations (count)."}}, "algorithm": [{"step": "base_effective", "formula": "base_effective = base_daily_ttc * specialty_factors[specialty] * complexity_factors[complexity]", "note_fr": "Un facteur absent vaut 1.0. Toutes les formules « base * … » ci-dessous utilisent base_effective.", "note_en": "A missing factor defaults to 1.0. Every 'base * …' below uses base_effective."}, {"step": "days_split", "formula": "remote_days = total_days - onsite_days", "note_fr": "onsite_days est plafonné à total_days.", "note_en": "onsite_days is capped at total_days."}, {"step": "onsite_mix_key", "formula": "ratio = onsite_days / total_days; key = remote_only if onsite_days<=0 else light_onsite_under_10 if ratio<0.10 else balanced_under_25 if ratio<0.25 else onsite_heavy_under_50 if ratio<0.50 else onsite_majority_under_80 if ratio<0.80 else onsite_almost_full", "note_fr": "Sélectionne le facteur dans factor_tables.onsite_mix_tjm_factors.", "note_en": "Selects the factor from factor_tables.onsite_mix_tjm_factors."}, {"step": "production_tjm_factor", "formula": "production_tjm_factor = duration_factors[duration_tier] * onsite_mix_tjm_factors[onsite_mix_key] * confirmation_tjm_factors[reservation_urgency]", "note_fr": "", "note_en": ""}, {"step": "remote_daily", "formula": "remote_daily = base_effective * production_tjm_factor", "note_fr": "", "note_en": ""}, {"step": "onsite_daily", "formula": "onsite_priority_premium = base_effective * onsite_priority_premium_factor if onsite_days>0 else 0; onsite_premium = base_effective * onsite_premium_factors[duration_tier] + onsite_priority_premium; onsite_daily = remote_daily + onsite_premium", "note_fr": "", "note_en": ""}, {"step": "production_total", "formula": "production_total = remote_days * remote_daily + onsite_days * onsite_daily", "note_fr": "", "note_en": ""}, {"step": "gross_mobility", "formula": "zone_unit = base_effective * zone_mobility_factors[zone]; gross_mobility = onsite_days * zone_unit * stability_factors[stability] * reservation_urgency_factors[reservation_urgency]", "note_fr": "reservation_urgency intervient deux fois : sur le TJM (confirmation) et sur la mobilité (urgency).", "note_en": "reservation_urgency appears twice: on the day rate (confirmation) and on mobility (urgency)."}, {"step": "regularity_key", "formula": "isolated if onsite_days<=0 else 3_days_week_3m if (total_days>=60 and onsite_days>=24) else 10_plus_consecutive if consecutive_days>=10 else 5_9_consecutive if consecutive_days>=5 else 3_4_consecutive if consecutive_days>=3 else 2_consecutive if consecutive_days>=2 else isolated", "note_fr": "target_factor = regularity_factors[regularity_key].", "note_en": "target_factor = regularity_factors[regularity_key]."}, {"step": "regularity_factor", "formula": "target_discount = clamp(1 - target_factor, 0, 0.85); onsite_volume = 1 - exp(-onsite_days / regularity_curve.onsite_half_life_days); total_volume = 1 - exp(-total_days / regularity_curve.total_half_life_days); density = smoothstep(0.03, 0.25, onsite_days / total_days); blended = (onsite_volume*onsite_volume_weight + total_volume*total_volume_weight + density*density_weight) / (onsite_volume_weight + total_volume_weight + density_weight); curve_strength = minimum_strength + (1 - minimum_strength) * blended; regularity = clamp(1 - target_discount * curve_strength, 0, 1)", "note_fr": "smoothstep(e0,e1,x): t=clamp((x-e0)/(e1-e0),0,1); renvoie t*t*(3-2t).", "note_en": "smoothstep(e0,e1,x): t=clamp((x-e0)/(e1-e0),0,1); returns t*t*(3-2t)."}, {"step": "mobility_total", "formula": "mobility_total = gross_mobility * regularity; regularity_bonus = gross_mobility * (1 - regularity)", "note_fr": "regularity_bonus est une remise affichée, déjà retirée du total.", "note_en": "regularity_bonus is a displayed saving, already removed from the total."}, {"step": "travel_time_total", "formula": "hourly_remote = base_effective / hours_per_day * hourly_factor; travel_raw = travel_hours * hourly_remote * travel_coefficients[travel_type]; travel_cap = travel_days * base_effective * travel_day_cap_factor; travel_time_total = min(travel_raw, travel_cap) if travel_days>0 else travel_raw", "note_fr": "Si travel_days est omis, il vaut le nombre de blocs sur site de l'optimiseur (voir schedule.onsite_blocks du résultat).", "note_en": "If travel_days is omitted it equals the optimiser's on-site block count (see schedule.onsite_blocks in the result)."}, {"step": "recovery_total", "formula": "recovery_total = recovery_days * base_effective * recovery_day_factor", "note_fr": "", "note_en": ""}, {"step": "reimbursable_costs", "formula": "facility_direct_costs = (facility_rental_daily*facility_rental_days + facility_setup + training_equipment + training_materials + specialty_costs + catering) if facility_responsibility=='consultant_rents' else 0; facility_management_fee = facility_direct_costs * facility_management_factor; reimbursable_costs = transport + nights*hotel_nightly + local_transport + meals + visa_baggage + other_costs + facility_direct_costs + facility_management_fee", "note_fr": "Les frais de salle ne comptent que si le consultant loue (consultant_rents).", "note_en": "Venue costs count only when the consultant rents (consultant_rents)."}, {"step": "change_fees", "formula": "change_fees = extra_mobilisations * base_effective * change_management_factor", "note_fr": "", "note_en": ""}, {"step": "subtotal_ttc", "formula": "subtotal_ttc = production_total + mobility_total + travel_time_total + recovery_total + reimbursable_costs + change_fees", "note_fr": "", "note_en": ""}, {"step": "promotions_and_total", "formula": "promo_discount = subtotal_ttc * promo_rate (0 unless a valid private code was supplied); total_ttc = max(0, subtotal_ttc - promo_discount)", "note_fr": "commercial_discount est un levier owner-only, toujours 0 sur le calcul public.", "note_en": "commercial_discount is an owner-only lever, always 0 on the public calculation."}, {"step": "taxes_and_deposit", "formula": "total_ht = total_ttc / (1 + vat_rate/100); vat = total_ttc - total_ht; deposit = total_ttc * deposit_rate", "note_fr": "Tous les montants sont arrondis au centime (arrondi commercial, demi vers le haut).", "note_en": "All amounts are rounded to the cent (half-up)."}], "specialist_day_rates": [{"specialty": "marketing_engineering", "specialty_factor": 0.88, "day_rate_ttc": 792.0}, {"specialty": "data_engineering", "specialty_factor": 0.94, "day_rate_ttc": 846.0}, {"specialty": "training", "specialty_factor": 1.0, "day_rate_ttc": 900.0}, {"specialty": "cdm", "specialty_factor": 1.0, "day_rate_ttc": 900.0}, {"specialty": "pv", "specialty_factor": 1.02, "day_rate_ttc": 918.0}, {"specialty": "ai_security", "specialty_factor": 1.06, "day_rate_ttc": 954.0}, {"specialty": "agentic_ai", "specialty_factor": 1.08, "day_rate_ttc": 972.0}, {"specialty": "blockchain", "specialty_factor": 1.08, "day_rate_ttc": 972.0}, {"specialty": "healthtech", "specialty_factor": 1.08, "day_rate_ttc": 972.0}, {"specialty": "reg_csv", "specialty_factor": 1.18, "day_rate_ttc": 1062.0}], "market_benchmarks": [{"key": "pv", "label_fr": "Pharmacovigilance / Data Engineer", "label_en": "Pharmacovigilance / Data Engineer", "p25_eur_day": 340, "median_eur_day": 420, "p75_eur_day": 500, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre", "verified_on": "2026-07-22"}, {"key": "cdm", "label_fr": "Clinical Data Management", "label_en": "Clinical Data Management", "p25_eur_day": 380, "median_eur_day": 460, "p75_eur_day": 540, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre", "verified_on": "2026-07-22"}, {"key": "healthtech", "label_fr": "HealthTech / PharmaTech Product Engineer", "label_en": "HealthTech / PharmaTech Product Engineer", "p25_eur_day": 420, "median_eur_day": 530, "p75_eur_day": 620, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre", "verified_on": "2026-07-22"}, {"key": "marketing_engineering", "label_fr": "Growth / Marketing Engineering", "label_en": "Growth / Marketing Engineering", "p25_eur_day": 510, "median_eur_day": 570, "p75_eur_day": 640, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre", "verified_on": "2026-07-22"}, {"key": "data_engineering", "label_fr": "Data Engineer", "label_en": "Data Engineer", "p25_eur_day": 540, "median_eur_day": 650, "p75_eur_day": 740, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre", "verified_on": "2026-07-22"}, {"key": "ai_security", "label_fr": "Consultant cybersécurité", "label_en": "Cybersecurity Consultant", "p25_eur_day": 630, "median_eur_day": 750, "p75_eur_day": 880, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre", "verified_on": "2026-07-22"}, {"key": "blockchain", "label_fr": "Développeur Blockchain", "label_en": "Blockchain Developer", "p25_eur_day": 610, "median_eur_day": 750, "p75_eur_day": 860, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre/developpeur", "verified_on": "2026-07-22"}, {"key": "agentic_ai", "label_fr": "IA / LLM", "label_en": "AI / LLM", "p25_eur_day": 680, "median_eur_day": 820, "p75_eur_day": 930, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre", "verified_on": "2026-07-22"}, {"key": "training", "label_fr": "Formateur IT", "label_en": "IT Trainer", "p25_eur_day": 500, "median_eur_day": 820, "p75_eur_day": 910, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre", "verified_on": "2026-07-22"}, {"key": "reg_csv", "label_fr": "Ingénieur réglementaire / CSV", "label_en": "Regulatory / CSV Engineer", "p25_eur_day": 750, "median_eur_day": 1100, "p75_eur_day": 1350, "source_name": "TJMètre", "source_url": "https://tjmetre.fr/barometre", "verified_on": "2026-07-22"}], "worked_example": {"input": {"specialty": "data_engineering", "complexity": "standard", "duration_tier": "3m", "zone": "Z2", "stability": "same_address", "reservation_urgency": "15_29_days", "travel_type": "productive_train", "total_days": 20, "onsite_days": 8, "consecutive_days": 4, "travel_hours": 10, "travel_days": 4, "transport": 880, "nights": 4, "hotel_nightly": 160, "meals": 200, "facility_responsibility": "client_provided", "promo_code": ""}, "output": {"rates": {"remote_daily_ttc": 774.56, "onsite_daily_ttc": 902.4}, "totals": {"subtotal_ttc": 20266.69, "total_ttc": 20266.69, "total_ht": 16888.91, "vat": 3377.78, "deposit_ttc": 6080.01, "all_in_per_work_day_ttc": 1013.33}, "schedule": {"onsite_blocks": 2, "max_onsite_streak": 5, "pattern": "O3 · R12 · O5", "legend_fr": "O = sur site, R = à distance", "legend_en": "O = onsite, R = remote"}}, "note_fr": "Montants recalculés en direct à chaque requête ; soumettez la même entrée au point de calcul public pour obtenir exactement ces montants et valider votre implémentation.", "note_en": "Amounts recomputed live on every request; submit the same input to the public compute endpoint to obtain exactly these amounts and validate your implementation."}, "endpoints": {"compute": "/api/public/quote", "spec": "/api/public/pricing-spec", "destinations": "/api/destinations", "method_page": "/outils/calculator/methode/", "mcp": "/mcp", "openapi": "/api/openapi.json"}, "notice_fr": "Estimation non contractuelle et indicative. Les frais réels, disponibilités, contraintes et règles de remboursement sont validés avant tout devis engageant.", "notice_en": "Non-contractual, indicative estimate. Actual expenses, availability, constraints and reimbursement rules are validated before any binding quote."}