feat(membership): enforce tenant subscription plans with blocked UI
Add configurable membership plans (free/plus/pro) synced to DB on boot, a subscription guard middleware that blocks tenant endpoints on expired or missing plans, and a MembershipBlockedView that surfaces the reason so the admin can contact the tenant owner. Quota and brand-library reads now honor the active plan's policy JSON and expired subscriptions.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestLoadPrefersEnvLLMAPIKey(t *testing.T) {
|
||||
@@ -113,6 +114,55 @@ brand_library: {}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadAppliesMembershipDefaults(t *testing.T) {
|
||||
configPath := writeTestConfig(t, `
|
||||
membership: {}
|
||||
`)
|
||||
|
||||
cfg, err := Load(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("Load() error = %v", err)
|
||||
}
|
||||
|
||||
if cfg.Membership.DefaultPlanCode != "free" {
|
||||
t.Fatalf("expected default plan code free, got %q", cfg.Membership.DefaultPlanCode)
|
||||
}
|
||||
if len(cfg.Membership.Plans) != 3 {
|
||||
t.Fatalf("expected 3 default plans, got %d", len(cfg.Membership.Plans))
|
||||
}
|
||||
|
||||
free, ok := cfg.Membership.FindPlan("free")
|
||||
if !ok {
|
||||
t.Fatalf("expected free plan to exist")
|
||||
}
|
||||
if free.ArticleGeneration != 3 {
|
||||
t.Fatalf("expected free article generation 3, got %d", free.ArticleGeneration)
|
||||
}
|
||||
if free.ImageStorageBytes != 10*1024*1024 {
|
||||
t.Fatalf("expected free image storage 10MB, got %d", free.ImageStorageBytes)
|
||||
}
|
||||
if free.CompanyLimit != 1 {
|
||||
t.Fatalf("expected free company limit 1, got %d", free.CompanyLimit)
|
||||
}
|
||||
if free.SubscriptionDuration != 72*time.Hour {
|
||||
t.Fatalf("expected free subscription duration 72h, got %s", free.SubscriptionDuration)
|
||||
}
|
||||
if !free.ContactAdminOnExpiry {
|
||||
t.Fatalf("expected free plan to require admin contact on expiry")
|
||||
}
|
||||
|
||||
pro, ok := cfg.Membership.FindPlan("pro")
|
||||
if !ok {
|
||||
t.Fatalf("expected pro plan to exist")
|
||||
}
|
||||
if pro.ArticleGeneration != 400 {
|
||||
t.Fatalf("expected pro article generation 400, got %d", pro.ArticleGeneration)
|
||||
}
|
||||
if pro.CompanyLimit != 2 {
|
||||
t.Fatalf("expected pro company limit 2, got %d", pro.CompanyLimit)
|
||||
}
|
||||
}
|
||||
|
||||
func writeTestConfig(t *testing.T, body string) string {
|
||||
t.Helper()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user