›
›
›
  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

Configuration.

Every key in config/assignment.php, its default, and what changing it affects.

php artisan vendor:publish --tag="assignment-config"

config/assignment.php holds infrastructure and wiring: table names, key types, which profile serves which model, and which notifications go out. Selection behaviour belongs on a profile or at the call site.

return [
    'tables' => [
        'assignments' => 'assignments',
        'scopes' => 'assignment_scopes',
        'queue' => 'assignment_queue',
    ],

    'assignable_key_type' => env('ASSIGNMENT_ASSIGNABLE_KEY_TYPE', 'id'),
    'assignee_key_type' => env('ASSIGNMENT_ASSIGNEE_KEY_TYPE', 'id'),

    'profiles' => [],

    'notifications' => [
        'offered' => ByRcsc\LaravelAssignment\Notifications\OfferReceived::class,
        'offer_expired' => ByRcsc\LaravelAssignment\Notifications\OfferExpired::class,
        'assigned' => ByRcsc\LaravelAssignment\Notifications\AssignmentReceived::class,
        'unassigned' => ByRcsc\LaravelAssignment\Notifications\AssignmentRemoved::class,
    ],

    'notification_channels' => ['mail'],

    'dispatch_expiry_jobs' => false,
];

Reference

KeyDefaultPurpose
tables.assignmentsassignmentsThe history table
tables.scopesassignment_scopesRotation state, one row per scope string
tables.queueassignment_queueAssignables waiting for a candidate
assignable_key_typeidColumn type for assignable_id
assignee_key_typeidColumn type for assignee_id
profiles[]Assignable class to profile class
notifications.offeredOfferReceived::classSent when an offer is made
notifications.offer_expiredOfferExpired::classSent when an offer lapses
notifications.assignedAssignmentReceived::classSent when an assignment becomes active
notifications.unassignedAssignmentRemoved::classSent when an assignment is taken away
notification_channels['mail']Channels for all four notifications
dispatch_expiry_jobsfalseQueue a delayed job per expiring cascade offer

tables

Renaming a table changes both the migration and the models, so publish the config before migrating. Changing a name after the fact means renaming the table by hand.

'tables' => [
    'assignments' => 'work_assignments',
    'scopes' => 'work_assignment_scopes',
    'queue' => 'work_assignment_queue',
],

Names are read at runtime, so a model resolves its table from config rather than from a hardcoded string.

Key types

The assignments and assignment_queue tables store polymorphic keys, which means their column type has to match your models.

ASSIGNMENT_ASSIGNABLE_KEY_TYPE=uuid
ASSIGNMENT_ASSIGNEE_KEY_TYPE=ulid
ValueColumn
idUnsigned big integer
uuidUUID
ulidULID
stringString

Any other value throws an InvalidArgumentException when the migration runs.

Two constraints are worth knowing before you design around this:

  • It is one setting per side, not per model. Every assignable shares a key type and every assignee shares another. Mixed key types on the same side need string.
  • The value is read by the migration. Changing it later means altering the column yourself.

profiles

'profiles' => [
    App\Models\Enquiry::class => App\Assignment\EnquiryProfile::class,
    App\Models\Callout::class => App\Assignment\CalloutProfile::class,
],

The key is the assignable class and the value is the profile class name. Profiles are resolved through the container.

Lookup walks the assignable's class and then its parents, so a profile registered against a base class serves subclasses that have none of their own. A model with no match throws NoProfile when autoAssign() is called.

A value that is not a string, or a class that does not extend AssignmentProfile, throws an UnexpectedValueException at resolution time.

notifications

Each key names the class sent at that moment, and null silences it:

'notifications' => [
    'offered' => App\Notifications\CrewOfferReceived::class,
    'offer_expired' => null,
    'assigned' => ByRcsc\LaravelAssignment\Notifications\AssignmentReceived::class,
    'unassigned' => ByRcsc\LaravelAssignment\Notifications\AssignmentRemoved::class,
],

The class is built through the container with the assignment passed as assignment. See notifications.

Notification channels

'notification_channels' => ['mail', 'database'],

Applies to all four notifications. database needs Laravel's notifications table, which is why it is off by default. Override via() on a replacement class when one notification needs different channels from the rest.

Delayed expiry jobs

'dispatch_expiry_jobs' => true,

With this on, creating a cascade offer that has an expires_at also queues a delayed job set to run at that moment, which expires the offer and advances the cascade with second-level precision.

It changes nothing about correctness. An overdue offer stops holding its slot on the timestamp either way. Keep assignment:tick scheduled as the safety net. See expiry and scheduling.

What is not configurable

  • Which events fire. All nine always dispatch.
  • The open-slot rule. It is a database constraint, not a setting.
  • Selection behaviour. Candidates, policy, and scope come from the call site or a profile.
  • Retention. Nothing prunes assignment rows, because they are the history.

What to read next

  • Installation and setup for the publish and migrate order.
  • Profiles for what a registered profile provides.
  • Notifications for swapping and silencing.
PreviousConcurrency guaranteesNextAPI reference
View source

On this page

  1. Reference
  2. tables
  3. Key types
  4. profiles
  5. notifications
  6. Notification channels
  7. Delayed expiry jobs
  8. What is not configurable
  9. What to read next