groupe-meditation/docs/60_ARCHITECTURE.md

167 lines
5.2 KiB
Markdown

# Architecture technique
Statut: référence technique
Public: mainteneurs, exploitants
Dernière révision: 2026-06-01
## Vue d'ensemble
L'application est composée de quatre couches:
- frontend PWA React;
- API FastAPI;
- base PostgreSQL;
- déploiement systemd, NGINX et Ansible.
Le frontend ne contient pas les règles d'autorisation finales. Il adapte l'interface selon les modules retournés par l'API, mais le backend reste responsable de refuser les actions non permises.
## Frontend
Emplacement: `frontend/src`.
Éléments principaux:
- `App.jsx`: routeur applicatif côté client;
- `stores/store.js`: état global Zustand, session, groupe courant, modules;
- `stores/api.js`: client HTTP et gestion du token;
- `components/PageHeader.jsx`: entête commun des pages authentifiées;
- `components/BottomNav.jsx`: navigation par contextes;
- `pages/`: écrans fonctionnels;
- `features/assemblees/`: composants et helpers propres aux assemblées;
- `utils/datesReunion.js`: logique de dates de rencontres;
- `utils/pushNotifications.js`: abonnement push.
Conventions:
- les pages protégées sont sélectionnées par code de module;
- la barre de navigation du bas n'apparaît que sur l'accueil;
- les tuiles expansibles sont le motif principal pour rencontres, assemblées, décisions, postes et journal;
- les pages doivent rester utilisables sur petit téléphone.
## Backend
Emplacement: `backend/app`.
Éléments principaux:
- `main.py`: application FastAPI, middleware, montage des routers, migrations légères au démarrage;
- `core/`: sécurité, rôles, audit, concurrence, finances, décisions, configuration;
- `models/`: modèles SQLAlchemy et tables;
- `routers/`: endpoints API;
- `schemas/`: contrats Pydantic;
- `services/`: logique métier réutilisable.
Règle de maintenance:
- un router orchestre une action HTTP;
- une règle métier partagée va dans `services/` ou `core/`;
- un router ne doit pas importer un autre router pour réutiliser sa logique.
## Authentification et session
Le membre se connecte par groupe, identifiant/courriel et PIN. Le backend émet un JWT contenant:
- `sub`: membre courant;
- `groupe_id`: groupe courant;
- `adm`: sysadmin d'origine lors d'une impersonification.
Les routes authentifiées récupèrent le membre courant depuis le token. Les données doivent toujours être filtrées par `membre.groupe_id`.
## Permissions
Les accès sont déterminés par:
- les affectations actives du membre;
- la catégorie du poste (`executif`, `service`, `physique`);
- les permissions de modules associées aux postes;
- le statut spécial `Sysadmin`.
Les modules visibles sont calculés par `/api/accueil/`.
## Multi-groupe
Chaque table métier doit avoir un `groupe_id`, ou être reliée à une table parent qui en a un. Une route recevant un identifiant client doit vérifier que l'objet appartient au groupe courant avant lecture ou modification.
Voir [Multi-groupe](93_MULTI_GROUPE.md).
## Journalisation
`AuditMiddleware` journalise les méthodes mutantes réussies (`POST`, `PUT`, `PATCH`, `DELETE`) sous `/api/`.
Les journaux techniques sont conservés dans `journal_actions`. Les changements métier détaillés peuvent aussi être enregistrés dans `historique_modifications`, avec ancienne valeur, nouvelle valeur, membre responsable et raison automatique.
## Notifications
Les notifications push sont optionnelles. Le backend mappe les chemins API vers des catégories (`gouvernance`, `tresorerie`, `membres`, `postes`, `rencontres`, `litterature`, `evenements`, `systeme`) et notifie les membres abonnés selon leurs préférences.
## Finances
La source de vérité financière est `transactions_comptables`.
Conventions:
- `compte = banque` ou `encaisse`;
- `sens = debit` augmente le compte;
- `sens = credit` diminue le compte;
- `source_table` et `source_id` relient l'écriture à l'objet métier.
Les réserves sont historisées dans `mouvements_reserves`. Le solde courant de `reserves` ne doit pas devenir la seule source de vérité.
## Décisions
Les propositions et décisions partagent la table `propositions`.
Une proposition devient une décision lorsque les champs de décision sont renseignés:
- `type_decision`;
- `date_adoption`;
- `numero_resolution`;
- `etant_donne_que`;
- `groupe_a_decide_de`.
La numérotation est produite par `core/decisions.py`.
## Rapports PDF
Les PDF sont produits côté backend avec WeasyPrint. Les rapports importants doivent rester imprimables en format lettre et utilisables comme reprise papier.
## Déploiement
La voie supportée est Ansible. Le playbook installe:
- paquets système;
- PostgreSQL;
- backend Python;
- frontend compilé;
- service systemd;
- NGINX;
- sauvegardes.
Voir [Déploiement Ansible](91_DEPLOIEMENT_ANSIBLE.md).
## Initialisation
`deploy/seed.py` crée le schéma et initialise `Groupe Démonstration`. Une VM vanille ne crée plus de groupe réel par défaut.
Le groupe de démonstration contient:
- `Sysadmin` avec PIN `0000`;
- postes et permissions de base;
- littérature;
- 12 mois d'activité fictive crédible.
## Tests
Tests actuellement présents:
```bash
.venv/bin/python -m pytest backend/tests/test_business_rules.py
```
Build frontend:
```bash
cd frontend
npm run build
```