[FEAT] Ruolo consulente: visibilità firm-scoped (org-switcher + Cruscotto Studio)
Un utente con role='consultant' e consulting_firm_id vede solo i CLIENTI del proprio studio (organizations.consulting_firm_id = suo firm) UNION le proprie membership dirette — non tutte le org (quello resta super_admin), non solo le membership. Applicato in OrganizationController::list (selettore azienda) e ConsultantController::portfolio (cruscotto). Additivo: super_admin e altri ruoli invariati. Verificato: utente-test consultant/firm1 vede 2 aziende (cliente studio 996003 + membership 996001), non tutte. version 1.25.11. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a8516efafc
commit
faadb62da6
@@ -19,12 +19,24 @@ class ConsultantController extends BaseController
|
|||||||
$user = $this->getCurrentUser() ?? [];
|
$user = $this->getCurrentUser() ?? [];
|
||||||
$uid = (int) $this->getCurrentUserId();
|
$uid = (int) $this->getCurrentUserId();
|
||||||
|
|
||||||
// Aziende visibili all'utente (stessa regola di OrganizationController::list).
|
// Aziende visibili all'utente (stessa regola di OrganizationController::list):
|
||||||
|
// super_admin = tutte; consulente = clienti del proprio studio (consulting_firm_id)
|
||||||
|
// UNION le proprie membership; altri = solo le proprie membership.
|
||||||
|
$firmId = (int) ($user['consulting_firm_id'] ?? 0);
|
||||||
if (($user['role'] ?? '') === 'super_admin') {
|
if (($user['role'] ?? '') === 'super_admin') {
|
||||||
$orgs = Database::fetchAll(
|
$orgs = Database::fetchAll(
|
||||||
"SELECT id, name, entity_type, voluntary_compliance, sector
|
"SELECT id, name, entity_type, voluntary_compliance, sector
|
||||||
FROM organizations WHERE is_active = 1 ORDER BY name LIMIT 200"
|
FROM organizations WHERE is_active = 1 ORDER BY name LIMIT 200"
|
||||||
);
|
);
|
||||||
|
} elseif (($user['role'] ?? '') === 'consultant' && $firmId > 0) {
|
||||||
|
$orgs = Database::fetchAll(
|
||||||
|
"SELECT DISTINCT o.id, o.name, o.entity_type, o.voluntary_compliance, o.sector
|
||||||
|
FROM organizations o
|
||||||
|
LEFT JOIN user_organizations uo ON uo.organization_id = o.id AND uo.user_id = ?
|
||||||
|
WHERE o.is_active = 1 AND (o.consulting_firm_id = ? OR uo.user_id IS NOT NULL)
|
||||||
|
ORDER BY o.name LIMIT 200",
|
||||||
|
[$uid, $firmId]
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
$orgs = Database::fetchAll(
|
$orgs = Database::fetchAll(
|
||||||
"SELECT o.id, o.name, o.entity_type, o.voluntary_compliance, o.sector
|
"SELECT o.id, o.name, o.entity_type, o.voluntary_compliance, o.sector
|
||||||
|
|||||||
@@ -124,8 +124,20 @@ class OrganizationController extends BaseController
|
|||||||
{
|
{
|
||||||
$this->requireAuth();
|
$this->requireAuth();
|
||||||
|
|
||||||
|
$firmId = (int) ($this->currentUser['consulting_firm_id'] ?? 0);
|
||||||
if ($this->currentUser['role'] === 'super_admin') {
|
if ($this->currentUser['role'] === 'super_admin') {
|
||||||
$orgs = Database::fetchAll('SELECT * FROM organizations WHERE is_active = 1 ORDER BY name');
|
$orgs = Database::fetchAll('SELECT * FROM organizations WHERE is_active = 1 ORDER BY name');
|
||||||
|
} elseif ($this->currentUser['role'] === 'consultant' && $firmId > 0) {
|
||||||
|
// Consulente: vede TUTTI i clienti del proprio studio (organizations.consulting_firm_id
|
||||||
|
// = il suo firm) UNION le org di cui è membro diretto. Non l'intero DB (quello è super_admin).
|
||||||
|
$orgs = Database::fetchAll(
|
||||||
|
'SELECT DISTINCT o.*, uo.role AS user_role, uo.is_primary
|
||||||
|
FROM organizations o
|
||||||
|
LEFT JOIN user_organizations uo ON uo.organization_id = o.id AND uo.user_id = ?
|
||||||
|
WHERE o.is_active = 1 AND (o.consulting_firm_id = ? OR uo.user_id IS NOT NULL)
|
||||||
|
ORDER BY uo.is_primary DESC, o.name',
|
||||||
|
[$this->getCurrentUserId(), $firmId]
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
$orgs = Database::fetchAll(
|
$orgs = Database::fetchAll(
|
||||||
'SELECT o.*, uo.role as user_role, uo.is_primary
|
'SELECT o.*, uo.role as user_role, uo.is_primary
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
{"version": "1.25.10", "build": "2026-07-29-v1.25.10", "date": "2026-07-29", "changelog": "Gestione Rischi: la tabella 'Rischi dai requisiti del framework di sicurezza' ora scorre verticalmente (riquadro a scorrimento con intestazione fissa) invece di allungare la pagina, e mostra SOLO i requisiti applicabili alla classe del soggetto (importante -> Allegato 1, essenziale -> Allegato 2 della Determinazione ACN 164179/2025): i requisiti non pertinenti non compaiono piu."}
|
{"version": "1.25.11", "build": "2026-07-29-v1.25.11", "date": "2026-07-29", "changelog": "Cruscotto Studio: ora e' previsto anche il ruolo CONSULENTE. Un utente con ruolo 'consulente' vede nel selettore azienda e nel Cruscotto Studio SOLO le aziende del proprio studio (i clienti collegati al proprio studio) piu' quelle di cui e' membro diretto, non l'intero elenco (che resta agli amministratori)."}
|
||||||
|
|||||||
Reference in New Issue
Block a user