RU | EN
📜

Change log

🛠 Release history

What we changed in the parser, classification, design, and infrastructure, and when. Newest entries at the top.

📡 Telegram-network of 12 city channels launched

We rolled out 12 city Telegram channels — Moscow, Saint Petersburg, Dubai, Tbilisi, Almaty, Yerevan, Minsk, Limassol, Belgrade, Istanbul, Tashkent and Berlin. Every new job is now routed to the channel that matches its geography automatically (Observer + Event + Listener). Each post carries an inline «📝 Apply for the job» button with UTM-tracking utm_source=tg&utm_medium=channel, so we can see in analytics which channel actually drives clicks.

🌐 11 new job-board parsers connected

The catalog now pulls jobs from eleven additional sources: Habr Career, RemoteOK, We Work Remotely, Jobicy, Himalayas, Remotive, plus four major ATS platforms (Greenhouse, Lever, Ashby, Workable) and a dedicated Russian-corporate scraper (Ru-Corporate). On top of that we hooked up a Telegram-side parser that watches 30 Russian-speaking job channels (gjobs, hrcpa, partnerkin_jobs and friends) — an AI classifier reads every message and decides «is this a job posting or not».

🎯 Niche filter: 8075 off-topic jobs removed

The new affiliate-niche filter went through the ATS scrapers and removed 8075 vacancies that have nothing to do with our audience — Anthropic engineers, Stripe lawyers and the like. Out of more than 8400 jobs the catalog kept the 1662 that actually matter to affiliates. We also extended the Russian whitelist with 40+ patterns (таргетолог, СММ-щик, сеошник, директолог, веб-мастер, лидгенщик and so on). For the Telegram source we use a softer filter — only a blacklist, so dedicated channels are not cut off.

🤖 LLM normalization + RU↔EN translation in one pass

Job descriptions are now broken into a clean structure — tasks, stack, requirements, conditions, application process — and at the same time translated to the second language. One call to openai/gpt-5.4-mini handles both. The job card renders the structured version with icons (📋 tasks, 🛠 stack, ✅ requirements, 🎁 conditions, 📞 process) and switches language based on locale. New jobs get processed automatically right after the Telegram post (10-second delay), and a cron runs every 15 minutes to catch the rest.

🖼 Per-job OG image — every job gets a unique preview

