All files / src/scripts backfill-simplified.ts

0% Statements 0/56
0% Branches 0/1
0% Functions 0/1
0% Lines 0/56

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71                                                                                                                                             
import { Prisma } from "@prisma/client";
import { loadConfig } from "../config.js";
import { fetchTrackGeometry } from "../lib/geo-client.js";
import { prisma } from "../lib/prisma.js";
import { createGpxContentStore } from "../storage/create-gpx-content-store.js";
 
/**
 * One-off backfill: compute and store the simplified polyline for tracks
 * uploaded before geo-service existed (simplified_geojson IS NULL). Idempotent —
 * a re-run only touches rows that are still NULL. Run inside the catalog
 * container so it shares DATABASE_URL / R2 / GEO_SERVICE_URL / SERVICE_TOKEN:
 *
 *   docker compose exec gpx-catalog-service npm run backfill:simplified
 */
async function main(): Promise<void> {
  const config = loadConfig();
  const store = createGpxContentStore(config);
 
  const tracks = await prisma.gpxTrack.findMany({
    where: {
      OR: [
        { simplifiedGeojson: { equals: Prisma.AnyNull } },
        { elevationProfile: { equals: Prisma.AnyNull } },
      ],
    },
    select: { id: true, fileName: true },
    orderBy: { id: "asc" },
  });
 
  console.log(`backfill: ${tracks.length} track(s) missing silhouette/profile`);
 
  let updated = 0;
  let skipped = 0;
  for (const track of tracks) {
    try {
      const { body } = await store.getByFileName(track.fileName);
      const geometry = await fetchTrackGeometry(body, config);
      if (!geometry) {
        skipped++;
        console.warn(`  #${track.id} ${track.fileName}: geo-service returned nothing — skipped`);
        continue;
      }
      await prisma.gpxTrack.update({
        where: { id: track.id },
        data: {
          simplifiedGeojson: geometry.simplified,
          ...(geometry.profile ? { elevationProfile: geometry.profile } : {}),
        },
      });
      updated++;
      console.log(
        `  #${track.id} ${track.fileName}: ${geometry.simplified.length} pts, profile ${geometry.profile?.length ?? 0}`,
      );
    } catch (err) {
      skipped++;
      const msg = err instanceof Error ? err.message : String(err);
      console.warn(`  #${track.id} ${track.fileName}: ${msg}`);
    }
  }
 
  console.log(`backfill done: ${updated} updated, ${skipped} skipped`);
  await prisma.$disconnect();
}
 
main()
  .then(() => process.exit(0))
  .catch((err) => {
    console.error(err);
    process.exit(1);
  });