feat: billing — usage tracking per SQS operation in PostgreSQL

- New package app/billing: Init/RecordUsage/Close with auto-migrate
- Integration in actionHandler: record tenant_id, operation, msg_count, msg_bytes
- Helm chart: billing section in values.yaml, secret-billing.yaml, env vars in deployment
- Optional: billing disabled by default (BILLING_PG_HOST not set = no-op)
- Table: sqs_usage_records with index on (tenant_id, recorded_at)
This commit is contained in:
Naeel
2026-04-12 11:51:27 +03:00
parent d1af612b48
commit 1272388673
13 changed files with 448 additions and 4 deletions
+12 -1
View File
@@ -33,4 +33,15 @@
- Решение предназначено для demo/showcase, не для production security model.
- В production demo token должен быть удалён вместе с seeded demo tenant.
- Основным постоянным сценарием остаётся вход по реальному Nubes JWT.
- Основным постоянным сценарием остаётся вход по реальному Nubes JWT.
## Что удалить перед production без demo user
- Ветку `authenticateUIDemoToken` и связанные demo-константы в [app/admin/admin.go](/home/naeel/remote_dev/SQS-service/app/admin/admin.go)
- Demo token и demo-подсказки из [app/ui/index.html](/home/naeel/remote_dev/SQS-service/app/ui/index.html)
- Seed demo tenant и его тестовые очереди/сообщения
- Публичные demo credentials из пользовательских README/инструкций
## Что лучше, если demo path может жить дольше
Если demo-режим понадобится и после первой презентации, лучший следующий шаг — не держать его как "просто ещё один путь", а вынести под отдельный явный feature flag с default=off для production. Тогда риски забыть demo bypass в боевом окружении будут существенно ниже.
+17
View File
@@ -2,6 +2,15 @@
## Версия v0.1.x
### v0.1.23-dev (2026-04-12) — billing: учёт SQS-операций в PostgreSQL
- ✅ Новый пакет `app/billing/` — подключение к PG, auto-migrate, async запись usage
- ✅ Интеграция в actionHandler — каждая успешная SQS-операция записывается
- ✅ Опциональность: если BILLING_PG_HOST не задан — billing выключен, SQS работает как раньше
- ✅ Helm chart: секция `billing:` в values.yaml, secret-billing.yaml, env в deployment.yaml
- ✅ Таблица `sqs_usage_records`: tenant_id, operation, msg_count, msg_bytes, recorded_at
- ✅ `go build ./...` — OK
- 🔲 Собрать Docker image и задеплоить с PostgreSQL credentials
### v0.1.22 (2026-04-12) — demo UI showcase mode deployed
- ✅ Demo UI token поддержан сервером: `demo-ui-shared-sqs-ngcloud-2026`
- ✅ Реальный JWT login сохранён без изменений
@@ -122,6 +131,8 @@
## Next Steps
- [ ] Перед production без demo user удалить из кода demo UI token path, seeded demo tenant, demo credentials в README и все публичные demo-подсказки в UI
- [ ] Если demo path нужен дольше, сначала вынести его под явный feature flag с default=off для production окружения
- [ ] Per-queue locking (заменить глобальный мьютекс на per-queue sync.RWMutex)
- [ ] DLQ (Dead Letter Queue) — maxReceiveCount → перемещение в DLQ
- [ ] Rate limiting per tenant
@@ -187,6 +198,12 @@ Secret Key: demo-secret-key-shared-sqs-ngcloud-2026
Endpoint: https://qu.kube5s.ru
```
TODO перед production без demo-доступа:
- удалить demo token path из [app/admin/admin.go](/home/naeel/remote_dev/SQS-service/app/admin/admin.go)
- выключить/удалить seeded demo tenant
- удалить публичные demo credentials и demo token из пользовательской документации
- убрать demo-подсказки из [app/ui/index.html](/home/naeel/remote_dev/SQS-service/app/ui/index.html)
## Deployment
```bash
+42
View File
@@ -389,4 +389,46 @@
- вопрос прикладной конкурентоспособности shared-sqs в practically useful диапазоне до `32KB`;
- отдельную transport/platform проблему `64KB+`, уже локализованную на ingress path.
---
# Agent: GitHub Copilot (Claude Opus 4.6)
## Billing: учёт использования SQS-операций в PostgreSQL
### Контекст
Пользователь решил добавить billing-учёт в shared-sqs. Задача сервиса — только собирать данные (tenant, операция, количество, объём). Подсчёт денег — отдельный биллинг-сервис.
### Решения (согласованы с пользователем)
1. **Одна таблица** `sqs_usage_records` — не по тенанту. PostgreSQL держит сотни миллионов строк с индексом.
2. **Строка на каждый API-вызов** — без агрегации. Место дешёвое.
3. **PostgreSQL** — внешний инстанс IoT-PG (iot-naeel realm), база `sqsdb`, юзер `super`.
4. **Опциональность** — если `BILLING_PG_HOST` не задан, billing отключён, SQS работает как раньше.
5. **При старте** — auto-migrate: CREATE TABLE IF NOT EXISTS + индекс.
6. **Helm chart** — секция `billing:` с enabled/postgres параметрами.
### Реализация
- Новый пакет `app/billing/billing.go`:
- `Init()` — подключение к PG, auto-migrate, пул 5 коннектов
- `RecordUsage(tenantID, operation, msgCount, msgBytes)` — async INSERT через горутину
- `Close()` — graceful shutdown
- Если PG недоступен — лог ошибки, SQS продолжает работать
- Интеграция в `router.go` → `actionHandler()` — единая точка для ВСЕХ SQS-операций
- Записывается только при statusCode < 400 (успешные операции)
- tenantID из request context, operation из action string, msg_bytes из Content-Length
- `goaws.go` (main) — `billing.Init()` при старте, `billing.Close()` при shutdown
- Helm: `values.yaml` (billing section), `secret-billing.yaml`, `deployment.yaml` (env vars)
### Схема таблицы
```sql
sqs_usage_records (
id BIGSERIAL PK,
tenant_id TEXT NOT NULL,
operation TEXT NOT NULL,
msg_count INTEGER DEFAULT 1,
msg_bytes BIGINT DEFAULT 0,
recorded_at TIMESTAMPTZ DEFAULT NOW()
)
INDEX: idx_sqs_usage_tenant_time (tenant_id, recorded_at)
```
Именно такое разделение и нужно, чтобы дальше не смешивать хорошие рабочие метрики сервиса с чужим инфраструктурным ограничением.