How to actually integrate AI into your existing workflows, without breaking everything

TL;DR

Difficulty: Intermediate

AI projects rarely stall on the model. They stall on the data.

  • Order of work: define the problem without the word AI, audit the data, clean it, choose the integration pattern, then start with one measured use case.
  • Three patterns add AI without replacing systems: a service wrapper with a fallback, an event listener on Spree::Bus, and middleware between systems.
  • MCP puts one standard server in front of each legacy system instead of a web of custom integrations.
  • Data protection: send identifiers, not identities, use business terms with a processing agreement, and log what you sent.
  • Start with cart recovery, product data enrichment, forecasting, ticket classification or campaign optimisation, one at a time.

Most AI projects stall, and almost never because of the model. I walk through the order of work that holds up, three ways to add AI to an existing Rails and Solidus stack without replacing it, what MCP changes for legacy systems, the data protection basics, and five realistic first projects, worked through on an invented Limerick car marketplace.

Why most AI projects stall, and it is rarely the AI

Let me save you six months and a lot of frustration. Most AI projects that stall do not stall because the model was not good enough. They stall because the data was rubbish.

The research points the same way. Gartner predicted in February 2025 that through 2026 organisations will abandon 60% of AI projects that are not supported by AI ready data.1 A survey of more than 550 data and analytics professionals by Precisely and Drexel University's LeBow College of Business found that 77% rated their organisation's data quality as average at best, up from 66% the year before, an eleven point fall.2 And BARC's Data, BI and Analytics Trend Monitor 2026, with 1,579 participants, put data quality management back in first place, level with data security and privacy, ahead of the newer AI topics.3

The pattern is always the same. A company gets excited about AI. It buys or builds a model and feeds it its data. The data is inconsistent, duplicated, out of date or incomplete. The model produces unreliable results, the project stalls, and six months and a budget later everyone concludes that "AI doesn't work for us". The AI was not the problem. Fixing the data should have been the first step.

I know this because I've lived it. When I started building GrowCentric.ai, my marketing optimisation SaaS, the machine learning models were not the hard part. The hard part was getting clean, consistent data out of the messy reality of real eCommerce businesses. And when I built AI assisted search and recommendations for a car marketplace running on Rails and Solidus, the challenge was not the algorithms. It was the same model entered in several different ways, mileage and engine power in mixed units, colour names all over the place, duplicate customer records and old supplier feeds.

Worked example: one car, five spellings

Adare Motor Exchange is an invented used car marketplace in Limerick at adaremotors.example, with 1,800 listings entered by dozens of dealers, a good few of them selling imports from the UK, so miles and kilometres sit side by side. The same car turns up as:

  1. "BMW 320i", 45,000 miles, 184 bhp, "black"
  2. "BMW 3 Series 320i", "45000", 135 kW, "Black"
  3. "3 Series 320 i", 72,420 km, 184PS, "jet black"
  4. "bmw 320I", "45k", no power given, "Black Sapphire metallic"
  5. "BMW 320i M Sport", 45,000 miles, 184 bhp, "BLACK"

A recommendation model sees five different cars. A search for "black BMW 3 Series under 50,000 miles" finds one of them, maybe two. No model in the world makes sense of that without cleaning it first. So that is where to start: not with AI, with data.

The right order of operations

Here is the order that works, from projects I've built and projects I've rescued.

The order of operations for an AI projectDefine the business problem without mentioning AI. Audit the data. If it is not good enough, clean and normalise it and audit again. Then choose how AI connects to existing systems, start with one small use case and measure it, and expand only if it pays.Define the business problem, withoutthe word AIAudit the dataGood enough for this problem?noClean, normalise and add validation,then audit againyesChoose the integration patternStart with one use case and measure itExpand only what pays

Read it from the top. The only loop is the data check: if the audit says the data cannot support the problem, the next job is cleaning, not modelling.

Step 1: define the business problem. Not "we want to use AI" but "we want to recover more abandoned carts", "we want to know which cars will sell within seven days" or "we want support tickets routed to the right person". If you cannot state the problem without mentioning AI, you are not ready.

Step 2: audit your data. Before a line of AI code, look at the data. How complete, how consistent, how accurate, how current? Where are the duplicates and the gaps? The audit tells you whether you are weeks or months away. For a Rails and Solidus shop it can be a short class:

