Commit Graph
928 Commits
Author SHA1 Message Date
bruno 38f39a10ae feat: tri, filtre, recherche et export CSV dans la visionneuse XLSX #153
A13 (affichage seul, le classeur n'est jamais réécrit) : clic sur un
en-tête pour trier la colonne (asc/desc, numérique si toutes les valeurs
le sont, localeCompare fr sinon — les cellules modifiées suivent leur
ligne) ; l'unique champ de recherche filtre les lignes ET surligne les
occurrences (marque <mark>, navigation ↑/↓/Entrée, compteur i18n,
insensible à la casse par défaut, bouton Aa) ; bouton « Réinitialiser »
qui re-rend le fichier (vérité serveur) ; export CSV de la feuille
visible (BOM UTF-8, échappement ;/" et retrait des ombres de valeurs
calculées).

Vérifié : xlsx-viewer.test.mjs 30/30 (5 nouveaux) + contre-preuves
(tri neutralisé -> 1 échec, filtre neutralisé -> 1 échec), validate-imports,
i18n parity (xlsx.find_*, xlsx.sort_*, xlsx.csv_export).

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <[email protected]>
v2.35.0
2026-09-28 12:28:09 -04:00
bruno 48e023ba25 feat: navigation clavier et barre de formule dans la visionneuse XLSX #153
A7 : barre de formule sous la barre d'outils (nom de cellule active A1 +
miroir du contenu, édition live, Entrée valide, Échap annule puis
refocalise) ; flèches et Tab déplacent la cellule active dans les 4
directions (Shift inverse Tab), outline persistant sur la cellule active
quand le focus passe à la barre ; Maj+Entrée ne valide plus (réservé au
multiligne A7+). td.tabIndex=0 pour la focalisation clavier.

Vérifié : xlsx-viewer.test.mjs 25/25 (6 nouveaux), E2E 9/9 (barre +
flèches + Échap sur fixture réelle), validate-imports, i18n parity
(xlsx.formula_bar_placeholder, xlsx.active_cell).

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <[email protected]>
v2.34.0
2026-09-28 12:18:24 -04:00
bruno 011ec84f23 feat: outils IA de lecture et d'edition des classeurs existants #153
A6 : list_xlsx_sheets (noms + dimensions + truncated), xlsx_to_markdown
(table bornee 100x20 pour le contexte LLM), update_xlsx_cells et
append_xlsx_rows (WRITE + confirmation, via edit_xlsx_cells : verrou,
ecriture atomique, neutralisation des formules, 409 lossy). Les lignes
ajoutees sont coercees comme dans le viewer (A10). Labels de step
ai.step.xlsx_* FR/EN ; update_xlsx_cells/append_xlsx_rows branches sur
MUTATING_TOOLS et FILE_WRITE_TOOLS (refresh viewer via obsigate:file-written).

Tests : test_spreadsheet_tools.py 17 (risque, confirmation, persistance,
garde formule heritee, coercion) + contre-preuve (cells vide -> 2 echecs).
ruff 0, mypy 0, i18n parity, validate-imports.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <[email protected]>
v2.33.0
2026-09-28 12:05:16 -04:00
bruno 472ea9d309 feat: chargement à la demande des lignes cachées des tableurs #153
CI / lint (push) Successful in 2m24s
CI / security (push) Failing after 1m39s
CI / test (push) Successful in 4m0s
CI / build (push) Successful in 1m37s
CI / e2e (push) Successful in 15m34s
A9bis : sous une feuille tronquée, un pied de page « N lignes affichées
sur M · Charger la suite » fetch la fenêtre suivante (limit=500) au clic
ou à l'approche du bas du tableau (sentinelle de défilement, marge 120px).
Les lignes ajoutées passent par le même pipeline d'édition que le rendu
initial (setupCell factorisé) : éditables et sauvegardables immédiatement.
Fetch échoué → bouton restauré (retry) + toast ; feuille complète → pied
de page masqué (class done).

