Detector: NamespaceCycleDetector
Report (why the flagged code is CORRECT and the detector is wrong):
This is Laravel's morph map, and the morph map must name the model classes — that is the whole artefact. ResourceType::morphMap() is registered as Eloquent's morph map, so morphTo()/resolve()/morph() are the map and its two lookups, not a service locator. The cycle the detector sees is inherent to the pattern: a polymorphic type register names its models, and models carry the type. Relocating the arms to another namespace moves the cycle rather than removing it, because the map and the type must agree. The genuine service-locator arms on this same enum — repositoryClass(), repository(), dataClass(), which reached into App\Repositories, Domain*\Repository, App\Data and even App\Http\View — were real and have been moved out to App\Resources registries in this same change; what remains is only the morph map.
Cleanest design the reporter can conceive:
The morph map on the type enum it maps: morphTo() as an exhaustive match, morphMap() folding it for Relation::morphMap(), resolve() the inverse lookup. Everything that presents or persists a resource type is a registry above App\Enums; only the model identity stays on the enum, because Eloquent resolves a stored type string to a class through exactly this map.
⚖️ Maintainer litmus: a valid detector-report needs the flagged code to ALREADY BE the
cleanest design. If the design above differs from the flagged code at all, THAT design is
the owed fix — close this report; the fix is still owed.
Where: app/Enums/ResourceType.php:93
Code (app/Enums/ResourceType.php:93):
90 self::WAREHOUSE => Warehouse::class,
91 };
92 }
→ 93
94 public static function morphMap(): array
95 {
96 $map = T_Array::empty();
97
98 foreach (self::cases() as $case)
99 {
100 $map[$case->value] = $case->morphTo();
101 }
102
103 return $map;
104 }
105
106 public static function resolve(string | object $class): ResourceType | null
107 {
108 if (is_object($class))
109 {
110 $class = get_class($class);
111 }
112
113 return array_find(self::cases(), fn (self $case) => is_a($class, $case->morphTo(), true))
114 ?? self::tryFrom($class);
115 }
116
117 public function label(): string
Where: app/Enums/ResourceType.php:122
Code (app/Enums/ResourceType.php:122):
119 return str($this->value)->replace('_', T_String::SPACE)->title()->toString();
120 }
121
→ 122 public function pluralName(): string
123 {
124 return str($this->value)->plural()->toString();
125 }
126
127 /**
128 * Whether resources of this type can be filtered by a single shop via the in-picker shop-scope header.
129 */
130 public function isShopScoped(): bool
131 {
132 return in_array($this, [self::CATEGORY, self::CUSTOMER, self::ORDER, self::PRODUCT, self::VARIANT], strict: true);
133 }
134
135 }
Where: app/Enums/ResourceType.php:134
Code (app/Enums/ResourceType.php:134):
131 {
132 return in_array($this, [self::CATEGORY, self::CUSTOMER, self::ORDER, self::PRODUCT, self::VARIANT], strict: true);
133 }
→ 134
135 }
Filed via commandments report from a consumer project.
Detector:
NamespaceCycleDetectorReport (why the flagged code is CORRECT and the detector is wrong):
This is Laravel's morph map, and the morph map must name the model classes — that is the whole artefact. ResourceType::morphMap() is registered as Eloquent's morph map, so morphTo()/resolve()/morph() are the map and its two lookups, not a service locator. The cycle the detector sees is inherent to the pattern: a polymorphic type register names its models, and models carry the type. Relocating the arms to another namespace moves the cycle rather than removing it, because the map and the type must agree. The genuine service-locator arms on this same enum — repositoryClass(), repository(), dataClass(), which reached into App\Repositories, Domain*\Repository, App\Data and even App\Http\View — were real and have been moved out to App\Resources registries in this same change; what remains is only the morph map.
Cleanest design the reporter can conceive:
The morph map on the type enum it maps: morphTo() as an exhaustive match, morphMap() folding it for Relation::morphMap(), resolve() the inverse lookup. Everything that presents or persists a resource type is a registry above App\Enums; only the model identity stays on the enum, because Eloquent resolves a stored type string to a class through exactly this map.
Where:
app/Enums/ResourceType.php:93Code (
app/Enums/ResourceType.php:93):Where:
app/Enums/ResourceType.php:122Code (
app/Enums/ResourceType.php:122):Where:
app/Enums/ResourceType.php:134Code (
app/Enums/ResourceType.php:134):Filed via
commandments reportfrom a consumer project.