Skip to content

BDD-22 — Consultation des fichiers d'un dossier client

📄 Ticket fonctionnel

Consulter les fichiers d'un dossier

L'administrateur peut accéder au détail d'un dossier client pour voir, télécharger et dénombrer les fichiers déposés. Le client peut associer un fichier à un dossier lors du dépôt.

1. User Story

En tant qu'administrateur,
Je veux consulter les fichiers contenus dans un dossier client,
Afin de suivre les dépôts et télécharger les documents reçus.

2. Critères d'acceptance

  1. La liste affiche nom, date de dépôt et taille de chaque fichier.
  2. L'admin peut télécharger n'importe quel fichier du dossier.
  3. Le nombre de fichiers et la date du dernier dépôt sont visibles sur la carte dossier.
  4. Le client peut associer un fichier à un dossier lors du dépôt.

3. Flux complet

mermaid
sequenceDiagram
    autonumber
    participant A as 👤 Admin
    participant F as 🖥️ Front
    participant API as 🧠 API NestJS
    participant DB as 🗄️ prisma.tool
    participant S3 as ☁️ Scaleway S3

    A->>F: Clique sur un dossier (/admin/folders/:uuid)
    F->>API: GET /folders/:uuid
    API->>DB: folders.findFirst WHERE uuid + deleted_at IS NULL
    DB-->>API: dossier (nom, client)
    F->>API: GET /folders/:uuid/documents
    API->>DB: documents WHERE folder_id = folder.id
    DB-->>API: [{uuid, name, size, created_at}]
    F-->>A: Affiche liste des fichiers

    A->>F: Clique "Télécharger"
    F->>API: GET /folders/:uuid/documents/:docUuid/download
    API->>DB: documents.findFirst WHERE uuid + folder_id
    API->>S3: getFileUrl (URL signée)
    S3-->>API: URL signée
    API-->>F: {url, filename}
    F-->>A: Déclenche le téléchargement

4. Sécurité

  • AuthGuard + AdminGuard sur tous les endpoints /folders/:uuid/**.
  • La résolution du document se fait via folder_id (pas par UUID seul) : un doc d'un autre dossier ne peut pas être téléchargé via ce endpoint.
  • Le FolderAccessDeniedException (403) est levé si le folder_id du document ne correspond pas au dossier demandé.
  • Côté client : l'association folderUuid est validée — le dossier doit exister, ne pas être supprimé, et appartenir au client authentifié.

5. Périmètre fonctionnel

Backend

FichierRôle
back/src/api/folders/folder.service.tsfindDocuments, getDocumentDownloadUrl, findOne, findMyFolders
back/src/api/folders/folder.controller.tsNouveaux endpoints GET
back/src/api/documents/document.service.tsdropFile accepte folderUuid optionnel
back/src/api/documents/document.controller.ts@Body('folderUuid') dans dropFile
back/src/exceptions/folder.exceptions.tsFolderAccessDeniedException (403)
back/src/exceptions/document.exceptions.tsFileNotFoundException, FileDownloadUnavailableException
sql/tool_04_folder_id_on_documents.sqlMigration SQL (folder_id nullable sur documents)
back/prisma/db_tool/schema.prismaRelation documents ↔ folders

Frontend

FichierRôle
front/src/stores/folder-store.jsfetchFolder, fetchFolderDocuments, getFolderDocumentDownloadUrl, fetchMyFolders
front/src/stores/files-store.jsuploadFileToDb transmet folderUuid
front/src/pages/admin/folders/AdminFolderDetailPage.vuePage détail dossier (liste + téléchargement)
front/src/pages/upload/UploadPage.vueSélecteur de dossier avant dépôt
front/src/components/admin/FolderListItem.vueAffiche documentCount et lastDepositAt
front/src/components/documents/DocumentListItem.vueProp hideCopyLink pour admin
front/src/router/routes.jsRoute admin/folders/:uuid

6. Endpoints API

MéthodeCheminGuardDescription
GET/folders/mineAuthGuardDossiers du client connecté
GET/folders/:uuidAuthGuard + AdminGuardDétail d'un dossier
GET/folders/:uuid/documentsAuthGuard + AdminGuardDocuments d'un dossier
GET/folders/:uuid/documents/:docUuid/downloadAuthGuard + AdminGuardURL signée de téléchargement

Les endpoints existants GET /folders, POST /folders, PATCH /folders/:uuid, DELETE /folders/:uuid et GET /folders/clients sont inchangés.

7. Modèle de données

Migration ajoutée (sql/tool_04_folder_id_on_documents.sql) :

sql
ALTER TABLE public.documents
  ADD COLUMN folder_id INTEGER REFERENCES public.folders(id) ON DELETE SET NULL;

CREATE INDEX idx_documents_folder ON public.documents(folder_id);

La colonne folder_id est nullable : les fichiers déposés sans dossier restent liés à l'utilisateur uniquement via users_documents.

8. Points de vérification

  • La page /admin/folders/:uuid est accessible uniquement aux admins.
  • La liste des fichiers affiche nom, taille formatée et date de dépôt.
  • Le bouton "Copier le lien" est masqué dans la vue admin (prop hideCopyLink).
  • La carte dossier dans /admin/folders affiche le nombre de fichiers et la date du dernier dépôt.
  • Le client voit un sélecteur de dossier dans la page de dépôt uniquement s'il a au moins un dossier.
  • Un fichier sans dossier est déposé normalement (champ folder_id null).

9. Tests associés

Backend

  • back/src/api/folders/folder.service.spec.tsfindOne, findMyFolders, findDocuments, getDocumentDownloadUrl, findAll (avec stats)
  • back/src/api/documents/document.service.spec.tsdropFile avec folderUuid

Frontend (unitaires)

  • front/src/__tests__/pages/admin/folders/AdminFolderDetailPage.spec.js
  • front/src/__tests__/stores/folder-store.spec.js — 4 nouvelles actions
  • front/src/__tests__/components/admin/FolderListItem.spec.js — stats dossier
  • front/src/__tests__/router/routes.spec.js — route admin/folders/:uuid
  • front/src/__tests__/pages/upload/UploadPage.spec.js — sélecteur dossier