[INVITE] Sistema inviti/licenze B2B + provisioning con invite_token
- InviteController: CRUD inviti (gen, list, show, revoke, rigenera, validate) - Token inv_* sha256-hashed, one-shot o multi-use, canali, scadenza - ServicesController::provision() accetta invite_token al posto di X-Provision-Secret Piano e durata forzati dall'invito, markUsed() chiaamto dopo provisioning riuscito - index.php: routing /api/invites/* aggiunto (controller + action map) - integrazioniext.html: nuovo tab "Inviti & Licenze" con flow completo, endpoints, esempi curl/php, guida lg231 aggiornata con sezione provisioning automatico Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
6933e1d3fb
commit
612befd66d
@@ -0,0 +1,58 @@
|
||||
-- ============================================================
|
||||
-- NIS2 Agile — Migration 012: Sistema Inviti / Licenze
|
||||
-- Inviti a tempo per provisioning automatico da e-commerce,
|
||||
-- lg231 e altri sistemi Agile partner.
|
||||
-- ============================================================
|
||||
|
||||
USE nis2_agile_db;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS invites (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
|
||||
-- Token (visibile al chiamante, formato: inv_XXXX...)
|
||||
token_prefix VARCHAR(16) NOT NULL, -- es: inv_a1b2c3
|
||||
token_hash VARCHAR(64) NOT NULL UNIQUE, -- SHA-256 del token completo
|
||||
|
||||
-- Configurazione licenza
|
||||
plan ENUM('essentials','professional','enterprise') NOT NULL DEFAULT 'professional',
|
||||
duration_months TINYINT UNSIGNED NOT NULL DEFAULT 12,
|
||||
label VARCHAR(255) NULL, -- es: "lg231 Partner Q1 2026"
|
||||
notes TEXT NULL,
|
||||
|
||||
-- Limiti utilizzo
|
||||
max_uses TINYINT UNSIGNED NOT NULL DEFAULT 1, -- 1 = one-shot, N = multi-use
|
||||
used_count TINYINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
|
||||
-- Scadenza invito (indipendente dalla scadenza licenza)
|
||||
expires_at DATETIME NOT NULL,
|
||||
|
||||
-- Canale di distribuzione
|
||||
channel VARCHAR(64) NULL, -- 'lg231', 'ecommerce', 'direct', 'manual'
|
||||
issued_to VARCHAR(255) NULL, -- email o nome destinatario
|
||||
issued_by INT UNSIGNED NULL, -- user_id NIS2 admin che ha generato
|
||||
|
||||
-- Utilizzo
|
||||
status ENUM('pending','used','expired','revoked') NOT NULL DEFAULT 'pending',
|
||||
used_at DATETIME NULL,
|
||||
used_by_org_id INT UNSIGNED NULL, -- org creata dall'invito
|
||||
used_by_ip VARCHAR(45) NULL,
|
||||
|
||||
-- Restrizioni facoltative
|
||||
restrict_vat VARCHAR(11) NULL, -- solo per questa P.IVA
|
||||
restrict_email VARCHAR(255) NULL, -- solo per questo admin email
|
||||
|
||||
-- Metadata extra (JSON)
|
||||
metadata JSON NULL, -- dati extra (es: lg231 order_id)
|
||||
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
PRIMARY KEY (id),
|
||||
INDEX idx_invites_token_hash (token_hash),
|
||||
INDEX idx_invites_status (status),
|
||||
INDEX idx_invites_channel (channel),
|
||||
INDEX idx_invites_expires (expires_at),
|
||||
INDEX idx_invites_org (used_by_org_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
SELECT 'Migration 012 invites completata.' AS stato;
|
||||
Reference in New Issue
Block a user