docs: cover the two new sources and the concurrent fetch pipeline
This commit is contained in:
@@ -17,7 +17,7 @@ bun daily # fetch, then Telegram the new jobs that match the profile
|
|||||||
bun recheck # show what the filters are currently dropping + keyword suggestions
|
bun recheck # show what the filters are currently dropping + keyword suggestions
|
||||||
```
|
```
|
||||||
|
|
||||||
`bun fetch` needs no setup — reruns are safe, already-seen jobs are skipped by ID. Telegram needs the two-line setup below.
|
`bun fetch` needs no setup — reruns are safe, already-seen jobs are skipped by ID, and every search/source runs concurrently (a full run is well under 2 minutes). Telegram needs the two-line setup below.
|
||||||
|
|
||||||
## Telegram setup
|
## Telegram setup
|
||||||
|
|
||||||
@@ -39,7 +39,8 @@ Then `bun daily --dry-run` prints the digest instead of sending it, and `bun dai
|
|||||||
config.ts # keyword families, search areas, the sweep() generator
|
config.ts # keyword families, search areas, the sweep() generator
|
||||||
fetch.ts # LinkedIn scraper, HTML parser, all title/content filters
|
fetch.ts # LinkedIn scraper, HTML parser, all title/content filters
|
||||||
fetch-other.ts # extra sources: itjobs.ch, job-room.ch, stellen-basel.ch,
|
fetch-other.ts # extra sources: itjobs.ch, job-room.ch, stellen-basel.ch,
|
||||||
# datacareer.ch (403, currently dead), Basel intl orgs
|
# jobbasel.ch, englishjobsearch.ch, Basel intl orgs,
|
||||||
|
# datacareer.ch (403, currently dead)
|
||||||
index.ts # orchestrator: run searches → dedupe → content-check → CSV
|
index.ts # orchestrator: run searches → dedupe → content-check → CSV
|
||||||
recheck.ts # raw-mode fetch: lists what the filters dropped
|
recheck.ts # raw-mode fetch: lists what the filters dropped
|
||||||
daily.ts # digest: fetch, match against the profile, send to Telegram
|
daily.ts # digest: fetch, match against the profile, send to Telegram
|
||||||
@@ -65,7 +66,7 @@ Two stages. Cheap title filters first, then one page fetch per survivor.
|
|||||||
6. `SOFTWARE_TITLE_RE` — requires a real tech/role term. Skipped in `raw` mode, which is what `bun recheck` uses.
|
6. `SOFTWARE_TITLE_RE` — requires a real tech/role term. Skipped in `raw` mode, which is what `bun recheck` uses.
|
||||||
7. `GERMAN_TITLE_RE` — "(German-speaking)", "deutschsprachig".
|
7. `GERMAN_TITLE_RE` — "(German-speaking)", "deutschsprachig".
|
||||||
|
|
||||||
**Content check** (`index.ts` only, one fetch + 350 ms per job): `isViableContent` counts German/French indicator words and drops at ≥ 6, then `requiresGerman()` drops English postings demanding German above B1.
|
**Content check**: `isViableContent`/`isViableUrl` (LinkedIn, one page fetch + 350 ms per job in `index.ts`) and `isViableDescription` (`fetch-other.ts` sources that already carry the description inline, no extra fetch) all run the same two checks — DE/FR indicator words dropped at ≥ 6, then `requiresGerman()` drops English postings demanding German above B1.
|
||||||
|
|
||||||
That last one is deliberately more than a keyword match. For each mention of German it takes the *nearest* qualifying marker, and ignores a marker when another language name sits between it and the mention — both rules came from real false results, like *"Fluent in English; German and/or French advantageous"*, where "Fluent" sits closer to "German" than "advantageous" does but qualifies English.
|
That last one is deliberately more than a keyword match. For each mention of German it takes the *nearest* qualifying marker, and ignores a marker when another language name sits between it and the mention — both rules came from real false results, like *"Fluent in English; German and/or French advantageous"*, where "Fluent" sits closer to "German" than "advantageous" does but qualifies English.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user