Skip to content

Latest commit

 

History

History
437 lines (333 loc) · 46.5 KB

File metadata and controls

437 lines (333 loc) · 46.5 KB

BACKLOG.md — план работ

Источник правды для текущей итерации. Каждый этап — отдельный коммит/проход. Прогресс отмечается через [ ][x].

Создан: 2026-05-16. Стратегия — минимум правок в существующих файлах; всё новое — отдельными файлами, чтобы экономить токены.


Что просил пользователь

  1. Страница: стоимость стандартной продуктовой корзины по городам.
  2. Карточка-страница по болезням с влиянием климата (доказательная медицина, ссылки на исследования).
  3. Азиатский блок: Вьетнам, Тайланд, Малайзия, Китай — ключевые города.
  4. Валюта: основная — USD, рядом мелким — RUB.
  5. Актуальный курс на 2026-05-16.
  6. В карточке города — визовая доступность для граждан РФ.
  7. Этот файл-бэклог + поэтапное выполнение, не задевая другие страницы.

Принципы

  • Не редактировать src/modules/{atlas,decision,finance,roadmap,wellbeing,qna}.jsx. Изменения только в новых файлах.
  • Минимальные правки допустимы только в:
    • index.html — подключение новых <script>.
    • src/components/app.jsx — добавление 2 пунктов навигации и 2 ключей в Page (3–4 строки суммарно).
    • FILES.md — освежить индекс.
  • Существующий src/data/index.js не редактируется — все недостающие поля у текущих 11 локаций добавляются через Object.assign в новом src/data/extras.js. Это критично: один большой Edit на 11 объектов сожжёт огромный бюджет токенов.

Ограничения (что знаю и чего не знаю)

  • Курс RUB/USD на 2026-05-16 — точное значение мне неизвестно (knowledge cutoff Anthropic — январь 2026). Поставлю аккуратную заглушку ~95 ₽/$ с явной пометкой asOf: '2026-05-16', source: 'placeholder'. Пункт «актуализировать курс» оставлен на ручную проверку.
  • Визовый статус Азии для РФ на середину 2026 — на моём срезе данных режимы были такие: Тайланд безвиз 60 дней (с июля 2024), Вьетнам e-visa 90 дней / безвиз туристам с пакетом 15 дней, Малайзия безвиз 30 дней, Китай — Хайнань безвиз 30 дней (15-day mainland transit). Данные могут устареть, отметку asOf: '2026-01' ставлю в каждом объекте visaRu.
  • Цены корзины — Numbeo-данные в USD, медиана для города. Пометка source: 'Numbeo актуальная корзина'.
  • Ссылки на медицинские исследования — даю реальные авторы/журнал/год; ссылки веду на PubMed-search по DOI/PMID. Где не уверен в точности PMID — даю URL поиска по NCBI вместо прямой ссылки. Подпись «верифицировать» в BACKLOG.md.

Этапы

Этап 1 — данные ✅

  • 1.1 Создать BACKLOG.md (этот файл).
  • 1.2 Создать src/data/extras.js:
    • window.FX = { usdRub, asOf, source }.
    • window.BASKET_ITEMS — список из 10 позиций (молоко, хлеб, яйца, рис, курица, яблоки, картофель, помидоры, лук, масло).
    • window.LOCATION_EXTRAS[id] для всех 15 локаций: { visaRu, basketUSD }.
    • 4 азиатские локации (Дананг VN, Чиангмай TH, Пенанг MY, Санья CN) — пушатся в window.LOCATIONS с полным набором полей.
    • В конце: Object.assign существующих локаций с LOCATION_EXTRAS.
  • 1.3 Создать src/data/conditions.js:
    • window.CONDITIONS — массив болезней (атопический дерматит, СРК-СИБР, риносинусит, экзема рук, мигрень от давления, sun-sensitivity). Каждая запись: { id, name, who, climateFactors[], evidence[] }. evidence — массив { title, authors, journal, year, link }.

Этап 2 — страницы ✅

  • 2.1 Создать src/modules/basket.jsx (window.Basket):
    • Таблица «город × позиция корзины», итог по городу.
    • USD крупно, RUB мелким (fmtMoneyDual локально внутри файла).
    • Сортировка по итогу, индикатор «дешевле/дороже медианы».
  • 2.2 Создать src/modules/conditions.jsx (window.Conditions):
    • Список карточек болезней; внутри — рейтинг локаций по совместимости (использует существующий LOCATIONS + CONDITIONS.climateFactors).
    • Список источников снизу карточки.

Этап 3 — интеграция ✅

  • 3.1 index.html: подключить src/data/extras.js, src/data/conditions.js, src/modules/basket.jsx, src/modules/conditions.jsx + src/styles/extras.css (5 строк).
  • 3.2 src/components/app.jsx: добавить в nav 2 пункта (07 Продуктовая корзина, 08 Болезни и климат) и в Page 2 ключа (basket: Basket, conditions: Conditions).
  • 3.3 Обновить FILES.md (раздел src/data/, src/modules/, типовые задачи).

