Completa le traduzioni EN/TH e corregge sezioni home ancora solo in italiano.
Stats e prodotti non usavano il locale, quindi dopo lo switch lingua lo scroll mostrava ancora l'italiano. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -1,66 +1,66 @@
|
||||
---
|
||||
import SubpageLayout from '../layouts/SubpageLayout.astro';
|
||||
import {
|
||||
modelloOrganizzativo,
|
||||
modelloOrganizzativoRuoli,
|
||||
modelloOrganizzativoGovernance,
|
||||
modelloOrganizzativoResponsabilitaSintesi,
|
||||
modelloOrganizzativoControlliLean,
|
||||
modelloOrganizzativoKpi,
|
||||
modelloOrganizzativoDocumentazione,
|
||||
modelloOrganizzativoPiano30,
|
||||
modelloOrganizzativoOutsourcing,
|
||||
modelloOrganizzativoNote,
|
||||
modelloOrganizzativoFlussiDecisionali,
|
||||
} from '../data/modello-organizzativo';
|
||||
import { getModelloOrganizzativo } from '../data/modello-organizzativo';
|
||||
|
||||
const path = Astro.url.pathname;
|
||||
const localeMatch = path.match(/^\/(en|th)(\/|$)/);
|
||||
const currentLocale = (localeMatch?.[1] ?? 'it') as 'it' | 'en' | 'th';
|
||||
const m = getModelloOrganizzativo(currentLocale);
|
||||
const { page } = m;
|
||||
|
||||
const localize = (href: string) => {
|
||||
if (currentLocale === 'it') return href;
|
||||
if (href.startsWith(`/${currentLocale}`)) return href;
|
||||
if (href.startsWith('/#')) return `/${currentLocale}${href}`;
|
||||
if (href.startsWith('/')) return `/${currentLocale}${href}`;
|
||||
return href;
|
||||
};
|
||||
|
||||
const link = 'text-sky-400/90 underline-offset-2 hover:text-sky-300 hover:underline';
|
||||
const tbl = 'min-w-[22rem] w-full border-collapse text-left text-sm';
|
||||
const th = 'border border-nx-border bg-nx-surface/60 px-3 py-2 font-semibold text-nx-fg';
|
||||
const td = 'border border-nx-border px-3 py-2 align-top text-nx-muted';
|
||||
const tableWrap = 'mt-2 overflow-x-auto';
|
||||
const mark = (on?: boolean) => (on ? '●' : '');
|
||||
---
|
||||
|
||||
<SubpageLayout
|
||||
title="Modello organizzativo — NexStudio"
|
||||
description="Modello organizzativo NexStudio: governance, ruoli, RACI, controlli lean, KPI, piano 30 giorni — per le linee LexAura (Legal Tech) e MediAura (Health Tech)."
|
||||
heading="Modello organizzativo"
|
||||
lead="Ruoli, ritmi di governo, processi e controlli «lean» in una software house con SaaS a elevata regolamentazione. Complementare al codice etico. Non sostituisce statuti, modelli di compliance societari (es. 231) né pareri legali: andate in parallelo con struttura reale e consulenti."
|
||||
title={page.title}
|
||||
description={page.description}
|
||||
heading={page.heading}
|
||||
lead={page.lead}
|
||||
>
|
||||
<div class="[&_h3]:mt-6 [&_h3]:text-base [&_h3]:font-semibold [&_h3]:text-nx-fg">
|
||||
<p class="border-l-2 border-sky-500/35 pl-4 text-sm leading-relaxed text-nx-muted">
|
||||
{modelloOrganizzativo.introBox}
|
||||
{m.introBox}
|
||||
</p>
|
||||
<p class="mt-3 text-sm leading-relaxed text-nx-muted sm:text-base">
|
||||
{modelloOrganizzativo.perimetro}
|
||||
{m.perimetro}
|
||||
</p>
|
||||
|
||||
<h2 id="indice" class="!mt-8">Indice</h2>
|
||||
<h2 id="indice" class="!mt-8">{page.indexTitle}</h2>
|
||||
<ol class="!mt-3 list-decimal space-y-1.5 pl-5 text-sm leading-relaxed sm:text-base">
|
||||
<li><a class={link} href="#ruoli">Ruoli e perimetro</a></li>
|
||||
<li><a class={link} href="#governance">Governance essenziale</a></li>
|
||||
<li><a class={link} href="#responsabilita">Principali responsabilità (sintesi)</a></li>
|
||||
<li><a class={link} href="#raci">RACI per processi critici</a></li>
|
||||
<li><a class={link} href="#flussi">Flussi decisionali rapidi</a></li>
|
||||
<li><a class={link} href="#controlli">Controlli minimi obbligatori (lean)</a></li>
|
||||
<li><a class={link} href="#kpi">KPI essenziali</a></li>
|
||||
<li><a class={link} href="#documentazione">Documentazione minima da mantenere</a></li>
|
||||
<li><a class={link} href="#piano-30">Primo piano operativo (30 giorni)</a></li>
|
||||
<li><a class={link} href="#outsourcing">Outsourcing consigliato</a></li>
|
||||
<li><a class={link} href="#note">Note pratiche e raccomandazioni</a></li>
|
||||
{
|
||||
page.index.map((item) => (
|
||||
<li>
|
||||
<a class={link} href={item.href}>
|
||||
{item.label}
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ol>
|
||||
|
||||
<h2 id="ruoli">1. Ruoli e perimetro</h2>
|
||||
<h2 id="ruoli">{page.sectionTitles.ruoli}</h2>
|
||||
<p>
|
||||
Elenco sintetico delle funzioni e delle attese di impegno. Per allineare il dominio
|
||||
prodotto (Legal Tech, Health Tech) a ruoli e consiglieri, fate riferimento anche a <a
|
||||
class={link}
|
||||
href="/codice-etico">codice etico</a
|
||||
> e, per i trattamenti di dati, a privacy policy e DPA.
|
||||
{page.ruoliIntroBefore}{' '}
|
||||
<a class={link} href={localize(page.codiceEticoHref)}>{page.codiceEticoLabel}</a>
|
||||
{' '}
|
||||
{page.ruoliIntroAfter}
|
||||
</p>
|
||||
<ul>
|
||||
{
|
||||
modelloOrganizzativoRuoli.map((r) => (
|
||||
m.ruoli.map((r) => (
|
||||
<li>
|
||||
<strong>{r.label}:</strong> {r.text}
|
||||
</li>
|
||||
@ -68,217 +68,85 @@ const tableWrap = 'mt-2 overflow-x-auto';
|
||||
}
|
||||
</ul>
|
||||
|
||||
<h2 id="governance">2. Governance essenziale</h2>
|
||||
<h2 id="governance">{page.sectionTitles.governance}</h2>
|
||||
<ul>
|
||||
{
|
||||
modelloOrganizzativoGovernance.map((g) => (
|
||||
m.governance.map((g) => (
|
||||
<li>
|
||||
<strong>{g.nome}:</strong> {g.partecipanti}. <span class="text-nx-muted/95">— {g.nota}</span>
|
||||
<strong>{g.nome}:</strong> {g.partecipanti}.{' '}
|
||||
<span class="text-nx-muted/95">— {g.nota}</span>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
|
||||
<h2 id="responsabilita">3. Principali responsabilità (sintesi)</h2>
|
||||
<h2 id="responsabilita">{page.sectionTitles.responsabilita}</h2>
|
||||
<ul>
|
||||
{modelloOrganizzativoResponsabilitaSintesi.map((l) => <li>{l}</li>)}
|
||||
{m.responsabilitaSintesi.map((l) => <li>{l}</li>)}
|
||||
</ul>
|
||||
|
||||
<h2 id="raci">4. RACI sintetico per processi critici</h2>
|
||||
<h2 id="raci">{page.sectionTitles.raci}</h2>
|
||||
<p>
|
||||
Legenda: <strong>R</strong> = Responsible, <strong>A</strong> = Accountable,
|
||||
<strong>C</strong> = Consulted, <strong>I</strong> = Informed.
|
||||
<strong>{page.raciLegendBefore}</strong> {page.raciLegend}
|
||||
</p>
|
||||
|
||||
<h3 class="!mt-5" id="raci-release">Rilascio in produzione</h3>
|
||||
<div class={tableWrap}>
|
||||
<table class={tbl}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class={th} scope="col">Ruolo</th>
|
||||
<th class={th} scope="col">R</th>
|
||||
<th class={th} scope="col">A</th>
|
||||
<th class={th} scope="col">C</th>
|
||||
<th class={th} scope="col">I</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class={td}>Lead engineer</td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>CTO</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>Security lead, DPO, product advisor</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>CEO, customer success</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{
|
||||
m.raci.map((matrix) => (
|
||||
<>
|
||||
<h3 class:list={[matrix.id === 'raci-release' && '!mt-5']} id={matrix.id}>
|
||||
{matrix.title}
|
||||
</h3>
|
||||
{'note' in matrix && matrix.note ? (
|
||||
<p class="text-sm text-nx-muted sm:text-base">
|
||||
{matrix.note}{' '}
|
||||
<a class={link} href={localize(matrix.noteLinkHref!)}>
|
||||
{matrix.noteLinkLabel}
|
||||
</a>
|
||||
{'noteAfter' in matrix ? matrix.noteAfter : null}
|
||||
</p>
|
||||
) : null}
|
||||
<div class={tableWrap}>
|
||||
<table class={tbl}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class={th} scope="col">
|
||||
{page.roleCol}
|
||||
</th>
|
||||
<th class={th} scope="col">
|
||||
R
|
||||
</th>
|
||||
<th class={th} scope="col">
|
||||
A
|
||||
</th>
|
||||
<th class={th} scope="col">
|
||||
C
|
||||
</th>
|
||||
<th class={th} scope="col">
|
||||
I
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{matrix.rows.map((row) => (
|
||||
<tr>
|
||||
<td class={td}>{row.role}</td>
|
||||
<td class={td}>{mark(row.r)}</td>
|
||||
<td class={td}>{mark(row.a)}</td>
|
||||
<td class={td}>{mark(row.c)}</td>
|
||||
<td class={td}>{mark(row.i)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</>
|
||||
))
|
||||
}
|
||||
|
||||
<h3 id="raci-incident">Incident response (violazione dei dati o incidente P0)</h3>
|
||||
<div class={tableWrap}>
|
||||
<table class={tbl}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class={th} scope="col">Ruolo</th>
|
||||
<th class={th} scope="col">R</th>
|
||||
<th class={th} scope="col">A</th>
|
||||
<th class={th} scope="col">C</th>
|
||||
<th class={th} scope="col">I</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class={td}>Security lead</td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>CEO</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>DPO, legal, CTO</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>Clienti interessati, board (se impatto elevato)</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3 id="raci-vendor">Onboarding vendor (sub-processore)</h3>
|
||||
<div class={tableWrap}>
|
||||
<table class={tbl}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class={th} scope="col">Ruolo</th>
|
||||
<th class={th} scope="col">R</th>
|
||||
<th class={th} scope="col">A</th>
|
||||
<th class={th} scope="col">C</th>
|
||||
<th class={th} scope="col">I</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class={td}>Operations</td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>Legal</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>Security lead, DPO</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>CTO, finance</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3 id="raci-dpia">DPIA (per perimetro: LexAura, MediAura, piattaforma)</h3>
|
||||
<p class="text-sm text-nx-muted sm:text-base">
|
||||
La matrice RACI non sostituisce il criterio legale (chi è titolare, chi responsabile) definito
|
||||
in contratti e in <a class={link} href="/codice-etico#tutela-dati-ruoli">§5.1 del codice etico</a
|
||||
>. Qui: chi coordina l’esercizio interno della valutazione d’impatto.
|
||||
</p>
|
||||
<div class={tableWrap}>
|
||||
<table class={tbl}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class={th} scope="col">Ruolo</th>
|
||||
<th class={th} scope="col">R</th>
|
||||
<th class={th} scope="col">A</th>
|
||||
<th class={th} scope="col">C</th>
|
||||
<th class={th} scope="col">I</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class={td}>DPO</td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>Legal</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>Product advisor, CTO, security lead</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
<td class={td}></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class={td}>CEO</td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}></td>
|
||||
<td class={td}>●</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 id="flussi">5. Flussi decisionali rapidi</h2>
|
||||
<h2 id="flussi">{page.sectionTitles.flussi}</h2>
|
||||
<ul>
|
||||
{
|
||||
modelloOrganizzativoFlussiDecisionali.map((f) => (
|
||||
m.flussiDecisionali.map((f) => (
|
||||
<li>
|
||||
<strong>{f.titolo}:</strong> {f.testo}
|
||||
</li>
|
||||
@ -286,15 +154,15 @@ const tableWrap = 'mt-2 overflow-x-auto';
|
||||
}
|
||||
</ul>
|
||||
|
||||
<h2 id="controlli">6. Controlli minimi obbligatori (lean)</h2>
|
||||
<h2 id="controlli">{page.sectionTitles.controlli}</h2>
|
||||
<ul>
|
||||
{modelloOrganizzativoControlliLean.map((c) => <li>{c}</li>)}
|
||||
{m.controlliLean.map((c) => <li>{c}</li>)}
|
||||
</ul>
|
||||
|
||||
<h2 id="kpi">7. KPI essenziali</h2>
|
||||
<h2 id="kpi">{page.sectionTitles.kpi}</h2>
|
||||
<ul>
|
||||
{
|
||||
modelloOrganizzativoKpi.map((k) => (
|
||||
m.kpi.map((k) => (
|
||||
<li>
|
||||
<strong>{k.area}:</strong> {k.testo}
|
||||
</li>
|
||||
@ -302,15 +170,15 @@ const tableWrap = 'mt-2 overflow-x-auto';
|
||||
}
|
||||
</ul>
|
||||
|
||||
<h2 id="documentazione">8. Documentazione minima da mantenere</h2>
|
||||
<h2 id="documentazione">{page.sectionTitles.documentazione}</h2>
|
||||
<ul>
|
||||
{modelloOrganizzativoDocumentazione.map((d) => <li>{d}</li>)}
|
||||
{m.documentazione.map((d) => <li>{d}</li>)}
|
||||
</ul>
|
||||
|
||||
<h2 id="piano-30">9. Primo piano operativo (30 giorni)</h2>
|
||||
<h2 id="piano-30">{page.sectionTitles.piano30}</h2>
|
||||
<ol>
|
||||
{
|
||||
modelloOrganizzativoPiano30.map((p) => (
|
||||
m.piano30.map((p) => (
|
||||
<li>
|
||||
<strong>{p.quando}:</strong> {p.testo}
|
||||
</li>
|
||||
@ -318,10 +186,10 @@ const tableWrap = 'mt-2 overflow-x-auto';
|
||||
}
|
||||
</ol>
|
||||
|
||||
<h2 id="outsourcing">10. Outsourcing consigliato (per restare snelli)</h2>
|
||||
<h2 id="outsourcing">{page.sectionTitles.outsourcing}</h2>
|
||||
<ul>
|
||||
{
|
||||
modelloOrganizzativoOutsourcing.map((o) => (
|
||||
m.outsourcing.map((o) => (
|
||||
<li>
|
||||
<strong>{o.titolo}:</strong> {o.testo}
|
||||
</li>
|
||||
@ -329,9 +197,9 @@ const tableWrap = 'mt-2 overflow-x-auto';
|
||||
}
|
||||
</ul>
|
||||
|
||||
<h2 id="note">11. Note pratiche e raccomandazioni</h2>
|
||||
<h2 id="note">{page.sectionTitles.note}</h2>
|
||||
<ul>
|
||||
{modelloOrganizzativoNote.map((n) => <li>{n}</li>)}
|
||||
{m.note.map((n) => <li>{n}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
</SubpageLayout>
|
||||
|
||||
Reference in New Issue
Block a user