class DataQualityAudit
  def run
    { products: audit_products, customers: audit_customers, inventory: audit_inventory }
  end

  private

  def audit_products
    {
      total: Spree::Product.count,
      missing_descriptions: Spree::Product.where(description: [nil, ""]).count,
      without_images: Spree::Product.where.missing(:variant_images).count,
      variants_without_price: Spree::Variant.where.missing(:prices).count,
      duplicate_skus: Spree::Variant.where.not(sku: [nil, ""]).group(:sku).having("count(*) > 1").count.size
    }
  end

  def audit_customers
    users = Spree.user_class
    {
      total: users.count,
      duplicate_emails: users.group("LOWER(email)").having("count(*) > 1").count.size,
      without_address: users.where.missing(:addresses).count,
      untouched_two_years: users.where(updated_at: ...2.years.ago).count
    }
  end

  def audit_inventory
    {
      negative_stock: Spree::StockItem.where("count_on_hand < 0").count,
      listed_but_unsellable: Spree::StockItem.where(count_on_hand: 0, backorderable: false)
                               .joins(variant: :product).merge(Spree::Product.available).count
    }
  end
end

Spree.user_class is the configured user model, and Solidus products and variants are soft deleted, so the default scopes already leave deleted records out.

A single number per area helps you track progress. A simple completeness score is the share of required fields that are filled:

C=fr×nC = \frac{f}{r \times n}

Here CC is the completeness score from 0 to 1, ff is the number of required fields that are actually filled, rr is the number of required fields per record and nn is the number of records. It is an ordinary rate, events over opportunities. Foundations: ratios and rates

Worked example: Adare's listing completeness

Adare requires five fields per listing: make and model, mileage, power, colour and at least one photo. With 1,800 listings there are 5×1,800=9,0005 \times 1{,}800 = 9{,}000 required fields. The audit finds 540 listings without power, 210 without a photo and 90 without mileage, so 540+210+90=840540 + 210 + 90 = 840 fields are empty and 9,000−840=8,1609{,}000 - 840 = 8{,}160 are filled.

C=8,1609,000=0.907C = \frac{8{,}160}{9{,}000} = 0.907

So CC is 90.7%. That sounds grand until you notice that the empty fields are exactly the ones a buyer filters on. The score tells you how much is missing. Which fields are missing tells you whether it matters.

Step 3: clean and normalise. The unglamorous work that makes everything else possible. Deduplicate, standardise formats, fill gaps where you can, and add validation so new dirty data cannot get in. For Adare that means a normaliser for listings:

class ListingNormaliser
  MAKE_ALIASES = { "bmw" => "BMW", "vw" => "Volkswagen", "merc" => "Mercedes-Benz", "mercedes" => "Mercedes-Benz" }.freeze
  KM_PER_MILE = 1.609344
  KW_PER_BHP = 0.7457
  KW_PER_PS = 0.7355

  def normalise(listing)
    {
      make: MAKE_ALIASES.fetch(listing[:make].to_s.strip.downcase, listing[:make].to_s.strip),
      mileage_miles: mileage_in_miles(listing[:mileage]),
      power_kw: power_in_kw(listing[:power]),
      colour: listing[:colour].to_s.strip.downcase.presence
    }
  end

  private

  def mileage_in_miles(value)
    text = value.to_s.downcase.strip
    return nil if text.empty?

    number = text.delete(",").to_f
    number *= 1_000 if text.match?(/\d\s*k\b/)
    number /= KM_PER_MILE if text.include?("km")
    number.positive? ? number.round : nil
  end

  def power_in_kw(value)
    text = value.to_s.downcase
    number = text[/\d+(\.\d+)?/].to_f
    return nil unless number.positive?

    if text.include?("kw") then number.round
    elsif text.include?("ps") then (number * KW_PER_PS).round
    else (number * KW_PER_BHP).round # bhp or hp
    end
  end
end

Note the two conversion factors. Brake horsepower and metric horsepower (PS) are not the same unit, and a normaliser that uses one factor for both is quietly wrong by about 1.4%.

Worked example: the five BMWs, normalised

Listing 3 says 72,420 km and 184PS. Mileage: 72,420÷1.609344=45,00072{,}420 \div 1.609344 = 45{,}000 miles. Power: 184×0.7355=135184 \times 0.7355 = 135 kW. Listing 1 says 184 bhp: 184×0.7457=137184 \times 0.7457 = 137 kW. Listing 2 already says 135 kW. Listing 4's "45k" becomes 45,000 miles.

