keshavmansure/laravel-chronicle

Lightweight Laravel package that automatically tracks Eloquent model changes.

Maintainers

Package info

github.com/keshavmansure/laravel-chronicle

pkg:composer/keshavmansure/laravel-chronicle

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-07-31 19:30 UTC

This package is auto-updated.

Last update: 2026-07-31 19:36:52 UTC


README

Lightweight Eloquent change tracker for Laravel.

Add one trait to a model — creates, updates, and deletes are recorded automatically with before/after snapshots, optional request metadata, and almost zero configuration.

Package: keshavmansure/laravel-chronicle

Requirements

  • PHP 8.2+
  • Laravel 11 or 12

Installation

composer require keshavmansure/laravel-chronicle

Publish the config (optional):

php artisan vendor:publish --tag=chronicle-config

Publish the migration (optional — migrations also auto-load):

php artisan vendor:publish --tag=chronicle-migrations

Or publish both:

php artisan vendor:publish --tag=chronicle

Run migrations:

php artisan migrate

If you publish the migration and leave package auto-loading enabled, keep only one copy so the table is not created twice.

Quick start

use KeshavMansure\Chronicle\Traits\HasChronicle;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasChronicle;
}

That's it.

$post = Post::create(['title' => 'Hello', 'body' => 'World']);
$post->update(['title' => 'Updated']);
$post->delete();

Reading history

use KeshavMansure\Chronicle\Models\ChronicleEntry;

ChronicleEntry::query()
    ->where('model_type', Post::class)
    ->where('model_id', $post->id)
    ->latest()
    ->get();

// Via the model relationship
$post->chronicleEntries;

Excluding attributes

Globalconfig/chronicle.php:

'exclude' => [
    'password',
    'remember_token',
],

Per model — merged with the global list:

class User extends Model
{
    use HasChronicle;

    protected array $chronicleExclude = [
        'api_token',
        'two_factor_secret',
    ];
}

Per-model overrides

class User extends Model
{
    use HasChronicle;

    protected array $chronicleEvents = ['created', 'updated'];

    protected array $chronicleExclude = ['api_token'];

    protected array $chronicleOnly = ['name', 'email'];

    protected string $chronicleSnapshot = 'changes'; // or "full"
}
Property Purpose
$chronicleEvents Which events to track on this model
$chronicleExclude Extra attributes to omit (merged with config)
$chronicleOnly If set, only these attributes are stored
$chronicleSnapshot full or changes

Configuration

Publish to config/chronicle.php. Only enabled reads from the environment (CHRONICLE_ENABLED); everything else is config-only.

Option Default Description
enabled true (CHRONICLE_ENABLED) Globally enable/disable tracking
connection null DB connection (app default if null)
table chronicle_entries Table name
snapshot full full or changes
events created, updated, deleted Events to track
exclude password, remember_token Attributes never stored
only [] When set, only these attributes are stored
metadata.user_id true Store authenticated user ID
metadata.ip true Store request IP
metadata.user_agent true Store user agent
pretty_print false Pretty-print JSON snapshots

What gets stored

Column Description
model_type Eloquent morph class
model_id Model primary key
event created, updated, or deleted
before JSON snapshot before the change
after JSON snapshot after the change
user_id Authenticated user (if available)
ip_address Request IP (if available)
user_agent User agent (if available)
created_at / updated_at Timestamps

Extensibility

Recording goes through the ChronicleRecorder contract. Bind your own implementation to swap storage or queue writes later without changing the public API:

$this->app->singleton(
    \KeshavMansure\Chronicle\Contracts\ChronicleRecorder::class,
    \App\Chronicle\QueuedChronicleRecorder::class,
);

Testing

composer install
composer test

CI runs on PHP 8.2 / 8.3 against Laravel 11 and 12 (SQLite in-memory).

If your local PHP has no pdo_sqlite:

cp .env.testing.example .env.testing
# set DB_* and create the database, then:
composer test

Or install SQLite: sudo apt install php8.2-sqlite3

Roadmap

Not in the current version:

  • Rollback support
  • Diff viewer / dashboard UI
  • Soft delete & restore tracking
  • Queue support
  • Multi-tenant support
  • Custom metadata providers

License

MIT © Keshav Mansure