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

Approval Laravel Package

cjmellor/approval

Laravel package to stage new model changes for review before they’re persisted. Add approvals to your workflow, store pending records in the database, and promote them once approved. Supports PHP 8.3+ and Laravel 12.4+/13.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Polymorphic Approval System: The package leverages Laravel’s polymorphic relationships to support approval workflows across multiple models, aligning well with domain-driven design (DDD) patterns where entities require validation before persistence.
  • Event-Driven Design: Built-in events (ApprovalCreated, ModelApproved, etc.) enable seamless integration with Laravel’s event system, allowing for side effects (e.g., notifications, auditing) without coupling logic to the approval process.
  • State Management: Uses an ApprovalStatus enum for state transitions (pending, approved, rejected, custom states), which is clean and extensible. The #[Scope] attribute (Laravel 12.4+) improves query readability and maintainability.
  • Flexible Data Handling: Stores new_data/original_data as JSON, preserving schema flexibility while enabling rollbacks and diffing. The approvalAttributes property allows granular control over which fields require approval.

Integration Feasibility

  • Laravel 12/13 Focus: Requires PHP 8.3+ and Laravel 12.4+/13, which may necessitate a minor upgrade for teams on older versions (though Laravel 11 support is dropped in v2.1).
  • Database Schema: Introduces a new approvals table with polymorphic relationships (approvalable_type, approvalable_id). Migration is straightforward but requires schema changes (backward-incompatible in v2.x).
  • Model-Level Integration: Minimal boilerplate—just add the MustBeApproved trait to models. Customization (e.g., foreign keys, approval attributes) is explicit and well-documented.
  • API Compatibility: Provides fluent methods (approve(), reject(), rollback()) and query scopes (pending(), approved()), reducing friction for existing Laravel patterns.

Technical Risk

  • Schema Migration: Upgrading from v1.x or integrating into an existing app requires careful sequencing (see UPGRADE.md). Risks include:
    • Data loss if migrations fail mid-execution.
    • Conflicts with existing polymorphic relationships (e.g., if approvalable_type/id collide with other tables).
  • Performance: JSON storage for new_data/original_data is efficient for small models but could bloat storage for large payloads (e.g., nested relationships). Consider indexing state, approvalable_id, and creator_id for query performance.
  • State Management Complexity: Custom states and expiration logic add layers of abstraction. Misconfiguration (e.g., infinite loops in thenCustom() handlers) could lead to edge cases.
  • Rollback Behavior: Default rollback(bypass: true) skips re-approval, which may not align with all workflows (e.g., requiring manual re-review). Requires explicit opt-in for re-approval.

Key Questions

  1. Workflow Alignment:

    • Does the package’s state machine (pendingapproved/rejected) match your business workflow? For example, do you need intermediate states like in_review or needs_revision?
    • How will expired approvals (thenReject, thenPostpone) interact with your SLA requirements?
  2. Data Sensitivity:

    • Are there fields in new_data/original_data that should be redacted or encrypted (e.g., PII)? The package doesn’t handle this natively.
    • How will you handle binary data (e.g., file uploads) in the JSON payload?
  3. Concurrency:

    • What happens if two users trigger a rollback or approve simultaneously? The package lacks explicit locking mechanisms.
    • How will you handle approvals for models with optimistic locking ($version)?
  4. Auditability:

    • The audited_by field tracks state changes, but does your compliance require a full audit log (e.g., who viewed/edited approvals)? Consider pairing with Laravel’s audit packages.
    • How will you reconcile approvals with soft-deleted models (e.g., if a Post is deleted while pending)?
  5. Testing:

    • Have you accounted for edge cases like:
      • Approvals for models with incrementing IDs disabled?
      • Custom fillable/guarded rules conflicting with approvalAttributes?
      • Timezone handling for expires_at/actioned_at?
  6. Scaling:

    • The approvals table could grow large. Will you partition it by approvalable_type or use archiving?
    • How will you handle high-volume approvals (e.g., 10K+ pending items)? The process-expired command runs every minute—is this frequency sufficient?

