feat: enhance risk pool management and role validation

- Updated AGENTS.md to streamline information on risk pool operations and agent account restrictions.
- Introduced filtering options in AdminRiskPoolIndexController for active risk pools.
- Refactored AdminRiskPoolLockLogIndexController to support grouping by ticket or entry.
- Enhanced AdminRoleStoreController and AdminRoleUpdateController to prevent the use of reserved slugs for new roles.
- Improved error messaging for role creation and updates to clarify reserved role restrictions.
- Added new API routes for ticket item retrieval to improve admin functionalities.
This commit is contained in:
2026-06-15 17:21:53 +08:00
parent 5b6d4cb74d
commit 606ed6817e
14 changed files with 440 additions and 49 deletions

View File

@@ -254,12 +254,63 @@ test('admin risk pool lock logs include ticket_no when linked', function (): voi
$token = mintRiskAdminToken();
$this->withHeader('Authorization', 'Bearer '.$token)
->getJson('/api/v1/admin/draws/'.$draw->id.'/risk-pool-lock-logs')
->getJson('/api/v1/admin/draws/'.$draw->id.'/risk-pool-lock-logs?group_by=entry')
->assertOk()
->assertJsonPath('data.group_by', 'entry')
->assertJsonPath('data.meta.total', 1)
->assertJsonPath('data.items.0.amount', 50);
});
test('admin risk pool lock logs can group by ticket and filter active pools', function (): void {
$draw = Draw::query()->create([
'draw_no' => '20260512-007',
'business_date' => '2026-05-12',
'sequence_no' => 7,
'status' => 'open',
'start_time' => now()->subHour(),
'close_time' => now()->addHour(),
'draw_time' => now()->addHours(2),
'cooling_end_time' => null,
'result_source' => null,
'current_result_version' => 0,
'settle_version' => 0,
'is_reopened' => false,
]);
RiskPool::query()->create([
'draw_id' => $draw->id,
'normalized_number' => '0043',
'total_cap_amount' => 1_000_000,
'locked_amount' => 0,
'remaining_amount' => 1_000_000,
'sold_out_status' => 0,
'version' => 0,
]);
RiskPool::query()->create([
'draw_id' => $draw->id,
'normalized_number' => '1288',
'total_cap_amount' => 1_000,
'locked_amount' => 850,
'remaining_amount' => 150,
'sold_out_status' => 0,
'version' => 1,
]);
$token = mintRiskAdminToken();
$this->withHeader('Authorization', 'Bearer '.$token)
->getJson('/api/v1/admin/draws/'.$draw->id.'/risk-pools?active_only=1')
->assertOk()
->assertJsonPath('data.meta.total', 1)
->assertJsonPath('data.items.0.normalized_number', '1288');
$this->withHeader('Authorization', 'Bearer '.$token)
->getJson('/api/v1/admin/draws/'.$draw->id.'/risk-pool-lock-logs?group_by=entry')
->assertOk()
->assertJsonPath('data.group_by', 'entry');
});
test('admin risk pool show 404 when pool missing', function (): void {
$draw = Draw::query()->create([
'draw_no' => '20260512-003',

View File

@@ -27,7 +27,7 @@ function platformRolesApiToken(string $username): string
return $admin->createToken('test', ['*'], now()->addDay())->plainTextToken;
}
test('platform role index only lists fixed super_admin and agent roles', function (): void {
test('platform role index lists built-in roles and custom system roles', function (): void {
AdminRole::query()->create([
'slug' => 'legacy_custom_ops',
'code' => 'legacy_custom_ops',
@@ -49,10 +49,37 @@ test('platform role index only lists fixed super_admin and agent roles', functio
->pluck('slug')
->all();
expect($slugs)->toBe(['super_admin', 'site_admin', 'agent']);
expect($slugs)->toContain('super_admin', 'site_admin', 'agent', 'legacy_custom_ops');
});
test('platform roles cannot be created and super_admin permissions are full catalog', function (): void {
test('admin can create custom platform role but not reserved slugs', function (): void {
PlatformSystemRoles::ensureAll();
$token = platformRolesApiToken('platform_role_create');
$this->withHeader('Authorization', 'Bearer '.$token)
->postJson('/api/v1/admin/admin-roles', [
'slug' => 'super_admin',
'name' => 'Fake Super',
])
->assertStatus(422);
$this->withHeader('Authorization', 'Bearer '.$token)
->postJson('/api/v1/admin/admin-roles', [
'slug' => 'new_ops',
'name' => 'New Ops',
'description' => 'Custom ops role',
'permission_slugs' => ['prd.dashboard.view'],
])
->assertCreated()
->assertJsonPath('data.slug', 'new_ops')
->assertJsonPath('data.name', 'New Ops')
->assertJsonPath('data.is_system', false);
expect(AdminRole::query()->where('slug', 'new_ops')->exists())->toBeTrue();
});
test('super_admin built-in role remains protected', function (): void {
PlatformSystemRoles::ensureAll();
$token = platformRolesApiToken('platform_role_guard');
@@ -64,13 +91,6 @@ test('platform roles cannot be created and super_admin permissions are full cata
->toBe($menuActionCount);
expect($super->legacyPermissionSlugs())->not->toBeEmpty();
$this->withHeader('Authorization', 'Bearer '.$token)
->postJson('/api/v1/admin/admin-roles', [
'slug' => 'new_ops',
'name' => 'New Ops',
])
->assertStatus(422);
$this->withHeader('Authorization', 'Bearer '.$token)
->putJson('/api/v1/admin/admin-roles/'.$super->id.'/permissions', [
'permission_slugs' => ['prd.dashboard.view'],