# Shift Plan — Retire Stacking · Holding → "Global Trading"

Source: `Business details.xlsx` (root, reviewed 2026-07-03) vs the current system.
Rule: **dynamic-first, non-destructive** — the business change is expressed through the
existing admin config wherever possible; code changes only add label/visibility dynamism.
No DB tables, enum values, ledger sources, or migrations are ever removed (money history).

---

## 1. What the sheet says vs what the system does today

| Area | Business details.xlsx | Current system | Delta |
|---|---|---|---|
| Investment | $80 min | $80 min (`min_investment`) | none |
| Split | $50 "Trading Pool" + $30 Global Auto Pool | working = deposit − $30 carve | same mechanics, new *name* |
| **Stacking** | **absent — removed** | 5 terms, currently all deactivated | retire from UI/nav/site |
| **ROI plan** | one plan: **6% FIXED, "daily and weekly payout"** | 4 Holding tiers (Bronze 0.2%/d … VIP 0.5%/d), only Bronze active | single flat plan named **Global Trading** (open Q1 on cadence) |
| 30-level income | header "5.5% of ROI distribution"; table L1 25% … L21-30 0.25%, directs 1–9 | identical table in `level_income` | table unchanged (open Q2 on the 5.5% note) |
| 15-level pool referral | 10/5/3/3/2/1/.75/.75/.5/.5/.5/.5/.75/.75/1 (=30%) | identical (`pool_referral_levels`) | none |
| Royalty | 10 directs → Pool 1, 21 → Pool 2 (5%) | identical | none |
| Matrix | L1 3% / L2 3% / L3 4% + "extra 13% company" | matrix 3/3/4, pool_split_matrix 23% (10+13 cascade) | none |
| Rebirth | 100 / 500 / 3000 / 10000, "continue onwards" | identical ladder | none |
| **Rank catalog** | **new thresholds/rewards** (below) | old M8.3 values (partially edited) | reseed catalog |
| Rank conditions | "2 × lower rank in different leg" (5★+) | require_count = 3 | 3 → **2** (open Q3) |
| Rank perks | no trips / cars anywhere | trips on 2★+, cars on Diamond+ | drop trips/cars (open Q3) |

New rank catalog from the sheet (Business 60:40 → Reward · Share):

| Rank | Business | Condition | Reward | Global share |
|---|---|---|---|---|
| Star | $2,000 | — | $100 | — |
| 2 Star | $5,000 | — | $250 | 1% |
| 3 Star | $10,000 | — | $600 | 0.5% |
| 4 Star | $25,000 | — | $1,500 | 0.5% |
| 5 Star | $60,000 | 2 × 4★ different legs | $4,500 | 0.25% |
| 7 Star | $100,000 | 2 × 5★ different legs | $10,000 | 0.25% |
| Diamond | $250,000 | 2 × 7★ | $25,000 | 0.5% |
| Double Diamond | $550,000 | 2 × Diamond | $60,000 | 0.5% |
| Triple Diamond | $1,000,000 | 2 × Double Diamond | $100,000 | 1% |

---

## 2. Open questions (blocking numbers — §11: never guess)

1. **ROI cadence.** "6% FIXED ON DAILY AND WEEKLY PAY OUT" — is that **6% per month
   accrued daily** (= 0.20%/day, exactly today's Bronze rate; "weekly payout" = the
   existing weekly withdrawal cycle)? That is the recommended reading. Or 6% weekly?
2. **"5.5% of ROI Distribution"** on the 30-level heading — the level table itself is
   unchanged, so what does 5.5% refer to? (If it caps the total level payout, that is
   new logic; if it's informational, ignore.)
3. **Ranks:** confirm trips/cars are gone, and the leg condition is **2** (not 3) of the
   lower rank.
4. **Existing active stacking plans** (6 in dev — test data): pre-launch we assume wipe
   with the test data; if any real plan ever exists, crons keep accruing it to maturity
   (code stays capable).

---

## 3. The plan, phase by phase

### Phase 1 — Config-only shift (no code, admin screens already exist)
- Stacking terms: already all **deactivated** (enabled=false → gate rejects, UI hides).
- `holding_tiers` → a single active tier: `{tier:"global-trading", min:80, max:null,
  rate:<per Q1>, foreign_trip:false, enabled:true}` (engine untouched; admin can add
  more tiers later — this is the "each plan dynamic" requirement, already built).
- Reseed `ranks_catalog` per the sheet via an idempotent migration (stays admin-editable
  at config/ranks). Update require_count per Q3.
- `capped_sources`: leave `stacking` listed (harmless; guards any legacy plan).

### Phase 2 — Dynamic plan labels (small code, the "reflect in frontend" ask)
- New **unlocked** settings: `plan_label_trading` = "Global Trading",
  `plan_label_pool` = "Global Auto Pool" (group `branding`), editable in Settings.
- Views print `$settings->getString('plan_label_trading')` instead of the hardcoded
  word "Holding": panel sidebar, dashboard cards, deposit page, holding views/heading,
  admin sidebar + holding screen title, config/plans card, report labels.
- Internal keys NEVER change: `plan_type='holding'`, `WalletLedger::SRC_HOLDING`,
  service/class names, DB enums. Rename is presentation-only (money-safe).

### Phase 3 — Retire Stacking from the UI, dynamically (not hardcoded away)
- Nav/menu items and dashboard cards for Stacking render **only when**
  `StackingService::enabledTerms() !== [] || user has stacking plans` (helper reused
  frontend + backend). Zero enabled terms + zero plans → invisible everywhere.
- Deposit form: already hides stacking when no term is enabled (verified earlier).
- Admin Stacking screen: shown only when stacking plans exist (history access).
- Crons (`stacking/daily-accrual`, `stacking/maturity` inside `cron/daily`): keep —
  idempotent no-ops with no active plans; still honor any legacy plan.
- `WithdrawalService` maturity gate, `LevelIncomeService::dailyRoiFor` stacking sum:
  keep (no-ops without plans).

### Phase 4 — Public site copy (marketing pages)
- `site/index`, `site/plans`, `site/how-it-works`, `site/about`, footer: replace the
  three-engine story (Stacking/Holding/Pool) with **Global Trading + Global Auto Pool**.
- Make `site/plans` render the plan cards **from config** (active tiers + rates + the
  label settings) so future admin edits reflect on the marketing page too.

### Phase 5 — Verify (definition of done)
- Full unit suite: no new failures vs baseline.
- Authenticated sweep: investor + admin pages 200, no "Stacking" visible anywhere,
  "Global Trading" label everywhere Holding used to appear.
- Deposit flow end-to-end: only Global Trading offered; $80 → $30 pool + $50 trading;
  approve → plan at the Q1 rate; label change in admin Settings reflects on the
  frontend after save (cache propagation already fixed).
- PROGRESS.md entry; note in the spec that M4 is retired and M5 renamed by the sheet.

---

## 4. Explicitly NOT done (safety)
- No dropping of stacking tables/columns/enum values/ledger sources.
- No renaming of internal identifiers (`holding`, `stacking`) in code or DB.
- No touching of wallet/ledger math; the ROI engine (HoldingService) is reused as-is.
