- Create SiteAssignments DynamoDB table with state GSI for site code and state-based queries - Add lookup_site function to wo-po-lookup action group lambda - Add seed script (scripts/seed-sites.ts) to load site CSV into DynamoDB - Upload site list markdown to KB S3 bucket for semantic search - Update agent instruction to include site lookup capability - Update README with site assignment docs and maintenance notes
84 lines
2.5 KiB
TypeScript
84 lines
2.5 KiB
TypeScript
/**
|
|
* Seed the SiteAssignments DynamoDB table from the Amazon site list CSV.
|
|
*
|
|
* Usage:
|
|
* npx tsx scripts/seed-sites.ts path/to/amazon-sites.csv
|
|
*/
|
|
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
|
|
import { DynamoDBDocumentClient, BatchWriteCommand } from '@aws-sdk/lib-dynamodb';
|
|
import { readFileSync } from 'fs';
|
|
|
|
const TABLE_NAME = 'SiteAssignments';
|
|
const REGION = 'us-east-1';
|
|
|
|
const ddb = DynamoDBDocumentClient.from(new DynamoDBClient({ region: REGION }));
|
|
|
|
function parseCSV(filePath: string) {
|
|
const content = readFileSync(filePath, 'utf-8');
|
|
const lines = content.split('\n').filter((l) => l.trim());
|
|
return lines.slice(1).map((line) => {
|
|
const cols = line.split(',');
|
|
return {
|
|
siteCode: (cols[0] ?? '').trim(),
|
|
address: (cols[1] ?? '').trim(),
|
|
city: (cols[2] ?? '').trim(),
|
|
state: (cols[3] ?? '').trim(),
|
|
zip: (cols[4] ?? '').trim(),
|
|
fullAddress: (cols[5] ?? '').trim(),
|
|
latitude: (cols[6] ?? '').trim(),
|
|
longitude: (cols[7] ?? '').trim(),
|
|
notes: (cols[9] ?? '').trim(),
|
|
};
|
|
}).filter((r) => r.siteCode);
|
|
}
|
|
|
|
async function seed(filePath: string) {
|
|
const allRows = parseCSV(filePath);
|
|
// Deduplicate by siteCode — last occurrence wins
|
|
const deduped = new Map(allRows.map((r) => [r.siteCode, r]));
|
|
const rows = [...deduped.values()];
|
|
console.log(`Parsed ${allRows.length} rows, ${rows.length} unique sites`);
|
|
|
|
let written = 0;
|
|
for (let i = 0; i < rows.length; i += 25) {
|
|
const batch = rows.slice(i, i + 25);
|
|
const requests = batch.map((row) => ({
|
|
PutRequest: {
|
|
Item: {
|
|
siteCode: row.siteCode,
|
|
address: row.address,
|
|
city: row.city,
|
|
state: row.state,
|
|
...(row.zip && { zip: row.zip }),
|
|
fullAddress: row.fullAddress,
|
|
...(row.latitude && { latitude: row.latitude }),
|
|
...(row.longitude && { longitude: row.longitude }),
|
|
...(row.notes && { notes: row.notes }),
|
|
},
|
|
},
|
|
}));
|
|
|
|
await ddb.send(
|
|
new BatchWriteCommand({
|
|
RequestItems: { [TABLE_NAME]: requests },
|
|
}),
|
|
);
|
|
written += batch.length;
|
|
if (written % 250 === 0 || written === rows.length) {
|
|
console.log(` Written ${written}/${rows.length}`);
|
|
}
|
|
}
|
|
|
|
console.log(`Done — seeded ${written} sites into ${TABLE_NAME}`);
|
|
}
|
|
|
|
const csvPath = process.argv[2];
|
|
if (!csvPath) {
|
|
console.error('Usage: npx tsx scripts/seed-sites.ts <path-to-csv>');
|
|
process.exit(1);
|
|
}
|
|
|
|
seed(csvPath).catch((err) => {
|
|
console.error('Seed failed:', err);
|
|
process.exit(1);
|
|
});
|