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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142import { db, event, graphqlQuery } from "#src/utils";
export const getAuditChart = async () => {
const auditId = (event.queryStringParameters as any).id;
const days = parseInt((event.queryStringParameters as any).days || "7", 10);
await db.connect();
const audit = (
await db.query({
text: `SELECT * FROM "audits" WHERE "id" = $1`,
values: [auditId],
})
).rows?.[0];
await db.clean();
// Query to get all scans for the audit with blocker counts
const query = {
query: `query ($audit_id: uuid!) {
audits_by_pk(id: $audit_id) {
scans(order_by: {created_at: asc}) {
id
created_at
blockers_aggregate(where: {_not: {ignored_blocker: {id: {_is_null: false}}}}) {
aggregate {
count
}
}
}
}
}`,
variables: { audit_id: auditId },
};
//console.log(JSON.stringify({ query }));
const response = await graphqlQuery(query);
//console.log(JSON.stringify({ response }));
const scans = response.audits_by_pk?.scans || [];
// Process scans to get the last scan per day
const scansByDate = new Map<
string,
{ date: string; blockers: number; timestamp: string }
>();
scans.forEach((scan:any) => {
const scanDate = new Date(scan.created_at);
//console.log("scan.created_at", scan.created_at);
//console.log("scanDate", scanDate);
const dateKey = scanDate.toISOString().split("T")[0]; // YYYY-MM-DD format
//console.log("dateKey", dateKey)
const blockerCount = scan.blockers_aggregate?.aggregate?.count || 0;
// Only keep the last scan for each day (scans are ordered by created_at asc)
scansByDate.set(dateKey, {
date: dateKey,
blockers: blockerCount,
timestamp: scan.created_at,
});
});
// Generate array of the last N days
const now = new Date();
now.setUTCHours(0, 0, 0, 0); // Reset to start of day in UTC
const chartData = [];
let lastKnownValue = 0;
// get the blockers value of the most recent scan
let mostRecentScan = null;
let oldestScan = "";
let mostRecentBlockersCount = 0;
if (scansByDate.size > 0) { // testing we have scans to avoid error when no scans are present
mostRecentScan = Array.from(scansByDate.values()).sort((a, b) =>
b.timestamp.localeCompare(a.timestamp),
)[0];
oldestScan =
Array.from(scansByDate.values()).sort((a, b) =>
a.timestamp.localeCompare(b.timestamp),
)[0].timestamp ?? "";
mostRecentBlockersCount = mostRecentScan.blockers;
}
lastKnownValue = mostRecentBlockersCount;
for (let i = days - 1; i >= 0; i--) {
const date = new Date(now);
date.setUTCDate(date.getUTCDate() - i);
const dateKey = date.toISOString().split("T")[0];
if (scansByDate.has(dateKey)) {
// Use the actual scan data for this day
const scanData = scansByDate.get(dateKey)!;
lastKnownValue = scanData.blockers;
chartData.push({
date: dateKey,
blockers: scanData.blockers,
timestamp: scanData.timestamp,
});
} else {
// Fill with the last known value
if (oldestScan === "" || date.toISOString() < oldestScan) {
lastKnownValue = 0; // if the date we're showing is before the first scan, set to zero
} else {
lastKnownValue = mostRecentBlockersCount; // otherwise use the blockers value from the latest scan
}
if (days > 30) {
// If the range is >30 days, only return weekly points
if (i % 7 === 0) {
chartData.push({
date: dateKey,
blockers: lastKnownValue,
timestamp: null,
});
}
} else {
chartData.push({
date: dateKey,
blockers: lastKnownValue,
timestamp: null,
});
}
}
}
return {
statusCode: 200,
headers: { "content-type": "application/json" },
body: {
audit_id: auditId,
audit_name: audit?.name,
period_days: days,
data: chartData,
},
};
};