Fullstack-разработчик с опытом работы на TypeScript (Nest.js, Express, Prisma) и Go для бэкенда, включая работу с PostgreSQL, Redis, BullMQ и чистым SQL. Также разрабатывал небольшие сервисы на Python с FastAPI. На фронтенде использую React, Next.js, Electron и Effector вместе с сопутствующими технологиями.
Успешно применяю Git для организации рабочего процесса и контроля версий. Имею опыт работы с инструментами непрерывной интеграции и развертывания (CI/CD) GitHub Actions, GitLab CI.
Также иногда вношу вклад в open-source проекты, которыми пользуюсь.
Хочу развиваться в направлениях бэкенд- и фронтенд-разработки. Открыт к изучению новых языков программирования, платформ и технологий.
В 2024 закончил бакалавриат по программе «Программная инженерия» в НГТУ.
Дипломный проект. Приложение, которое позволяет сканировать компьютер пользователя на наличие файлов игровых сохранений и выгружать их на сервер. Умеет извлекать из файлов некоторых игр параметры прохождения (пол персонажа, время в игре, уровни навыков и т.д.)
TypeScript Node.js Electron React React Query react-i18next
Steam и GOG синхронизируют сейвы только своих игр. Cloud Saves — десктопное приложение, которое резервирует сейвы любых игр на сервере и вытаскивает из файлов параметры прохождения — например, пол персонажа, время в игре, уровни навыков. Серверную часть с REST API написал одногруппник, репозиторий — GameSavesStore.
Приложение написано на Electron: процесс на Node.js сканирует файловую систему, парсит сейвы и синхронизирует их с сервером, а интерфейс на React работает в отдельном Chromium-окне и обменивается данными с этим процессом через IPC.
Самая нетривиальная часть парсинга — разные форматы сейвов у разных игр: Unreal Engine хранит состояние в бинарных .sav-файлах, иногда сжатых zlib, другие игры — в текстовых файлах с параметрами вида «ключ: значение». Конвертеры приводят оба формата к JSON — .sav распаковывается и разбирается утилитой uesave, текстовый разбирается построчно. Из JSON значения читаются по ключам, включая вложенные поля и индексы массивов, а одинаковые по смыслу параметры разных игр сводятся к общим типам.
За автосинхронизацию отвечает SyncManager — модуль Node-процесса. Он выгружает сейвы по заданному периоду и скачивает серверную версию, если она новее. Перед отправкой сейв копируется во временную папку и архивируется, поэтому файлы игры остаются нетронутыми. Работая в фоне из трея, приложение продолжает синхронизацию даже при закрытом окне.
Интерфейс поддерживает русский и английский, светлую и тёмную тему.
Регистрация
Форма создания учетной записи: имя пользователя, email, пароль с подтверждением, и ссылка на вход для тех, у кого уже есть аккаунт.
Вход
Форма входа с логином и паролем, ссылкой на восстановление и переключателями языка и темы.
Профиль
Страница профиля: имя пользователя и email, форма смены пароля.
Сейвы
Сейвы доступны на нескольких страницах: «Мои сохранения» — свои сейвы на сервере, «Общие сохранения» — чужие сейвы, доступ к которым владелец дал лично тебе, «Публичные сохранения» — сейвы, открытые для всех пользователей. Локальные сейвы, найденные на диске, видны отдельно внутри «Моих сохранений» — оттуда их можно выгрузить на сервер. Везде есть поиск по названию, на публичных — ещё и фильтр по игре.
Страница сейва
На странице сейва доступны ручная выгрузка и удаление, настройка периода автосинхронизации и уровня доступа — только себе, выбранным людям или всем.
Игры
Поддержку новой игры настраивает администратор: маски путей — с подстановкой домашней папки — и схема конвертации: исходный файл, тип конвертера, выходной JSON, ключ чтения каждого параметра.
Общие параметры
Один и тот же по смыслу параметр в разных играх может называться по-своему. Чтобы это не мешало анализу, администратор группирует такие параметры под общим именем — например, «время в игре». Значения по общему параметру собираются со всех сейвов, где он есть.
Дашборд
Дашборд собирает все графики в одном месте — можно открыть любой, добавить новый или отредактировать существующий.
Графики
Гистограмма или круговая диаграмма строится по всем сейвам, у которых есть значение выбранного общего параметра, независимо от игры — например, распределение времени в игре сразу по всем сохранённым состояниям разных игр. Администратор строит такие графики по любому общему параметру.
Пользователи
На странице «Пользователи» у администратора есть возможность поиска по пользователям и блокировки/разблокировки пользователей, нарушающих правила сервиса — заблокированный теряет доступ в приложение и к своим сейвам, разблокировка возвращает доступ обратно.
Релизы
Коммиты оформляются по стандарту Conventional Commits — с префиксом вида feat/fix/docs, коротким описанием и деталями после пустой строки, — а commitlint через git-хук проверяет это перед каждым коммитом. Разработка ведётся в ветке dev или отдельных ветках под конкретную функциональность, готовые изменения вливаются в master. При пуше в master GitHub Actions запускает semantic-release: он прогоняет тесты и, если они прошли, разбирает историю коммитов, поднимает версию проекта по SemVer и добавляет коммит с новой версией. После этого GitHub Actions собирает приложение и публикует архив с исполняемым файлом и установщик во вкладке Release.