Filament navigation badges relied on two separate implementations for generating the same cache key.
app/Traits/Models/UpdatesNavigationBadgeCount.php
getTableName()→ returns the model table namegetNavBadgeCacheKey()→ builds:
filament:nav-badge:{table}:count
app/Traits/Filament/HasNavigationBadgeCount.php
- Maintained its own key formatter (e.g.
getFormattedModelLabel())
The cache key format diverged between the two traits.
As a result:
- The model trait updated one cache key (increment / decrement)
- The resource trait read a different cache key
This caused navigation badge counts to appear stale or incorrect.
We established a single source of truth on the model.
-
HasNavigationBadgeCountnow delegates key resolution:static::getModel()::getNavBadgeCacheKey();
-
UpdatesNavigationBadgeCountis now responsible for:getTableName()getNavBadgeCacheKey
To enforce consistency across the application:
app/Models/BaseModel.phpapp/Models/BaseAuthModel.php
Both include the shared model trait.
- All models expose a consistent cache key API
- Filament resources read the exact same key updated by model events
- Badge counts remain accurate and synchronized
- Removed repetition and tightened phrasing
- Clarified “divergence” as the root cause
- Made the “single source of truth” explicit and central
- Grouped responsibilities cleanly (model vs resource)
- Improved scannability (shorter sections, sharper bullets)