# Investor Profit Log Architecture

## Why Investor Profit Logs are Critical in Hedge Fund/Trading Systems

### 1. Audit Trail
- Complete record of every profit distribution to investors
- Tracks investor equity, units, and balance changes over time
- Provides transparent transaction history
- Required for regulatory compliance and audits

### 2. Settlement History
- Historical record of all profit settlements
- Enables tracking of investor returns over time
- Supports performance analysis and reporting
- Provides evidence of fair distribution practices

### 3. Investor Transparency
- Investors can view their complete profit history
- Clear record of how profits were calculated and distributed
- Builds trust and confidence in the fund
- Supports investor portal and dashboard functionality

### 4. Rollback Recovery
- Ability to reverse incorrect distributions
- Restore investor balances to previous state
- Correct calculation errors without data loss
- Maintain data integrity during disputes

### 5. Accounting Compliance
- Financial accounting requires detailed transaction logs
- Tax reporting needs historical profit distribution records
- Regulatory bodies demand complete audit trails
- Supports reconciliation and financial statements

## Database Schema

### investor_profit_logs Table
```sql
CREATE TABLE investor_profit_logs (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    profit_distribution_id BIGINT UNSIGNED NOT NULL,
    investor_id BIGINT UNSIGNED NOT NULL,
    equity DECIMAL(15, 2) NOT NULL,
    units INT NOT NULL,
    unit_share_ratio DECIMAL(10, 8) NOT NULL,
    profit_amount DECIMAL(15, 2) NOT NULL,
    previous_balance DECIMAL(15, 2) NOT NULL,
    new_balance DECIMAL(15, 2) NOT NULL,
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL,
    deleted_at TIMESTAMP NULL,
    FOREIGN KEY (profit_distribution_id) REFERENCES profit_distributions(id) ON DELETE CASCADE,
    FOREIGN KEY (investor_id) REFERENCES investors(id),
    INDEX idx_distribution_investor (profit_distribution_id, investor_id),
    INDEX idx_investor (investor_id)
);
```

### Key Design Decisions

**Decimal Precision**
- equity, profit_amount, balances: DECIMAL(15, 2) - Standard financial precision
- unit_share_ratio: DECIMAL(10, 8) - High precision for unit calculations
- Supports values up to 999,999,999,999.99

**Foreign Keys with Cascade**
- profit_distribution_id: CASCADE DELETE - Auto-cleanup when distribution deleted
- investor_id: RESTRICT - Prevent deletion of investor with profit logs

**Composite Index**
- (profit_distribution_id, investor_id) for fast investor-specific queries
- investor_id index for investor history queries

**Soft Deletes**
- Enables recovery of accidentally deleted logs
- Maintains complete audit trail
- Supports rollback scenarios

## Model Architecture

### InvestorProfitLog Model
```php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;

class InvestorProfitLog extends Model
{
    use SoftDeletes;

    protected $fillable = [
        'profit_distribution_id',
        'investor_id',
        'equity',
        'units',
        'unit_share_ratio',
        'profit_amount',
        'previous_balance',
        'new_balance',
    ];

    protected $casts = [
        'equity' => 'decimal:2',
        'units' => 'integer',
        'unit_share_ratio' => 'decimal:5',
        'profit_amount' => 'decimal:2',
        'previous_balance' => 'decimal:2',
        'new_balance' => 'decimal:2',
    ];

    public function investor(): BelongsTo
    {
        return $this->belongsTo(Investor::class);
    }

    public function profitDistribution(): BelongsTo
    {
        return $this->belongsTo(ProfitDistribution::class);
    }
}
```

## Profit Log Creation Flow

### Distribution Settlement
```
Profit Distribution Created
    ↓
Calculate Investor Shares
    ↓
For Each Investor:
    - Calculate unit_share_ratio
    - Calculate profit_amount
    - Update previous_balance
    - Calculate new_balance
    ↓
Create InvestorProfitLog Record
    ↓
Update Investor Available Balance
```

## Query Scopes

### Common Queries
```php
// Get profit logs for specific investor
$logs = InvestorProfitLog::forInvestor($investorId)->get();

// Get logs for specific distribution
$logs = InvestorProfitLog::forDistribution($distributionId)->get();

// Get investor's total profit
$totalProfit = InvestorProfitLog::forInvestor($investorId)
    ->sum('profit_amount');

// Get investor's current balance
$currentBalance = Investor::find($investorId)->available_balance;

// Get investor profit history with pagination
$history = InvestorProfitLog::forInvestor($investorId)
    ->with('profitDistribution')
    ->orderBy('created_at', 'desc')
    ->paginate(20);
```

## Performance Metrics

### Investor Returns
```php
// Calculate total return for investor
$totalProfit = InvestorProfitLog::forInvestor($investorId)->sum('profit_amount');
$totalInvested = Investor::find($investorId)->equity;
$returnPercentage = ($totalProfit / $totalInvested) * 100;
```

### Monthly Performance
```php
$monthlyProfit = InvestorProfitLog::forInvestor($investorId)
    ->whereHas('profitDistribution', function ($query) use ($month) {
        $query->whereYear('distribution_date', $month->year)
              ->whereMonth('distribution_date', $month->month);
    })
    ->sum('profit_amount');
```

### Average Profit per Unit
```php
$avgProfitPerUnit = InvestorProfitLog::forInvestor($investorId)
    ->selectRaw('AVG(profit_amount / units) as avg_profit_per_unit')
    ->value('avg_profit_per_unit');
```

## Best Practices

