a cache for slack profile pictures and emojis
at main 3.4 kB view raw
1import type { Database } from "bun:sqlite"; 2import type { Migration } from "./types"; 3 4/** 5 * Migration to group request logs that aren't already grouped 6 * This migration normalizes request_analytics data to use consistent endpoint grouping 7 */ 8export const logGroupingMigration: Migration = { 9 version: "0.3.2", 10 description: "Group request logs that aren't already grouped", 11 12 async up(db: Database): Promise<void> { 13 console.log("Running log grouping migration..."); 14 15 // Get all request_analytics entries with specific URLs that need grouping 16 const results = db 17 .query(` 18 SELECT id, endpoint FROM request_analytics 19 WHERE 20 endpoint NOT LIKE '/users/%/r' AND 21 endpoint NOT LIKE '/users/%' AND 22 endpoint NOT LIKE '/emojis/%/r' AND 23 endpoint NOT LIKE '/emojis/%' AND 24 endpoint NOT LIKE '/health' AND 25 endpoint NOT LIKE '/dashboard' AND 26 endpoint NOT LIKE '/swagger%' AND 27 endpoint NOT LIKE '/reset' AND 28 endpoint NOT LIKE '/stats' AND 29 endpoint NOT LIKE '/' 30 `) 31 .all() as Array<{ id: string; endpoint: string }>; 32 33 console.log(`Found ${results.length} entries to update`); 34 35 // Process each entry and update with the correct grouping 36 for (const entry of results) { 37 let newEndpoint = entry.endpoint; 38 39 // Apply grouping logic 40 if ( 41 entry.endpoint.includes("localhost") || 42 entry.endpoint.includes("http") 43 ) { 44 // Extract the path from URLs 45 try { 46 const url = new URL(entry.endpoint); 47 newEndpoint = url.pathname; 48 } catch (_e) { 49 // If URL parsing fails, try to extract the path manually 50 const pathMatch = entry.endpoint.match(/https?:\/\/[^/]+(\/.*)/); 51 if (pathMatch?.[1]) { 52 newEndpoint = pathMatch[1]; 53 } 54 } 55 } 56 57 // Now apply the same grouping logic to the extracted path 58 if (newEndpoint.match(/^\/users\/[^/]+$/)) { 59 newEndpoint = "/users/USER_ID"; 60 } else if (newEndpoint.match(/^\/users\/[^/]+\/r$/)) { 61 newEndpoint = "/users/USER_ID/r"; 62 } else if (newEndpoint.match(/^\/emojis\/[^/]+$/)) { 63 newEndpoint = "/emojis/EMOJI_NAME"; 64 } else if (newEndpoint.match(/^\/emojis\/[^/]+\/r$/)) { 65 newEndpoint = "/emojis/EMOJI_NAME/r"; 66 } else if ( 67 newEndpoint.includes("/users/") && 68 newEndpoint.includes("/r") 69 ) { 70 newEndpoint = "/users/USER_ID/r"; 71 } else if (newEndpoint.includes("/users/")) { 72 newEndpoint = "/users/USER_ID"; 73 } else if ( 74 newEndpoint.includes("/emojis/") && 75 newEndpoint.includes("/r") 76 ) { 77 newEndpoint = "/emojis/EMOJI_NAME/r"; 78 } else if (newEndpoint.includes("/emojis/")) { 79 newEndpoint = "/emojis/EMOJI_NAME"; 80 } else if (newEndpoint === "/") { 81 newEndpoint = "/"; 82 } else if (newEndpoint === "/health") { 83 newEndpoint = "/health"; 84 } else if (newEndpoint === "/dashboard") { 85 newEndpoint = "/dashboard"; 86 } else if (newEndpoint.startsWith("/swagger")) { 87 newEndpoint = "/swagger"; 88 } else if (newEndpoint === "/reset") { 89 newEndpoint = "/reset"; 90 } else if (newEndpoint === "/stats") { 91 newEndpoint = "/stats"; 92 } else { 93 newEndpoint = "/other"; 94 } 95 96 // Only update if the endpoint has changed 97 if (newEndpoint !== entry.endpoint) { 98 db.run( 99 ` 100 UPDATE request_analytics 101 SET endpoint = ? 102 WHERE id = ? 103 `, 104 [newEndpoint, entry.id], 105 ); 106 } 107 } 108 109 console.log("Log grouping migration completed"); 110 }, 111};