Replace the per-tour import UI with a fire-and-forget background job: - Add `import_batches` DB table tracking status, found/imported/duplicate counts - Add `runKomootBulkImport` server function that pages all Komoot tours, fetches GPX, creates activities, and deduplicates via sync_imports - Add `komoot-bulk-import` pg-boss job registered at server startup - Add POST /api/sync/komoot/import to enqueue the job - Add GET /api/sync/komoot/import-status to return the latest batch - Replace the Komoot import page with a progress UI that polls every 2s while a batch is running and shows found/imported/skipped counts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
// POST /api/sync/komoot/import
|
|
// Enqueues a background bulk import of all Komoot tours for the connected user.
|
|
// Returns { batchId } immediately; poll /api/sync/komoot/import-status for progress.
|
|
|
|
import { randomUUID } from "node:crypto";
|
|
import { data, redirect } from "react-router";
|
|
import type { Route } from "./+types/api.sync.komoot.import";
|
|
import { getSessionUser } from "~/lib/auth/session.server";
|
|
import { getService } from "~/lib/connected-services/manager";
|
|
import { getBoss } from "~/lib/boss.server";
|
|
import { getDb } from "~/lib/db";
|
|
import { importBatches } from "@trails-cool/db/schema/journal";
|
|
|
|
export async function action({ request }: Route.ActionArgs) {
|
|
const user = await getSessionUser(request);
|
|
if (!user) return redirect("/auth/login");
|
|
|
|
const service = await getService(user.id, "komoot");
|
|
if (!service) return data({ error: "not_connected" }, { status: 400 });
|
|
|
|
const db = getDb();
|
|
const batchId = randomUUID();
|
|
await db.insert(importBatches).values({
|
|
id: batchId,
|
|
userId: user.id,
|
|
connectionId: service.id,
|
|
provider: "komoot",
|
|
status: "pending",
|
|
});
|
|
|
|
const boss = getBoss();
|
|
await boss.send("komoot-bulk-import", {
|
|
batchId,
|
|
userId: user.id,
|
|
creds: service.credentials,
|
|
});
|
|
|
|
return data({ batchId });
|
|
}
|