Микро-SaaS на 1 ГБ RAM: Telegram-мини-апп, СБП и один очень дорогой дефис

efreeze 24 минуты назад Краткое содержание статьи Микро-SaaS на 1 ГБ RAM: Telegram-мини-апп, СБП и один очень дорогой дефис Средний 3 мин 685 TypeScript * ReactJS * PostgreSQL * Ретроспектива Как «Паспорт вещей»...
Will Anthropic have the best AI model at the end of October 2026?
Вот важная новость с фронта ИИ: efreeze 24 минуты назад Краткое содержание статьи Микро-SaaS на 1 ГБ RAM: Telegram-мини-апп, СБП и один очень дорогой дефис Средний 3 мин 685 TypeScript * ReactJS * PostgreSQL * Ретроспектива Как «Паспорт вещей» (Next. js + Prisma + PostgreSQL) живёт на самом дешёвом VDS, зачем MAX нужен мост и собственный корень Минцифры, и почему платежи не работали с первого дня — а никто не замечал. ДисклеймерЭто не туториал, а полевой отчёт соло-разработчика.
Продукт — «Паспорт вещей» (паспорт-вещей. рф): цифровой паспорт покупок с напоминаниями о гарантии в Telegram/MAX. Бесплатно — до 5 вещей и все функции для авто (пробег, ТО, история); подписка «Открытый» (59 ₽/мес, СБП) — безлимит, OCR чеков, CSV и документы.
Технические детали
js 16, Prisma + PostgreSQL, grammy, ЮKassa. Всё это — на VDS с 1 vCPU и 1 ГБ RAM. Урок 1: сборка на слабом сервере — это OOMПервая же docker compose build на 1-гигабайтном сервере уронила машину: sshd и контейнеры были убиты OOM-киллером, помогла перезагрузка через панель хостера.
С тех пор правило железное: сборка — на локальной машине, на сервер — docker save | ssh docker load. Бонус: чиним место на диске заранее (образы плодятся). Урок 2: Idempotence ≠ IdempotencyСамая дорогая буква в проекте.
Платежи через ЮKassa у нас создаются POST-ом с идемпотентным ключом. Стандартное имя заголовка — Idempotency-Key? У ЮKassa — нет: контрактное имя Idempotence-Key.
Отраслевые последствия
Мы отправляли «правильное» имя — ЮKassa молча отвечала 400 «Idempotence key is missing», а пользователю показывалось «Не получилось создать платёж». Прелесть в том, что дефект жил с первого дня: ни одного платежа не прошло никогда, но и никто не платил — поэтому узнавали мы об этом только через месяц с лишним, когда прогнали полный цикл на тестовом магазине. Морали три:Юнит-тест на моке закреплял неверное имя — тестируйте контракт, а не свою интерпретацию контракта.
Полный платёжный e2e на тестовом окружении — до релиза, а не после. Ошибка создания платежа обязана логироваться со статусом и телом ответа. Кстати о тестовом магазине ЮKassa: в нём нет СБП — только тестовые карты.
Поэтому в тестовом режиме создаём платёж без payment_method_data и способ выбирается на стороне ЮKassa. Урок 3: вебхукам нельзя верить, а return_url — можно (немного)Тело вебхука мы не доверяем: по id платежа дергаем живой GET к API ЮKassa, сверяем сумму с прайсом, и в одной транзакции клеймим Payment. subscriptionId + выдаём подписку.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.





