Files
Claude Code DTP Worker cc3e5aef0e [DTP-Worker] Sprint 2 · ERPNext RBAC 50 rôles (schéma + data + spec + gate)
Livrable Sprint 2 (roadmap §S2 l.38 « RBAC 50 rôles configuration »,
GAP_ANALYSIS §3.4). Seul deliverable S2 100% autorable en-repo — les clones
Frontend/CRM dépendent des layouts LIVE (VPS).

- rbac/rbac.schema.json — contrat JSON-Schema draft-07 (sous-ensemble validateur
  maison, zéro pip) : 50 rôles, DocPerm par DocType, scope User Permission.
- rbac/rbac_50_roles.json — 50 rôles × 5 portails métier + console plateforme,
  mappés aux entités CLAUDE.md, ciblant des DocTypes ERPNext v15 natifs.
- rbac/RBAC_50_ROLES_SPEC.md — design RBAC 3 niveaux + séparation des pouvoirs +
  procédure d'application VPS (fixtures bench, hors périmètre worker).
- rbac/tests/test_rbac.py — 10 tests unittest (réutilise le validateur
  Publiciste, pas de doublon) : 50 rôles exacts, unicité, 5 portails, anti-
  élévation de privilège. Oracle jsonschema si présent.
- ci.yml — job rbac-tests ajouté au gate (Gitea Actions uniquement).
- GAP_ANALYSIS §3.4 + daily report 2026-07-30 (session 4) mis à jour.

Anti-invention #6 : aucun plafond monétaire inventé ; DocTypes non natifs
marqués custom → à confirmer VPS. Gate local vert (guard/json/docs + 10 tests
RBAC + 23 tests Publiciste régression).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-30 02:05:54 +00:00

122 lines
5.2 KiB
JSON

{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://oto.dtp/schemas/rbac/rbac.schema.json",
"title": "Contrat RBAC · OTO Enterprise OS DTP (50 rôles)",
"description": "Design machine-lisible des 50 rôles RBAC (CLAUDE.md · roadmap Sprint 2 · ERPNext Backend). Chaque rôle cible un Role natif Frappe v15 + un jeu de permissions par DocType. Les bindings sont la CIBLE à appliquer sur le VPS par l'agent ERPNext (bench/fixtures) — ce document ne touche jamais la prod (contrainte worker).",
"type": "object",
"required": ["version", "generated_at", "cible_rbac_roles", "portails_business", "roles"],
"additionalProperties": false,
"properties": {
"version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
"generated_at": { "type": "string", "format": "date-time" },
"cible_rbac_roles": {
"type": "integer",
"const": 50,
"description": "Cible non-négociable CLAUDE.md « RBAC 50 rôles ». La longueur de roles[] DOIT valoir 50 (contrôlé par le test)."
},
"portails_business": {
"type": "array",
"minItems": 5,
"maxItems": 5,
"uniqueItems": true,
"items": { "type": "string", "enum": ["ventes", "construction", "achat", "compta", "direction"] },
"description": "Les 5 portails rôle métier de la roadmap Sprint 4. « plateforme » est une console technique transversale, hors de ce compte de 5."
},
"roles": {
"type": "array",
"minItems": 50,
"maxItems": 50,
"items": { "$ref": "#/definitions/role" }
}
},
"definitions": {
"role": {
"type": "object",
"required": [
"id", "nom_fr", "famille", "portail", "entite_principale",
"niveau", "erpnext_role_name", "scope_donnees", "description",
"modules", "permissions_cibles"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
"minLength": 3,
"description": "Identifiant kebab-case unique (unicité vérifiée par le test)."
},
"nom_fr": { "type": "string", "minLength": 1 },
"famille": {
"type": "string",
"enum": ["direction", "ventes", "marketing", "construction", "achat", "finance", "faisabilite", "legal", "plateforme"]
},
"portail": {
"type": "string",
"enum": ["ventes", "construction", "achat", "compta", "direction", "plateforme"],
"description": "Console de rattachement. Les 5 premières = portails métier (roadmap S4) ; « plateforme » = console technique transversale."
},
"entite_principale": {
"type": "string",
"enum": ["WAF", "WAG", "WA SRL", "AC Arias Cuevas", "Consortium ECR DR", "Helios RD", "Ploutos", "9060 QC", "Groupe"],
"description": "Entité juridique de rattachement principal (CLAUDE.md §Entités). « Groupe » = périmètre consolidé transversal."
},
"niveau": {
"type": "integer",
"minimum": 1,
"maximum": 5,
"description": "Niveau hiérarchique/sensibilité : 1 externe/opérationnel → 5 direction/système."
},
"erpnext_role_name": {
"type": "string",
"minLength": 4,
"pattern": "^OTO ",
"description": "Nom du DocType Role Frappe v15 à créer (préfixe « OTO » pour ne pas entrer en collision avec les rôles natifs). Unicité vérifiée par le test."
},
"scope_donnees": {
"type": "string",
"enum": ["own", "equipe", "entite", "groupe"],
"description": "Row-level (User Permissions Frappe) : own=ses docs · equipe=son équipe · entite=sa Company · groupe=consolidé."
},
"description": { "type": "string", "minLength": 1 },
"modules": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": { "type": "string", "minLength": 1 },
"description": "Modules/Workspaces ERPNext visibles pour ce rôle."
},
"permissions_cibles": {
"type": "array",
"minItems": 1,
"description": "Bindings CIBLES par DocType (à appliquer sur VPS via fixtures). Verbes = actions de permission Frappe v15.",
"items": {
"type": "object",
"required": ["doctype", "actions"],
"additionalProperties": false,
"properties": {
"doctype": { "type": "string", "minLength": 1 },
"custom": {
"type": "boolean",
"description": "true = DocType OTOV7/DTP à créer (non natif ERPNext) — à confirmer VPS avant application."
},
"actions": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"enum": [
"read", "write", "create", "delete", "submit", "cancel",
"amend", "print", "email", "export", "import", "report",
"share", "set_user_permissions"
]
}
}
}
}
}
}
}
}
}