'array', 'file_size' => 'integer', ]; // Relación polimórfica: pertenece a Project, Phase, Layer o Feature public function mediable() { return $this->morphTo(); } public function uploader() { return $this->belongsTo(User::class, 'uploaded_by'); } // Helper: URL pública del archivo public function getUrlAttribute() { return Storage::url($this->file_path); } // Helper: si es imagen public function getIsImageAttribute() { return str_starts_with($this->file_type, 'image/'); } // Helper: tamaño formateado public function getFormattedSizeAttribute() { $bytes = $this->file_size; if ($bytes >= 1073741824) return round($bytes / 1073741824, 2) . ' GB'; if ($bytes >= 1048576) return round($bytes / 1048576, 1) . ' MB'; if ($bytes >= 1024) return round($bytes / 1024) . ' KB'; return $bytes . ' B'; } // Scopes public function scopeImages($query) { return $query->where('category', 'image'); } public function scopeDocuments($query) { return $query->where('category', 'document'); } // Boot: borrar archivo físico al eliminar registro protected static function booted() { static::deleting(function ($media) { Storage::delete($media->file_path); }); } }