feat: RGPD 100% + UX improvements staff contrats
- Audit RGPD: confirmation PDFMonkey (100% services conformes EU) - Staff contrats: reset tous filtres lors filtres rapides (recherche, org, type) - Staff contrats: ajout colonne Production (production_name) - Signature salarie: message info scroll pour signature
This commit is contained in:
parent
8cb366ee53
commit
e1d89ab765
3 changed files with 108 additions and 29 deletions
|
|
@ -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%**.
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
|
|
|
|||
|
|
@ -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' ? '▲' : '▼') : ''}
|
||||
</th>
|
||||
<th className="text-left px-3 py-2">Structure</th>
|
||||
<th className="text-left px-3 py-2">Production</th>
|
||||
<th className="text-left px-3 py-2">Type</th>
|
||||
<th className="text-left px-3 py-2 cursor-pointer" onClick={() => { 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
|
|||
|
||||
<td className="px-3 py-2">{formatEmployeeName(r)}</td>
|
||||
<td className="px-3 py-2">{r.structure || "—"}</td>
|
||||
<td className="px-3 py-2">{r.production_name || "—"}</td>
|
||||
<td className="px-3 py-2">{
|
||||
r.type_de_contrat === "CDD d'usage" ? "CDDU" : (r.type_de_contrat || "—")
|
||||
}</td>
|
||||
|
|
|
|||
Loading…
Reference in a new issue