Pro Account Deactivation and Reactivation

Summary

Admins can deactivate a Pro account (with a mandatory reason) or reactivate it. Deactivation immediately kills all active sessions by deleting refresh tokens, preventing any further authenticated access. Both actions are recorded in the audit log. Deactivated pros see a clear error message at login directing them to support.

State Diagram

stateDiagram-v2
    state "Compte actif" as Active
    state "Désactivation en cours" as Deactivating
    state "Compte inactif" as Inactive
    state "Réactivation en cours" as Reactivating

    [*] --> Active: Pro registered
    Active --> Deactivating: admin deactivates account
    Deactivating --> Inactive: isActive=false, sessions killed, audit logged
    Inactive --> Reactivating: admin reactivates account
    Reactivating --> Active: isActive=true, deactivationReason cleared, audit logged
    Inactive --> [*]
    Active --> [*]

Steps

1. Deactivate Account (Actor: admin)

PATCH /admin/pros/:id/deactivate with body { deactivationReason: string } (required field).

The system fetches the Pro. If not found → 404 NOT_FOUND.

In a single prisma.$transaction:

  • Sets isActive = false and deactivationReason on the Pro.
  • Calls prisma.proRefreshToken.deleteMany({ where: { proId } }) — all active sessions across all devices are immediately invalidated.
  • Inserts an AuditLog entry with action: "pro.deactivate", targetType: "pro", targetId, actorId, metadata: { reason: deactivationReason }.

Triggers: Admin takes moderation action Outcome: Account locked; all sessions terminated; action logged

2. Effect on Pro Session (Actor: system)

After deactivation:

  • Any existing access token (valid for up to 15 min) will fail at the authenticatePro hook DB check on the next request — the hook checks isActive on every call.
  • The refresh token is gone from DB, so token refresh will fail with 401 UNAUTHORIZED.
  • Login attempts return 403 ACCOUNT_DISABLED with message “Votre compte a été désactivé. Contactez support@sealion.fr”.

Triggers: Pro attempts to use their account after deactivation Outcome: All API access blocked

3. Reactivate Account (Actor: admin)

PATCH /admin/pros/:id/reactivate (no body required).

The system fetches the Pro. If not found → 404 NOT_FOUND. If already active → 409 ALREADY_ACTIVE.

In a single prisma.$transaction:

  • Sets isActive = true and deactivationReason = null.
  • Inserts an AuditLog entry with action: "pro.reactivate", targetType: "pro", targetId, actorId.

No new sessions are issued — the Pro must log in again manually.

Triggers: Admin lifts the moderation action Outcome: Account restored; Pro can log in

Error States

  • Pro not found → 404 NOT_FOUND
  • Reactivating an already active Pro → 409 ALREADY_ACTIVE
  • Deactivated Pro trying to log in → 403 ACCOUNT_DISABLED
  • Deactivated Pro using existing access token → blocked by authenticatePro isActive check
  • login-session — deactivation blocks login; reactivation restores access
  • registration — account must exist before it can be deactivated