fix: catch job-room.ch's structured German-fluency requirement
languageSkills[] (e.g. {languageIsoCode: "de", spokenLevel: "PROFICIENT"})
sits outside jobDescriptions[].description, so requiresGerman()/
isViableDescription() never saw it — the UI renders this as
"Deutsch (Fliessend)", which is exactly what kept reaching Telegram.
Measured: 69 of 1843 ads required PROFICIENT German, prose check caught
only 3.
This commit is contained in:
@@ -236,9 +236,28 @@ interface JobRoomAd {
|
||||
jobDescriptions?: Array<{ title: string; description?: string }>;
|
||||
company?: { name?: string; city?: string };
|
||||
location?: { city?: string; cantonCode?: string };
|
||||
languageSkills?: JobRoomLanguageSkill[];
|
||||
};
|
||||
}
|
||||
|
||||
interface JobRoomLanguageSkill {
|
||||
languageIsoCode?: string;
|
||||
spokenLevel?: string;
|
||||
writtenLevel?: string;
|
||||
}
|
||||
|
||||
// job-room's language requirement is a structured field, not prose — it never
|
||||
// touches jobDescriptions[].description, so isViableDescription()/requiresGerman()
|
||||
// can't see it. The UI renders it as e.g. "Deutsch (Fliessend)"; PROFICIENT is
|
||||
// that "Fliessend" (fluent/C1+) tier, well above Rafael's German B1. BASIC and
|
||||
// INTERMEDIATE stay in scope.
|
||||
function jobRoomRequiresGerman(skills?: JobRoomLanguageSkill[]): boolean {
|
||||
if (!skills) return false;
|
||||
return skills.some(
|
||||
(s) => s.languageIsoCode === "de" && (s.spokenLevel === "PROFICIENT" || s.writtenLevel === "PROFICIENT")
|
||||
);
|
||||
}
|
||||
|
||||
// jobs.ch links arrive with a tracking query string that would break dedup
|
||||
// across runs if it ever changes; the path alone identifies the posting.
|
||||
function stripTracking(url: string): string {
|
||||
@@ -299,6 +318,10 @@ export async function fetchJobRoom(): Promise<Job[]> {
|
||||
if (MS_STACK_RE.test(title)) continue;
|
||||
if (PHARMA_ROLE_RE.test(title)) continue;
|
||||
|
||||
// Structured language requirement — separate from the free-text description
|
||||
// entirely, so it must be checked even when the description reads clean.
|
||||
if (jobRoomRequiresGerman(content?.languageSkills)) { langDropped++; continue; }
|
||||
|
||||
// A handful of ads ship without a description. isViableDescription passes
|
||||
// those through by design, so leave contentChecked unset and let index.ts
|
||||
// fall back to fetching the page.
|
||||
|
||||
Reference in New Issue
Block a user