refactor(api): ApiKeyController index() excludes expired keys (review M1)

Code-quality review of Task 3: index() filtered by is_active only —
an expired-but-active key would be listed as valid. Adds an
expires_at > now() filter plus a test. Cannot occur today (regenerate
is the only write path, always +1 year) but is the correct semantic
contract for an «active key» listing.

phpstan-baseline.neon: count bumps only for ApiKeyControllerTest.php
($tenant 5→7, $user 3→5, getJson 3→4).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Дмитрий
2026-05-15 22:06:14 +03:00
parent a5e2bbbbe8
commit a26f5af2da
3 changed files with 24 additions and 3 deletions
@@ -43,6 +43,26 @@ test('GET /api/api-keys изолирован по тенанту', function () {
expect($response->json('data'))->toHaveCount(0);
});
test('GET /api/api-keys не возвращает истёкшие ключи', function () {
ApiKey::factory()->create([
'tenant_id' => $this->tenant->id,
'user_id' => $this->user->id,
'is_active' => true,
'expires_at' => now()->subDay(),
]);
ApiKey::factory()->create([
'tenant_id' => $this->tenant->id,
'user_id' => $this->user->id,
'is_active' => true,
'expires_at' => now()->addYear(),
]);
$response = $this->getJson('/api/api-keys');
$response->assertOk();
expect($response->json('data'))->toHaveCount(1);
});
test('POST /api/api-keys/regenerate создаёт ключ и возвращает plaintext один раз', function () {
$response = $this->postJson('/api/api-keys/regenerate');