Aller au contenu

Project Presentation

Contrôleur HTTP de gestion de la présentation d'un projet (étape porteur de projet : nom, catégorie, montant demandé, lots, etc.). La présentation a deux statuts : draft (édition libre) et completed (verrouillé après validation des champs requis).

Source : project-presentation.controller.ts.

Tous les endpoints requièrent un porteur de projet authentifié via better-auth (ProjectFinancingRequestOwnerGuard). Comme la route porte un :projectId, le guard vérifie aussi que le projet appartient à ce porteur (sinon 403 Forbidden) et qu'il existe (sinon 404 Not Found).

GET /project-financing-request/:projectId/presentation

Récupère la présentation du projet. Si elle n'existe pas encore, en crée une vide en status='draft' (idempotent : pattern getOrCreate). Voir project-presentation.controller.ts#L15-L23.

Path params

  • projectId — id de la demande de financement

Response

Schéma getProjectPresentationResponseSchema — projection via getProjectPresentationView : chaque imageKey S3 devient une paire { key, url } (la key est renvoyée pour que le client la ré-émette au save, l'url est une URL GET presignée fraîche pour l'affichage) :

{
  "id": "uuid",
  "status": "draft | completed",
  "mainImage": { "key": "s3-key", "url": "https://..." },
  "secondaryImages": [{ "key": "s3-key", "url": "https://..." }],
  "name": "string?",
  "category": "marchandDeBiens | locatif | exploitation | promotion",
  "fundingAmountRequested": 1000000,
  "fundsNeededByDate": "ISO date?",
  "description": "string?",
  "address": "string?",
  "localizationDescription": "string?",
  "totalSurface": 250,
  "lots": [
    { "id": "uuid", "name": "string", "surface": 50, "image": { "key": "s3-key", "url": "https://..." } }
  ]
}

Erreurs

Code Statut Cause
Erreur S3 500 Échec de signature d'une URL GET presignée (la view fail-fast pour ne pas décaler les indices côté front)
not-found 404 Projet inconnu lors du getOrCreate initial (cf. project-not-found)

PATCH /project-financing-request/:projectId/presentation/:presentationId

Auto-save déclaratif de la présentation. Le statut est forcé à draft. Voir project-presentation.controller.ts#L25-L42.

Sémantique par champ (images et fundsNeededByDate) : absent = inchangé, null = effacé, valeur = appliqué. Les lots sont mergés par id (stable côté client). Les autres champs texte : body.field ?? existant.

Les imageKey du body doivent avoir été confirmées au préalable (confirm-upload, qui vérifie leur existence sur S3). Au save : les clés conservées n'ont aucun tag ; les clés qui disparaissent de la galerie sont taguées pending (jamais supprimées directement — une lifecycle rule S3 fait l'expiry). Voir le cycle de vie des images.

Path params

  • projectId — id de la demande de financement
  • presentationId — id de la présentation à mettre à jour

Request body

Validé via saveProjectPresentationBodySchema :

{
  "name": "string?",
  "category": "marchandDeBiens | locatif | exploitation | promotion (optional)",
  "fundingAmountRequested": 1000000,
  "fundsNeededByDate": "ISO datetime?",
  "description": "string?",
  "address": "string?",
  "localizationDescription": "string?",
  "totalSurface": 250,
  "lots": [{ "id": "uuid", "name": "string", "surface": 50, "imageKey": "s3-key | null?" }],
  "mainImageKey": "s3-key | null?",
  "secondaryImageKeys": ["s3-key"]
}

lots[].id est généré côté client (UUID stable) pour matcher les lots existants lors du save. mainImageKey / lots[].imageKey sont nullish : null efface l'image, l'absence la conserve.

Response

undefined (pas de payload). Le client doit re-fetch via GET pour récupérer la vue à jour.

Erreurs

Code Statut Cause
validation-body 400 Body invalide
s3-key-invalid-prefix 400 Une imageKey n'appartient pas au préfixe S3 du projet
image-key-not-found 400 Une imageKey n'existe pas dans S3 (jamais uploadée)
presentation-id-mismatch 409 Le presentationId ne correspond pas à la présentation du projet
project-not-found 404 Le projet est introuvable

PUT /project-financing-request/:projectId/presentation/:presentationId/complete

Verrouille la présentation en status='completed'. Re-valide tous les champs requis via le schéma ProjectFinancingRequestPresentationPgSchema.completed. Idempotent : si déjà completed, renvoie une erreur de conflit. Voir project-presentation.controller.ts#L44-L56.

Path params

  • projectId — id de la demande de financement
  • presentationId — id de la présentation à compléter

Response

undefined.

Erreurs

Code Statut Cause
presentation-not-found 404 Aucune présentation pour ce projet
presentation-already-completed 409 Présentation déjà en status='completed'
presentation-incomplete 400 Champs requis manquants (le détail Zod est dans body)

Liens