Nikita Malyshenko's notes
73 subscribers
302 photos
7 videos
50 links
Frontend Developer
Download Telegram
Я больше любитель дождливой погоды, но сейчас на улице действительно хорошо✍️

Солнечно, но не жарко, ветерок помогает🍀
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
32
Отключение электроэнергии - прекрасная возможность пощипать травку во дворе, пока нет возможности взять косилку

Какая никакая физическая нагрузка, переключение от нехороших мыслей, более аккуратный двор, свежий воздух, отдых от всей электроники
Одни плюсы🍀
Please open Telegram to view this post
VIEW IN TELEGRAM
22
Немного Ангары и милых уток
32
Йо, я всё ещё в поисках job. 6,5 месяцев карл..
Если у вас есть что-то для меня и это ещё не делает ии, буду благодарен
26-ой год запомнится, как год поисков работы и больше ничего🤕
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Начал писать новый pet проект. Кодовое название Fruit-Store (угадайте техника какого производителя там будет)🙂

Fullstack интернет-магазин. На фронт возьму Next, на бэк Go
Посмотрим, что из этого получится

В промежуточных моментах буду показывать

Начал с бэка
Сделал самый базовый скелет проекта:
1. Docker-compose, чтобы базу поднять
2. Миграции для создания таблиц
3. Накидал архитектуру
4. Пару эндпоинтов для продуктов и категорий

Будем дальше посмотреть🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
5
🆕Продолжаю делать Fruit Store 🍎

На этом этапе подключил фронт на Next.js к API.
Что сейчас есть:
- Каталог товаров
- Страница отдельного товара
- Навигация по категориям
- Перешел с обычных колонок на JSONB для хранения атрибутов товара
- Добавил GIN-индекс для JSONB
- Появились варианты товара (например, разные цвета/объем памяти) со своими остатками
- Немного пересмотрел структуру категорий и решил отказаться от вложенности, а модели и серии хранить как атрибуты

Самое интересное, что часть этого изначально вообще не планировалась. Я специально по ходу разработки меняю себе ТЗ, чтобы проект развивался не по идеальному сценарию, а как это обычно бывает в работе.

По ощущениям так намного интереснее, чем пытаться сразу придумать "идеальную" архитектуру.

Дальше планирую заняться фильтрацией, поиском и ещё множеством других фич, о которых будет позже. 🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
71
Во-первых, спасибо за актив на последних постах, это дает знак, что смысл в них есть

🆕Продолжаю делать Fruit Store 🍎

За это время больше поработал над самим каталогом и немного подтянул инфраструктуру проекта.

Что сейчас появилось:
- Настроил структурированное логирование через slog в JSON-формате
- Написал первые unit-тесты (табличные тесты на валидацию параметров)
- Разделил страницы: теперь у каждой категории свой URL, а главная стала хабом с категориями
- Вынес Header в отдельный переиспользуемый виджет
- Добавил сортировку товаров (по цене и новизне)
- Сделал фильтрацию по атрибутам (цвет, память и т.д.) через JSONB
- Добавил отдельный эндпоинт, который сам отдает доступные фильтры для выбранной категории (без хардкода на фронте)
- Переделал каталог: теперь каждая вариация товара отображается отдельной карточкой

Из интересного - сначала думал оставить одну карточку на товар, но в какой-то момент понял, что такой подход начинает мешать. В итоге переделал каталог так, чтобы каждая конфигурация была отдельной карточкой. Это намного ближе к тому, как работают интернет-магазины.

Дальше планирую подключить фильтры на фронте, сделать мультивыбор в фильтрах, добавить остальные специфичные фильтры по категориям, добавить пагинацию. Пока план такой, идем дальше.🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
7
🆕Продолжаю делать Fruit Store 🍎

На этом этапе полностью закрыл фильтрацию и пагинацию каталога.
Что нового:
- Добавил категориальные фильтры для всех трёх категорий: цвет, серия, память, чип, RAM, тип дисплея
- Добавил числовые фильтры: цена и диагональ экрана (запрос уходит по debounce)
- Добавил мультивыбор значений внутри одного фильтра
- Собрал конфигурацию фильтров по категориям - для iPhone, Mac и Watch отображаются свои наборы атрибутов без дублирования логики
- Реализовал пагинацию с сохранением выбранных фильтров при переключении страниц. Тут решил не делать InfiniteScroll
- Добавил loading-скелетон во время загрузки следующей страницы
- Связал карточки товаров в каталоге с детальными страницами
- Детальная страница теперь отображает характеристики в зависимости от категории товара

Набор доступных характеристик отличается у разных категорий, но не хотелось делать отдельную логику под каждую из них. В итоге собрал конфигурацию, на основе которой фронт понимает, какие фильтры и значения нужно показать.

Дальше по плану - корзина:
привязка к сессии без авторизации (пока что, после корзины сделаю авторизацию);
пересчёт суммы корзины на бэкенде;
проверка доступного остатка;
базовый скелет страницы корзины.

Пока план такой, идём дальше 🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
41
🆕 В Fruit Store появилась корзина 🍎

