Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
66 lines
2.8 KiB
Markdown
66 lines
2.8 KiB
Markdown
# 05 — Legacy plan feature seed (agent 5/20)
|
|
|
|
**Status:** Implemented in `apps/api/internal/billing`.
|
|
**Coordinates with:** [`03-roles-matrix.md`](./03-roles-matrix.md), [`04-contract.md`](./04-contract.md), [`docs/plan-permissions/06-defaults-matrix.md`](../plan-permissions/06-defaults-matrix.md).
|
|
|
|
---
|
|
|
|
## PROBLEM
|
|
|
|
A1 / migrated packages previously resolved as **custom all-ON**, which exposed Background Tasks (`processing.monitor`), stores, marketing, etc. Legacy tenants must get the **image-nav** matrix only.
|
|
|
|
---
|
|
|
|
## Behavior
|
|
|
|
| Concern | Implementation |
|
|
|---------|----------------|
|
|
| Profile | `PlanProfileLegacy` / `ResolvePlanProfile` |
|
|
| Allow-list | `LegacyFeatureAllowed` + `legacyFeatureAllowlist` in `legacy_plan.go` |
|
|
| Defaults | `DefaultPlanFeatures` / `DefaultPlanFeaturesEx` check legacy **before** custom all-ON |
|
|
| Sparse store | `SparseLegacyOverrides` / `SparseDefaultOverridesEx` |
|
|
| Detect | `IsLegacyPlanName` (exact `legacy`, `A1` / `A1 …`), `IsLegacyPlan(name, is_legacy)`, `IsLegacyCompanyID` |
|
|
| Column | `plans.is_legacy` via `028_plan_is_legacy.sql` (additive; code falls back if missing) |
|
|
| Seed | `EnsureDefaultFeatureSeeds` → `EnsureLegacyPlanFeatureSeeds` → `EnsureLegacyDefaults` |
|
|
| Reset | `ApplyDefaultMatrix` writes sparse legacy for legacy plans |
|
|
| Create | `prepareCustomPackageCreateFeatures` seeds sparse legacy for A1-named plans |
|
|
|
|
### Seed / backfill rules (`EnsureLegacyDefaults`)
|
|
|
|
1. Upsert plan row named **Legacy** (`is_legacy=true`).
|
|
2. For each plan matching name or `is_legacy`:
|
|
- **empty** `features` → write `SparseLegacyOverrides`
|
|
- **full enable-all** map (prior custom create) → repair to sparse legacy
|
|
- **`is_legacy=true`** → re-apply sparse legacy
|
|
- **non-empty customized** (not enable-all, not flagged) → **leave alone**
|
|
3. Assign Legacy plan to A1 cohort companies (`legacy_company_id` / A1 name / Local Demo Co stand-in).
|
|
|
|
### Explicitly OFF (examples)
|
|
|
|
- `processing.monitor` (Background Tasks)
|
|
- all `stores.*`, `marketing.*`, `integrations.*`, `support.*`
|
|
- `catalog.structured_descriptions`, `catalog.vector_categories`
|
|
- `shell.support_notifications`, `dashboard.store_reconnect`
|
|
- `capability.byok`, campaign/email/brand/seo capabilities
|
|
|
|
### Explicitly ON (image-nav)
|
|
|
|
Dashboard, Products, Feeds, Export Feeds, Categories, Attributes, Standard Fields, Usage & Billing, Settings — plus required shell/capabilities for catalog AI.
|
|
|
|
---
|
|
|
|
## Verification
|
|
|
|
```bash
|
|
cd apps/api
|
|
go test ./internal/billing/ -count=1 -run "Legacy|DefaultPlanFeatures|SparseDefault|IsCustomPackage|Prepare"
|
|
```
|
|
|
|
---
|
|
|
|
## ASSUMPTIONS
|
|
|
|
1. Name patterns from agent 3 win over `is_custom` for matrix resolution.
|
|
2. Non-legacy client deals (e.g. Merkur) remain enable-all custom.
|
|
3. Local Demo Co may be treated as A1 stand-in during demo seed when remapped.
|