# Data Model

## テーブル構造

```
sot.products (商品マスター)
  ├─ id (uuid) PK
  ├─ shop + barcode (UNIQUE) ← 受注・在庫との結合キー
  ├─ product_name, sku, variant_name, brand, category_l1/l2/l3
  ├─ current_price, current_compare_at_price, current_cost, currency
  │
  ├──< sot.product_update_logs (変更ログ)
  │     └─ change_type: created / updated (+ changed_fields)
  │
  └──< sot.inventory_levels (在庫)
        ├─ product_id FK → products.id
        ├─ location_id FK → locations.id
        ├─ on_hand_qty, available_qty, allocated_qty, reserved_qty, incoming_qty
        │
        └──< sot.inventory_update_logs (変更ログ)
              └─ change_type: snapshot / available_set / available_delta

sot.locations (拠点マスター)
  ├─ id (uuid) PK
  ├─ display_label, location_type, region
  └─ ec_fulfillable, is_active

sot.order_line_master (受注 / 1 row = 1 販売単位)
  ├─ barcode ──結合──> products.barcode
  ├─ channel_id ──> channels.id, location_id ──> locations.id
  └─ net_amount_taxincl, tax_amount, refund_amount, ...

sot.inventory_daily_snapshots (日次スナップショット)
  └─ snapshot ingest が当日行を upsert ＋ 日次 rollup cron で確定

sot.lm_fulfillment_source_members (出荷元 → 在庫ロケーション 紐付け / 1:N)
  └─ UNIQUE (shop, inventory_location_id) ← 在庫ロケーションは1出荷元のみ

sot.lm_routing_orders (受注ルーティングの注文ヘッダ / routing-native)
  ├─ UNIQUE (shop, source_system, external_order_ref) ← 入口冪等
  ├─ status: received / routed / dispatched / failed / no_stock
  │
  ├──< sot.lm_routing_decisions (unit 単位の判定結果, decision_status=applied)
  │     ├─ fulfillment_source_location_id=指定出荷元 / selected_location_id=引き当て先在庫ロケーション
  │     ├─ oversold / superseded_by_decision_id ← 売越し・再引き当て
  │     └──< sot.lm_routing_candidates (拠点別スコア snapshot / 除外理由)
  │
  └──< sot.lm_shipping_instructions (出荷指示 dispatch ログ)
        └─ UNIQUE (shop, idempotency_key) ← 出口冪等
           delivery_status: pending / sent / failed / skipped
```

## テーブル一覧

| Schema | Table                           | Description                    |
| ------ | ------------------------------- | ------------------------------ |
| `sot`  | `products`                      | 商品マスター（1 row = 1 barcode）      |
| `sot`  | `product_identifiers`           | 商品識別子（shopify\_variant\_id 等）  |
| `sot`  | `product_update_logs`           | 商品変更ログ（created / updated）      |
| `sot`  | `inventory_levels`              | 在庫マスター（1 row = 1 商品 × 1 拠点）    |
| `sot`  | `inventory_update_logs`         | 在庫変更ログ                         |
| `sot`  | `inventory_daily_snapshots`     | 在庫日次スナップショット                   |
| `sot`  | `locations`                     | 拠点マスター                         |
| `sot`  | `location_identifiers`          | 拠点識別子                          |
| `sot`  | `customers`                     | 顧客マスター                         |
| `sot`  | `customer_identifiers`          | 顧客識別子                          |
| `sot`  | `order_line_master`             | 受注（1 row = 1 販売単位）             |
| `sot`  | `order_line_master_update_logs` | 受注変更ログ                         |
| `sot`  | `lm_fulfillment_source_members` | 出荷元 → 在庫ロケーション 紐付け（1:N）        |
| `sot`  | `lm_routing_orders`             | 受注ルーティングの注文ヘッダ（routing-native） |
| `sot`  | `lm_routing_decisions`          | ルーティング判定結果（unit 単位）            |
| `sot`  | `lm_routing_candidates`         | ルーティング候補スコア snapshot           |
| `sot`  | `lm_shipping_instructions`      | 出荷指示 dispatch ログ               |

read は `agent_read.*` の safe view 経由（`products` / `inventory_levels` / `inventory_daily_snapshots` / `inventory_update_logs` / `product_update_logs` / `order_line_master`）。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lmile.gitbook.io/lmile-docs/reference/data-model.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
