diff --git a/server/internal/httpapi/api_test.go b/server/internal/httpapi/api_test.go index 3181a01..2428f51 100644 --- a/server/internal/httpapi/api_test.go +++ b/server/internal/httpapi/api_test.go @@ -1,6 +1,24 @@ // Наскрізний тест API: справжня БД, справжній HTTP, справжній WebSocket. // // NETPULSE_TEST_DSN="postgres://netpulse:netpulse@localhost/netpulse_it" go test ./... +// +// БАЗА МАЄ БУТИ ПОРОЖНЬОЮ — лише зі схемою, без даних. +// +// Кабінети тут унікальні (slug із наносекундами), а от КОРИСТУВАЧІ в +// цьому продукті глобальні: одна людина може працювати в кількох +// кабінетах, тому `core.users.username` унікальний наскрізно, і +// CreateUser при зіткненні свідомо підхоплює наявного, НЕ переписуючи +// пароль (users.go, і це правильно: інакше адмін одного кабінету міняв +// би пароль людини в чужому). +// +// Наслідок для тестів: на базі, де вже стоїть робоча інсталяція, +// seedUser("admin@example.com") натрапляє на власника з ім'ям `admin`, +// пароль лишається чужим, вхід не вдається — і тест падає на 401 у +// зовсім іншому місці. Це не поломка продукту, а невиконана умова. +// +// Так знайшлось: набір прогнали проти пісочниці установника, тобто +// проти ВЖЕ поставленої системи. CI і `./netpulse sandbox once` дають +// чисту базу, тому там усе зелене. package httpapi_test import ( diff --git a/server/internal/store/billing.go b/server/internal/store/billing.go index 98d9688..013ab1b 100644 --- a/server/internal/store/billing.go +++ b/server/internal/store/billing.go @@ -298,7 +298,14 @@ func (s *Store) TenantUsage(ctx context.Context, tenantID string) (Usage, error) var u Usage err := s.InTenantTx(ctx, tenantID, func(tx pgx.Tx) error { return tx.QueryRow(ctx, - `SELECT devices, maps, agents, users FROM bill.usage_now($1)`, tenantID). + // Суфікс `_used` — не косметика: функція повертає колонки з + // цими іменами саме тому, що `devices` поруч із таблицею + // inv.devices дає неоднозначність (пояснення в 0069). Тут + // імена спершу лишились старими, і це знайшлось лише в + // пісочниці: код збирався, а перший же запит до бази падав + // з «column "devices" does not exist». + `SELECT devices_used, maps_used, agents_used, users_used + FROM bill.usage_now($1)`, tenantID). Scan(&u.Devices, &u.Maps, &u.Agents, &u.Users) }) return u, err