After the normaliser, four of the five agree on mileage, and the power figures sit at 135 to 137 kW, which is close enough to flag as probably the same car for a person to check. The colour still needs a lookup table (black, jet black, Black Sapphire metallic all map to "black" for search), which is a morning's work. Only then is the data worth showing to a model.

Step 4: choose the integration pattern. Now, and only now, think about how AI connects to your systems.

Step 5: start small, measure everything, iterate.

Three patterns for adding AI without replacing anything

Most businesses cannot rip out their systems and start again. You have a Rails application that has run for years, a Solidus shop with thousands of products and customers, staff who depend on the workflows, and integrations with suppliers, payment providers and couriers. You do not need to replace any of it. You layer AI on top.

Pattern 1: the service wrapper. Put the AI behind a service your application calls. The application does not need to know that machine learning is involved. It asks, gets an answer and uses it, and if the AI is slow or down, it falls back.

class ProductRecommendationService
  def recommendations_for(user, limit: 6)
    fetch_ai_recommendations(user, limit).presence || fallback_recommendations(user, limit)
  end

  private

  def fetch_ai_recommendations(user, limit)
    response = AiClient.post("/recommendations", user_id: user.id, limit: limit)
    in_stock(Spree::Product.where(id: response.fetch("product_ids", []))).limit(limit)
  rescue AiClient::Error, Timeout::Error => e
    Rails.logger.warn("Recommendations unavailable: #{e.message}")
    nil
  end

  def fallback_recommendations(user, limit)
    in_stock(Spree::Product.available).order(available_on: :desc).limit(limit)
  end

  def in_stock(products)
    products.joins(:variants_including_master).merge(Spree::Variant.in_stock).distinct
  end
end

If the AI service fails, the shop shows the newest products in stock instead. Customers never see an error. AI should improve a workflow, never become its single point of failure.

Notice what is sent: a user id and a number. Not the customer's name, email or address. More on that below.

Pattern 2: the event listener. Your shop already announces what happens. Solidus publishes events such as order_finalized on its own bus, Spree::Bus, built on the Omnes library, and you can register your own.4 An AI layer subscribes to those events and acts, without touching the checkout:

# config/initializers/omnes.rb
Rails.application.config.to_prepare do
  Spree::Bus.register(:cart_abandoned) unless Spree::Bus.registry.registered?(:cart_abandoned)
  Adare::AiSubscriber.new.subscribe_to(Spree::Bus)
end

# app/subscribers/adare/ai_subscriber.rb
module Adare
  class AiSubscriber
    include Omnes::Subscriber

    handle :order_finalized, with: :after_order
    handle :cart_abandoned, with: :after_abandonment

    def after_order(event)
      order = event.payload[:order]
      CrossSellAnalysisJob.perform_later(order.id)
      DemandForecastUpdateJob.perform_later(order.id)
    end

    def after_abandonment(event)
      CartRecoveryJob.perform_later(event.payload[:order].id)
    end
  end
end

# A recurring job publishes the custom event for carts left alone for an hour
Spree::Bus.publish(:cart_abandoned, order: order)

The subscriber only enqueues jobs, so the checkout never waits for a model to think. Your Solidus checkout, payments and order management do not change. The AI layer listens and adds to them.

Pattern 3: the middleware layer. When AI needs to sit between two systems and improve the data passing through, a middleware layer does the job. I use this pattern in GrowCentric.ai, which sits between eCommerce shops and advertising platforms such as Google Ads and Meta. It reads performance data, enriches it with its own analysis and passes adjusted campaign settings back. The shop does not change at all. GrowCentric only needs API access to read performance and write campaign changes.

Worked example: choosing a pattern at Adare

Three jobs at Adare. "Show similar cars on a listing page" is a question the page asks and needs answered in under a second, so it is a service wrapper with a fallback. "When a car sells, update the demand forecast for that model" reacts to something that happened, so it is an event listener. "Adjust Adare's Google Ads bids by how fast each model sells" sits between two systems, so it is middleware. The pattern follows from the question: asked, happened, or in between.

Legacy systems, and what MCP changes