На данный момент закончил работу над корзиной.

Что нового:
- Реализовал корзину для неавторизованных пользователей через гостевую сессию и httpOnly cookie
- Проверка остатка на складе и пересчёт суммы корзины происходят на бэкенде
- Подключил TanStack Query: корзина, счётчик в Header и страница корзины синхронизированы между собой без перезагрузки
- Настроил CORS с поддержкой credentials для запросов между фронтом и бэком
- Добавил оптимистичные обновления: изменение количества и удаление товара происходят сразу, а при ошибке сервера состояние откатывается
- По пути нашёл и поправил пару багов

Корзина самый насыщенный функциональный блок на текущий момент. Состояние нужно синхронизировать сразу в нескольких местах интерфейса (счётчик в хедере, страница корзины), и сама корзина при этом должна оставаться источником истины на бэкенде, а не жить только на фронте. TanStack Query сюда хорошо вписался.

По плану - авторизация.
Начну со входа по email и коду, возможно ещё magic link, а дальше уже буду развивать эту часть.
Идём дальше 🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
5
🆕 В Fruit Store появилась авторизация 🍎

Перешёл к авторизации.

Что нового:
- Реализовал вход через email и одноразовый код с реальной отправкой писем через Resend
- Для хранения кодов подключил Redis с TTL. Впервые понадобился Redis, закрыл сразу две задачи: хранение кодов и rate limiting для повторных запросов
- JWT хранится в httpOnly cookie, а middleware опционально извлекает пользователя из токена, не блокируя запросы для гостей
- Гостевая корзина (сессия) автоматически привязывается к аккаунту при первом входе
- Собрал скелет формы логина на фронте: email → одноразовый код, с валидацией через Zod и React Hook Form

С авторизацией продумал не только сам процесс входа, но и то, что происходит с данными гостя после авторизации.
Гостевая корзина автоматически привязывается к аккаунту при первом входе. Следующим шагом нужно будет разобраться со слиянием корзин, если пользователь добавлял товары с разных устройств.

Дальше по плану - добавить профиль пользователя, реализовать слияние корзин при входе с разных устройств, перейти с одного долгоживущего JWT на связку access/refresh токенов, а затем заняться OAuth через Яндекс.

Идём дальше 🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
5
🆕В Fruit Store появились профиль и OAuth 🍎

Продолжил заниматься авторизацией.
Что нового:
- Собрал простой профиль пользователя (email + выход) с защищённым доступом
- Реализовал слияние корзин при входе с разных устройств через транзакции - если гость успел накидать товаров и на телефоне, и на компьютере, при логине всё объединяется в одну корзину
- Перешёл с одного долгоживущего JWT на связку access/refresh токенов: короткоживущий access для запросов, refresh для его обновления, авторизация теперь переживает разлогинивание по времени без повторного ввода кода
- Настроил автоматическое обновление токена на фронте - если сессия протухла, приложение само подтягивает новый access и повторяет запрос, без разрыва для пользователя
- Добавил вход через Яндекс OAuth - вторым способом попасть в ту же систему токенов, без дублирования логики

Больше всего времени ушло на слияние корзин. Хотелось, чтобы пользователь не терял товары, если успел что-то добавить с разных устройств до входа в аккаунт.

По плану дальше - заказы: хочу сделать оформление доступным без обязательной авторизации, добавить подтверждение заказа на почту и страницу отслеживания для гостей, а для авторизованных пользователей - историю заказов в профиле. Оплату подключу уже после этого.

Идём дальше 🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
4
🆕 В Fruit Store появились заказы и оплата 🍎

Добрался до оформления заказов.
Что нового:
- Реализовал оформление заказов без обязательной авторизации
- Добавил транзакционное создание заказа с блокировкой строк (FOR UPDATE) и списанием остатка
- Подключил Stripe: сначала создаётся PaymentIntent, а сам заказ появляется только после успешной оплаты через вебхук
- Сделал вебхук идемпотентным - повторная доставка одного и того же события больше не создаёт дубликаты заказов
- Проверил конкурентный доступ: если два пользователя одновременно пытаются купить последнюю единицу товара, заказ оформит только один
- Собрал чекаут на фронте через Stripe Elements и полностью прошёл сценарий оплаты тестовой картой
- После успешной оплаты автоматически отправляется письмо с номером заказа

Пока делал оплату, пришлось немного пересмотреть первоначальный план. Сначала хотел создавать заказ сразу, а оплату делать отдельным шагом, но после проверки сценария с последним товаром на складе стало понятно, что логичнее создавать заказ только после подтверждённой оплаты.
Так не приходится резервировать остатки заранее и меньше шансов получить неконсистентное состояние.

Дальше по плану - личный кабинет: история заказов и профиль на отдельных вкладках, а также страница отслеживания заказа по номеру и email для гостей.
Идём дальше 🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
3
🆕 В Fruit Store появился личный кабинет и поиск 🍎

