Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
83.33% covered (warning)
83.33%
5 / 6
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ConfigKeyPolicy
83.33% covered (warning)
83.33%
5 / 6
50.00% covered (danger)
50.00%
1 / 2
5.12
0.00% covered (danger)
0.00%
0 / 1
 canRoleEdit
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
 canRoleRead
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace App\Domain\Configuration;
6
7use function in_array;
8
9/**
10 * Access policy for loan_config keys.
11 *
12 * Some keys directly price money or gate eligibility (yield rate, loan APR,
13 * LTV, loan amount limits, account minimums, origination fee). Those are
14 * super_admin-only. Operational thresholds (grace period, late fees, default
15 * counters, behavior toggles) are admin-editable.
16 */
17final class ConfigKeyPolicy
18{
19    /**
20     * Keys that only super_admin may edit. All other authenticated admins
21     * may edit any other known key.
22     */
23    private const SUPER_ADMIN_ONLY_KEYS = [
24        'account_yield_rate',
25        'default_interest_rate',
26        'ltv_percentage',
27        'min_loan_amount',
28        'max_loan_amount',
29        'min_account_balance',
30        'origination_fee_pct',
31        // FSC-98 toggle: flipping this materially weakens the
32        // leverage-stacking control. super_admin only.
33        'allow_investment_with_active_loans',
34        // FSC-49 toggle: flipping this weakens an MPA §5.3
35        // contractual obligation. super_admin only.
36        'allow_withdrawal_with_active_loans',
37        // FSC-123: raising the simultaneous-loan cap is a business
38        // limit change; treated the same as the FSC-98 toggle.
39        'max_allowed_loans',
40        // FSC-48: lockup period and override for MPA §5.2 enforcement.
41        // Tuning the window or flipping the override changes a contractual
42        // obligation; super_admin only.
43        'lockup_period_days',
44        'allow_withdrawal_during_lockup',
45        // FSC-51: program fee amounts (MPA fee schedule). These price money;
46        // super_admin only.
47        'servicing_fee_rate',
48        'treasury_management_fee_rate',
49        'platform_access_fee_monthly',
50        'platform_access_fee_annual',
51    ];
52
53    public static function canRoleEdit(string $role, string $configKey): bool
54    {
55        if ($role === 'super_admin') {
56            return true;
57        }
58
59        if ($role !== 'admin') {
60            return false;
61        }
62
63        return !in_array($configKey, self::SUPER_ADMIN_ONLY_KEYS, true);
64    }
65
66    public static function canRoleRead(string $role): bool
67    {
68        return $role === 'admin' || $role === 'super_admin';
69    }
70}