'array', 'expires_at' => 'datetime', 'active' => 'boolean', ]; // Configuración visual por tipo public const TYPES = [ 'info' => ['label' => 'Información', 'color' => 'primary', 'icon' => 'fa-info-circle'], 'promocion' => ['label' => 'Promoción', 'color' => 'success', 'icon' => 'fa-tag'], 'mantenimiento' => ['label' => 'Mantenimiento', 'color' => 'warning', 'icon' => 'fa-tools'], 'aviso' => ['label' => 'Aviso', 'color' => 'danger', 'icon' => 'fa-exclamation-triangle'], ]; public const ROLES = [ 'all' => 'Todos', 'Alumno' => 'Alumnos', 'Docente' => 'Docentes', 'Admin' => 'Administradores', 'Control escolar' => 'Control escolar', 'Coordinación académica' => 'Coordinación académica', 'Programador' => 'Programadores', 'Promotor' => 'Promotores', ]; public function author(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } // Solo activos y no vencidos public function scopeVigentes(Builder $q): void { $q->where('active', true) ->where(fn($q) => $q->whereNull('expires_at')->orWhere('expires_at', '>', now())); } // Filtra por roles del usuario public function scopeParaRoles(Builder $q, array $roles): void { $q->where(function ($q) use ($roles) { $q->whereJsonContains('audience', 'all'); foreach ($roles as $role) { $q->orWhereJsonContains('audience', $role); } }); } public function typeConfig(): array { return self::TYPES[$this->type] ?? self::TYPES['info']; } public function isExpired(): bool { return $this->expires_at && $this->expires_at->isPast(); } }