> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sourcemedium.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# How SourceMedium models your data

> What happens to your raw platform data before it reaches your dashboards and warehouse: cleaning, enrichment, and the four table shapes.

SourceMedium takes the raw data from your connected platforms and turns it into one set of tables. Your dashboards, SourceMedium Agent, and your warehouse all read those same tables. This page explains what happens in between. [Data architecture](/docs/help-center/core-concepts/data-transformation/data-architecture) shows the same path as a diagram.

Cleaning is about quality, enrichment is about completeness, and modeling is about making the result easy to query.

## Cleaning

Every platform sends data in its own shape. Cleaning makes those shapes comparable.

* **One schema across sources.** Equivalent fields from different platforms get the same name and type, so a Shopify order and an Amazon order share the same columns in `obt_orders`. Names follow the [schema standards](/docs/data-transformations/naming-conventions/index).
* **Consistent identifiers.** IDs and keys use the same data type across sources, so joins do not fail silently.
* **Deductions stored as negatives.** Discounts and refunds are stored as negative numbers, so revenue math adds up without special cases. See [Revenue fields](/docs/help-center/core-concepts/data-definitions/revenue-fields).
* **Timestamps in UTC and local time.** Timestamps are delivered in UTC plus a `_local_datetime` version in your reporting timezone, for example `order_processed_at` and `order_processed_at_local_datetime`.
* **Lowercased categorical values.** Machine-generated text such as UTM values is lowercased and trimmed, so grouping is not case sensitive. See [UTM normalization](/docs/help-center/core-concepts/data-definitions/utm-normalization).
* **Automated checks.** Tests on the delivered tables confirm, for example, that keys are unique and that `sm_channel` only takes expected values.

## Enrichment

Once the data is clean, we add context that no single platform has.

* **Product costs.** SKU-level costs from your [cost configuration](/docs/data-inputs/configuration-sheet/costs/how-do-i-surface-product-costs) are joined to order lines, so profitability sits next to revenue.
* **Sales channel.** Every order gets an `sm_channel` and `sm_sub_channel`, from platform signals and your own [channel mapping rules](/docs/data-inputs/configuration-sheet/how-can-i-create-order-channels-and-subchannels). See [Sales channel](/docs/data-transformations/order-segmentation/sales-channel).
* **Order type.** Every order and order line is classified as subscription or one-time. See [Order type](/docs/data-transformations/order-segmentation/order-type).
* **Order attribution.** Last-click UTM evidence from Shopify, website analytics, referrers, and post-purchase surveys is collected into one table, [`fct_order_attribution_signals`](/docs/data-activation/data-tables/sm_transformed_v2/fct_order_attribution_signals). The winning source becomes the order's `sm_utm_*` fields. The [attribution source hierarchy](/docs/data-transformations/attribution-source-hierarchy) explains which source wins.
* **Customer demographics.** Age and gender are not in platform exports. See [Demographic data](/docs/help-center/core-concepts/demographics/demographic-data-sources) for what is available and how to add your own.
* **Media mix measurement.** When a measurement vendor is connected, its modelled attribution lands in [`rpt_media_mix_channel_daily`](/docs/data-activation/data-tables/sm_transformed_v2/rpt_media_mix_channel_daily) next to last-click and platform-reported figures.

## Table shapes

Every table name starts with a prefix that tells you what one row is.

| Prefix | One row is | Example |
| - | - | - |
| `fct_` | One event or transaction, with its measures | `fct_refunds_processed`: one refund line |
| `dim_` | One entity and its descriptive attributes, which can change over time | `dim_customers`: one customer |
| `obt_` | One entity with its facts and dimensions already joined | `obt_orders`: one order, with customer, channel, and attribution columns |
| `rpt_` | One reporting grain, pre-aggregated for a specific report | `rpt_executive_summary_daily`: one store, channel, sub-channel, and day |

Start with `obt_` tables. Use `fct_` and `dim_` tables when you need a grain the OBT does not have, and `rpt_` tables when the aggregation you want already exists. [Modeling](/docs/data-activation/managed-data-warehouse/modeling) shows how to build on them.

## Related

<CardGroup cols={2}>
  <Card title="Table docs" icon="table" href="/docs/data-activation/data-tables/sm_transformed_v2/index">
    Column-level schemas for every `sm_transformed_v2` table.
  </Card>

  <Card title="Data definitions" icon="book-open" href="/docs/help-center/core-concepts/data-definitions/index">
    Valid orders, revenue fields, refunds, and the other rules behind the numbers.
  </Card>

  <Card title="Data architecture" icon="sitemap" href="/docs/help-center/core-concepts/data-transformation/data-architecture">
    How data flows from your platforms to the tools you use.
  </Card>

  <Card title="Data freshness" icon="clock" href="/docs/help-center/core-concepts/data-transformation/data-freshness">
    When each source is fresh to the previous day.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.