diff --git a/RGPD_AUDIT_LOCALISATION_DONNEES.md b/RGPD_AUDIT_LOCALISATION_DONNEES.md index 8781281..4b598b6 100644 --- a/RGPD_AUDIT_LOCALISATION_DONNEES.md +++ b/RGPD_AUDIT_LOCALISATION_DONNEES.md @@ -2,7 +2,8 @@ > **Date de l'audit** : 23 octobre 2025 > **Projet** : Nouvel Espace Paie Odentas -> **Objectif** : Vérifier que toutes les données clients restent dans l'Union Européenne +> **Objectif** : Vérifier que toutes les données clients restent dans l'Union Européenne +> **Résultat** : ✅ **9/9 services conformes (100%)** --- @@ -18,7 +19,7 @@ | **Docuseal** | 🇪🇺 api.docuseal.eu | Version EU | ✅ Conforme | Signatures électroniques | - | | **PostHog** | 🇪🇺 eu.i.posthog.com | Instance EU | ✅ Conforme | Analytics utilisateurs | - | | **GoCardless** | 🇪🇺 EEE | Serveurs EEE + SCC UE | ✅ Conforme | Mandats SEPA, paiements | ✅ **Confirmé par support** | -| **PDFMonkey** | ⚠️ **En attente** | Heroku + AWS (région ?) | ⚠️ **À confirmer** | Contrats CDDU (données salariés) | **Mail envoyé - en attente réponse** | +| **PDFMonkey** | 🇪🇺 EU | Heroku + AWS EU | ✅ Conforme | Contrats CDDU (données salariés) | ✅ **Confirmé par support** | --- @@ -69,19 +70,7 @@ ### ⚠️ Services à vérifier -#### PDFMonkey -- **API** : `https://api.pdfmonkey.io` -- **Entreprise** : Française (Paris - 51 rue de Ponthieu, 75008) -- **Infrastructure déclarée** : Heroku + AWS (région non spécifiée) -- **Données envoyées** : - - Informations contrats CDDU (nom, prénom, dates, salaires) - - Informations structure employeur - - Informations production -- **Problème** : Heroku héberge par défaut aux USA (`us-east-1`) -- **Action** : - - ✅ Mail envoyé à `tinymonkey@pdfmonkey.io` le 23/10/2025 - - ⏳ En attente de confirmation de la région de traitement -- **Statut** : ⚠️ **En attente de réponse** +- **Statut** : ✅ **100% conforme** #### GoCardless - **Environment** : `live` @@ -98,6 +87,49 @@ - **Confirmation** : ✅ Support GoCardless - 23 octobre 2025 - **Statut** : ✅ **Conforme RGPD** +#### PDFMonkey +- **API** : `https://api.pdfmonkey.io` +- **Entreprise** : Française (Paris - 51 rue de Ponthieu, 75008) +- **Infrastructure** : Heroku + AWS - Serveurs UE +- **Données envoyées** : + - Informations contrats CDDU (nom, prénom, dates, salaires) + - Informations structure employeur + - Informations production +- **Confirmation support** : ✅ 23 octobre 2025 + > "Je confirme, les données (serveurs, base de données, stockage des fichiers) sont bien stockées en UE" + > — Simon, PDFMonkey (tinymonkey@pdfmonkey.io) +- **Statut** : ✅ **Conforme RGPD** + +--- + +#### GoCardless +- **Environment** : `live` +- **API** : GoCardless UK/EU +- **Infrastructure** : Serveurs dans l'Espace Économique Européen (EEE) +- **Données** : Mandats SEPA, paiements, coordonnées bancaires +- **Mécanismes de protection** : + - Opérations principales de traitement des paiements : ✅ Serveurs EEE + - Prestataires tiers (hors EEE) : ✅ Clauses Contractuelles Types (SCC) de l'UE + - Contrôle préalable des fournisseurs avec mécanismes RGPD approuvés +- **Documentation** : + - https://gocardless.com/legal/data-protection/ + - https://gocardless.com/fr-fr/privacy/fr-gdpr/ +- **Confirmation** : ✅ Support GoCardless - 23 octobre 2025 +- **Statut** : ✅ **Conforme RGPD** + +#### PDFMonkey +- **API** : `https://api.pdfmonkey.io` +- **Entreprise** : Française (Paris - 51 rue de Ponthieu, 75008) +- **Infrastructure** : Heroku + AWS - Serveurs UE +- **Données envoyées** : + - Informations contrats CDDU (nom, prénom, dates, salaires) + - Informations structure employeur + - Informations production +- **Confirmation support** : ✅ 23 octobre 2025 + > "Je confirme, les données (serveurs, base de données, stockage des fichiers) sont bien stockées en UE" + > — Simon, PDFMonkey (tinymonkey@pdfmonkey.io) +- **Statut** : ✅ **Conforme RGPD** + --- ## 📝 Notes sur les services retirés @@ -139,15 +171,20 @@ Ces services ont été **complètement retirés** du projet le 23 octobre 2025 : ## 🎯 Plan d'action -### 🚨 Priorité CRITIQUE +### ✅ Tous les services confirmés ! -1. **PDFMonkey - Attendre réponse** - - ✅ Mail envoyé le 23/10/2025 - - ⏳ Attendre confirmation de la localisation des serveurs - - Si réponse négative (serveurs hors EU) → **Migrer vers alternative** : - - DocRaptor (option EU disponible) - - PDF.co (serveurs EU) - - Solution auto-hébergée (Puppeteer + AWS Lambda eu-west-3) +**Statut global** : 🎉 **9/9 services conformes RGPD (100%)** + +Tous les services utilisés par l'Espace Paie Odentas ont été vérifiés et **stockent les données dans l'Union Européenne** : +- ✅ AWS (S3, SES, Lambda) - eu-west-3 +- ✅ Supabase - EU +- ✅ Vercel - cdg1 (Paris) +- ✅ Docuseal - api.docuseal.eu +- ✅ PostHog - eu.i.posthog.com +- ✅ GoCardless - EEE + SCC (confirmé par support) +- ✅ PDFMonkey - EU (confirmé par support) + +**Aucune action requise** - La plateforme est **100% conforme RGPD**. --- @@ -194,6 +231,20 @@ Merci d'avance pour votre retour rapide. **Citation** : > "L'ensemble de nos principales opérations de traitement des paiements européens sont exécutées sur des serveurs situés dans l'Espace économique européen (EEE). [...] Dès lors que des données sont stockées dans ces services, nous veillons à ce qu'elles soient protégées selon les normes de l'Union européenne, en utilisant un mécanisme de transfert approuvé par le RGPD." +### Réponse de PDFMonkey + +**Date** : 23 octobre 2025 +**Source** : Simon - PDFMonkey (tinymonkey@pdfmonkey.io) +**Statut** : ✅ **Conforme RGPD** + +**Citation** : +> "Bonjour Renaud, +> +> Je confirme, les données (serveurs, base de données, stockage des fichiers) sont bien stockées en UE +> +> Bien à vous, +> Simon" + --- ## 📝 Notes importantes @@ -224,12 +275,13 @@ Ces CDNs peuvent servir depuis des serveurs hors UE, mais ils ne contiennent **a | Statut | Nombre de services | |--------|-------------------| -| ✅ Conforme RGPD | 8 services | -| ⚠️ À vérifier | 1 service | +| ✅ Conforme RGPD | 9 services | +| ⚠️ À vérifier | 0 service | | ❌ Non conforme | 0 service | | ✅ Retiré | 2 services (Airtable, n8n) | -### Taux de conformité actuel -**8 / 9 confirmés = 89%** +### Taux de conformité final +**9 / 9 confirmés = 100% 🎉** + +Tous les services utilisés par l'Espace Paie Odentas sont conformes RGPD et stockent les données dans l'Union Européenne. -Avec la vérification en cours (PDFMonkey), le taux devrait atteindre **100%**. diff --git a/app/(app)/staff/contrats/page.tsx b/app/(app)/staff/contrats/page.tsx index 59ea6e7..4ca87ee 100644 --- a/app/(app)/staff/contrats/page.tsx +++ b/app/(app)/staff/contrats/page.tsx @@ -36,7 +36,7 @@ export default async function StaffContractsPage() { const { data: contracts, error } = await sb .from("cddu_contracts") .select( - `id, contract_number, employee_name, employee_id, structure, type_de_contrat, start_date, end_date, created_at, etat_de_la_demande, etat_de_la_paie, dpae, gross_pay, org_id, contrat_signe_par_employeur, contrat_signe, last_employer_notification_at, last_employee_notification_at, + `id, contract_number, employee_name, employee_id, structure, type_de_contrat, start_date, end_date, created_at, etat_de_la_demande, etat_de_la_paie, dpae, gross_pay, org_id, contrat_signe_par_employeur, contrat_signe, last_employer_notification_at, last_employee_notification_at, production_name, salaries!employee_id(salarie, nom, prenom, adresse_mail)` ) .order("start_date", { ascending: false }) diff --git a/components/staff/ContractsGrid.tsx b/components/staff/ContractsGrid.tsx index faaac46..29bb41b 100644 --- a/components/staff/ContractsGrid.tsx +++ b/components/staff/ContractsGrid.tsx @@ -128,6 +128,7 @@ type Contract = { contrat_signe?: string | null; last_employer_notification_at?: string | null; last_employee_notification_at?: string | null; + production_name?: string | null; salaries?: { salarie?: string | null; nom?: string | null; @@ -294,6 +295,11 @@ function ContractsGridImpl({ initialData, activeOrgId }: { initialData: Contract const applyQuickFilterDpaeAFaire = () => { const today = new Date(); const in7 = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7); + // Reset tous les filtres pour voir uniquement ce filtre rapide + setQ(""); // Reset recherche + setStructureFilter(null); // Reset organisation + setTypeFilter(null); // Reset type de contrat + setSignatureFilter(null); // Reset signature setDpaeFilter('À faire'); setEtatContratFilters(new Set()); // Reset état contrat setEtatPaieFilter(null); // Reset état paie @@ -309,6 +315,11 @@ function ContractsGridImpl({ initialData, activeOrgId }: { initialData: Contract const today = new Date(); const firstDay = new Date(today.getFullYear(), today.getMonth(), 1); const lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0); + // Reset tous les filtres pour voir uniquement ce filtre rapide + setQ(""); // Reset recherche + setStructureFilter(null); // Reset organisation + setTypeFilter(null); // Reset type de contrat + setSignatureFilter(null); // Reset signature setEtatContratFilters(new Set(['Reçue', 'En cours'])); // Multiple selections setDpaeFilter(null); // Reset DPAE setEtatPaieFilter(null); // Reset état paie @@ -329,6 +340,11 @@ function ContractsGridImpl({ initialData, activeOrgId }: { initialData: Contract // Premier jour du mois dernier const firstDayLastMonth = new Date(lastDayLastMonth.getFullYear(), lastDayLastMonth.getMonth(), 1); + // Reset tous les filtres pour voir uniquement ce filtre rapide + setQ(""); // Reset recherche + setStructureFilter(null); // Reset organisation + setTypeFilter(null); // Reset type de contrat + setSignatureFilter(null); // Reset signature setEtatPaieFilter('À traiter'); setDpaeFilter(null); // Reset DPAE setEtatContratFilters(new Set()); // Reset état contrat @@ -342,6 +358,11 @@ function ContractsGridImpl({ initialData, activeOrgId }: { initialData: Contract }; const applyQuickFilterPaieATraiterToutes = () => { + // Reset tous les filtres pour voir uniquement ce filtre rapide + setQ(""); // Reset recherche + setStructureFilter(null); // Reset organisation + setTypeFilter(null); // Reset type de contrat + setSignatureFilter(null); // Reset signature setEtatPaieFilter('À traiter'); setDpaeFilter(null); // Reset DPAE setEtatContratFilters(new Set(['Traitée'])); // Ajouter le filtre "Traitée" @@ -365,6 +386,10 @@ function ContractsGridImpl({ initialData, activeOrgId }: { initialData: Contract const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); + // Reset tous les filtres pour voir uniquement ce filtre rapide + setQ(""); // Reset recherche + setStructureFilter(null); // Reset organisation + setTypeFilter(null); // Reset type de contrat setSignatureFilter('non_signe'); // Filtre pour les contrats non complètement signés setEtatPaieFilter(null); // Reset état paie setEtatContratFilters(new Set()); // Reset état contrat @@ -1957,6 +1982,7 @@ function ContractsGridImpl({ initialData, activeOrgId }: { initialData: Contract Salarié {sortField === 'employee_name' ? (sortOrder === 'asc' ? '▲' : '▼') : ''} Structure + Production Type { setSortField('start_date'); setSortOrder((o) => o === 'asc' ? 'desc' : 'asc'); }}> Date début {sortField === 'start_date' ? (sortOrder === 'asc' ? '▲' : '▼') : ''} @@ -2062,6 +2088,7 @@ function ContractsGridImpl({ initialData, activeOrgId }: { initialData: Contract {formatEmployeeName(r)} {r.structure || "—"} + {r.production_name || "—"} { r.type_de_contrat === "CDD d'usage" ? "CDDU" : (r.type_de_contrat || "—") }