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