From 7d81470c05d555b8774f88d4f83677d301cdda0e Mon Sep 17 00:00:00 2001 From: aliceout Date: Wed, 4 Feb 2026 12:29:40 +0300 Subject: [PATCH 1/9] dev docs creation --- .gitignore | 1 + docs/guides/README.md | 28 ++ docs/guides/onboarding.md | 54 ++++ docs/modules/README.md | 9 + docs/modules/back-office-edition.md | 42 +++ docs/modules/back-office-users.md | 56 ++++ docs/modules/front-office.md | 42 +++ docs/specifications.md | 410 ++++++++++++++++------------ docs/technical/README.md | 10 + docs/technical/api.md | 65 +++++ docs/technical/auth.md | 45 +++ docs/technical/vigilance.md | 20 ++ docs/technical/zones.md | 38 +++ 13 files changed, 642 insertions(+), 178 deletions(-) create mode 100644 docs/guides/README.md create mode 100644 docs/guides/onboarding.md create mode 100644 docs/modules/README.md create mode 100644 docs/modules/back-office-edition.md create mode 100644 docs/modules/back-office-users.md create mode 100644 docs/modules/front-office.md create mode 100644 docs/technical/README.md create mode 100644 docs/technical/api.md create mode 100644 docs/technical/auth.md create mode 100644 docs/technical/vigilance.md create mode 100644 docs/technical/zones.md diff --git a/.gitignore b/.gitignore index cb3f2a3..16b8f99 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ dist-ssr *.sw? yarn.lock .gitignore +export.md diff --git a/docs/guides/README.md b/docs/guides/README.md new file mode 100644 index 0000000..9822589 --- /dev/null +++ b/docs/guides/README.md @@ -0,0 +1,28 @@ +# Documentation modules + +Ce dossier contient la documentation technique par domaine fonctionnel. + +## Utilisation de la doc + +- **Onboarding nouveau dev** : commencer par `docs/guides/onboarding.md` +- **Reference technique** : utiliser les fichiers de `docs/modules/` et `docs/technical/` selon le perimetre modifie + +## Index + +- `docs/modules/front-office.md` : parcours public, recherche, resultats, fiche organisme +- `docs/modules/back-office-edition.md` : edition des organismes (CRUD, archivage, filtres) +- `docs/modules/back-office-users.md` : gestion des utilisateurs et droits +- `docs/technical/auth.md` : authentification, session, securite client +- `docs/technical/zones.md` : fonctionnement des zones et impact metier +- `docs/technical/api.md` : organisation des appels API et conventions +- `docs/technical/vigilance.md` : liste centralisee des points a surveiller/corriger + +## Convention de mise a jour + +Pour chaque PR, mettre a jour les fichiers impactes: + +1. Objectif / perimetre +2. Routes et composants touches +3. Flux de donnees / API +4. Regles de droits +5. Cas limites et points de vigilance diff --git a/docs/guides/onboarding.md b/docs/guides/onboarding.md new file mode 100644 index 0000000..279df6e --- /dev/null +++ b/docs/guides/onboarding.md @@ -0,0 +1,54 @@ +# Onboarding developpeur + +Ce guide est le point d'entree rapide pour contribuer a la webapp. + +## 1) Contexte du projet + +- Frontend: ce repo (`web_app`) +- Backend: Directus (`https://github.com/Watizat/directus`) +- Le frontend depend du backend pour fonctionner (auth, donnees, edition, roles, zones). + +## 2) Setup local + +```bash +npm install +npm run dev +``` + +Puis ouvrir `http://localhost:5173`. + +## 3) Parcours de lecture conseille (30 min) + +1. `docs/specifications.md` (vue d'ensemble) +2. `docs/modules/front-office.md` +3. `docs/modules/back-office-edition.md` +4. `docs/modules/back-office-users.md` +5. `docs/technical/auth.md` +6. `docs/technical/zones.md` +7. `docs/technical/api.md` +8. `docs/technical/vigilance.md` + +## 4) Fichiers source a connaitre + +- `src/router.tsx` : routes front/back +- `src/context/AppStateContext.tsx` : state global +- `src/components/App/FrontOffice.tsx` : shell front +- `src/components/App/BackOffice.tsx` : shell back + guard auth +- `src/utils/axios.ts` : auth bearer + refresh + +## 5) Regles de contribution doc + +A chaque PR, mettre a jour au moins un fichier dans `docs/modules/` ou `docs/technical/` si le comportement change. + +## 6) Verification minimale avant PR + +```bash +npm run lint +npm run build +``` + +Si un flux metier est touche, verifier manuellement: + +- login/logout +- parcours recherche front (zone + categorie) +- ecran admin impacte diff --git a/docs/modules/README.md b/docs/modules/README.md new file mode 100644 index 0000000..76d4ee5 --- /dev/null +++ b/docs/modules/README.md @@ -0,0 +1,9 @@ +# Modules fonctionnels + +Ce dossier contient uniquement les modules metier du produit. + +- `docs/modules/front-office.md` +- `docs/modules/back-office-edition.md` +- `docs/modules/back-office-users.md` + +Les sujets transversaux (auth, zones, API) sont dans `docs/technical/`. diff --git a/docs/modules/back-office-edition.md b/docs/modules/back-office-edition.md new file mode 100644 index 0000000..3b7a32e --- /dev/null +++ b/docs/modules/back-office-edition.md @@ -0,0 +1,42 @@ +# Module Back Office - Edition + +## Objectif + +Gerer le referentiel d'organismes: creation, edition, gestion des services/contacts, archivage. + +## Routes concernees + +- `/admin/edition` + +## Composants / fichiers cles + +- `src/components/BackOffice/Edition/Edition.tsx` +- `src/components/BackOffice/Edition/SideList.tsx` +- `src/components/BackOffice/Edition/DataPanel/*` +- `src/components/BackOffice/SlideOvers/Edition/*` +- `src/components/Modals/ArchiveOrganism.tsx` +- `src/context/BackOfficeContext.tsx` +- `src/api/admin.ts` +- `src/api/crud.ts` + +## Flux principal + +1. Chargement de la liste des organismes selon la zone active (`fetchAdminOrganisms`). +2. Selection d'un organisme -> chargement detail (`fetchAdminOrganism`). +3. Edition via slide-over (general, infos, services, contacts, visibilite). +4. Archivage/desarchivage via `editOrganismVisibility`. +5. Rafraichissement liste/detail apres mutation. + +## Etat UI local (BackOfficeContext) + +- `isOpenSlideNewOrga` +- `isOpenFiltersOrga` +- `isDisplayArchivedOrga` + +## Regles metier principales + +- La liste est filtree par zone et par visibilite. +- Un organisme archive est `visible = false` avec message `visible_comment` possible. +- Creation/edition geolocalise l'adresse via `api-adresse.data.gouv.fr`. + +Points de vigilance de ce module: `docs/technical/vigilance.md`. diff --git a/docs/modules/back-office-users.md b/docs/modules/back-office-users.md new file mode 100644 index 0000000..d913aa6 --- /dev/null +++ b/docs/modules/back-office-users.md @@ -0,0 +1,56 @@ +# Module Back Office - Utilisateurs + +## Objectif + +Gerer les comptes membres, leur role, leur zone de rattachement et leur cycle de vie. + +## Routes concernees + +- `/admin/users` +- `/admin/profil` +- `/account-request` (entree creation de compte) + +## Composants / fichiers cles + +- `src/components/BackOffice/Users/Users.tsx` +- `src/components/BackOffice/Users/UserLine.tsx` +- `src/components/BackOffice/SlideOvers/Users/EditUser.tsx` +- `src/components/BackOffice/Profil.tsx` +- `src/components/BackOffice/SlideOvers/Profil/EditProfil.tsx` +- `src/api/admin.ts` (`fetchUsers`, `fetchRoles`) +- `src/api/user.ts` (`registerUser`, `editUser`, `updateUserStatus`, `fetchMe`) +- `src/components/BackOffice/Sidebar/SideBase.tsx` +- `src/components/BackOffice/Dashboard/Dashboard.tsx` + +## Roles observes et droits frontend + +- `Administrator` +- `RefLocal` +- `Edition` +- `NewUser` +- `UserToDelete` + +## Matrice des droits (frontend) + +| Action | Administrator | RefLocal | Edition | NewUser | UserToDelete | +|---|---|---|---|---|---| +| Acceder au back-office (`/admin/*`) | Oui | Oui | Oui | Non | Non | +| Acceder a `/admin/users` | Oui | Oui | Non | Non | Non | +| Changer la zone active dans le header back-office | Oui | Oui | Non | Non | Non | +| Voir l'entree "Back-end" dans la navigation | Oui | Non | Non | Non | Non | +| Modifier un utilisateur (nom/email/role/zone) | Oui | Oui | Non | Non | Non | +| Attribuer le role `Administrator` depuis l'UI users | Oui | Oui* | Non | Non | Non | +| Archiver / reactiver un utilisateur | Oui | Oui | Non | Non | Non | + +\* Cote frontend actuel, `RefLocal` a acces a la meme UI de role/zone qu'`Administrator`. Les droits effectifs finaux dependent des regles backend Directus. + +## Flux principal gestion users + +1. Recuperation du role courant via `/users/me`. +2. Chargement users selon zone: + - admin/reflocal: zone active (ou toutes si pas de zone selectionnee) + - autres: zone du user connecte +3. Edition d'un user via slide-over (`editUser`). +4. Changement de statut via `updateUserStatus` (`active`, `suspended`, `archived`). + +Points de vigilance de ce module: `docs/technical/vigilance.md`. diff --git a/docs/modules/front-office.md b/docs/modules/front-office.md new file mode 100644 index 0000000..d8f6b72 --- /dev/null +++ b/docs/modules/front-office.md @@ -0,0 +1,42 @@ +# Module Front Office + +## Objectif + +Permettre la consultation publique du guide: recherche d'organismes, consultation des resultats et fiche detail. + +## Routes concernees + +- `/` (home et formulaire de recherche) +- `/resultats` +- `/organisme/:slug` +- `/mentions-legales` +- `/guides-papier` + +## Composants / fichiers cles + +- `src/components/App/FrontOffice.tsx` +- `src/components/FrontOffice/Home/SearchBox.tsx` +- `src/components/FrontOffice/Resultats/Resultats.tsx` +- `src/components/FrontOffice/Organisme/Organisme.tsx` +- `src/api/organisms.ts` + +## Flux principal + +1. Chargement initial des categories, zones et jours (`FrontOffice.tsx`). +2. L'utilisateur choisit zone + categorie sur la home. +3. Navigation vers `/resultats?city=...&category=...`. +4. `Resultats.tsx` charge: + - la position de la zone (`fetchCityPosition`) + - la liste des organismes (`fetchOrganisms`) +5. Clic sur un organisme -> `organisme/:slug` puis `fetchOrganism`. + +## Donnees d'etat cle + +- `organismState.categories` +- `organismState.organisms` +- `organismState.filteredOrganisms` +- `organismState.organism` +- `organismState.days` +- `adminState.zones` + +Points de vigilance de ce module: `docs/technical/vigilance.md`. diff --git a/docs/specifications.md b/docs/specifications.md index de49291..988b743 100644 --- a/docs/specifications.md +++ b/docs/specifications.md @@ -1,178 +1,232 @@ ---- - ---- - -# Cahier des charges - -## I- Votre structure - -### Présentez votre entreprise : ( son histoire, sa taille (CA et nombre de salariés), ses activités principales, ses produits et services vendus, Votre positionnement concurrentiel : qui sont vos trois principaux concurrents ? quel est l’élément différenciant de votre activité/de votre communication ? quelle est votre positionnement de gamme (haut/bas/milieu) ou votre niveau de service (sur mesure/préfabriqué) ? ) - -Il y a une association qui se nomme Watizat (une des assos dans laquelle je suis bénevole) - -Son objet est d'éditer un guide à destination des personnes exilées récapitulant l'ensemble de services (publics, privés, associatifs) accessible dans une ville donnée (logement, distribution de nourriture, asso LGBT pour réfugié·e·s, asso de lutte contre les violences basées sur le genre, etc). - -Actuellement le guide est edité par trois groupes locaux, dans trois villes : Paris, Lyon, Toulouse (bientôt Marseille ?) - -Le guide est édité en plusieurs langues : français, anglais, espagnol, dari, pachtou, arabe (langues différentes selon les villes) - -Le guide est mis à jour régulièrement : Paris (tous les mois), Lyon et Toulouse (tous les deux mois) - -Exemple de guide : - -## II- Votre projet - -### PLANNING PRÉVISIONNEL Indiquez, ici, si vous avez des attentes particulières pour la mise en ligne de votre site. Précisez également si vous attendez une mise en ligne en plusieurs phases - -Livrable à rendre pour la fin de l'apothéose - -Version minimale à rendre pour l3 - -### COMITÉ DE PILOTAGE : Indiquez ici quels seront les processus de validation sein de votre entreprise et qui se chargera des différentes missions suivantes : valider les phases de choix (graphisme, ergonomie, contenus), valider le respect du cahier des charges, veiller au respect des délais, fournir les contenus de base (textes, plaquettes, logos, images, photos) - -Pilotage uniquement en interne (équipe stagiaires o'clock) avec lien siège Watizat (de loin) - -### Vos attentes ? : faire connaître l’entreprise, vendre vos produits sur internet, donner à vos clients des conseils sur vos produits ou services, générer des contacts de nouveaux prospects - -Donner de l'information avtuellement seulement en version papier à des personnes exilées sur mobile et desktop via un service web, et créer une base de données permettant aussi d'alimenter une application mobile native - -### Objectifs du site Indiquez les principales vocations du site : site de vente, site d’information, support de communication, support de fidélisation - -Permettre l'accès aus données sur une carte et/ou via un système de recherche, de filtre les types de services par pleins de filtres. - -L'API servira à terme aussi bien au site desktop et mobile, qu'à l'application mobile en cours de refonte - -### À qui s’adresse le site – Les cibles Notez ici le nombre de cibles différentes et les hiérarchiser. Pour chacune, merci de préciser - -Personnes exilées, et travailleu·r·se·s socia·ux·les - -### Langues Préciser ici en quelles versions linguistiques le site sera disponible. Si le site est en plusieurs langues, s’agira-t-il de versions identiques ou de versions adaptées. Dans ce cas précisez. Indiquez également qui se chargera des éventuels besoins en traduction - -Gestion de plusieurs langues (anglais, espagnol, patchou, dari, arabe, etc) (v2) - -Peut-être à faire dans un second temps, hors apothèose ? - -### Développement Spécifiez si dans le site, il faut des éléments qui font appel à de la programmation et à des bases de données - -Beaucoup de travail sur le côté data, gestion et modification des données - -### STATISTIQUES Avez-vous des attentes particulières en matière de statistiques de fréquentation ? - -Peut-être quelque question (V2) sur les catégories les plus utilisées - -### Arborescence – Plan du site Proposez une arborescence pour montrer l’architecture du site telle que vous l’imaginez. Celle-ci sera présentée sous forme schématique avec les rubriques principales, les sous rubriques et les liens qui les unissent - -``` -Accueil -├── Résultat (carte + liste) -│   ├── Fiche de détail -│   └── Export fil d'orientation -├── Page de connexion -│   ├── Accueil espace admin    -| │   ├── Espace modification des données -| │   ├── Gestion des utilisateurs -| │   ├── Espace graphiste (v3) -| │   ├── Espace actualisation (v3)  -| │   └── Espace traduction (v2) -│   ├── Demande de création de compte -│   └── Mot de passe oublié -│   │   └── Réinitialisation de mot de passe -``` - -### Technologies utilisées - -- Front : Typescript · React + (framework CSS à déterminer) - -- Back ! Directus - -- Api externes : gestion des données de transport (soit agrégées via un sevrice spécifique, soit à l'échelle de chaque ville) - -### Fonctionnalités attendues - -#### **Fonctionnalités à dev front :** - -##### **Page Accueil** - -- API CRUD (à première vu Directus peut le gérer avec les éléments de la BDD) ***v1*** - -- Filtre par ville ***v1*** - -- Filtre par catégorie ***v1*** - -- Switch de langue ***v2*** - -- Gestion des cookies (comment qu’on fait??) ***v1*** - -- Fil d'orientation (panier/favoris) ***v1*** - -###### **Page Résultat de recherche** - -- filtre (catégorie, service..) ***v1*** - -- affichage des résultats ***v1*** - -- Maps ***v1*** - -##### **Fiche Organisme/Filiale :** - -- Affichage des différentes infos ***v1*** - -- Affichage des données de transport **v1 (sauf si difficulté avec API et besoin de construire quelque chose de spécifique)** - -#### **Fonctionnalités à dev back :** - -- affichage des services : différents états, par qui, quand (cf maquette) ***v1*** - -- accès suivant les rôles ***v1*** - -#### Fonctionnalités des prochaines versions - -##### v1.1 - -- Fil d'orientation social - -- Fonctions d'export du fil - -- Sidebar plus d'infos - -##### v.2 - -- Espace traduction - -- Gestion des langues - -##### v.3 - -- Espace graphiste - -### Hébergement Indiquez, ici, si vous souhaitez que l’agence vous propose une prestation d’hébergement et éventuellement de quel type d’hébergement il s’agira - -Hébergement déjà assuré en interne par l’association Watizat sur son propre serveur - -Rien à faire de ce côté là - -### Référencement Indiquez, ici, si vous souhaitez que l’agence prenne en charge le référencement de votre site auprès des moteurs de recherche. Précisez quels sont vos objectifs en la matière, si vous attendez une prestation de suivi et de quelle nature. Indiquez également si possible sur quels axes vus souhaitez vous positionner - -Peu important pour ce site pour le moment - -En effet, le guide est déjà extrêmement connu, et le site de Watizat pointera – au moins pour le moment – principalement vers le site actuel - -Ce site est ubn outil de l'association, et non sa vitrine - -### Dépôt du nom de domaine et adresses mail Indiquez, ici, si vous souhaitez que l’agence se charge de déposer un ou plusieurs noms de domaine. Si vous êtes déjà propriétaire d’un nom de domaine. Précisez si l’agence doit se charger du transfert du nom de domaine auprès de l’hébergeur du site - -Rien à faire par ici - -### Vos outils de communication - -*Logo* : Oui et sous format numérique - -*Identité visuelle* : Oui - -*Site internet* : Oui () - -*Blog* : Non - -*Newsletter* : Non - -*Réseaux sociaux* : Forte présence et forte communauté (Facebook, Instagram, Twitter) +# Documentation developpeur - WebApp Watizat + +## 0) Organisation de la documentation + +Documentation fonctionnelle par module dans `docs/modules/` : + +- `docs/modules/front-office.md` +- `docs/modules/back-office-edition.md` +- `docs/modules/back-office-users.md` + +Documentation technique transversale dans `docs/technical/` : + +- `docs/technical/auth.md` +- `docs/technical/zones.md` +- `docs/technical/api.md` +- `docs/technical/vigilance.md` + +Parcours recommandes selon le besoin: + +- **Onboarding nouveau dev** : `docs/guides/onboarding.md` +- **Reference technique** : ce fichier + `docs/modules/*.md` + `docs/technical/*.md` + +Utiliser ce fichier comme **vue globale**, et les autres dossiers comme references de travail pour les evolutions. + +--- + +## 1) Objectif du projet + +Cette application contient deux espaces : + +- **Front office** : consultation publique du guide (recherche par zone + categorie, vue resultats, fiche organisme). +- **Back office** : administration du guide (edition des organismes, gestion des utilisateurs, profil). + +Le frontend (ce repo) depend d'un backend Directus. + +- Repo backend : `https://github.com/Watizat/directus` +- Sans ce backend, la webapp ne peut pas fonctionner correctement (auth, donnees, edition, zones, roles). + +--- + +## 2) Stack et architecture technique + +- **Framework** : React 18 + TypeScript + Vite +- **Styling** : Tailwind CSS +- **Routing** : `react-router-dom` +- **HTTP** : `axios` (instance centralisee) +- **Formulaires** : `react-hook-form` +- **Carte** : Leaflet / React-Leaflet +- **Auth** : JWT (login + refresh token) + +Entree de l'app : `src/main.tsx` +Router principal : `src/router.tsx` +Etat global : `src/context/AppStateContext.tsx` +Contexte back-office (UI locale) : `src/context/BackOfficeContext.tsx` + +--- + +## 3) Comment le site est construit + +### Arborescence logique + +- `src/components/App/FrontOffice.tsx` : shell front (header/footer + preload categories/zones/jours) +- `src/components/App/BackOffice.tsx` : shell back (auth guard, chargement roles/zones, layout sidebar/header) +- `src/components/FrontOffice/*` : pages publiques +- `src/components/BackOffice/*` : pages admin +- `src/api/*` : appels API (Directus + geocodage adresse) +- `src/utils/axios.ts` : gestion auth, injection bearer, refresh token + +### Routing (haut niveau) + +- Front : + - `/` (home / recherche) + - `/resultats` + - `/organisme/:slug` + - `/login`, `/account-request`, `/forgotten-password`, `/recover-password` + - pages statiques (`/mentions-legales`, `/guides-papier`) +- Back : + - `/admin/dashboard` + - `/admin/edition` + - `/admin/users` + - `/admin/profil` + +Note : les entrees `Traduction`, `Print`, `Actualisation` sont visibles dans certains menus mais les routes ne sont pas implementees dans ce repo (fonctionnalites prevues/non actives). + +--- + +## 4) Front office : fonctionnement + +### Parcours principal + +1. L'utilisateur choisit une **zone** + une **categorie** sur la home. +2. L'app navigue vers `/resultats?city=...&category=...`. +3. `Resultats.tsx` : + - recupere la position de la zone (`fetchCityPosition`) + - recupere les organismes de la zone (`fetchOrganisms`) + - alimente le state global (`organismState`) +4. Clic sur un organisme -> `/organisme/:slug` puis chargement des details (`fetchOrganism`). + +### Donnees front importantes + +- `organismState.categories` : categories de services +- `organismState.organisms` / `filteredOrganisms` : resultats de recherche +- `organismState.organism` : organisme affiche dans la fiche +- `adminState.zones` : liste des zones (aussi utilisee dans le front pour les selects) + +--- + +## 5) Back office : fonctionnement + +### Garde d'acces + +`BackOffice.tsx` : + +- verifie la session locale (`localStorage.user`) +- appelle `/users/me` +- bloque/redirige vers `/login` si non authentifie +- refuse l'acces aux roles `NewUser` / `UserToDelete` + +### Modules actifs + +- **Dashboard** : point d'entree admin avec tuiles de navigation +- **Edition** : liste d'organismes + panneau detail + creation/edition/archivage +- **Utilisateurs** : liste et edition des comptes +- **Profil** : consultation/edition de son profil + +### Specificites UX + +- Le back office est volontairement bloque sur mobile (`NoMobile.tsx`). +- Le header back-office permet de changer de zone (uniquement pour certains roles utilisateur.ice.s). + +--- + +## 6) Roles utilisateurs et droits + +Les roles sont recuperes depuis Directus (`/roles`, `/users/me`). +Le code manipule a la fois des **noms de role** (`Administrator`, `RefLocal`, `Edition`, etc.) et des **UUID** (legacy dans certains composants). + +### Roles metiers observes + +- `Administrator` +- `RefLocal` +- `Edition` +- `NewUser` +- `UserToDelete` + +### Differences de droits (dans le frontend) + +- **Administrator** + - acces complet au back-office + - acces a la gestion utilisateur + - peut changer la zone active dans le header + - voit le lien "Back-end" +- **RefLocal** + - acces back-office et gestion utilisateur + - peut changer la zone active dans le header + - pas d'acces "Back-end" dans la navigation filtree +- **Edition** + - acces edition/dashboards limites + - pas d'acces au module utilisateurs + - pas de changement global de zone (zone figee selon son rattachement) +- **NewUser** + - acces back-office refuse (deconnexion + retour login) + - user en attente de validation par un.e admin ou refLocal +- **UserToDelete** + - acces back-office refuse (deconnexion + retour login) + - user en attente de suppression definitive par un.e admin ou refLocal + +--- + +## 7) Les zones : ce que c'est et ce que ca change + +Une **zone** represente une antenne / territoire (ex: ville). + +### Ou elles sont utilisees + +- Front office : + - choix de zone pour la recherche + - filtrage des organismes par `zone_id.name` + - centrage carte selon la zone +- Back office : + - filtrage des organismes affiches dans Edition selon la zone active + - filtrage des utilisateurs selon la zone + - affectation d'une zone lors de la creation/edition d'un user ou d'un organisme + +### Impact concret + +- Changer de zone change immediatement le perimetre des donnees affichees. +- Les roles non-admin sont limites a leur zone de rattachement. +- La zone selectionnee est persistee en local (`localStorage.city`) pour garder le contexte entre pages. + +--- + +## 8) Modele de donnees (resume) + +Principales collections Directus manipulees : + +- `organisme` (+ `organisme_translation`) +- `service` (+ `service_translation`) +- `contact` +- `schedule` +- `zone` +- `categorie` (+ traductions) +- `users` +- `roles` + +Relations importantes : + +- un organisme appartient a une zone (`zone_id`) +- un organisme contient des services, contacts, horaires +- un utilisateur est rattache a une zone (`user.zone`) et a un role (`user.role`) + +--- + +## 9) Authentification et session + +- Login via `/auth/login`, token stocke dans `localStorage.user`. +- Intercepteur Axios : + - ajoute le bearer token aux requetes + - rafraichit automatiquement via `/auth/refresh` si expire + - deconnecte si refresh invalide +- Deconnexion automatique par inactivite (`InactivityDetector`) apres timeout. + +--- + +## 10) Demarrage local + +```bash +npm install +npm run dev +``` + +Puis ouvrir `http://localhost:5173`. diff --git a/docs/technical/README.md b/docs/technical/README.md new file mode 100644 index 0000000..a95380f --- /dev/null +++ b/docs/technical/README.md @@ -0,0 +1,10 @@ +# Documentation technique transversale + +Ce dossier contient les sujets techniques qui traversent plusieurs modules. + +- `docs/technical/auth.md` +- `docs/technical/zones.md` +- `docs/technical/api.md` +- `docs/technical/vigilance.md` + +Les modules metier sont dans `docs/modules/`. diff --git a/docs/technical/api.md b/docs/technical/api.md new file mode 100644 index 0000000..c2f64b5 --- /dev/null +++ b/docs/technical/api.md @@ -0,0 +1,65 @@ +# Technique - API + +## Objectif + +Centraliser les conventions d'appel API et la cartographie des principaux endpoints utilises par le frontend. + +## Organisation des fichiers + +- `src/utils/axios.ts` : instance Axios + interceptors auth/refresh +- `src/api/user.ts` : auth et users +- `src/api/admin.ts` : zones, roles, listes admin +- `src/api/organisms.ts` : consultation front des organismes +- `src/api/crud.ts` : mutations organisme/service/contact +- `src/api/navitia.ts` : transport (si active) + +## Base URL et auth + +- Base URL: `https://api.watizat.app` +- Bearer token injecte automatiquement si session presente +- Refresh token via `POST /auth/refresh` +- En cas d'echec refresh: purge session + redirection login + +## Endpoints principaux utilises + +### Auth / user + +- `POST /auth/login` +- `POST /auth/logout` +- `POST /auth/password/request` +- `GET /users/me` +- `POST /users` +- `PATCH /users/:id` + +### Zones / roles / users admin + +- `GET /items/zone` +- `GET /roles` +- `GET /users` (filtre par zone) + +### Organismes / contenu guide + +- `GET /items/organisme` (liste/front + liste/admin + detail) +- `PATCH /items/organisme/:id` +- `POST /items/organisme` +- `POST/PATCH/DELETE` sur: + - `/items/service` + - `/items/service_translation` + - `/items/contact` + - `/items/schedule` + +### Service externe + +- Geocodage adresse: `https://api-adresse.data.gouv.fr/search/?q=...` +- Releases app (modal versions): `https://api.github.com/repos/Watizat/web_app/releases` + +## Caching local existant + +- `fetchZones`: cache memoire (`zonesCache`, `zonesPromise`) +- `fetchMe`: cache memoire (`meCache`, `mePromise`) + +## Cas limites / vigilance + +- Les champs `fields` Directus sont tres verbeux et repetes; risque de divergence entre endpoints. +- Quelques champs semblent typo/incomplets (`services.categorie_id.translations.`). +- Harmoniser les filtres de zone entre front/back pour eviter des comportements differents. diff --git a/docs/technical/auth.md b/docs/technical/auth.md new file mode 100644 index 0000000..0556969 --- /dev/null +++ b/docs/technical/auth.md @@ -0,0 +1,45 @@ +# Technique - Auth + +## Objectif + +Gerer l'authentification des membres, la persistance de session et la protection du back office. + +## Routes concernees + +- `/login` +- `/account-request` +- `/forgotten-password` +- `/recover-password` +- `/new-user` +- toutes les routes `/admin/*` (acces conditionnel) + +## Composants / fichiers cles + +- `src/components/FrontOffice/Login/SignIn.tsx` +- `src/components/FrontOffice/Login/AccountRequest.tsx` +- `src/components/FrontOffice/Login/NewUser.tsx` +- `src/components/App/BackOffice.tsx` +- `src/components/InactivityDetector/InactivityDetector.tsx` +- `src/utils/axios.ts` +- `src/api/user.ts` +- `src/utils/user.ts` + +## Flux principal + +1. Login via `POST /auth/login` (`login` dans `src/api/user.ts`). +2. Token stocke dans `localStorage.user`. +3. `BackOffice.tsx` appelle `/users/me` pour valider l'acces. +4. L'intercepteur Axios ajoute le bearer et gere le refresh (`POST /auth/refresh`). +5. Si refresh impossible: purge session + redirection `/login`. + +## Regles de droits appliquees a l'entree back-office + +- Role `NewUser` : acces refuse, deconnexion, retour login. +- Role `UserToDelete` : acces refuse, deconnexion, retour login. +- Roles valides pour le back-office: `Administrator`, `RefLocal`, `Edition` (avec menus differents). + +## Cas limites / vigilance + +- Le code melange noms de roles et UUID selon les composants. +- La suppression de compte utilisateur est un passage en statut (`suspended`/`archived`) selon contexte. +- L'inactivite deconnecte la session apres timeout (5h par defaut cote state). diff --git a/docs/technical/vigilance.md b/docs/technical/vigilance.md new file mode 100644 index 0000000..3415282 --- /dev/null +++ b/docs/technical/vigilance.md @@ -0,0 +1,20 @@ +# Technique - Points de vigilance + +Ce document centralise les points de vigilance/corrections a suivre. + +## Front Office + +- `fetchOrganism` force actuellement `zone_id.name = Toulouse` dans le filtre API. +- La zone est memorisee dans `localStorage.city` et reutilisee par la carte/resultats. +- Les categories/translations reposent sur l'index `[0]` de `translations` dans plusieurs composants. + +## Back Office - Edition + +- Plusieurs refreshs de liste sont dupliques selon composants. +- Le flag `isDisplayArchivedOrga` impacte les requetes et le rendu, verifier coherence lors d'evolutions. + +## Back Office - Utilisateurs + +- Le code utilise a la fois UUID de roles et noms de roles. +- Les menus dashboard/sidebar filtrent par `roleName`; garder la meme table de droits partout. +- Certaines operations de suppression sont en pratique des changements de statut. diff --git a/docs/technical/zones.md b/docs/technical/zones.md new file mode 100644 index 0000000..e54397c --- /dev/null +++ b/docs/technical/zones.md @@ -0,0 +1,38 @@ +# Technique - Zones + +## Objectif + +Documenter le role des zones (antennes/territoires) dans la navigation, le filtrage et les droits. + +## Donnees et API + +- Collection Directus: `zone` +- Chargement via `fetchZones` (`src/api/admin.ts`) +- Position d'une zone via `fetchCityPosition` (`src/api/organisms.ts`) + +## Usages front office + +- Select de recherche sur la home (`SearchBox.tsx`) +- Filtre des organismes en resultats (`fetchOrganisms`) +- Centrage carte resultats (lat/lng de la zone) +- Persistance de la zone dans `localStorage.city` + +## Usages back office + +- Filtre des organismes dans Edition selon zone active +- Filtre des utilisateurs dans Users selon zone active / zone user +- Zone editable sur: + - creation organisme + - edition utilisateur (si droits suffisants) + - profil (lecture) + +## Regles de droits + +- `Administrator` / `RefLocal`: peuvent changer la zone active dans le header back-office. +- `Edition`: zone de travail en pratique contrainte a son rattachement. + +## Cas limites / vigilance + +- Plusieurs composants lisent la zone depuis `localStorage.city`; garantir une valeur coherente. +- Le filtre resultats utilise `city` en query params et localStorage en parallele. +- Penser a invalider le cache zones (`clearZonesCache`) si le referentiel zone evolue a chaud. From 8f2a20fab2d8f2c93e5c402398fb9c3de2842297 Mon Sep 17 00:00:00 2001 From: aliceout Date: Wed, 4 Feb 2026 12:37:31 +0300 Subject: [PATCH 2/9] fix: user.role detection (closes #156) --- src/api/admin.ts | 12 +++- .../BackOffice/Dashboard/Button.tsx | 49 +++++------------ .../BackOffice/Sidebar/LinkLarge.tsx | 23 +++----- .../BackOffice/Sidebar/LinkSquare.tsx | 55 +++++++------------ .../BackOffice/SlideOvers/Users/EditUser.tsx | 44 +++++---------- src/components/BackOffice/Users/UserLine.tsx | 47 ++++++++-------- src/utils/userRoles.ts | 49 ----------------- 7 files changed, 90 insertions(+), 189 deletions(-) delete mode 100644 src/utils/userRoles.ts diff --git a/src/api/admin.ts b/src/api/admin.ts index a5a62c3..c1ef35f 100644 --- a/src/api/admin.ts +++ b/src/api/admin.ts @@ -39,7 +39,17 @@ export const fetchAdminOrganisms = async ({ export const fetchUsers = async (zone: string | null) => { const { data } = await axiosInstance.get<{ data: DirectusUser[] }>('/users', { params: { - fields: ['*'].join(','), + fields: [ + 'id', + 'first_name', + 'last_name', + 'email', + 'role.id', + 'role.name', + 'zone', + 'last_access', + 'status', + ].join(','), filter: { zone, }, diff --git a/src/components/BackOffice/Dashboard/Button.tsx b/src/components/BackOffice/Dashboard/Button.tsx index ba9cf43..19996de 100644 --- a/src/components/BackOffice/Dashboard/Button.tsx +++ b/src/components/BackOffice/Dashboard/Button.tsx @@ -25,69 +25,46 @@ export default function Button({ item }: Props) { setMe(meData); } catch (error) { // eslint-disable-next-line no-console - console.error( - "Erreur lors de la récupération des données de l'utilisateur : ", - error - ); + console.error("Erreur lors de la recuperation des donnees de l'utilisateur : ", error); setMe(null); } } getUserInfos(); }, []); + const roleName = typeof me?.role === 'string' ? me.role : me?.role?.name; + const canAccessPrivilegedItems = roleName === 'RefLocal' || roleName === 'Administrator'; + const isDisabled = item.active === false || ((item.refLocalOnly || item.devOnly) && !canAccessPrivilegedItems); + return (
-
+
- +

