Register all models in the morph map + lock it with a test
Add the five automation models to Relation::enforceMorphMap(), document the all-models-must-be-mapped rule in CLAUDE.md, and add MorphMapTest to fail when any app/Models class is missing from the map.
This commit is contained in:
parent
f223cf14ce
commit
65116de859
3 changed files with 37 additions and 0 deletions
|
|
@ -297,6 +297,12 @@ ## Array Data Access
|
|||
- Example: `data_get($data, 'name')` instead of `$data['name']`.
|
||||
- Use the third parameter for fallback values: `data_get($data, 'username', $sender->username)` instead of `$data['username'] ?? $sender->username`.
|
||||
|
||||
## Eloquent Models & Morph Map
|
||||
|
||||
- EVERY Eloquent model in `app/Models` MUST be registered in `Relation::enforceMorphMap([...])` inside `AppServiceProvider::configureMorphMap()`, keyed by a camelCase alias (e.g. `'postPlatform' => PostPlatform::class`).
|
||||
- When you add a new model, add it to the morph map in the same change. `tests/Unit/MorphMapTest.php` fails if any model is missing.
|
||||
- The alias is persisted in polymorphic columns, so never rename or remove an existing alias for a model that has stored rows.
|
||||
|
||||
## Imports
|
||||
|
||||
- NEVER use inline class references (e.g., `\DB::listen`, `\Str::uuid()`). ALWAYS import classes at the top of the file with a `use` statement.
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@
|
|||
use App\Models\AccessToken;
|
||||
use App\Models\Account;
|
||||
use App\Models\AiUsageLog;
|
||||
use App\Models\Automation;
|
||||
use App\Models\AutomationNodeRun;
|
||||
use App\Models\AutomationNodeState;
|
||||
use App\Models\AutomationRun;
|
||||
use App\Models\AutomationTriggerItem;
|
||||
use App\Models\Invite;
|
||||
use App\Models\Media;
|
||||
use App\Models\Notification;
|
||||
|
|
@ -114,6 +119,11 @@ protected function configureMorphMap(): void
|
|||
'accessToken' => AccessToken::class,
|
||||
'account' => Account::class,
|
||||
'aiUsageLog' => AiUsageLog::class,
|
||||
'automation' => Automation::class,
|
||||
'automationNodeRun' => AutomationNodeRun::class,
|
||||
'automationNodeState' => AutomationNodeState::class,
|
||||
'automationRun' => AutomationRun::class,
|
||||
'automationTriggerItem' => AutomationTriggerItem::class,
|
||||
'invite' => Invite::class,
|
||||
'media' => Media::class,
|
||||
'notification' => Notification::class,
|
||||
|
|
|
|||
21
tests/Unit/MorphMapTest.php
Normal file
21
tests/Unit/MorphMapTest.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
|
||||
test('every Eloquent model is registered in the morph map', function () {
|
||||
$mapped = array_values(Relation::morphMap());
|
||||
|
||||
$missing = collect(glob(app_path('Models/*.php')))
|
||||
->map(fn (string $file): string => 'App\\Models\\'.pathinfo($file, PATHINFO_FILENAME))
|
||||
->filter(fn (string $class): bool => class_exists($class)
|
||||
&& is_subclass_of($class, Model::class)
|
||||
&& ! (new ReflectionClass($class))->isAbstract())
|
||||
->reject(fn (string $class): bool => in_array($class, $mapped, true))
|
||||
->values()
|
||||
->all();
|
||||
|
||||
expect($missing)->toBe([]);
|
||||
});
|
||||
Loading…
Reference in a new issue