/home/techb158/cosmic.abdallabala.com/src/integrations/pmClients
Edit: /home/techb158/cosmic.abdallabala.com/src/integrations/pmClients/plannerClient.js (2227B)
const { fetchJson, buildRiskDescription } = require("./httpClient.js");
class PlannerClient {
constructor(options = {}) {
this.accessToken = options.accessToken;
this.planId = options.planId;
this.bucketId = options.bucketId;
this.fetchImpl = options.fetchImpl;
if (!this.accessToken) throw new Error("Microsoft Planner requires MICROSOFT_GRAPH_ACCESS_TOKEN or a stored OAuth token");
}
headers(extra = {}) {
return Object.assign({ "Authorization": `Bearer ${this.accessToken}`, "Accept": "application/json", "Content-Type": "application/json" }, extra);
}
async testConnection() {
const user = await fetchJson("https://graph.microsoft.com/v1.0/me", { headers: this.headers() }, this.fetchImpl);
return { ok: true, provider: "Microsoft Planner", account: user.displayName || user.userPrincipalName || user.id, raw: user };
}
async createRiskWorkItem(risk, mitigations = [], integration = {}) {
const planId = integration.external_project_key || this.planId;
const bucketId = integration.live_config && integration.live_config.bucketId || this.bucketId;
if (!planId || !bucketId) throw new Error("Microsoft Planner live sync requires PLANNER_PLAN_ID and PLANNER_BUCKET_ID, or integration.external_project_key plus live_config.bucketId");
const task = await fetchJson("https://graph.microsoft.com/v1.0/planner/tasks", {
method: "POST",
headers: this.headers(),
body: JSON.stringify({ planId, bucketId, title: `[COSMIC Risk] ${risk.title}` })
}, this.fetchImpl);
return {
externalId: task.id,
externalKey: task.id,
externalUrl: task.id ? `https://tasks.office.com/Home/Task/${task.id}` : "",
externalStatus: `Created. Details not patched automatically: ${buildRiskDescription(risk, mitigations).slice(0, 80)}`
};
}
async updateRiskWorkItem(mapping, risk) {
return {
externalId: mapping.external_item_id,
externalKey: mapping.external_item_key,
externalUrl: mapping.external_url,
externalStatus: `Skipped update. Planner task updates require an eTag fetched from Microsoft Graph for PATCH operations. Risk title: ${risk.title}`
};
}
}
module.exports = { PlannerClient };