{item.name}

-
-
Description
-
- {item.descript} -
+
+
Description
+
{item.descript}
diff --git a/src/components/BackOffice/Sidebar/LinkLarge.tsx b/src/components/BackOffice/Sidebar/LinkLarge.tsx index 7b65f79..7286b4d 100644 --- a/src/components/BackOffice/Sidebar/LinkLarge.tsx +++ b/src/components/BackOffice/Sidebar/LinkLarge.tsx @@ -26,27 +26,24 @@ export default function LinkLarge({ item }: Props) { setMe(meData); } catch (error) { // eslint-disable-next-line no-console - console.error( - "Erreur lors de la récupération des données de l'utilisateur : ", - error - ); + console.error("Erreur lors de la recuperation des donnees de l'utilisateur : ", error); setMe(null); } } getUserInfos(); }, []); + const roleName = typeof me?.role === 'string' ? me.role : me?.role?.name; + const canAccessPrivilegedItems = roleName === 'RefLocal' || roleName === 'Administrator'; + const isDisabled = item.active === false || ((item.refLocalOnly || item.devOnly) && !canAccessPrivilegedItems); + return (
  • ); diff --git a/src/components/BackOffice/SlideOvers/Users/EditUser.tsx b/src/components/BackOffice/SlideOvers/Users/EditUser.tsx index a179c09..6de393c 100644 --- a/src/components/BackOffice/SlideOvers/Users/EditUser.tsx +++ b/src/components/BackOffice/SlideOvers/Users/EditUser.tsx @@ -1,12 +1,10 @@ -import jwt_decode from 'jwt-decode'; import { useState } from 'react'; import { SubmitHandler, useForm } from 'react-hook-form'; import { Inputs } from '../../../../@types/formInputs'; -import { DirectusUser, UserSession } from '../../../../@types/user'; +import { DirectusUser } from '../../../../@types/user'; import { useAppState } from '../../../../hooks/appState'; import { fetchUsers } from '../../../../api/admin'; import { editUser, updateUserStatus, fetchMe } from '../../../../api/user'; -import { getUserDataFromLocalStorage } from '../../../../utils/user'; import { validateEmail } from '../../../../utils/form/form'; import Slide from '../components/Slide'; import Header from '../components/Header'; @@ -50,32 +48,18 @@ export default function SlideEditUser({ const cityId = cityLocal ? zones.find((zone) => zone.name === cityLocal) : zones.find((zone) => zone.name === city); - const localUser = getUserDataFromLocalStorage(); const me = await fetchMe(); - const { zone } = me; - - if (!localUser?.token) { - return; - } - try { - const decodedUser = jwt_decode( - localUser.token.access_token - ) as UserSession; - if (decodedUser.role === '53de6ec2-6d70-48c8-8532-61f96133f139') { - if (cityId !== undefined) { - const usersList = await fetchUsers(cityId.id.toString()); - setAdminState((prev) => ({ ...prev, users: usersList })); - } else { - const usersList = await fetchUsers(null); - setAdminState((prev) => ({ ...prev, users: usersList })); - } - } else { - const usersList = await fetchUsers(zone.toString()); - setAdminState((prev) => ({ ...prev, users: usersList })); - } - } catch (error) { - // eslint-disable-next-line no-console - console.error('Error while decoding JWT or dispatching actions:', error); + if (isAdmin) { + if (cityId !== undefined) { + const usersList = await fetchUsers(cityId.id.toString()); + setAdminState((prev) => ({ ...prev, users: usersList })); + } else { + const usersList = await fetchUsers(null); + setAdminState((prev) => ({ ...prev, users: usersList })); + } + } else if (me?.zone) { + const usersList = await fetchUsers(me.zone.toString()); + setAdminState((prev) => ({ ...prev, users: usersList })); } setIsOpenSlide(false); }; @@ -189,9 +173,7 @@ export default function SlideEditUser({ {!isAdmin && roles .filter( - (filteredRole) => - filteredRole.id !== - '53de6ec2-6d70-48c8-8532-61f96133f139' + (filteredRole) => filteredRole.name !== 'Administrator' ) .map((role) => (