feat(integration-requests): let the admin bypass limits and auto-approve (#551)
## What
The user matching \`ADMIN_EMAIL\` curates the integration-requests
board, so they get special treatment:
- **No monthly cap** — \`actionsRemaining()\` reports a full quota for
the admin, so neither the backend checks nor the frontend buttons ever
gate them.
- **Auto-approved proposals** — requests created by the admin are stored
as \`approved\` instead of \`pending\`, skipping moderation.
## How
- New \`User::isAdmin()\` helper, mirroring \`isDemoAccount()\`,
comparing against \`config('mail.admin_email')\` (already wired to
\`ADMIN_EMAIL\`).
- \`IntegrationRequestController::actionsRemaining()\` early-returns the
limit for the admin.
- \`IntegrationRequestController::store()\` sets \`status\` to
\`Approved\` for the admin.
## Tests
- Added a feature test covering the admin bypassing the monthly limit
and auto-approval. All 16 \`IntegrationRequestTest\` tests pass.
This commit is contained in:
parent
5e8f227fbd
commit
7e9122eaf4
|
|
@ -40,7 +40,11 @@ class IntegrationRequestController extends Controller
|
|||
return $this->limitReachedResponse();
|
||||
}
|
||||
|
||||
$integrationRequest = $user->integrationRequests()->create($request->only(['name', 'url']));
|
||||
$integrationRequest = $user->integrationRequests()->create([
|
||||
...$request->only(['name', 'url']),
|
||||
// The admin curates the board, so their proposals skip moderation.
|
||||
'status' => $user->isAdmin() ? IntegrationRequestStatus::Approved : IntegrationRequestStatus::Pending,
|
||||
]);
|
||||
$integrationRequest->votes()->create(['user_id' => $user->id]);
|
||||
|
||||
return $this->payload($user, 201);
|
||||
|
|
@ -96,6 +100,12 @@ class IntegrationRequestController extends Controller
|
|||
|
||||
private function actionsRemaining(User $user): int
|
||||
{
|
||||
// The admin has no monthly cap; report a full quota so neither the
|
||||
// backend checks nor the frontend buttons ever gate them.
|
||||
if ($user->isAdmin()) {
|
||||
return self::MONTHLY_ACTION_LIMIT;
|
||||
}
|
||||
|
||||
$start = now()->startOfMonth();
|
||||
|
||||
$used = $user->integrationRequests()->where('created_at', '>=', $start)->count()
|
||||
|
|
|
|||
|
|
@ -304,6 +304,11 @@ class User extends Authenticatable implements HasLocalePreference, MustVerifyEma
|
|||
return $this->email === config('app.demo.email');
|
||||
}
|
||||
|
||||
public function isAdmin(): bool
|
||||
{
|
||||
return $this->email === config('mail.admin_email');
|
||||
}
|
||||
|
||||
public function preferredLocale(): string
|
||||
{
|
||||
return $this->locale ?? 'en';
|
||||
|
|
|
|||
|
|
@ -108,6 +108,29 @@ test('a user cannot exceed the monthly action limit', function () {
|
|||
->assertStatus(422);
|
||||
});
|
||||
|
||||
test('the admin bypasses the monthly limit and their requests are auto-approved', function () {
|
||||
config(['mail.admin_email' => 'admin@whisper.test']);
|
||||
$admin = User::factory()->create(['email' => 'admin@whisper.test']);
|
||||
IntegrationRequest::factory()->count(5)->create(['user_id' => $admin->id]);
|
||||
|
||||
$this->actingAs($admin)
|
||||
->postJson('/integration-requests', ['name' => 'Revolut', 'url' => 'https://revolut.com'])
|
||||
->assertCreated()
|
||||
->assertJsonPath('actionsRemaining', 3);
|
||||
|
||||
$this->assertDatabaseHas('integration_requests', [
|
||||
'user_id' => $admin->id,
|
||||
'name' => 'Revolut',
|
||||
'status' => IntegrationRequestStatus::Approved->value,
|
||||
]);
|
||||
|
||||
$other = IntegrationRequest::factory()->approved()->create();
|
||||
|
||||
$this->actingAs($admin)
|
||||
->postJson("/integration-requests/{$other->id}/vote")
|
||||
->assertOk();
|
||||
});
|
||||
|
||||
test('removing a vote is allowed even at the monthly limit', function () {
|
||||
$user = User::factory()->create();
|
||||
$request = IntegrationRequest::factory()->approved()->create();
|
||||
|
|
|
|||
Loading…
Reference in New Issue