feat(CC-077): add Retention Policies page (7 data categories with legal basis)

This commit is contained in:
admin-valentin 2026-08-02 12:50:21 +00:00
parent 4f9718dce4
commit ea7ecb5cf9

View file

@ -0,0 +1,122 @@
'use client';
import Link from 'next/link';
interface RetentionPolicy {
id: string; category: string; dataTypes: string[]; retentionDays: number;
legalBasis: string; autoDelete: boolean; notes: string;
}
const POLICIES: RetentionPolicy[] = [
{
id: 'personal-data', category: 'Date Personale (C3)', dataTypes: ['Contacte', 'Persoane', 'Date GDPR'],
retentionDays: 365 * 3, legalBasis: 'Consimțământ + Interes legitim', autoDelete: false,
notes: 'Ștergere manuală la revocare consimțământ. Anonimizare alternativă permisă.',
},
{
id: 'financial', category: 'Date Financiare (C2)', dataTypes: ['Tranzacții', 'Facturi', 'Contracte'],
retentionDays: 365 * 10, legalBasis: 'Obligație legală (Codul Fiscal RO art. 25)', autoDelete: false,
notes: 'Retenție 10 ani obligatorie conform legislație fiscală. Nu se poate scurta.',
},
{
id: 'documents', category: 'Documente (C1-C4)', dataTypes: ['Documente OCR', 'Fișiere', 'Atașamente'],
retentionDays: 365 * 5, legalBasis: 'Proceduri interne', autoDelete: false,
notes: 'C4 (secret) — ștergere securizată la expirare. C0/C1 — arhivare permisă indefinit.',
},
{
id: 'audit-logs', category: 'Audit Logs (C1)', dataTypes: ['Log acces', 'Modificări', 'Sesiuni'],
retentionDays: 365 * 2, legalBasis: 'Securitate + Conformitate', autoDelete: true,
notes: 'Ștergere automată după 2 ani. Evenimentele critice se păstrează 5 ani.',
},
{
id: 'ai-data', category: 'Activitate AI (C2)', dataTypes: ['Cereri AI', 'Aprobări', 'Costuri'],
retentionDays: 365, legalBasis: 'Proceduri interne', autoDelete: true,
notes: 'Cereri AI se șterg automat după 1 an. Metadatele anonimizate se păstrează pentru analiză.',
},
{
id: 'observations', category: 'Observații Personale (C2)', dataTypes: ['KPI personal', 'Energie', 'Educație'],
retentionDays: 365 * 5, legalBasis: 'Consimțământ explicit', autoDelete: false,
notes: 'Utilizatorul controlează complet. Ștergere disponibilă din Export & Deletion.',
},
{
id: 'communications', category: 'Comunicații (C2)', dataTypes: ['Email import', 'Follow-ups', 'Interacțiuni'],
retentionDays: 365 * 3, legalBasis: 'Interes legitim', autoDelete: false,
notes: 'Emailuri importate necesită consimțământ explicit al expeditorului dacă sunt persoane fizice.',
},
];
function formatDays(days: number) {
if (days >= 365 * 10) return '10 ani';
if (days >= 365 * 5) return '5 ani';
if (days >= 365 * 3) return '3 ani';
if (days >= 365 * 2) return '2 ani';
if (days >= 365) return '1 an';
if (days >= 30) return `${Math.floor(days/30)} luni`;
return `${days} zile`;
}
export default function RetentionPoliciesPage() {
return (
<div className="max-w-4xl space-y-6 p-6">
<div>
<h1 className="font-display text-2xl font-semibold text-ink">Politici de Retenție</h1>
<p className="text-sm text-ink-faint mt-1">
Reguli de retenție per categorie de date GDPR + legislație fiscală RO/DE.
</p>
</div>
<div className="card p-4 bg-primary/5 border-primary/20">
<p className="text-xs font-semibold text-ink mb-1">Principii generale</p>
<div className="space-y-1 text-xs text-ink-faint">
<p> Datele se rețin doar cât este necesar scopului pentru care au fost colectate.</p>
<p> La expirarea perioadei: ștergere securizată sau anonimizare ireversibilă.</p>
<p> Utilizatorul poate solicita ștergerea anticipată prin <Link href="/dashboard/privacy/export" className="text-primary hover:underline">Export & Deletion</Link>.</p>
<p> Obligațiile legale de retenție (ex: fiscal) nu pot fi reduse prin cerere individuală.</p>
</div>
</div>
<div className="space-y-3">
{POLICIES.map((policy) => (
<div key={policy.id} className="card p-5 space-y-3">
<div className="flex items-start justify-between gap-3 flex-wrap">
<div>
<p className="text-sm font-semibold text-ink">{policy.category}</p>
<div className="flex flex-wrap gap-1 mt-1">
{policy.dataTypes.map((dt) => (
<span key={dt} className="rounded-full bg-muted px-2 py-0.5 text-[9px] text-ink-faint">{dt}</span>
))}
</div>
</div>
<div className="text-right">
<p className="text-lg font-bold text-ink">{formatDays(policy.retentionDays)}</p>
<div className="flex items-center gap-2 justify-end mt-0.5">
{policy.autoDelete ? (
<span className="text-[10px] text-signal-ok">🤖 auto-ștergere</span>
) : (
<span className="text-[10px] text-warn">👤 manual</span>
)}
</div>
</div>
</div>
<div className="space-y-1 border-t border-border/50 pt-3">
<p className="text-[10px] font-semibold text-ink-faint">Temei legal: {policy.legalBasis}</p>
<p className="text-[10px] text-ink-faint">{policy.notes}</p>
</div>
</div>
))}
</div>
<div className="flex flex-wrap gap-2">
<Link href="/dashboard/privacy/export" className="rounded-lg border px-4 py-2 text-sm text-ink hover:bg-muted/50">
Cerere ștergere date
</Link>
<Link href="/dashboard/privacy/audit" className="rounded-lg border px-4 py-2 text-sm text-ink hover:bg-muted/50">
Audit log
</Link>
<Link href="/dashboard/privacy/consents" className="rounded-lg border px-4 py-2 text-sm text-ink hover:bg-muted/50">
Consimțăminte GDPR
</Link>
</div>
</div>
);
}