Commit Graph

1 Commits

Author SHA1 Message Date
Víctor Falcón 8382a56e98
feat(ai): add command to delete a user's AI consent by email (#729)
## What

Adds an Artisan command to delete a specific user's AI consent by email:

```bash
php artisan ai:delete-consent user@example.com
```

It looks up the user by email and **hard-deletes** all their AI consent
records — as if they had never granted it (no `revoked_at` trail left
behind). Since `AiCategorizationGate` requires `hasActiveAiConsent()`,
AI stops being used for that account immediately (queued categorization
jobs re-check the gate at execution time and early-return).

The command is idempotent: it reports "nothing to do" when there's no
consent on record and fails cleanly when the email doesn't exist.

## Why

Two goals:

1. **Stop using AI for a given user** on request, with no lingering
consent record.
2. **Let users who enabled AI by mistake fall back to a free plan.**
Non-Pro users with active AI consent are pushed toward the paid plan by
`EnsureUserIsSubscribed`. Deleting consent moves them back into the
free-plan-eligible bucket. This billing-gating change is **intended**,
not a side effect.

## Notes / scope decisions

- **Hard delete, not revoke.** Removes every consent row for the user
(all scopes/versions) so there's no trace they ever consented.
- **Prompt flag untouched.** `ai_consent_prompt_dismissed_at` is left
as-is, so the in-app consent banner does not re-appear to nudge them
back on.
- **Live users only.** Deleted (soft-deleted) accounts are out of scope
— they can't use the app, so their consent is moot.
- **No subscription changes.** The command only touches AI consent; it
doesn't cancel Stripe subscriptions (`user:delete` already handles that
separately).

## Tests

New Pest feature test covering all three paths (delete all consent
records incl. a revoked one / no consent on record / user not found).
Green locally.
2026-07-23 08:35:28 +00:00