{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://oto-enterprise-os-dtp/rbac/roleprofile.schema.json",
  "title": "Bundle Role Profile généré depuis rbac_50_roles.json",
  "description": "Contrat de sortie de roleprofile_gen.py. Validé par le validateur maison Publiciste (zéro pip) dans le job CI rbac-roleprofile-tests. Un Role Profile ERPNext v15 natif par portail distinct du contrat ; chaque profil bundle les rôles (Has Role) de son portail. Couverture bijective des 50 rôles.",
  "type": "object",
  "additionalProperties": false,
  "required": ["manifest", "role_profile"],
  "properties": {
    "manifest": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "generated_from",
        "source_version",
        "cible_rbac_roles",
        "counts",
        "profiles"
      ],
      "properties": {
        "generated_from": { "type": "string", "const": "rbac_50_roles.json" },
        "source_version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
        "cible_rbac_roles": { "type": "integer", "const": 50 },
        "counts": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "role_profiles",
            "portails_metier",
            "portails_techniques",
            "roles_couverts"
          ],
          "properties": {
            "role_profiles": { "type": "integer", "minimum": 1 },
            "portails_metier": { "type": "integer", "minimum": 0 },
            "portails_techniques": { "type": "integer", "minimum": 0 },
            "roles_couverts": { "type": "integer", "minimum": 50, "maximum": 50 }
          }
        },
        "profiles": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/definitions/profile_meta" }
        }
      }
    },
    "role_profile": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/definitions/role_profile_fixture" }
    }
  },
  "definitions": {
    "profile_meta": {
      "type": "object",
      "additionalProperties": false,
      "required": ["portail", "role_profile", "metier", "nb_roles"],
      "properties": {
        "portail": { "type": "string", "minLength": 1 },
        "role_profile": { "type": "string", "pattern": "^OTO Portail " },
        "metier": { "type": "boolean" },
        "nb_roles": { "type": "integer", "minimum": 1 }
      }
    },
    "role_profile_fixture": {
      "type": "object",
      "additionalProperties": false,
      "required": ["doctype", "name", "role_profile", "roles"],
      "properties": {
        "doctype": { "type": "string", "const": "Role Profile" },
        "name": { "type": "string", "pattern": "^OTO Portail " },
        "role_profile": { "type": "string", "pattern": "^OTO Portail " },
        "roles": {
          "type": "array",
          "minItems": 1,
          "items": { "$ref": "#/definitions/has_role_row" }
        }
      }
    },
    "has_role_row": {
      "type": "object",
      "additionalProperties": false,
      "required": ["doctype", "parentfield", "parenttype", "role"],
      "properties": {
        "doctype": { "type": "string", "const": "Has Role" },
        "parentfield": { "type": "string", "const": "roles" },
        "parenttype": { "type": "string", "const": "Role Profile" },
        "role": { "type": "string", "pattern": "^OTO " }
      }
    }
  }
}
