34f202af40
Contrat pipeline commercial CRM natif (lead → visite → devis → réservation → contrat → CONFOTUR) → fixtures Frappe/ERPNext v15 : Workflow (9 états / 11 transitions) + Workflow State + Workflow Action Master + MANIFEST. Rôles gardant états/transitions résolus depuis rbac_50_roles.json (réutilisation, zéro duplication · #6) : le contrat ne cite qu'un id de rôle, jamais un nom Frappe en dur. CLI build/validate refuse d'écrire si l'un des 9 invariants de graphe casse (monotonie doc_status, atteignabilité, séparation des pouvoirs sur les étapes engageant de l'argent / clôturant). 25 tests (stdlib pur + oracle jsonschema) · job CI crm-workflow-vente-tests ajouté au gate · 146 tests de régression verts au total. Application VPS (DocType porteur OTO Dossier Vente + bench migrate) = agent ERPNext Backend, hors périmètre worker. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
188 lines
6.4 KiB
JSON
188 lines
6.4 KiB
JSON
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"$id": "https://oto-enterprise-os-dtp/crm/workflow.schema.json",
|
|
"title": "Bundle de fixtures ERPNext Workflow généré depuis workflow_vente_spec.json",
|
|
"description": "Contrat de sortie du générateur workflow_vente_gen.py. Validé par le validateur maison Publiciste (zéro pip) dans le job CI crm-workflow-vente-tests.",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["manifest", "workflow", "workflow_state", "workflow_action_master"],
|
|
"properties": {
|
|
"manifest": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"generated_from",
|
|
"rbac_source",
|
|
"source_version",
|
|
"workflow_name",
|
|
"document_type",
|
|
"document_type_custom",
|
|
"counts",
|
|
"custom_doctypes_a_confirmer",
|
|
"roles_rbac_utilises"
|
|
],
|
|
"properties": {
|
|
"generated_from": { "type": "string", "const": "workflow_vente_spec.json" },
|
|
"rbac_source": { "type": "string", "const": "rbac_50_roles.json" },
|
|
"source_version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
|
|
"workflow_name": { "type": "string", "minLength": 1 },
|
|
"document_type": { "type": "string", "minLength": 1 },
|
|
"document_type_custom": { "type": "boolean" },
|
|
"counts": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"states",
|
|
"transitions",
|
|
"workflow_state_masters",
|
|
"workflow_action_masters",
|
|
"terminal_states"
|
|
],
|
|
"properties": {
|
|
"states": { "type": "integer", "minimum": 2 },
|
|
"transitions": { "type": "integer", "minimum": 1 },
|
|
"workflow_state_masters": { "type": "integer", "minimum": 2 },
|
|
"workflow_action_masters": { "type": "integer", "minimum": 1 },
|
|
"terminal_states": { "type": "integer", "minimum": 1 }
|
|
}
|
|
},
|
|
"custom_doctypes_a_confirmer": {
|
|
"type": "array",
|
|
"uniqueItems": true,
|
|
"items": { "type": "string", "minLength": 1 }
|
|
},
|
|
"roles_rbac_utilises": {
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"items": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["role_id", "erpnext_role_name"],
|
|
"properties": {
|
|
"role_id": { "type": "string", "minLength": 1 },
|
|
"erpnext_role_name": { "type": "string", "pattern": "^OTO " }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"workflow": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"doctype",
|
|
"name",
|
|
"workflow_name",
|
|
"document_type",
|
|
"workflow_state_field",
|
|
"is_active",
|
|
"send_email_alert",
|
|
"override_status",
|
|
"states",
|
|
"transitions"
|
|
],
|
|
"properties": {
|
|
"doctype": { "type": "string", "const": "Workflow" },
|
|
"name": { "type": "string", "minLength": 1 },
|
|
"workflow_name": { "type": "string", "minLength": 1 },
|
|
"document_type": { "type": "string", "minLength": 1 },
|
|
"workflow_state_field": { "type": "string", "minLength": 1 },
|
|
"is_active": { "$ref": "#/definitions/flag" },
|
|
"send_email_alert": { "$ref": "#/definitions/flag" },
|
|
"override_status": { "$ref": "#/definitions/flag" },
|
|
"states": {
|
|
"type": "array",
|
|
"minItems": 2,
|
|
"items": { "$ref": "#/definitions/document_state" }
|
|
},
|
|
"transitions": {
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"items": { "$ref": "#/definitions/transition" }
|
|
}
|
|
}
|
|
},
|
|
"workflow_state": {
|
|
"type": "array",
|
|
"minItems": 2,
|
|
"items": { "$ref": "#/definitions/state_master" }
|
|
},
|
|
"workflow_action_master": {
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"items": { "$ref": "#/definitions/action_master" }
|
|
}
|
|
},
|
|
"definitions": {
|
|
"flag": { "type": "integer", "enum": [0, 1] },
|
|
"docstatus": { "type": "string", "enum": ["0", "1", "2"] },
|
|
"style": {
|
|
"type": "string",
|
|
"enum": ["", "Primary", "Info", "Success", "Warning", "Danger", "Inverse"]
|
|
},
|
|
"document_state": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"state",
|
|
"doc_status",
|
|
"allow_edit",
|
|
"update_field",
|
|
"update_value",
|
|
"is_optional_state",
|
|
"message"
|
|
],
|
|
"properties": {
|
|
"state": { "type": "string", "minLength": 1 },
|
|
"doc_status": { "$ref": "#/definitions/docstatus" },
|
|
"allow_edit": { "type": "string", "pattern": "^OTO " },
|
|
"update_field": { "type": "string", "minLength": 1 },
|
|
"update_value": { "type": "string", "minLength": 1 },
|
|
"is_optional_state": { "$ref": "#/definitions/flag" },
|
|
"message": { "type": "string", "minLength": 1 }
|
|
}
|
|
},
|
|
"transition": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"state",
|
|
"action",
|
|
"next_state",
|
|
"allowed",
|
|
"allow_self_approval",
|
|
"condition"
|
|
],
|
|
"properties": {
|
|
"state": { "type": "string", "minLength": 1 },
|
|
"action": { "type": "string", "minLength": 1 },
|
|
"next_state": { "type": "string", "minLength": 1 },
|
|
"allowed": { "type": "string", "pattern": "^OTO " },
|
|
"allow_self_approval": { "$ref": "#/definitions/flag" },
|
|
"condition": { "type": ["string", "null"] }
|
|
}
|
|
},
|
|
"state_master": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["doctype", "name", "workflow_state_name", "style"],
|
|
"properties": {
|
|
"doctype": { "type": "string", "const": "Workflow State" },
|
|
"name": { "type": "string", "minLength": 1 },
|
|
"workflow_state_name": { "type": "string", "minLength": 1 },
|
|
"style": { "$ref": "#/definitions/style" }
|
|
}
|
|
},
|
|
"action_master": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["doctype", "name", "workflow_action_name"],
|
|
"properties": {
|
|
"doctype": { "type": "string", "const": "Workflow Action Master" },
|
|
"name": { "type": "string", "minLength": 1 },
|
|
"workflow_action_name": { "type": "string", "minLength": 1 }
|
|
}
|
|
}
|
|
}
|
|
}
|