Every job page now generates its own 1200×630 OG-image — Inter Display Black font, a city accent color, the title and the company. When a job is shared in Telegram, Twitter or WhatsApp it gets a distinct preview instead of the generic site cover. The same fix landed on taxonomy pages (/jobs/role/*, /jobs/vertical/*, /jobs/format/*) — they used to share without OG-tags at all.

🏢 NDA employers: 559 jobs got a proper fallback

A big share of jobs come from recruiters who keep the employer under NDA — 559 out of 1193 had no company_norm. They no longer look broken: the card shows «🏢 NDA employer» plus a «🔍 Through a recruiter» badge, and the JSON-LD reports hiringOrganization = EmploymentAgency. Google for Jobs accepts it without warnings.

🔗 Share button + smart apply label

Every job card now has a «Share» button — three options: Telegram, WhatsApp, or just copy the link. The apply button no longer says a flat «Apply» — it reads the destination URL and shows a contextual label: «Write on Telegram», «Apply on hh.ru», «Go to Habr Career», «Open at partnerkin», «Send an email». Smaller thing — for 549 jobs we stripped the source prefixes «Salary »/«Location ».

🛠 Admin dashboard for the Telegram job-network

A new section appeared in the admin panel — /admin/careers/tg-network — with four screens: a dashboard, the list of channels, the publishing queue and the log of published posts. Each of the 12 channels has its own edit page. The «💼 Job-network» item in the side navigation is now highlighted when you are inside it.

🧹 Small fixes: duplicate descriptions, sources counter, footer

Sixteen jobs had the same description duplicated twice in description_clean — fixed. The «sources» counter on the card used to always show 0 for non-Telegram entries because it wasn't reading the source_count column — now it does. The geo and profession taggers ran over 1193 jobs and filled in the missing gtag / ptag. We also removed the «🌐 Ecosystem» block from the footer — we are no longer cross-linking the five domains to each other.

🔌 Partnerkin: one more job source

We connected scraping for partnerkin.com — that gives roughly 10–50 new jobs per day across nine categories (affiliate, management, account farming, SEO, sales, design and others). They will be collected automatically every six hours and added to our common catalog.

🌙 Monitoring is quieter at night

Before, the system could send a false «parser is down» alert at four in the morning, simply because nobody was publishing in the channels. Now alerts are not sent during Moscow night hours (from 23:00 to 08:00), and the sensitivity threshold is higher — it only wakes us up on a real breakage.

🔬 Microsoft Clarity: heatmaps and session recordings

We connected Microsoft Clarity for behavior analysis. We can now see how users click, scroll and where they «get stuck» on pages. That helps us improve navigation and copy based on live data instead of guesses.

💰 Salaries: quality upgrade

We ran every job through AI-driven salary normalization. Garbage values used to leak in — like «10 USD/month» — because the text said «payout on the 10th». Such cases are now recognized as «salary not specified», while real ranges (like $1500–3000) are written cleanly. The Google for Jobs salary filter sees us again.

🧹 Duplicate jobs: collapsed 89 groups

Previously the same job could appear 2–9 times — reposted across different channels with different HR contacts. We fixed the merging logic: we now compare by the content itself rather than by contacts. 89 duplicate groups were removed from the database (174 rows merged into 85 master records).

⚡ Bing and IndexNow: faster indexing

We connected Bing Webmaster Tools and the IndexNow API. Every new job is now automatically pinged to Bing, Yandex, Naver and Seznam — indexing dropped from days to hours.

📈 Major SEO campaign: 9 areas at once

  • Expanded the glossary from 31 to 63 industry terms.
  • The /about and /methodology pages were rewritten in plain language, with real examples.
  • Comparison pages now show full tables with figures from our database.
  • Every role and vertical got a 200–400 word description and a FAQ block.
  • Every job now has a markdown version at /job/{slug}.md — built for AI assistants.

🛠 JSON-LD: critical fix

Found and fixed a structured-data bug across the entire site — Google had not seen our jobs in Google for Jobs for a month because of a template-level conflict. After the fix all 600+ jobs are back with correct markup.

🆕 New job sources

Launched scrapers for cpa.live (still in development — needs a proxy) and partnerkin.com (test run succeeded, went live on May 12).

🔒 Domain isolation and UX upgrades

  • Fixed /reports and /companies — previously a middleware was 301-redirecting them to the parent domain, which leaked the relationship between sites and killed SEO. Added a carve-out for the catalog — we now have our own Report/CompanyController.
  • Expired jobs now open with a red «Job closed» banner, meta robots noindex,follow and a link to similar active jobs. Previously they returned 404 — backlinks and sitemap signals were being lost.
  • Added Vary: Accept-Encoding, Host to Cache-Control, so the CDN does not serve the parent domain's HTML on a catalog request and vice versa.
  • Mega-menu: removed the 6px gap between the trigger and the panel — the cursor used to «lose» the menu while moving down. An invisible padding-top bridge now catches the hover.
  • Homepage: top jobs moved from cards to a table (Vacancy / Company / Salary / Format / Tags / Date) — more compact, more jobs visible on one screen.
  • Homepage: «Verticals / Roles / Employers» — was 3 blocks in a row, now one section with tabs. Saves about two-thirds of the page height.
  • 💼 logo in the header with an amber drop shadow.
  • OG image 1200×630 (PNG 107 KB) for social networks.

🚀 Performance — 100 / 100 mobile

  • Lighthouse mobile Performance: was 83–97, now 99–100 / 100 on every key page.
  • LCP (Largest Contentful Paint — main-content render speed): was 4.3 seconds on /jobs and /market-pulse, now 1.5–1.7 seconds.
  • Lazy-loaded analytics trackers: 236 KB of Google Analytics and Yandex.Metrika JS no longer blocks the first load — it loads on the first user interaction (or after 6.5 seconds as a fallback for search bots).
  • SEO 100 / 100 on every page. CLS (layout shift) = 0. TBT (main-thread blocking) = 0 ms.

📚 Glossary and jargon dictionary

  • New page /jobs/glossary — 31 industry-jargon terms: CPA, CPL, RevShare, FTD, ROI, account farmer, media buyer, accounts, ZRD, BM, traffic combo, caps, GEO, vertical and more.
  • DefinedTermSet schema for Google Rich Results — the glossary is now visible in enhanced search results.
  • Account farmer role — a separate jobs cluster (65 positions). Backfilled via regex (farm / warm-up / ZRD / multi-account / account farming / warming up).
  • AI overview via Claude Sonnet: 96% of active jobs received tags for vertical, role and seniority (junior / middle / senior).

🚀 Relaunch on new infrastructure

  • Migrated the backend to Laravel 11 (from custom PHP). A single technology stack across the whole ecosystem.
  • 3,355 jobs were ported over without losing history or links to sources.
  • New visual identity — amber accent (#f59e0b), the shared ecosystem design system.
  • The Telegram parser moved to our pool of 15 accounts (Telethon library, Python).
  • AI moderation switched from OpenAI gpt-4o-mini to Claude Sonnet — better classification quality at controlled cost.

📊 AI moderation and analytics

  • Auto-publishing of confident cases and auto-rejection of fraudulent jobs via the LLM.
  • Daily-rollup analytics: jobs with salary, format, vertical, top roles.
  • Quality score per job (description completeness, presence of a company, contacts, location).

🔍 Structured data and SEO

  • JSON-LD JobPosting for every job — the catalog is ready for Google Jobs.
  • Yandex Vacancy Feed (XML) for Yandex.Rabota.
  • Sitemap with 887 active jobs and 500 company cards.
  • llms.txt for AI crawlers.