feat(ai_working_help): expose folder_uid and user_id on GET /v1/response

Allows LeCoffre backend to validate polls after process restart.
This commit is contained in:
Nicolas Cantu 2026-04-10 00:07:23 +02:00
parent 7eec9d15ee
commit b5e1749b74
2 changed files with 14 additions and 2 deletions

View File

@ -35,7 +35,7 @@
Écrit dans `projects/<id>/data/notary-ai/pending/<safe_uid>.json`. **Authentification** : header `Authorization: Bearer <token>` obligatoire (le token identifie le projet) ; 401 si absent ou inconnu.
- **GET /v1/response/:request_uid**
Réponse **200** : `{ status: "pending" }` ou `{ status: "responded", response: { answer, nextActionsTable, membersInfoSheet, synthesisRecommendation } }`.
Réponse **200** : `{ status: "pending" }` ou `{ status: "responded", response: { answer, nextActionsTable, membersInfoSheet, synthesisRecommendation } }`. Lorsque le fichier pending ou responded est trouvé, le corps inclut en plus **`folder_uid`** et **`user_id`** (issus du JSON spooler) pour que le backend LeCoffre autorise le poll même si sa table mémoire `request_uid → meta` a été perdue (redémarrage, autre instance).
Si le fichier responded contient `anon_mapping`, la réponse est recontextualisée avant envoi (voir `docs/business-qa-api.md`).
Lit dabord `projects/<id>/data/notary-ai/responded/`, sinon `pending/`. **Authentification** : idem (token obligatoire).

View File

@ -97,6 +97,17 @@ function findFileByRequestUid(dir, requestUid) {
return null;
}
/** Expose folder_uid + user_id so backends without in-memory meta (restart, multi-instance) can authorize GET /response. */
function ownershipFromPayload(data) {
if (!data || typeof data !== "object") return {};
const folder_uid = data.folder_uid;
const user_id = data.user_id;
if (typeof folder_uid === "string" && typeof user_id === "string" && folder_uid.length > 0 && user_id.length > 0) {
return { folder_uid, user_id };
}
return {};
}
app.get("/health", (req, res) => {
res.status(200).json({ status: "ok" });
});
@ -165,12 +176,13 @@ app.get("/v1/response/:request_uid", requireApiTokenAndResolveProject, (req, res
return res.status(200).json({
status: "responded",
response,
...ownershipFromPayload(foundResponded.data),
});
}
const pendingDir = path.join(dir, "pending");
const foundPending = findFileByRequestUid(pendingDir, requestUid);
if (foundPending) {
return res.status(200).json({ status: "pending" });
return res.status(200).json({ status: "pending", ...ownershipFromPayload(foundPending.data) });
}
res.status(200).json({ status: "pending" });
});