Disguised Runner v.1.0.0 New Patch
- Вынес загрузку текстур и добавил простенький loader, который отображается пока текстуры загружаются + 1 секунда delay
Link на апку
- Вынес загрузку текстур и добавил простенький loader, который отображается пока текстуры загружаются + 1 секунда delay
Link на апку
Я больше любитель дождливой погоды, но сейчас на улице действительно хорошо✍️
Солнечно, но не жарко, ветерок помогает🍀
Солнечно, но не жарко, ветерок помогает
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Отключение электроэнергии - прекрасная возможность пощипать травку во дворе, пока нет возможности взять косилку
Какая никакая физическая нагрузка, переключение от нехороших мыслей, более аккуратный двор, свежий воздух, отдых от всей электроники
Одни плюсы🍀
Какая никакая физическая нагрузка, переключение от нехороших мыслей, более аккуратный двор, свежий воздух, отдых от всей электроники
Одни плюсы
Please open Telegram to view this post
VIEW IN TELEGRAM
Йо, я всё ещё в поисках job. 6,5 месяцев карл..
Если у вас есть что-то для меня и это ещё не делает ии, буду благодарен
26-ой год запомнится, как год поисков работы и больше ничего🤕
Если у вас есть что-то для меня и это ещё не делает ии, буду благодарен
26-ой год запомнится, как год поисков работы и больше ничего
Please open Telegram to view this post
VIEW IN TELEGRAM
Начал писать новый pet проект. Кодовое название Fruit-Store (угадайте техника какого производителя там будет)🙂
Fullstack интернет-магазин. На фронт возьму Next, на бэк Go
Посмотрим, что из этого получится
В промежуточных моментах буду показывать
Начал с бэка
Сделал самый базовый скелет проекта:
1. Docker-compose, чтобы базу поднять
2. Миграции для создания таблиц
3. Накидал архитектуру
4. Пару эндпоинтов для продуктов и категорий
Будем дальше посмотреть🧩
Fullstack интернет-магазин. На фронт возьму Next, на бэк Go
Посмотрим, что из этого получится
В промежуточных моментах буду показывать
Начал с бэка
Сделал самый базовый скелет проекта:
1. Docker-compose, чтобы базу поднять
2. Миграции для создания таблиц
3. Накидал архитектуру
4. Пару эндпоинтов для продуктов и категорий
Будем дальше посмотреть
Please open Telegram to view this post
VIEW IN TELEGRAM
На этом этапе подключил фронт на Next.js к API.
Что сейчас есть:
- Каталог товаров
- Страница отдельного товара
- Навигация по категориям
- Перешел с обычных колонок на JSONB для хранения атрибутов товара
- Добавил GIN-индекс для JSONB
- Появились варианты товара (например, разные цвета/объем памяти) со своими остатками
- Немного пересмотрел структуру категорий и решил отказаться от вложенности, а модели и серии хранить как атрибуты
Самое интересное, что часть этого изначально вообще не планировалась. Я специально по ходу разработки меняю себе ТЗ, чтобы проект развивался не по идеальному сценарию, а как это обычно бывает в работе.
По ощущениям так намного интереснее, чем пытаться сразу придумать "идеальную" архитектуру.
Дальше планирую заняться фильтрацией, поиском и ещё множеством других фич, о которых будет позже.
Please open Telegram to view this post
VIEW IN TELEGRAM
Во-первых, спасибо за актив на последних постах, это дает знак, что смысл в них есть
🆕 Продолжаю делать Fruit Store 🍎
За это время больше поработал над самим каталогом и немного подтянул инфраструктуру проекта.
Что сейчас появилось:
- Настроил структурированное логирование через slog в JSON-формате
- Написал первые unit-тесты (табличные тесты на валидацию параметров)
- Разделил страницы: теперь у каждой категории свой URL, а главная стала хабом с категориями
- Вынес Header в отдельный переиспользуемый виджет
- Добавил сортировку товаров (по цене и новизне)
- Сделал фильтрацию по атрибутам (цвет, память и т.д.) через JSONB
- Добавил отдельный эндпоинт, который сам отдает доступные фильтры для выбранной категории (без хардкода на фронте)
- Переделал каталог: теперь каждая вариация товара отображается отдельной карточкой
Из интересного - сначала думал оставить одну карточку на товар, но в какой-то момент понял, что такой подход начинает мешать. В итоге переделал каталог так, чтобы каждая конфигурация была отдельной карточкой. Это намного ближе к тому, как работают интернет-магазины.
Дальше планирую подключить фильтры на фронте, сделать мультивыбор в фильтрах, добавить остальные специфичные фильтры по категориям, добавить пагинацию. Пока план такой, идем дальше.🧩
За это время больше поработал над самим каталогом и немного подтянул инфраструктуру проекта.
Что сейчас появилось:
- Настроил структурированное логирование через slog в JSON-формате
- Написал первые unit-тесты (табличные тесты на валидацию параметров)
- Разделил страницы: теперь у каждой категории свой URL, а главная стала хабом с категориями
- Вынес Header в отдельный переиспользуемый виджет
- Добавил сортировку товаров (по цене и новизне)
- Сделал фильтрацию по атрибутам (цвет, память и т.д.) через JSONB
- Добавил отдельный эндпоинт, который сам отдает доступные фильтры для выбранной категории (без хардкода на фронте)
- Переделал каталог: теперь каждая вариация товара отображается отдельной карточкой
Из интересного - сначала думал оставить одну карточку на товар, но в какой-то момент понял, что такой подход начинает мешать. В итоге переделал каталог так, чтобы каждая конфигурация была отдельной карточкой. Это намного ближе к тому, как работают интернет-магазины.
Дальше планирую подключить фильтры на фронте, сделать мультивыбор в фильтрах, добавить остальные специфичные фильтры по категориям, добавить пагинацию. Пока план такой, идем дальше.
Please open Telegram to view this post
VIEW IN TELEGRAM
На этом этапе полностью закрыл фильтрацию и пагинацию каталога.
Что нового:
- Добавил категориальные фильтры для всех трёх категорий: цвет, серия, память, чип, RAM, тип дисплея
- Добавил числовые фильтры: цена и диагональ экрана (запрос уходит по debounce)
- Добавил мультивыбор значений внутри одного фильтра
- Собрал конфигурацию фильтров по категориям - для iPhone, Mac и Watch отображаются свои наборы атрибутов без дублирования логики
- Реализовал пагинацию с сохранением выбранных фильтров при переключении страниц. Тут решил не делать InfiniteScroll
- Добавил loading-скелетон во время загрузки следующей страницы
- Связал карточки товаров в каталоге с детальными страницами
- Детальная страница теперь отображает характеристики в зависимости от категории товара
Набор доступных характеристик отличается у разных категорий, но не хотелось делать отдельную логику под каждую из них. В итоге собрал конфигурацию, на основе которой фронт понимает, какие фильтры и значения нужно показать.
Дальше по плану - корзина:
привязка к сессии без авторизации (пока что, после корзины сделаю авторизацию);
пересчёт суммы корзины на бэкенде;
проверка доступного остатка;
базовый скелет страницы корзины.
Пока план такой, идём дальше
Please open Telegram to view this post
VIEW IN TELEGRAM
На данный момент закончил работу над корзиной.
Что нового:
- Реализовал корзину для неавторизованных пользователей через гостевую сессию и httpOnly cookie
- Проверка остатка на складе и пересчёт суммы корзины происходят на бэкенде
- Подключил TanStack Query: корзина, счётчик в Header и страница корзины синхронизированы между собой без перезагрузки
- Настроил CORS с поддержкой credentials для запросов между фронтом и бэком
- Добавил оптимистичные обновления: изменение количества и удаление товара происходят сразу, а при ошибке сервера состояние откатывается
- По пути нашёл и поправил пару багов
Корзина самый насыщенный функциональный блок на текущий момент. Состояние нужно синхронизировать сразу в нескольких местах интерфейса (счётчик в хедере, страница корзины), и сама корзина при этом должна оставаться источником истины на бэкенде, а не жить только на фронте. TanStack Query сюда хорошо вписался.
По плану - авторизация.
Начну со входа по email и коду, возможно ещё magic link, а дальше уже буду развивать эту часть.
Идём дальше
Please open Telegram to view this post
VIEW IN TELEGRAM
Перешёл к авторизации.
Что нового:
- Реализовал вход через 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
Продолжил заниматься авторизацией.
Что нового:
- Собрал простой профиль пользователя (email + выход) с защищённым доступом
- Реализовал слияние корзин при входе с разных устройств через транзакции - если гость успел накидать товаров и на телефоне, и на компьютере, при логине всё объединяется в одну корзину
- Перешёл с одного долгоживущего JWT на связку access/refresh токенов: короткоживущий access для запросов, refresh для его обновления, авторизация теперь переживает разлогинивание по времени без повторного ввода кода
- Настроил автоматическое обновление токена на фронте - если сессия протухла, приложение само подтягивает новый access и повторяет запрос, без разрыва для пользователя
- Добавил вход через Яндекс OAuth - вторым способом попасть в ту же систему токенов, без дублирования логики
Больше всего времени ушло на слияние корзин. Хотелось, чтобы пользователь не терял товары, если успел что-то добавить с разных устройств до входа в аккаунт.
По плану дальше - заказы: хочу сделать оформление доступным без обязательной авторизации, добавить подтверждение заказа на почту и страницу отслеживания для гостей, а для авторизованных пользователей - историю заказов в профиле. Оплату подключу уже после этого.
Идём дальше
Please open Telegram to view this post
VIEW IN TELEGRAM
Добрался до оформления заказов.
Что нового:
- Реализовал оформление заказов без обязательной авторизации
- Добавил транзакционное создание заказа с блокировкой строк (FOR UPDATE) и списанием остатка
- Подключил Stripe: сначала создаётся PaymentIntent, а сам заказ появляется только после успешной оплаты через вебхук
- Сделал вебхук идемпотентным - повторная доставка одного и того же события больше не создаёт дубликаты заказов
- Проверил конкурентный доступ: если два пользователя одновременно пытаются купить последнюю единицу товара, заказ оформит только один
- Собрал чекаут на фронте через Stripe Elements и полностью прошёл сценарий оплаты тестовой картой
- После успешной оплаты автоматически отправляется письмо с номером заказа
Пока делал оплату, пришлось немного пересмотреть первоначальный план. Сначала хотел создавать заказ сразу, а оплату делать отдельным шагом, но после проверки сценария с последним товаром на складе стало понятно, что логичнее создавать заказ только после подтверждённой оплаты.
Так не приходится резервировать остатки заранее и меньше шансов получить неконсистентное состояние.
Дальше по плану - личный кабинет: история заказов и профиль на отдельных вкладках, а также страница отслеживания заказа по номеру и email для гостей.
Идём дальше
Please open Telegram to view this post
VIEW IN TELEGRAM
Закрыл ещё несколько частей пользовательской части проекта.
Что нового:
- Собрал личный кабинет: профиль и история заказов на отдельных вкладках с навигацией через URL
- Сделал страницу отслеживания заказа по номеру и email для гостей без авторизации
- Добавил поиск по каталогу: инпут в Header с debounce и выпадающей панелью результатов прямо под ним
Пока поиск работает на ILIKE, полноценный full-text search и кэширование каталога оставил как следующие этапы развития после деплоя
Страница отслеживания заказа - интересная задача. Хотелось оставить её доступной без авторизации, но при этом не дать возможности подобрать чужой заказ. Поэтому поиск работает только по двум параметрам сразу - номеру заказа и email.
С поиском тоже решил пока не усложнять. Для текущего объёма данных ILIKE более чем хватает.
Дальше по плану: перехожу к дизайну, анимациям, доработкам функционала - предстоит перевёрстать все страницы под референс и заодно закрыть накопившийся по ходу проекта список мелких доработок (свотчи цветов, тосты, замена нативных элементов на shadcn/ui и другое), так что финальный объём этой фазы будет проясняться по ходу работы.
Идём дальше
Please open Telegram to view this post
VIEW IN TELEGRAM
С понедельника (10 августа) захожу на тренинг Миши Ларченко
Что будет:
1. Созвоны с Мишей 2 раза в неделю, разбирать код. Так же будет закреплен человек, который будет замечать слабые места и помогать скорректировать наплавление
2. Всех разобьют на команды по 7-8 человек сбалансировав по опыту
3. Командный Fullstack проект. Тут будет всё - спринты, планирование, код-ревью, ретро, финальная защита
Роли будут чередоваться, чтобы понимать все процессы
4. AI-Driven development. О том, как использовать ИИ на всем цикле разработки
5. Карьерная упаковка. Разбор резюме, гитхаба, линкедина, System Design, собеседования, ревью
Что будет:
1. Созвоны с Мишей 2 раза в неделю, разбирать код. Так же будет закреплен человек, который будет замечать слабые места и помогать скорректировать наплавление
2. Всех разобьют на команды по 7-8 человек сбалансировав по опыту
3. Командный Fullstack проект. Тут будет всё - спринты, планирование, код-ревью, ретро, финальная защита
Роли будут чередоваться, чтобы понимать все процессы
4. AI-Driven development. О том, как использовать ИИ на всем цикле разработки
5. Карьерная упаковка. Разбор резюме, гитхаба, линкедина, System Design, собеседования, ревью