karimms/model-pulse

Add collaboration, messaging, and activity tracking to any Eloquent model.

Maintainers

Package info

github.com/karim-mesghouni/model-pulse

pkg:composer/karimms/model-pulse

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-03-22 22:01 UTC

This package is auto-updated.

Last update: 2026-04-22 22:24:41 UTC


README

Add collaboration, messaging, attachments, activity logs, and domain events to any Eloquent model.

Features

  • Follow/unfollow support for any model (Followable)
  • Thread-like messaging APIs (Messagable)
  • File attachment helpers (Attachable)
  • Automatic model activity logging (HasLogActivity)
  • Typed Laravel events for messaging and activity operations

Requirements

  • PHP 8.3+
  • Laravel components:
    • illuminate/container ^12|^13
    • illuminate/contracts ^12|^13
    • illuminate/database ^12|^13

Installation

composer require karimms/model-pulse

Run package migrations:

php artisan migrate --path=vendor/karimms/model-pulse/database/migrations

Quick Start

Add traits to your Eloquent model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Karim\ModelPulse\Traits\Attachable;
use Karim\ModelPulse\Traits\Followable;
use Karim\ModelPulse\Traits\HasLogActivity;
use Karim\ModelPulse\Traits\Messagable;

class Project extends Model
{
    use Followable;
    use Messagable;
    use Attachable;
    use HasLogActivity;

    public function getModelTitle(): string
    {
        return $this->name ?? 'Project';
    }

    public function getLogAttributeLabels(): array
    {
        return [
            'name' => 'Name',
            'status' => 'Status',
        ];
    }
}

Usage

Collaboration (Followers)

$project->addFollower($user);
$project->isFollowedBy($user);
$project->removeFollower($user);

Messaging

$message = $project->addMessage([
    'type' => 'note',
    'subject' => 'Kickoff',
    'body' => 'Project started',
]);

$reply = $project->replyToMessage($message, [
    'type' => 'note',
    'subject' => 'Re: Kickoff',
    'body' => 'Acknowledged',
]);

$project->markAsRead();
$project->pinMessage($message);
$project->unpinMessage($message);
$project->removeMessage($message->id);

Attachments

$attachments = $project->addAttachments([
    'uploads/spec.pdf',
    'uploads/mockup.png',
]);

$project->getImageAttachments();
$project->getDocumentAttachments();
$project->removeAttachment($attachments->first()->id);

Custom Storage Disk

Set a global attachment disk in configuration:

// config/model-pulse.php
return [
    'attachments' => [
        'disk' => 's3',
    ],
];

Optional per-model override:

public function getModelPulseAttachmentDisk(): ?string
{
    return 's3';
}

Resolution order:

  • Model override (getModelPulseAttachmentDisk)
  • model-pulse.attachments.disk
  • filesystems.default

Activity Logging

HasLogActivity automatically records model lifecycle activity and stores audit-style entries through the package message model.

You can also trigger logging manually:

$project->logModelActivity('updated');

Events

The package dispatches typed Laravel events after successful messaging/activity operations.

Messaging Events

  • Karim\ModelPulse\Events\MessageCreated
  • Karim\ModelPulse\Events\MessageReplied
  • Karim\ModelPulse\Events\MessageRemoved
  • Karim\ModelPulse\Events\MessagesMarkedRead
  • Karim\ModelPulse\Events\MessagePinned
  • Karim\ModelPulse\Events\MessageUnpinned

Activity Event

  • Karim\ModelPulse\Events\ActivityLogged

Listening to Events

Example listener registration in your EventServiceProvider:

use App\Listeners\HandleMessageCreated;
use Karim\ModelPulse\Events\MessageCreated;

protected $listen = [
    MessageCreated::class => [
        HandleMessageCreated::class,
    ],
];

Notes

  • Events are dispatched only when operations succeed.
  • Failed or no-op operations do not dispatch success events.