NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Request

RoundlyConsulting\Requests\Models\Request is the claim or application. It has a polymorphic author, a Status enum, free-form meta, a require_approvals_from record of the declared approvers’ keys and an optional expires_at. It is soft-deletable:

$request->status;                  // Status enum — New, Approved, Rejected, Cancelled, Expired
$request->author;                  // polymorphic author (MorphTo), nullable
$request->type;                    // e.g. 'Claim'
$request->title;                   // e.g. 'Expense reimbursement'
$request->description;
$request->meta;                    // Collection — free-form metadata
$request->require_approvals_from;  // Collection — the declared approvers’ keys
$request->expires_at;              // ?Carbon — the expiry deadline

$request->delete();                // soft delete (deleted_at)

Status

RoundlyConsulting\Requests\Enums\Status is a string-backed enum with five cases. It carries isOpen(), isTerminal() and canTransitionTo(), plus the shared enum helpers from enums-for-laravel (see Status & transitions):

use RoundlyConsulting\Requests\Enums\Status;

Status::New;        // open — awaiting a decision
Status::Approved;
Status::Rejected;
Status::Cancelled;
Status::Expired;

The approval engine

A Request is an approvals subject — it uses the engine’s RequiresApproval trait. Declaring approvers (or stages, or a workflow preset) opens an approval round — an ApprovalRequest in the engine — that names those approvers: only they, or someone they delegated to, may decide it. Its rule decides when the bar is met. A listener, SyncRequestStatusFromApproval, mirrors every engine resolution back onto the request’s Status, so the outcome moves the request and fires the requests events no matter how the decision arrived.

Database schema

The requests table the published migration creates:

ColumnTypeNotes
statusstring(16)Default New.
author_type / author_idmorph, nullableThe author; the id column follows key_type.
typestring, nullableYour own classifier, e.g. Claim or AccessRequest.
titlestring, nullableShort headline.
descriptiontext, nullableLong-form body.
metajson, nullableFree-form metadata, cast to a Collection.
require_approvals_fromjson, nullableA record of the declared approvers’ keys, cast to a Collection.
expires_attimestamp, nullable, indexedThe expiry deadline.
created_at / updated_at / deleted_attimestampsRequests are soft-deletable.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.