Two scrapers, one schema
Naukri and Turing have nothing in common — different DOM, different anti-bot posture, different listing shapes. A naive scraper produces two parallel datasets that never merge.
A browser MV3 extension hosts per-portal adapters. Each adapter normalizes into the same sankalp_applications row shape: company, role, comp_range, location, source_url, raw_html, captured_at.
Claude-in-Browser handles the high-friction listings (LinkedIn-style obfuscation) via Act capability dispatched from the panel. Same row shape lands in the same table.
Per-portal back-off + page-of-30 cursor + jittered click cadence keep the autopilot quiet enough that the operator account is never flagged.
-- shared schema for every source
create table sankalp_applications (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users not null,
source text not null check (source in
('naukri','turing','claude_in_chrome','manual')),
company text not null,
role text not null,
raw_html text,
match_score int,
status text default 'captured'
);
create index on sankalp_applications (user_id, captured_at desc);