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:
@@ -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 в боевом окружении будут существенно ниже.
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
```
|
||||
|
||||
Именно такое разделение и нужно, чтобы дальше не смешивать хорошие рабочие метрики сервиса с чужим инфраструктурным ограничением.
|
||||
Reference in New Issue
Block a user