feat: show the German/French drop count in the digest

Jobs rejected for German/French content never reach jobs.csv, so daily.ts
had no way to see they existed — the digest silently under-reported how
much the run actually looked at.

index.ts now counts them across both the LinkedIn and extra-source paths
and writes results/.lang-dropped.json; daily.ts reads it back, keyed on
the digest date, and appends a count-only category. Count-only because
there is no Row to list — these were dropped before ever being parsed.
This commit is contained in:
2026-09-05 18:04:29 +02:00
parent 2b7bf3b5f7
commit af5df25fa1
2 changed files with 23 additions and 1 deletions
+14 -1
View File
@@ -8,6 +8,7 @@ import { matchesProfile } from "./profile.ts";
const CSV = "./results/jobs.csv";
const SENT = "./results/sent.txt"; // links already pushed — never resend
const LANG_DROPPED = "./results/.lang-dropped.json"; // written by index.ts — jobs dropped for German/French content never reach the CSV
const dry = process.argv.includes("--dry-run");
const resend = process.argv.includes("--resend");
@@ -47,10 +48,19 @@ const sent = new Set(
: []
);
const dateArg = process.argv.find((a) => a.startsWith("--date="))?.slice(7);
const digestDate = dateArg ?? new Date().toISOString().slice(0, 10);
const fresh = resend
? all.filter((r) => r.fetched === (dateArg ?? new Date().toISOString().slice(0, 10)))
? all.filter((r) => r.fetched === digestDate)
: all.filter((r) => !before.has(r.link));
// Jobs dropped for German/French content never make it into the CSV, so this
// is the only place their count survives — shown as a count-only category,
// never listed, since there's no Row to show for them.
const langDropped = await Bun.file(LANG_DROPPED)
.json()
.then((j) => (j.date === digestDate ? j.count : 0))
.catch(() => 0);
// Only leads that actually match the CV (profile.ts) and haven't been sent before.
const matched = fresh.filter((r) => !sent.has(r.link) && matchesProfile(r.title, r.company).ok);
console.log(`${fresh.length} new · ${matched.length} match profile · ${fresh.length - matched.length} filtered or already sent`);
@@ -95,6 +105,9 @@ for (const k of order) {
lines.push(`• ${escapeHtml(r.title)} — ${escapeHtml(r.company)} ${label}`);
}
}
if (langDropped > 0) {
lines.push(`\n<b>🔴 Ignored (German/French)</b> (${langDropped})`);
}
const msg = lines.join("\n");
if (dry) {