keyword-counters.js
1 /** 2 * Keyword Counter Updates 3 * 4 * Utilities for incrementing keyword counters on the happy path. 5 * Each stage updates its respective counter when sites are processed. 6 */ 7 8 import { run } from './db.js'; 9 import Logger from './logger.js'; 10 11 const logger = new Logger('KeywordCounters'); 12 13 /** 14 * Increment assets_scraped_count for a keyword 15 * Called after assets (screenshots) are captured 16 * 17 * @param {string} keyword 18 * @param {string} countryCode 19 * @returns {Promise<void>} 20 */ 21 export async function incrementAssetsScraped(keyword, countryCode) { 22 try { 23 await run( 24 ` 25 UPDATE keywords 26 SET assets_scraped_count = assets_scraped_count + 1, 27 updated_at = CURRENT_TIMESTAMP 28 WHERE keyword = $1 AND country_code = $2 29 `, 30 [keyword, countryCode] 31 ); 32 } catch (error) { 33 logger.warn(`Failed to increment assets_scraped_count for "${keyword}": ${error.message}`); 34 } 35 } 36 37 /** 38 * Increment low_scoring_count for a keyword 39 * Called after scoring when site scores < 82 40 * 41 * @param {string} keyword 42 * @param {string} countryCode 43 * @returns {Promise<void>} 44 */ 45 export async function incrementLowScoring(keyword, countryCode) { 46 try { 47 await run( 48 ` 49 UPDATE keywords 50 SET low_scoring_count = low_scoring_count + 1, 51 updated_at = CURRENT_TIMESTAMP 52 WHERE keyword = $1 AND country_code = $2 53 `, 54 [keyword, countryCode] 55 ); 56 } catch (error) { 57 logger.warn(`Failed to increment low_scoring_count for "${keyword}": ${error.message}`); 58 } 59 } 60 61 /** 62 * Increment rescored_count for a keyword 63 * Called after rescoring stage 64 * 65 * @param {string} keyword 66 * @param {string} countryCode 67 * @returns {Promise<void>} 68 */ 69 export async function incrementRescored(keyword, countryCode) { 70 try { 71 await run( 72 ` 73 UPDATE keywords 74 SET rescored_count = rescored_count + 1, 75 updated_at = CURRENT_TIMESTAMP 76 WHERE keyword = $1 AND country_code = $2 77 `, 78 [keyword, countryCode] 79 ); 80 } catch (error) { 81 logger.warn(`Failed to increment rescored_count for "${keyword}": ${error.message}`); 82 } 83 } 84 85 /** 86 * Batch increment assets_scraped_count for multiple sites 87 * More efficient than individual updates 88 * 89 * @param {Array<{keyword: string, country_code: string}>} sites 90 * @returns {Promise<void>} 91 */ 92 export async function batchIncrementAssetsScraped(sites) { 93 if (!sites || sites.length === 0) return; 94 95 for (const site of sites) { 96 if (site.keyword && site.country_code) { 97 try { 98 await run( 99 ` 100 UPDATE keywords 101 SET assets_scraped_count = assets_scraped_count + 1, 102 updated_at = CURRENT_TIMESTAMP 103 WHERE keyword = $1 AND country_code = $2 104 `, 105 [site.keyword, site.country_code] 106 ); 107 } catch (error) { 108 logger.warn(`Failed to increment for "${site.keyword}": ${error.message}`); 109 } 110 } 111 } 112 } 113 114 /** 115 * Batch increment low_scoring_count for multiple sites 116 * 117 * @param {Array<{keyword: string, country_code: string}>} sites 118 * @returns {Promise<void>} 119 */ 120 export async function batchIncrementLowScoring(sites) { 121 if (!sites || sites.length === 0) return; 122 123 for (const site of sites) { 124 if (site.keyword && site.country_code) { 125 try { 126 await run( 127 ` 128 UPDATE keywords 129 SET low_scoring_count = low_scoring_count + 1, 130 updated_at = CURRENT_TIMESTAMP 131 WHERE keyword = $1 AND country_code = $2 132 `, 133 [site.keyword, site.country_code] 134 ); 135 } catch (error) { 136 logger.warn(`Failed to increment for "${site.keyword}": ${error.message}`); 137 } 138 } 139 } 140 } 141 142 /** 143 * Batch increment rescored_count for multiple sites 144 * 145 * @param {Array<{keyword: string, country_code: string}>} sites 146 * @returns {Promise<void>} 147 */ 148 export async function batchIncrementRescored(sites) { 149 if (!sites || sites.length === 0) return; 150 151 for (const site of sites) { 152 if (site.keyword && site.country_code) { 153 try { 154 await run( 155 ` 156 UPDATE keywords 157 SET rescored_count = rescored_count + 1, 158 updated_at = CURRENT_TIMESTAMP 159 WHERE keyword = $1 AND country_code = $2 160 `, 161 [site.keyword, site.country_code] 162 ); 163 } catch (error) { 164 logger.warn(`Failed to increment for "${site.keyword}": ${error.message}`); 165 } 166 } 167 } 168 }