feat(tenant): per-tenant brand and question limit overrides
Add nullable brand_limit / question_limit columns on tenants so ops admins can override the plan-derived brand-library quotas per account. When set, these take precedence over config.yml plan defaults across the brand-library summary, question materialization, and the daily monitoring worker's primary-client plan resolution. Ops side exposes them on admin-user create plus a new PUT /admin-users/:id/limits endpoint, invalidating the brand-library summary cache on change. The ops-web AdminUsers view gains matching inputs on the create and edit modals. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/shared/response"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestValidateOptionalAdminUserLimit(t *testing.T) {
|
||||
positive := 3
|
||||
zero := 0
|
||||
negative := -1
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
value *int
|
||||
wantErr bool
|
||||
}{
|
||||
{name: "null inherits config", value: nil},
|
||||
{name: "positive override", value: &positive},
|
||||
{name: "zero rejected", value: &zero, wantErr: true},
|
||||
{name: "negative rejected", value: &negative, wantErr: true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := validateOptionalAdminUserLimit("brand_limit", tt.value)
|
||||
if !tt.wantErr {
|
||||
require.NoError(t, err)
|
||||
return
|
||||
}
|
||||
var appErr *response.AppError
|
||||
require.ErrorAs(t, err, &appErr)
|
||||
assert.Equal(t, "invalid_limit", appErr.Message)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user