Pet-проект · Anton N · 2026

AI-интервьюер собирает профиль за разговор. Затем выгружает PDF под каждую вакансию.

«Один профиль. Резюме под каждую позицию.» Подробный профиль заполняется один раз (разговором с AI-интервьюером или импортом), дальше под каждую вакансию AI собирает отдельный PDF с нужными акцентами.

обновлено 2026-06-11
01 — что это

Из чего состоит продукт

2 абзаца
продукт

DevMatch AI — приложение для подготовки профиля кандидата. Ядро ценности — профиль: он заполняется один раз и переиспользуется бесконечно — под каждую целевую роль AI генерирует отдельное PDF-резюме, сам расставляя акценты. Разговор с AI-интервьюером — механизм, который делает глубокое заполнение безболезненным.

доступ и данные

Авторизация и хранение резюме — через внешний сервис nefron-mic. У каждого пользователя один профиль; роли user/admin приходят с сервера.

02 — как работает

От разговора до PDF

11 блоков
01
Разговор
голос / текст
02
Извлечение
LLM · facts
03
Профиль
8 разделов
04
PDF под роль
ATS-friendly
aАвторизация и сессия
Вход — по логину и паролю через внешний сервис nefron-mic (метод auth.php). Пароль шифруется на сервере приложения алгоритмом AES-256-CBC и не хранится. В ответ приходит пользовательский токен и признак роли (обычный пользователь или администратор). Эти данные кладутся в подписанную httpOnly-cookie на 24 часа. Middleware проверяет сессию на каждой странице: без неё — редирект на /login. Регистрации и восстановления пароля нет — только вход.
bПрофиль пользователя
У каждого пользователя ровно один профиль (резюме). Он привязан к пользователю по сессии: какой профиль показывать и куда писать — сервер определяет сам из токена, клиент не может открыть чужой профиль. После входа резюме подтягивается с сервера nefron (getresume) и сравнивается с локальной копией: источником правды становится та версия, в которой больше заполненных полей (в норме они одинаковы — это защита от потери данных; если локальная богаче, она остаётся и целиком отправляется на сервер). Профиль хранится файлом на сервере приложения. Правки сохраняются сами: кнопки «Сохранить» нет — через короткую паузу после ввода поле автоматически сохраняется, а рядом с его заголовком коротко загорается отметка «Сохранено». Профиль можно держать открытым сразу в нескольких вкладках (побеждает последнее сохранение).
cAI-интервьюер (двухпроходный агент)
Диалог с кандидатом обрабатывают два прохода одной модели. Проход 1 (извлечение): из последних реплик модель вызывает инструменты записи и заполняет поля профиля — это единственное место, где данные пишутся в профиль. Идёт сверху вниз по карте приоритетов заполнения. Проход 2 (разговор): только чтение — модель отвечает пользователю и подтверждает строго то, что реально записал первый проход. Есть голосовой ввод (через отдельный WS-relay к OpenAI Realtime, ключ не уходит в браузер).
dХранение переписок (чатов)
История чата хранится рядом с профилем, в отдельном файле <пользователь>.chat.json в формате { messages, costUsd }. Каждое сообщение — это { id, роль (user/assistant), текст, время, токены }. Токены проставляются на сообщении ассистента (расход за ход), накопленная стоимость диалога — на весь чат. Переписки лежат локально на сервере приложения, а не на сервере nefron.
eИмпорт резюме (PDF / DOCX → профиль)
Загруженный файл сначала превращается в текст (unpdf для PDF, mammoth для DOCX). Затем модель за одну генерацию возвращает структурированный объект резюме (structured output — быстрее, чем десятки последовательных вызовов инструментов). Этот объект НЕдеструктивно мерджится в профиль: карточки (опыт, проекты, образование) сопоставляются по идентификатору и дополняются, а не затираются и не удаляются.
fЭкспорт PDF под роль (двухпроходный: составитель + рецензент)
Резюме собирается под выбранную целевую роль с учётом ожиданий и стоп-листа: модуль compose-resume формирует содержимое, заточенное под эту роль. Структура опыта — по каждому месту работы 3–5 конкретных тезисов плюс кейсы, привязанные к этому месту; шаблонные фразы («управлял полным циклом», «руководил кросс-функциональной командой» без конкретики) запрещены промптом; саммари опирается на авторское «О себе», если оно заполнено. После генерации черновик проходит через второго агента-рецензента: он проверяет соответствие роли, вычищает шаблонность и всё, чего нет в профиле, и возвращает исправленный документ (если рецензент упал — уходит черновик). Затем рендер в PDF (@react-pdf/renderer), шрифт Carlito — корректная кириллица и чистый текстовый слой (копипаст и ATS). Доступ к экспорту — не по абстрактному проценту, а по чек-листу минимума: имя, целевая роль, одно место работы (компания + должность), навыки. Пока минимум не набран, кнопка показывает прогресс («PDF · 46%»), а поповер — конкретный список недостающего с кнопками «спросить в чате». После минимума экспорт разрешён (черновое резюме — само по себе мотиватор дозаполнить), с порога «Хорошее резюме» — полный режим.
gСинхронизация резюме с сервером
Каждое изменение — руками или через AI — мгновенно сохраняется локально, а на сервер nefron (saveresume) резюме уходит ЦЕЛИКОМ с разумным гэпом: через 5 секунд после последнего изменения, но не позже 15 секунд с первой несинхронизированной правки (непрерывный поток правок не откладывает отправку бесконечно). Так сервер не бомбардируется запросом на каждый символ. При сбое данные не теряются — отправка повторяется автоматически, а в шапке появляется «сервер недоступен · повторяем». Вместе с резюме едет накопленная стоимость всех AI-запросов пользователя — в поле overview.cost (число); при входе она подтягивается обратно, чтобы счётчик продолжался. Серверный баг с пустыми списками устранён — проверено вживую (пустой список сохраняется без падения, стоимость записывается и читается).
hРоли и админ-функции
Роль (обычный пользователь / администратор) приходит с сервера при входе. Администраторам доступны: настройки, накопленная стоимость запросов (бейдж в нижнем баре + сумма в шапке чата) и кнопка «Скачать все чаты» (выгрузка всех переписок в один CSV-файл с UTF-8 BOM для Excel). Стоимость — приватная метрика: обычным пользователям она не видна вообще, и сервер дополнительно проверяет права — скрытием в интерфейсе защита не ограничивается.
iОнбординг и обучающий тур (короче до продукта)
При первом входе пользователь видит два знакомящих экрана подряд, оба сокращены до минимума (~60–90 секунд + ~30 секунд). Кинопоказ-онбординг — 3 сцены в порядке иерархии ценности: «один профиль → резюме под любую роль» (зачем), «просто общайся» (как), и финальное мини-интервью «попробуй сам», где пользователь называет имя, роль и опыт — эти ответы сразу сохраняются в реальный профиль. Затем обучающий тур из 4 шагов (разделы, чат с упоминанием голоса, экспорт с честным текстом про минимум, автосохранение) — на десктопе; на телефоне после онбординга сразу редактор. Интервью в чате стартует только ПОСЛЕ онбординга и записи собранного — агент продолжает с четвёртого вопроса, а не здоровается заново. Если профиль почти пуст, вместо автостарта чат один раз предлагает развилку: «есть старое резюме? загрузить PDF/DOCX — или просто начнём разговор». Каждый экран показывается ровно один раз; в настройках есть кнопка «Пройти знакомство заново».
jВзвешенный прогресс, стадии и «Следующий шаг»
Процент заполнения считается по весам важности полей (та же карта приоритетов, по которой идёт интервьюер): название компании двигает прогресс сильнее, чем ссылка на диплом, — первые содержательные ответы дают видимый рост. Поверх процента — три именованные стадии: «Минимум для резюме» (~40%, открывает экспорт), «Хорошее резюме» (~65%) и «Сильное резюме» (~85%, зелёное кольцо на кнопке PDF); пересечение стадии отмечается тостом. В сайдбаре под прогресс-баром живёт виджет «Дальше»: одна конкретная подсказка, что заполнить следующим, — клик открывает раздел и отправляет вопрос в чат. На телефоне та же подсказка — строкой над рельсой разделов.
kEvent-лог для фокус-группы
Минимальная продуктовая телеметрия без внешних SDK: события воронки (вход, онбординг пройден/пропущен, тур, первое сообщение, импорт, чекпоинты заполненности, клик по закрытому экспорту, скачивание PDF с ролью и стадией, длительность сессии) пишутся в файл рядом с профилем пользователя. Администратор выгружает весь лог одной кнопкой в меню-аватаре — по нему считается воронка «вошёл → первое сообщение → минимум → скачал PDF».
03 — статус

