PHPackages                             matjeninstudio/laravel-contact-approvable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. matjeninstudio/laravel-contact-approvable

ActiveLibrary

matjeninstudio/laravel-contact-approvable
=========================================

A Laravel package for managing contacts and approval workflows with polymorphic relationships, audit trails, and a Telescope-like admin interface.

10PHPCI passing

Since Oct 31Pushed 6mo agoCompare

[ Source](https://github.com/nuzulfikrie/matjeninstudio-laravel-approvable-contactlist)[ Packagist](https://packagist.org/packages/matjeninstudio/laravel-contact-approvable)[ RSS](/packages/matjeninstudio-laravel-contact-approvable/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)DependenciesVersions (1)Used By (0)

Laravel Contact Approvable
==========================

[](#laravel-contact-approvable)

[![Latest Version on Packagist](https://camo.githubusercontent.com/3f639da004f7064431c72a1d2021b6408b3d049bf469f341bf692259000b9546/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d61746a656e696e73747564696f2f6c61726176656c2d636f6e746163742d617070726f7661626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/matjeninstudio/laravel-contact-approvable)[![GitHub Tests Action Status](https://camo.githubusercontent.com/a41967ba6446da52a068bae0284174e79a6a330e263f8180fef235bbcc743afe/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6e757a756c66696b7269652f6d61746a656e696e73747564696f2d6c61726176656c2d617070726f7661626c652d636f6e746163746c6973742f74657374732e796d6c3f6272616e63683d6d61696e267374796c653d666c61742d737175617265)](https://github.com/nuzulfikrie/matjeninstudio-laravel-approvable-contactlist/actions)[![Total Downloads](https://camo.githubusercontent.com/abf9da2d1916c5b884bb909c2c267a8cbef864f394af6934e45f00e463607d2d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d61746a656e696e73747564696f2f6c61726176656c2d636f6e746163742d617070726f7661626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/matjeninstudio/laravel-contact-approvable)[![License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/nuzulfikrie/matjeninstudio-laravel-approvable-contactlist/blob/main/LICENSE.md)[ ![CodeRabbit Pull Request Reviews](https://camo.githubusercontent.com/433556432d1248235e68e6efe9c3d30872b53cbddcb594fab560a1b38d86da92/68747470733a2f2f696d672e736869656c64732e696f2f636f64657261626269742f7072732f6769746875622f6e757a756c66696b7269652f6d61746a656e696e73747564696f2d6c61726176656c2d617070726f7661626c652d636f6e746163746c6973743f75746d5f736f757263653d6f73732675746d5f6d656469756d3d6769746875622675746d5f63616d706169676e3d6e757a756c66696b7269652532466d61746a656e696e73747564696f2d6c61726176656c2d617070726f7661626c652d636f6e746163746c697374266c6162656c436f6c6f723d31373137313726636f6c6f723d464635373041266c6162656c3d436f64655261626269742b52657669657773)](https://coderabbit.ai)

A powerful Laravel package that brings enterprise-grade approval workflows to your application. Manage contacts, approval requests, and audit trails with polymorphic relationships, real-time notifications, and a beautiful admin interface inspired by Laravel Telescope.

✨ Features
----------

[](#-features)

- 🔄 **Polymorphic Approval Workflows** - Attach approval workflows to any Eloquent model
- 👥 **Contact Management** - Create and manage contacts with user relationships
- 📝 **Approval Records &amp; Audit Trails** - Track every approval decision with comments
- 🔔 **Multi-Channel Notifications** - Email, database, and custom notification channels
- ⚡ **Auto-Approval Support** - Configure threshold-based or percentage-based auto-approvals
- ⏰ **Deadline Management** - Set approval deadlines with automated reminders
- 🎨 **Admin Interface** - Telescope-like UI for monitoring approval workflows
- 🎯 **Event-Driven Architecture** - Comprehensive events for all approval lifecycle stages
- 🔧 **Highly Configurable** - Extensive configuration options for every feature
- 🧪 **Fully Tested** - Comprehensive test coverage with Pest PHP

📋 Requirements
--------------

[](#-requirements)

- PHP 8.4 or higher
- Laravel 12.0 or higher

📦 Installation
--------------

[](#-installation)

Install the package via Composer:

```
composer require matjeninstudio/laravel-contact-approvable
```

Publish the configuration file:

```
php artisan vendor:publish --provider="MatJeninStudio\ContactApprovable\ContactApprovableServiceProvider" --tag="config"
```

Publish and run the migrations:

```
php artisan vendor:publish --provider="MatJeninStudio\ContactApprovable\ContactApprovableServiceProvider" --tag="migrations"
php artisan migrate
```

🚀 Quick Start
-------------

[](#-quick-start)

### 1. Add the Trait to Your Model

[](#1-add-the-trait-to-your-model)

```
use Illuminate\Database\Eloquent\Model;
use MatJeninStudio\ContactApprovable\Traits\Approvable;

class Document extends Model
{
    use Approvable;

    // Your model code...
}
```

### 2. Create a Contact and Request Approval

[](#2-create-a-contact-and-request-approval)

```
// Create a contact with approvers
$contact = $document->createContact(
    name: 'Legal Department',
    users: [$legalUser1, $legalUser2],
    markAsApprover: true
);

// Request approval
$approval = $document->requestApproval($contact);
```

### 3. Approve or Reject

[](#3-approve-or-reject)

```
use MatJeninStudio\ContactApprovable\Models\ApprovalRecord;

// Approve with comment
ApprovalRecord::create([
    'approval_id' => $approval->id,
    'user_id' => $legalUser1->id,
    'is_approved' => true,
    'comment' => 'Document reviewed and approved.',
]);

// Check approval status
$status = $document->getApprovalStatus(); // 'pending', 'approved', or 'rejected'
```

📖 Usage Guide
-------------

[](#-usage-guide)

### Working with Contacts

[](#working-with-contacts)

Contacts are groups of users that can approve requests. Each contact can have multiple users, and users can be designated as approvers.

#### Create a Contact

[](#create-a-contact)

```
// Simple contact creation
$contact = $model->createContact('Finance Team');

// With users and approvers
$contact = $model->createContact(
    name: 'Executive Board',
    users: [$ceo, $cfo, $cto],
    isActive: true,
    markAsApprover: true
);

// With mixed user types
$contact = $model->createContact(
    name: 'HR Department',
    users: [1, 2, $userModel], // User IDs or models
    markAsApprover: true
);
```

#### Manage Contact Users

[](#manage-contact-users)

```
// Attach users to existing contact
$contact = $model->attachUsersToContact($contact, [$user1, $user2], markAsApprover: true);

// Sync users (removes users not in the list)
$contact = $model->syncContactUsers($contact, [$user1, $user3]);

// Detach specific users
$contact = $model->detachUsersFromContact($contact, [$user1]);

// Detach all users
$contact = $model->detachUsersFromContact($contact);

// Update approver status
$contact = $model->updateContactUserApproverStatus($contact, $user1, isApprover: true);
```

### Approval Workflows

[](#approval-workflows)

#### Request Approval

[](#request-approval)

```
// Request approval from a contact
$approval = $document->requestApproval($contact);

// Request with contact ID
$approval = $document->requestApproval(contactId: 1);

// Check for pending approvals (prevents duplicates)
$pendingApproval = $document->hasPendingApproval();
```

#### Process Approvals

[](#process-approvals)

```
use MatJeninStudio\ContactApprovable\Models\ApprovalRecord;

// Approve
ApprovalRecord::create([
    'approval_id' => $approval->id,
    'user_id' => auth()->id(),
    'is_approved' => true,
    'comment' => 'Looks good to me!',
]);

// Reject
ApprovalRecord::create([
    'approval_id' => $approval->id,
    'user_id' => auth()->id(),
    'is_approved' => false,
    'comment' => 'Please revise section 3.',
]);
```

#### Query Approval Status

[](#query-approval-status)

```
// Get latest approval
$latestApproval = $document->latestApproval();

// Get approval status
$status = $document->getApprovalStatus(); // 'pending', 'approved', or 'rejected'

// Check specific states
$isPending = $approval->isPending();
$isApproved = $approval->isApproved();
$isRejected = $approval->isRejected();

// Query scopes
use MatJeninStudio\ContactApprovable\Models\Approval;

$pendingApprovals = Approval::pending()->get();
$approvedApprovals = Approval::approved()->get();
$rejectedApprovals = Approval::rejected()->get();
```

### Events

[](#events)

The package dispatches events for all key actions, allowing you to hook into the approval lifecycle:

```
// Listen to approval events
Event::listen(ApprovalRequestedEvent::class, function ($event) {
    // $event->approval
    Log::info('Approval requested', ['approval_id' => $event->approval->id]);
});

Event::listen(ApprovalApprovedEvent::class, function ($event) {
    // $event->approvalRecord
    // Send custom notification, update related models, etc.
});

Event::listen(ApprovalRejectedEvent::class, function ($event) {
    // $event->approvalRecord
    // Handle rejection logic
});
```

**Available Events:**

- `ApprovalRequestedEvent` - When approval is requested
- `ApprovalApprovedEvent` - When approval is approved
- `ApprovalRejectedEvent` - When approval is rejected
- `ContactCreatedEvent` - When a contact is created
- `ContactUpdatedEvent` - When a contact is updated
- `ContactDeletedEvent` - When a contact is deleted

### Notifications

[](#notifications)

The package includes built-in notifications that can be sent via multiple channels:

```
// Configure in config/contact-approvable.php
'notifications' => [
    'enabled' => true,
    'channels' => ['mail', 'database'],
    'queue' => true,
    'queue_name' => 'default',
],
```

**Built-in Notifications:**

- `ApprovalRequestedNotification` - Sent to approvers when approval is requested
- `ApprovalApprovedNotification` - Sent when approval is approved
- `ApprovalRejectedNotification` - Sent when approval is rejected

### Auto-Approval

[](#auto-approval)

Configure automatic approval based on threshold or percentage:

```
// In config/contact-approvable.php
'auto_approve' => [
    'enabled' => true,

    // Approve after 2 approvals
    'threshold' => 2,

    // OR approve after 50% of approvers approve
    'percentage' => 50, // Set to null to use threshold instead
],
```

### Deadline Management

[](#deadline-management)

Set approval deadlines with automated reminders:

```
'deadline' => [
    'enabled' => true,
    'default_days' => 7,        // Approval expires in 7 days
    'reminder_days' => 2,       // Send reminder 2 days before deadline
],
```

⚙️ Configuration
----------------

[](#️-configuration)

The package is highly configurable. Here are some key configuration options:

```
// config/contact-approvable.php

return [
    // Admin interface route
    'route' => 'contact-approvable',

    // Middleware for admin routes
    'middleware' => ['web', 'auth'],

    // Customize table names
    'table_names' => [
        'contacts' => 'contacts',
        'contact_user' => 'contact_user',
        'approvals' => 'approvals',
        'approval_records' => 'approval_records',
    ],

    // Your User model
    'user_model' => 'App\\Models\\User',

    // Enable/disable specific events
    'events' => [
        'enabled' => true,
        'dispatch' => [
            'approval_requested' => true,
            'approval_approved' => true,
            'approval_rejected' => true,
        ],
    ],

    // Admin interface settings
    'admin' => [
        'per_page' => 15,
        'real_time' => false,
        'brand' => 'Contact Approvable',
    ],
];
```

🔧 Advanced Usage
----------------

[](#-advanced-usage)

### Custom Polymorphic Relationships

[](#custom-polymorphic-relationships)

The approval system works with any Eloquent model:

```
class Invoice extends Model
{
    use Approvable;
}

class PurchaseOrder extends Model
{
    use Approvable;
}

class Contract extends Model
{
    use Approvable;
}

// All can use the same approval workflow
$invoice->requestApproval($financeContact);
$purchaseOrder->requestApproval($procurementContact);
$contract->requestApproval($legalContact);
```

### Relationship Access

[](#relationship-access)

```
// Get all approvals for a model
$approvals = $document->approvals;

// Get approval records through relationship
$approval->records;

// Get the approvable model from approval
$model = $approval->approvable;

// Get contact and users
$contact = $approval->contact;
$users = $contact->users;
$approvers = $contact->approvers; // Only users marked as approvers
```

🧪 Testing
---------

[](#-testing)

The package includes comprehensive tests using Pest PHP:

```
# Run all tests
composer test

# Run with coverage
composer test-coverage

# Run architecture tests
composer test-arch

# Run static analysis
composer analyse

# Format code
composer format

# Run linting (format + analyse)
composer lint
```

📚 Use Cases
-----------

[](#-use-cases)

This package is perfect for:

- **Document Approval Systems** - Route documents through approval chains
- **Purchase Order Management** - Multi-level approval for procurement
- **Contract Review Workflows** - Legal and executive approvals
- **Time-off Requests** - HR approval workflows
- **Expense Approvals** - Finance department sign-offs
- **Content Publishing** - Editorial approval pipelines
- **Change Request Management** - IT change approval boards
- **Quality Assurance** - QA sign-off processes

🤝 Contributing
--------------

[](#-contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

🔐 Security
----------

[](#-security)

If you discover any security-related issues, please email  instead of using the issue tracker.

📝 License
---------

[](#-license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

👨‍💻 Credits
-----------

[](#‍-credits)

- [Nuzul Fikrie](https://github.com/nuzulfikrie)
- [All Contributors](../../contributors)

🙏 Acknowledgments
-----------------

[](#-acknowledgments)

- Inspired by Laravel Telescope's elegant UI design
- Built with [Spatie's Laravel Package Tools](https://github.com/spatie/laravel-package-tools)
- Tested with [Pest PHP](https://pestphp.com/)

---

Made with ❤️ by [MatJenin Studio](https://github.com/nuzulfikrie)

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance47

Moderate activity, may be stable

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity13

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/102560da8bddbbbbfae7c42321ff99fda6048c35f13e5ac5115f65453220531c?d=identicon)[nuzul.fikrie](/maintainers/nuzul.fikrie)

---

Top Contributors

[![nuzulfikrie](https://avatars.githubusercontent.com/u/5245744?v=4)](https://github.com/nuzulfikrie "nuzulfikrie (31 commits)")

### Embed Badge

![Health badge](/badges/matjeninstudio-laravel-contact-approvable/health.svg)

```
[![Health](https://phpackages.com/badges/matjeninstudio-laravel-contact-approvable/health.svg)](https://phpackages.com/packages/matjeninstudio-laravel-contact-approvable)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
