Client Authentication System
Statut : ✅ TERMINÉ - Phase 5 Complétée Priorité : Haute Estimation : 8-10 semaines (5 phases) Dernière mise à jour : 2026-01-31
📊 Tableau de Bord d'Avancement
| Phase | Description | Statut | Progression |
|---|---|---|---|
| Phase 1 | MVP Authentification | ✅ Complétée | 100% |
| Phase 2 | Expérience Client | ✅ Complétée | 100% |
| Phase 3 | Messagerie | ✅ Complétée | 100% |
| Phase 4 | Fichiers et Préférences | ✅ Complétée | 100% |
| Phase 5 | Côté Photographe | ✅ Complétée | 100% |
Progression globale : 100% (5/5 phases)
📝 Journal d'Implémentation
2026-01-31 - Revue complète Portail Client (Phases 3, 4, 5)
Objectif : Corriger les bugs i18n, UX et robustesse identifiés lors de la revue des phases Messagerie, Fichiers et Côté Photographe.
Corrections i18n :
- ✅ Suppression des chaînes françaises hardcodées dans
ClientPortalMessagesPage:"fr-FR"→ locale dynamique (i18n.language),"Hier"→ cléclientPortal.messages.yesterday,"Vous: "→ cléclientPortal.messages.you - ✅ Tous les
defaultValuedu layout et de la messagerie passés en anglais (fallback FR → EN) - ✅ Ajout des clés de traduction manquantes dans
clientPortal.nav:galleries,profile,logout - ✅ Ajout des clés
clientPortal.messages.yesterday,you,markReadError(EN + FR) - ✅ Ajout des clés
clientPortal.files.downloadError,fileTooLarge(EN + FR) - ✅ Ajout de la clé
contacts.clientPortal.messages.sendError(EN + FR)
Corrections UX / robustesse :
- ✅ Fix clé d'erreur download :
uploadError→downloadErrordansClientPortalFilesPage - ✅ Validation taille 10 MB côté frontend avant upload (toast d'erreur + reset input)
- ✅ Toast d'erreur à l'envoi de message côté client (
ClientPortalMessagesPage) - ✅ Toast d'erreur sur
markAsRead(onErrorcallback) - ✅ Toast d'erreur à l'envoi de message côté photographe (
ContactClientMessagesSection) - ✅ Hauteur responsive page messages :
h-[600px]→h-[calc(100vh-12rem)] min-h-[500px] - ✅ Badge "Invitation en attente" ajouté dans
ContactCard(liste contacts), même pattern queContactHero
Fichiers modifiés :
frontend/src/i18n/locales/en/translation.json- Clés nav, messages, files, contactsfrontend/src/i18n/locales/fr/translation.json- Clés nav, messages, files, contactsfrontend/src/pages/client-portal/messages/ClientPortalMessagesPage/ClientPortalMessagesPage.tsx- i18n, toasts, hauteur responsivefrontend/src/pages/client-portal/files/ClientPortalFilesPage/ClientPortalFilesPage.tsx- Fix downloadError, validation 10 MBfrontend/src/pages/contacts/ContactsListPage/components/ContactCard.tsx- Badge pending invitationfrontend/src/pages/contacts/ContactViewPage/components/ContactClientMessagesSection.tsx- Toast erreur envoifrontend/src/components/layout/ClientPortalLayout.tsx- defaultValues EN, clés nav
2026-01-30 - Durcissement accès portail & thème
Objectif : Sécuriser le parcours d'invitation et appliquer réellement les préférences d'apparence.
Réalisations Backend :
- ✅ Endpoint
POST /client-auth/validate-invitation: validation dédiée des tokens d'invitation - ✅ Ré-invitation : suppression/invalidation des anciens tokens avant création d'un nouveau
- ✅ Fix documents client : évite les requêtes
WHERE id IN ()quand aucun owner n'est disponible
Réalisations Frontend :
- ✅ Portail login : inscription affichée uniquement si le token est valide (sinon login)
- ✅ Bannière d'invitation + message d'erreur si lien invalide/expiré
- ✅ Portail public : accès
/portal/*sans redirection vers/loginuser - ✅ Apparence : thème client (light/dark/system) appliqué sur tout le portail
- ✅ UI : liens légaux sous le bloc de connexion + lien photographe repositionné
Fichiers modifiés (extraits) :
backend/src/client-auth/client-auth.controller.tsbackend/src/client-auth/client-auth.service.tsbackend/src/client-auth/client-auth.repository.tsbackend/src/client-accounts/client-accounts.repository.tsfrontend/src/components/layout/ClientPortalLayout.tsxfrontend/src/pages/client-portal/auth/ClientPortalLoginPage/ClientPortalLoginPage.tsxfrontend/src/components/layout/AppLayout.tsx
2026-01-30 - Phase 5 Complétée
Objectif : Côté photographe - Invitation clients, badges, messages dans fiche contact
Réalisations Backend :
- ✅ Repository : 6 méthodes invitation tokens (
createInvitationToken,findInvitationTokenByHash,markInvitationTokenUsed,findPendingInvitationForContact,deleteExpiredInvitationsForContact,getClientAccountStatusForContact) - ✅ Service
ClientAuthInvitationService: création/envoi invitation, validation/consommation token, statut compte contact - ✅ Endpoint
POST /contacts/:id/invite-to-create-account: invitation avec email contenant lien portail - ✅ Endpoint
GET /contacts/:id/client-account-status: statut compte (hasAccount, accountStatus, hasPendingInvitation, invitationSentAt) - ✅ Gestion invitation token au register : validation, consommation, liaison contact avec source
INVITATION - ✅ Modules mis à jour :
ClientAuthModule(imports CommunicationModule/ConfigModule, exports InvitationService),ContactsModule(import ClientAuthModule)
Réalisations Frontend :
- ✅ Hooks :
useClientAccountStatus(contactId),useInviteToCreateAccount()dansuseContacts.ts - ✅
ContactHero: Badge vert "Portail Client" (compte actif), badge orange "Invitation en attente" - ✅
ContactHero: Action "Inviter au Portail Client" dans le menu actions - ✅
ContactViewPage: Dialog de confirmation invitation avec toast succès/erreur - ✅
ContactCard: Badge "Portail" si compte client actif - ✅
ContactClientMessagesSection: Section messages dans la fiche contact (tab Communications) - ✅
ClientPortalLoginPage: Support paramètre URLinvite, auto-switch register, bannière invitation - ✅
ClientAuthProvider+api.ts: SupportinvitationTokendans le register - ✅ i18n FR/EN : traductions invitation, badges, messages
Fichiers créés :
# Backend
backend/src/client-auth/client-auth-invitation.service.ts
# Frontend
frontend/src/pages/contacts/ContactViewPage/components/ContactClientMessagesSection.tsx
Fichiers modifiés :
backend/src/client-auth/client-auth.repository.ts- Méthodes invitation tokensbackend/src/client-auth/client-auth.service.ts- Gestion invitationToken au registerbackend/src/client-auth/client-auth.module.ts- Imports CommunicationModule, ConfigModule, exports InvitationServicebackend/src/contacts/contacts.controller.ts- Endpoints invite + client-account-statusbackend/src/contacts/contacts.module.ts- Import ClientAuthModulefrontend/src/client/contacts/useContacts.ts- Hooks et API client-account-status + invitationfrontend/src/pages/contacts/ContactViewPage/ContactViewPage.tsx- Dialog invitation + section messagesfrontend/src/pages/contacts/ContactViewPage/components/ContactHero.tsx- Badges + action invitationfrontend/src/pages/contacts/ContactsListPage/components/ContactCard.tsx- Badge portailfrontend/src/pages/client-portal/auth/ClientPortalLoginPage/ClientPortalLoginPage.tsx- Support invite tokenfrontend/src/client-auth/ClientAuthProvider.tsx- invitationToken dans registerfrontend/src/client-auth/api.ts- invitationToken dans registerfrontend/src/i18n/locales/*/translation.json- Traductions Phase 5
2026-01-29 - Phase 4 Complétée
Objectif : Stockage de fichiers personnels pour clients + Page paramètres complète
Réalisations Backend :
- ✅ Migration 0163 : Table
client_filesavec indexes - ✅ Module
client-files: Repository, Service, Controller avec 5 endpoints - ✅ Endpoints : list, presigned-url, create record, download, delete
- ✅ Validation types fichiers réutilisée depuis
contact-files/file-validation.ts - ✅ Clé storage :
client-files/{clientAccountId}/{uuid}.{ext} - ✅ Max 10MB par fichier
- ✅ OpenAPI : schemas et paths dans
client-files.yaml - ✅ Types Kysely :
ClientFileTable
Réalisations Frontend - Page Fichiers :
- ✅
ClientPortalFilesPage: Liste fichiers avec icônes par type - ✅ Upload via presigned URL (workflow complet)
- ✅ Téléchargement via URL signée
- ✅ Suppression avec confirmation (AlertDialog)
- ✅ État vide avec illustration