feat: 扩展奖池、风控与报表能力,新增对账补偿、广播和人工操作接口
This commit is contained in:
@@ -18,7 +18,11 @@ use App\Models\AdminUser;
|
||||
use App\Lottery\DrawStatus;
|
||||
use App\Models\OddsVersion;
|
||||
use App\Models\RiskCapVersion;
|
||||
use App\Services\Ticket\PlayCatalogResolver;
|
||||
use App\Events\OddsUpdateBroadcast;
|
||||
use App\Events\PlayToggleBroadcast;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use App\Lottery\ConfigVersionStatus;
|
||||
use Database\Seeders\CurrencySeeder;
|
||||
use Database\Seeders\PlayTypeSeeder;
|
||||
@@ -48,7 +52,7 @@ function acceptanceMintAdminToken(): string
|
||||
return $admin->createToken('test', ['*'], now()->addDay())->plainTextToken;
|
||||
}
|
||||
|
||||
function oddsPutPayloadFromDetail(array $items): array
|
||||
function acceptanceOddsPutPayloadFromDetail(array $items): array
|
||||
{
|
||||
return collect($items)->map(fn (array $r) => [
|
||||
'play_code' => $r['play_code'],
|
||||
@@ -104,7 +108,7 @@ test('§12.6 published odds are visible on public effective catalog without code
|
||||
$draftId = (int) $create->json('data.id');
|
||||
|
||||
$detail = $this->getJson('/api/v1/admin/config/odds-versions/'.$draftId, $auth)->assertOk()->json('data.items');
|
||||
$payload = oddsPutPayloadFromDetail($detail);
|
||||
$payload = acceptanceOddsPutPayloadFromDetail($detail);
|
||||
foreach ($payload as &$row) {
|
||||
if ($row['play_code'] === 'big' && $row['prize_scope'] === 'first') {
|
||||
$row['odds_value'] = 333_333;
|
||||
@@ -132,7 +136,7 @@ test('§5 odds publish archives prior version lists history and writes audit log
|
||||
$detail = $this->getJson('/api/v1/admin/config/odds-versions/'.$draftId, $auth)->assertOk()->json('data.items');
|
||||
$this->putJson(
|
||||
'/api/v1/admin/config/odds-versions/'.$draftId.'/items',
|
||||
['items' => oddsPutPayloadFromDetail($detail)],
|
||||
['items' => acceptanceOddsPutPayloadFromDetail($detail)],
|
||||
$auth,
|
||||
)->assertOk();
|
||||
|
||||
@@ -235,7 +239,7 @@ test('§5 existing ticket_items odds snapshot row is not mutated when new odds v
|
||||
$draftId = (int) $create->json('data.id');
|
||||
|
||||
$detail = $this->getJson('/api/v1/admin/config/odds-versions/'.$draftId, $auth)->assertOk()->json('data.items');
|
||||
$payload = oddsPutPayloadFromDetail($detail);
|
||||
$payload = acceptanceOddsPutPayloadFromDetail($detail);
|
||||
foreach ($payload as &$row) {
|
||||
if ($row['play_code'] === 'big' && $row['prize_scope'] === 'first') {
|
||||
$row['odds_value'] = 9_999_999;
|
||||
@@ -330,6 +334,38 @@ test('§5 risk cap publish is audited and version history exists', function ():
|
||||
expect(count($list))->toBeGreaterThanOrEqual(2);
|
||||
});
|
||||
|
||||
test('§10 default risk cap template applies to unconfigured numbers', function (): void {
|
||||
$token = acceptanceMintAdminToken();
|
||||
$auth = ['Authorization' => 'Bearer '.$token];
|
||||
|
||||
$create = $this->postJson('/api/v1/admin/config/risk-cap-versions', ['reason' => 'default risk cap'], $auth);
|
||||
$create->assertOk();
|
||||
$draftId = (int) $create->json('data.id');
|
||||
|
||||
$this->putJson('/api/v1/admin/config/risk-cap-versions/'.$draftId.'/items', [
|
||||
'items' => [
|
||||
[
|
||||
'draw_id' => null,
|
||||
'normalized_number' => '0000',
|
||||
'cap_amount' => 12_345,
|
||||
'cap_type' => 'default',
|
||||
],
|
||||
[
|
||||
'draw_id' => null,
|
||||
'normalized_number' => '1234',
|
||||
'cap_amount' => 777,
|
||||
'cap_type' => 'per_number',
|
||||
],
|
||||
],
|
||||
], $auth)->assertOk();
|
||||
|
||||
$this->postJson('/api/v1/admin/config/risk-cap-versions/'.$draftId.'/publish', [], $auth)->assertOk();
|
||||
|
||||
$resolver = app(PlayCatalogResolver::class);
|
||||
expect($resolver->resolveCapAmount(9999, '5678'))->toBe(12_345)
|
||||
->and($resolver->resolveCapAmount(9999, '1234'))->toBe(777);
|
||||
});
|
||||
|
||||
test('§5 play_config publish is audited', function (): void {
|
||||
$token = acceptanceMintAdminToken();
|
||||
$auth = ['Authorization' => 'Bearer '.$token];
|
||||
@@ -367,3 +403,66 @@ test('§5 play_config publish is audited', function (): void {
|
||||
->exists(),
|
||||
)->toBeTrue();
|
||||
});
|
||||
|
||||
test('§9 play_config publish broadcasts changed play toggles', function (): void {
|
||||
Event::fake([PlayToggleBroadcast::class]);
|
||||
config([
|
||||
'broadcasting.default' => 'reverb',
|
||||
'broadcasting.connections.reverb.driver' => 'reverb',
|
||||
]);
|
||||
|
||||
$token = acceptanceMintAdminToken();
|
||||
$auth = ['Authorization' => 'Bearer '.$token];
|
||||
|
||||
$create = $this->postJson('/api/v1/admin/config/play-versions', ['reason' => 'toggle broadcast'], $auth);
|
||||
$create->assertOk();
|
||||
$draftId = (int) $create->json('data.id');
|
||||
|
||||
$itemPayload = $create->json('data.items');
|
||||
foreach ($itemPayload as &$row) {
|
||||
if ($row['play_code'] === 'big') {
|
||||
$row['is_enabled'] = false;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
$this->putJson('/api/v1/admin/config/play-versions/'.$draftId.'/items', ['items' => $itemPayload], $auth)->assertOk();
|
||||
$this->postJson('/api/v1/admin/config/play-versions/'.$draftId.'/publish', [], $auth)->assertOk();
|
||||
|
||||
Event::assertDispatched(
|
||||
PlayToggleBroadcast::class,
|
||||
fn (PlayToggleBroadcast $event): bool => $event->playCode === 'big' && $event->enabled === false,
|
||||
);
|
||||
});
|
||||
|
||||
test('§9 odds publish broadcasts odds update', function (): void {
|
||||
Event::fake([OddsUpdateBroadcast::class]);
|
||||
config([
|
||||
'broadcasting.default' => 'reverb',
|
||||
'broadcasting.connections.reverb.driver' => 'reverb',
|
||||
]);
|
||||
|
||||
$token = acceptanceMintAdminToken();
|
||||
$auth = ['Authorization' => 'Bearer '.$token];
|
||||
|
||||
$create = $this->postJson('/api/v1/admin/config/odds-versions', ['reason' => 'odds broadcast'], $auth);
|
||||
$create->assertOk();
|
||||
$draftId = (int) $create->json('data.id');
|
||||
|
||||
$detail = $this->getJson('/api/v1/admin/config/odds-versions/'.$draftId, $auth)->assertOk()->json('data.items');
|
||||
$payload = acceptanceOddsPutPayloadFromDetail($detail);
|
||||
foreach ($payload as &$row) {
|
||||
if ($row['play_code'] === 'big' && $row['prize_scope'] === 'first') {
|
||||
$row['odds_value'] = 444_444;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
$this->putJson('/api/v1/admin/config/odds-versions/'.$draftId.'/items', ['items' => $payload], $auth)->assertOk();
|
||||
$this->postJson('/api/v1/admin/config/odds-versions/'.$draftId.'/publish', [], $auth)->assertOk();
|
||||
|
||||
Event::assertDispatched(
|
||||
OddsUpdateBroadcast::class,
|
||||
fn (OddsUpdateBroadcast $event): bool => $event->versionId === $draftId,
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user