Staging Test: Profit & Referral Distribution

Time: 20 minutes
Prerequisites: Seed data loaded, tranches exist

Quick Reference

URLs

PageURL
Admin Cycleshttps://zestamc.savibm.com/admin/cycles
Fund Admin Cycleshttps://zestamc.savibm.com/fund-admin/cycles
Profits Pagehttps://zestamc.savibm.com/investor/profits

Test Accounts

RoleEmailOTP
Super Adminadmin@zestamc.comCheck email
Fund Adminfundadmin@zestamc.comCheck email
Investortestinvestor@zestamc.comCheck email
Institutioninstitution@zestamc.comCheck email
Note: FUND_ADMIN users access cycles via /fund-admin/cycles. SUPER_ADMIN users access via /admin/cycles.

Permission Matrix

ActionFUND_ADMINSUPER_ADMIN
View cycles
Create cycle
Start cycle
Set/update profit rate
Distribute profits
Distribute referrals
Note: Rate setting is FUND_ADMIN only. Distribution is SUPER_ADMIN only.

Cycle Status Flow

PENDING → PROCESSING → PROFIT_DISTRIBUTED → COMPLETED
   │          │              │                  │
Create    Start Cycle    Distribute        Distribute
           (OTP)         Profits (OTP)     Referrals (OTP)

Fee Split

User TypeUser SharePlatformReferral Pool
Individual50%30%20%
Institution70%30%0%

Single Fund Setup

The staging database uses a single fund for all users:
FundCodeUUID
Zest Growth FundZGF33333333-3333-3333-3333-333333333333

Cycles

  • Cycle 0: Seed cycle for test users
  • Cycles 1-4: Historical cycles from migration (Oct-Nov 2025)
  • Next cycle: Cycle 5 (when admin creates new)

Seed Data (Active Tranches - Test Users)

UserPrincipalTypeLinked to Cycle
testinvestor$10,000IndividualCycle 0
test$5,000IndividualCycle 0
l2investor$2,000IndividualCycle 0
l3investor$3,000IndividualCycle 0
institution$100,000InstitutionCycle 0
Total$120,000
Note: Migrated users (~3,857) are linked to Cycles 1-4.

Test Cases

Test 1: Create Cycle

As: admin@zestamc.com (SUPER_ADMIN)
  1. Go to Admin → Cycles (/admin/cycles)
  2. Click “Create Cycle”
  3. Set dates: Start = today, End = tomorrow
  4. Click Create
Expected: Cycle appears with status PENDING, rate shows -

Test 1b: Cycle Date Overlap Prevention

As: admin@zestamc.com (SUPER_ADMIN) Goal: Verify the system prevents creating cycles with overlapping dates
  1. Go to Admin → Cycles (/admin/cycles)
  2. Click “Create Cycle”
  3. Enter dates that overlap with an existing PENDING or PROCESSING cycle
  4. Observe the form
Expected Results:
ScenarioWhat You Should See
Overlapping datesRed warning: “Dates overlap with: Cycle X”
Submit buttonDisabled (cannot submit)
Adjacent datesNo warning (allowed: Cycle 1 ends Jan 10, Cycle 2 starts Jan 10 is OK)
Non-overlappingNo warning, can submit
Pass Criteria: ✅ System blocks overlapping cycle dates

Test 2: Start Cycle

As: admin@zestamc.com (SUPER_ADMIN)
  1. Go to Admin → Cycles (/admin/cycles)
  2. Find PENDING cycle
  3. Click “Start Cycle”
  4. Enter OTP from email
Expected: Status changes to PROCESSING

Test 3: Set Profit Rate

As: fundadmin@zestamc.com (FUND_ADMIN)
Permission Requirement: Setting profit rate requires FUND_ADMIN role. SUPER_ADMIN cannot set rates (separation of duties). FUND_ADMIN users access cycles via /fund-admin/cycles.
  1. Login as fundadmin@zestamc.com (use OTP from email)
  2. You will be redirected to Fund Admin → Cycles (/fund-admin/cycles)
  3. Find PROCESSING cycle
  4. Click “Set Rate”
  5. Enter OTP from email
  6. Enter: 2.5 (for 2.5% profit)
  7. Click Save
Expected: Rate displays as +2.50%
If you see 403 Forbidden: The account doesn’t have FUND_ADMIN role. Use fundadmin@zestamc.com which has the FUND_ADMIN role.

Test 4: Distribute Profits

As: admin@zestamc.com (SUPER_ADMIN)
  1. Go to Admin → Cycles (/admin/cycles)
  2. Find cycle with rate set
  3. Click “Distribute Profits”
  4. Enter OTP from email
  5. Confirm