Legacy systems are where most businesses get stuck. A supplier sends product data as a CSV attachment. The accounting system only speaks SOAP XML. The warehouse system from 2015 has a barely documented REST API. Customer data is split across three systems that were never joined up. That is the reality for every mid market eCommerce business I've worked with.

The traditional answer is custom integrations between each pair of systems. With nn systems that can mean up to n(n−1)/2n(n-1)/2 integrations, so ten systems means up to 10×9÷2=4510 \times 9 \div 2 = 45, and each change breaks several of them.

The Model Context Protocol (MCP), which I covered in AI agents vs chatbots, changes the shape. Anthropic published it in November 2024 as an open standard for connecting AI assistants to the systems where data lives,5 and in December 2025 donated it to the Agentic AI Foundation under the Linux Foundation, so no single vendor controls it.6 Instead of point to point integrations, you put one MCP server in front of each system. Each server describes what its system can do in a standard way, and any MCP aware agent can use it. Ten systems, ten servers.

The official Ruby SDK, the mcp gem, defines each capability as a tool class:7

class CheckSupplierStock < MCP::Tool
  description "Check stock at the supplier for one SKU"
  input_schema(properties: { sku: { type: "string" } }, required: ["sku"])

  class << self
    def call(sku:, server_context:)
      stock = LegacySupplierSoapClient.check_stock(sku) # wraps the old SOAP API
      MCP::Tool::Response.new([{ type: "text", text: { sku: sku, available: stock }.to_json }])
    end
  end
end

class LatestSupplierCatalogue < MCP::Tool
  description "The supplier's latest catalogue, parsed and normalised"
  input_schema(properties: { since: { type: "string", format: "date" } })

  class << self
    def call(server_context:, since: nil)
      rows = SupplierCsvImporter.new.fetch_and_normalise(since: since) # reads the CSV attachments
      MCP::Tool::Response.new([{ type: "text", text: rows.to_json }])
    end
  end
end

server = MCP::Server.new(name: "adare_supplier", tools: [CheckSupplierStock, LatestSupplierCatalogue])

The agent never needs to know that one supplier sends CSV attachments while another has a SOAP API. The server hides that. Notice what is missing: a tool that places purchase orders. Reading comes first. Anything that commits money waits until the read only tools have earned trust, and then goes through a person.

Data protection before the first API call

Every request you send to a cloud AI service leaves your systems. If it contains anything that identifies a person, it is processing of personal data under the GDPR, which applies in Ireland directly as an EU regulation, and the usual rules apply: the data must be limited to what is necessary for the purpose,8 and a provider that processes it on your behalf needs a contract with the terms Article 28 sets out.9 The Irish regulator is the Data Protection Commission (DPC), established under the Data Protection Act 2018,10 and the DPC's guidance on AI, large language models and data protection is the place to start.11

The risk is not theoretical. In May 2023 Samsung restricted staff use of generative AI tools such as ChatGPT on company computers after cases of misuse, reportedly including confidential code entered into ChatGPT.12 Nobody meant harm. Someone wanted help with a bug. My article on AI in business goes through more incidents like it and how to route sensitive work so it never leaves the building, and building GDPR compliant AI features covers the product side.

In integration code, three habits cover most of it. Send identifiers, not identities: a user id, never a name and an email, unless the task truly needs them. Use business or API terms with a processing agreement, never a personal account. And log what you sent, so you can answer the question "what did we give the AI?" when someone asks.

Worked example: what Adare sends to the recommendation service

The first draft of Adare's integration sent the full user record: name, email, phone number, Eircode and the cars viewed. The question to ask of each field is whether the recommendation needs it.

  1. Name: no.
  2. Email and phone: no.
  3. Eircode: only the routing key, if distance matters (V94, not the full code).
  4. Cars viewed: yes, as listing ids.
  5. A stable user id, so the service can learn: yes, a random identifier, not the database id.

Five personal fields become one random id, one routing area and a list of listing ids. The recommendations are just as good, and a leak at the provider would expose almost nothing.

Five realistic starting points

Enough theory. Here are five starting points, ranked by impact and difficulty. Pick one. Get it working. Then move to the next.

1. Smarter cart recovery (low difficulty, high impact). Abandoned carts are one of the biggest revenue leaks in eCommerce. Baymard Institute's average across 50 studies puts the abandonment rate at about 70%.13 The AI version goes beyond "you left something in your basket". It estimates why the customer left (delivery cost shock, comparison shopping, just browsing), picks the channel and the incentive, and times the follow up. On the car marketplace I mentioned, this was the most useful AI integration I built.

