The pitch most agencies are making right now is that AI writes the code and the project gets cheaper. That is not what happens on a real Spryker or Symfony build, and pretending otherwise sets up a client for a bad surprise around week six.

What actually changes is narrower and more useful: the ratio of time spent on mechanical work versus decisions. On a typical enterprise commerce build, a depressing share of engineering hours goes to work that is not hard, just long — module scaffolding, transfer object definitions, data importers, test fixtures, mapping one system's vocabulary onto another's. That is where the leverage is.

The three places it pays

Boilerplate with a known shape. Spryker's module structure is highly regular: a new module means a bundle of files whose contents are almost fully determined by the domain object. Generating that from a specification and reviewing the result is faster than typing it, and the review is genuinely quick because the shape is familiar. The same applies to Symfony form types, doctrine mappings, and API resource definitions.

Migration sweeps. Applying one mechanical change across two hundred call sites is the canonical case. A deprecation, a renamed transfer property, a changed signature. The work is tedious enough that engineers batch it, defer it, and let it rot. When the sweep is cheap, it happens on schedule.

Test scaffolding. Not the assertions that matter — the fixtures, the builders, the setup that makes writing the meaningful test bearable. Teams under-test integration code because standing up the fixture costs more than the test. Lower that cost and coverage moves without anyone being told to care about coverage.

Notice what is missing from that list: the architecture, the integration contracts, the pricing rules, the decision about where a boundary goes. Those are the parts that were always the job, and they are still the job.

The review discipline is the whole product

Generated code that nobody reads is a liability with a faster clock speed. The practice that makes this work is unremarkable and non-negotiable:

  • Every generated change goes through the same review as hand-written code. No separate lane, no "it's just boilerplate" exemption.
  • The reviewer is the engineer who will own the code in production. Not the person who prompted for it.
  • Anything touching money, tax, availability or personal data gets read line by line, twice. The cost of a plausible-looking bug in a pricing rule is not symmetric with the cost of reading it.

The failure mode is not that the model writes nonsense — modern ones rarely do. It is that it writes something reasonable that quietly disagrees with a business rule nobody wrote down. That failure is invisible to tests generated from the same misunderstanding, which is why "the tests pass" carries less weight here than it used to.

A worked example

Here is the kind of thing that looks fine and is wrong. A generated price resolver for a B2B catalog:

public function resolve(ProductTransfer $product, CustomerTransfer $customer): Money
{
    $contract = $this->contractReader->findActive($customer);

    if ($contract !== null) {
        return $contract->getPriceFor($product);
    }

    return $product->getDefaultPrice();
}

Idiomatic, typed, readable, and it will pass a review that is checking whether the code is well-formed. It is also wrong in most B2B contexts, because contract price and list price are not alternatives — the customer pays the lower of the two, and in some jurisdictions a contract price above list is not merely a bad deal but unenforceable. No amount of static analysis finds that. Someone who knows the domain reading it does, in about four seconds.

That four seconds is the job now.

What it means for an estimate

The honest version of the economics: mechanical work compresses substantially, decision work does not compress at all, and review work goes up — you are reviewing more code per unit of calendar time than before.

On builds where the mechanical share was large — a fresh Spryker implementation with many modules, or a broad integration surface — that nets out to a meaningfully shorter delivery. On builds that are mostly gnarly business rules against a legacy integration, it barely moves the total, and anyone promising otherwise is selling you an estimate rather than a plan.

The useful question to ask a supplier is not whether they use AI. It is which of their hours are mechanical, and who reads the output before it ships.