This is a Laravel package using Orchestra Testbench to simulate a booted Laravel application sandbox for feature and integration tests.
php artisan boost:add-skill sm-me/laravel-redis-model-cache
Save this content to: AGENTS.md
# Agent Configuration for laravel-redis-model-cache
## Working Directory
- **Root:** Always run commands from the **project root** (`/home/sm-me/Codes/Laravel/laravel-redis-model-cache`). Do NOT use `workbench/`.
- **Commands:** Run tools directly from root: `vendor/bin/phpunit`, `vendor/bin/phpstan analyse`, `vendor/bin/pint`.
- **Composer:** Use `composer dump-autoload` from project root after adding new classes.
- **Testing:** Run `vendor/bin/phpunit` from project root. Testbench auto-bootstraps Laravel.
## Code Quality
- **PHPStan:** Run `vendor/bin/phpstan analyse --no-progress` — level 8, target zero errors.
- **Pint:** Run `vendor/bin/pint --test` after changes. Fix with `vendor/bin/pint`.
- **Tests:** All 145 tests must pass. Both `tests/Unit/` and `tests/Feature/` exist.
## Key Files & Patterns
- `src/RedisModelService.php` — core cache service (main file for changes)
- `src/Concerns/HasRedisModelCache.php` — Eloquent trait for models
- `config/redis-model-cache.php` — package configuration
- `tests/Fixtures/DummyModel.php` + `DummySoftDeleteModel.php` — test models with `redisModelCacheConfig()`
- `phpstan.stub` — stubs for optional Telescope/Pulse dependencies
- `phpstan.neon.dist` — configures stub files and ignores Telescope class-not-found errors
## Package Architecture & Testbench
This is a Laravel package using **Orchestra Testbench** to simulate a booted Laravel application sandbox for feature and integration tests.
### Test Case & Bootstrapping
- **Base Test Class:** All tests extend `Orchestra\Testbench\TestCase` (defined in [tests/TestCase.php](file:///home/sm-me/Codes/Laravel/laravel-redis-model-cache/tests/TestCase.php)).
- **Service Providers:** Registered via `getPackageProviders($app)` on the test class.
- **Environment Setup:** Set config/env settings inside `getEnvironmentSetUp($app)`.
- **Database Migrations:**
- Load migrations automatically with the `RefreshDatabase` trait.
- Override `defineDatabaseMigrations()` to call `$this->loadMigrationsFrom(...)` for custom database schema paths.
- Load core Laravel migrations with `$this->loadLaravelMigrations()`.
- **PHP Attributes:** Use `#[WithEnv('KEY', 'value')]`, `#[WithConfig('config.key', 'value')]`, or custom environment method execution using `#[DefineEnvironment('methodName')]`.
### Testbench CLI Commands
- Run migrations: `vendor/bin/testbench migrate`
- Interactive tinker sandbox: `vendor/bin/testbench tinker`
- Run seeds: `vendor/bin/testbench db:seed`
- Purge skeleton: `vendor/bin/testbench package:purge-skeleton` (or `composer clear`)
- Package discovery: `vendor/bin/testbench package:discover` (or `composer prepare`)
- Run tests: `vendor/bin/phpunit` or `vendor/bin/pest` (or `composer test`)
### Workbench Directory (`workbench/`)
- The `workbench/` directory is generated by Testbench. Do not operate/modify files directly inside it as sandbox purges will clean and regenerate it.
- Autoloading namespaces for sandbox-only code are defined in `composer.json` under `autoload-dev`:
- `Workbench\App\` maps to `workbench/app/`
- `Workbench\Database\Factories\` maps to `workbench/database/factories/`
- `Workbench\Database\Seeders\` maps to `workbench/database/seeders/`
## Feature Areas
- Redis hash-based model caching with index/sorted-set lookups
- Stale-while-revalidate (SWR) pattern with background queue jobs
- Stampede protection with Redis lock mechanism
- Compression (zstd/gzip) support
- Pluck/hydrate with configurable batch size (uses HMGET for O(1) round trips)
- `selective()` method for lightweight field-only fetches (60-80% less memory)
- Compression min_size threshold to skip CPU waste on small payloads
- Incremental index updates on model changes
- Debug tooling (inspect, analyzeIndexes, debug mode)
- Telescope & Pulse integration (optional)
- Observability metrics (hit rates, latency percentiles)
- Warmup artisan command
- Benchmark suite (in `benchmarks/`) for throughput, latency, memory
- Multi-tenant cache isolation via `{tenant:{id}:{table}}:` key prefixing
- `TenantResolverInterface` with default `RequestTenantResolver` (header/subdomain/auth/session strategies)
## graphify
This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.
When the user types `/graphify`, invoke the `skill` tool with `skill: "graphify"` before doing anything else.
Rules:
- For codebase questions, first run `graphify query "<question>"` when graphify-out/graph.json exists. Use `graphify path "<A>" "<B>"` for relationships and `graphify explain "<concept>"` for focused concepts. These return a scoped subgraph, usually much smaller than GRAPH_REPORT.md or raw grep output.
- Dirty graphify-out/ files are expected after hooks or incremental updates; dirty graph files are not a reason to skip graphify. Only skip graphify if the task is about stale or incorrect graph output, or the user explicitly says not to use it.
- If graphify-out/wiki/index.md exists, use it for broad navigation instead of raw source browsing.
- Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context.
- After modifying code, run `graphify update .` to keep the graph current (AST-only, no API cost).
===
<laravel-boost-guidelines>
=== foundation rules ===
# Laravel Boost Guidelines
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to ensure the best experience when building Laravel applications.
## Foundational Context
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
- php - 8.4
## Skills Activation
This project has domain-specific skills available in `**/skills/**`. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck.
## Conventions
- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming.
- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`.
- Check for existing components to reuse before writing a new one.
## Verification Scripts
- Do not create verification scripts or tinker when tests cover that functionality and prove they work. Unit and feature tests are more important.
## Application Structure & Architecture
- Stick to existing directory structure; don't create new base folders without approval.
- Do not change the application's dependencies without approval.
## Frontend Bundling
- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `npm run build`, `npm run dev`, or `composer run dev`. Ask them.
## Documentation Files
- You must only create documentation files if explicitly requested by the user.
## Replies
- Be concise in your explanations - focus on what's important rather than explaining obvious details.
=== boost rules ===
# Laravel Boost
## Tools
- Laravel Boost is an MCP server with tools designed specifically for this application. Prefer Boost tools over manual alternatives like shell commands or file reads.
- Use `database-query` to run read-only queries against the database instead of writing raw SQL in tinker.
- Use `database-schema` to inspect table structure before writing migrations or models.
- Use `get-absolute-url` to resolve the correct scheme, domain, and port for project URLs. Always use this before sharing a URL with the user.
- Use `browser-logs` to read browser logs, errors, and exceptions. Only recent logs are useful, ignore old entries.
## Searching Documentation (IMPORTANT)
- Always use `search-docs` before making code changes. Do not skip this step. It returns version-specific docs based on installed packages automatically.
- Pass a `packages` array to scope results when you know which packages are relevant.
- Use multiple broad, topic-based queries: `['rate limiting', 'routing rate limiting', 'routing']`. Expect the most relevant results first.
- Do not add package names to queries because package info is already shared. Use `test resource table`, not `filament 4 test resource table`.
### Search Syntax
1. Use words for auto-stemmed AND logic: `rate limit` matches both "rate" AND "limit".
2. Use `"quoted phrases"` for exact position matching: `"infinite scroll"` requires adjacent words in order.
3. Combine words and phrases for mixed queries: `middleware "rate limit"`.
4. Use multiple queries for OR logic: `queries=["authentication", "middleware"]`.
## Artisan
- Run Artisan commands directly via the command line (e.g., `php artisan route:list`). Use `php artisan list` to discover available commands and `php artisan [command] --help` to check parameters.
- Inspect routes with `php artisan route:list`. Filter with: `--method=GET`, `--name=users`, `--path=api`, `--except-vendor`, `--only-vendor`.
- Read configuration values using dot notation: `php artisan config:show app.name`, `php artisan config:show database.default`. Or read config files directly from the `config/` directory.
## Tinker
- Execute PHP in app context for debugging and testing code. Do not create models without user approval, prefer tests with factories instead. Prefer existing Artisan commands over custom tinker code.
- Always use single quotes to prevent shell expansion: `php artisan tinker --execute 'Your::code();'`
- Double quotes for PHP strings inside: `php artisan tinker --execute 'User::where("active", true)->count();'`
=== php rules ===
# PHP
- Always use curly braces for control structures, even for single-line bodies.
- Use PHP 8 constructor property promotion: `public function __construct(public GitHub $github) { }`. Do not leave empty zero-parameter `__construct()` methods unless the constructor is private.
- Use explicit return type declarations and type hints for all method parameters: `function isAccessible(User $user, ?string $path = null): bool`
- Use TitleCase for Enum keys: `FavoritePerson`, `BestLake`, `Monthly`.
- Prefer PHPDoc blocks over inline comments. Only add inline comments for exceptionally complex logic.
- Use array shape type definitions in PHPDoc blocks.
=== deployments rules ===
# Deployment
- Laravel can be deployed using [Laravel Cloud](https://cloud.laravel.com/), which is the fastest way to deploy and scale production Laravel applications.
=== testbench rules ===
# Testbench
- This is a Laravel package bootstrapped via Orchestra Testbench for testing.
- `src/` contains source. `tests/` contains unit and feature tests.
- **Base TestCase:** Tests must extend `Orchestra\Testbench\TestCase` (configured in [TestCase.php](file:///home/sm-me/Codes/Laravel/laravel-redis-model-cache/tests/TestCase.php)).
- **Service Providers:** Register package providers using the `getPackageProviders($app)` method in the test class.
- **Environment Setup:** Customize settings or config variables in the `getEnvironmentSetUp($app)` method.
- **Database Migrations:**
- Automatically load migrations with the `RefreshDatabase` trait.
- Manually configure migrations by overriding `defineDatabaseMigrations()` and calling `$this->loadMigrationsFrom(...)`.
- Load default Laravel migrations (e.g. users table) with `$this->loadLaravelMigrations()`.
- **PHP Attributes for Custom Env:** Set configuration/env dynamically using `#[WithEnv('KEY', 'value')]`, `#[WithConfig('config.key', 'value')]`, or execute custom config helpers with `#[DefineEnvironment('methodName')]`.
- **Testbench CLI Commands:**
- Run package-context commands: `vendor/bin/testbench <command>` (e.g., `vendor/bin/testbench migrate`, `vendor/bin/testbench tinker`, `vendor/bin/testbench db:seed`).
- Purge skeleton/workbench workspace: `vendor/bin/testbench package:purge-skeleton` (also mapped to `composer clear`).
- Re-discover package: `vendor/bin/testbench package:discover` (also mapped to `composer prepare`).
- **Workbench Directory (`workbench/`):**
- The `workbench/` directory is generated by Testbench — do not manually modify files inside it unless they are part of a persistent workbench template. Purges will clean/regenerate this workspace.
- Workbench app namespaces (`Workbench\App\`, `Workbench\Database\Factories\`, `Workbench\Database\Seeders\`) are autoloaded in `composer.json` under `autoload-dev`.
</laravel-boost-guidelines>
/home/sm-me/Codes/Laravel/laravel-redis-model-cache). Do NOT use workbench/.vendor/bin/phpunit, vendor/bin/phpstan analyse, vendor/bin/pint.composer dump-autoload from project root after adding new classes.vendor/bin/phpunit from project root. Testbench auto-bootstraps Laravel.vendor/bin/phpstan analyse --no-progress — level 8, target zero errors.vendor/bin/pint --test after changes. Fix with vendor/bin/pint.tests/Unit/ and tests/Feature/ exist.src/RedisModelService.php — core cache service (main file for changes)src/Concerns/HasRedisModelCache.php — Eloquent trait for modelsconfig/redis-model-cache.php — package configurationtests/Fixtures/DummyModel.php + DummySoftDeleteModel.php — test models with redisModelCacheConfig()phpstan.stub — stubs for optional Telescope/Pulse dependenciesphpstan.neon.dist — configures stub files and ignores Telescope class-not-found errorsThis is a Laravel package using Orchestra Testbench to simulate a booted Laravel application sandbox for feature and integration tests.
Orchestra\Testbench\TestCase (defined in tests/TestCase.php).getPackageProviders($app) on the test class.getEnvironmentSetUp($app).RefreshDatabase trait.defineDatabaseMigrations() to call $this->loadMigrationsFrom(...) for custom database schema paths.$this->loadLaravelMigrations().#[WithEnv('KEY', 'value')], #[WithConfig('config.key', 'value')], or custom environment method execution using #[DefineEnvironment('methodName')].vendor/bin/testbench migratevendor/bin/testbench tinkervendor/bin/testbench db:seedvendor/bin/testbench package:purge-skeleton (or composer clear)vendor/bin/testbench package:discover (or composer prepare)vendor/bin/phpunit or vendor/bin/pest (or composer test)workbench/)workbench/ directory is generated by Testbench. Do not operate/modify files directly inside it as sandbox purges will clean and regenerate it.composer.json under autoload-dev:
Workbench\App\ maps to workbench/app/Workbench\Database\Factories\ maps to workbench/database/factories/Workbench\Database\Seeders\ maps to workbench/database/seeders/selective() method for lightweight field-only fetches (60-80% less memory)benchmarks/) for throughput, latency, memory{tenant:{id}:{table}}: key prefixingTenantResolverInterface with default RequestTenantResolver (header/subdomain/auth/session strategies)This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.
When the user types /graphify, invoke the skill tool with skill: "graphify" before doing anything else.
Rules:
graphify query "<question>" when graphify-out/graph.json exists. Use graphify path "<A>" "<B>" for relationships and graphify explain "<concept>" for focused concepts. These return a scoped subgraph, usually much smaller than GRAPH_REPORT.md or raw grep output.graphify update . to keep the graph current (AST-only, no API cost).===
The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to ensure the best experience when building Laravel applications.
This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions.
This project has domain-specific skills available in **/skills/**. You MUST activate the relevant skill whenever you work in that domain—don't wait until you're stuck.
isRegisteredForDiscounts, not discount().npm run build, npm run dev, or composer run dev. Ask them.=== boost rules ===
database-query to run read-only queries against the database instead of writing raw SQL in tinker.database-schema to inspect table structure before writing migrations or models.get-absolute-url to resolve the correct scheme, domain, and port for project URLs. Always use this before sharing a URL with the user.browser-logs to read browser logs, errors, and exceptions. Only recent logs are useful, ignore old entries.search-docs before making code changes. Do not skip this step. It returns version-specific docs based on installed packages automatically.packages array to scope results when you know which packages are relevant.['rate limiting', 'routing rate limiting', 'routing']. Expect the most relevant results first.test resource table, not filament 4 test resource table.rate limit matches both "rate" AND "limit"."quoted phrases" for exact position matching: "infinite scroll" requires adjacent words in order.middleware "rate limit".queries=["authentication", "middleware"].php artisan route:list). Use php artisan list to discover available commands and php artisan [command] --help to check parameters.php artisan route:list. Filter with: --method=GET, --name=users, --path=api, --except-vendor, --only-vendor.php artisan config:show app.name, php artisan config:show database.default. Or read config files directly from the config/ directory.php artisan tinker --execute 'Your::code();'
php artisan tinker --execute 'User::where("active", true)->count();'=== php rules ===
public function __construct(public GitHub $github) { }. Do not leave empty zero-parameter __construct() methods unless the constructor is private.function isAccessible(User $user, ?string $path = null): boolFavoritePerson, BestLake, Monthly.=== deployments rules ===
=== testbench rules ===
src/ contains source. tests/ contains unit and feature tests.Orchestra\Testbench\TestCase (configured in TestCase.php).getPackageProviders($app) method in the test class.getEnvironmentSetUp($app) method.RefreshDatabase trait.defineDatabaseMigrations() and calling $this->loadMigrationsFrom(...).$this->loadLaravelMigrations().#[WithEnv('KEY', 'value')], #[WithConfig('config.key', 'value')], or execute custom config helpers with #[DefineEnvironment('methodName')].vendor/bin/testbench <command> (e.g., vendor/bin/testbench migrate, vendor/bin/testbench tinker, vendor/bin/testbench db:seed).vendor/bin/testbench package:purge-skeleton (also mapped to composer clear).vendor/bin/testbench package:discover (also mapped to composer prepare).workbench/):
workbench/ directory is generated by Testbench — do not manually modify files inside it unless they are part of a persistent workbench template. Purges will clean/regenerate this workspace.Workbench\App\, Workbench\Database\Factories\, Workbench\Database\Seeders\) are autoloaded in composer.json under autoload-dev.How can I help you explore Laravel packages today?