
I used Laravel Pipeline for commission calculation and the logic became much clearer
Too many business rules usually lead to messy code. Here's how Laravel Pipeline helped organize a complex commission calculation into a clean and readable flow.
A series about design patterns through real ICanUp cases. Instead of a pattern encyclopedia, each article starts with a concrete architectural problem where Pipeline, Observer, Registry, Strategy, Factory, Template Method, or Adapter became a natural solution.


Too many business rules usually lead to messy code. Here's how Laravel Pipeline helped organize a complex commission calculation into a clean and readable flow.

In ICanUp, I added a derived search_text field to ContentBlock for search. The harder problem was not extracting text, but guaranteeing that search_text always matches the current data regardless of which service, command, importer, or future code saves the model. This article shows why a saving Observer fits the invariant, why extraction remains in a separate class, and why existing records still need a backfill.

The ICanUp Page Builder grew from simple Paragraph and Image blocks to Hero, Cards, FAQ, Forms, Model Collection, and scoped blocks. This article shows how the Registry Pattern collects definitions behind one contract, resolves the right implementation by type, and lets the system grow without one giant switch.

Public Search in ICanUp searches Posts, Categories, News, and Tips, but every type has its own visibility rules, relations, ordering, and searchable fields. This article shows how SearchProviderInterface and dedicated providers turned those algorithms into interchangeable Strategy implementations.

The ICanUp Communication Center has Private, Group, Support, Feedback, and Post Discussion threads, but each type is resolved differently. This article shows how ThreadResolverFactory selects the correct resolver by ThreadTypeEnum while MessageService stays independent of concrete implementations.

Hero, CTA, Highlight, Cards, Steps, and FAQ have different data but share the same defaults, validation, and configuration structure. This article shows how AbstractPresentationBlockDefinition fixes the common algorithm while concrete definitions provide only their own hooks.

Прикладний шар ICanUp має лише передати список публічних URL і не знати нічого про endpoint, API key, формат HTTP-запиту чи Laravel Http facade. У статті я показую, як `IndexNowClientInterface` став портом для прикладного коду, а `IndexNowHttpClient` адаптує цей простий контракт до зовнішнього API IndexNow.