Navbar admin :
- Barre de recherche persistante en haut de toutes les pages admin
- Recherche dans tous les index Meilisearch simultanément :
clients (5), NDD (5), sites (5), contacts (5), revendeurs (3)
- Résultats en dropdown glassmorphism avec icône par type
- Clic sur un résultat → page + tab correspondant :
Client → /admin/clients/{id}
NDD → /admin/clients/{id}?tab=ndd
Site → /admin/clients/{id}?tab=sites
Contact → /admin/clients/{id}?tab=contacts
Revendeur → /admin/revendeurs/{id}/edit
DashboardController::globalSearch :
- Route GET /admin/global-search?q=...
- Agrège les résultats de 5 index Meilisearch
- Retourne [{type, label, sub, url}]
app.js :
- Debounce 250ms, min 2 chars
- Badges type (Client, NDD, Site, Contact, Revendeur)
- Fermeture Escape / clic extérieur
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pages services :
- /admin/services/ndd : liste tous les NDD avec client, registrar,
Cloudflare, gestion, facturation, expiration + barre recherche
- /admin/services/esyweb : liste tous les sites avec client, UUID,
type, statut + barre recherche
- Liens sidebar mis à jour (Esy-Web → esyweb, Nom de domaine → ndd)
MeilisearchService :
- Index customer_ndd : searchable fqdn/registrar/customerName/customerEmail,
filterable customerId/isGestion/isBilling
- Index customer_website : searchable name/uuid/customerName/customerEmail,
filterable customerId/type/state
- CRUD : indexDomain/removeDomain/searchDomains, indexWebsite/removeWebsite/searchWebsites
- Serializers avec infos client intégrées (customerName, customerEmail, customerId)
SyncController :
- Route POST /admin/sync/domains : sync tous les Domain dans Meilisearch
- Route POST /admin/sync/websites : sync tous les Website dans Meilisearch
- Compteurs totalDomains et totalWebsites dans index
Template admin/sync :
- Bloc "Noms de domaine" (slate) avec bouton sync
- Bloc "Sites Internet" (blue) avec bouton sync
Recherche (app.js) :
- renderHit adapté : affiche fqdn/name pour NDD/sites, customerName en sous-texte
- Lien vers la fiche client (customerId) pour les résultats NDD/Website
- setupSearch configuré pour search-ndd et search-websites
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend (ClientsController::entrepriseSearch) :
- Route GET /admin/clients/entreprise-search?q=...
- Proxy PHP vers https://recherche-entreprises.api.gouv.fr/search
(pas d'appel API direct depuis le JS)
- Retourne JSON avec results[], total_results
- Gestion erreur avec 502 si API indisponible
Frontend (assets/modules/entreprise-search.js) :
- Module JS séparé, pas de script inline (CSP compatible)
- Modal glassmorphism avec champ recherche et liste résultats
- Chaque résultat affiche : nom, SIREN, SIRET, adresse, dirigeant, statut
- Au clic sur un résultat, auto-remplissage du formulaire :
raisonSociale, siret, numTva (calcul clé TVA), address, zipCode, city
+ firstName/lastName du dirigeant si les champs sont vides
- Fermeture modal via overlay, bouton X, ou Escape
Template :
- Bouton "Rechercher SIRET / SIREN" à côté du bouton Retour
- Modal HTML avec header glass-dark, champ recherche, zone résultats scrollable
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Problem: OAuth login failed because the authenticator was checking for
old Keycloak group names (super_admin_asso, gp_member) that no longer
exist in the master realm.
Changes:
- src/Security/KeycloakAuthenticator.php:106: resolveRoles() now checks
for 'siteconseil_admin' instead of 'super_admin_asso' to grant ROLE_ROOT
- src/Controller/Admin/MembresController.php:140: member creation role
resolution updated from 'super_admin_asso' to 'siteconseil_admin'
- templates/admin/membres.html.twig: checkbox values updated from
'gp_member' to 'siteconseil_member' and 'super_admin_asso' to
'siteconseil_admin' in the member management form
- assets/app.js:5-6: JS mutual exclusion logic updated to use new
group values 'siteconseil_member' and 'siteconseil_admin'
- tests/Security/KeycloakAuthenticatorTest.php:79: test data updated
from 'super_admin_asso' to 'siteconseil_admin'
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace email layout tables with CSS divs in base.html.twig
- Replace deprecated width/align attributes with CSS styles in PDF templates
- Add role="presentation" to email layout tables
- Convert td to th[scope=row] in profil and attestation verify tables
- Reduce function nesting in app.js by extracting renderHit/performSearch
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>