{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://oto.dtp/schemas/faisabilite/projets_master.schema.json", "title": "Contrat d'extraction Publiciste (projets_master.json)", "description": "Contrat de données produit par le parser Faisabilité et consommé par le Publiciste Agent (otoia/capabilities/publiciste.py) pour générer vente.otov7.com. Zéro invention: chaque valeur provient de data_room/PXX/ (contrainte CLAUDE.md #6).", "type": "object", "required": ["generated_at", "template_version", "projets"], "additionalProperties": false, "properties": { "generated_at": { "type": "string", "format": "date-time" }, "template_version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" }, "projets": { "type": "array", "items": { "$ref": "#/definitions/projet" } } }, "definitions": { "projet": { "type": "object", "required": ["code", "nom", "statut", "localisation", "typologies", "inclus", "source"], "additionalProperties": false, "properties": { "code": { "type": "string", "pattern": "^P0[1-9]$" }, "nom": { "type": "string", "minLength": 1 }, "statut": { "type": "string", "enum": ["disponible", "en_developpement", "bientot", "en_processus"], "description": "Mappé depuis _META/version.json.statut_faisabilite. Faisabilité incomplète => 'en_developpement'." }, "positionnement": { "type": "object", "description": "Copy marketing multilingue générée depuis le positionnement documenté (jamais inventée).", "additionalProperties": false, "properties": { "fr": { "type": "string" }, "en": { "type": "string" }, "es": { "type": "string" } } }, "localisation": { "type": "string" }, "typologies": { "type": "array", "description": "Reprise fidèle du tableau §3.2 du template. Vide autorisé UNIQUEMENT si statut != 'disponible'.", "items": { "type": "object", "required": ["nom", "prix_depuis_usd"], "additionalProperties": false, "properties": { "nom": { "type": "string" }, "quantite": { "type": ["integer", "null"], "minimum": 0 }, "surface_interieure_m2": { "type": ["number", "null"] }, "surface_terrasse_m2": { "type": ["number", "null"] }, "surface_totale_m2": { "type": ["number", "null"] }, "prix_depuis_usd": { "type": ["number", "null"], "description": "Prix 'à partir de' en USD. null autorisé seulement si statut != 'disponible'." }, "prix_depuis_dop": { "type": ["number", "null"] } } } }, "inclus": { "type": "array", "items": { "type": "string" }, "description": "Services/équipements inclus (volet 3.3 du template)." }, "rendus": { "type": "array", "description": "Rendus liés au projet réel (❌ IA générique interdite - contrainte CLAUDE.md).", "items": { "type": "object", "required": ["fichier"], "additionalProperties": false, "properties": { "fichier": { "type": "string" }, "vue": { "type": "string" }, "hero": { "type": "boolean" } } } }, "source": { "type": "object", "description": "Traçabilité: fichiers data_room sources (contrainte #6).", "required": ["template_version", "score_4big"], "additionalProperties": false, "properties": { "template_version": { "type": "string" }, "score_4big": { "type": "integer", "minimum": 0, "maximum": 100 }, "fichiers": { "type": "array", "items": { "type": "string" } } } } }, "allOf": [ { "if": { "properties": { "statut": { "const": "disponible" } } }, "then": { "properties": { "typologies": { "minItems": 1, "items": { "properties": { "prix_depuis_usd": { "type": "number" } }, "required": ["prix_depuis_usd"] } } } } } ] } } }