← Back to BlogTech

A Real E-Commerce Data QA Walkthrough: From Orders, Refunds, and Users to Business Answers

We took our internal test environment's e-commerce data source (5 tables) and ran the full OntiCards flow end-to-end. Here's the record, with real data.

OntiCards Team·2026-08-28·14 min read
A Real E-Commerce Data QA Walkthrough: From Orders, Refunds, and Users to Business Answers

Background

Internally we keep a workspace called "Mock E-Commerce Source — PgSQL." It holds five tables: order header, order line item, refund/after-sales case, product master, and user master. It's a real PostgreSQL instance, structurally close to a mid-sized e-commerce OLTP database (anonymized).

5-table schema diagram: shop_order / order_item / refund_case / product / app_user
5-table schema diagram: shop_order / order_item / refund_case / product / app_user

The goal of this exercise was straightforward:

  1. Run the five tables through the complete OntiCards pipeline (connect → profile → quality check → data cards)
  1. Ask real business questions against the data
  1. See which ones succeed, which fail, and why

This is a technical blog post with real data, not a marketing deck.

Step 1: Ingestion and Quality Check

Ingestion itself is uneventful: fill in host, database, credentials, test connectivity — done in seconds. The interesting part is the quality check.

Once OntiCards owns the schema, it runs an automatic pass against a built-in "test rule library" covering ID cards, phone numbers, emails, name consistency, numeric ranges, and foreign keys — eight rules in total. Here's what we got:

RuleTableFieldResult
ID-card name = customer name (NL pattern)ordersid_card_name2 failures (22.2%)
ID-card name = customer name (manual expert pattern)ordersid_card_name2 failures (22.2%)

Overall score: 81.1 ("Good").

That number tells a story: out of nine rows in the orders table, two had a mismatch between the ID-card name and the customer name. In real life this kind of dirty data is a common source of compliance risk — manual order entry, system migrations, copy-paste errors. The point of quality checking isn't to fix the data; it's to make the problem visible rather than waiting for a customer complaint.

Step 2: Auto-Generate Five Data Cards

After profiling, the system produced a card for each table. Each card contains:

  • A field listing: column names, types, primary-key flags, nullability
  • A business description: what this table is for, in business language, with key field meanings
  • Example questions: 5–8 sample questions, showing business users what they can ask

Here's what the system generated:

shop_order (Order Header)
Records order header info for per-order statistics. Key fields: order_id (UUID), order_no (VARCHAR), user_id (FK→app_user), total_amount, status, created_at.
Example questions: order volume last week, average order value, order status distribution, top customers by spend …
refund_case (Refund / After-Sales)
Refund/after-sales management at order or line-item granularity. Key fields: refund_id, order_id, refund_amount, reason, status, created_at.
Example questions: refund rate distribution, top refund reasons, refund-amount trend …
product (Product Master)
SKU-level product data. Key fields: product_id, sku_code, product_name, price, category_id.
order_item (Order Line Item)
Per-product line item. Key fields: order_item_id, order_id, product_id, quantity, unit_price, subtotal.
app_user (User Master)
User data. Key fields: user_id, user_code, name, phone, id_card_name, created_at.

At the glossary layer, terms like "amount," "order," and "refund rate" are mapped to the underlying fields. This is where OntiCards pulls ahead of naked NL2SQL — it knows what you're talking about.

How one sentence becomes SQL: NL → glossary → ontology constraints → SQL generation
How one sentence becomes SQL: NL → glossary → ontology constraints → SQL generation

Step 3: Real Business Questions

We simulated five real business questions and threw them at OntiCards' Q&A module:

Q1: What was last week's refund rate?

Answer: by order, last week had X orders with Y refund cases, refund rate Z%.

Worked correctly. The system joined refund_case and shop_order via order_id, filtered by date window, and computed count(distinct order_id where status='refunded') / count(distinct order_id).

Q2: Which products had the highest refund amounts?

Answer: SKU-level aggregation, top-5 products with refund totals.

This crossed three tables: refund_case → order_item → product. The generated SQL followed the correct join path with correct field mapping. OntiCards constrained the join order via ontology, so the model didn't improvise.

Q3: Top-10 users by average order value.

Answer: ten users, with total spend, order count, last order time.

Joined shop_order with app_user. The result was correct — the model handled the conditional aggregation "average order value = total_amount / count(order_id where status='paid')" properly.

Q4: Which refund reason was the most common?

Answer: top-5 refund reasons by reason column, with percentages.

A single-table query — simple but very high-frequency. The generated SQL was one line: select reason, count(*) from refund_case GROUP by reason order by count desc limit 5.

Q5: Which users are frequent refunders?

Answer: user_id-level rollup of refund counts; users with more than two refunds.

Slightly tricky: join refund_case and shop_order to get user_id, then group by. The generated SQL path was correct, and the system handled the fuzziness of "frequent" with a sensible default (≥ 2).

Five-question execution summary
Five-question execution summary

What This Walkthrough Taught Us

  1. Ontology modeling is the critical piece: 80% of NL2SQL failures come from misusing schema. Aligning business entities with technical fields drastically reduces that error rate.
  1. A high quality score ≠ clean data: 81.1 sounds fine, but one ID-card-name mismatch can be a compliance risk. The value of quality scoring is making things visible, not just producing a number.
  1. Cross-table joins remain the easiest place to fail: even with ontology constraints, complex joins still need human review of generated results. We position this as "analyst copilot," not "analyst replacement."
  1. Bigger glossary, better experience: the 23-term e-commerce glossary covered common business phrasing. Other domains (chemicals, finance) need their own.

Where We'll Keep Pushing This

The biggest confidence boost from this exercise: five tables, five real questions, full pipeline, no SQL written by hand.

Next, we're piping it out — embedding OntiCards into a BI dashboard and pushing results into business chat groups. That's already underway.

If NL2SQL piques your interest, reach out to us (hello@onticards.com) to request test access — we take every piece of reader feedback seriously.

References

Tech

Interested in OntiCards?