Skip to content

bug: deleting a vendor workspace leaves orphaned data (Qdrant vectors, assessments, files) — no cascade / GDPR erasure #417

Description

@AndreLiar

Constat (vérifié dans le code)

WorkspaceService.deleteWorkspace ne supprime que 2 choses :

await this.WorkspaceMember.deleteMany({ workspaceId });
await this.Workspace.findByIdAndDelete(workspaceId);

Pas de hook de cascade sur le modèle (seulement pre('save') pour les certifs), personne d'autre ne nettoie.

Données laissées ORPHELINES après suppression d'un vendor

Donnée Store Supprimé aujourd'hui ?
Vecteurs des docs vendor (langchain-rag, metadata.workspaceId — inclut le dual-write #394) Qdrant
Collections par-assessment (assessment_<id>) Qdrant
Assessments MongoDB
Conversations + Messages MongoDB
VendorQuestionnaires MongoDB
Fichiers (storageKey) MinIO / Spaces

Sévérité

  • Pas une fuite d'accès : l'isolation tenant tient (plus de workspace → vecteurs jamais récupérés).
  • MAIS gap d'effacement/rétention, sérieux pour un produit de conformité :
    • RGPD Art 17 (droit à l'effacement) — on vend de la conformité, on doit l'honorer.
    • Offboarding DORA propre — prouver que les données d'un vendor sorti sont parties.
    • Fuite de stockage / coût (Qdrant + Mongo + Spaces).

→ Candidat roadmap:now vu l'angle conformité (à trancher).

Fix — cascade deleteWorkspace (réutilise des briques EXISTANTES)

  • Purge collection workspace par workspaceId : client.delete('langchain-rag', { filter: { must: [{ key: 'metadata.workspaceId', match: { value: workspaceId } }] } }) — même pattern que deleteAssessmentChunksFromWorkspace (déjà en prod, fix: connect assessment documents to Ask AI chat retrieval #394)
  • Pour chaque assessment du workspace : deleteAssessmentCollection(id) (existe) — supprime la collection assessment_<id>
  • Cascade Mongo : supprimer Assessments, Conversations + Messages, VendorQuestionnairesworkspaceId = <id>
  • Supprimer les fichiers (storageKey) de MinIO/Spaces (réutiliser config/storage.js)
  • Best-effort + idempotent + loggé (ne pas faire échouer la suppression si un store est indisponible — mêmes garde-fous que la cascade assessment)
  • Test : créer workspace + assessment + doc indexé → delete → vérifier 0 vecteur metadata.workspaceId restant + 0 doc Mongo orphelin

Réf code

  • backend/services/WorkspaceService.js (deleteWorkspace) · config/vectorStore.js (deleteAssessmentChunksFromWorkspace → pattern de purge par filtre) · services/fileIngestionService.js (deleteAssessmentCollection) · services/AssessmentService.js (cascade assessment existante à imiter) · config/storage.js (fichiers)
  • Lien : complète feat(privacy): GDPR Art. 17 + Art. 20 — data export, account erasure, DPA + sub-processor list #217 (RGPD export/erasure au niveau compte) mais au niveau workspace/vendor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendBackend changesbugSomething isn't workingpriority: highHigh priorityroadmap:nextCanal consultant + profondeur (3-6 mois)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions