[ADD] migration quality: needaction became notifications in 15

Verified bump by bump rather than deduced from a name that looks alike:
1269 rows in 12, 13 and 14, the table disappears in 15 and
mail_notification holds exactly 1269. Not one lost. That row-for-row
carry-over is what earns the entry — a neighbouring name would have
proved nothing.

It is dated at 15 and not earlier: the table is still full at 14, and an
entry that applied sooner would mask a loss that happened before the
redesign.

The unexplained list goes from 56 to 55.

--- FR ---

[ADD] qualité de migration : needaction est devenu notifications en 15

Vérifié palier par palier plutôt que déduit d'un nom qui se ressemble :
1269 lignes en 12, 13 et 14, la table disparaît en 15 et
mail_notification en compte exactement 1269. Pas une perdue. C'est ce
report à l'unité près qui autorise l'entrée — un nom voisin n'aurait rien
prouvé.

Elle est datée de 15 et pas avant : la table est encore pleine en 14, et
une entrée qui s'appliquerait plus tôt masquerait une perte survenue avant
la refonte.

La liste des pertes inexpliquées passe de 56 à 55.

Assisted-by: Claude Opus 5
This commit is contained in:
Mathieu Benoit 2026-08-21 03:03:04 -04:00
parent 53fa936168
commit 4103e13800
2 changed files with 43 additions and 0 deletions

View file

@ -513,6 +513,16 @@ SEMANTIC_MAP = (
"kind": "retired",
"why": "chart templates left the database",
},
# Vérifié palier par palier : 1269 lignes en 12, 13 et 14, la table
# disparaît en 15 et `mail_notification` en compte exactement 1269.
# Pas une perdue.
{
"since": 15,
"table": "mail_message_res_partner_needaction_rel",
"into": "mail_notification",
"kind": "merged",
"why": "needaction became notifications",
},
{
"since": 15,
"table": "stock_inventory",

View file

@ -333,6 +333,39 @@ class TestTheSemanticMap(Base):
texte = "\n".join(quality.render_compare(diff, colour=False))
self.assertLess(texte.index("unexplained"), texte.index("moved or"))
def test_needaction_became_notifications_in_15(self):
"""Vérifiée palier par palier, pas déduite d'un nom qui se ressemble.
1269 lignes en 12, 13 et 14 ; la table disparaît en 15 et
`mail_notification` en compte exactement 1269. Pas une perdue.
C'est ce report à l'unité près qui autorise l'entrée — un nom
voisin n'aurait rien prouvé.
"""
diff = self.perte(
"mail_message_res_partner_needaction_rel",
1269,
0,
version="15.0",
cible="mail_notification",
cible_avant=0,
cible_apres=1269,
)
connu = diff["rows_lost"][0][3]
self.assertIsNotNone(connu)
self.assertEqual(connu["into"], "mail_notification")
self.assertEqual(connu["gained"], 1269)
def test_it_is_not_explained_at_the_14_bump(self):
# La table est encore pleine en 14 : une entrée qui s'appliquerait
# plus tôt masquerait une perte survenue avant la refonte.
diff = self.perte(
"mail_message_res_partner_needaction_rel",
1269,
0,
version="14.0",
)
self.assertIsNone(diff["rows_lost"][0][3])
def test_an_unknown_table_stays_unexplained(self):
diff = self.perte("ma_table_a_moi", 50, 0)
self.assertIsNone(diff["rows_lost"][0][3])