import { getDbPool } from '../../server/src/db/pool.js'; import { createScriptLogger } from './postal-logging.js'; async function logPostalAreaCounts() { const pool = getDbPool(); const result = await pool.query<{ country_code: string; area_count: string }>(` select country_code, count(*)::text as area_count from public.postal_areas group by country_code order by country_code asc `); return result.rows; } async function buildNeighborsForCountry(countryCode: 'US' | 'CA') { const pool = getDbPool(); const logger = createScriptLogger(`postal-neighbors:${countryCode.toLowerCase()}`); const sourceCountResult = await pool.query<{ area_count: string }>( `select count(*)::text as area_count from public.postal_areas where country_code = $1`, [countryCode], ); const areaCount = sourceCountResult.rows[0]?.area_count ?? '0'; logger.info(`Starting neighbor build for ${countryCode} with ${areaCount} postal areas.`); await pool.query( ` insert into public.postal_area_neighbors (postal_area_id, neighbor_postal_area_id) select source.id, neighbor.id from public.postal_areas source join public.postal_areas neighbor on source.country_code = neighbor.country_code and source.id <> neighbor.id and ST_Touches(source.geom, neighbor.geom) where source.country_code = $1 `, [countryCode], ); const neighborCountResult = await pool.query<{ neighbor_count: string }>( ` select count(*)::text as neighbor_count from public.postal_area_neighbors link join public.postal_areas area on area.id = link.postal_area_id where area.country_code = $1 `, [countryCode], ); logger.info(`Completed neighbor build for ${countryCode}. Built ${neighborCountResult.rows[0]?.neighbor_count ?? '0'} adjacency links.`); } async function run() { const logger = createScriptLogger('postal-neighbors'); const pool = getDbPool(); const client = await pool.connect(); try { logger.info('Gathering postal area counts before neighbor build.'); const counts = await logPostalAreaCounts(); counts.forEach((row) => logger.info(`Found ${row.area_count} postal areas for ${row.country_code}.`)); await client.query('begin'); logger.info('Clearing existing postal adjacency links.'); await client.query('truncate table public.postal_area_neighbors'); await client.query('commit'); await buildNeighborsForCountry('US'); await buildNeighborsForCountry('CA'); const summary = await pool.query<{ count: string }>('select count(*)::text as count from public.postal_area_neighbors'); logger.info(`Finished building postal neighbors. Total adjacency links: ${summary.rows[0]?.count ?? '0'}.`); } catch (error) { await client.query('rollback'); logger.error('Neighbor build failed.'); throw error; } finally { client.release(); await pool.end(); } } await run();