byrcsc/laravel-approval
byrcsc/laravel-approval is a Laravel package for adding approval workflows to your application. Attach approvals to Eloquent models, manage pending and approved states, and keep approval logic organized within your existing Laravel app.
config/approval.php first. It is the control surface for workflows, resolvers, notification events, SLA strategies, and guard mode.approval-translations and approval-views. They are intentionally separate so you can customize copy and mail templates independently.workbench/README.md is the fastest way to see every integration seam in a bootable Laravel app. Treat it as reference, not production runtime; it is excluded from the dist archive.Approvable trait to one model, define a simple workflow with one or two stages, bind an approver resolver (start with StaticUsersResolver or CallbackResolver), run approval:sync, submit a record, and approve/reject it through the request model and policy. This exercises schema, workflow snapshotting, approver resolution, authorization, and audit in one pass.ApprovalRequestPolicy, ApproverResolver, StageCondition, and WorkflowCondition. Those are the main extension points you will reach for as the workflow grows beyond a demo.approval:sync. Define workflows as arrays or fluent builders, commit them, and use approval:sync for idempotent reconciliation. Run dry-run mode in CI or before deployment. In-flight requests keep their snapshots, so workflow edits do not rewrite live approvals.approvable_type, use container-resolved WorkflowCondition classes to select candidates for a given submission, and use priority to order the remainder. Use Approval::workflows() and Approval::workflowsFor() to drive a workflow picker. Avoid ambiguous candidates; the package refuses equally specific workflows rather than guessing.ApproverResolver for dynamic org data, or use StaticUsersResolver / CallbackResolver for simpler cases. Stage conditions are container-resolved StageCondition classes evaluated once at submission and snapshotted as visible skipped stages.ApprovalRequestPolicy covers approve, reject, return, cancel, delegate, and view. It is backed by the same checks as the engine, so UI and engine stay aligned.conflicted state explicitly. Use withoutApprovalGuard() only as a re-entrant, record-scoped, audited escape hatch; the final stale check remains the backstop for writes outside model events.approval:escalate idempotently and use approval:doctor for stranded-stage detection. Use approval:status for operational visibility and approval:verify for global or request-scoped audit-chain verification.ApprovalNotification::mailFor() so replacement notifications follow the same path. Keep translations and views aligned with application locale and record-name placeholders.Approval::fake() and exported factories for host tests. Fake records every public mutation with matching assertions and avoids approval-state writes. Use real database integration tests where transactions, row locks, and per-request behavior matter.approval:verify.priority and conditions carefully, and test Approval::workflowsFor() with real records.approval:sync before deploying workflow changes. It is the cheapest way to catch destructive drift and accidental stage removals before they hit a live environment.approval:escalate is safe to rerun, but stranded stages only surface if the command runs often enough and your bounded scans cover the relevant population. Use approval:doctor when stages look stuck.How can I help you explore Laravel packages today?