danilovl/entity-traits-bundle
createdAt, updatedAt, slug, soft deletes) across teams, reducing technical debt. Critical for scaling products with multiple engineers (e.g., SaaS platforms, marketplaces).SoftDeletableTrait for global soft deletes but extend with custom ArchiveTrait for tenant-specific archiving.User, Product, Article). Measure dev time saved (e.g., "Reduced entity creation time by 60%").SubscriptionTermTrait for billing systems).PriceTrait/CurrencyTrait.TenantTrait), audit logs (BlameableTrait), and role-based access via WorkflowTrait.ViewsCountTrait, ClicksCountTrait, and LastLoginAtTrait for user engagement tracking.Adopt When:
Look Elsewhere When:
fillable).Problem:
"Our dev team spends 30% of entity development time writing repetitive fields (timestamps, IDs, status flags). This delays feature launches and increases bugs from inconsistent patterns."
Solution:
"The EntityTraitsBundle eliminates 90% of Doctrine entity boilerplate with 410+ pre-built traits (timestamps, slugs, soft deletes, counters, etc.). It’s like copy-paste automation—but standardized, validated, and future-proof."
ROI:
Product entity time from 2 days → 30 mins).DateTimeImmutable, soft deletes) across teams.Ask:
"Let’s pilot this on our
UserandProductentities. If it saves 2 dev-weeks in Month 1, we’ll expand to all new entities."
Why This?
"This bundle replaces manual Doctrine mappings (e.g.,
#[ORM\Column],#[Assert\NotBlank]) with batteries-included traits. Think of it as Symfony’smake:entityon steroids—but with 21 categories of reusable logic."
Key Wins:
use TimestampableTrait → get createdAt, updatedAt, and isNew() methods automatically.use SlugTrait → auto-generate slugs from title (configurable fallback).$em->remove($entity) → UPDATE ... SET deleted_at = NOW() (configurable filter).BlameableTrait auto-populates createdBy/updatedBy from Security user.#[Iban], #[VatNumber], #[HexColor] with zero setup.UuidTrait + ?string $description).protected function getSlugSource(): string).SoftDeleteFilter (disable with filter_auto_enable: false).Migration Path:
User, Product).Entity base class).SubscriptionTermTrait for billing).Risks & Mitigations:
| Risk | Mitigation |
|---|---|
Trait conflicts (e.g., two IdTraits) |
Use strict naming (e.g., UuidTrait + ExternalIdTrait). |
| Overhead for simple apps | Start with 1–2 traits (e.g., TimestampableTrait + SoftDeletableTrait). |
| Learning curve | Run a 1-hour workshop on trait categories (e.g., "Audit," "SEO," "Business"). |
Example Migration:
// Before (Manual)
#[ORM\Entity]
class Article {
#[ORM\Column(type: 'datetime_immutable')]
private ?DateTimeImmutable $createdAt = null;
#[ORM\Column(type: 'string', length: 255)]
#[Assert\NotBlank]
private string $slug;
// ... 20+ lines of boilerplate
}
// After (Traits)
#[ORM\Entity]
class Article implements TimestampableInterface, SluggableInterface {
use UuidTrait; // Auto-ID
use TimestampableTrait; // createdAt/updatedAt
use SlugTrait; // Auto-slug from title
use SoftDeletableTrait; // Soft deletes
}
Next Steps:
"Let’s start with the
Userentity. I’ll provide a PR template for migration, and we’ll measure the time saved. If successful, we’ll expand toProductandOrder."
How can I help you explore Laravel packages today?