PR #842 — итоговая позиция
PR: https://bitbucket.org/stevens_edu/stevens_main_nextjs/pull-requests/842 Задача: IX-SIT60 — Add schema for youtube Parent / спека: ICUS-211 / ICUS-212 — обновлена 2026-03-12 (Option 2 — Contentful App, по решению Michael Forbes от 2026-03-10) Статус: OPEN (на 2026-04-16, не замержен) Цикл: 31.03.2026 → 16.04.2026 → продолжается = 16+ дней
Owner / зона ответственности — Контentful App (Саша) ↔ Frontend (Иван)
Архитектура задачи (по обновлённой спеке ICUS-211/212 от 2026-03-12):
[YouTube Data API]
↓ (snippet.publishedAt)
[Contentful App] — отдельное React-приложение, работает в Contentful UI
↓ (пишет в youtubeUploadDate field)
[Contentful entry] — Video entry с полем youtubeUploadDate
↓ (Delivery API)
[Next.js фронт] — читает youtubeUploadDate, рендерит <VideoObject> JSON-LD
| Слой | Кто | Что |
|---|---|---|
| Contentful App (отдельное React-приложение в Contentful UI) | Olexandr (Sasha) Fedorenko | Создание App, trigger (Publish vs URL change), поведение поля youtubeUploadDate (disabled для manual editing, App может писать), миграция 700 existing entries, размещение API key в App config, репо для App, pre-merge tasks (deploy App + Contentful merge develop→master) |
| Frontend (этот PR #842) | Иван | Чтение youtubeUploadDate из Contentful через Delivery API; рендер VideoObject JSON-LD; guard "нет uploadDate → не выводить schema"; гигиена коммита; PR description |
| Ревью со стороны Stevens | Michael Forbes (+ Bemin) | Поймал scope-несоответствия как со стороны App, так и frontend |
Это разделение меняет адресатов вопросов. Решения по тому, как работает Contentful App (когда тригерится, что синкается, как мигрируем existing entries) — к Саше. Решения по тому, как фронт обрабатывает данные (guard на пустое поле, формат вывода в schema, debug-код) — к Ивану.
Краткое резюме (с разбиением по ответственному)
| # | Тип | Тема | Обоснованно | Ответственный |
|---|---|---|---|---|
| 1 | Претензия | Debug console.log оставлен в коде | ✓ Да | Иван (frontend гигиена) |
| 2 | Претензия | PR требует pre-merge tasks (deploy Stevens CMS Tools / Contentful App + Contentful merge develop→master), но они не описаны → build сломался у ревьюера | ✓ Да, прямой кейс из письма Alexis | Саша (architectural knowledge: что нужно для deploy App) + Иван (PR description: должен был спросить) |
| 3 | Претензия | Невалидный VideoObject — schema без обязательного uploadDate | ✓ Да | Иван (frontend guard — если поле пустое, не выводить schema). Саша — косвенно: не предупредил, что для existing entries поле может быть пустым |
| 4 | Служебный | Vercel deploy bot | — | — |
| 5 | Снят | Michael сам снял свой вопрос | — | — |
| 6 | Претензия (UX/process) | ~700 Video entries в "Not synced yet" — нет миграционной стратегии | ✓ Да | Саша (Contentful App не предусматривал backfill для existing entries — это scope-решение) |
4 обоснованные претензии:
- 2 чисто на Иване (frontend):
console.log, отсутствие guard на пустойuploadDate. - 1 чисто на Саше (App scope): миграция 700 entries.
- 1 совместная: pre-merge tasks (Саша знает архитектуру, Иван пишет PR-описание).
Этот PR — почти точная иллюстрация письма Alexis
Письмо от 29.04.2026 содержит четыре основные претензии, и минимум три из них именно про этот PR:
| Претензия из письма | Конкретика в PR #842 | Кто отвечает за корневую причину |
|---|---|---|
| "deliverables that deviate considerably from spec and require revisiting" | Schema без uploadDate (Comment #3) → Иван (frontend guard); backfill для 700 entries (Comment #6) → Саша (App scope) | |
| "PRs that require post-deployment tasks are always accompanied by such" | Comment #2 — pre-merge tasks отсутствовали в описании | Саша (architectural knowledge) + Иван (PR description) |
| "internal validation pass prior to sending things over" | Comment #1 (console.log) → Иван; Comment #6 (продуктовый gap про 700) → Саша | |
| "chunk this work into smaller batches, smaller incremental releases to reduce TTM" | PR висит 16+ дней OPEN, охватывает: фронт + Contentful App + поле в Contentful + Stevens CMS Tools + backfill script | Саша + менеджер (декомпозиция scope) |
PR #842 очень вероятно — один из триггеров письма Alexis (одновременно по тематике, времени написания и набору проблем).
Что признаём (объективно), с разбивкой по слою
Frontend (Иван — этот PR):
- Debug-код в PR (
console.log) — гигиена коммита, self-review бы это отловил за 10 секунд. - Нет guard на пустое
youtubeUploadDateв первой версии — фронт выводил<VideoObject>без обязательного поля. Это можно было поймать одной проверкой "если нет даты — не выводить schema". Не пойман до ревью Michael. - PR description без pre-merge tasks на момент открытия — даже если архитектурное знание у Саши, текст PR пишет Иван; должен был дёрнуть Сашу/менеджера и переспросить.
Contentful App (Саша — отдельное приложение):
- Trigger выбран on URL change, хотя спека предпочитала on Publish — это бы автоматически синкало entries при следующем publish и закрывало проблему "Not synced yet" хотя бы частично.
- Не закрыта миграция существующих 700 entries до открытия фронт-PR — Contentful App работает только на новых/обновлённых entries; для 700 уже существующих нужен был отдельный backfill (его не было в scope, в итоге появился по запросу Michael).
- Pre-merge tasks архитектурно не проговорены (deploy App + Contentful field develop→master) — это знание сидит у scope-владельца, должно было быть передано Ивану до открытия PR.
Совместная зона / процесс:
- PR висит ~3 недели OPEN — большой батч работы. Декомпозиция — это менеджмент + scope-владелец, не разработчик в одиночку.
- Не было product-checkpoint перед коммитом: Саша + Иван + менеджер не прошли спеку построчно вместе.
Что в нашу пользу
- Иван оперативно реагирует:
console.logубран в следующем коммите.- Условие на
uploadDateдобавлено за 1 день после комментария Michael. - Backfill script предложен и реализован (правда, по существу это Саша должен был спроектировать заранее, но Иван довёл до коммита).
- Конструктивное обсуждение с Michael — нашли решения для всех замечаний.
- Финальное описание PR хорошее: pre-merge tasks, инструкция по backfill, ссылка на .
Корневые причины
- Не было совместного product-checkpoint перед коммитом: Саша спроектировал scope, Иван реализовал, но не было явного шага "пройти спеку построчно вместе и зафиксировать что в PR, что в pre-merge tasks, что с migration" — отсюда uploadDate-guard и 700 entries вылезли только в ревью.
- Нет self-review checklist на уровне Ивана (debug-код).
- Нет шаблона PR description с обязательными секциями (Pre-merge tasks / Post-deployment / Migration plan) — это бы заставило Ивана/Сашу проговорить вслух, что нужно для deploy.
- Slow review cycle — 16+ дней не из-за ревьюеров, а из-за нескольких раундов "поймали → исправили → нашли следующее". Если бы scope был закрыт до коммита — циклы были бы короче.
Уточнение по спеке (после получения ICUS-211/212)
Спека есть — задачи ICUS-211 и ICUS-212 (одинаковый текст), обновлены 2026-03-12 (Option 2 — Contentful App). PR открыт 2026-03-31 → через 19 дней после обновления спеки, времени на чтение более чем достаточно.
Кто читал спеку: scope-владелец = Саша. Понимал ли Иван спеку перед коммитом — вопрос отдельный (см. discussion-questions).
Что соответствует спеке (по делу):
- ✓ Чтение сохранённого
youtubeUploadDateиз Contentful (без runtime-вызовов YouTube) - ✓ Использование Contentful Delivery API
- ✓ Подход через Contentful App (Option 2)
Что не соответствует:
- ✗ Сначала VideoObject выводился без
uploadDate(Comment #3) — спека прямо требует валидной schema → scope-решение, к Саше - Sync trigger выбран на URL change, хотя спека предпочитала on Publish → отсюда UX-проблема "Not synced yet" → scope-решение, к Саше
Что спека сама не закрывает:
- Поведение для существующих entries (~700) — спека описывает только "при создании/обновлении". Это частично пробел спеки (Stevens не продумал миграцию), а не только реализации.
Поле youtubeUploadDate (требование спеки): должно быть disabled для ручного редактирования в Contentful UI, но App может писать. Реализовано ли так — вопрос к Саше (он проектировал поле и App).
YouTube API key: в Jira в описании задачи ключ упоминался; по проверке в git он в исходники PR #842 и репозиторий Contentful App не попадал — отдельный срочный чеклист снят. Держим ключ только в конфиге App / секретах; если когда-нибудь окажется в коммите — ротировать и при необходимости чистить историю.
Репо Contentful App: по спеке "TBD with client". На встрече — уточнить, в каком репо живёт код App (iX / Stevens / отдельный) — вопрос к Саше.
Действия
- Утечка YouTube API key в репозиторий — не зафиксирована (проверка закрыта).
- Подтянуть PR #842 в встречу как иллюстрацию к письму Alexis. Разделение слоёв (Contentful App / фронт) учитывать при разборе, но все вопросы — общекомандные, на встрече отвечаем все вместе.
- Вопросы по Contentful App (scope-уровень — нужны участие владельца App):
- Почему trigger выбран on URL change, а не on Publish (как предпочитала спека)?
- Реализовано ли
youtubeUploadDateкак disabled для ручного editing (с разрешением App писать)? - Где живёт код Contentful App (репо)?
- Какой план по миграции существующих 700 entries был на момент открытия PR?
- Pre-merge tasks (deploy Stevens CMS Tools + Contentful merge develop→master) — почему не были озвучены до открытия PR?
- Вопросы по фронту PR #842:
- Почему изначально не было guard "не выводить VideoObject если нет uploadDate"?
- Почему
console.logпопал в PR? Используются ли pre-commit hooks / lint правила? - При написании PR description — переспрашивали ли владельца scope / менеджера, что нужно для deploy этого PR (pre-merge tasks)?
- Командный процесс (общие договорённости):
- PR template с обязательными секциями (pre-merge tasks, migration, validation steps).
- Self-review checklist перед "Open PR".
- Product-checkpoint перед коммитом: владелец scope + разработчик проходят acceptance criteria построчно.
- Кто и когда делает internal validation pass.
- К встрече со Stevens — этот PR использовать как признание + конкретный план: PR template + self-review checklist + product checkpoint.
Ключевой вывод
PR #842 — главная иллюстрация претензий Alexis из письма, но ответственность распределена:
- Иван виноват в гигиене (
console.log) и в том, что в PR description не было pre-merge tasks. - Саша виноват в scope-решениях: uploadDate-guard, выбор trigger, миграция 700 entries, отсутствие проговорённых pre-merge tasks.
- Менеджмент виноват в том, что не было product-checkpoint перед коммитом.
На встрече со Stevens — это признание + план, а внутри команды — разговор с правильными людьми про правильные вещи. Не валить всё на Ивана; не делать вид что Саши тут не было.