Documentation

Espace utilisateur

Profil, avatar R2, settings, organizations, API keys et danger zone.

L'espace user vit sous /account. Layout <UserShell> (sidebar + header).

Profil (/account)

Page principale : avatar inline, nom, username, profil public.

  • Avatar uploadable au survol (overlay caméra), pas besoin d'aller dans settings — UX onboarding-friendly. Stocké sur Cloudflare R2.
  • Username unique (User.username), modifiable, lowercase a-z 0-9 _. Profil public visible sur /u/[username].
  • Email locked — non modifiable côté user (changement = re-verif).

Settings (/account/settings)

Tabs :

1. Profil

Nom, username, locale (fr/en), avatar. Bouton Changer à côté de l'email pour le flow change-email.

2. Sécurité

  • Changer mot de passe (vérifie l'ancien, bump tokenVersion)
  • Toggle 2FA — email et/ou TOTP (Google Authenticator). Voir 2FA
  • Sessions actives : liste + bouton "Révoquer" par session
  • Connections OAuth : link/unlink GitHub, Google

3. Notifications

Toggles email :

  • Security — toujours ON, non modifiable (login alerts, password reset, 2FA)
  • Product — updates produit, nouvelles features
  • Marketing — promos, newsletter

Stockés dans User.productEmails et User.marketingEmails.

4. Billing

Plan actuel (depuis DB), code coupon actif, 6 dernières factures Stripe, boutons Stripe Portal et Changer de plan. Voir Facturation.

5. Danger zone

Schedule deletion — set User.deletionScheduledAt = now + 7j. Pendant ces 7 jours, l'user peut annuler avec un bouton "Cancel deletion". Au-delà, un cron Trigger.dev (/api/cron/...) hard-delete.

Tu peux modifier le délai dans lib/auth.ts ou la route /api/user/delete-account.

Activité (/account/activity)

Historique des actions sensibles : connexions, changements sécurité, partages. Voir Activity log.

Parrainage (/account/referrals)

Liste filleuls + bouton copier code/URL. Voir Parrainage.

Organizations (/account/organizations)

CRUD orgs. Modèles Organization + OrganizationMember(role). Invites par email via /api/invite (mailé via template custom à brancher).

Liste DataList, default view = card (cf. DataList).

API Keys (/account/api-keys)

Génère des clés pour usage programmatique. Modèle ApiKey :

  • key unique (préfixe sk_ + bytes random)
  • lastUsedAt, revokedAt
  • Affichée une seule fois à la création (toast + bouton copier)

Helper côté server pour authentifier les requêtes :

import { authenticateApiKey } from "@/lib/api-key-auth";

const user = await authenticateApiKey(request);
if (!user) return new Response("Unauthorized", { status: 401 });

Headers acceptés : Authorization: Bearer sk_xxx.

Profil public (/u/[username])

Hors [locale]. Affiche name, avatar, bio (à brancher si tu veux). Sert aussi pour le partage de référral (/r/[code] redirige vers register en posant le cookie).

Allez plus loin

On this page