# ✨ Считать объём, минуты и расход по каждому пользователю - **Тип:** feature - **Категория:** Очередь — Учёт по пользователям требует владельца записи и метрик расхода — оба выше. - **Зачем:** Ни объём, ни длительность, ни обращения к платным сервисам никуда не записываются: восстановить расход задним числом не из чего. По каждому пользователю копятся объём, минуты и расход на внешние сервисы, и повтор шага не удваивает счёт. Учёт ведётся записями о потреблении, а не счётчиком в строке пользователя: счётчик, увеличенный дважды при повторе шага, обратно не отматывается. ## Затрагивает - таблица записей потребления: владелец, задача, вид ресурса, величина, время — и её миграция; - `TranscribeService.createTranscribeJob` — размер файла и длительность записи на приёме; - `TranscribeService.completeJob` и `failJob` — запись потребления после успешного шага и после отказа; - адаптер SpeechKit и адаптер языковой модели: откуда берутся минуты и токены; - `internal/metrics` — счётчики того же расхода без разбивки по людям; - `docs/database.md` — представление данных. ## Критерии приёмки - Дошедшая до `done` запись оставляет строки потребления: объём файла, длительность в минутах, минуты распознавания и токены языковой модели. Оракул — тест конвейера на подставных адаптерах: четыре строки с владельцем задачи. - Повторный проход шага после перезапуска не удваивает потребление. Оракул — тест: шаг выполнен дважды, сумма по задаче не изменилась. - Отказавшая задача сохраняет то, что уже потрачено, а не обнуляет счёт. Оракул — тест на ветке `failJob` после успешной конвертации. - Величина расхода не смешивает пользователей: выборка по владельцу отдаёт только его строки. Оракул — тест на двух владельцах. ## Рамки Снаружи эта задача не видна сама по себе: ни экрана, ни эндпоинта она не заводит — их строит `admin-stats-screen`. Тип оставлен `feature` сознательно: это первая половина работы, которую вторая делает видимой. Потолков и отказов по исчерпании квоты не заводим — учёт показывает, а не ограничивает. Пересчёт расхода в деньги здесь не делается: копятся минуты и токены, цена прайс-листа живёт вне сервиса. Данные о потреблении содержат идентификаторы, но не текст записи и не имя файла (инвариант приватности).