♻ update
This commit is contained in:
@@ -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
|
||||
|
||||
### Добавлено
|
||||
|
||||
Reference in New Issue
Block a user