trails/apps/journal/app/jobs/komoot-bulk-import.ts
Ullrich Schäfer b0b58d36fb
chore(ts): eliminate the remaining 4 \as any\ casts in production code
Followup to #447. The audit ran on \`as unknown as\` first; this PR
closes out \`as any\` separately. After this, \`grep -rn ' as any\\b'
apps/ packages/\` returns 0 (excluding tests and node_modules).

## Sites fixed

**\`apps/journal/server.ts\`** + **\`packages/jobs/src/types.ts\`** —
\`komootBulkImportJob as any\`. The job had a typed payload
(\`JobDefinition<KomootBulkImportData>\`) but the worker's
\`JobDefinition[]\` array forced a contravariance cast at every site
that mixed typed and untyped jobs. Dropped the generic from
\`JobDefinition\` entirely; handlers narrow their own \`job.data\`. Only
one job (komoot-bulk-import) used the generic, so the surface is tiny.

**\`apps/journal/app/lib/connected-services/fit.ts\`** + same pattern in
\`routes/sync.import.\$provider.server.ts\` — \`parser.parse(buffer as any,
(err: unknown, d: any) => ...)\`. fit-file-parser's TypeScript types
require \`Buffer<ArrayBuffer>\` specifically; a generic Node \`Buffer\`
is structurally \`Buffer<ArrayBufferLike>\` (which includes
SharedArrayBuffer). The runtime accepts either, so narrowed the cast
to \`as Buffer<ArrayBuffer>\` — still a cast, but precise about what
we're asserting and why. Removed the \`(err, d: any) => …\` ad-hoc
callback typings; the library exports a proper \`FitParserCallback\`.

**\`apps/mobile/lib/editor/RouteMap.tsx\`** — \`onLongPress\` handler
took \`(event: any)\`. maplibre-react-native v11 generates the event
type via React Native codegen but doesn't re-export it as a public
TypeScript type. Replaced with a local structural slice of the parts
we actually read.

Net: 4 \`as any\` sites in prod code → 0. \`pnpm typecheck\` / \`lint\` /
\`test\` all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 07:11:02 +02:00

29 lines
1,023 B
TypeScript

import type { JobDefinition } from "@trails-cool/jobs";
import { logger } from "../lib/logger.server.ts";
import { runKomootBulkImport } from "../lib/komoot-bulk-import.server.ts";
type KomootCreds =
| { mode: "public"; komootUserId: string }
| { mode: "authenticated"; email: string; encryptedPassword: string; komootUserId: string };
interface KomootBulkImportData {
batchId: string;
userId: string;
creds: KomootCreds;
}
export const komootBulkImportJob: JobDefinition = {
name: "komoot-bulk-import",
retryLimit: 1,
expireInSeconds: 1800,
async handler(jobs) {
const batch = Array.isArray(jobs) ? jobs : [jobs];
for (const job of batch) {
// pg-boss serialized payload — caller (enqueueOptional) wrote it
// as KomootBulkImportData. Narrow at the boundary.
const { batchId, userId, creds } = job.data as KomootBulkImportData;
logger.info({ batchId, userId }, "komoot bulk import job started");
await runKomootBulkImport(batchId, userId, creds);
}
},
};