Закрыл ещё несколько частей пользовательской части проекта.
Что нового:
- Собрал личный кабинет: профиль и история заказов на отдельных вкладках с навигацией через URL
- Сделал страницу отслеживания заказа по номеру и email для гостей без авторизации
- Добавил поиск по каталогу: инпут в Header с debounce и выпадающей панелью результатов прямо под ним
Пока поиск работает на ILIKE, полноценный full-text search и кэширование каталога оставил как следующие этапы развития после деплоя

Страница отслеживания заказа - интересная задача. Хотелось оставить её доступной без авторизации, но при этом не дать возможности подобрать чужой заказ. Поэтому поиск работает только по двум параметрам сразу - номеру заказа и email.

С поиском тоже решил пока не усложнять. Для текущего объёма данных ILIKE более чем хватает.

Дальше по плану: перехожу к дизайну, анимациям, доработкам функционала - предстоит перевёрстать все страницы под референс и заодно закрыть накопившийся по ходу проекта список мелких доработок (свотчи цветов, тосты, замена нативных элементов на shadcn/ui и другое), так что финальный объём этой фазы будет проясняться по ходу работы.
Идём дальше 🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
6
С понедельника (10 августа) захожу на тренинг Миши Ларченко

Что будет:
1. Созвоны с Мишей 2 раза в неделю, разбирать код. Так же будет закреплен человек, который будет замечать слабые места и помогать скорректировать наплавление

2. Всех разобьют на команды по 7-8 человек сбалансировав по опыту

3. Командный Fullstack проект. Тут будет всё - спринты, планирование, код-ревью, ретро, финальная защита
Роли будут чередоваться, чтобы понимать все процессы

4. AI-Driven development. О том, как использовать ИИ на всем цикле разработки

5. Карьерная упаковка. Разбор резюме, гитхаба, линкедина, System Design, собеседования, ревью
5
🍎 В Fruit Store - тёмная тема, shadcn/ui и новый дизайн главной 🍎

Веду работу над визуальной частью и доработками проекта.
Что нового:
- Настроил тёмную и светлую тему через next-themes, с переключателем в хедере и плавным переходом цвета при смене
- Перешёл на shadcn/ui: кастомизировал Button, Input, Card, Carousel, Skeleton под свою палитру вместо самописных компонентов
- Полностью переверстал Header - логотип, поиск с картинками товаров и скелетон-состоянием загрузки, авторизация, корзина с бейджем количества
- Собрал главную страницу: hero-секция, сетка из 5 категорий (добавил iPad и AirPods) с ценой "от", и карусель "Новинки" с карточками товаров, стрелками и дотсами
- Добавил изображения категорий и товаров через Cloudflare R2, с оптимизацией через next/image

Из бэкенда и архитектуры:
- Переделал хранение изображений товаров: перешёл с одного поля image_url на отдельную таблицу product_variant_images - несколько фото на вариант, с порядком отображения
- Добавил GET /categories/:slug вместо того, чтобы тянуть на фронте весь список категорий ради одной
- Добавил вычисляемую min_price для каждой категории через агрегатный запрос
- Объединил три разрозненных конфига категорийных атрибутов (для фильтров, для карточек, для детальной страницы) в один источник правды
- Настроил Prettier для единообразного форматирования кода

Дальше по плану: довести дизайн каталога и детальной страницы товара до того же уровня, что и главная, а потом - личный кабинет и остальные пользовательские страницы.
Летим дальше 🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Я тут приболел в конце лета, поэтому пока просадка по постам
Не болейте🍀
Please open Telegram to view this post
VIEW IN TELEGRAM
🍎 В Fruit Store - готовы каталог и карточка товара 🍎

Продолжаю доводить дизайн до конца.

Что нового:
• Собрал каталог категорий: карточки товаров, сортировка через shadcn Select с кастомной анимацией, пагинация
• Реализовал полный набор фильтров - диапазон цены со Slider'ом, чекбоксы для атрибутов, цветные свотчи с реальными HEX-значениями с бэка, все с плавным сворачиванием/разворачиванием
• Адаптировал фильтры под мобильные - на десктопе сайдбар всегда виден, на узких экранах прячутся за кнопкой и выезжают снизу через Sheet
• Переделал детальную страницу товара с нуля: галерея с каруселью и миниатюрами, переключение параметров через URL (без клиентского состояния - можно поделиться прямой ссылкой на конкретный вариант)
• Продумал и реализовал состояния для недоступных комбинаций атрибутов - если сочетания атрибутов не существует, кнопка выбора неактивна; если товар просто раскуплен, выбрать его можно, но кнопка покупки будет - "Нет в наличии"
•Добавил iPad и AirPods в конфигурацию фильтров и переключателей вариантов, с нужными атрибутами под каждую категорию

Больше всего времени ушло на разбор UX для раскупленных товаров - на бумаге кажется мелочью, но даже крупные площадки используют разные подходы.

Дальше по плану: личный кабинет, корзина и чекаут - последние страницы, которым нужен тот же уровень дизайна, а после них перехожу к деплою.
Летим дальше 🧩
Please open Telegram to view this post
VIEW IN TELEGRAM
3