Skip to content

Commit 1fb1d36

Browse files
committed
Fullstack: testing for refactored auditsummary
1 parent d4f2d7c commit 1fb1d36

4 files changed

Lines changed: 124 additions & 4 deletions

File tree

apps/backend/routes/auth/getAuditSummary.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ interface ItemCount {
4040
}
4141

4242
export const getAuditSummary = async () => {
43+
const start = performance.now();
4344
const auditId = (event.queryStringParameters as any).id;
4445
const mostCommonUrlsLimit =
4546
(event.queryStringParameters as any).mostCommonUrlsLimit ?? 5;
@@ -74,7 +75,7 @@ export const getAuditSummary = async () => {
7475
},
7576
};
7677
const response = (await graphqlQuery(query)) as AuditSummaryResp;
77-
console.log(JSON.stringify({ response }));
78+
//console.log(JSON.stringify({ response }));
7879

7980
const flattened = response.blockers.map((item) => {
8081
return {
@@ -117,6 +118,8 @@ export const getAuditSummary = async () => {
117118
mostCommonTagsLimit
118119
)
119120

121+
const end = performance.now();
122+
120123
return {
121124
statusCode: 200,
122125
headers: { "content-type": "application/json" },
@@ -125,7 +128,8 @@ export const getAuditSummary = async () => {
125128
urlsWithMostErrors,
126129
mostCommonErrors,
127130
mostCommonCategory,
128-
mostCommonTags
131+
mostCommonTags,
132+
executionTime: end - start
129133
},
130134
};
131135
};
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { db, event, graphqlQuery } from "#src/utils";
2+
3+
// db resp types
4+
interface AuditSummaryRespBlockerMessagesTag {
5+
tag: {
6+
content: string;
7+
};
8+
}
9+
10+
interface AuditSummaryRespBlockerMessages {
11+
message: {
12+
content: string;
13+
message_tags: AuditSummaryRespBlockerMessagesTag[];
14+
category: string;
15+
};
16+
}
17+
18+
interface AuditSummaryRespBlocker {
19+
blocker_messages: AuditSummaryRespBlockerMessages[];
20+
url: {
21+
url: string;
22+
};
23+
}
24+
25+
interface AuditSummaryResp {
26+
blockers: AuditSummaryRespBlocker[];
27+
}
28+
29+
30+
export const getAuditSummaryFast = async () => {
31+
32+
const start = performance.now();
33+
const auditId = (event.queryStringParameters as any).id;
34+
const mostCommonUrlsLimit =
35+
(event.queryStringParameters as any).mostCommonUrlsLimit ?? 5;
36+
const mostCommonBlockersLimit =
37+
(event.queryStringParameters as any).mostCommonBlockersLimit ?? 5;
38+
const mostCommonCategoriesLimit =
39+
(event.queryStringParameters as any).mostCommonCategoriesLimit ?? 3;
40+
const mostCommonTagsLimit =
41+
(event.queryStringParameters as any).mostCommonTagsLimit ?? 3;
42+
43+
const query = {
44+
query: `query GetAuditStats($audit_id: uuid!, $urlLimit: Int!, $msgLimit: Int!) {
45+
unique_urls: blocker_summary_view_aggregate(
46+
distinct_on: [url],
47+
where: { audit_id: { _eq: $audit_id } }
48+
) {
49+
aggregate {
50+
count
51+
}
52+
}
53+
}`,
54+
variables: {
55+
audit_id: auditId,
56+
urlLimit: mostCommonUrlsLimit,
57+
msgLimit: mostCommonBlockersLimit
58+
},
59+
};
60+
const response = (await graphqlQuery(query)) as AuditSummaryResp;
61+
//console.log(JSON.stringify({ response }));
62+
63+
const urlFreq: Record<string, number> = {};
64+
const msgFreq: Record<string, number> = {};
65+
const catFreq: Record<string, number> = {};
66+
const tagFreq: Record<string, number> = {};
67+
let uniqueUrlCount = 0;
68+
const urlSeen = new Set<string>();
69+
70+
// SINGLE PASS: We touch each piece of data exactly once
71+
for (const blocker of response.blockers) {
72+
const url = blocker.url.url;
73+
74+
// Track unique URLs
75+
if (!urlSeen.has(url)) {
76+
urlSeen.add(url);
77+
uniqueUrlCount++;
78+
}
79+
80+
urlFreq[url] = (urlFreq[url] || 0) + 1;
81+
82+
// Process nested messages (assuming at least one exists)
83+
const firstMsg = blocker.blocker_messages[0]?.message;
84+
if (firstMsg) {
85+
msgFreq[firstMsg.content] = (msgFreq[firstMsg.content] || 0) + 1;
86+
catFreq[firstMsg.category] = (catFreq[firstMsg.category] || 0) + 1;
87+
88+
for (const t of firstMsg.message_tags) {
89+
const tag = t.tag.content;
90+
tagFreq[tag] = (tagFreq[tag] || 0) + 1;
91+
}
92+
}
93+
}
94+
95+
// Reusable helper for sorting/slicing
96+
const getTop = (freqMap: Record<string, number>, limit: number) =>
97+
Object.entries(freqMap)
98+
.map(([key, count]) => ({ key, count }))
99+
.sort((a, b) => b.count - a.count)
100+
.slice(0, limit);
101+
102+
103+
const end = performance.now();
104+
return {
105+
statusCode: 200,
106+
body: {
107+
urlsWithBlockersCount: uniqueUrlCount,
108+
urlsWithMostErrors: getTop(urlFreq, mostCommonUrlsLimit),
109+
mostCommonErrors: getTop(msgFreq, mostCommonBlockersLimit),
110+
mostCommonCategory: getTop(catFreq, mostCommonCategoriesLimit),
111+
mostCommonTags: getTop(tagFreq, mostCommonTagsLimit),
112+
executionTime: end-start
113+
},
114+
};
115+
};

apps/backend/routes/auth/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export * from './getAuditTable'
1414
export * from './getLogs'
1515
export * from './inviteUser'
1616
export * from './getAuditSummary'
17+
export * from './getAuditSummaryFast'
1718
export * from './saveQuickScan'
1819
export * from './getQuickScans'
1920
export * from './fetchRemoteCsv'

apps/frontend/src/components/BlockersTableSummary.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ export const BlockersTableSummary = ({ auditId, isShared, chartData, pages, scan
5353
};
5454
const response = await API.get({
5555
apiName: isShared ? "public" : "auth",
56-
path: "/getAuditSummary",
56+
path: "/getAuditSummaryFast",
5757
options: { queryParams: params },
5858
}).response;
5959
const resp = (await response.body.json()) as any as SummaryResp;
60-
//console.log(resp);
60+
console.log(resp);
6161
return resp;
6262
}
6363
});

0 commit comments

Comments
 (0)