class CartRecoveryAgent
  def recover(order)
    user = order.user
    return unless user&.marketing_consent? # the shop's own consent record: no consent, no email or advert

    reason = AbandonmentClassifier.predict(signals_for(order))
    strategy = RecoveryStrategy.for(reason)

    CartRecoveryMailer.recovery(order, template: strategy.template, incentive: strategy.incentive)
                      .deliver_later(wait: strategy.delay)

    AgentAuditLog.create!(agent_name: "CartRecovery", action_type: "recovery_email",
                          decision_payload: { order_id: order.id, reason: reason, strategy: strategy.to_h })
  end

  private

  def signals_for(order)
    {
      reached_delivery_step: order.state.in?(%w[delivery payment confirm]),
      first_time_buyer: order.user.orders.complete.none?,
      items: order.line_items.count,
      basket_value: order.item_total.to_f
    }
  end
end

Two details matter. The consent check comes first: a recovery email is marketing, and so is a retargeting advert. And the mailer is called through its own method, recovery, never through Ruby's send, which would call a method on the class rather than send an email.

Worked example: is it worth building?

The example's assumptions: Adare's parts shop sees 600 abandoned carts a month at an average of €85, 60% of those customers have given marketing consent, and the smarter emails recover 6% of the carts they go to, against 3% for the old fixed reminder.

Carts that can be emailed: 600×0.6=360600 \times 0.6 = 360. Old reminder: 360×0.03=10.8360 \times 0.03 = 10.8 orders. New agent: 360×0.06=21.6360 \times 0.06 = 21.6 orders. The difference is 10.8×85=€91810.8 \times 85 = €918 a month in revenue. If the build costs less than the margin on that over a year, it is worth it. The 6% is the example's assumption, and the first month of measurement replaces it with a real number. Foundations: expected value

2. Product data enrichment (low difficulty, medium impact). Thin or inconsistent product descriptions can be improved with AI, but only after the structured data is clean. Generate or improve descriptions, extract attributes from free text, and keep categories consistent. Do not apply the output blindly:

class ProductEnrichmentService
  def enrich(product)
    return unless product.description.to_s.length < 100 || product.meta_description.blank?

    properties = product.product_properties.joins(:property).pluck("spree_properties.name", :value).to_h
    result = AiClient.post("/enrich-product", name: product.name, description: product.description.to_s,
                                              properties: properties, taxons: product.taxons.pluck(:name))

    if result["confidence"].to_f >= 0.8
      product.update!(description: result["description"], meta_description: result["meta_description"])
    else
      EnrichmentReview.create!(product: product, proposal: result) # a person decides
    end
  end
end

Below the confidence threshold, a person reviews the proposal. Note that only product data goes to the service, never customer data.

3. Demand forecasting (medium difficulty, high impact). As I described in agentic AI for eCommerce, stock management is one of the most valuable uses of AI. It needs clean history first. If stock counts were wrong, sales data has gaps or categories are inconsistent, the forecast will be unreliable. Start with at least 12 months of clean orders, accurate stock and consistent categories, then build a basic forecasting model that improves over time.

4. Support ticket classification (low difficulty, medium impact). AI can tag incoming tickets by type (return, delivery question, product question, complaint), urgency and tone, and route them to the right person. That needs no new support system, just an event listener that reads each new ticket and adds labels.

5. Marketing campaign optimisation (medium difficulty, high impact). This is what GrowCentric.ai does. Instead of adjusting budgets, bids and targeting by hand, AI agents monitor performance continuously and make the routine optimisation decisions. The prerequisite is clean tracking. If attribution is broken or conversion tracking incomplete, the AI optimises for the wrong thing.

What I do for clients

To be concrete about how this maps to my work:

Data audits and clean up. I audit a Solidus shop's data (product completeness, duplicate customers, stock accuracy, order integrity), then build the normalisation and validation that keep new dirty data out. It is the foundation for everything else.

AI ready architecture on Rails. Events, background jobs and fallbacks, so the application is ready for AI and an AI failure never breaks the shop.

MCP servers. Servers that expose existing systems (Solidus, supplier feeds, warehouse, accounting) to AI agents in a standard way, so legacy systems join in without being replaced.

