13 KiB
tubev — Site Migration Playbook
Призначення: robust план для міграції / refactor наступного site (player, banners, sidebar responsive, etc.). Не лінійний — discovery-driven з conditional branches. Кожен пункт може бути SKIP якщо feature відсутня.
Спирається на досвід з 8148 (PlayerJS pilot), 8161 (full migration + R7 responsive sidebar), 8081 (videojs10 + bannersBlocks reference). Доповнення — у ADS.md § Migration checklist.
Modes
- Interactive (default) — Claude робить Discovery, потім confirm scope з юзером перед Phase 2.
- Autonomous batch — юзер дає пакет sites + global instructions; Claude робить sam без апрувів, per-site report + master
~/comms/batch-summary.md. Halt тільки на critical ambiguity. Memory:feedback_autonomous_batch_migration.
Phase 1 — Discovery (ОБОВ'ЯЗКОВО спершу)
Перед будь-якими правками — Claude запитує юзера + інспектує наявний site, фіксує scope. Без цього — risk hidden assumptions.
A) Scope decisions (запитати юзера)
| # | Питання | Why it matters |
|---|---|---|
| A1 | Чи мігруємо player? (videojs4 → PlayerJS / videojs10 / залишаємо?) | Якщо ні — skip Phase 3 player. |
| A2 | Чи замінюємо ad spot IDs? (rotation / new account) — якщо так, дай mapping таблицю. | Якщо ні — skip banner spot rewrite. |
| A3 | Чи треба responsive sidebar→grid swap (R7-style)? | Tільки якщо site має sidebar з ads AND junior-grid (related/recommended thumbs). |
| A4 | Чи зробити уніфікацію критичних inline + index.css? | За замовчуванням так — запобігає FOUC. |
| A5 | Spec for site — щось унікальне (custom player, ASG-bypass, GDPR overlay, etc.)? | Невідомі вимоги дізнаємось ранo, не пізно. |
B) Site inspection (Claude робить empirically)
| # | Check | Tool / Command |
|---|---|---|
| B1 | URL pattern для video page | grep id_index references у layout, парсинг mysettings.location_css == "id" block |
| B2 | Player generation у DOM | curl t1.<domain>/<video-url> → grep videojs|PlayerJS|pjs_container |
| B3 | Native banners серед thumbs (1thumb_a-f чи інший module чи нема) | grep -rn 'native_allpg_1thumb|render.*banners' views/modules/related_video.etlua views/modules/recommended_video.etlua |
| B4 | Sidebar layout (vi-side-col? інший?) | grep -n 'embed_sidebar|vi-side-col|sidebar_adspy' views/id_index.etlua |
| B5 | Cols-change button (для bannersBlocks observer scope) | grep -rn 'changeNumberCols|data-changecolumns' views/ |
| B6 | CSS layers — index.css + критичні views/css/css_<page>.etlua |
ls views/css/css_*.etlua |
| B7 | Shared lib references — views/static/js/lib/ git submodule? |
cd views/static/js/lib && git remote -v |
| B8 | Cooldown regex у layout.etlua (popunder spot ID hardcoded) |
grep 'asgsl|_popRr' layout.etlua |
| B9 | c counter call безпеки (if(typeof c==="function")) |
grep tb.start_events_v2 у id_index.etlua |
| B10 | lazyLoadFunc defined inline |
grep -c 'function lazyLoadFunc' layout.etlua views/static/js/main.min.js |
Output Discovery phase: короткий summary — "Site X: player Y, banners Z (mapping pending), sidebar W, cols-button A/N, etc." → юзер confirms scope перед Phase 2.
Phase 2 — Conditional Task Branches
Кожна гілка SKIP-нулагається якщо Discovery показав feature відсутньою. Кожна = окремий atomic commit.
Branch P (Player migration) — якщо A1=yes
→ повний 30+ checkpoint список у ADS.md § Migration checklist.
- Inline lazysizes wrapper якщо main.min.js його не містить (R3).
if(typeof c==="function")guard (counter race fix).- foreign 8148 classes (
vdo-blk-*) → site-native (vi-limiteretc.) (R5). - Playwright probe → pageerrors empty.
- Cleanup dead videojs CSS —
.video-js,.vjs-*,@keyframes vjs-*,.waiting .loading-spinnerrules видалити зviews/static/css/index.css+views/css/css_<page>.etlua(для video page) AFTER player migrated. Залишити тільки якщо site has окремі pages що ще videojs (embed.etlua, id_xvideos.etlua module — conditional render). Не видалитиviews/static/css/video-js.cssфайл (used by embed iframe).
Branch S (Spot ID rotation) — якщо A2=yes
- Replace IDs у
views/static/js/ad-config.js(popunder.spot, vast.spot). - Replace
(?:^|\|)<id>=regex уlayout.etlua(must sync з ad-config!). - Replace IDs у
views/modules/banners/*adspy*.etlua(footer/header/middle/sidebar/native). - 1thumb_a..f spots якщо site має those modules.
- Per-site inventory таблицю — додати у ADS.md § Per-site spot inventory.
- Build bundle → cache-bust md5.
- ad-test → 6/6 PASS на новий popunder/vast spots.
Branch R7 (Responsive sidebar→grid) — якщо A3=yes
Передумови: site має sidebar (.vi-side-col чи аналог) з ad slots AND grid (#related_video_block чи similar) з thumbs.
- Уніфікувати DOM IDs sidebar slots (mobile + desktop templates обидва використовують ті самі ID —
sdd_a/sdd_b). - Move banner-load logic з template
<script>уid_index.etluainline → один місто, server-sideisMobile()choose spot pair, callback() => bannersBlocks.calc(). - Inject
bannersBlocksJS з activateWidth (1024 default), main block selector (#related_video_block), thumb selector (.video-item:not(.js-iframe_banner)). - Banner wrapper class — match site thumb structure (8161 =
<div class="video-item">, 8081 =<figure>). Inspect 1 existing thumb DOM. - iframe transform scale = thumbW / banner_natural_width (default 300) для banner content fit.
- Wrapper height = scaled height (250 * scale) для row consistency.
- CSS hide empty sidebar:
@media(max-width:<activateWidth>px){.<sidebar-class>{display:none}}у обидва index.css + critical css_.etlua. - MutationObserver:
mainBlock— childList + class/style attrs (lazy-load thumbs)document.body— attributes ['class'] (cols-change button updates body class — без observer banners stale)
- Defer init до DOMContentLoaded якщо script render-иться перед grid block.
- Debounce calc ~150ms на frequent events.
Branch C (Critical CSS sync) — якщо A4=yes (default)
Кожна правка views/static/css/index.css → перевірити чи selector існує у відповідному views/css/css_<page>.etlua → дзеркалити rule. Без цього FOUC. Memory: feedback_critical_inline_css_sync.
Branch X (Site-specific) — якщо A5 показав щось
Custom план залежно від спецификy. Документуй у session notes.
Phase 3 — Universal post-checks (ALWAYS, незалежно від Branch)
Усі ці checkpoints — обов'язкові, незалежно від scope. Вони catch генеричні regressions.
CSS / DOM
index.css+ critical inlinecss_<page>.etluaмають однакові rules для торкнутих selectors.- No duplicate DOM IDs на сторінці (Playwright probe
Array.from(document.querySelectorAll('[id]')).map(e=>e.id)+ count duplicates). - No foreign-site classes (8148
vdo-blk-*etc.) у site-specific files.
JS / errors
- Playwright headless
pageerrorarray empty при load video page (timeout 8s). - No
c is not definedу inlinestart_events_v2(counter race). - No
lazyLoadFunc is not definedу timeline-pjs (якщо використовується). - No
c2.min.js: Unexpected identifier(re-minify якщо source edit). - Console clean: no ASGB loader errors.
Ad pipeline
ad-test "<test_url>"→ 6/6 PASS.- VAST endpoint returns
<Ad>(curl) — не empty<VAST/>no-fill. - Popunder endpoint returns
renderSpotJSON. - CDN serves fresh bundle (
curl t1/static/js/ad-bundle.min.js | grep spot:reflects новий config). - adspyglass dashboard show графік не падає (ручний check 1-2h після deploy).
Responsive (якщо Branch R7 активний)
- Width > activateWidth: banners у sidebar slots, sidebar visible.
- Width <= activateWidth: banners у grid (зайве sidebar hidden), no overlap з thumbs, row heights consistent.
- Resize transition (drag window narrow → wide → narrow): banners move properly, no duplicate, no orphan.
- Cols-change button click: banners recalc + reposition.
- Hard-refresh test (browser cache
max-age=3600): нові правила apply.
Player (якщо Branch P активний)
- Click play → VAST pre-roll shows (after popunder cooldown set on first visit).
- After VAST done → main video starts via
_revealPjs()callback. - Tooltip likes/dislikes над player chrome (z-index battle won).
- Timeline thumb hover → play icon shown.
- iOS Safari:
.no-js/.jsswap robitь native controls hidden.
Diff / commit hygiene
- Atomic commits — 1 commit per logical change (Branch P / S / R7 / C / X = окремий commit).
- Commit messages пояснюють "WHY", не лише "WHAT".
~/git-save-all.sh(якщо є backup_) виконано.- Push до origin (якщо SSH key authorized).
Phase 4 — Production verification
- Юзер натискає button у
https://rss.g--o.info/admin/site/controlдля prod deploy. - 5-10 хв — adspyglass dashboard продовжує показувати impressions.
- Кейс real-юзер test (попросити reload + перевірити likes/timeline/banners visually).
Anti-patterns (не повторювати помилок 8161 migration)
- Скопіювати foreign classes (
vdo-blk-lmtr) тільки тому що 8148 так робить. Site має native equivalent — використовуй його. R5 урок. - Append external JS file (
tb.append_script) коли можна inline. Зайвий HTTP request. R3 урок. - Edit тільки
index.cssбез критичногоcss_<page>.etlua. FOUC на first paint. Юзер скаржиться. Урок 2026-05-04. - Compound bash chains з fail-prone steps (
cd && head wrong-file). Червоні errors дратують юзера. Урок 2026-05-04. - Single-line snippet output форсити. Терминал word-wrap ламає copy → file workflow краще. Урок 2026-05-04.
- Early-return у calc() тільки на widthLine — не зловити thumb width зміну (button cols toggle). Має track обидва. R7 урок.
- observe лише
mainBlockбез body — cols-button updates body class, banners stale. R7 урок. - Брати template з memory без verify — пишемо у memory одразу коли юзер каже "це знадобиться", не після compaction. Урок 2026-05-04.
Cheat-sheet команд
# Discovery
grep -rn 'PATTERN' /home/nosfortube/frontend_<port>/views/
# Test ad pipeline
ad-test "https://t1.<domain>/v/<id>/<slug>"
# Empirical browser probe (write to /tmp first, не до /home/w4/playwright-tests/)
node /tmp/probe-X.mjs
# Build ad bundle (8148-only — інші sites копіювати pipeline)
bash views/static/js/build-ad-bundle.sh
# Snippet delivery до VSCode
cat > /home/nosfortube/orest/snippet.txt << EOF
...
EOF
Memory rules що activate-яться під час migration
feedback_critical_inline_css_sync— CSS dual-layerfeedback_clean_bash_no_red— Read tool > head/catfeedback_use_bots_proactively— gocc1/gocc2 для audit/research parallelfeedback_pre_push_subagent— code-reviewer на diff перед pushfeedback_clipboard_snippet_workflow— snippet → filereference_native_banner_templates— ASG ExoClick / TrafficStars wrappersreference_ad_regression_tool— ad-test usageproject_player_roadmap— generation map sites