DOCS/kanban/done/170-lot-medias-termine-cote-serveur-backfill-c2-e.md
2026-09-03 14:00:51 +02:00

6 lines
2.5 KiB
Markdown

---
title: Lot médias terminé côté serveur — backfill (C2) et quota autoritaire (C3)
---
<span><strong>C2</strong> : <code>POST /api/Resource/backfill-storage</code>, SuperAdmin, <code>dryRun</code> à <strong>true par défaut</strong> — la migration se joue sur une base vide, ce backfill sur des lignes de production. La méthode annoncée au plan (« <code>SizeBytes</code> par listing du bucket Firebase ») était <strong>inapplicable</strong> : le serveur n'avait aucun client de stockage. Le sondage passe par HEAD, et <strong>le sondeur est extrait plutôt que recopié</strong> (<code>ResourceSizeProbe</code>, partagé avec la migration — même raisonnement que L5). ⚠️ <strong>L'extraction a bouché un trou que personne ne cherchait</strong> : l'original ne notait l'échec que dans son <code>catch</code>, or un HEAD sur un blob absent <strong>ne lève pas</strong> — il répond 404 sans <code>Content-Length</code>. Ces ressources arrivaient à 0 octet <em>sans figurer dans le rapport</em>. Le « 37 sur 45 » du plan n'étant pas vérifiable d'ici, le backfill rend son propre inventaire, <code>Orphans</code> et <code>Unsized</code> séparés — deux causes distinctes, jamais additionnées.</span>
<span><strong>C3</strong> : ⚠️ le pré-vol <strong>existait déjà à moitié et ce n'était écrit nulle part</strong><code>Upload</code> (multipart) contrôlait, <code>Create</code> (JSON) ne contrôlait rien, or c'est le chemin qu'emprunte manager-app. ⚠️ Et les deux lectures du quota <strong>divergeaient</strong> : <code>Upload</code> lisait le <em>plan</em>, <code>GetQuota</code> l'<em>instance</em> avec le plan en repli — une instance à quota surchargé (le mécanisme de l'add-on) affichait un chiffre et se faisait bloquer sur un autre. Fermé par <code>StorageQuota</code>. <code>Delete</code> supprime le blob <strong>avant</strong> la ligne et renvoie <strong>502</strong> en la conservant si le bucket échoue : une ressource encore listée se rattrape, un blob que plus aucune ligne ne désigne est facturé à l'aveugle. ✅ L'angle mort laissé par C1 était une <strong>fausse crainte</strong> : <code>PathFor</code> ne construit qu'un <code>pictures/{instanceId}/{resourceId}</code>, le type n'entre pas dans le chemin. <strong>Aucun secret nouveau</strong> : <code>FirebaseAdmin</code> était déjà là pour le push, <code>Google.Cloud.Storage.V1</code> réutilise le même credential. <code>dotnet test</code> <strong>163/163</strong>.</span>