Agents themselves. Cart recovery, forecasting, ticket classification, order routing, each with tiered autonomy, audit logs and the guardrails from my agentic AI and agents vs chatbots articles.

Compliance built in. The GDPR from the first line of code, and, because an Irish business sits inside the EU, the Cyber Resilience Act and the NIS2 Directive. Deploying AI that breaks data protection law is not an advantage, it is a liability.

The honest reality check

Some uncomfortable truths to finish.

It takes longer than you think. Budget three to six months for a meaningful integration, not three to six weeks. The data clean up alone can take weeks, integration testing takes longer than development, and your team needs time to trust the AI's decisions before it gets more autonomy.

You need less AI than you think. Most businesses would gain more from clean data and better basic analytics than from a sophisticated model. If you cannot answer basic questions about customer behaviour, your conversion funnel and stock turnover with the data you have, AI will not help yet. Fix the basics first.

The first version will be underwhelming. Expect a 5% to 10% improvement from a first integration, not a transformation. That is normal. The value compounds as the models see more data and you extend them to more uses.

You cannot outsource understanding. Even if you hire someone (like me) to build it, your team needs to understand what it does and why. If nobody can explain how the cart recovery agent decides, nobody can improve it, debug it or trust it. Handing over the knowledge matters as much as the code.

The businesses that do well with AI are not the ones with the most impressive models. They are the ones with the cleanest data, the most careful integration, and the discipline to start small and measure. It is not glamorous. It works.

Footnotes

  1. Freevacy, Gartner reveals 60% of AI projects with data issues will fail, 26 February 2025, reporting the Gartner press release Lack of AI-Ready Data Puts AI Projects at Risk of the same date, https://www.freevacy.com/news/gartner/gartner-reveals-60-of-ai-projects-with-data-issues-will-fail/6155

  2. Rachel Galvez, 2025 planning insights: data quality remains the top data integrity challenge, Precisely, 5 November 2024, on the 2025 Outlook: Data Integrity Trends and Insights report with Drexel University LeBow College of Business, https://www.precisely.com/blog/data-integrity/2025-planning-insights-data-quality-remains-the-top-data-integrity-challenges

  3. BARC, Data quality beats AI hype: BARC publishes the Data, BI and Analytics Trend Monitor 2026, 12 November 2025, https://barc.com/news/barc-publishes-the-data-bi-and-analytics-trend-monitor-2026/

  4. Solidus Guides, Subscribing to events, accessed November 2026, https://guides.solidus.io/customization/subscribing-to-events

  5. Anthropic, Introducing the Model Context Protocol, 25 November 2024, https://www.anthropic.com/news/model-context-protocol

  6. MCP Core Maintainers, MCP joins the Agentic AI Foundation, Model Context Protocol blog, 9 December 2025, https://blog.modelcontextprotocol.io/posts/2025-12-09-mcp-joins-agentic-ai-foundation/

  7. Model Context Protocol, Ruby SDK (the mcp gem), GitHub, accessed November 2026, https://github.com/modelcontextprotocol/ruby-sdk

  8. Regulation (EU) 2016/679 (General Data Protection Regulation), Article 5(1)(c), data minimisation, EUR-Lex, https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679

  9. Regulation (EU) 2016/679 (General Data Protection Regulation), Article 28, processor, EUR-Lex, https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679

  10. Data Protection Act 2018 (Ireland), section 10, establishment of the Data Protection Commission, Irish Statute Book, https://www.irishstatutebook.ie/eli/2018/act/7/section/10/enacted/en/html

  11. Data Protection Commission, AI, Large Language Models and Data Protection, 18 July 2024, https://www.dataprotection.ie/en/dpc-guidance/blogs/AI-LLMs-and-Data-Protection

  12. Arjun Kharpal, Samsung bans use of generative AI tools like ChatGPT after April internal data leak, CNBC, 2 May 2023, https://www.cnbc.com/2023/05/02/samsung-bans-use-of-ai-like-chatgpt-for-staff-after-misuse-of-chatbot.html

  13. Baymard Institute, Cart abandonment rate statistics, updated 28 October 2026, https://baymard.com/lists/cart-abandonment-rate

If you know AI could help but not where to start, bring your messiest data export and the workflow you would most like to fix to the free workshop. We will find the realistic first step together, and the first two weeks of work are on me.