Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Eloquent Blameable Laravel Package

richan-fongdasen/eloquent-blameable

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Model-Centric Fit: The package extends Eloquent models with blameable behavior (e.g., created_by, updated_by, deleted_by fields), aligning well with Laravel’s ORM-first architecture. It abstracts audit trail logic into reusable traits, reducing boilerplate in CRUD-heavy applications (e.g., SaaS platforms, admin panels).
  • Separation of Concerns: Leverages Laravel’s built-in Auth facade for user resolution, avoiding tight coupling with business logic. Complements packages like spatie/laravel-activitylog for broader observability.
  • Limitation: No built-in support for non-user entities (e.g., services, IPs) or multi-tenancy without customization.

Integration Feasibility

  • Low Friction: Single trait (Blameable) attaches to models; no middleware or service provider changes required. Works with Laravel 10+ (PHP 8.1+).
  • Database Agnostic: Uses Eloquent’s schema builder; compatible with MySQL, PostgreSQL, SQLite.
  • Risk: Potential conflicts with:
    • Custom boot() methods overriding blameable events.
    • Existing observers or model events managing created_at/updated_at.
    • Soft-deletes (SoftDeletes) if deleted_by isn’t pre-defined.

Technical Risk

Risk Mitigation
Auth Resolution Failures Validate auth()->user() exists before model operations; fallback to null.
Performance Overhead Add indexes to *_by columns if queries filter by them.
Version Skew Test with Laravel 11+ early; check for breaking changes in eloquent-blameable v2.0+.
Data Migration Backfill *_by columns via seeder or data migration if adopting mid-project.

Key Questions

  1. Use Case Alignment:
    • Is blame tracking a core feature (e.g., compliance) or nice-to-have (e.g., debugging)?
    • Are there existing audit solutions (e.g., spatie/laravel-medialibrary events) that could conflict?
  2. User Model Assumptions:
    • Does the app use a custom User model? Will blameable resolve correctly?
  3. Scalability:
    • Will *_by columns bloat queries? Plan for read replicas or caching (e.g., blameable in API responses).
  4. Testing:
    • How will blameability be tested? Mock auth() in unit tests; verify deleted_by in soft-delete scenarios.

Integration Approach

Stack Fit

  • Laravel Ecosystem: Native compatibility with Eloquent, Auth, and Events systems. Pairs well with:
    • Auth: laravel/breeze, laravel/jetstream, or custom providers.
    • Observability: spatie/laravel-activitylog (for full audit trails).
    • APIs: laravel/sanctum/passport to expose blame data in responses.
  • Non-Laravel: Not applicable; hard dependency on Eloquent.

Migration Path

  1. Assessment Phase:
    • Audit models needing blame tracking (e.g., Post, UserProfile).
    • Check for existing created_by/updated_by columns (rename if needed).
  2. Implementation:
    • Option A (Greenfield): Add trait to models during initial development.
      use RichanFongdasen\EloquentBlameable\Blameable;
      class Post extends Model { use Blameable; }
      
    • Option B (Brownfield): a. Add columns via migration:
      Schema::table('posts', function (Blueprint $table) {
          $table->foreignId('created_by')->nullable()->constrained('users');
          $table->foreignId('updated_by')->nullable()->constrained('users');
      });
      
      b. Backfill data:
      Post::query()->update(['created_by' => auth()->id()]); // Hypothetical backfill
      
      c. Apply trait to models.
  3. Validation:
    • Test CRUD flows with auth()->shouldUse() to simulate different users.
    • Verify soft deletes populate deleted_by.

Compatibility

  • Laravel Versions: Tested up to Laravel 10; confirm PHP 8.1+ support.
  • Database: No SQL-specific logic; works with any PDO-supported DB.
  • Conflicts:
    • SoftDeletes: Ensure deleted_by column exists before using Blameable.
    • Timestamps: Package respects useTimestamps = false but may need manual created_by/updated_by handling.
    • Caching: Clear cached models if updated_by changes (e.g., Model::refresh()).

Sequencing

  1. Phase 1: Pilot on 1–2 non-critical models (e.g., LogEntry).
  2. Phase 2: Roll out to core models; monitor query performance.
  3. Phase 3: Extend to APIs (e.g., include created_by in responses).
  4. Phase 4: Integrate with activity logs or third-party tools.

Operational Impact

Maintenance

  • Pros:
    • Reduced Boilerplate: No need to manually set auth()->id() on model saves.
    • Centralized Logic: Updates to blame resolution (e.g., switching to service accounts) require one trait change.
  • Cons:
    • Hidden Complexity: Blameability may not be obvious to junior devs reviewing models.
    • Migration Risk: Adding *_by columns to large tables may lock tables during backfills.

Support

  • Debugging:
    • Log blameable failures (e.g., auth()->user() null) in App\Exceptions\Handler.
    • Document edge cases (e.g., "Blame fields are nullable if no user is authenticated").
  • User Stories:
    • Support may need to explain why actions show as "system" (e.g., deleted_by: null) or resolve disputes via logs.

Scaling

  • Performance:
    • Reads: Add indexes to *_by columns if frequently queried:
      Schema::table('posts', function (Blueprint $table) {
          $table->index('created_by');
      });
      
    • Writes: Minimal overhead; blame resolution happens in save().
  • Distributed Systems:
    • In queue workers, ensure auth()->setUser() is called before model operations.
    • For APIs, consider caching blame data (e.g., Redis) if resolved often.

Failure Modes

Failure Impact Mitigation
Auth System Down Blame fields set to null. Fallback to config('app.blame_fallback') or service account.
Database Constraints Foreign key violations on *_by. Use nullable() or default to a "system" user.
Trait Overrides Custom save() breaks blame logic. Extend trait or use protected $blameable = true.
Time Zone Issues updated_at vs. updated_by confusion. Document that blame fields are user-specific, not time-based.

Ramp-Up

  • Onboarding:
    • Developers: Add 5-minute doc on where to apply Blameable and how to test.
    • QA: Include blame checks in test suites (e.g., "Verify Post shows correct created_by").
  • Training:
    • Demo how to:
      • Filter queries by created_by (e.g., Post::where('created_by', auth()->id())).
      • Handle edge cases (e.g., anonymous users, API clients).
  • Metrics:
    • Track adoption rate (models using Blameable).
    • Monitor null values in blame fields to identify auth gaps.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware