Commit Graph

8 Commits

Author SHA1 Message Date
pr-daaif
28eecc1fb9 feat(r5.3): écrans IA — assistant web, corpus administrable, suggestions OT/mobile
- Contrat (76 opérations) : Document expose inCorpus/indexedAt/chunkCount,
  PATCH /documents/{id}/corpus (ASSETS.edit), POST /assistant/reindex
  (bilan chiffré) ; ci-contract vérifie désormais aussi le client mobile.
- Web : page /assistant (chat sourcé — extraits exacts cités, Ouvrir vers
  PDF authentifié ou fiche OT, avertissement permanent ; refus honnête
  chiffré avec action utile) ; Bibliothèque = corpus (bandeau 09-08,
  statut d'indexation par document, interrupteur d'exclusion PDF,
  Réindexer tout) ; fiche OT : « Décrire pour suggérer » (Appliquer =
  geste humain, liseré « suggéré » retiré au choix manuel).
- Mobile : chips de suggestion dans la clôture (un appui = un champ
  pré-rempli, « réseau requis » hors-ligne — la file R4 n'en dépend pas).
- apps/ai : seuils AI_SEUIL_* configurables par env (CI + calibrage).
- CI e2e : service siop2-ai (embeddeur déterministe, seuils calibrés sur
  mesures : match 0,66 vs bruit 0,11) + parcours R5 Playwright (PDF généré
  xref valide → réindexation → réponse sourcée → refus → suggestion).
- Vérifié : 16/16 Playwright, 78 tests API, 23 pytest, 17 jest-expo ;
  chaîne réelle au vrai modèle ONNX (web 7/7, mobile Expo web 6/6).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 17:26:22 +01:00
pr-daaif
460ef4a80e feat(r3.4): corrections de recette (8 écarts) + recherche globale ⌘K
Arbitrage du référent sur la revue pixel : tout corriger, activer la
recherche.

- Stock : filtre fournisseur, sous-seuil en tête, « Entrée de stock »
  depuis la liste ; fiche pièce : fournisseur → lien Tiers.
- Statistiques : période 3/6/12 mois (paramètre months au contrat).
- Tiers : rattachements syndic→site (migration r3_recette_fixes,
  Location.partnerId gardé CLIENT), éditable sur la fiche site, seedé.
- Bibliothèque : filtre « Rattaché à » + glisser-déposer (modale
  préremplie, rattachement toujours requis).
- Recherche globale : GET /search (73 opérations) — familles OT/
  ascenseurs/sites filtrées par la matrice, « voir autre » respecté ;
  topbar ⌘K, debounce, résultats groupés, navigation clavier.

74 tests API (8 nouveaux sur le scoping de la recherche), 14/14
Playwright dont un parcours « recette corrigée », 18/18 contrôles en
navigateur réel, zéro erreur console.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 02:14:43 +01:00
pr-daaif
c5382a5538 feat(r3.3): écrans web de la gestion — stock, achats, coûts OT, documents, statistiques
- Stock : alertes sous seuil (strie ambre), « Préparer le BC » sur la ligne ;
  fiche pièce où les mouvements SONT le stock (entrée / ajustement motivé)
- Bons de commande : liste + panneau (envoi, annulation, réception → entrées
  de stock à PU figé) ; création préremplie depuis l'alerte de seuil
- Fiche OT : carte « Pièces & main-d'œuvre » réelle (consommation à prix figé
  annoncé avant le clic, temps au taux figé) + carte Documents (upload/download) ;
  même carte Documents sur la fiche ascenseur
- Statistiques : 4 KPI, pannes par organe (bilans codés), coûts par mois,
  top équipements ; le tableau de bord allume « Pannes par organe »
- Tiers, bibliothèque (upload rattaché, filtre par type), taux horaire
  éditable dans Personnes ; nav Ressources/Pilotage activée par la matrice
- Recette R3 Playwright (2 parcours autonomes) ; cleanup-e2e étendu aux
  entités R3 ; le formulaire BC attend la fin du refetch (stock périmé en cache)

13/13 e2e verts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:16:56 +01:00
pr-daaif
32eb20b5a0 fix(web): connexion — signaler clairement une API injoignable
Le formulaire email/mot de passe s'affichait seul, sans explication, quand
l'API locale n'était pas démarrée (la liste démo était masquée comme si
DEMO_MODE était absent). Une erreur réseau affiche désormais « L'API ne
répond pas — démarrez-la avec pnpm dev » ; le 404 (pas de mode démo)
reste silencieux, c'est le comportement ADR-002.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 21:11:46 +01:00
pr-daaif
50254daea4 feat(r2.4): portail public QR — signalement sans compte, suivi par jeton
- 3 routes publiques /portal (les seules @Public métier), throttlées
  (@nestjs/throttler : 10 signalements/min, 60 lectures/min) : résolution
  du QR, signalement (retourne un jeton de suivi opaque), suivi par
  référence + jeton — pas de jeton, pas de lecture, jamais de liste
