Преминете към основното съдържание

Usage Recording и Quota Management

Usage системата проследява колко време потребителите диктуват и управлява quota-та за free потребители. Работи както с автентикирани, така и с анонимни (само device ID) потребители.

Поток на записване

Endpoints

POST /usage/record (OptionalAuth)

Записва нова диктовка и връща актуалния quota статус.

Request:

{
"device_id": "DEVICE_HASH",
"duration_seconds": 15.5
}

Response: QuotaStatusResponse (виж по-долу)

Логика:

  1. Валидация: duration_seconds > 0
  2. Ако потребителят е автентикиран: MigrateDeviceToUser -- прехвърля всички анонимни usage_records от това устройство към потребителя
  3. INSERT в usage_recordsuser_id ако е логнат, NULL ако не е)
  4. UPDATE на кумулативните статистики в users таблицата
  5. UPSERT на stats_aggregate (singleton с id=1)
  6. Изчисляване и връщане на QuotaStatusResponse

Всичко се изпълнява в единична транзакция за consistency.

GET /usage/quota-status (OptionalAuth)

Проверява текущия quota статус без да записва нова диктовка.

Query params: ?device_id=DEVICE_HASH

Response: QuotaStatusResponse

GET /stats/public (без автентикация)

Публична статистика за уеб сайта.

Response:

{
"total_users": 1234,
"total_dictation_hours": 567.89,
"total_typing_saved_hours": 2271.56,
"total_dictation_count": 45678
}

QuotaStatusResponse

{
"status": "active",
"used_seconds": 300.0,
"quota_seconds": 600.0,
"remaining_seconds": 300.0,
"cooldown_until": null,
"trial_ends_at": null,
"total_dictation_seconds": 1500.0,
"total_typing_saved_seconds": 6000.0
}
ПолеТипОписание
statusstringЕдин от: unlimited, trial, active, cooldown
used_secondsfloatИзползвани секунди в текущия цикъл
quota_secondsfloatОбщо позволени секунди за цикъла
remaining_secondsfloatОставащи секунди
cooldown_untilstring?ISO 8601 datetime кога cooldown-ът приключва
trial_ends_atstring?ISO 8601 datetime кога trial-ът изтича
total_dictation_secondsfloatОбщо секунди диктовка (lifetime)
total_typing_saved_secondsfloatСпестено време от типене (lifetime, x TypingRatio)

Quota логика

Статуси

СтатусОписаниеКога се случва
unlimitedБез ограниченияPro план
trialTrial период, без лимитНов потребител в рамките на TRIAL_DAYS дни
activeНормална работа с quotaFree потребител след trial
cooldownВременно блокиранFree потребител, изчерпал quota-та

Rolling Quota Algorithm (walkCycles)

Алгоритъмът обхожда всички usage records хронологично и поддържа текущ "цикъл":

Ключови характеристики:

  • Quota-та е rolling, не calendar-based
  • Cooldown се закръглява нагоре до най-близкия цял час (roundUpToHour)
  • При изтекъл cooldown, записите след cooldown-а се преизчисляват за нов цикъл

Typing Ratio Multiplier

total_typing_saved_seconds = total_dictation_seconds * TYPING_RATIO

По подразбиране TYPING_RATIO = 4.0, което означава, че 1 секунда диктовка спестява приблизително 4 секунди типене. Използва се за маркетингови цели в публичната статистика и в клиента.

Device-to-User Migration

Когато анонимен потребител (само с device_id) се логне за първи път, MigrateDeviceToUser:

  1. Обновява всички usage_records с device_id = X и user_id IS NULL -> user_id = потребителя
  2. Преизчислява total_dictation_seconds и total_dictation_count за потребителя чрез SUM и COUNT заявки

Това гарантира, че анонимната usage история се запазва след логване.

Конфигурация

ПроменливаDefaultОписание
QUOTA_MINUTES10Quota в минути за free потребители per цикъл
COOLDOWN_HOURS5Cooldown период в часове след изчерпване
TRIAL_DAYS7Trial период в дни за нови потребители
TYPING_RATIO4.0Множител за изчисляване на спестено време

Prometheus Metrics

Usage handler-ът записва следните metrics:

  • usage_records_total -- counter за общ брой записани usage events
  • usage_duration_seconds_total -- counter за общо записани секунди