fix: A31 — transaction par migration + helper columns() (v7.6.0)
FlowDeck CI / lint (push) Canceled after 0s
FlowDeck CI / test (push) Canceled after 0s
FlowDeck CI / docker (push) Canceled after 0s

- `_apply_one()` : BEGIN explicite → `fn(conn)` → marque `schema_version` →
  commit ; rollback complet à l'échec. Avant le DDL sortait en autocommit
  (isolation_level legacy) : un échec au milieu laissait un schéma partiel
  commité SANS ligne de version, et la reprise rejouait un DDL déjà appliqué.
  Si une transaction englobante subsiste (init_db commit juste avant), on la
  vide d'abord plutôt que de l'englober.
- Helper unique `columns(conn, table)` (valide l'identifiant, ValueError sinon)
  : 25 copies de `{r[1] for r in conn.execute("PRAGMA table_info(...)")}`
  éliminées dans migrations.py (21 littéraux + 3 f-string + 1 variante row).
  `table_exists`/`column_exists` préconisés par l'audit NON livrés : aucune
  migration n'interroge sqlite_master, un contrôle unitaire se lit dans le set.
- Smoke : DB fraîche → 28 migrations → version 29, ré-apply idempotent.

tests : test_migration_transaction_rolls_back (DDL partiel annulé + zéro marque
de version), test_columns_helper_validates_table_name

suite **1036/1036** · `ruff check app tests` OK · OpenAPI 511 chemins / 7.6.0
docs (ROADMAP/CHANGELOG/WORKLOAD/VERSION) à jour
This commit is contained in:
2026-10-01 10:13:23 -04:00
parent 7be96f0618
commit f706424f90
8 changed files with 140 additions and 34 deletions
+21
View File
@@ -1,5 +1,26 @@
# Changelog - FlowDeck
## v7.6.0 (2026-10-01) — Audit : A31 (dette migrations)
### Fixed
- **A31** — transaction par migration : `_apply_one()` fait `BEGIN` → `fn(conn)`
→ marque `schema_version` → `commit`, rollback complet à l'échec. Avant, le
DDL sortait en autocommit (isolation_level legacy) : un échec au milieu
laissait un schéma partiel commité SANS ligne de version, et la reprise
rejouait un DDL déjà appliqué
- **A31** — helper unique `columns(conn, table)` (valide l'identifiant,
`ValueError` sinon) : **25 copies** de
`{r[1] for r in conn.execute("PRAGMA table_info(...)")}` éliminées dans
`migrations.py`. `table_exists`/`column_exists` préconisés par l'audit non
livrés : aucune migration n'interroge `sqlite_master`, un contrôle unitaire
se lit dans le set
### Tests
- `test_migration_transaction_rolls_back` (DDL partiel annulé + pas de marque
de version, chemin nominal enregistré), `test_columns_helper_validates_table_name`
## v7.5.0 (2026-10-01) — Audit : A29, A42 (partiel)
### Changed