File size: 2,759 Bytes
89b6a21
 
 
 
 
37ee895
 
89b6a21
 
 
 
 
 
 
 
 
 
 
37ee895
 
 
 
 
 
 
 
89b6a21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37ee895
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { fetchWithTimeout } from "../shared/api.js";
import { getStorageItem } from "../shared/dom.js";

const TOKEN_KEY = "byte_dashboard_admin_token";
const ACTION_QUEUE_ENDPOINT = "./api/action-queue";
const OPS_PLAYBOOKS_ENDPOINT = "./api/ops-playbooks";
const OPS_PLAYBOOKS_TRIGGER_ENDPOINT = "./api/ops-playbooks/trigger";
const REQUEST_TIMEOUT_MS = 12000;

function authHeaders() {
    const headers = {};
    const token = getStorageItem(TOKEN_KEY);
    if (token) {
        headers["X-Byte-Admin-Token"] = token;
    }
    return headers;
}

function normalizeChannelId(channelId) {
    return (
        String(channelId || "")
            .trim()
            .toLowerCase() || "default"
    );
}

export async function getActionQueue({ status = "", limit = 80 } = {}, timeoutMs = REQUEST_TIMEOUT_MS) {
    const params = new URLSearchParams();
    if (String(status || "").trim()) {
        params.set("status", String(status).trim());
    }
    params.set("limit", String(limit || 80));

    const endpoint = `${ACTION_QUEUE_ENDPOINT}?${params.toString()}`;
    return await fetchWithTimeout(endpoint, { method: "GET", headers: authHeaders() }, timeoutMs);
}

export async function decideActionQueueItem(actionId, decision, note = "", timeoutMs = REQUEST_TIMEOUT_MS) {
    const safeActionId = encodeURIComponent(String(actionId || "").trim());
    return await fetchWithTimeout(
        `${ACTION_QUEUE_ENDPOINT}/${safeActionId}/decision`,
        {
            method: "POST",
            headers: authHeaders(),
            body: JSON.stringify({
                decision: String(decision || "").trim().toLowerCase(),
                note: String(note || "").trim(),
            }),
        },
        timeoutMs
    );
}

export async function getOpsPlaybooks(channelId = "default", timeoutMs = REQUEST_TIMEOUT_MS) {
    const params = new URLSearchParams({
        channel: normalizeChannelId(channelId),
    });
    return await fetchWithTimeout(
        `${OPS_PLAYBOOKS_ENDPOINT}?${params.toString()}`,
        { method: "GET", headers: authHeaders() },
        timeoutMs
    );
}

export async function triggerOpsPlaybook(
    { playbookId = "", channelId = "default", reason = "manual_dashboard", force = false } = {},
    timeoutMs = REQUEST_TIMEOUT_MS
) {
    return await fetchWithTimeout(
        OPS_PLAYBOOKS_TRIGGER_ENDPOINT,
        {
            method: "POST",
            headers: authHeaders(),
            body: JSON.stringify({
                playbook_id: String(playbookId || "").trim().toLowerCase(),
                channel_id: normalizeChannelId(channelId),
                reason: String(reason || "manual_dashboard").trim(),
                force: Boolean(force),
            }),
        },
        timeoutMs
    );
}