/** * Dev-only smoke check for the berth recommender. Resolves the first * port-nimara interest (with desired dims set) and prints the top-N * recommendations. * * pnpm tsx scripts/dev-recommender-smoke.ts */ import 'dotenv/config'; import { eq, isNotNull, and } from 'drizzle-orm'; import { db } from '@/lib/db'; import { ports } from '@/lib/db/schema/ports'; import { interests } from '@/lib/db/schema/interests'; import { recommendBerths } from '@/lib/services/berth-recommender.service'; async function main() { const [port] = await db .select({ id: ports.id }) .from(ports) .where(eq(ports.slug, 'port-nimara')) .limit(1); if (!port) throw new Error('port-nimara not found'); const [interest] = await db .select({ id: interests.id }) .from(interests) .where(and(eq(interests.portId, port.id), isNotNull(interests.desiredLengthFt))) .limit(1); if (!interest) throw new Error('No interest with desired dims set'); console.log(`> Recommending berths for interest ${interest.id} on port ${port.id}…`); const recs = await recommendBerths({ interestId: interest.id, portId: port.id, }); console.log(`> ${recs.length} recommendations:`); for (const r of recs) { console.log( ` ${r.mooringNumber.padEnd(5)} tier=${r.tier} fit=${r.fitScore} ` + `${r.lengthFt}×${r.widthFt}×${r.draftFt} ft buf=${r.sizeBufferPct}% ` + `${r.reasons.dimensional}; ${r.reasons.pipeline}`, ); } } main() .then(() => process.exit(0)) .catch((err) => { console.error(err); process.exit(1); });