Repository navigation
Replies: 1 comment
|
Answered on the PR, @vnk8071, and the same answer holds here: under rule 1 of the Source Indexing Policy an aggregator that republishes other boards' postings isn't a source career-ops indexes, so #3520 is closed on that rule and not on the code. Boards that publish their own employer-attributed postings behind a public API go straight in, as your ITviec and CareerViet providers did. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
What goodjobs is
goodjobs is a self-hosted, open-source job-search aggregator (a sibling project of mine) that scrapes 18 boards behind one FastAPI backend — LinkedIn, ITViec, TopCV, VietnamWorks, CareerViet, TopDev, JobsGo, CareerLink, Glints, ViecOi, Indeed VN, plus a global US/UK/SG set. One search box, real-time SSE streaming, a Redis cache warmed every 2 hours, AI intent detection, skill extraction, and a vector-embedding "related jobs" supplement.
It's a genuinely different shape of source from anything currently in
providers/: every existing provider either scrapes one board directly (itviec.mjs,careerviet.mjs) or hits one ATS's public API (greenhouse.mjs,ashby.mjs). goodjobs is neither — it's a pre-aggregated multi-board feed that a user (or the community) self-hosts.What's already shipped
#3520 adds
providers/goodjobs.mjsas a thin client: it POSTs to goodjobs' own publicPOST /scrapeendpoint and normalizes the JSON array into career-ops'Jobshape. Explicit opt-in only (provider: goodjobsinportals.yml) — no auto-detection, since there's no fixed host or URL pattern to key off for a self-hosted service.Two things worth calling out from actually running it end-to-end against the live instance rather than just reading the API docs:
goodjobs.io.vnis a static GitHub Pages frontend; the actual backend lives onapi.goodjobs.io.vn. Caught this before merging by reading the frontend's built JS bundle for its baked-inVITE_API_URL./scrapecall — root cause was a Pydantic model rejecting aNonesentinel that 8 of the scrapers legitimately write (summary_description: null= "not yet summarized"). Fixed upstream (vnk8071/goodjobs@0748103) the same day, verified live, and it's now a resolved historical note in the provider's own header comment rather than an open caveat.Ran it for real afterward:
node scan.mjs --company goodjobsagainst "AI Engineer" / Ho Chi Minh City pulled 57 postings, 45 of them new after title-filter and dedup.Where I'd like input
/scrapeendpoint. goodjobs also exposes/recent-jobs(a cached, pre-filtered VN-facing view) and/search-semantic(vector search over the cache). Is a second, cheaper provider variant worth it for users who want a fast/cached read instead of a live multi-board sweep, or is that scope creep for a scan provider whose whole job is "return jobs for this keyword/location"?https://api.goodjobs.io.vn), but the more interesting long-term case is someone running their own goodjobs instance and pointingportals.yml'sapi:field at it. Is there appetite for a short "run your own aggregator" doc pairing career-ops with goodjobs (or a similar self-hosted aggregator), given career-ops' SSRF guard means only a publicly routable instance works — a localdocker compose upwon't do?providers/. If there's interest in more of this shape (as opposed to single-board scrapers or single-ATS clients), worth thinking about whether the contract needs anything generalized, or whethergoodjobs.mjs's thin-client pattern is already the right template for the next one.Happy to hear if this is useful to anyone outside VN-market job searches too — the global US/UK/SG side of goodjobs is there and untouched by this PR.
All reactions