docs(audit): proposer le centre documentaire global
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
Some checks are pending
CI - Tests et Syntax / lint-and-test (push) Waiting to run
This commit is contained in:
parent
c58bcbd5fb
commit
8e6a67915c
2 changed files with 502 additions and 0 deletions
493
docs/ui-audit/DOCUMENT_CENTER_PROPOSAL.md
Normal file
493
docs/ui-audit/DOCUMENT_CENTER_PROPOSAL.md
Normal file
|
|
@ -0,0 +1,493 @@
|
|||
# Proposition d'architecture — Centre documentaire global
|
||||
|
||||
État : étude uniquement, aucune route, table, migration ou modification du
|
||||
code n'est créée par cette proposition.
|
||||
|
||||
## A. État documentaire actuel
|
||||
|
||||
Le dépôt ne possède pas de modèle `Document` générique ni de table commune.
|
||||
Les documents sont spécialisés par module :
|
||||
|
||||
| Modèle | Table | Parent métier | Métadonnées | État UI / routes |
|
||||
|---|---|---|---|---|
|
||||
| `InterventionDocument` | `intervention_documents` | `Intervention` obligatoire | `filename`, `filepath`, `description`, `uploaded_at`, `uploaded_by_id` | upload, édition de description, téléchargement et suppression depuis la fiche intervention |
|
||||
| `EquipmentDocument` | `equipment_documents` | `Equipment` obligatoire | `filename`, `filepath`, `description`, `uploaded_at`, `uploaded_by_id` | deux familles de routes et upload depuis la fiche équipement |
|
||||
| `ProductDocument` | `cleaning_product_documents` | `CommercialProduct` obligatoire | `document_type`, `title`, `filename`, `filepath`, `version`, `published_at`, `uploaded_at`, `uploaded_by_id`, `is_current` | liste FDS/fiches techniques ; aucun upload ou téléchargement produit clairement exposé dans les routes actuelles |
|
||||
|
||||
Le modèle `Contract` possède en plus un champ historique `contract_file` qui
|
||||
est un simple chemin de fichier, sans ligne documentaire ni métadonnées
|
||||
associées. Aucun modèle documentaire dédié aux entreprises, à la prévention
|
||||
ou aux contrats n'a été trouvé. Les pièces jointes Outlook/ENT sont un autre
|
||||
système d'intégration et restent hors périmètre de ce centre documentaire.
|
||||
|
||||
Le centre devra donc fonctionner par adaptateurs de sources et non par
|
||||
copie des objets existants.
|
||||
|
||||
## B. Modèles et relations existants
|
||||
|
||||
### Interventions
|
||||
|
||||
`Intervention.documents` est une relation vers
|
||||
`InterventionDocument`. Le document pointe vers l'intervention par
|
||||
`intervention_id`; l'uploader est facultatif (`users.id`, `SET NULL` côté
|
||||
modèle logique). Il n'existe pas de type métier normalisé pour le document.
|
||||
|
||||
### Équipements
|
||||
|
||||
`Equipment.documents` est une relation vers `EquipmentDocument`. Le parent
|
||||
est obligatoire. La localisation doit être calculée via l'équipement,
|
||||
éventuellement son parent et `effective_room`, puis `Room → Zone → Building`.
|
||||
|
||||
### Produits d'entretien
|
||||
|
||||
`CommercialProduct.documents` est une relation vers `ProductDocument`.
|
||||
Le produit commercial remonte vers le produit générique, le fabricant et le
|
||||
fournisseur. Une localisation éventuelle doit être calculée via les lots,
|
||||
balances et `StockLocation → Building/Zone/Room`; elle ne doit pas être
|
||||
recopiée dans le document.
|
||||
|
||||
### Ce qui n'est pas encore un document global
|
||||
|
||||
- `Contract.contract_file` est un chemin historique, pas un document
|
||||
normalisé.
|
||||
- Outlook/ENT ont leurs propres pièces jointes distantes et ne doivent pas
|
||||
être aspirés dans le centre pendant cette phase.
|
||||
- Les photos, plans, certificats ou documents de prévention n'ont pas de
|
||||
modèle local identifié dans le dépôt.
|
||||
|
||||
## C. Stockage actuel
|
||||
|
||||
La configuration définit `UPLOAD_FOLDER` sous
|
||||
`app_new/uploads`. Docker monte ce répertoire dans le volume
|
||||
`gmao_uploads` (`/app/app_new/uploads`). La limite globale est de 50 MiB.
|
||||
|
||||
Les routes historiques utilisent actuellement plusieurs conventions :
|
||||
|
||||
- intervention : `uploads/interventions/<uuid>_<secure_filename>` ;
|
||||
- équipement, blueprint `documents` : `uploads/equipments/<uuid>_<secure_filename>` ;
|
||||
- équipement, blueprint `equipments_documents` :
|
||||
`uploads/documents/<equipment_id>/<uuid>.<extension>` ;
|
||||
- produit : le modèle stocke un chemin, mais aucune route locale d'upload
|
||||
produit n'a été identifiée.
|
||||
|
||||
Le fichier physique est donc unique aujourd'hui, mais l'organisation n'est
|
||||
pas homogène. Les noms sont générés avec UUID ; `secure_filename` réduit le
|
||||
risque de traversal. Les extensions sont allowlistées (`pdf`, images,
|
||||
documents Office), mais le MIME réel n'est pas inspecté. Les modèles ne
|
||||
stockent généralement ni MIME, ni taille, ni hash, et le nom original n'est
|
||||
pas distingué proprement du nom interne dans toutes les routes.
|
||||
|
||||
Le volume n'est pas servi comme répertoire statique public : les téléchargements
|
||||
passent par `send_file`. Cependant, plusieurs téléchargements font confiance
|
||||
directement au `filepath` DB et certaines routes ne vérifient pas l'existence
|
||||
du fichier avant `send_file`.
|
||||
|
||||
État observé sur la copie locale au moment de l'étude : 2 lignes
|
||||
`intervention_documents`, 0 ligne `equipment_documents` et 0 ligne
|
||||
`cleaning_product_documents`. Les deux fichiers d'intervention présents dans
|
||||
le volume correspondent aux deux lignes DB. Ce constat est un instantané, pas
|
||||
une hypothèse de conception.
|
||||
|
||||
## D. Routes actuelles
|
||||
|
||||
### Blueprint `documents` (`/documents`)
|
||||
|
||||
- `POST /documents/upload/intervention/<id>`
|
||||
- `POST /documents/upload/equipment/<id>`
|
||||
- `POST /documents/intervention/delete/<doc_id>`
|
||||
- `POST /documents/intervention/<doc_id>/edit`
|
||||
- `GET /documents/intervention/download/<doc_id>`
|
||||
- `POST /documents/equipment/delete/<doc_id>`
|
||||
- `GET /documents/equipment/download/<doc_id>`
|
||||
|
||||
Ces routes utilisent `login_required` et la garde globale d'autorisation,
|
||||
qui déduit actuellement `intervention.view/manage` ou
|
||||
`patrimoine.view/manage` du nom d'endpoint.
|
||||
|
||||
### Blueprint `equipments_documents` (préfixé `/equipments`)
|
||||
|
||||
- `POST /equipments/<id>/documents/upload`
|
||||
- `GET /equipments/documents/<doc_id>/download`
|
||||
- `POST /equipments/documents/<doc_id>/delete`
|
||||
|
||||
Il s'agit d'une seconde famille d'upload/téléchargement pour les équipements.
|
||||
Elle utilise un autre répertoire et un autre format de nom. Cette duplication
|
||||
de routes devra être résolue ou encapsulée avant d'exposer un index global.
|
||||
|
||||
### Produits
|
||||
|
||||
`GET /cleaning/documents` liste les `ProductDocument`, mais n'offre pas de
|
||||
route globale, ni de téléchargement produit identifié dans le code inspecté.
|
||||
`GET /documents/` n'est donc pas l'index attendu par UI-011 et répond 404.
|
||||
|
||||
## E. Problèmes actuels à traiter avant ou pendant le MVP
|
||||
|
||||
1. Trois schémas de documents et plusieurs conventions de chemin coexistent.
|
||||
2. Le nom affiché/téléchargé n'est pas toujours le nom original (la route
|
||||
intervention stocke notamment le nom UUID comme `filename`).
|
||||
3. Une route d'upload équipement tente de renseigner `file_type` et
|
||||
`file_size`, alors que ces colonnes ne sont pas déclarées sur
|
||||
`EquipmentDocument` ; les deux chemins d'upload ne sont donc pas
|
||||
équivalents et doivent être consolidés avant extension.
|
||||
4. Les types métier sont riches pour les produits, mais absents pour les
|
||||
interventions et équipements.
|
||||
5. Le stockage de document produit est modélisé, mais son workflow d'upload/
|
||||
download n'est pas complet.
|
||||
6. `Contract.contract_file` n'est pas interrogeable comme un document.
|
||||
7. Les routes de téléchargement doivent vérifier parent, permission et
|
||||
fichier sous la racine autorisée afin d'éviter IDOR et chemins arbitraires.
|
||||
8. Une erreur après écriture physique mais avant commit DB peut laisser un
|
||||
fichier orphelin ; l'inverse peut laisser une ligne sans fichier.
|
||||
9. La validation par extension seule ne suffit pas pour les exécutables
|
||||
renommés et les fichiers malformés.
|
||||
|
||||
## F. Architecture recommandée
|
||||
|
||||
### Recommandation : option A pour la V1, avec adaptateurs de lecture
|
||||
|
||||
La V1 doit agréger les trois tables spécialisées sans créer une table de
|
||||
stockage ou recopier les fichiers. Un service de lecture produira un
|
||||
descripteur commun en mémoire, par exemple :
|
||||
|
||||
```text
|
||||
DocumentResult
|
||||
source_kind intervention | equipment | product
|
||||
source_id identifiant de la ligne documentaire
|
||||
parent_id identifiant de l'objet métier
|
||||
display_name nom lisible
|
||||
document_type type métier normalisé à l'affichage
|
||||
description
|
||||
uploaded_at / published_at
|
||||
stored_path utilisé seulement côté téléchargement sécurisé
|
||||
context_label Intervention #… / Équipement … / Produit …
|
||||
context_url URL de détail autorisée
|
||||
location calculée par relations métier
|
||||
capabilities view / download / edit / delete
|
||||
```
|
||||
|
||||
Chaque adaptateur sait lire sa table, construire le contexte, appliquer la
|
||||
permission du module source et produire l'action de téléchargement vers la
|
||||
ligne propriétaire. Le centre est ainsi un index de recherche logique, pas
|
||||
un second propriétaire de fichier.
|
||||
|
||||
Pour une recherche SQL paginée, les adaptateurs peuvent exposer des sélections
|
||||
alignées combinées par `UNION ALL` (ou trois requêtes paginées fusionnées pour
|
||||
le premier incrément). Aucune modification de schéma n'est nécessaire pour
|
||||
la V1.
|
||||
|
||||
### Pourquoi cette option
|
||||
|
||||
- aucune migration ni backfill destructif ;
|
||||
- conservation immédiate des documents existants ;
|
||||
- aucun fichier copié ;
|
||||
- réutilisation des relations et permissions existantes ;
|
||||
- retour arrière simple : retirer la vue globale ne touche pas aux sources.
|
||||
|
||||
La contrepartie est une couche d'adaptation plus explicite et une pagination
|
||||
globale plus complexe si le volume devient très élevé.
|
||||
|
||||
## G. Alternative étudiée : option B — index documentaire commun
|
||||
|
||||
Une table `document_index` pourrait contenir une ligne par document source,
|
||||
avec `source_kind`, `source_document_id`, `parent_type`, `parent_id`, type,
|
||||
dates et éventuellement un hash. Elle ne contiendrait pas une copie du
|
||||
fichier : le chemin et la suppression resteraient propriétaires de la table
|
||||
source.
|
||||
|
||||
### Avantages
|
||||
|
||||
- recherche et pagination uniformes ;
|
||||
- index SQL uniques et filtres simples ;
|
||||
- base future pour tags, OCR et classement ;
|
||||
- détection centralisée des documents orphelins.
|
||||
|
||||
### Inconvénients et risques
|
||||
|
||||
- migration et backfill des trois tables ;
|
||||
- synchronisation lors de chaque création, modification, suppression et
|
||||
changement de parent ;
|
||||
- gestion des documents historiques incomplets et de `contract_file` ;
|
||||
- risque de ligne d'index périmée ou d'un faux sentiment de stockage unifié ;
|
||||
- complexité supplémentaire avant d'avoir validé les besoins de recherche.
|
||||
|
||||
### Recommandation de trajectoire
|
||||
|
||||
Ne pas créer cette table pour le MVP. La réévaluer si les mesures montrent
|
||||
que l'agrégation SQL dépasse les objectifs à 10 000+ documents ou si les tags,
|
||||
l'OCR et la recherche plein texte deviennent prioritaires. Dans ce cas, la
|
||||
table restera un index réparable, jamais le propriétaire physique du fichier.
|
||||
|
||||
## H. Règle RBAC recommandée
|
||||
|
||||
Le centre ne doit jamais élargir l'accès d'un module.
|
||||
|
||||
Pour afficher un résultat, appliquer :
|
||||
|
||||
```text
|
||||
permission d'accès au Centre (documents.view)
|
||||
ET
|
||||
permission de lecture de la source
|
||||
```
|
||||
|
||||
Exemples :
|
||||
|
||||
- document d'intervention : `documents.view` + `intervention.view` ;
|
||||
- document équipement : `documents.view` + `patrimoine.view` ;
|
||||
- FDS produit : `documents.view` + `stock.view` ;
|
||||
- contrat futur : `documents.view` + `contract.view` ;
|
||||
- prévention future : `documents.view` + `prevention.view`.
|
||||
|
||||
Si `documents.view` n'est pas accordée, le menu et l'URL globale sont
|
||||
refusés. Si la source est refusée, le résultat est absent, même si sa ligne
|
||||
documentaire est connue.
|
||||
|
||||
Le téléchargement réévalue les deux permissions et l'existence du parent ;
|
||||
il ne doit jamais accepter uniquement un `doc_id` global. La suppression ou
|
||||
la modification reste dans la fiche source et utilise la permission de
|
||||
mutation du module (`intervention.manage`, `patrimoine.manage`, etc.). Il
|
||||
n'est pas recommandé d'introduire un vague `documents.manage` pour remplacer
|
||||
ces contrôles.
|
||||
|
||||
`super_admin` bénéficie de son wildcard existant. Le rôle `admin` et les
|
||||
rôles métier devront recevoir `documents.view` seulement après décision du
|
||||
catalogue RBAC ; aucune permission d'intégration ne doit être impliquée.
|
||||
|
||||
## I. Classification métier proposée
|
||||
|
||||
V1 : un type principal, peu de valeurs et une valeur de repli :
|
||||
|
||||
- FDS ;
|
||||
- Fiche technique ;
|
||||
- Notice / manuel ;
|
||||
- Facture ;
|
||||
- Devis ;
|
||||
- Rapport / compte rendu ;
|
||||
- Contrat ;
|
||||
- Certificat / contrôle ;
|
||||
- Photo / plan ;
|
||||
- Autre.
|
||||
|
||||
Pour les produits, `ProductDocument.document_type` est conservé et mappé
|
||||
vers les libellés métier. Pour les interventions et équipements, le type
|
||||
sera `Autre` tant qu'aucune donnée source ne le porte. Les tags et sous-types
|
||||
sont différés ; ils ne doivent pas être simulés dans `description`.
|
||||
|
||||
## J. Recherche
|
||||
|
||||
### Recherche simple visible
|
||||
|
||||
Un champ unique recherche : nom de fichier, titre, description, nom de
|
||||
l'objet parent, référence équipement, produit, intervention et entreprise
|
||||
accessible par relation.
|
||||
|
||||
### SQL classique suffisant
|
||||
|
||||
Pour les volumes attendus, SQL/MariaDB suffit avec `LIKE` ciblé et des indexes
|
||||
sur les clés étrangères, dates, `document_type`, `filename`, `uploaded_at` et
|
||||
`expiry`/`is_current` côté produits. La recherche plein texte PDF, OCR et
|
||||
Elasticsearch sont explicitement hors MVP.
|
||||
|
||||
### Résultats
|
||||
|
||||
Les requêtes doivent filtrer par source avant pagination et ne jamais charger
|
||||
en mémoire tous les fichiers. Le contenu binaire n'est jamais recherché.
|
||||
|
||||
## K. Filtres
|
||||
|
||||
### Visibles par défaut
|
||||
|
||||
- Type de document ;
|
||||
- Source/module ;
|
||||
- période (date d'ajout ou de publication) ;
|
||||
- recherche libre.
|
||||
|
||||
### Filtres avancés repliés
|
||||
|
||||
- bâtiment, zone, salle ;
|
||||
- équipement ;
|
||||
- produit/FDS ;
|
||||
- entreprise ;
|
||||
- actif/courant pour les produits.
|
||||
|
||||
Les filtres non applicables à une source doivent rester neutres, pas produire
|
||||
un faux « aucun résultat ».
|
||||
|
||||
## L. UI proposée pour `/documents/`
|
||||
|
||||
Titre : **Centre documentaire**. Sous le titre, une phrase explique que les
|
||||
fichiers restent attachés à leur fiche métier et sont seulement regroupés
|
||||
pour la recherche.
|
||||
|
||||
```text
|
||||
Recherche [ nom, titre, équipement, produit... ] [Rechercher]
|
||||
|
||||
Filtres principaux : Type | Source | Période
|
||||
Filtres avancés : Bâtiment | Zone | Salle | Équipement | Produit | Entreprise
|
||||
|
||||
Document | Type | Lié à | Localisation | Date | Actions
|
||||
```
|
||||
|
||||
Chaque ligne présente : nom lisible, icône non porteuse d'information seule,
|
||||
type, source (« Intervention #142 »), localisation calculée, date, bouton
|
||||
Télécharger si autorisé et lien Ouvrir la fiche. Aucun terme technique
|
||||
(`source_kind`, `entity_type`, nom de classe Python) ne doit être affiché.
|
||||
|
||||
La pagination est obligatoire, avec conservation des filtres dans l'URL. La
|
||||
V1 est consultation/recherche uniquement : aucun upload global et aucun
|
||||
bouton de suppression dans ce centre.
|
||||
|
||||
## M. Vue FDS `/documents/fds`
|
||||
|
||||
Vue filtrée ou route dédiée sur les `ProductDocument` de type FDS et
|
||||
`is_current=True`. Colonnes : produit commercial, fabricant/fournisseur,
|
||||
version, date de publication, statut courant, localisation des balances de
|
||||
stock lorsque disponible, téléchargement et fiche produit.
|
||||
|
||||
Un état vide doit expliquer : « Les FDS sont ajoutées depuis la fiche du
|
||||
produit commercial » et proposer ce lien si `stock.view` le permet.
|
||||
|
||||
Le futur « classeur FDS » pourra réutiliser exactement le même service de
|
||||
sélection autorisé pour produire une liste ou un PDF ; aucune génération n'est
|
||||
incluse dans le MVP.
|
||||
|
||||
## N. Documents et localisation
|
||||
|
||||
Ne pas dénormaliser les chemins bâtiment/zone/salle dans une nouvelle table.
|
||||
|
||||
- équipement : `Equipment → effective_room → Zone → Building` ;
|
||||
- intervention : salle directe, sinon équipement lié ;
|
||||
- FDS produit : `CommercialProduct → StockLot → StockLotBalance →
|
||||
StockLocation → Room/Zone/Building`, en signalant « plusieurs
|
||||
emplacements » si nécessaire ;
|
||||
- contrat : relation équipement/lot/entreprise si le document historique est
|
||||
finalement inclus.
|
||||
|
||||
Si aucune localisation n'est calculable, afficher « Localisation non
|
||||
renseignée », jamais `None` ou un identifiant interne.
|
||||
|
||||
## O. Sécurité
|
||||
|
||||
Avant développement, les contrôles suivants sont requis :
|
||||
|
||||
- autoriser une liste d'extensions métier limitée et contrôler aussi le MIME
|
||||
réel / signatures connues ;
|
||||
- refuser exécutables, scripts et archives non prévues ;
|
||||
- conserver un nom original d'affichage séparé d'un nom interne UUID ;
|
||||
- résoudre le chemin avec `Path.resolve()` et vérifier qu'il reste sous la
|
||||
racine `UPLOAD_FOLDER` ;
|
||||
- vérifier parent, source et permission pour chaque download/delete ;
|
||||
- ne jamais exposer le volume par une route statique ;
|
||||
- définir explicitement `Content-Disposition: attachment` et un nom sûr ;
|
||||
- conserver la limite 50 MiB et afficher une erreur utilisateur claire ;
|
||||
- supprimer le fichier si l'insertion DB échoue, ou journaliser une tâche de
|
||||
réconciliation ;
|
||||
- fournir un diagnostic non destructif des lignes DB sans fichier et des
|
||||
fichiers sans ligne DB ;
|
||||
- ajouter des tests IDOR avec deux utilisateurs et deux sources.
|
||||
|
||||
Les documents de prévention, personnel et contrats peuvent contenir des
|
||||
données sensibles. Leur inclusion doit rester soumise à la permission source;
|
||||
aucun filtrage global par simple URL ne suffit.
|
||||
|
||||
## P. Performance
|
||||
|
||||
| Volume | Stratégie V1 attendue |
|
||||
|---:|---|
|
||||
| 100 | `UNION ALL`/adaptateurs, pagination 20–50 lignes, eager loading des parents |
|
||||
| 1 000 | mêmes principes, indexes FK/date/type, count limité aux lignes filtrées |
|
||||
| 10 000 | mesurer les plans SQL ; envisager vue/index commun réparable si la fusion paginée devient lente |
|
||||
|
||||
Indexes utiles côté sources : clés étrangères parent, `uploaded_at`,
|
||||
`document_type`, `is_current`, `published_at`, et éventuellement index
|
||||
composé parent/date. Aucun index de contenu PDF n'est proposé.
|
||||
|
||||
## Q. Migrations éventuelles
|
||||
|
||||
### Option A recommandée
|
||||
|
||||
Aucune migration nécessaire. Il faut seulement ajouter un service de lecture,
|
||||
des requêtes, des tests et une route protégée.
|
||||
|
||||
### Option B différée
|
||||
|
||||
Une future migration créerait un index documentaire avec `source_kind`,
|
||||
`source_document_id`, `parent_type`, `parent_id`, type, dates et hash
|
||||
optionnels, puis un backfill idempotent. Elle ne déplacerait ni ne copierait
|
||||
les fichiers et devrait prévoir la réparation des entrées obsolètes. Elle
|
||||
serait déployée séparément après validation des volumes.
|
||||
|
||||
## R. Compatibilité historique
|
||||
|
||||
La V1 lit les trois tables sans transformer les lignes existantes. Les
|
||||
documents sans type reçoivent `Autre`; les descriptions nulles restent vides;
|
||||
les noms UUID sont présentés avec une règle d'affichage documentée. Les
|
||||
fichiers manquants apparaissent éventuellement dans une vue d'administration
|
||||
diagnostique, mais ne sont jamais supprimés automatiquement.
|
||||
|
||||
`Contract.contract_file` doit faire l'objet d'une décision séparée : soit il
|
||||
reste exclu du MVP, soit il est adapté par un lecteur temporaire avec
|
||||
permission `contract.view`, soit il est converti plus tard en document source
|
||||
normalisé. Il ne faut pas le mélanger silencieusement aux trois tables.
|
||||
|
||||
## S. Tests à prévoir avant implémentation
|
||||
|
||||
1. Intervention, équipement et produit présents dans la liste globale.
|
||||
2. Recherche sur filename, titre, description et parent.
|
||||
3. Filtres type/source/date et filtres localisation.
|
||||
4. Pagination stable et conservation des paramètres d'URL.
|
||||
5. FDS : uniquement documents courants et accès produit autorisé.
|
||||
6. Lien vers chaque fiche métier et absence de lien si source interdite.
|
||||
7. Téléchargement autorisé, refusé et IDOR entre deux utilisateurs.
|
||||
8. Document DB présent mais fichier manquant : réponse contrôlée, jamais 500.
|
||||
9. Fichier présent sans ligne DB : diagnostic, aucune exposition publique.
|
||||
10. Parent supprimé/inaccessible : résultat masqué ou marqué orphelin selon
|
||||
politique validée.
|
||||
11. Aucun upload, suppression ou modification possible depuis `/documents/`.
|
||||
12. Wildcard `super_admin`, rôles source et deny individuel.
|
||||
13. Compatibilité avec noms spéciaux, extensions refusées et taille maximale.
|
||||
14. Non-régression des téléchargements depuis les fiches existantes.
|
||||
|
||||
## T. MVP et évolutions
|
||||
|
||||
### V1 obligatoire
|
||||
|
||||
- `GET /documents/` protégé ;
|
||||
- agrégation lecture seule des interventions, équipements et produits ;
|
||||
- recherche simple, pagination et trois filtres principaux ;
|
||||
- type/source/localisation lisibles ;
|
||||
- téléchargement sécurisé sans duplication ;
|
||||
- lien vers le parent métier ;
|
||||
- contrôle `documents.view` + permission source ;
|
||||
- vue FDS courante ;
|
||||
- états vides et messages d'accès compréhensibles ;
|
||||
- tests de sécurité, IDOR, fichier manquant et non-régression.
|
||||
|
||||
### Plus tard
|
||||
|
||||
- index commun matérialisé si le volume le justifie ;
|
||||
- tags métier ;
|
||||
- recherche plein texte/OCR ;
|
||||
- prévisualisation avancée ;
|
||||
- versionnement transversal ;
|
||||
- classeur FDS exportable ;
|
||||
- intégration explicite des contrats et documents généraux ;
|
||||
- diagnostic et réparation assistés des orphelins.
|
||||
|
||||
## Questions nécessitant validation
|
||||
|
||||
1. Le centre doit-il inclure les chemins historiques `Contract.contract_file`
|
||||
dès la V1, ou les laisser dans les contrats ?
|
||||
2. Le catalogue RBAC accepte-t-il deux nouvelles permissions
|
||||
`documents.view` et `documents.download`, ou la visibilité doit-elle être
|
||||
dérivée uniquement des permissions sources ?
|
||||
3. Le téléchargement global doit-il être séparé de la consultation, ou
|
||||
`documents.view` suffit-il pour la V1 ?
|
||||
4. Quel est le type officiel des documents d'intervention et d'équipement
|
||||
actuellement sans classification ?
|
||||
5. Les documents prévention/personnel/contrats doivent-ils être inclus après
|
||||
une revue de confidentialité ?
|
||||
6. Faut-il afficher une localisation quand plusieurs emplacements stock sont
|
||||
possibles, et sous quel libellé ?
|
||||
7. Quel seuil de volume déclenche l'étude d'un index matérialisé ?
|
||||
8. La V1 reste-t-elle strictement consultation/recherche, sans document
|
||||
général non lié à un objet métier ?
|
||||
|
|
@ -31,6 +31,15 @@ implémenté.
|
|||
Contrôle post-rebuild effectué : `/health/` répond 200 avec la version
|
||||
`0.1.0-dev.4`, le commit `b6fbfe6` et une base MariaDB connectée.
|
||||
|
||||
## Étude Centre documentaire global — 22 août 2026
|
||||
|
||||
Étude d'architecture terminée dans `DOCUMENT_CENTER_PROPOSAL.md`. Le dépôt
|
||||
possède trois modèles documentaires spécialisés, plusieurs conventions de
|
||||
stockage et aucune table commune. La recommandation est une agrégation de
|
||||
lecture par adaptateurs pour la V1, sans migration ni copie de fichier, avec
|
||||
contrôle conjoint `documents.view` et permission du module source. Aucune
|
||||
modification applicative, route, migration ou donnée de test n'a été créée.
|
||||
|
||||
Couverture estimée : **environ 85 %**. Les principaux workflows patrimoine,
|
||||
interventions, stock, prévention et RBAC ont été testés localement ; restent
|
||||
partiels la recherche documentaire globale, certaines variantes de planning,
|
||||
|
|
|
|||
Loading…
Reference in a new issue