Что готово, что ограничено

обновлено 2026-06-11
готовоГотово
  • Выкатано в прод (весь nefron-стек, проверено вживую)

  • Реальная авторизация через nefron (AES-256-CBC)

  • Профили на пользователя + гидрация резюме при логине

  • Роли user/admin

  • Синхронизация всего резюме + стоимость на сервер — проверено вживую

    Резюме целиком (все секции: контакты, роли, навыки, опыт, проекты, образование, ожидания + накопленная стоимость в overview.cost) отправляется на сервер пакетом с гэпом (5с после последнего изменения, ретраи при сбое) и подтягивается обратно при входе. Проверено на проде: полный round-trip без потерь. Пол кодируется в 1 символ под серверную колонку.

  • Накопленная стоимость запросов — только админу (бейдж в баре + сумма в чате)

  • Экспорт всех чатов в CSV (только админ)

  • Трекинг токенов по сообщениям

  • Кинопоказ-онбординг (заполняет профиль из ответов) + обучающий тур (по разу, галочки в настройках)

  • Автосохранение полей без кнопки «Сохранить» + отметка «Сохранено» у поля

  • Единый формат дат (ДД.ММ.ГГГГ в UI, ISO на сервер) + аккуратный выбор в календаре

  • Загрузка резюме и экспорт PDF вынесены в шапку

  • Редактирование профиля в нескольких вкладках (блокировка убрана, last-write-wins)

  • Карточки категорий показывают полный текст (перенос, без обрезки)

  • Публичный лендинг на «/» для гостей + обогащённая страница входа

    Незалогиненный гость на «/» видит лендинг (демо «разговор → поля заполняются», «один профиль → резюме под роль», призыв попробовать); залогиненный — сразу редактор. Страница входа: фактура, ценности, показ/скрытие пароля. Навигация между «/», /about и /login замкнута в обе стороны.

  • Полноценная мобильная версия редактора

    На экранах уже 1024px редактор перестраивается: вместо сайдбара — горизонтальная рельса разделов с кольцами прогресса, чат с AI-интервьюером открывается снизу выезжающим листом по кнопке в нижнем баре. Пока агент пишет в профиль, лист сам сжимается в полоску — «магия» заполнения полей видна и на телефоне. Лендинг, вход, /about и онбординг тоже адаптированы; раскладка на 390px проверяется автоматически (layout-чекер).

  • Плавная анимация записи агентом (без «дёрганья»)

    Подсветка раздела и поля при записи AI теперь включается и гаснет плавно (мягкий вход свечения, эластичные переходы между фазами), смена раздела — спокойный кроссфейд, автоподстройка высоты текстовых полей больше не «резинит» при печати.

  • Синхронизация: локально сразу, на сервер — с гэпом, при входе побеждает полная версия

    Каждая правка мгновенно сохраняется локально (в шапке — «сохранено»), а на сервер nefron резюме уходит целиком пакетом: через 5 секунд после последнего изменения, максимум через 15 секунд непрерывной активности — сервер не бомбардируется запросом на каждое поле. Если отправка падает, в шапке появляется «сервер недоступен · повторяем» и отправка ретраится до успеха; ошибки логируются. При входе локальная и серверная версии сравниваются по количеству заполненных полей — источником правды становится более полная (в норме они одинаковы; это защита от потери данных: если сервер отдал огрызок, локальная копия не затирается, а отправляется на сервер). Версии резюме хранит сервер — локальных бэкапов нет. Корректность закреплена тестами (пустой, частичный, полный профиль, мусорные значения, потолок отправки) и живым round-trip на реальном сервере.

  • Фото профиля: загрузка, круговой кроп, локальное хранение

    В «Общих сведениях» вместо текстовой ссылки на фото — настоящая загрузка: кликом или перетаскиванием файла (JPEG/PNG/WebP). Фото ужимается до 1280px по длинной стороне ещё в браузере, затем пользователь выбирает в круге нужную область (двигает и приближает). На сервере приложения хранится необрезанный оригинал под уникальным именем (UUID), привязанный к пользователю; в интерфейсе показывается выбранный круг. Область круга можно поменять в любой момент без повторной загрузки файла. На сервер nefron фото не отправляется.

  • Компактные карточки полей: два состояния и поля по два в ряд

    Короткие поля (пол, дата рождения, город, гражданство, уровень, зарплата и т.п.) больше не растягиваются на всю ширину карточки — они идут парами в ряд. Карточки разделов с несколькими записями (места работы, проекты, образование) получили два состояния: свёрнутая — одна строка со сводкой (например, «Компания · Должность» и счётчик заполненности) без полей ввода, развёрнутая — привычные поля. Заполненные карточки по умолчанию свёрнуты (три места работы — три строки вместо трёх экранов), новые пустые открыты, а когда AI пишет в свёрнутую карточку — она раскрывается сама, чтобы запись была видна.

  • Связи между карточками — настоящий пикер

    Поле «Кейсы» в «Рабочем опыте» и «Методах и инструментах» теперь привязывает существующие карточки раздела «Проекты и кейсы» через выпадающий список с галочками (раньше было текстовое поле с подсказкой, которая на телефонах не работала). Ссылка на переименованную/удалённую карточку подсвечивается жёлтым. На сервер связи уходят прежним форматом — списком названий.

  • Новое позиционирование: «Один профиль. Резюме под каждую позицию.»

    По плану продакт-менеджера (демо для фокус-группы): hero лендинга продаёт актив (профиль) и результат (резюме под позицию), а не механизм («поговори с AI»); секция «1 профиль → 3 резюме» поднята сразу под hero с болевым заголовком «Хватит переписывать резюме под каждую вакансию» и контр-аргументом к «а я просто попрошу ChatGPT»; тексты STATS, карточки «Под вакансию» и финального CTA переписаны честно; кикер логина повторяет слоган.

  • Гейт экспорта: чек-лист вместо «заполните на 80%»

    Вместо абстрактного процента — конкретный минимум: имя, целевая роль, место работы (компания + должность), навыки. Закрытая кнопка показывает прогресс («PDF · 46%»), поповер — чек-лист недостающего, каждый пункт кликабелен («спросить в чате» — открывает раздел и кидает вопрос агенту). После минимума экспорт разрешён с честной подсказкой, что добавить; с «Хорошего резюме» — полный режим.

  • Взвешенная полнота + стадии + виджет «Следующий шаг»

    Процент — по весам fill-priority (важные поля двигают сильнее), стадии «Минимум/Хорошее/Сильное» с тостами на пересечении, в сайдбаре и на мобильной рельсе — одна детерминированная подсказка «Дальше: …» с кнопкой «спросить в чате».

  • Онбординг 5→3 сцены, тур 7→4 шага, развилка «импорт или разговор»

    Кино сокращено до «результат → общайся → попробуй сам» (~90 секунд), тур — до 4 шагов с честным текстом про экспорт. Починена гонка: интервью стартует только после записи собранного онбордингом (агент не переспрашивает имя/роль). Пустому профилю чат один раз предлагает загрузить старое резюме вместо разговора — самый быстрый путь к ценности.

  • Резюме: тезисы + кейсы по местам работы + агент-рецензент

    Промпт экспорта требует по каждому месту работы 3–5 конкретных тезисов и привязанные кейсы из «Проектов»; шаблонные фразы запрещены; саммари — из авторского «О себе». После генерации — второй проход агента-рецензента (соответствие роли, шаблонность, выдумки) с возвратом исправленного документа.

  • Event-лог воронки (для фокус-группы) + админ-выгрузка

    События login / onboarding / tour / first_message / import / fill_percent-чекпоинты / export_locked_click / export_done / session_end пишутся в сайдкар рядом с профилем; админ скачивает общий JSON одной кнопкой. Внешних аналитик-SDK нет.

ограничениеОграничения на стороне сервера nefron
  • HTTPS: истёкший TLS-сертификат

    TLS-сертификат nefron-mic истёк (+ не загружен pdo_mysql) — работаем по http (server-to-server, на работу приложения не влияет). Нужен новый сертификат на стороне nefron.

  • saveresume падает целиком из-за одного «неподходящего» поля (robustness)

    Если поле не лезет в колонку БД, весь запрос падает PHP-фаталом и не сохраняется ничего. Наши известные триггеры устранены (пустой массив — пофикшен на сервере; gender — кодируем в 1 символ у нас). Остаётся пожелание серверу: не ронять весь save из-за одного поля. Отчёт: docs/nefron-save-robustness-report.md.

27
пунктов готово
8
разделов профиля
2
ограничения сервера
2026-06-11
обновлено