diff --git a/CLAUDE.md b/CLAUDE.md index ec414276..0c066141 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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. diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index b7b2cdf0..8d5ed7d9 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -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, diff --git a/tests/Unit/MorphMapTest.php b/tests/Unit/MorphMapTest.php new file mode 100644 index 00000000..859f5392 --- /dev/null +++ b/tests/Unit/MorphMapTest.php @@ -0,0 +1,21 @@ +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([]); +});