using ManagerService.Data; namespace ManagerService.Helpers { /// /// Seule source de vérité pour StoragePath et SizeBytes d'une Resource. /// /// Trois chemins écrivent ces colonnes : la création par téléversement et la /// création par JSON (ResourceController), le backfill des lignes existantes, /// et MigrationController (écart e de la bascule). Chacun calculant pour son /// compte, ils divergeaient déjà : le chemin multipart renseignait SizeBytes /// mais laissait StoragePath nul. /// public static class ResourceStorage { /// /// Les types URL pointent hors du bucket : ni chemin de stockage, ni poids /// à compter dans le quota. C'est la distinction que les appelants perdaient. /// public static bool HasBlob(ResourceType type) => type != ResourceType.ImageUrl && type != ResourceType.VideoUrl && type != ResourceType.JSONUrl; /// /// Chemin déterministe dans le bucket — reconstructible sans lire la ligne, /// ce dont le backfill dépend. Null pour un type sans blob. /// public static string PathFor(ResourceType type, string instanceId, string resourceId) => HasBlob(type) ? $"pictures/{instanceId}/{resourceId}" : null; /// /// Renseigne les deux colonnes de stockage. Ne touche à rien pour un type URL, /// dont SizeBytes doit rester à 0 pour ne pas peser sur le quota. /// public static void Apply(Resource resource, long sizeBytes) { if (!HasBlob(resource.Type)) return; resource.StoragePath = PathFor(resource.Type, resource.InstanceId, resource.Id); resource.SizeBytes = sizeBytes; } } }