'integer', 'user_id' => 'integer', 'is_read' => 'boolean', 'delivered' => 'boolean', 'delivered_at' => 'datetime', ]; /* ============================================================ * Relationships (optional) * ============================================================ */ public function user(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } public function notification(): BelongsTo { // Change Notification::class if your model name differs return $this->belongsTo(Notification::class, 'notification_id'); } /* ============================================================ * Scopes * ============================================================ */ public function scopeForUser(Builder $q, int $userId): Builder { return $q->where('user_id', $userId); } public function scopeUnread(Builder $q): Builder { return $q->where('is_read', 0); } public function scopeRead(Builder $q): Builder { return $q->where('is_read', 1); } public function scopeDelivered(Builder $q): Builder { return $q->where('delivered', 1); } public function scopeUndelivered(Builder $q): Builder { return $q->where(function (Builder $w) { $w->whereNull('delivered')->orWhere('delivered', 0); }); } /* ============================================================ * Helpers * ============================================================ */ public function markDelivered(?\DateTimeInterface $at = null): self { $this->delivered = true; $this->delivered_at = $at ?: now(); $this->save(); return $this; } public function markRead(): self { $this->is_read = true; $this->save(); return $this; } /* ============================================================ * Optional validation helper * ============================================================ */ public static function rules(bool $updating = false): array { $req = $updating ? 'sometimes' : 'required'; return [ 'notification_id' => [$req, 'integer', 'min:1', 'exists:notifications,id'], 'user_id' => [$req, 'integer', 'min:1', 'exists:users,id'], 'is_read' => ['nullable', 'boolean'], 'delivered' => ['nullable', 'boolean'], 'delivered_at' => ['nullable', 'date'], ]; } }