[FEAT] Supply chain Fase 1: modulo questionari configurabile (categorie + template + domande + import)

Backend del modulo questionari fornitori (design docs/DESIGN_MODULO_QUESTIONARI_FORNITORI.md).
Migrazioni 032+033 gia applicate su host (6 tabelle + 10 categorie preset + suppliers.category_id/external_ref/source).

SupplyChainController:
- categorie: categories/createCategory/updateCategory/deleteCategory (preset org 0 + custom per-org, no delete se in uso)
- template: templates/getTemplate/createTemplate/updateTemplate (per-org, scope categoria)
- domande: addTemplateQuestion/updateTemplateQuestion/deleteTemplateQuestion (7 tipi, weight, nis2_ref, vuln_flag, high_criticality_only)
- import: importSuppliers + bulkUpsertSuppliers (upsert per external_ref, anti formula-injection CSV, max 1000, riusabile da API key)
- helper: assertCategoryVisible/assertTemplateOwned/slugify/sanitizeCell

Tutte le query org-scoped (no leak cross-org). Route in public/index.php actionMap supply-chain.
Smoke: no-auth=401, categcategorie_visibili=10 (preset). USR2 applicato. php -l OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-05-31 10:36:44 +02:00
co-authored by Claude Opus 4.8
parent 34bac1a237
commit f85876f2a2
2 changed files with 419 additions and 0 deletions
+13
View File
@@ -280,6 +280,19 @@ $actionMap = [
'GET:{id}/questionnaireStatus' => 'questionnaireStatus',
'GET:{id}/questionnaire-status' => 'questionnaireStatus',
'POST:{id}/assess' => 'assessSupplier',
// Modulo questionari configurabile (Fase 1): categorie, template, domande, import
'GET:categories' => 'categories',
'POST:categories' => 'createCategory',
'PUT:categories/{subId}' => 'updateCategory',
'DELETE:categories/{subId}' => 'deleteCategory',
'GET:templates' => 'templates',
'POST:templates' => 'createTemplate',
'GET:templates/{subId}' => 'getTemplate',
'PUT:templates/{subId}' => 'updateTemplate',
'POST:{id}/questions' => 'addTemplateQuestion', // {id} = template id
'PUT:questions/{subId}' => 'updateTemplateQuestion',
'DELETE:questions/{subId}' => 'deleteTemplateQuestion',
'POST:import' => 'importSuppliers',
'GET:{id}' => 'get',
'PUT:{id}' => 'update',
'DELETE:{id}' => 'delete',