›
›
›
  1. docs
  2. ›
  3. byrcsc/laravel-assignment
1.x
Browse documentationOpenClose

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Assignments and slots
  • Assigning and offering
  • Selection policies
  • Scopes and rotation
  • Profiles
  • The queue
  • Offer cascades

Operations

  • Expiry and scheduling
  • Reading assignments
  • Notifications
  • Events and listeners
  • Concurrency guarantees

Reference

  • Configuration
  • API reference
  • Console commands
  • Exceptions
  • Testing
  • Troubleshooting

Getting started

  • Introduction
  • Installation and setup
  • Quick start

Core concepts

  • Assignments and slots
  • Assigning and offering
  • Selection policies
  • Scopes and rotation
  • Profiles
  • The queue
  • Offer cascades

Operations

  • Expiry and scheduling
  • Reading assignments
  • Notifications
  • Events and listeners
  • Concurrency guarantees

Reference

  • Configuration
  • API reference
  • Console commands
  • Exceptions
  • Testing
  • Troubleshooting

byrcsc/laravel-assignment · 1.x

Introduction.

Laravel Assignment routes work to people and teams, and records who held what.

An enquiry needs a tradie. A callout needs a crew. A lead needs a sales agent. A ticket needs whoever is on shift. Two requests arrive at once and both pick the same person, so one of them overwrites the other without an error. Nobody can answer who held the record last week, because the second write also replaced the only column that recorded the answer.

Laravel Assignment gives you the slot and the history. Any Eloquent model can be assigned, and any Eloquent model can take assignments. A database constraint, not an application check, allows at most one open assignment per slot.

$enquiry->assign($tradie);          // active immediately
$enquiry->assignee();               // the Tradie, or null
$enquiry->reassign($otherTradie);   // ends the old row, opens the new one
$enquiry->assignments;              // every row, oldest first

Your application keeps ownership of its users, its teams, its eligibility rules, and whatever being assigned actually means.

RequirementSupported versions
PHP8.3, 8.4
Laravel12.x, 13.x
DatabasesMySQL, PostgreSQL, SQLite

The package follows semantic versioning, so upgrading within 1.x is safe. Source and issues live on GitHub.

Assignables, assignees, and assignments

An assignable is anything that gets assigned: an enquiry, an order, a ticket, a callout. Add the Assignable trait to that model.

An assignee is anything that takes an assignment: a user, a crew, a team. Add the Assignee trait to that model.

A role is an optional label that lets one assignable hold more than one assignee at a time. A callout can hold a crew and a tradie at once, because each role is its own slot. Leave the role off and an assignable has one slot.

What is included

  • assign(), which writes an active assignment, and offer(), which writes one that the assignee has to accept or decline.
  • One open assignment per assignable and role, enforced by a unique index, so two concurrent callers cannot both fill the same slot.
  • The RoundRobin, LeastWorkload, Random, and FirstAvailable selection policies, plus any closure, behind one SelectionPolicy contract.
  • Rotation state per scope. The package locks the scope row during selection, so round robin cursors do not skip or repeat a turn under concurrency.
  • Profiles: one class per assignable model, holding the candidates, the policy, the scope, and the mode, so assignment can run with no arguments.
  • A priority queue for assignables that nobody can take yet. The queue flushes by priority, then first in, first out.
  • Offer cascades that pass a declined or expired offer to the next candidate and stop when the candidates run out.
  • Expiry decided by the timestamp, so an overdue offer stops holding its slot whether or not a scheduled command has run.
  • Events for every transition, and assignee notifications that you can swap or remove in config.

What it does not do

The package leaves the following out by design. None of it is planned work.

  • Deciding who is eligible. The engine never asks whether a candidate belongs in the pool. You pass the candidates, and passing an ineligible model produces an assignment rather than an error. Territory, skill, shift, and capacity are queries on data your application already owns. See selection policies.
  • Screens. No Blade views beyond the notification mail, no Livewire, no Nova resources.
  • Database-defined pools or rules. Candidate lists and admin-editable routing rules belong to your application.
  • Authorization. assign() and offer() are ordinary method calls with no policy behind them.
  • Approval of assignments. Pair the package with byrcsc/laravel-approval and drive it from the events.
  • SLA or escalation timers beyond the offer TTL.
  • Notifying anyone but the assignee. Managers, watchers, and dashboards listen to events.

Design boundaries

These design decisions shape the rest of the package.

The open-slot rule is a database constraint. An internal slot column holds the role while a row is open and null once it ends, under a unique index on the assignable and that column. The loser of a race gets an exception, never a duplicate. A check in PHP could not stop two concurrent requests from both writing an open row.

The package ends assignments and never deletes them. An ended row records ended_at and an ended_reason of unassigned, reassigned, declined, expired, or completed. The rows are the history, and there is no separate audit table.

Timestamps decide expiry. An offer whose expires_at has passed stops holding its slot immediately. assignment:tick advances cascades and flushes the queue. Reads are correct whether or not the command has run.

Eligibility and selection are separate jobs. Your application answers who can take the work. The engine answers who gets it, among the candidates you passed, fairly and atomically.

What to read next

  • Installation and setup to create the tables and add the traits.
  • Quick start to assign an enquiry to a tradie end to end.
  • Assignments and slots for what a slot is and when it is occupied.
NextInstallation and setup
View source

On this page

  1. Assignables, assignees, and assignments
  2. What is included
  3. What it does not do
  4. Design boundaries
  5. What to read next