feat: enhance player authentication and agent management features
Some checks failed
lotterLaravel CI / test (push) Has been cancelled

- Updated AGENTS.md to clarify player interface bindings and agent account restrictions.
- Improved PlayerAuthLoginController to include captcha verification for player login.
- Enhanced AdminPlayerIndexController with permission checks for admin users.
- Refactored AdminPlayerStoreController to enforce agent node restrictions for non-super admins.
- Introduced new error codes for player authentication failures and updated related services.
- Enhanced validation rules for agent profiles to include settlement cycle options.
- Improved AdminCaptchaService to support separate scopes for admin and player captcha handling.
- Updated various services to ensure proper credit management and settlement processes.
This commit is contained in:
2026-06-17 15:27:00 +08:00
parent b496a9457c
commit 2e0b257160
49 changed files with 714 additions and 334 deletions

View File

@@ -134,3 +134,56 @@ test('credit player wallet logs distinguish win credit from bill settlement', fu
->assertJsonPath('data.total', 1)
->assertJsonPath('data.items.0.type', 'win_credit');
});
test('credit wallet logs page 2 balance_after continues from page 1 baseline', function (): void {
$player = Player::query()->create([
'site_code' => 'default_site',
'site_player_id' => 'native:logs-page2',
'auth_source' => PlayerAuthSource::LOTTERY_NATIVE,
'funding_mode' => PlayerFundingMode::CREDIT,
'username' => 'credit_logs_page2',
'default_currency' => 'NPR',
'status' => 0,
]);
DB::table('player_credit_accounts')->insert([
'player_id' => $player->id,
'credit_limit' => 500,
'used_credit' => 12,
'frozen_credit' => 0,
'created_at' => now(),
'updated_at' => now(),
]);
for ($i = 1; $i <= 12; $i++) {
DB::table('credit_ledger')->insert([
'owner_type' => 'player',
'owner_id' => $player->id,
'amount' => -1000,
'reason' => 'bet_hold',
'ref_type' => 'bet',
'ref_id' => $i,
'created_at' => now()->subMinutes(12 - $i),
'updated_at' => now()->subMinutes(12 - $i),
]);
}
$page1 = $this->withHeader('Authorization', 'Bearer dev:'.$player->id)
->getJson('/api/v1/wallet/logs?page=1&size=10')
->assertOk()
->json('data');
$page2 = $this->withHeader('Authorization', 'Bearer dev:'.$player->id)
->getJson('/api/v1/wallet/logs?page=2&size=10')
->assertOk()
->json('data');
expect($page1['total'])->toBe(12);
expect($page2['items'])->toHaveCount(2);
$page1LastBalanceAfter = $page1['items'][9]['balance_after'];
$page2FirstBalanceAfter = $page2['items'][0]['balance_after'];
// Page 2 must continue the running balance from page 1, not restart at current available.
expect($page2FirstBalanceAfter)->toBe($page1LastBalanceAfter + 1000);
});