Этап 4 — верификация (ручная)

  • 4.1 Открыть index.html локально, проверить:
    • Главная грузится без ошибок в консоли.
    • Пункты 07 и 08 появились в сайдбаре.
    • Старые страницы (атлас, сравнение, финансы, план, опора, Q&A) работают.
  • 4.2 Открыть Продуктовая корзина — увидеть таблицу с 15 локациями, USD + RUB.
  • 4.3 Открыть Болезни и климат — увидеть карточки, рейтинг локаций, кликабельные ссылки на источники.

Этап 6 — bug-fix после first-pass review

Итог верхнеуровневой проверки по файлам (искали: «где видны / не видны азиатские локации»):

Файл Использует LOCATIONS как Видны ли азиатские Действие
src/modules/atlas.jsx const locs = window.LOCATIONS (no persist) ✅ да, но группируются в «Континент / Горы» known limitation, фиксить позже
src/modules/decision.jsx useLocalState('locs', window.LOCATIONS) нет — persisted старый список перекрывает обновление fix в Этапе 7.1
src/modules/finance.jsx не использует LOCATIONS напрямую (только budget) n/a
src/modules/basket.jsx window.LOCATIONS напрямую ✅ да OK
src/modules/conditions.jsx window.LOCATIONS напрямую ✅ да OK
src/modules/wellbeing.jsx, roadmap.jsx, qna.jsx не используют LOCATIONS n/a

Этап 7 — фиксы и доработки

  • 7.1 Decision Engine (src/modules/decision.jsx): на инициализации locs мерджит persisted с window.LOCATIONS, дополняя новые id (см. useEffect после useLocalState). После одной перезагрузки страницы старые сессии увидят все 15 локаций.
  • 7.2 Финансовая модель (src/modules/finance.jsx): курс rate инициализируется из window.FX.usdRub, ручное изменение синхронизирует обратно window.FX (Basket подхватит при переключении). Под полем — строка с актуальным FX, датой asOf, источником и кнопкой «Применить FX-курс» если значения разошлись.
  • 7.3 Health Atlas — расширить группировку по морю на азиатские бассейны (Южно-Китайское, Малаккский пролив, Индийский океан). Опционально: расширить SVG-карту или добавить второй «Азиатский» SVG-блок. В этом проходе не делаем — пользователь явно ограничил скоуп. Частично закрыто в app/screens/atlas.jsx: pill-фильтр Азия + Горы + match-score сортировка — но только в mobile-версии.

