'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); }); } }