♻ update

This commit is contained in:
gsr
2026-10-04 13:05:06 +03:00
parent 935f7503e5
commit 1cfce2d2db
+48
View File
@@ -1,5 +1,53 @@
# Changelog
## [0.6.9-beta] - 2026-10-04
### Добавлено
- **Три типа монетизации** — единый ответ `GET /api/billing/packages` теперь возвращает `{ free, credits, subscriptions }` вместо плоского списка пакетов.
- **Новые пакеты кредитов** — `Micro` (300 кредитов за 49₽) для быстрых задач и `Ultra` (20 000 кредитов за 799₽) для тяжёлых сценариев и сбора датасетов.
- **Авто-расчёт производных полей пакетов** — `PricePer100Requests`, `SavingsRub` и `DiscountPercent` вычисляются по формулам относительно базового тарифа Micro через конструктор `newCreditPackage()`.
- **Функция `ceilDiv`** — округление цены за 100 запросов вверх (16.33 → 17₽) для честной маркетинговой цены без `float` и импорта `math`.
- **Метрика `PricePer100Requests`** вместо «копеек за запрос» — понятнее для пользователя (например, «17 ₽ за 100 запросов»).
- **Подписки (Subscriptions)** — 4 периода (1/3/6/12 месяцев) с базовой ставкой 499₽/мес и авто-расчётом экономии через `newSubscriptionPlan()`.
- **Безлимитный доступ для подписчиков** — `CheckQuota` и `IncrementUsage` пропускают пользователей с активной подпиской без списания кредитов и дневного лимита.
- **Агрегированный ответ `UsageStatsResponse`** — один эндпоинт возвращает и кредиты, и информацию о подписке (`credits` + `subscription` + `is_subscriber`).
- **Флаг `IsPopular`** для пакетов — позволяет фронтенду подсвечивать «Хит продаж» (Optimal).
### Изменено
- **Кэш подписки** — проверка `HasActiveSubscription` кэшируется в Redis с TTL 10 минут и инвалидируется при активации.
- **Базовая ставка подписки** — 499₽/мес (было 699₽), скидка на 12 месяцев увеличена до 20%.
### Исправлено
- **Детерминированность `detectContentLanguage`** — язык теперь всегда определяется на чистом контенте (до добавления title/TOC/frontmatter), независимо от комбинации флагов.
- **Fail-open стратегия** — при падении Redis проверка подписки и кредитов продолжает работать через БД, не блокируя пользователя.
---
## [0.6.8-beta] - 2026-10-04
### Добавлено
- **💳 Подписки (Subscriptions)** — новая модель безлимитного доступа к конвертеру.
- **Таблица `user_subscriptions`** — миграция для хранения активных подписок с полями `starts_at`, `ends_at`, `updated_at` и constraint `starts_at <= ends_at`.
- **`SubscriptionRepository`** — интерфейс с методами `HasActiveSubscription`, `GetActive`, `Activate`.
- **Атомарный SQL-апсерт подписок** — один запрос `INSERT ... ON CONFLICT DO UPDATE` корректно продлевает активную подписку или создаёт новую для истёкшей. Защищает от race condition при двойном клике на оплату.
- **Доменная сущность `Subscription`** с методами `IsActive()` и `DaysRemaining()`.
- **Интеграция в `QuotaService`** — методы `HasActiveSubscription` и `ActivateSubscription` с кэшированием в Redis (TTL 10 мин) и автоматической инвалидацией при активации.
- **Оптимизированный запрос `HasActiveSubscription`** — `SELECT true ... LIMIT 1` для максимальной скорости в hot path.
- **Тестовый эндпоинт** `POST /api/billing/test/activate-subscription` для проверки функционала без интеграции с платёжной системой (только в dev/test режиме).
- **DTO `SubscriptionResponse`** и `UsageStatsResponse` — агрегированная структура для отображения статуса подписки на фронтенде (активна / дней до окончания / безлимит).
### Изменено
- **`checkAuthenticatedQuota`** — сначала проверяется наличие активной подписки, и только при её отсутствии выполняется проверка кредитов и дневного лимита.
- **`IncrementUsage`** — подписчики не тратят кредиты и не увеличивают счётчик дневного лимита.
- **`GetUsageStats`** — возвращает агрегированную информацию (кредиты + подписка) в одном запросе.
- **Clean Architecture** — проверка подписки теперь идёт через сервис, а не через прямой вызов репозитория из `checkAuthenticatedQuota`.
### Безопасность
- **Атомарность upsert** — SQL-запрос с `ON CONFLICT` исключает состояние гонки при одновременных запросах на активацию подписки.
- **Fail-open стратегия** — при недоступности Redis проверка подписки fallback-ит в БД, не блокируя легитимных пользователей.
---
## [0.5.8-beta] - 2026-10-03
### Добавлено