-- 103_scrape_schedules_seed_newbuilding_enrich.sql
-- Issue #973 (GG-форсайт, 950-E2) — seed scrape_schedules row for the nightly
-- newbuilding-enrichment backfill.
--
-- Context:
--   The three newbuilding-enrichment tables (houses_price_dynamics,
--   house_reliability_checks, house_reviews) are populated only INLINE during the cian
--   full-sweep — there was never a standalone schedule for them. On prod 306 houses are
--   linked to ext_source='cian_newbuilding' (all fetchable) but only ~18 have price
--   dynamics, ~3 have reliability, 0 have reviews. This schedule drains that backlog
--   nightly, one bounded slice at a time.
--
--   Components deployed together (same release as this migration):
--     1. tasks/newbuilding_enrich_backfill.py — run_newbuilding_enrich() scheduler wrapper
--        (heartbeat → backfill_newbuilding_enrichment → mark_done/mark_failed). The
--        backfill itself (backfill_newbuilding_enrichment) shipped with #972.
--     2. scheduler.py — trigger_newbuilding_enrich_run() + dispatch branch
--        `elif source == "newbuilding_enrich"` in scheduler_loop().
--     3. This migration — seeds the scrape_schedules row.
--
-- Idempotency (inherited from backfill_newbuilding_enrichment, #972):
--   With force=False the backfill's SELECT excludes houses that already have BOTH
--   price_dynamics AND reliability rows, and each house is processed under a SAVEPOINT,
--   so a re-fire never re-enriches a done house nor double-appends on a partial run.
--   default_params.limit bounds how many houses one fire fetches (anti-bot politeness);
--   the nightly cadence drains the remaining backlog over successive nights.
--
-- Schedule window 00:00-01:00 UTC (= 03:00-04:00 МСК):
--   Deep-night МСК slot, placed BEFORE the 01:00+ UTC sweep block (listing_source_snapshot
--   01:00-02:00, avito/cian/yandex sweeps 02:00-05:00 UTC) so the Cian HTTP fetches of this
--   task do not overlap the daytime/early-morning SERP-sweeps and compete for the Cian
--   anti-bot budget. Per-house polite delay = get_scraper_delay('cian') (~5s) with ±20%
--   jitter; at limit=25 a fire is ~2-3 min of fetches.
--
-- enabled = FALSE (seeded dormant, deliberately). As of 2026-06-13 every external-HTTP
--   scrape source on prod is enabled=false (scraping paused on purpose) except
--   deactivate_stale_avito (pure-internal). Seeding this dormant preserves that posture —
--   the schedule + trigger code ship ready, but do NOT begin fetching Cian until scraping is
--   resumed deliberately (avoids a lone external-HTTP source firing while the rest are paused).
--   TO ACTIVATE when scraping resumes:
--     UPDATE scrape_schedules SET enabled=true WHERE source='newbuilding_enrich';
--   (ON CONFLICT DO NOTHING below will NOT change an already-existing row's enabled flag.)
--
-- next_run_at bootstrapped to tomorrow 00:00 UTC — the scheduler will not fire immediately
--   on deploy (same pattern as 078/079/082/088/091/093/096).
--
-- Idempotent: ON CONFLICT (source) DO NOTHING — safe to re-apply.
--
-- Dependencies:
--   052_scrape_schedules.sql (table + UNIQUE(source))
--   scheduler.py change (trigger_newbuilding_enrich_run must be deployed)
--   tasks/newbuilding_enrich_backfill.py run_newbuilding_enrich() must be deployed (#973),
--     which delegates to backfill_newbuilding_enrichment() shipped with #972.
--
-- Deploy order:
--   Apply after deploying the scheduler.py + task changes so the scheduler can dispatch
--   'newbuilding_enrich' correctly on first fire.

BEGIN;

INSERT INTO scrape_schedules (
    source,
    enabled,
    window_start_hour,
    window_end_hour,
    next_run_at,
    default_params
)
VALUES
(
    'newbuilding_enrich',
    false,                                       -- DORMANT: prod scraping paused — flip true to activate (see note above)
    0,                                           -- window 00:00-01:00 UTC = 03:00-04:00 МСК
    1,
    ((CURRENT_DATE + INTERVAL '1 day') + make_interval(hours => 0)) AT TIME ZONE 'UTC',
    '{"limit": 25, "force": false}'::jsonb       -- bounded per-fire slice; request_delay_sec omitted → get_scraper_delay('cian')
)
ON CONFLICT (source) DO NOTHING;

COMMENT ON TABLE scrape_schedules IS
    'In-app scheduler config (заменяет cron-script setup). '
    'Sources: avito_city_sweep, yandex_city_sweep (dormant, #561), '
    'cian_history_backfill, rosreestr_dkp_import, listing_source_snapshot (#570), '
    'asking_to_sold_ratio_refresh (#648), refresh_search_matview (#769), '
    'yandex_address_backfill (#855, EKB pilot), '
    'sber_index_pull (#887, monthly СберИндекс city-level price index), '
    'rosreestr_quarter_poll (#888, monthly Rosreestr new-quarter availability check), '
    'newbuilding_enrich (#973, nightly cian_newbuilding enrichment backfill slice).';

COMMIT;
