indexnowkit/history
A Laravel package for adding audit-style history to Eloquent models. Track creates, updates, and deletes, persist snapshots or changed fields, and review a clear timeline of record activity with simple, framework-friendly APIs. Ideal for lightweight auditing and accountability without a heavyweight...
indexnowkit/laravel at ^0.4 (it pulls indexnowkit/core ^0.13); ensure ext-mbstring is installed because RecordCodec now truncates error text with mb_substr().config/indexnow.php after publishing). Check the host/key settings, the debounce store, and the history/PDO table setting before writing any submission code.php artisan indexnow:status first. As of 0.4.0 this command is supplied by the package as a Symfony console class over Console\StatusRunner, and it prints the debounce store exactly as the core describes it (memory, none, <id> (<ShortClass>), or <id> (missing)) plus queue facts. This is the quickest way to verify the installation.php artisan indexnow:history to inspect recorded submissions. HistoryCommand::DEFAULT_LIMIT is 50, and --limit values that are not numeric fall back to that default.indexnow:status and indexnow:history --limit=10 to confirm the submission path and store are working.indexnow:status in deploy/health-check scripts to assert the expected debounce backend and queue configuration. Treat an <id> (missing) store description as an environment/config failure, not as an empty cache.indexnow:history --limit=N for audit/debugging workflows and deploy verification. If you pass the limit dynamically, validate it yourself—the command silently uses 50 for non-numeric input.History\Adapter\HistoryServices::historyRunner() / statusRunner() and their *For() twins. This keeps the debounce-store description and queue facts identical to the package commands.HistoryServices::describeStore($store, $default, $lookup) rather than reimplementing the formatting. The lookup closure resolves a shared cache id to an object/class label; the method handles memory, none, missing ids, and throwing lookups consistently.Pdo\Schema::table($table) before interpolating the history table name into SQL. It returns the table name after the identifier check—the form that reaches the SQL—and assertTable() still delegates to it. This is the sanctioned boundary for history.pdo.table; keep the checked value rather than the raw config value.Adapter\OptionalPackage::history() directly (name, marker, feature word). HistoryServices::package() now delegates to it; new code should not depend on the old entry point.Console\HistoryCommand and Console\StatusCommand from this package instead of copying them. If the package is absent, register Console\Command\HistoryNotInstalledCommand / StatusNotInstalledCommand from indexnowkit/console under the same command names, so CLI behaviour degrades predictably.indexnowkit/console ^0.5 is require-dev/suggest, not a hard runtime requirement. If production uses the Artisan commands, require it explicitly in production dependencies.describeStore() returns <id> (missing) when the lookup resolves to nothing or throws. Do not use the returned string as proof of cache health; it is a human-readable status line, not a validation API.describeStore() can throw and is caught internally. If you need the underlying cause, log it in the closure rather than relying on the description.Pdo\Schema::table() is deliberately taint-aware (@psalm-taint-escape sql) so the checked value can flow into CREATE TABLE / INSERT. Bypassing it and using config('indexnow.history.pdo.table') directly reintroduces the injection boundary the method exists to enforce.--limit fallback to 50 is silent. Validate numeric input at the call site if the exact limit matters for pagination or exports.HistoryServices::package() still works but is now a delegation shim. Prefer OptionalPackage::history(); it avoids loading the history service class just to ask whether the package is present.indexnow:history / indexnow:status.ext-mbstring in CI and production images. The dependency is now declared, but existing locked environments may not have it installed.How can I help you explore Laravel packages today?