Trois n'existaient pas — vérifié dans l'export Mongo plutôt que dans la doc :
- (a) « BuildSection ne couvre que 11 types sur 13 » : les 327 sections de
l'export ne contiennent que les types 0 à 10. SectionEvent et
SectionParcours sont nés avec Postgres v3, le default est un filet.
- (f) IsQRCode/IsSearchText/IsSearchNumber n'existent pas dans Mongo, false
est le bon défaut. Contrôle inverse fait : les cinq réglages qui existent
vraiment sont bien mappés sur AppConfigurationLink.
- (g) était tombé avec le rename du lot B.
Les cinq réels :
- (b) QuizQuestions = new() jetait les questions. Mesuré : 5 sections quiz
en portent 41, réponses comprises. Migrées en MultipleChoice, le type de
validation n'existant pas dans l'ancien modèle. EventAgendas et l'absence
de GuidedPath sont corrects : Mongo n'a ni événement ni parcours.
- (c) la source ne contient que 4 champs, il n'y avait rien à mapper de
plus. PublicApiKey générée (même schéma que l'onboarding), WebSlug via
SlugHelper, drapeaux de plateforme dérivés des configurations, plan
affecté par nom avec repli sur Pro, IsAssistant allumé seulement si le
plan donne des jetons.
- (d) Mongo n'a pas de champ Role : le ContentEditor en dur dégradait les
10 utilisateurs en silence, plus personne n'aurait pu gérer les
utilisateurs de son instance. Passé à InstanceAdmin.
- (e) StoragePath n'était pas écrit du tout. Passe par ResourceStorage, le
calculateur commun à la création et au backfill. L'échec du HEAD, jusqu'ici
avalé, remonte dans le rapport.
- (h) transaction unique sur les neuf étapes, et 500 au lieu de 200 OK sur
échec fatal — un script de bascule testant le code HTTP concluait au
succès alors que l'erreur n'était que dans le corps.
ApplyPlanQuotas est dupliqué depuis InstanceController plutôt qu'appelé : la
migration ne doit pas casser si ce contrôleur change de forme.
dotnet build vert, dotnet test 143/143. Reste le dry run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
LOT B — une seule migration EF (LotB_FreezeSchema) :
- SectionMap.MapResourceId → IconResourceId. L'écart (g) de la bascule tombe
avec. Il fallait renommer aussi la propriété de navigation MapResource :
la convention EF l'appariait au FK, la laisser aurait fabriqué un FK
fantôme. Elle n'était utilisée nulle part ailleurs.
- SectionEvent.ParcoursIds supprimé (champ, DTO, SectionFactory, et une
initialisation dans un montage de test).
- Instance.IsImageWatermark remplace le `instanceId == "633ee379…"` en dur
de ResourceController.
EF a généré un RenameColumn, pas un drop+add : les icônes déjà configurées
survivent. L'avertissement de perte de données ne porte que sur le DropColumn
de ParcoursIds, ce qui est l'intention.
Non fait, et c'était une erreur de doc : « supprimer SectionEvent.IconResourceId ».
Ce champ n'existe pas — la ligne visée appartient à la classe imbriquée
MapAnnotation, partagée par SectionEvent, SectionAgenda et SectionMap, lue par
cinq contrôleurs et par GetReferencedResourceIds. La supprimer aurait cassé
les icônes d'annotation des trois types et la collecte offline.
SÉCURITÉ (lot A, même repo) :
- AuthenticationController.Authenticate : un bloc #if DEBUG écrasait l'email
et le mot de passe reçus par un compte de test, donc toute compilation en
Debug authentifiait n'importe quelle saisie. Retiré.
- EnableSensitiveDataLogging (qui écrit les valeurs des paramètres dans les
logs) passe sous #if DEBUG, l'idiome déjà employé dans Startup.cs pour le
CORS et Hangfire. Le Dockerfile publiant en -c Release, c'est un verrou réel.
LOT C1 :
- Calculateur StoragePath/SizeBytes extrait dans Helpers/ResourceStorage.cs,
avec 13 tests fixant l'invariant des types URL. Il ferme le lien L5 : le
backfill (C2) et l'écart (e) de la migration appelleront le même code.
- L'extraction a révélé la divergence qu'elle devait empêcher : des deux
chemins de création de ResourceController, le chemin multipart écrivait
SizeBytes mais laissait StoragePath nul.
dotnet build Debug et Release verts, dotnet test 143/143 (130 + 13).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>