export const WARNING_LIMIT_BYTES = 4_294_967_296; export const CRITICAL_LIMIT_BYTES = 4_831_838_208; export const HARD_LIMIT_BYTES = 5_368_709_120; export const CAPACITY_COUNTED_FILE_KINDS = [ "reference", "generated", "export", "derived", "sticker_original", "sticker_thumbnail", ] as const; export const CAPACITY_EXCLUDED_STORAGE = [ "read_only_assets", "application_files", "database", "logs", "audit", "browser_cache", "user_downloads", ] as const; export type CapacityNoticeLevel = "normal" | "warning" | "critical"; export type StorageStatus = "active" | "full" | "unavailable"; export type StorageAction = | "project_json_write" | "binary_write" | "ai_call" | "latest_export_write" | "read" | "download" | "client_only_download" | "permanent_delete" | "explicit_cleanup"; export type StorageActionDecision = "allow" | "reject_capacity" | "reject_unavailable" | "reject_uncommitted"; export function classifyCapacity(managedContentBytes: number, activeReservationBytes: number) { if (!Number.isSafeInteger(managedContentBytes) || managedContentBytes < 0) throw new Error("managed_content_bytes_invalid"); if (!Number.isSafeInteger(activeReservationBytes) || activeReservationBytes < 0) throw new Error("active_reservation_bytes_invalid"); const capacity_notice_level: CapacityNoticeLevel = managedContentBytes < WARNING_LIMIT_BYTES ? "normal" : managedContentBytes < CRITICAL_LIMIT_BYTES ? "warning" : "critical"; const storage_status: StorageStatus = managedContentBytes + activeReservationBytes >= HARD_LIMIT_BYTES ? "full" : "active"; return { capacity_notice_level, storage_status }; } export function decideStorageAction( status: StorageStatus, sqliteWritable: boolean, action: StorageAction, ): StorageActionDecision { if (status === "unavailable") { if (action === "read" || action === "download" || action === "client_only_download") return "allow"; if (action === "permanent_delete" || action === "explicit_cleanup") { return sqliteWritable ? "allow" : "reject_uncommitted"; } return "reject_unavailable"; } if (status === "full" && (action === "binary_write" || action === "ai_call" || action === "latest_export_write")) { return "reject_capacity"; } return "allow"; } export function storageCapacityErrorDetails(input: { activeReservationBytes: number; managedContentBytes: number; projectedWriteBytes: number; }) { const { capacity_notice_level, storage_status } = classifyCapacity( input.managedContentBytes, input.activeReservationBytes, ); return { capacity_status: storage_status === "full" ? "full" as const : capacity_notice_level, remaining_bytes: Math.max(0, HARD_LIMIT_BYTES - input.managedContentBytes - input.activeReservationBytes), }; }