Integration Approach

Stack Fit

  • Laravel Ecosystem: Perfect fit for Laravel apps using Eloquent, Events, and Scheduling. Complements packages like:
    • Spatie/Laravel-Permission: For role-based approval gates.
    • Laravel Nova/Vue: For UI approval dashboards.
    • OracleID/Laravel-Audit: For immutable audit trails.
  • PHP 8.3+ Features: Leverages enums, attributes (#[Scope]), and typed properties, reducing runtime overhead.
  • Database: Works with MySQL, PostgreSQL, SQLite (via JSON support). Avoids ORM-specific quirks (e.g., no raw SQL assumptions).

Migration Path

  1. Assessment Phase:
    • Audit existing models to identify candidates for approval (e.g., Post, UserProfile, FinancialTransaction).
    • Review current validation logic to ensure it doesn’t conflict with the package’s MustBeApproved trait.
  2. Dependency Upgrade (if needed):
    • Upgrade Laravel to 12.4+ (or 13) and PHP to 8.3+.
    • Test the package in a staging environment with a subset of models.
  3. Schema Migration:
    • Run php artisan vendor:publish --tag="approval-migrations" and php artisan migrate.
    • For existing databases, write a data migration to backfill approvals for historical records (if required).
  4. Model Integration:
    • Add MustBeApproved to target models, starting with low-risk ones (e.g., non-critical content).
    • Customize foreign keys (getApprovalForeignKeyName()) and approval attributes ($approvalAttributes) as needed.
  5. Workflow Implementation:
    • Build approval UI (e.g., Nova tool, custom Blade views) using the Approval model’s query scopes.
    • Implement event listeners for ModelApproved, ModelRejected, etc., to trigger downstream actions (e.g., notifications, webhooks).
  6. Expiration Handling:
    • Register the approval:process-expired command in your scheduler (everyMinute() or less frequent if SLAs permit).
    • Test expiration logic with time-sensitive approvals (e.g., time-limited promotions).

Compatibility

  • Backward Compatibility: v2.x drops Laravel 11 support but maintains API consistency for v2.0 users. Custom states and scopes are backward-compatible with default states.
  • Conflict Risks:
    • Polymorphic Conflicts: Ensure approvalable_type/id doesn’t clash with existing polymorphic tables (e.g., taggable).
    • Observer/Event Conflicts: If models use saving/saved observers, ensure they don’t interfere with the package’s MustBeApproved logic.
    • Caching: The package doesn’t cache approval states. If using Laravel Cache, ensure cache keys don’t invalidate approval data prematurely.
  • Testing Compatibility: The package includes Pest tests. Add integration tests for:
    • Approval state transitions.
    • Rollback scenarios.
    • Expiration edge cases (e.g., expires_at in the past).

Sequencing

  1. Phase 1: Core Integration
    • Install the package and publish migrations/config.
    • Integrate with 1–2 non-critical models (e.g., blog posts).
    • Implement basic approval/rejection logic (manual or automated).
  2. Phase 2: Workflow Enhancement
    • Add custom states (e.g., in_review) via config/approval.php.
    • Implement expiration logic for time-sensitive approvals.
    • Build UI for approval management.
  3. Phase 3: Scaling & Optimization
    • Add indexes to approvals table for performance-critical queries.
    • Implement archiving for old approvals.
    • Extend with custom event listeners (e.g., Slack notifications on rejection).
  4. Phase 4: Monitoring
    • Log approval-related events (e.g., ModelApproved) to a monitoring tool.
    • Set up alerts for stalled approvals (e.g., pending > 48 hours).

Operational Impact

Maintenance

  • Package Updates: The package is actively maintained (last release: 2026-05-04). Follow the CHANGELOG for breaking changes (e.g., Laravel 11 drop in v2.1).
  • Customization Overhead:
    • Low: Core functionality requires minimal code changes (just the trait).
    • Medium: Custom states, expiration logic,
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope