Add audit trail for lock lifecycle events#79
Closed
bashgeek wants to merge 26 commits into
Closed
Conversation
…-lock - Replace all Kenepa/kenepa references with Blendbyte/blendbyte - Rename PHP namespace from Blendbyte\ResourceLock to Blendbyte\FilamentResourceLock - Rename composer package to blendbyte/filament-resource-lock - Rename config file to filament-resource-lock.php - Update artisan command signatures to filament-resource-lock:* - Simplify and clean up README, remove upgrade guides and version table
- Bump filament/filament to ^5.0, illuminate/contracts to ^11.28|^12.0|^13.0 - Bump nunomaduro/larastan to ^3.0, orchestra/testbench to ^9.0|^10.0|^11.0 - Bump pestphp/pest to ^3.7 and related plugins, tightenco/duster to ^3.1 - Drop spatie/laravel-ray and composer/package-versions-deprecated - Replace $this->listeners boot methods with #[On] attributes for Livewire 4 - Remove BladeCaptureDirectiveServiceProvider dropped by Filament 5 - Clean up phpunit.xml.dist for PHPUnit 11 (removed deprecated attributes)
No custom CSS or JS to compile — the plugin uses only inline styles/scripts and Filament's own components. Filament 5 handles its own Tailwind compilation.
…into rename-kenepa-to-blendbyte
- Fix doubled command name in ResourceLockCommandTest - Replace Pest\Livewire\livewire() with Livewire::test() for Livewire 4 - Drop pestphp/pest-plugin-livewire (requires Livewire 3) - Migrate phpunit.xml.dist to current PHPUnit schema - Remove dead CHANGELOG.md link from README
…4 event dispatch
- Fix ?object property types for userModel and resourceLockModel (should be ?string) - Guard Gate::allows() calls against null gate in LockResource and ResourceLockObserver - Fix duplicate updated_at column key in LockResource table; use virtual lock_status column for Expired badge
…ervice provider Move Livewire::component() registration from the Filament plugin's boot() to ResourceLockServiceProvider::packageBooted() so the component alias is always registered, including during Livewire AJAX requests where the panel may not boot.
…registration Registers the filament-resource-lock-observer component via callAfterResolving in packageRegistered() in addition to packageBooted(). This ensures the component is always registered even if the boot chain fails to complete, fixing the intermittent ComponentNotFoundException on Livewire AJAX update requests.
- Add phpstan.neon.dist (level 5, src/ scope) and phpstan-baseline.neon for unfixable library-pattern errors (unused public API traits, vendor view-string) - Add phpstan CI job to GitHub Actions workflow with 512M memory limit - Fix getNavigationBadge() return type (cast int to string) - Replace deprecated Filament actions()/bulkActions() with recordActions()/toolbarActions() - Add @Property annotation for $updated_at on ResourceLock model
Fixes ordered_imports, concat_space, not_operator_with_successor_space, fully_qualified_strict_types, no_unused_imports, and whitespace issues across src/, tests/, config/, and database/factories/.
- actions/checkout v4 → v6 - ramsey/composer-install v3 → v4 - PHP matrix: 8.2, 8.3, 8.4, 8.5 (was single 8.2) - PHPStan runs on PHP 8.5 with progress output enabled
- Add fork note and migration guide to README (kenepa/resource-lock → blendbyte/filament-resource-lock) - Add Packagist, Tests, Static Analysis, and License badges - Extract PHPStan job from tests.yml into dedicated static-analysis.yml workflow
Dispatches ResourceLocked, ResourceUnlocked, ResourceLockExpired, and ResourceLockForceUnlocked events from all lock/unlock surfaces including the HasLocks model trait, Lock Manager table actions, and the Unlock All header action. Events are opt-out via config (events.enabled) and a new ResourceLockPlugin::enableEvents() fluent method. Also cleans up orphaned expired lock records when a new lock overwrites them in HasLocks::lock(), and adds @Property int|string $user_id to the ResourceLock model for PHPStan correctness.
Add first-class Laravel event dispatching for lock lifecycle transitions
Introduces a resource_lock_audit table that records every lock event (locked, unlocked, expired, force_unlocked) via event listeners, plus a read-only Filament resource to browse the log. Opt-in via audit.enabled.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
resource_lock_audittable that records every lock lifecycle event(
locked,unlocked,expired,force_unlocked) with action, lockable morph,lock owner, actor (for force-unlocks), and timestamp
AuditResourceLockEventSubscriberlistens to all 4 events and writes a row per event
audit.enabled = false— users enable it explicitly in configor via
->enableAudit()on the pluginAuditResourcewith colour-coded action badges, filtersby action type and date range, sorted newest-first; nav entry is hidden until
audit.enabled = trueconfig or plugin fluent API, consistent with the lock manager
Test plan
composer test)vendor/bin/phpstan analyse --memory-limit=512M)audit.enabled = trueand events fireaudit.enabled = false(default)events.enabled = falseaudit.enabled = false, visible whentrue