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

# Data model

> Master data vs app-managed entities, the analytics layers, and the plan status enumerations.

Solya's data splits into **analytics data** (ingested, read-mostly, on Databricks) and
**app-managed data** (created in Solya, on PostgreSQL). See
[Architecture](/en/developers/architecture).

## Master data (ingested)

Catalog and transactional entities are populated by the data platform's ETL from POS
systems (Polaris, Kezia) and are **read-only** in the app. They are organization-scoped.

| Entity                                                            | Nature                          |
| ----------------------------------------------------------------- | ------------------------------- |
| Shops, brands, products, product variants, collections, suppliers | Catalog dimensions              |
| Inventory items                                                   | Product × shop stock identity   |
| Sales lines, order lines, movement lines                          | Transactional facts             |
| Stock ledger, stock snapshot                                      | Stock over time / point-in-time |

### Analytics layers

The data platform exposes these as **silver** (cleaned/normalized) and **gold**
(business-ready) tables — e.g. `fact_sales_lines`, `fact_order_lines`,
`fact_movement_lines`, `stock_ledger`, `stock_snapshot`, the `dim_*` dimensions,
`*_shop_analytics` summaries, `sales_forecasts`, and `decision_vector`. The app reads
these for dashboards, KPIs, search, alerts, and recommendations.

```mermaid theme={null}
graph LR
  subgraph analytics["Analytics Data (Databricks) — Read-Only"]
    direction TB
    pos["POS Systems<br/>(Polaris, Kezia)"]
    etl["ETL Pipeline"]
    silver["Silver Layer<br/>(normalized)"]
    gold["Gold Layer<br/>(business-ready)"]

    pos --> etl
    etl --> silver
    silver --> gold
  end

  subgraph app["App-Managed Data (PostgreSQL) — Created in Solya"]
    direction TB
    plans["Inventory Plans<br/>& Items"]
    rules["Business Rules<br/>& Rulesets"]
    budget["Budget Envelopes"]
    curves["Size Curves"]
    alerts["Alerts & Tags"]
    workflows["Workflows"]
    audit["Audit Log"]
  end

  gold -->|read| plans
  gold -->|read| rules
  gold -->|read| budget
  gold -->|read| alerts
  
  style analytics fill:#e8f5e9,stroke:#2e7d32,color:#000
  style app fill:#e3f2fd,stroke:#1565c0,color:#000
```

<Note>
  Because catalog data is ingested, you don't create shops/products/variants in the app —
  they arrive through ingestion. See the [Data layer](/en/data-layer/overview).
</Note>

## App-managed data (created in Solya)

Everything you create lives in PostgreSQL and is org-scoped: inventory plans and their
items, business rules and rulesets, budget envelopes, size curves, markdown calendars,
supplier constraints, approval/return policies, org lists, alerts, tags and tagging rules,
workflows, settings, navigation templates, and the audit log. Each new table documents how
its data is populated, modified, and access-controlled.

## Plan status enumerations

The exact statuses per plan type (used by the API and surfaced in the UI):

| Plan              | Statuses                                                    |
| ----------------- | ----------------------------------------------------------- |
| Restock           | `DRAFT → VALIDATED → SENT → RECEIVED → CLOSED`              |
| Rebalance         | `DRAFT → VALIDATED → SENT`                                  |
| Markdown          | `DRAFT → VALIDATED → CLOSED`                                |
| Pre-season        | `DRAFT → VALIDATED → SENT → CLOSED`                         |
| Supplier return   | `DRAFT → SENT → CREDITED → CLOSED`                          |
| Supplier exchange | `DRAFT → PROPOSED → AGREED → IN_TRANSIT → SETTLED → CLOSED` |

**Plan item status** is shared: `TO_REVIEW` and `READY_FOR_ORDER`. Supplier-side plans
carry extra enumerations — return **reason codes** (e.g. defect, transit damage, wrong
SKU/quantity, recall, QC fail, other), return **source types** (restock, pre-season), and
exchange **sides** (return, receive).

<Note>
  These status values are stable identifiers you can branch on. The conceptual lifecycle
  (reversible transitions, decision moments, approvals) is described in
  [Inventory plans → lifecycle](/en/inventory-plans/lifecycle).
</Note>
