Aller au contenu

Project Analysis

Flux d'analyse d'un dossier de financement : lecture côté porteur, réponses aux compléments, et endpoints internes consommés par Projet Analyse (app hors monorepo).

Sources :

Machine à états (rappel)

Statut projet Vue analyse porteur (GET …/analysis/status) Projet Analyse
draft pending
in-analysis pending peut pousser questions / demandes de docs / refuser un fichier / commentaire analyste
blocked blocked (commentaire analyste + questions + demandes de docs) idem + lit reanalysisComment via GET interne
offer, finalization, completed 409 project-analysis-status-unsupported hors périmètre analyse (offre / collecte)
rejected declined (rejectionComment)

Passage blockedin-analysis : le porteur appelle POST …/analysis/reanalysis (optionnellement avec un commentaire). Projet Analyse est notifié via ProjetAnalyseApi.notifyProjectUpdated avec reason: 'reanalysis-requested'.

Endpoints porteur (ProjectFinancingRequestOwnerGuard)

Préfixe : /project-financing-request/project/:projectId/analysis.

GET /status

Retourne l'état de l'analyse pour l'écran « Analyse » du funnel.

Réponses (contrat getProjectAnalysisStatusResponseValidator) :

{ "status": "pending" }

ou, si le dossier est blocked :

{
  "status": "blocked",
  "comment": "Merci de préciser le montant des travaux restants.",
  "questions": [{ "id": "uuid", "question": "…", "answer": "…" }],
  "documentRequests": [
    {
      "id": "uuid",
      "title": "…",
      "description": "…",
      "documents": [
        {
          "id": "uuid",
          "name": "kbis.pdf",
          "type": "application/pdf",
          "size": 12345,
          "createdAt": "2026-07-01T10:00:00.000Z",
          "comment": "…",
          "isRefused": false
        }
      ]
    }
  ]
}

isRefused est dérivé de refusedAt sur le document (voir Documents).

Erreur HTTP Cause
project-analysis-status-unsupported 409 Projet offer, finalization ou completed

POST /question/:questionId/answer

Répond à une question posée par Projet Analyse. Corps : { "answer": "…" }.

Erreur HTTP Cause
project-not-blocked 409 Projet pas en blocked
question-project-mismatch 409 Question rattachée à un autre projet

POST /reanalysis

Demande une ré-analyse après avoir traité les compléments. Corps optionnel : { "comment": "…" }.

  • Passe le projet de blockedin-analysis
  • Persiste reanalysisComment (écrasé à null si le corps omet comment après une demande commentée)
  • Notifie Projet Analyse, puis renvoie le même shape que GET /status (pending)
Erreur HTTP Cause
project-cannot-be-reanalyzed 409 Projet pas en blocked

Endpoints internes Projet Analyse

Préfixe : /internal/projet-analyse/project/:projectId. Auth : x-api-key consommateur projet-analyse.

La forme des payloads (params, bodies, réponses) fait foi dans l'OpenAPI — les descriptors vivent dans @bricks-common/api-communication-internal, la doc est servie sur /internal/docs/json (voir le guide consommateur). Cette page ne documente que les invariants métier que le schéma ne dit pas.

GET /

État complet de la phase 1 (source de vérité côté Bricks) : l'état d'instruction et le dossier lui-même — présentation, emprunteur, documents déposés.

missingDocumentsFromAnalysis n'est renvoyé que si status === 'blocked' (sinon {}).

presentation et borrower valent null tant que l'entité n'existe pas, et leurs champs sont majoritairement optionnels en draft : l'analyse lit un dossier en cours de remplissage. L'emprunteur reste facultatif jusqu'à l'acceptation de l'offre.

comment est le commentaire que le porteur a joint à son fichier (null s'il n'en a pas laissé), à ne pas confondre avec le comment racine, qui est celui de l'analyste.

documents liste tous les fichiers du projet — dépôt d'onboarding compris (documentRequestId: null) et documents refusés (refusedAt horodaté), que l'analyse doit continuer de voir. s3Key accompagne l'URL signée : c'est la référence stable une fois le bucket partagé, l'URL expirant à brève échéance.

finalization porte ce que l'analyse assemble pour son bundle de signature : coordonnées bancaires, LEI, notaire, avantages investisseurs et les 4 pièces société. Le bloc vaut null tant que le porteur n'a pas validé sa finalisation — c'est le passage de la société en finalized qui le renseigne, et ce même geste émet le ping finalized. L'emprunteur n'y est pas repris : il vit à la racine.

POST /comment

Pousse un commentaire analyste affiché en tête de l'écran analyse bloquée côté porteur. Corps : { "comment": "…" }.

  • Idempotent : re-push écrase le scalaire comment sur le projet
  • Passe le projet en blocked si besoin (in-analysisblocked)
Erreur HTTP Cause
project-not-under-analysis 409 Statut hors in-analysis / blocked

POST /questions

Pousse une question. Corps : { "questionId": "uuid", "text": "…" }.

  • Idempotent sur questionId (re-push assure blocked sans doublon)
  • Dérive in-analysisblocked si besoin
Erreur HTTP Cause
question-project-mismatch 409 questionId déjà utilisé sur un autre projet
project-cannot-be-blocked 409 Statut incompatible (ex. offer)

POST /document-requests

Pousse une demande de document complémentaire. Corps : { "requestId": "uuid", "label": "…", "description": "…?" }.

Même sémantique d'idempotence et de passage en blocked que les questions.

PUT /document/:documentId/refuse

Marque un fichier déjà uploadé par le porteur comme refusé (refusedAt horodaté). Idempotent : un second appel conserve le premier refusedAt.

Autorisé uniquement si le projet est in-analysis ou blocked.

Erreur HTTP Cause
project-not-under-analysis 409 Statut hors analyse
document-not-found 404 Document inconnu ou autre projet

Voir aussi Documents — sync missing (PUT /internal/…/missing-documents).

Liens