Этап 8 — Mobile-first PWA (Сессия 4, 2026-05-19)

  • 8.1 Перенесены 9 файлов из Claude Design canvas в app/: index.html, manifest.json, app/shell/primitives.jsx, styles.css, 4 экрана. Полностью совместимы с существующим data layer (../src/data/*), общий rc2027: префикс.
  • 8.2 Сгенерировать PWA-иконки (192px, 512px, apple-touch) и прописать в manifest.json. Сейчас icons: [].
  • 8.3 Наполнить stub-экраны (_stubs.jsx): приоритет — Finance, Basket, Wellbeing, Conditions, Chat. Подсмотреть структуру у уже готовых today/atlas/location.jsx.
  • 8.4 Добавить ссылку «📱 mobile-версия» в десктоп index.html (sidebar или header) — чтобы пользователь нашёл новый entry point. Опционально: настроить Vercel rewrites для красивого URL /m → /app/.
  • 8.5 Live-AQI через open-meteo (today.jsx сейчас использует мок-данные для климата SPb ↔ цели).
  • 8.6 Sensitivity-pivot онбординг — ScreenOnboarding сейчас stub. План — 6 шагов: семья → диагнозы → бюджет → веса критериев → шорт-лист → готово.

8.3 и 8.4 устарели после Этапа 9 (mobile стал корнем) — расщеплены в Этап 10.

Этап 9 — Unify в одно приложение (Сессия 5, 2026-05-19)

  • 9.1 Mobile-first app/ поднят в корень. Новый index.html → mobile PWA, старый desktop → legacy/index.html с правкой путей на ../src/*.
  • 9.2 manifest.json поднят в корень. vercel.json: добавлены Cache-Control для /app/* и application/manifest+json.
  • 9.3 Stubs-ссылки ../index.htmllegacy/index.html. Удалён дубль app/index.html.
  • 9.4 Memory: сохранены feedback_workflow.md (спрашивать перед каждым шагом) и project_mobile_first_phase.md (mobile-only до явной команды).

Этап 10 — Migrate 8 desktop pages → mobile shell

Решение пользователя (2026-05-19): «сразу мигрировать все 8 страниц». Делаем по одной за пайплайн, конкретный экран выбирает пользователь на каждом шаге.

# Legacy file New Screen Status
10.1 src/modules/basket.jsx ScreenBasket ✅ done · session 6
10.2 src/modules/conditions.jsx ScreenConditions
10.3 src/modules/finance.jsx ScreenFinance
10.4 src/modules/decision.jsx ScreenCompare
10.5 src/modules/roadmap.jsx ScreenRoadmap ✅ done · session 13 (audience-aware)
10.6 src/modules/wellbeing.jsx ScreenWellbeing ⏳ (частично в ScreenToday)
10.7 src/modules/qna.jsx ScreenQnA
10.8 После миграции — удалить src/modules/, src/components/, src/styles/main.css, legacy/

Миграция приостановлена после 10.1 в пользу Этапа 11 (Pivot). Возобновится после ScreenOnboarding + ScreenProfile с новым user-state.

Этап 11 — Pivot к публичному сервису (Сессия 7+, 2026-05-19)

Решение пользователя: проект становится сервисом для русскоязычных релокантов. Я работаю в роли системного аналитика.

  • 11.1 Зафиксирован pivot в memory: project_pivot_to_service.md, project_privacy_architecture.md, feedback_workflow.md.
  • 11.2 Создан docs/DATA_MAP.md: 35+ подгрупп ЦА, инвентаризация всех данных, PII, lifecycle, admin/debug procedure, negative list.
  • 11.3 docs/USER_STORIES.md — 4 personas (Артём, Мария+Денис, Лидия, Камиль), 18 user stories по 6 фазам, acceptance criteria, story map.
  • 11.4 User Profile data layersrc/data/user-profile/ (5 файлов): schema, default, demo, storage с profileId-префиксом, ProfileProvider + useProfile() с reducer. <App /> обёрнут в <ProfileProvider>. localStorage: rc2027:<profileId>:userProfile + rc2027:meta:activeProfileId + rc2027:meta:profiles.
  • 11.5 ScreenOnboardingapp/screens/onboarding.jsx с 8 шагами (welcome+demo, name, tags по 5 категориям, family, health, finance, target, ready). Required: name + minimum 1 tag. PageResolver форсирует онбординг при первом запуске. BottomTabs скрываются на время онбординга.
  • 11.6 ScreenProfileapp/screens/profile.jsx. 6 секций (Identity, Audience, Household, Health, Finance, Privacy), Profile switcher (>1 профиль), demo-exit, Danger zone (clearAll). Корневой экран таба me. Экспорт/импорт через <a download> / FileReader.
  • 11.7 Depersonalization 2 экранов (today + location). today.jsx использует profile.displayName/targetCity/originCity/targetDate; insight контекстный. location.jsx: weights из profile.weights, TabHealth фильтрует по profile.health.conditions. atlas.jsx и basket.jsx уже не имеют hardcoded семейных данных.
  • 11.8 Возобновить Этап 10 (миграция остальных 7 страниц) с использованием user-state.

Принципы миграции (фиксированы для всех 7 оставшихся):

  • Не переносить desktop UI 1:1; переосмыслить под mobile (большие тач-таргеты, скролл вместо таблиц, sheet вместо modal).
  • Использовать только существующие primitives из app/primitives.jsx.
  • Каждый экран должен иметь видимый entry point из главных экранов (top-bar IconBtn / hero CTA / nested goto).
  • Все state через useLocalState с префиксом-под-screen (basket:sort, compare:weights, …) — чтобы не конфликтовать с legacy.

🩺 Медицинский раздел — диагнозы семьи Π

Сводный список всех диагнозов, ранее упомянутых пользователем (на дату 2026-05-16). Тон — академический, уровень мировых клиник (Mayo / Charité / King's College London). Источники — в src/data/conditions.js.

Профиль пациентов

Член семьи Подтверждённые диагнозы Сопутствующие риски
Муж Атопический дерматит (L20), аллергический ринит (J30, атопическая триада), экзема кистей рук (L30.9) SAD (сезонный аффективный), HPA-стресс-нагрузка при релокации
Жена Синдром раздражённого кишечника (K58, СРК) Дисбиоз при смене региональной микробиоты; HPA-cortisol при переезде

Что говорил бы дерматолог мирового уровня (Eric Simpson / Jonathan Silverberg / Carsten Flohr school)

Атопический дерматит — патогенетические оси, релевантные климату:

  1. Эпидермальный барьер (filaggrin / TEWL): низкая влажность <40% (зимнее отопление СПб) и высокая >75% (Кобулети, Пенанг, Дананг) одинаково плохи. Первая разрушает stratum corneum, вторая запускает Malassezia globosa и потовую мацерацию. Оптимум 50–65%.
  2. AhR-сигналинг и PM2.5: долгосрочное воздействие тонкой пыли (PM2.5 >25 мкг/м³) активирует aryl-hydrocarbon receptor в кератиноцитах → хроническое воспаление. Чиангмай в «burning season» (фев-апр PM2.5 >150) — клинически противопоказан для не-стабилизированных пациентов на дупилумабе.
  3. Жёсткость воды (Perkin BMJ 2016): Ca²⁺/Mg²⁺ + анионные ПАВ → осадок на коже → разрушение барьера. Кобулети, Анталья (7 мг-экв/л), Кирения (8) — категорически нужен ионообменник + осмос. Дилижан (3) и Пенанг (3) — оптимум.
  4. Pinene-фитонциды (ЮБК-эффект): α/β-пинены от P. pityusa + морской аэрозоль с морскими полисахаридами (Fucus, Cystoseira) — известный adjuvant к топической терапии. Лучшие: Пицунда (юридически невозможна), Геленджик (юрид. риск), Кобулети (влажность гасит эффект). Компромисс: Кирения.
  5. UV-индекс: UVB зимой полезен (NB-UVB-аналог), UVА летом — фотостарение + триггер у части пациентов. Тропические локации (Дананг, Пенанг, Санья) дают круглогодичный UV-стресс — нужен SPF50 ежедневно.

Дерматологическая ранжировка 15 локаций (атопия + экзема рук + ринит, чем выше — тем лучше):

Ранг Локация Комментарий дерматолога
1 Кирения Идеальный микроклимат: 58% влажн, 19°C, AQI 25. Минус — жёсткая вода (нужен осмос).
2 Дилижан Сухой горный воздух, мягкая вода (3), AQI 22 — лучший по воде и воздуху. Минус — нет моря.
3 Поморие ЕС-медицина + 65% влажн + AQI 32. Дупилумаб по НЗОК.
4 Бар Адриатика, 60% влажн, P. halepensis. Минус — дорогая медицина.
5 Анталья Сухой средиземноморский, JCI-клиники. Минус — жёсткая вода + UV круглый год.
6 Влёра Сухо (58%), но слабая медицина — рискованно для тяжёлой атопии.
7 Нови-Сад Континент 65% влажн, но AQI 40 и нет морских фитонцидов.
8 Трабзон 80% влажн — серьёзный риск; язык — барьер для медицины.
9 Геленджик Лучший ЮБК-эффект, но юрисдикция = 4.
10 Кобулети 80% влажн летом — почти противопоказание; новостройки с HVAC снимают риск.
11 Пицунда Идеальная P. pityusa, но юрисдикция = 5 (нет медицины).
12 Санья Чистый воздух (AQI 35), но 78% влажн + 25°C круглый год + Great Firewall = риск для системы.
13 Пенанг 80% влажн + 27°C + EN-медицина мирового уровня — медицина спасает, климат вредит.
14 Дананг Тропический муссон, 82% влажн — высокий риск Malassezia и потовой экземы.
15 Чиангмай «Burning season» март-апрель PM2.5 >150 — противопоказание для атопии без герметичного жилья + HEPA H13.

Что говорил бы эндокринолог мирового уровня (Ricardo Correa / Anthony Heaney school)

Эндокринный аспект релокации — не отдельный диагноз, а гормональный фон, на котором разворачиваются хронические заболевания семьи:

  1. HPA-ось (гипоталамус-гипофиз-надпочечники): релокация — это chronic mild stress длительностью 6–18 мес. Уровни кортизола повышены → обострение атопии (Th2-shift) и СРК (висцеральная гиперчувствительность). Рекомендация: измерять cortisol AM/PM в первый месяц на месте и через 6 мес.
  2. Витамин D (25-OH-D₃): дефицит у переехавших из СПб (60° с.ш., UVB 5 мес/год) — статистически >70% популяции. Целевой уровень 30–60 нг/мл. Тропики и Средиземноморье решают проблему; Дилижан/Нови-Сад/Поморие — частично; ИЛИ супплементация 2000 МЕ/сут круглогодично.
  3. Щитовидная железа и йод: дефицит йода в горных и удалённых от моря регионах (Дилижан, Нови-Сад). На приморских локациях — естественный йод в воздухе. Контроль ТТГ через 6 мес после переезда.
  4. Циркадные ритмы и SAD: разница широт. СПб (60°N) → Кобулети (42°N) → Пенанг (5°N) — фотопериод меняется радикально. Тропики (Дананг 16°N, Пенанг 5°N, Санья 18°N) — стабильный 12/12, что у части пациентов вызывает sub-clinical SAD из-за отсутствия сезонной мелатониновой амплитуды.
  5. Микробиота и СРК (gut-microbiota-brain axis): региональная микробиота на 30-40% определяется водой и местной диетой. Резкая смена → 3–6 мес дисбиоза. Рекомендация: профилактический приём Saccharomyces boulardii первые 4 недели + локальные ферментированные продукты (мацун в Дилижане, болгарское кисело млеко, корейское кимчи).

Эндокринологическая ранжировка (HPA-нагрузка + витамин D + йод):

Лучший профиль Худший профиль
Поморие (ЕС-эндокринология, средиз. UV, морской йод) Чиангмай (PM2.5-стресс + неравный UV)
Бар (Адриатика, морской йод, мягкий стресс адаптации) Пицунда (нет нормальной медицины)
Кирения (стабильный UV, морской йод) Санья (Great Firewall = инф. изоляция = chronic stress)

Что в коде уже учтено (соответствие src/data/conditions.js)

Текущие climateFactors в conditions.js:

  • ✅ Влажность с оптимумом и штрафом за >75%
  • ✅ Температура с диапазоном
  • ✅ AQI/PM2.5
  • ✅ Жёсткость воды
  • ✅ Фитонциды (через ybkScore)
  • ✅ Доступность гастро-инфраструктуры
  • ✅ Пыльцевой пик
  • Не учтено: широта / UV-индекс / SAD-риск
  • Не учтено: йод в воздухе у моря (актуально для горных Дилижан/Нови-Сад)
  • Не учтено: региональная микробиота — оценка качественная, не количественная

Эти пункты — в backlog как 7.4–7.6 (для следующего прохода, не в этом).

  • 7.4 Добавить в conditions.js фактор latitude (для SAD/UV-D) и nearSea (йодный фон).
  • 7.5 Добавить новую condition vitamin_d_deficiency (E55) с фактором широты.
  • 7.6 Добавить новую condition hpa_stress_adjustment — переходный 6-месячный диагноз релокации; локационные факторы — langBarrier, diaspora, infra.

Этап 5 — пост-задачи на пользователя

  • 5.1 Актуализировать курс window.FX.usdRub на актуальный (например, через ЦБ РФ XML или fixer.io). Сейчас стоит заглушка.
  • 5.2 Верифицировать визовые режимы Азии на текущий момент (МИД РФ / посольства целевых стран).
  • 5.3 Проверить PMID/DOI в conditions.js через PubMed, заменить URL-поиски на прямые ссылки.
  • 5.4 Дополнить азиатские локации полями, специфичными для региона (сезон муссонов, qi-сезоны и т.п.) — если решим расширять.

Список новых файлов (после полного прохода)

BACKLOG.md                                   ← этот файл
src/data/extras.js                           ← FX, BASKET_ITEMS, LOCATION_EXTRAS, 4 азиатские локации
src/data/conditions.js                       ← CONDITIONS + scoreLocationForCondition()
src/styles/extras.css                        ← стили только для basket + conditions, изолированы от main.css
src/modules/basket.jsx                       ← страница «Продуктовая корзина»
src/modules/conditions.jsx                   ← страница «Болезни и климат»

Правки существующих файлов: только index.html (+4 строки), src/components/app.jsx (+2 пункта nav, +2 ключа Page), FILES.md (актуализация индекса).


Карточка «Продуктовая корзина» — спецификация

Состав корзины (10 позиций, Numbeo-наборы):

id label unit
milk Молоко, 1 л 1 л
bread Хлеб (буханка) 500 г
eggs Яйца 12 шт
rice Рис 1 кг
chicken Куриная грудка 1 кг
apples Яблоки 1 кг
potatoes Картофель 1 кг
tomatoes Помидоры 1 кг
onions Лук 1 кг
oil Масло раст. 1 л

basketTotal = sum(basketUSD[id]). Это «недельная половина» — корзина одного похода в магазин, не месячный бюджет.


Карточка «Визы для РФ» — структура

visaRu: {
  type: 'visa-free' | 'evisa' | 'voa' | 'visa-required',
  days: 60,                       // дней пребывания без визы / по e-visa
  link: 'https://…',              // официальный источник
  asOf: '2026-01',                // дата проверки
  notes: 'Краткое уточнение'
}

Карточка «Болезни» — структура

{
  id: 'atopic_dermatitis',
  name: 'Атопический дерматит',
  who: 'Муж',                          // пациент в семье
  summary: '…',                        // 1-2 предложения
  climateFactors: [
    { factor: 'humidity', optimum: [55, 65], penaltyAbove: 75,
      reason: 'Malassezia рост при >75%', weight: 3 },
    { factor: 'temp', optimum: [10, 18], weight: 2 },
    { factor: 'aqi', maxOk: 35, weight: 2 },
    { factor: 'waterHard', maxOk: 5, weight: 2,
      reason: 'жёсткая вода + ПАВ → раздражение кожи' }
  ],
  evidence: [
    { title: '…', authors: '…', journal: 'BMJ', year: 2016, link: 'https://…' },
    { title: '…', authors: '…', journal: 'JEADV', year: 2020, link: 'https://…' }
  ]
}

Рейтинг локации = взвешенная сумма штрафов по факторам. Сортируем LOCATIONS по этому значению и показываем топ-5 для каждой болезни.


Phase 6 · 50-step refinement plan (2026-05-23+)

Цель: доработать и улучшить проект до состояния, готового к публичному запуску для русскоязычных релокантов. 50 концентрированных пунктов из анализа проекта и ролей (Product, UX, FE, BE, Data, T&S, Security, A11y, DevOps, Localization, BD). Каждый пункт — ~0.5–2 дня работы.

Прогресс: [ ][x]. Текущий статус — Спринт 0 (база готова: 2 досье городов, Action Loop, Multi-city compare).

Track 1 · Расширение данных и контента (#1–7)

  • #1 🔴 M Ереван, Армения — досье · Data Scientist. ✓ 2026-05-26 (v0.053): 68 Q&A записей по 15 блокам + 40 KB yerevan.json, 13 секций. Уникальные особенности: СИДН РФ-РА действует (не приостановлен), ратификация Римского статута МУС 02.2024 (риск), ЕАЭС-преимущество для питомцев (3-6 нед vs 5-6 мес для ЕС), Yandex Go работает, IT-сертификат 1% налог до 2032. Валидатор: ✓.
  • #2 🔴 M Тбилиси, Грузия — досье · Data Scientist. Пара к Кобулети для городских семей; закон о трудовой миграции 2026
  • #3 🟡 M Белград, Сербия — досье · Data Scientist. Вне ЕС/НАТО, 2-я волна релокантов
  • #4 🟡 M Будапешт, Венгрия — досье · Data Scientist. Лояльнее РФ-граждан; ВНЖ-инвестора 2024
  • #5 🟡 M Бечичи/Будва, Черногория — досье · Data Scientist. Популярно у пенсионеров; Eurozone-unilateral
  • #6 🟢 M Беломорье, Карелия — досье · Data Scientist. Внутрироссийская релокация
  • #7 🟢 L Stage 2 пул — Лиссабон, Стамбул, Дубай, Аланья · Data Scientist

Track 2 · UX и онбординг (#8–13)

  • #8 🔴 M Audience quiz onboarding v2 · UX + PM. 5–7 визуальных вопросов → 3–5 audience-тегов
  • #9 🔴 S Empty states ревизия · UX Designer. ✓ 2026-05-26 (v0.055): аудит показал что <Empty> уже используется в 11 местах. Главный пробел — Today для нового пользователя без targetCity → добавлена CTA-карточка «Выберите целевой город» с кнопками к Атласу и AI. Компонент Empty дополнен пропом action для CTA.
  • #10 🟡 S Loading skeletons вместо текста · Frontend. ✓ 2026-05-26 (v0.055): новый компонент <Skeleton> в primitives.jsx с linear-gradient shimmer + CSS keyframes rc-skeleton. Props: width, height, lines, gap, rounded. Использован вместо plain-text «загрузка...» в location.jsx (deepLoading) и compare.jsx (CompareDeepSections).
  • #11 🟡 S Error boundaries на уровне экрана · Frontend. ✓ 2026-05-26 (v0.055): React class <ErrorBoundary> в primitives.jsx с getDerivedStateFromError + componentDidCatch + reset(). Fallback UI с акцентной красной полоской, кнопками «попробовать снова» и «на главную», сообщением ошибки (обрезано 240 char), напоминанием что данные в localStorage не потеряны. PageResolver в shell.jsx оборачивает screenContent в ErrorBoundary с key={boundaryKey} — сброс error state при навигации.
  • #12 🟡 M Sticky tab bar на ScreenLocation · UX + FE. 11 табов скроллятся горизонтально
  • #13 🟡 M A11y baseline · A11y Specialist. Keyboard nav, focus-visible, ARIA, semantic HTML

Track 3 · Инструменты и калькуляторы (#14–21)

  • #14 🔴 L Visa/tax calculator · Data Scientist + PM. Расчёт нагрузки ИП-1% Грузия vs ЕООД-14.5% Болгария vs Virtual Zone vs РФ-ИП
  • #15 🔴 M Document checklist generator · PM + UX. Динамический список под локацию + audience
  • #16 🔴 M Progress tracker · PM + FE. % выполнения по фазам (доки/банк/жильё/школа/мед)
  • #17 🟡 L Timeline planner · UX + FE. Drag&drop дат на шкале T-6...T+3 мес; auto-зависимости
  • #18 🟡 M Budget calculator с audience override · FE. Расширить ScreenFinance
  • #19 🟡 M Startup cost wizard · PM + FE. Таблица расходов первых 3 мес под состав семьи
  • #20 🟢 S Currency converter widget · FE. EUR↔USD↔RUB↔GEL↔AMD с фиксацией дня
  • #21 🟡 M Risk profile assessment · T&S + Data. 10 вопросов «насколько в группе риска» → рекомендации городов

Track 4 · Достоверность и качество данных (#22–28)

  • #22 🔴 S Schema CI validator · DevOps + Data Eng. ✓ 2026-05-23 (v0.051): scripts/validate-locations.mjs (AJV draft 2020-12) + scripts/validate-jsx.mjs (@babel/parser). Поймал 13 нарушений в pomorie.json — все исправлены. Запуск: npm run validate:locations / npm run validate:jsx. Pre-commit hook опционален (см. FILES.md)
  • #23 🔴 S Data freshness audit · Data Eng. ✓ 2026-05-24 (v0.052): scripts/audit-freshness.mjs сканирует qna.js и locations/*.json, парсит форматы YYYY-MM-DD/YYYY.MM/MM.YYYY, флаги --threshold N, --format text\|json\|csv, --exit-on-stale. Первый запуск с порогом 60 дней — 57 устаревших записей в qna.js. С порогом 365 — 0 устаревших (норма после 2026.05 правок).
  • #24 🟡 S URL source audit · Data Eng. ✓ 2026-05-26 (v0.056): scripts/audit-urls.mjs (npm run audit:urls). Извлекает URL из qna.js + locations/*.json (256 уникальных найдено). HEAD-запросы с fallback на GET-Range при 405/501. Параллельно (default 8), timeout 8 сек. Флаги --concurrency, --timeout, --format text\|json\|csv, --exit-on-broken, --limit N.
  • #25 🟡 L Schema v2 — мульти-валютная поддержка нативно · Software Architect. Без параллельных *Local
  • #26 🟡 S Source priority tier в схеме · T&S + Data. ✓ 2026-05-26 (v0.056): classifySource(url) + <SourceTierBadge url /> в primitives.jsx. Whitelist доменов: official (gov.*, cba.am, ena.am, nalog.ru, pubmed.ncbi, freedomhouse, interpol), community (t.me, vc.ru, dtf.ru, habr, *.wiki, *.blog), default secondary. Badge с цветовым тоном в SourceSheetBody чата. Без правки схемы — классификация во время рендера по домену.
  • #27 🟢 S Crowdsourced corrections · T&S + PM. Кнопка «сообщить о неточности» → mailto/GitHub Issues
  • #28 🟡 S Deprecation flow · T&S. ✓ 2026-05-26 (v0.056): <VerifyBadge> дополнен props deprecatedSince и note. При status==='deprecated' показывает «⚠ устарело с YYYY-MM» с красным toнe + tooltip с объяснением. Backwards-compatible: если deprecatedSince не передан — fallback к «устарело». Все 4 места использования в location.jsx обновлены.

Track 5 · Performance и масштаб (#29–35)

  • #29 🔴 M Service Worker для offline · Mobile Eng + DevOps. ✓ 2026-05-26 (v0.057): service-worker.js ~180 строк. Три стратегии: cache-first (app shell), stale-while-revalidate (JSON-досье городов), cache-first с passive ingest (CDN unpkg/fonts — обходит CSP connect-src 'self'). 32 файла в pre-cache (~1.2 MB), Promise.allSettled (партиальные сбои не валят install). Версионирование через CACHE_VERSION, skipWaiting+claim. Регистрация в app.jsx. vercel.json: Service-Worker-Allowed: /, no-cache headers, CSP worker-src 'self'. Локальный тест 32/32 файлов OK.
  • #30 🔴 S PWA install prompt · Mobile Eng. ✓ 2026-05-27 (v0.058): SVG-иконка + 5 PNG (sharp-генератор generate:icons). Полноценный manifest.json (id, shortcuts, maskable, display_override). SW update flow: убран auto-skipWaiting, постоянная регистрация waiting через postMessage. useServiceWorker() + useInstallPrompt() хуки. На Today: <UpdateAvailableCard> (acc-полоска, dismissible) + <InstallPromptCard> (после 3-го визита, dismiss 30 дней, iOS-инструкция через Sheet). На Profile: <AppInfoSection> (версия, SW, кнопки «Проверить»/«Установить»). vercel.json: icons immutable 1 год. APP_VERSION='1.0.58', BroadcastChannel架h-готовность для future force-update.
  • #31 🟡 M Code splitting крупных screens · Frontend. location.jsx 48 KB / finance 27 KB / compare 41 KB
  • #32 🟡 M CDN immutable URL для досье · DevOps. pomorie.v1.0.0.json с 1-year cache
  • #33 🟡 S Web Vitals monitoring · Performance Eng. Opt-in LCP/CLS/INP без backend
  • #34 🟢 S Lazy-load изображений · Frontend. Когда добавим фото городов (Track 1+)
  • #35 🟡 S Bundle analysis · Performance Eng. Цель: initial bundle <100 KB gzipped

Track 6 · Безопасность и приватность (#36–40)

  • #36 🔴 S CSP headers · Security Eng. ✓ 2026-05-26 (v0.054): Content-Security-Policy с 'unsafe-eval' для Babel Standalone, whitelist unpkg.com для script-src, fonts.googleapis.com/gstatic.com для style/font, frame-ancestors 'none', upgrade-insecure-requests. + Strict-Transport-Security (1 год) + X-Frame-Options DENY.
  • #37 🔴 S Sanitization user-input · Security Eng. ✓ 2026-05-26 (v0.054): sanitizeUrl(url) блокирует javascript:/data:/vbscript:/file:/blob:/filesystem: (case-insensitive); sanitizeText(text, maxLength) убирает управляющие символы и обрезает длину. Использованы в chat.jsx (saveEntry для q/a/src, SourceSheetBody для href) и conditions.jsx (sanitizeUrl + noopener noreferrer для PubMed-ссылок). 15 атакующих векторов протестированы, все блокируются. Альтернатива DOMPurify (через CDN +60 KB) не нужна — нет dangerouslySetInnerHTML в кодовой базе.
  • #38 🟡 L localStorage encryption optional · Security Eng + UX. Для sensitive medical/financial; ключ из PIN
  • #39 🔴 S Privacy disclosure modal · Legal + UX. ✓ 2026-05-26 (v0.054): expandable Privacy-блок в StepWelcome онбординга. 🔒 «Все данные хранятся только в вашем браузере» с раскрывающимися деталями: что хранится локально (localStorage rc2027:), что НЕ уходит наружу, что грузится с CDN, GDPR-права (export/delete). Без отдельного modal — встроено в первый шаг.
  • #40 🟡 S GDPR-friendly export/delete · Legal + FE. Уже есть export, нужно «удалить всё навсегда» + подтверждение

Track 7 · Engagement и удержание (#41–46)

  • #41 🟡 M Daily check-in streak · PM + UX. «N дней подряд» + visual badge
  • #42 🟡 L Push notifications API · Mobile Eng. Opt-in browser push для legal/banking/санкции
  • #43 🟡 M Insight cards · Data Scientist + PM. «У вас уже 3 задачи в lane:docs — спланируйте визит в МФЦ»
  • #44 🟢 S What's new экран · PM + Data. Что обновилось в выбранных городах с прошлого визита
  • #45 🟡 S Onboarding completion badge + soft prompts · UX. «Заполните health → видите медриски»
  • #46 🟢 M Community testimonials · PM + Content. Анонимные истории в Atlas/Location

Track 8 · Дистрибуция, локализация, монетизация (#47–50)

  • #47 🟡 L EN-локализация ключевых экранов · Localization + FE. Today + Atlas + Location overview
  • #48 🟡 M SEO meta + Open Graph · SEO + DevOps. SSG-снимки для каждого досье; индексация в Google
  • #49 🟢 L Freemium model — premium consultancy · PM + BD. Партнёрская сеть юристов; revenue share
  • #50 🟢 L B2B model — корпоративные подписки · PM + BD. HR-кейс; white-label вариант

Сводка по приоритетам

Приоритет Кол-во Описание
🔴 High 14 Core data + базовый UX + критичные основы безопасности
🟡 Medium 26 Большинство аналитики и engagement
🟢 Low 10 Зрелые фичи и монетизация

Критические зависимости

  • #22 (CI validator)#1–7 — нужен до массовой генерации досье
  • #1–7 (города)#14 (visa/tax calc)#16 (progress tracker)
  • #36–39 (security)#47 (EN) — публичная версия в ЕС требует security baseline
  • #29 (service worker)#30 (PWA install)#42 (push)
  • #48 (SEO/SSG)#1–7 — генерировать HTML только при готовых данных
  • #23–24 (audit)#28 (deprecation flow) — деприкейт работает с auto-flagging

Рекомендованная последовательность спринтов

Спринт Пункты Тема
1 #22, #1 Фундамент данных
2 #2, #23 Ереван + freshness
3 #36, #37, #39 Security baseline
4 #9, #10, #11 UX-фундамент
5 #8 Quiz onboarding
6 #14 Visa/tax calculator
7 #15 Document checklist
8 #16 Progress tracker
9 #29, #30 Service worker + PWA install
10 #3 или #4 Белград / Будапешт
11 #24, #26, #28 Data quality
12 #43, #45 Engagement

После 12 спринтов: 25 из 50 пунктов сделано, продукт готов к публичному запуску по линии «доступности + достоверности», с 4–5 городами в полной готовности.