-- 160_seed_deactivate_stale_domklik_n1.sql
-- Issue #2204 — seed scrape_schedules rows for nightly stale-listing deactivation
-- of domklik and n1 (wildcard deactivate_stale_* family, #759 generalisation).
--
-- Context (verified on prod 2026-07-02):
--   n1:      381 is_active rows; last_seen_at frozen at 2026-06-16; no scraper runs
--            anymore -> source is DEAD. Nothing keeps these rows fresh, yet they
--            inflate the active-listing denominator used by coverage/estimator.
--   domklik: 6296 is_active rows; scraped_at frozen at 2026-06-28, BUT last_seen_at
--            is advanced every day by an UNtracked bulk UPDATE (all rows share one
--            timestamp) -> a TTL over last_seen_at can NEVER fire for domklik.
--            Honest freshness for domklik = scraped_at, which only moves when a real
--            scrape actually re-sees the listing.
--
--   Fix:
--     1. app/tasks/deactivate_stale_avito.py — deactivate_stale_listings() gains a
--        staleness_column kwarg (whitelist {last_seen_at, scraped_at}); the WHERE
--        clause compares the chosen column against NOW() - ttl_days.
--     2. app/services/product_handlers.py + app/services/scheduler.py — both
--        deactivate_stale_* dispatch paths read staleness_column from default_params
--        (default 'last_seen_at').
--     3. This migration — seeds the two scrape_schedules rows below.
--
-- Why staleness_column='scraped_at' for domklik (NOT last_seen_at):
--   The daily bulk-touch advances last_seen_at for every domklik row to the same
--   instant, so `last_seen_at < NOW() - INTERVAL '14 days'` matches 0 rows forever —
--   the TTL is useless. scraped_at moves ONLY on a genuine scrape, so it reflects
--   true visibility. TTL=14 mirrors the estimator's LISTINGS_FRESH_DAYS: a listing
--   invisible to valuations for >14 days should also be deactivated, keeping the
--   active set synchronous with what the estimator actually consumes.
--
-- Why domklik is blanket (no "segments" key), unlike yandex/cian (#115 vtorichka-only):
--   verified on prod 2026-07-02 — ALL 6296 domklik rows are listing_segment='vtorichka';
--   the BFF sweep ingests secondary only, so there are no novostroyki to protect.
--
-- Why n1 uses the default last_seen_at (staleness_column omitted):
--   n1 is dead — last_seen_at is frozen at 2026-06-16, so the default column already
--   crosses the TTL threshold. The very first run will deactivate the stale inventory.
--   TTL=14 days keeps it conservative and consistent with domklik.
--
-- Schedule window 07:00-08:00 UTC:
--   After the avito deactivate_stale window (06:00-07:00 UTC) and after the main city
--   sweeps (02:00-05:00 UTC), same slot as the yandex/cian deactivate rows (#115).
--   Running after the sweeps ensures listings genuinely re-seen are NOT deactivated.
--
-- next_run_at bootstrapped to tomorrow 07:00 UTC so the scheduler does not fire
-- immediately on deploy (same pattern as 090/115).
--
-- Idempotent: ON CONFLICT (source) DO NOTHING — safe to re-apply.
--
-- Dependencies:
--   052_scrape_schedules.sql (table + UNIQUE(source)).
--   listings table with last_seen_at + scraped_at columns.
--   app/tasks/deactivate_stale_avito.py — deactivate_stale_listings() (staleness_column).
--   app/services/scheduler.py + product_handlers.py — deactivate_stale_* dispatch that
--     forwards staleness_column from default_params.
--
-- Deploy order:
--   Apply after deploying the scheduler.py + product_handlers.py + task changes so the
--   dispatch can forward staleness_column correctly on the first fire.

BEGIN;

INSERT INTO scrape_schedules (
    source,
    enabled,
    window_start_hour,
    window_end_hour,
    next_run_at,
    default_params
)
VALUES
(
    'deactivate_stale_domklik',
    true,                                        -- SAFE: pure internal DB UPDATE, no ext calls
    7,
    8,
    ((CURRENT_DATE + INTERVAL '1 day') + make_interval(hours => 7)) AT TIME ZONE 'UTC',
    -- staleness_column=scraped_at: last_seen_at bulk-touched daily -> useless TTL.
    '{"listing_source":"domklik","ttl_days":14,"staleness_column":"scraped_at"}'::jsonb
),
(
    'deactivate_stale_n1',
    true,                                        -- SAFE: pure internal DB UPDATE, no ext calls
    7,
    8,
    ((CURRENT_DATE + INTERVAL '1 day') + make_interval(hours => 7)) AT TIME ZONE 'UTC',
    -- n1 dead (last_seen_at frozen 2026-06-16); default last_seen_at column fires first run.
    '{"listing_source":"n1","ttl_days":14}'::jsonb
)
ON CONFLICT (source) DO NOTHING;

COMMIT;
