Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Record Lock Laravel Package

asignua/filament-record-lock

Filament Record Lock adds optimistic record locking to Filament resources, preventing users from editing the same record simultaneously. It locks rows on edit, shows who's editing, and releases locks automatically, reducing conflicting saves in multi-user admin panels.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install the package with Composer, publish its config/migration, and run migrations. The lock table and connection are configurable, so decide early whether locks live on the default DB or a dedicated connection.
  • Add the HasLocks trait to every model that should participate in pessimistic locking.
  • On Filament 5 Edit pages, add UsesResourceLock to the page class. For modal edits, use UsesSimpleResourceLock instead.
  • Schedule record-lock:prune in the app scheduler. This is the safety net for abandoned locks when navigator.sendBeacon release-on-leave does not fire.
  • First use case: two admins open the same record. The first editor holds the lock; the second sees a blocking notice with “Back to list”, “View read-only”, and, when authorized, “Unlock and edit”. A save from a page that no longer holds the lock is refused.
  • Where to look first: the README migration section if coming from kenepa/resource-lock, then the package config for table/connection/heartbeat settings, then the HasLocks model trait and the Edit-page trait.

Implementation Patterns

  • Standard resource editing: add UsesResourceLock to the Edit page. The package handles heartbeat renewal, lock release on leave, stale-page detection, and lock-guarded Edit-page actions.
  • Modal editing: use UsesSimpleResourceLock on the modal edit page/component. This gives the same lock lifecycle without the full-page resource behavior.
  • Table visibility: add RecordLockColumn to resource tables so support/admin users can see who currently holds a record lock.
  • Manual release: use ReleaseLockAction for a single record and ReleaseLocksBulkAction for bulk cleanup from a table or admin workflow.
  • Audit/manager view: expose the read-only “Record locks” manager page for support teams. It is intentionally read-only; use the actions for changes.
  • Takeover flow: wire “Unlock and edit” behind your authorization gate. The package exposes an atomic takeOver() path and fires RecordLockTakenOver, which is the right hook for notifications, audit logs, or Slack alerts.
  • Events: listen for RecordLockTakenOver to record who took over a lock and why, especially in regulated or multi-tenant apps.
  • Key types: integer, UUID, and ULID keys are supported. This matters if you mix models with different key strategies in the same lock table.
  • Tenant panels: if the “Record locks” manager is used on a tenant panel, implement scopeManagerQuery() on the panel/resource. Without it, the manager is closed on tenant panels.
  • Migration from kenepa/resource-lock: the package is API-compatible “where it makes sense.” Read the migration section before swapping traits/config, and verify table name, connection, and any custom actions.

Example shape:

use HasLocks;

class Invoice extends Model
{
    use HasLocks;
}
use UsesResourceLock;

class EditInvoice extends EditRecord
{
    use UsesResourceLock;
}

For modal edits:

use UsesSimpleResourceLock;

class EditInvoiceModal extends EditRecord
{
    use UsesSimpleResourceLock;
}

Gotchas and Tips

  • Heartbeat rows can be re-created. The heartbeat re-creates lock rows with the page token. Do not assume a lock row continuously exists for the lifetime of the page; rely on the page token/lock state instead.
  • Release-on-leave is best-effort. navigator.sendBeacon will not fire on crashes, hard network failures, or some browser terminations. Always run record-lock:prune on a schedule.
  • Do not mutate lock state client-side. Lock state is #[Locked]; treat it as server-owned. Custom UI that tries to flip lock state manually will not work as expected.
  • Saves can be refused. That is the feature, not a bug. Surface the blocking notice clearly and avoid swallowing the refusal into a generic validation error.
  • Stale records are detected. If the lock lapsed and the record changed in the meantime, the package detects it. Build a user-facing conflict path rather than assuming the last writer wins.
  • Custom Edit-page actions need thought. Built-in Edit-page actions are lock-guarded. If you add custom actions that write to the record, guard them with the same lock state or authorization assumptions.
  • Tenant manager closure is deliberate. If the manager does not appear on a tenant panel, check whether scopeManagerQuery() is implemented. That is the extension point.
  • Unknown morph types do not crash the manager. They may be skipped or handled defensively; if you use custom morph maps, test the manager view.
  • Separate connection caveat. If you configure a dedicated lock connection, make sure migrations, prune scheduling, and tenant scoping all use that same connection.
  • PostgreSQL string-key eager loading and MySQL renewal behavior are fixed in this release. If you maintain custom forks or extensions around renewal/loading, re-test against v1.0.0.
  • API compatibility is not identity. kenepa/resource-lock compatibility is intentional but scoped. Check the migration section for differences in config keys, trait names, and manager behavior before assuming a drop-in replacement.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style