Марсель Абазбеков

Full Stack разработчик

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 закончил бакалавриат по программе «Программная инженерия» в НГТУ.

Навыки

Frontend

JavaScript, TypeScript, Electron, React, Next.js, Vite, Tailwind, Styled Components, SCSS, Redux, Effector, PWA, SSG

Backend

JavaScript, TypeScript, Node.js, Express.js, Nest.js, SQL, Prisma, PostgreSQL, Redis, BullMQ, Go, Gin, Gorm, REST API, GraphQL, SSE

Общие навыки

Git, Linux, Nginx, Docker, Ansible, GitLab CI, etc.

Другие технологии

C, C++, Java, Hibernate, JavaFX, Android apps on Android SDK, Python, Selenium, FastAPI, Vue

Cloud Saves

Дипломный проект. Приложение, которое позволяет сканировать компьютер пользователя на наличие файлов игровых сохранений и выгружать их на сервер. Умеет извлекать из файлов некоторых игр параметры прохождения (пол персонажа, время в игре, уровни навыков и т.д.)

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.