От схемы базы до пикселя
Full-stack разработчик. Бэкенд на Python и FastAPI, фронтенд без лишних слоёв.













AniWorld
Библиотека аниме и манги с личными коллекциями, оценками и профилями.
Метаданные из Shikimori, видео из Kodik, манга сразу из трёх читалок за общим контрактом провайдера. Серверный рендеринг вместо SPA, потому что трафик такому сайту даёт поиск. 900 тестов, 43 миграции, прод на VPS в ЕС.
- FastAPI
- SQLAlchemy 2.0
- MySQL
- Alembic
- Jinja2
- nginx

Голубика Давидика
Лендинг фермерского хозяйства: заявка уходит владельцу в Telegram за секунду.
Ноль фреймворков на фронте, минифицированные css и js, разметка под поиск: sitemap, robots, манифест. Форма заказа бьёт в Express, тот отдаёт заявку боту. Развёрнуто на Vercel.
- Express
- Vanilla JS
- Telegram Bot API
- Vercel

RecipeVault
Кулинарная книга на WPF: рецепты, подбор блюд по имеющимся продуктам и планы питания.
Десять таблиц в MySQL за Entity Framework, весь маппинг выписан руками: в базе змеиный регистр, в C# паскалевский, соглашения их сами не свяжут. Поиск идёт от обратного, не что приготовить, а что приготовить из этого. План питания складывает одноимённые ингредиенты всех рецептов и выдаёт список покупок.
- C#
- .NET Framework
- WPF
- Entity Framework 6
- MySQL

Breaking Bad
Лонгрид по сериалу: персонажи, сезоны, галерея, локации, две языковые версии.
Здесь меня интересовала только подача. Палитра собрана из кадров, заголовки на Bebas Neue, вёрстка держит длинный текст и не разваливается на середине. Переключатель EN и RU работает без перезагрузки.
- HTML
- Tailwind
- ES Modules

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

DotaCounters
Портативная утилита для Dota 2: против кого герой играет слабо, а против кого сильно.
Тянет свежую статистику матчапов с Dotabuff и рисует её в одном окне с иконками героев. Патч определяется сам при запуске. Один exe, без установки и без браузера.
- Python
- Tkinter
- PyInstaller
Сначала контракт
Источники прячутся за интерфейсом
У манги в AniWorld три поставщика с разными API и разной пагинацией. Слой синхронизации не знает ни одного из них: он видит только нормализованный ответ. Добавить четвёртый значит написать один класс, а не править половину проекта.
class MangaProvider(ABC): name: str # ключ в конфиге: "mangadex" can_read: bool = True # можем ли забрать страницы глав page_hosts: tuple[str, ...] = () @abstractmethod async def fetch_catalog(self, client, *, limit, offset, language) -> list[MangaRaw]: ...
Рендер по задаче
SPA не всегда правильный ответ
AniWorld живёт поиском, поэтому страницы тайтлов отдаёт сервер на Jinja2, а динамика идёт отдельными запросами к тому же FastAPI. Индексируемо из коробки, быстрый первый экран, никакого сборщика.
@router.get("/", response_class=HTMLResponse)async def home_page(request: Request, db: AsyncSession = Depends(get_db)): featured = await pick_featured(db) return templates.TemplateResponse( "home.html", {"request": request, "featured": featured}, )
Версии под контролем
Зависимости закреплены по разбору CVE
В requirements рядом с версиями лежат причины: какой разбор формы читается до проверки входа, какая дыра закрыта в каком релизе. Обновление пакета это решение, а не автоматика.
# Разбор формы идёт до проверки входа: так устроен FastAPI,# тело читается раньше зависимостей маршрута.python-multipart==0.0.32Pillow==12.3.0 argon2-cffi==25.1.0PyJWT==2.13.0
Залеский Кирилл
Началось со школы: мне было интересно всё, что связано с компьютерами, и со временем это сузилось до серверной логики. Люблю продумать, как ходят данные, а потом открыть сайт и сразу увидеть результат. Python выбрал за простой синтаксис и за то, что почти под любую задачу уже есть библиотека.
AniWorld делаю для себя. Самым тяжёлым оказалась не архитектура, а отладка: найти, почему источник отдаёт не то, починить и не бросить проект на этом месте. По-моему, это и есть главный навык, который у меня появился.
Сейчас учусь и хочу практики: одинаково рад заказу, стажировке и работе в команде.
NEVERMORE это старое имя Shadow Fiend из Dota 2, одного из моих любимых персонажей.
Чем работаю
Открыт к работе и к заказам. Отвечаю в течение дня.
Или оставьте заявку прямо здесь: она придёт мне в Telegram.