Initial commit of Descrybe v2 without local scratch artifacts.

Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
2026-08-09 22:47:43 +02:00
commit 8580c996c3
1285 changed files with 325780 additions and 0 deletions
+168
View File
@@ -0,0 +1,168 @@
package billing
import (
"strings"
)
// A1LegacyCompanyID is the MySQL company_id for A1 Slovenija (migrated dump name kept in PG).
// Cohort remains legacy even if an older local rename used "Local Demo Co".
const A1LegacyCompanyID = "97e1a309-3d23-4aa2-b518-8e8d7afdfec7"
// LegacyPlanName is the seeded package name for migrated / limited-nav tenants.
const LegacyPlanName = "Legacy"
// PlanProfile is the packaging bucket used for default feature matrices.
type PlanProfile string
const (
PlanProfileFree PlanProfile = "free"
PlanProfileStarter PlanProfile = "starter"
PlanProfileGrowth PlanProfile = "growth"
PlanProfileBusiness PlanProfile = "business"
PlanProfileEnterprise PlanProfile = "enterprise"
PlanProfileLegacy PlanProfile = "legacy"
PlanProfileCustom PlanProfile = "custom"
)
// legacyFeatureAllowlist is the ON set for the legacy (A1) matrix.
// Source: docs/admin-roles-support/03-roles-matrix.md / .json (legacy_user).
var legacyFeatureAllowlist = map[string]struct{}{
"shell.navigation": {},
"shell.command_palette": {},
"shell.company_switcher": {},
"shell.tutorial": {},
"shell.account_menu": {},
"shell.billing_recovery_banner": {},
"dashboard.overview": {},
"dashboard.stats": {},
"dashboard.quick_links": {},
"dashboard.recent_jobs": {},
"dashboard.news_feed": {},
"dashboard.activation_checklist": {},
"dashboard.migrated_checklist": {},
"dashboard.etl_gaps": {},
"dashboard.upgrade_banners": {},
"catalog.products": {},
"catalog.products.tab_processed": {},
"catalog.products.tab_needs_review": {},
"catalog.products.tab_error": {},
"catalog.products.tab_processing": {},
"catalog.products.tab_unprocessed": {},
"catalog.products.process_categories": {},
"catalog.products.process_attributes": {},
"catalog.products.process_ai_titles": {},
"catalog.products.process_ai_descriptions": {},
"catalog.products.enrichment_review": {},
"catalog.products.export_selection": {},
"catalog.products.upgrade_prompt": {},
"catalog.categories": {},
"catalog.categories.title_formula": {},
"catalog.categories.description_formula": {},
"catalog.attributes": {},
"catalog.attributes.bulk_import": {},
"catalog.standard_fields": {},
"catalog.standard_fields.groups": {},
"feeds.list": {},
"feeds.add_url": {},
"feeds.add_csv": {},
"feeds.sync": {},
"feeds.mapping": {},
"feeds.mapping.select_item": {},
"feeds.mapping.map_fields": {},
"feeds.export_feeds": {},
"feeds.export_feeds.create": {},
"feeds.export_feeds.generate": {},
"feeds.uploads": {},
"billing.overview": {},
"billing.customer_portal": {},
"billing.quick_upgrade": {},
"billing.plans_compare": {},
"billing.checkout": {},
"settings.profile": {},
"settings.company": {},
"settings.alerts": {},
"settings.api_keys": {},
"settings.team": {},
"settings.team_invite": {},
"capability.sku_cap": {},
"capability.ai_credits": {},
"capability.ai_processing": {},
"capability.eprel": {},
"capability.normalize_specs_fill": {},
"capability.feed_source_limit": {},
"capability.export_feed_limit": {},
"capability.storage_limit": {},
"capability.api_access": {},
}
// IsLegacyPlanName reports whether a plan name matches the legacy cohort patterns
// (exact "legacy", A1*, or "a1 slovenija"). See docs/admin-roles-support/03-roles-matrix.md.
func IsLegacyPlanName(planName string) bool {
n := strings.ToLower(strings.TrimSpace(planName))
if n == "" {
return false
}
if n == "legacy" {
return true
}
if strings.Contains(n, "a1 slovenija") {
return true
}
if n == "a1" || strings.HasPrefix(n, "a1 ") || strings.HasPrefix(n, "a1-") || strings.HasPrefix(n, "a1_") {
return true
}
return false
}
// IsLegacyPlan reports legacy packaging from an explicit flag and/or name patterns.
func IsLegacyPlan(planName string, isLegacyFlag bool) bool {
return isLegacyFlag || IsLegacyPlanName(planName)
}
// IsLegacyCompanyID reports whether a remapped legacy MySQL company id is the A1 cohort.
func IsLegacyCompanyID(legacyCompanyID string) bool {
return strings.EqualFold(strings.TrimSpace(legacyCompanyID), A1LegacyCompanyID)
}
// IsA1CohortCompany reports whether a company is the migrated A1 tenant.
// Match only immutable legacy_company_id — never mutable display names
// (register/rename to "A1" must not grant Legacy plan privileges).
// companyName is retained for call-site compatibility; it is ignored.
func IsA1CohortCompany(legacyCompanyID, companyName string) bool {
_ = companyName
return IsLegacyCompanyID(legacyCompanyID)
}
// LegacyFeatureAllowed reports whether key is ON in the legacy matrix.
func LegacyFeatureAllowed(key string) bool {
_, ok := legacyFeatureAllowlist[key]
return ok
}
// ResolvePlanProfile maps name + flags to the default matrix bucket.
func ResolvePlanProfile(planName string, isCustom, isLegacyFlag bool) PlanProfile {
if IsCustomPackage(planName, isCustom) {
norm := strings.ToLower(strings.TrimSpace(planName))
if norm == "enterprise" {
return PlanProfileEnterprise
}
return PlanProfileCustom
}
if IsLegacyPlan(planName, isLegacyFlag) {
return PlanProfileLegacy
}
norm := strings.ToLower(strings.TrimSpace(planName))
switch norm {
case "", "free":
return PlanProfileFree
case "starter", "plus":
return PlanProfileStarter
case "growth":
return PlanProfileGrowth
case "business", "scale":
return PlanProfileBusiness
case "enterprise":
return PlanProfileEnterprise
}
return PlanProfileFree
}