Files
runners-calendar/backend/src/seed.ts
2026-04-08 00:22:11 +03:00

89 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import fs from "fs";
import path from "path";
import { parse } from "csv-parse/sync";
import { pool } from "./db";
interface CsvRow {
date: string;
month: string;
day: string;
event: string;
distance_km: string;
}
function slugify(text: string): string {
return text
.toLowerCase()
.replace(/[«»"]/g, "")
.replace(/[^a-zа-яё0-9]+/gi, "-")
.replace(/(^-|-$)/g, "")
.substring(0, 60);
}
function makeId(date: string, title: string): string {
return `${date}-${slugify(title)}`;
}
const CSV_NAME = "races_2026_calendar.csv";
function resolveCsvPath(): string | null {
// Docker image: /app/dist/*.js → ../import = /app/import (matches Dockerfile COPY import ./import)
// Local monorepo: backend/dist/*.js → ../../import = repo root import/
const candidates = [
path.resolve(__dirname, "../import", CSV_NAME),
path.resolve(__dirname, "../../import", CSV_NAME),
];
return candidates.find((p) => fs.existsSync(p)) ?? null;
}
async function seed() {
const csvPath = resolveCsvPath();
if (!csvPath) {
console.error(
`[seed] CSV not found: ${CSV_NAME}. Tried:\n - ${path.resolve(__dirname, "../import", CSV_NAME)}\n - ${path.resolve(__dirname, "../../import", CSV_NAME)}`,
);
process.exit(1);
}
const raw = fs.readFileSync(csvPath, "utf-8");
const records: CsvRow[] = parse(raw, {
columns: true,
skip_empty_lines: true,
trim: true,
});
console.log(`[seed] Parsed ${records.length} rows from CSV`);
const client = await pool.connect();
try {
for (const row of records) {
const id = makeId(row.date, row.event);
const distanceKm = parseFloat(row.distance_km);
await client.query(
`INSERT INTO races (id, race_date, title, distance_km, status)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (id) DO UPDATE SET
race_date = EXCLUDED.race_date,
title = EXCLUDED.title,
distance_km = EXCLUDED.distance_km,
status = EXCLUDED.status,
updated_at = NOW()`,
[id, row.date, row.event, distanceKm, "planned"],
);
console.log(`[seed] Upserted: ${id}`);
}
console.log("[seed] Done.");
} finally {
client.release();
await pool.end();
}
}
seed().catch((err) => {
console.error("[seed] FAILED:", err.message);
process.exit(1);
});