# Сайт-генератор резюме без опыта работы Сайт для тех, кто ищет первую работу (школьники, студенты, выпускники колледжей/вузов, гэп-год) и не знает, что писать в резюме без опыта. Помогает найти "скрытые" навыки в хобби/интересах и объясняет, где они пригодятся. ## Статус Прототипная стадия. Все файлы ниже — рабочие черновики для оценки тона, механик и дизайна, не production-код. **Куда смотреть в первую очередь:** `START_HERE.md` — краткий вход для новой сессии/устройства (как запустить, карта проекта, текущая точка останова). Здесь — полный журнал решений и роадмап; деплой — в `docs/DEPLOY.md`. **Astro-версия собрана (пункт 2 плана «Дальнейшие шаги» → см. конец README).** Теперь в репозитории две плоскости: - Ветка/репо на GitHub: **github.com/Splendor1980/resume-site-v17** (пуб/приват — как создано). Это git-ремот для синхронизации проекта между устройствами, а не хостинг сайта (см. «Дорожная карта»). - `index.html` и `data/`, `prototypes/` **в корне** — прежний прототип (SPA на чистом JS), сохранён как история решений и для сравнения; - **Astro-приложение** в `src/` — статические SEO-страницы идей + конструктор как «остров» на `/konstruktor/`. Именно его нужно развивать дальше и хостить (шаг 3 плана — домен и хостинг). **Как запустить Astro-версию локально:** ``` npm install # первый раз npm run dev # http://localhost:4321/ (только один раз потребуется npx playwright install chromium) npm run build # статическая сборка в dist/ npm run preview # посмотреть собранное npm run test:e2e # headless-проверка конструктора и SEO-страниц (Playwright) ``` Важно: `npm run build` сам копирует `data/ideas.json`, `prototypes/` и `README.md` в `public/` (скрипт `scripts/sync-data.mjs`) — это runtime-файлы, на которые ссылается конструктор. Если меняешь `data/ideas.json` — правь только корневой файл, копия в `public/` обновится при сборке. Архивы для скачивания версионируются по папке (`resume-site-v4`, следующий будет `v5` и так далее) — не переиспользуем номер версии повторно, чтобы не путать файлы в загрузках. **Правило версионирования (договорённость с v17):** текущая папка проекта — `resume-site-v17`, при загрузке на GitHub имя папки/репо НЕ меняем. Каждое следующее крупное изменение — это переименование папки в `resume-site-v18`, `resume-site-v19` и т.д. (номер +1 от текущего, не пропуская). Мелкие правки внутри одной версии папку не переименовывают. ## Структура ``` index.html — ГЛАВНАЯ СТРАНИЦА продукта (не список черновиков!): три режима поиска идей (листай / по профессии / помощник-подсказчик) + резюме слева, само переключается между компактным и плотным шаблоном в зависимости от объёма выбранного контента (< 2 выбранных идей → компактный сайдбар-шаблон, 2+ → плотный многосекционный). Шестерёнка (правый верхний угол) открывает служебную панель со ссылками на черновики ниже — обычный посетитель туда не заходит. data/ ideas.json — база связок "интерес → навыки → роли → комментарий", 103 записи (schema v3: category — устойчивая, examples_now — обновляемые конкретные примеры игр/сериалов, освежать раз в 6-12 мес) about-snippets.json — примеры фрагментов "О себе/навыки" для вдохновения, размечены по persona, tone и length (short/medium/long) prototypes/ (черновики, оставлены для истории решений — доступны из index.html через шестерёнку) 01-cards-board.html — экран "листания идей" с фильтром по тегам 02-builder-split-screen.html — первая версия конструктора со статичным шаблоном резюме 03-template-compact-vs-dense.html — сравнение шаблонов резюме под разный объём текста (дизайн отсюда перенесён в главный index.html) 04-mode-switcher.html — предыдущая версия главной страницы (три режима), но ещё со статичным, не адаптивным шаблоном резюме слева 05-ai-assistant-system-prompt.md — черновик системного промта для платного ИИ-ассистента (режим 3); провайдер — YandexGPT Lite, подключение отложено до появления реального спроса (см. README) src/ — Astro-приложение (SSG под SEO), мастер-копия конструктора layouts/BaseLayout.astro — общий SEO-страниц: title/description/canonical/OG/метрика, JSON-LD (передаётся как structuredData) components/ Constructor.astro — «ОСТРОВ» интерактивности, перенесён из index.html почти без изменений. Отличия от прототипа: fetch('/data/ideas.json') по абсолютному пути, ссылки черновиков и данных абсолютные (/prototypes/...), заголовок карточки стал ссылкой на её SEO-страницу. CSS — изолированный (is:global), JS собирается/минифицируется Astro. Логика отлажена Playwright-тестом — сознательно не переписывалась на React/Vue. Header.astro / Footer.astro / Metrika.astro pages/ index.astro — лендинг: hero под длинный поисковый запрос, «как работает», подборка популярных идей, все темы, FAQ (с JSON-LD FAQPage), CTA на конструктор idei/index.astro — полный список 103 идей, сгруппированных по тегам (ItemList JSON-LD) idei/[slug].astro — СТАТИЧЕСКИЕ SEO-СТРАНИЦЫ: 103 шт., по одной на запись ideas.json. Route: /idei/strategy_games/ и т.д. Внутри: хлебные крошки, activity_title (h1/заголовок), resume_bullet, comment как объяснение «почему интересно работодателю», навыки, роли, примеры, employer_value, блок исследований, CTA на конструктор, похожие идеи (связи по тегам). JSON-LD Article. konstruktor.astro — страница-обёртка для Component.astro (полный экран приложения). methodika.astro — страница «О методологии» (/methodika/): принцип «хобби → навыки → роль», подходы Ramit Sethi / Laszlo Bock / инфостиль, честная пометка «исследования есть у 3 из 103» + блок с реальными источниками (динамически из data/ideas.json), AboutPage JSON-LD, CTA на конструктор public/ — статика, попадающая в dist как есть data/ideas.json — рабочая копия для runtime-fetch конструктора (автообновляется сборкой) prototypes/, README.md, favicon.svg, og-cover.svg, robots.txt astro.config.mjs — site (=https://resumegenerator.ru), trailingSlash, @astrojs/sitemap (конструктор исключён) scripts/ sync-data.mjs — копирует data/prototypes/README в public/ (вызывается prebuild) run-e2e.mjs — обёртка теста: сама поднимает «astro preview» на :4321, ждёт готовности, запускает test-constructor.mjs и гасит сервер (нужен только npm run build; это то, что реально вызывает npm run test:e2e) test-constructor.mjs — сами проверки: 103 карточки, фильтры, add/toggle, режимы, чат, дровер, SEO-ссылка на статику, лендинг, список идей upload-yandex.mjs — выгрузка dist/ в Yandex Cloud Object Storage (AWS SDK, без глобального CLI): node scripts/upload-yandex.mjs {buckets|sync [--delete]|configure} (ключи из deploy/.env, см. см. docs/DEPLOY.md) data/ — источник истины (см. выше), из него генерируются и статика в /idei, и (через public-копию) доска в конструкторе ``` ## Ключевые решения по ходу разработки - **Монетизация**: бесплатно — генерация идей и вдохновение; платно (~50₽ или пакетом) — скачивание/редактирование. Рассматриваются варианты: пакет вместо разового платежа, бесплатный экспорт с watermark, "поделись — получи бесплатно". - **Экономика ИИ**: основной объём (подбор идей, сборка черновика резюме) работает БЕЗ живого вызова ИИ — за счёт заранее подготовленной базы `ideas.json`. Живой ИИ подключается только на платном этапе финальной редактуры текста. - **SEO**: интерактивный конструктор (это, по сути, SPA на JS) поисковики не индексируют. Реальный SEO-трафик должен идти через отдельные статические страницы, сгенерированные из `ideas.json` (например `/idei/kvadrokopter-pomoshnik-blogera`). Нужен SSG-фреймворк — чистый `index.html` для этого не подходит. - **Переход на Astro сделан (шаг 2 плана).** Маршруты: `/` — SEO-лендинг, `/idei//` — 103 статические страницы идей (генерируются из `ideas.json` на сборке), `/konstruktor/` — интерактивный конструктор как «остров» (перенесён из `index.html` почти без изменений). Подробное дерево — в разделе «Структура». Осознанные решения, принятые при переносе: - **Конструктор НЕ переписан на React/Vue** — логика в `Constructor.astro` осталась ванильной, проверена Playwright-тестом (запуск `npm run test:e2e`). Нативный скрипт собирается и минифицируется Astro-бандлером; это и есть «остров» в смысле Astro — вся остальная часть сайта статический HTML. - **Слаги — английские id из базы** (`/idei/strategy_games/`), а не транслитерация названий. Причина: стабильность и уникальность без ручной разметки 103 записей; транслитерация русских названий в слаги — отдельная контентная/техзадача, не сделано. - **`ideas.json` живёт в двух местах**: источник истины `data/ideas.json` (из него генерируются SEO-страницы на сборке) + рабочая копия `public/data/ideas.json` для runtime-fetch() конструктора. Копию обновляет `scripts/sync-data.mjs` при каждом `npm run build` — руками ничего не трогаем. - **Домен вписан**: `site` в `astro.config.mjs` и `Sitemap:` в `public/robots.txt` = **`https://resumegenerator.ru`** (куплен на reg.ru), на него указывают canonical/OG/sitemap. Канонический адрес — без `www`; редирект `www` → без `www` делаем на DNS/хостинге (шаг 3). - **HTTPS включён и работает** (18.08.2026): сертификат Let's Encrypt выпущен на домен (`CN=resumegenerator.ru`, действителен до 16.11.2026), `http://` отдаёт 301 → `https://`, каталоги `/`, `/idei/`, `/methodika/`, sitemap/robots проверены по https — 200, live E2E PASS. Открывается из РФ (Yandex Cloud), переживает перевыпуск сертификата автоматически. - **Стек**: выбран **Astro** — статическая генерация страниц под SEO + "острова" интерактивности только там, где нужны (конструктор резюме). Astro не привязан к конкретному хостингу. - **Хостинг — НЕ Vercel**: изначально рассматривался Vercel, но отклонён. Причины: (1) российские карты не принимаются для платных тарифов, (2) отдельные сайты на `*.vercel.app` реально попадают в реестр Роскомнадзора, (3) есть подтверждённые случаи, когда `.ru`-домен, привязанный к Vercel, переставал открываться с мобильного интернета в РФ без VPN. Для сайта на российскую аудиторию (и с `.ru`-доменом) это неприемлемый риск. Решение: **Yandex Cloud** (Object Storage + Cloud Functions — аналог связки Vercel) либо для старта проще — **обычный российский VPS** (Timeweb Cloud, Selectel, Beget) с Node.js, отдающим и статику, и вебхук оплаты с одной машины. Оплата хостинга и оплата от пользователей (через ЮKassa) в этом случае в одной валюте/юрисдикции — меньше точек отказа. GitHub Pages по-прежнему годится только для просмотра статических прототипов (нет серверных функций для вебхука оплаты), не для продакшена. - **Не только лето**: изначально ниша задумывалась как "выпускники + летние подработки", но верно расширена до "любой, кому нечего писать в резюме" — зимние каникулы, первая работа после колледжа/вуза, гэп-год. Все тексты должны быть сезонно-нейтральными. - **Актуальность примеров**: конкретные игры/сериалы/тренды быстро устаревают, поэтому в схеме `ideas.json` они вынесены в отдельное поле `examples_now`, не смешанное с устойчивой логикой (`category`, `skills`, `roles`). - **Авторское право**: реальные резюме/тексты других людей брать нельзя ни для дизайна (лицензии), ни для контента (авторское право + чужие персональные данные). Вместо этого — собственная база примеров, сгенерированная с нуля. - **Адаптивные шаблоны**: короткий текст ("О себе" в одну строку) не должен выглядеть как пустой лист А4. Решение — шаблоны на два типа: "компактный" (сайдбар, крупная типографика, визуальные элементы для малого объёма контента) и "плотный" (для тех, у кого есть что рассказать развёрнуто). Система должна сама подбирать шаблон по объёму заполненного контента, а не спрашивать пользователя. - **AI-провайдер — выбор сделан (YandexGPT Lite), но подключение сознательно отложено**: сравнивали GigaChat Business, YandexGPT Lite и агрегатор Ofox.ai — Ofox отклонён (не решает вопрос доступа/данных из РФ, просто прокси поверх зарубежных моделей, неясный статус для встраивания в клиентский продукт). YandexGPT Lite выигрывает у GigaChat Business по порогу входа (не требует юрлица для базового доступа). НО: оба тарифицируются по токенам без абонплаты — значит подключать их есть смысл только когда появится реальный трафик. Режимы 1 и 2 (карточки, поиск по профессии) не требуют ИИ вообще — работают на чистом `ideas.json`. Запускаем их первыми, без ИИ-зависимости и без затрат. **Триггер для подключения живого ИИ**: когда появится измеримый сигнал, что люди реально доходят до режима 3 и хотят большего, чем дают карточки — не раньше. До этого момента режим 3 остаётся локальным помощником-подсказчиком (поиск по ключевым словам + словарь синонимов, уже реализовано в `index.html`), без единого платного вызова. - **Три режима конструктора** (переключаются одной кнопкой на экране): 1. *Листай и собирай* — базовый режим, карточки идей с фильтром по тегам (уже реализован). 2. *Навыки под профессию* — обратный режим: пользователь выбирает интересующую роль/профессию, система показывает навыки, которые для неё может — но не факт что имеет — обладать; это переиндексация того же `ideas.json` по полю `roles`, отдельных данных не требует. 3. *Помощник-подсказчик* — сейчас бесплатный и локальный: наводящими вопросами и ветвлением по темам подбирает идеи из `ideas.json` (поиск по ключевым словам + словарь синонимов, без внешнего ИИ). Живой платный ИИ (RAG поверх той же базы) — в бэклоге, подключается по указанному выше триггеру. - **Самозанятость**: подходит для приёма платежей от физлиц (ставка 4% НПД, лимит дохода 2.4 млн ₽/год). Для приёма оплаты + автофискализации чеков — агрегаторы вроде ЮKassa, CloudPayments (сами формируют чек в "Мой налог"). - **`index.html` теперь загружает полную базу через `fetch('data/ideas.json')`**, а не захардкоженный список ~20 карточек, как было раньше во всех трёх режимах. Все 103 записи теперь видны и в "листай и собирай", и в "навыки под профессию", и в подсказчике. Важно: `fetch()` не работает при открытии файла двойным кликом с диска (`file://`) — нужен локальный сервер (`python -m http.server`) или реальный хостинг (GitHub Pages и выше уже подходят). На этот случай на странице показывается понятное предупреждение вместо молчаливой пустой страницы. - **Резюме-панель увеличена (~в 1.6 раза, 300px → 480px макс.) и стала редактируемой**: поля Имя, Целевая роль, Телефон, Email, Образование — обычные ``, значения хранятся в отдельном JS-объекте `profile`, который переживает перерисовку шаблона при добавлении/удалении идей (проверено headless-тестом в Playwright — значения не теряются). Вопрос "платно или бесплатно" по самому редактированию — сознательно не решён, нужно обкатать на реальных пользователях сначала. - **Исправлена ошибка: нельзя было убрать добавленную идею.** Кнопка "Добавить в резюме" раньше навсегда переходила в состояние "Добавлено" без возможности отмены — теперь это полноценный toggle (`toggleAdded()`), работает одинаково в режиме "листай" и в рекомендациях подсказчика. В режиме "навыки под профессию" тоже поправлено: снятие галочки с навыка убирает карточку из резюме, только если ни один другой отмеченный навык больше не ссылается на ту же карточку. - **Резюме больше не показывает объясняющий `comment` дословно.** Раньше в "Что предлагаю" (компактный шаблон) и "Проектный опыт" (плотный шаблон) подставлялся текст поля `comment` — а он написан вторым лицом, объясняющим тоном ("Стратегии учат распределять ресурсы...") и адресован пользователю сайта, а не читается как то, что сам кандидат написал бы о себе рекрутеру. Заменено на `skills` — короткие профессиональные формулировки, которые уже есть в базе и звучат уместно в резюме. `comment` остался только в карточках при листании — там ему место. Полноценные авторские резюме-формулировки под каждую из 103 записей — в бэклоге как отдельная контент-задача, не сделано. - **Локальный подсказчик получил словарь синонимов/жаргона** (`SYNONYMS` в `index.html`) — около 40 записей вида "катка"/"дота"/"кс" → тег "игры", "стрим"/"твич" → тег "видео" и т.д. Это упрощённая версия изначально задуманного "этапа 2" (полноценный ручной список ключевых слов на каждую из 103 записей не сделан — это большой объём контентной работы, отложено до появления сигнала, что базового стемминга + словаря недостаточно). - **Добавлен тёплый блок-синтез черт характера** (`TRAIT_RULES` + `renderTraitSynthesis()`), показывается в режиме "Помощник-подсказчик" после выбора 2+ идей. НЕ психологический разбор в духе "глубокого" ИИ-примера (пользователь показал скриншот диалога с Google AI — там реально впечатляющая генеративная глубина, но: а) для резюме подобный текст всё равно избыточен, б) для настоящей персонализации нужен живой ИИ, не шаблоны — попытка подделать это статикой быстро начинает повторяться и терять доверие). Вместо этого — ~14 правил вида "теги → черта характера" (например `["дети","животные"] → "забота о других"`), каждое с 3 вариациями фразы для разнообразия, показывается отдельно от самого резюме (это не документ для рекрутера, это поддержка для пользователя). Проверено headless-тестом (Playwright): комбинация тегов "дети"+"животные" корректно матчит правило "забота о других". - **"О себе" и "Проектный опыт"/"Что предлагаю" стали редактируемыми полями** (textarea), а не статичным текстом. Показывают автосгенерированный черновик, пока пользователь не начнёт печатать — после первой правки поле "становится его" и не перезатирается при добавлении новых идей (проверено тестом: правка переживает даже переключение между компактным и плотным шаблоном). Есть кнопка "↺ вернуть автотекст" для отката. - **Исправлена грамматическая ошибка в "О себе"**: было "Активно интересуюсь: [название категории в именительном падеже]" — требует творительного падежа, согласование ломалось почти всегда. Вместо ручного склонения 103 категорий (риск новых ошибок, нужна морфология) формулировка переписана на "Мои интересы: [список]" — падеж вообще не нужен. - **Отклонена идея с вымышленным "научно-исследовательским институтом"** для обоснования связок навыков — это фабрикация несуществующего источника, репутационный и юридически небезопасный риск (как заявления "исследования показали" у сомнительных БАДов). Если для конкретных связок будут найдены настоящие исследования — их можно процитировать по существу, с реальным источником. Общий вывод: уверенный тон без выдуманного авторитета. - **Убрана запутанная/дублирующая подсказка в "Навыки под профессию"**: подсказка снизу ссылалась на "профессию выше", но при длинном списке ролей это легко пропустить. Верхняя подсказка (перед списком) сделана заметнее (карточка с иконкой вместо мелкого серого текста), а нижняя переформулирована без отсылки к "выше". - **Режим "Навыки под профессию" — починена навигация.** Оказалось, что база даёт 271 уникальную роль на 103 записи (роли слишком раздроблены — "Технический ассистент", "Технический ассистент в геймдев-студии" и т.д. как отдельные строки). Добавлено поле поиска над списком (фильтрует на лету) + после выбора профессии плитка сворачивается в один чип "Выбрано: Х [изменить]", результат сразу виден без скролла через десятки чипов. Отдельная задача на будущее (не сделано) — нормализовать/объединить похожие роли в самих данных, а не только чинить интерфейс сверху. - **Добавлен блок "🔬 Что говорят исследования"** — необязательное поле `research` в `ideas.json` (v3.1), пока заполнено только для 3 карточек (`reading_books`, `team_shooter`, `team_sport`), где реально существуют метаанализы/систематические обзоры. Каждая запись содержит: вывод, честную оговорку (воспроизводимость, ограничения) и реальный источник со ссылкой. Раскрывается по клику в карточке при листании, в резюме не попадает (как и `comment`). Осознанно НЕ добавлено на все 103 записи — для большинства узких связок ("квадрокоптер → пространственное мышление") просто не существует профильных исследований; добавлять туда наукообразный текст значило бы либо упрощать до неправды, либо фабриковать источник (что мы уже отклонили как отдельную идею с вымышленным институтом). - **Резюме-панель теперь масштабируется под размер экрана**, а не упирается в жёсткий потолок в пикселях. Было `minmax(320px, 480px)` — на больших мониторах колонка визуально "терялась" на фоне выросшего правого блока. Стало `minmax(320px, min(34vw, 560px))` — растёт вместе с окном, но не бесконечно (проверено тестом: 435px на экране 1280px, 560px на экране 1920px). - **Поле "Образование" было однострочным ``** — длинный текст обрезался по ширине вместо переноса. Заменено на `