- migration r2_portail : Request.publicToken (unique)
- page /q/{réf} fidèle à l'écran 6 validé R0 (mobile d'abord) : équipement
  prérempli « détecté par le QR », interrupteur personne bloquée,
  suivi sans jargon Reçu → Intervention → Résolu (dérivé de l'OT lié),
  rejet affiché « Sans suite : {motif} », photo annoncée (upload R3) ;
  signalements gardés sur le téléphone (localStorage, 10 max)
- e2e : LA boucle produit — gardien sans compte → traitement → ✓ Résolu ;
  11 tests Playwright verts, 50 tests API, 52 opérations au contrat
- générateur OpenAPI : paramètres non-« id » plus typés uuid

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:33:10 +01:00
pr-daaif
6a2dae1710 feat(r2.3): écrans web exploitation — OT, demandes, préventif, compteurs, urgence
- liste OT (filtres, strie rouge, « immédiat ») ; fiche OT : transitions
  pilotées par allowedTransitions, clôture grisée avec la garde expliquée,
  bilan codé (6 selects sur référentiels), checklist Fait→N-A→à faire,
  activité + commentaires, assignation, annulation motivée
- nouvel OT : interrupteur « personne bloquée » qui force la priorité
- demandes : table + panneau d'approbation (priorité, assignation,
  approuver → fiche OT), rejet en modale à motif obligatoire, signalement
  interne ; statut « Résolue » dérivé de l'OT lié
- préventif : tuiles réelles, générer + résumé (« regénérer ne double
  rien »), gabarits administrables ; compteurs : saisie + historique
- tableau de bord réel : bandeau urgence cliquable, KPIs, OT par statut,
  interventions récentes ; accueil dédié aux rôles sans exploitation
- urgence traversante : chip topbar pulsante (60 s), badges de nav
- GET /assets/options (auth seule) : le Demandeur peut désigner l'appareil
  qu'il signale — trou débusqué par l'e2e (49 opérations au contrat)
- génération préventive durcie : collision de référence RETENTÉE (plus de
  saut silencieux), P2003 toléré ; 3 runs Jest complets consécutifs verts
- 9 tests Playwright (recette R2 officielle rejouée intégralement),
  50 tests API (94,6 % / 78,9 %)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:13:20 +01:00
pr-daaif
9778629827 feat(r1.2): écrans web du référentiel — 7 écrans fidèles à maquette-r1
- Sites : liste + carte Leaflet/OSM réelle (pins maquette, positions
  PostGIS), création en modale avec position posée au clic sur la carte
- Fiche site : arbre site→zones, appareils rattachés, ajout de zone
- Ascenseurs : table dense, filtres site/statut, strie rouge à l'arrêt ;
  fiche appareil (organes ± ajout/retrait, statut, QR réel) ; création
  identité → rattachement → organes ; étiquette A6 imprimable (objet
  papier, window.print n'imprime qu'elle)
- Personnes & équipes : invitation → lien d'activation affiché à copier
  (pas d'email en R1, décision explicite), renvoi de lien, équipes ;
  page /activation (choix du mot de passe, connexion directe)
- Catégories : ajout, renommage inline, désactivation
- navigation et actions pilotées par la matrice (usePermissions) —
  l'API re-vérifie chaque requête
- e2e Playwright : recette R1 officielle rejouée intégralement (site →
  zone → appareil+organe → étiquette → invitation → activation) +
  parcours « la matrice pilote l'UI » ; purge idempotente en globalSetup
- alias Vite @siop/shared → source TS (exports nommés CJS ↯ workspace lié)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:06:45 +01:00
pr-daaif
4f3af5af4f feat(r0.11): apps/web — connexion + sélecteur démo, coquille, /design, client typé
- React 19 + Vite + Tailwind v4 : tokens.css copié tel quel (source de
  vérité), classes composants extraites de la maquette validée, Manrope
  auto-hébergée, primitives shadcn-style possédées (Button cva, menu Radix)
- connexion fidèle à la maquette ; liste démo affichée seulement si
  /auth/demo-accounts répond (404 ⇒ rien — ADR-002, l'API seule source)
- coquille : sidebar 4 groupes avec rail safran actif (écrans futurs marqués
  R1-R3), topbar recherche/thème/chip DÉMO + sélecteur de rôle (bascule 101 ms,
  critère < 3 s) ; page /design = référence vivante des revues pixel
- règle d'or : schema.d.ts généré depuis docs/openapi.json et committé
  (openapi-typescript + openapi-fetch)
- tokens.css : tokens --nav-* ajoutés (valeurs de la maquette validée) ;
  seed réaligné sur les personas de la maquette
- vérifié en navigateur réel (Playwright + Chrome headless) : 7 captures,
  parcours démo complet, bi-thème, zéro erreur console ; typecheck + vitest + build OK

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 22:09:40 +01:00