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:
parent
7eec9d15ee
commit
b5e1749b74
@ -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.
|
É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**
|
- **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`).
|
Si le fichier responded contient `anon_mapping`, la réponse est recontextualisée avant envoi (voir `docs/business-qa-api.md`).
|
||||||
Lit d’abord `projects/<id>/data/notary-ai/responded/`, sinon `pending/`. **Authentification** : idem (token obligatoire).
|
Lit d’abord `projects/<id>/data/notary-ai/responded/`, sinon `pending/`. **Authentification** : idem (token obligatoire).
|
||||||
|
|
||||||
|
|||||||
@ -97,6 +97,17 @@ function findFileByRequestUid(dir, requestUid) {
|
|||||||
return null;
|
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) => {
|
app.get("/health", (req, res) => {
|
||||||
res.status(200).json({ status: "ok" });
|
res.status(200).json({ status: "ok" });
|
||||||
});
|
});
|
||||||
@ -165,12 +176,13 @@ app.get("/v1/response/:request_uid", requireApiTokenAndResolveProject, (req, res
|
|||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
status: "responded",
|
status: "responded",
|
||||||
response,
|
response,
|
||||||
|
...ownershipFromPayload(foundResponded.data),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const pendingDir = path.join(dir, "pending");
|
const pendingDir = path.join(dir, "pending");
|
||||||
const foundPending = findFileByRequestUid(pendingDir, requestUid);
|
const foundPending = findFileByRequestUid(pendingDir, requestUid);
|
||||||
if (foundPending) {
|
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" });
|
res.status(200).json({ status: "pending" });
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user