Vérifié : xlsx-viewer.test.mjs 19/19 (5 nouveaux, contre-preuve
wireLazyRows désactivé → 5 échecs), E2E 8/8 (A520 visible et éditable
après clic), validate-imports 40 modules, unit.test.mjs 12/12, i18n parity.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <[email protected]>
v2.32.0
2026-09-28 11:52:42 -04:00
bruno 6ba04c4381 feat: troncature annoncee et lecture par fenetres des tableurs #153
CI / lint (push) Successful in 2m29s
CI / security (push) Failing after 1m39s
CI / test (push) Successful in 4m1s
CI / build (push) Successful in 1m37s
CI / e2e (push) Successful in 14m47s
- BUG-090 (#153 A8) : render_sheets() expose total_rows/total_cols,
  max_rows/max_cols et truncated ; la visionneuse affiche un bandeau
  « Feuille tronquée » (i18n FR/EN) au lieu de couper en silence, et la
  ligne d'en-têtes devient sticky (top:auto sur les numéros de ligne).
- #153 A9 : GET /api/file/{vault}/xlsx/sheet?sheet&offset&limit sert une
  fenêtre de 1 à 1000 lignes avec les vraies coordonnées A1, has_more de
  pagination et valeurs calculées A12 ; 404 feuille inconnue, 415 non-xlsx.
- Tests : TestXlsxTruncationNotice (4) + TestXlsxSheetWindow (11) avec
  contre-preuves, xlsx-viewer.test.mjs 14/14, E2E 7/7 (fixture
  sample-xlsx-large.xlsx 520 lignes), suite 1417 passed / 6 skipped,
  ruff/mypy 0, i18n parity.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <[email protected]>
v2.31.0
2026-09-28 10:38:24 -04:00
bruno 06f8e63d06 feat: tableurs indexables, saisie typée et valeurs calculées #153
Les tableurs étaient invisibles à la recherche, chaque saisie devenait
du texte, et une formule n'affichait que sa formule.

- A5 : extract_indexable_text() indexe les noms de feuilles et les 20
  premières lignes (plafond 5 k caractères) pour le TF-IDF et la
  recherche sémantique. Un mot tapé dans une cellule rend le fichier
  trouvable ; un classeur chiffré s'indexe par son seul nom.
- A10 : la saisie est typée comme dans Excel — booléens
  (TRUE/FAUX/OUI/NON) et dates FR JJ/MM/AAAA en ordre jour-first, donc
  01/02/2026 est le 1er février. Une saisie ressemblant à une formule
  n'est jamais convertie (BUG-088 préservé).
- A12 : la valeur calculée par Excel s'affiche sous la formule, via une
  2e lecture data_only=True faite seulement si l'archive contient un
  <v>. Info-bulle traduite FR/EN, aucun texte d'interface côté backend.
- BUG-089 : un reindex manuel ne reconstruisait pas l'index inversé, et
  backend/search.py lisait l'index via un import par valeur — après un
  rechargement du module, la recherche écrivait dans un dict périmé.

Contre-preuves vérifiées pour A5, A10 et A12 (neutralisation de chaque
fonction → échec des tests concernés). Tests : 1402 pytest, 10 JSDOM,
4 E2E, suite E2E complète verte, ruff/mypy 0.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <[email protected]>
v2.30.0
2026-09-27 22:43:24 -04:00
bruno 31d4616baf feat: garde-fous d'écriture des classeurs Excel #153 (P0)
L'édition d'un .xlsx pouvait détruire une partie du classeur, le
concurrencer en silence, ou diffuser une injection de formule.

- BUG-085 : inspect_workbook() détecte ce qu'un round-trip openpyxl perd
  (valeurs calculées en cache, slicers, contrôles, connexions, custom
  XML, signature, commentaires enrichis, macros) → xlsx_lossy_features
  exposé en lecture, bandeau FR/EN, et 409 xlsx_lossy_content sans
  `force` (confirmation explicite puis reprise). Périmètre réel
  revalidé : graphiques, images et TCD survivent au round-trip.
- BUG-086 : écriture atomique (fichier .tmp + os.replace) : un plantage
  ne peut plus tronquer le classeur, le backup reste intact.
- BUG-087 : verrou par fichier autour du read-modify-write (timeout 15 s,
  409 conflict) ; endpoint xlsx/save devenu synchrone pour que
  l'attente s'exécute dans le threadpool.
- BUG-088 : une saisie en '=' ou '@' est stockée en texte, sauf opt-in
  `allow_formula` ou le bouton f(x) de la visionneuse. Le handler
  ServiceError expose désormais code + details, que api() propage.
- BUG-084 : la suppression d'une vault purge enfin l'index inversé
  (documents fantômes qui continuaient de matcher) et is_stale() devient
  is_ready(), le nom étant trompeur (la staleness n'existe plus).

Tests : 1390 pytest, 10 JSDOM (xlsx-viewer.test.mjs, branché au CI),
3 E2E Playwright, suite E2E complète verte, ruff/mypy 0.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <[email protected]>
v2.29.0
2026-09-27 20:39:12 -04:00
bruno 4c4b1222d5 chore: ignore les diagrammes E2E générés (excalidraw)
CI / lint (push) Successful in 2m23s
CI / security (push) Failing after 1m48s
CI / test (push) Successful in 3m49s
CI / build (push) Successful in 2m28s
CI / e2e (push) Successful in 14m5s
v2.28.16
2026-09-27 14:46:09 -04:00
bruno a3973b981c securite: #87 T6-T8 fin dette — deps qualifiées, semgrep, Secure auto, CORS v2.28.15 2026-09-27 12:43:31 -04:00
bruno b6e2029770 fix: E2E node-direct, timeouts réalistes 25/30 min (complément BUG-080)
CI / lint (push) Successful in 2m22s
CI / security (push) Successful in 1m37s
CI / test (push) Successful in 4m48s
CI / build (push) Successful in 1m33s
CI / e2e (push) Successful in 14m3s
v2.28.14
2026-09-27 11:28:35 -04:00
bruno 6b878caff3 securite: #87 T5c script-src sans unsafe-inline (nonces T5b)
CI / lint (push) Successful in 2m18s
CI / security (push) Successful in 1m37s
CI / test (push) Successful in 4m32s
CI / build (push) Successful in 1m34s
CI / e2e (push) Successful in 14m22s
v2.28.13
2026-09-27 10:36:00 -04:00
bruno e9b7a317c1 fix: mfa/status 200 auth désactivée (garde anonymous) BUG-081 + clôture BUG-080/082/083 v2.28.12 2026-09-27 10:35:33 -04:00
bruno 14b8032635 fix: CI lint — config-ai-keys.test.mjs rejoint l'étape JSDOM (complément BUG-082)
CI / security (push) Successful in 1m37s
CI / lint (push) Successful in 2m18s
CI / test (push) Successful in 4m8s
CI / build (push) Successful in 1m38s
CI / e2e (push) Successful in 14m28s
v2.28.11
2026-09-27 09:44:18 -04:00
bruno 7dfe26c83d fix: CI security — echo pip-audit sans dièse (runner Act) BUG-083
CI / lint (push) Failing after 1m50s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
CI / security (push) Successful in 1m37s
v2.28.10
2026-09-27 09:37:34 -04:00
bruno 24229316c7 fix: CI lint — upload.test.mjs rejoint l'étape JSDOM (jsdom) BUG-082
CI / lint (push) Failing after 1m30s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
CI / security (push) Failing after 1m33s
v2.28.9
2026-09-27 09:23:51 -04:00
bruno 7d70e0fb75 fix: harnais E2E local anti-blocage BUG-080
CI / lint (push) Failing after 1m51s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
CI / security (push) Failing after 1m33s
v2.28.8
2026-09-27 09:08:58 -04:00
bruno d70ecd0968 securite: #87 T5b nonces CSP prets pour bascule (sans changement) v2.28.7 2026-09-26 22:44:12 -04:00
bruno 36a4030c09 securite: #87 T5a supprime 16 handlers inline au profit de listeners (CSP inchangee) v2.28.6 2026-09-26 22:32:01 -04:00
bruno 330462e7a5 docs: #87 T4 consigne resultats E2E locaux (108/108 desktop, 10/10 mobiles cibles) v2.28.5 2026-09-26 22:22:31 -04:00
bruno 922dfa2e79 test: #87 T4 E2E XSS partage et lecteur + script serveur E2E avec progression v2.28.4 2026-09-26 21:46:16 -04:00
bruno 34fce932cb securite: #87 T3 cookies Secure centralises + CORS atteste (defaut inchange) v2.28.3 2026-09-26 18:37:19 -04:00
bruno 18b1e13f34 test: #87 T2 durcissement concurrence users.json et budget temps regex v2.28.2 2026-09-26 18:34:06 -04:00
bruno 7bee4a237d ci: #87 T1 bandit et npm audit bloquants, 5 suites frontend au CI v2.28.1 2026-09-26 18:30:04 -04:00
bruno d6cca2b1af feat: #85 T10 persistance etat (verrous stores, ratelimit SQLite) et cloture refonte v2.28.0 2026-09-26 18:10:10 -04:00
bruno 58312e64da refactor: #85 T9 extrait realtime et render vers modules dedies (comportement inchange) v2.27.12 2026-09-26 16:59:25 -04:00
bruno 3b0927a8c9 refactor: #85 T8 extrait vaults-history-conflicts vers backend/routers (comportement inchange) v2.27.11 2026-09-26 14:46:55 -04:00
bruno 6e527c371d refactor: #85 T7 extrait le domaine config vers backend/routers (comportement inchange) v2.27.10 2026-09-26 14:33:40 -04:00
bruno 6cccdc1f34 refactor: #85 T6c extrait media-pdf-export vers backend/routers (comportement inchange) v2.27.9 2026-09-26 14:06:52 -04:00
bruno 0abc17e9f2 refactor: #85 T6b extrait mutations fichiers-dossiers vers backend/routers (comportement inchange) v2.27.8 2026-09-26 13:51:36 -04:00
bruno b83d8dacdf refactor: #85 T6a extrait lecture fichiers vers backend/routers (comportement inchange) v2.27.7 2026-09-26 13:43:53 -04:00
bruno dadc055429 refactor: #85 T5 extrait le domaine search vers backend/routers + executor partage (comportement inchange) v2.27.6 2026-09-26 13:14:31 -04:00
bruno 750114a923 refactor: #85 T4 extrait le domaine backups vers backend/routers + sse partage (comportement inchange) v2.27.5 2026-09-26 13:06:45 -04:00
bruno 83a81da319 refactor: #85 T3 extrait le domaine sharing vers backend/routers (comportement inchange) v2.27.4 2026-09-26 12:51:06 -04:00
bruno 3eb0256127 refactor: #85 T2 extrait le CRUD webhooks vers backend/routers (comportement inchange) v2.27.3 2026-09-26 12:43:57 -04:00
bruno 9d8b3cc854 refactor: #85 T1 extrait le domaine health vers backend/routers (comportement inchange) v2.27.2 2026-09-26 12:36:49 -04:00
bruno 0ab402aa73 docs: roadmap priorise dette et securite #85 #87 (#77 non signe, #73 reporte)
CI / lint (push) Successful in 2m13s
CI / security (push) Successful in 1m34s
CI / test (push) Successful in 4m9s
CI / build (push) Successful in 1m31s
CI / e2e (push) Successful in 14m17s
v2.27.1
2026-09-26 11:55:32 -04:00
bruno c36c299466 docs: #152 — aligne changelog et roadmap sur la version livrée 2.27.0
Fusionne la section 2.26.0 (jamais publiée) dans 2.27.0 et corrige la ligne
index de la roadmap ; suppression du tag local v2.26.0.
v2.27.0
2026-09-25 20:32:14 -04:00
bruno 8611416670 feat: #152 viewer XLSX — affichage multi-feuilles, édition des cellules et téléchargement des .xlsx
- backend/xlsx_reader.py : rend openpyxl en tableaux HTML (plafond 500x40 par feuille)
- PUT /api/file/{vault}/xlsx/save : service edit_xlsx_cells (backup avant écriture, refs A1 validées)
- frontend : renderXlsxViewer (onglets, contenteditable, sauvegarde par feuille)
- docs : CHANGELOG [Unreleased], Roadmap index #152, archive, README FR/EN, exemple OpenAPI
2026-09-25 20:30:45 -04:00
bruno e20fd6bf97 fix: /api/diagnostics 500 « dictionary changed size during iteration » — snapshot des dicts avant itération BUG-079
CI / lint (push) Successful in 2m3s
CI / security (push) Successful in 1m27s
CI / test (push) Successful in 4m22s
CI / build (push) Successful in 1m22s
CI / e2e (push) Successful in 13m36s
v2.25.1
2026-09-24 17:13:40 -04:00
bruno 943005328c feat: barre d'outils de lecture epinglee, coloration syntaxique des fichiers de code et avatars predefinis (#115, #117, BUG-078)
CI / lint (push) Successful in 2m5s
CI / security (push) Successful in 1m27s
CI / test (push) Successful in 4m10s
CI / build (push) Successful in 1m23s
CI / e2e (push) Successful in 13m55s
v2.25.0
2026-09-24 16:21:45 -04:00
bruno e1842043d8 feat: assistant IA — approbation groupee des actions, bloc d'etapes, refresh UI et bouton Stop (BUG-074, BUG-075, BUG-076, BUG-077)
CI / lint (push) Successful in 2m1s
CI / security (push) Successful in 1m25s
CI / test (push) Successful in 4m19s
CI / build (push) Successful in 1m26s
CI / e2e (push) Successful in 13m38s
v2.24.0
2026-09-24 10:05:32 -04:00
bruno 9fb094f505 feat: refonte mobile de la section Configurations #114
CI / lint (push) Successful in 2m1s
CI / security (push) Successful in 1m26s
CI / test (push) Successful in 4m50s
CI / build (push) Successful in 1m22s
CI / e2e (push) Successful in 15m34s
v2.23.0
2026-09-24 08:43:18 -04:00
bruno d142049216 fix: degagement mobile sous la barre de navigation du bas (clearance retargetee .main-body) BUG-073
CI / lint (push) Successful in 1m59s
CI / security (push) Successful in 1m26s
CI / test (push) Successful in 3m41s
CI / build (push) Successful in 1m21s
CI / e2e (push) Successful in 14m0s
v2.22.1
2026-09-23 23:36:35 -04:00
bruno 33fe1a3439 feat: ordre naturel des sections Configurations et avatar utilisateur #113
CI / lint (push) Successful in 1m59s
CI / security (push) Successful in 1m28s
CI / test (push) Successful in 4m14s
CI / build (push) Successful in 1m20s
CI / e2e (push) Successful in 13m43s
v2.22.0
2026-09-23 22:18:29 -04:00
bruno a726ad8511 feat: en-tete allege, compte utilisateur en sidebar et pellicule d'images defilable (molette + fleches) #112
CI / lint (push) Successful in 1m59s
CI / security (push) Successful in 1m29s
CI / test (push) Successful in 4m59s
CI / build (push) Successful in 1m48s
CI / e2e (push) Successful in 13m49s
v2.21.0
2026-09-23 21:06:41 -04:00
bruno b926f01b85 feat: visionneuse d'images - navigation fluide, image ajustee au cadre, fleches laterales et pellicule persistante #111
CI / lint (push) Successful in 2m2s
CI / security (push) Successful in 1m23s
CI / test (push) Successful in 4m23s
CI / build (push) Successful in 1m19s
CI / e2e (push) Successful in 13m27s
v2.20.0
2026-09-23 14:37:41 -04:00
bruno 8264e7ffae fix: conserver plein ecran et panneau metadonnees dans la visionneuse d'images (sidebar droite) + lanceur E2E Windows BUG-072
CI / lint (push) Successful in 2m1s
CI / security (push) Successful in 1m23s
CI / test (push) Successful in 4m27s
CI / build (push) Successful in 1m19s
CI / e2e (push) Successful in 17m45s
v2.19.2
2026-09-23 13:43:47 -04:00
bruno 80852374a8 fix: positionnement lecteur media (mobile/desktop) et drag libre de la mini-video #110
CI / lint (push) Successful in 2m0s
CI / security (push) Successful in 1m22s
CI / test (push) Successful in 4m36s
CI / build (push) Successful in 1m18s
CI / e2e (push) Successful in 13m7s
v2.19.1
2026-09-23 11:42:23 -04:00
bruno e3c6789776 feat: lecteur média persistant Now Playing (dock audio, mini-vidéo PiP, Media Session, mobile) #110
CI / lint (push) Successful in 2m5s
CI / security (push) Successful in 1m23s
CI / test (push) Successful in 3m57s
CI / build (push) Successful in 1m18s
CI / e2e (push) Successful in 13m18s
v2.19.0
2026-09-23 10:41:15 -04:00
bruno e2417cb5ab feat: support audio & vidéo — lecteurs HTML5 intégrés #109
CI / lint (push) Successful in 1m58s
CI / security (push) Successful in 1m22s
CI / test (push) Successful in 4m32s
CI / build (push) Successful in 2m6s
CI / e2e (push) Successful in 12m57s
v2.18.0
2026-09-23 09:14:34 -04:00