Data shapes Required
Use enums instead of magic strings
Give every fixed set of values an enum or union type. Never compare against loose strings such as "paid".
How to do it
Define the set once, and use it in signatures, database mapping and tests. The type checker then catches typos and missing cases. At an API boundary, also follow use enums for fixed values, so clients survive values added later.
Example
// Bad: a typo compiles and fails quietly
if ($order->status === 'payed') { /* ... */ }
// Good: the set of values is a type
enum OrderStatus: string { case Pending = 'pending'; case Paid = 'paid'; case Refunded = 'refunded'; }
if ($order->status === OrderStatus::Paid) { /* ... */ }
from enum import StrEnum
class OrderStatus(StrEnum):
PENDING = "pending"
PAID = "paid"
REFUNDED = "refunded"
if order.status is OrderStatus.PAID: ...
How to check
The tools flag unhandled cases. Examples are typescript-eslint switch-exhaustiveness-check and PHPStan's check that a match covers every enum case. Reviewers fail comparisons of status fields with string literals.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers architecture playbook: https://agentwranglers.se/playbook/architecture/data-shapes/enums-not-strings.