Expected: Status changes to PROFIT_DISTRIBUTED

Test 5: Distribute Referrals

As: admin@zestamc.com (SUPER_ADMIN)
  1. Go to Admin → Cycles (/admin/cycles)
  2. Find PROFIT_DISTRIBUTED cycle
  3. Click “Distribute Referrals”
  4. Enter OTP from email
  5. Confirm
Expected: Status changes to COMPLETED

Test 6: Verify testinvestor Profit

As: testinvestor@zestamc.com Expected Values (2.5% rate on $10,000 principal):
ItemCalculationAmount
Gross Profit$10,000 × 2.5%$250.00
User Share$250 × 50%$125.00
Platform Fee$250 × 30%$75.00
Referral Pool$250 × 20%$50.00
  1. Go to Portfolio or Profits page
  2. Check available_profit increased by ~$125
Expected: Available profit shows +$125.00 from this cycle

Test 7: Verify Institution Profit

As: institution@zestamc.com Expected Values (2.5% rate on $100,000 principal):
ItemCalculationAmount
Gross Profit$100,000 × 2.5%$2,500.00
User Share$2,500 × 70%$1,750.00
Platform Fee$2,500 × 30%$750.00
Referral Pool-$0.00
Expected: Available profit shows +$1,750.00

Test 8: Verify Referral Bonuses

As: testinvestor@zestamc.com Referral chain: testinvestor → test → l2investor → l3investor Referral pool generated by testinvestor’s downline:
FromPrincipalPool (20% of gross)testinvestor gets
test$5,000$25.00L1: 15% = $3.75
l2investor$2,000$10.00L2: 10% = $1.00
l3investor$3,000$15.00L3: 5% = $0.75
Total$5.50
Expected: Bonus wallet balance increased by ~$5.50

Test 9: Loss Cycle

As: admin@zestamc.com (SUPER_ADMIN) and fundadmin@zestamc.com (FUND_ADMIN)
  1. As SUPER_ADMIN: Go to Admin → Cycles (/admin/cycles)
  2. As SUPER_ADMIN: Create new cycle
  3. As SUPER_ADMIN: Start cycle (use OTP from email)
  4. As FUND_ADMIN: Login as fundadmin@zestamc.com, go to Fund Admin → Cycles (/fund-admin/cycles)
  5. As FUND_ADMIN: Set rate: -3.0 (3% loss) (use OTP from email)
  6. As SUPER_ADMIN: Switch back to admin@zestamc.com, go to Admin → Cycles (/admin/cycles)
  7. As SUPER_ADMIN: Distribute profits (use OTP from email)
  8. As SUPER_ADMIN: Distribute referrals (use OTP from email)
Expected:
  • Rate displays as -3.00% (red)
  • Cycle completes successfully
  • No referral bonuses (loss cycles = $0 referral pool)

Test 10: Verify Loss Applied

As: testinvestor@zestamc.com Expected Values (-3% rate on $10,000 principal):
ItemCalculationAmount
Loss$10,000 × -3%-$300.00
User Loss100% of loss-$300.00
Loss is deducted from:
  1. available_profit first
  2. Then principal if profit insufficient
Expected: Principal or profit reduced by $300

Results Summary

TestDescriptionStatus
1Create Cycle
1bOverlap Prevention
2Start Cycle
3Set Rate (2.5%)
4Distribute Profits
5Distribute Referrals
6testinvestor +$125
7institution +$1,750
8Referral bonus +$5.50
9Loss Cycle (-3%)
10Loss applied -$300

Expected Values Quick Reference

After 2.5% Profit Cycle

UserPrincipalProfit AddedBonus Added
testinvestor$10,000+$125.00+$5.50
test$5,000+$62.50+$1.75
l2investor$2,000+$25.00+$0.75
l3investor$3,000+$37.50$0
institution$100,000+$1,750.00$0

After -3% Loss Cycle

UserPrincipal ChangeProfit Change
testinvestor-$300 (or from profit)Reduced first

Troubleshooting

IssueSolution
”Set Rate” not availableCycle must be PROCESSING. Start it first.
”Set Rate” shows 403 ForbiddenUse fundadmin@zestamc.com (FUND_ADMIN role). SUPER_ADMIN cannot set rates.
Can’t find cycles pageFUND_ADMIN users access /fund-admin/cycles, SUPER_ADMIN uses /admin/cycles.
”Distribute” not availableRate must be set first.
Distribution slowBackground job. Wait 10-30 sec, refresh.
Wrong profit amountCheck user type (50% vs 70% share).
No referral bonusInstitution users don’t generate referral pool.