### 1. Transaction Safety
```php
DB::transaction(function () use ($investor, $distribution, $profitAmount) {
    $previousBalance = $investor->available_balance;
    $newBalance = $previousBalance + $profitAmount;

    InvestorProfitLog::create([
        'profit_distribution_id' => $distribution->id,
        'investor_id' => $investor->id,
        'equity' => $investor->equity,
        'units' => $investor->units,
        'unit_share_ratio' => $investor->units / $totalUnits,
        'profit_amount' => $profitAmount,
        'previous_balance' => $previousBalance,
        'new_balance' => $newBalance,
    ]);

    $investor->available_balance = $newBalance;
    $investor->save();
});
```

### 2. Validation
```php
$validator = Validator::make($data, [
    'profit_amount' => 'required|numeric|min:0',
    'units' => 'required|integer|min:0',
    'unit_share_ratio' => 'required|numeric|between:0,1',
    'previous_balance' => 'required|numeric|min:0',
    'new_balance' => 'required|numeric|min:0',
]);
```

### 3. Balance Consistency
```php
// Verify new_balance matches previous_balance + profit_amount
if ($newBalance !== $previousBalance + $profitAmount) {
    throw new \Exception("Balance calculation error");
}
```

### 4. Audit Logging
```php
InvestorProfitLog::creating(function ($log) {
    Log::info("Creating investor profit log", [
        'investor_id' => $log->investor_id,
        'profit_amount' => $log->profit_amount,
        'distribution_id' => $log->profit_distribution_id,
    ]);
});
```

## Rollback Recovery

### Reverse Distribution
```php
public function reverseDistribution(ProfitDistribution $distribution)
{
    DB::transaction(function () use ($distribution) {
        $logs = InvestorProfitLog::forDistribution($distribution->id)->get();

        foreach ($logs as $log) {
            $investor = $log->investor;
            $investor->available_balance = $log->previous_balance;
            $investor->save();
        }

        $distribution->delete();
    });
}
```

### Restore Deleted Log
```php
$deletedLog = InvestorProfitLog::onlyTrashed()
    ->where('profit_distribution_id', $distributionId)
    ->where('investor_id', $investorId)
    ->first();

if ($deletedLog) {
    $deletedLog->restore();
    $investor = $deletedLog->investor;
    $investor->available_balance = $deletedLog->new_balance;
    $investor->save();
}
```

## Reporting & Analytics

### 1. Investor Statement
```php
$statement = InvestorProfitLog::forInvestor($investorId)
    ->with('profitDistribution')
    ->whereHas('profitDistribution', function ($query) use ($from, $to) {
        $query->whereBetween('distribution_date', [$from, $to]);
    })
    ->orderBy('created_at', 'desc')
    ->get();
```

### 2. Fund Performance Summary
```php
$fundPerformance = InvestorProfitLog::selectRaw('
        investor_id,
        SUM(profit_amount) as total_profit,
        COUNT(*) as total_distributions,
        AVG(profit_amount) as avg_profit
    ')
    ->whereHas('profitDistribution', function ($query) use ($from, $to) {
        $query->whereBetween('distribution_date', [$from, $to]);
    })
    ->groupBy('investor_id')
    ->get();
```

### 3. Tax Reporting
```php
$taxYear = 2024;
$taxReport = InvestorProfitLog::forInvestor($investorId)
    ->whereHas('profitDistribution', function ($query) use ($taxYear) {
        $query->whereYear('distribution_date', $taxYear);
    })
    ->selectRaw('SUM(profit_amount) as total_taxable_profit')
    ->value('total_taxable_profit');
```

## Troubleshooting

### Issue: Balance mismatch
**Solution**: Verify new_balance = previous_balance + profit_amount

### Issue: Missing profit logs for distribution
**Solution**: Check if distribution was completed successfully

### Issue: Duplicate logs for same investor/distribution
**Solution**: Add unique constraint or use firstOrCreate()

### Issue: Incorrect unit_share_ratio
**Solution**: Recalculate: investor_units / total_units

## Production Considerations

### 1. Data Retention
- Keep investor profit logs indefinitely
- Archive to cold storage after 7 years
- Maintain audit trail for regulatory compliance

### 2. Monitoring
- Monitor profit log creation rate
- Alert on balance calculation errors
- Track investor withdrawal patterns
- Monitor distribution completion rates

### 3. Backup Strategy
- Daily backup of investor_profit_logs table
- Point-in-time recovery capability
- Test restore procedures regularly

### 4. Security
- Encrypt sensitive investor data
- Implement role-based access control
- Audit all balance modifications
- Regular security audits

## Testing Checklist

- [ ] InvestorProfitLog model exists with correct namespace
- [ ] Migration runs successfully with softDeletes
- [ ] Eloquent relationships work correctly
- [ ] Profit logs create successfully during distribution
- [ ] Balance calculations are accurate
- [ ] Unit share ratios are correct
- [ ] Query scopes work properly
- [ ] Soft deletes work correctly
- [ ] Rollback recovery works
- [ ] Audit logging works

## Migration Commands

### Fresh Migration (Development)
```bash
php artisan migrate:fresh
```

### Apply Migration
```bash
php artisan migrate
```

### Check Migration Status
```bash
php artisan migrate:status
```

## Next Steps

1. ✅ InvestorProfitLog model created
2. ✅ Migration updated with softDeletes
3. ✅ Eloquent relationships added
4. ✅ Database migrated successfully
5. ⏳ Test profit distribution with investor logs
6. ⏳ Verify settlement process completes successfully
