A>Думаю, что выражать через типы имеет смысл только достаточно стабильную часть логики, т.к. изменение типов может быть болезненной процедурой и затрагивать кучу мест в проекте.
Ой, как это? Мне тут рядом говорили, что придется менять не в 1024 местах, а только в одном месте
A>Ограничение "нельзя менять amount у processed order" выглядит стабильным.
Увы, нет

Начиная с "все спецификации ad-hoc" из оригинального сообщения и до последнего тикета, который таки позволяет увеличивать сумму заказа для pre-paid закаов согласно конфигурации магазина. И это связано с дополнительной логикой — что, если
A>+= Еще один момент: некая функция принимает параметром Order, вызывает другую, та третью и далее по цепочке. Нам нужна гарантия, что эта некая функция не меняет amount, т.к. мы ее вызываем с processed order. Если тип параметра явно указать как ProcessedOrder, то такую гарантию нам даст компилятор, если нет — то остается только просматривать всю цепочку вызовов. Так что вышеуказанные "1024 мест" включают и такие случаи.
Во-первых, совсем не факт, что нам нужна эта гарантия. Во-вторых, если Order — это черный ящик, и смена суммы происходит через order:set_amount, то внезапно все проверки тоже оказываются в одном месте

В-третьих, увеличение суммы может зависить не только от того, запроцессился заказ или нет.
Лишь некоторые из условий:
— заказ не обработан, заказ не pre-paid, сумма повышена, risk chek пройден: повысили
— заказ не обработан, заказ не pre-paid, сумма повышена, risk chek не пройден: не повысили
— заказ обработан, заказ не pre-paid, сумма повышена, risk chek пройден: повысили
— заказ обработан, заказ не pre-paid, сумма повышена, risk chek не пройден: не повысили
...
...
...
и ко всему этому еще надо добавить проверку «а если order expired?», «а надо ли делать re-auth в банке?», «а надо ли...» ну и т.п. :D