# Data Ownership — magento-orderwebhook

> **Last verified:** 2026-02-26 (Europe/London)
> **Owner:** Engineering
> **Related:** [GDPR.md](GDPR.md) | [BOUNDARIES.md](BOUNDARIES.md)

---

## Data Ownership Summary

| Entity | System of Record | Writes Here | Reads Here | Notes |
|--------|------------------|------------|------------|-------|
| `sales_order` (core) | Magento Sales Module | Magento Sales | This module (reads order fields for payload) | This module does NOT own the order row |
| `ngauge_order_no` column | NGauge (originator) / This module (storage) | `WebhookSender::persistOrder()` | `NgaugeFields` block, admin template | Written after NGauge responds |
| `ngauge_order_id` column | NGauge (originator) / This module (storage) | `WebhookSender::persistOrder()` | `NgaugeFields` block, admin template | Presence gates resend button visibility |
| `ngauge_order_link` column | NGauge (originator) / This module (storage) | `WebhookSender::persistOrder()` | `NgaugeFields` block, admin template | Deep-link URL |
| `core_config_data` (module config) | This module | Magento admin save | `WebhookSender`, `TestWebhookCommand` | API key stored encrypted |

---

## DB Schema — Added Columns

This module adds 3 nullable columns to the Magento-owned `sales_order` table via declarative schema.

**Table:** `sales_order`
**Schema file:** `/modules/magento-orderwebhook/src/etc/db_schema.xml`

| Column | Type | Nullable | Default | Notes |
|--------|------|----------|---------|-------|
| `ngauge_order_no` | varchar(255) | YES | NULL | NGauge order number |
| `ngauge_order_id` | varchar(255) | YES | NULL | NGauge internal order ID |
| `ngauge_order_link` | text | YES | NULL | NGauge deep-link URL |

No indexes added on these columns.

---

## PII and Special-Category Data

### Data Sent in Webhook Payload

| Field | Category | Source | Sent To | Legal Basis Documented |
|-------|----------|--------|---------|------------------------|
| Customer email | Personal data (PII) | `sales_order` | NGauge Platform | `UNKNOWN — Requires Clarification` |
| Customer first/last name | Personal data (PII) | `sales_order` | NGauge Platform | `UNKNOWN — Requires Clarification` |
| Customer DOB | Special-category / sensitive personal data | `customer_entity` | NGauge Platform | `UNKNOWN — Requires Clarification` |
| Customer gender | Personal data | `customer_entity` | NGauge Platform | `UNKNOWN — Requires Clarification` |
| Billing address (incl. telephone) | Personal data (PII) | `sales_order` | NGauge Platform | `UNKNOWN — Requires Clarification` |
| Shipping address (incl. telephone) | Personal data (PII) | `sales_order` | NGauge Platform | `UNKNOWN — Requires Clarification` |
| Payment cc_last4 / type / exp | Financial data (partial) | `sales_payment` | NGauge Platform | `UNKNOWN — Requires Clarification` |
| IP address | Personal data (if identifiable) | `sales_order.remote_ip` | Not explicitly sent in payload (used only to detect admin orders) | N/A |

### Data Stored Locally

| Field | Category | Table | Retention |
|-------|----------|-------|-----------|
| `ngauge_order_no` | Non-personal | `sales_order` | Follows Magento order retention — `UNKNOWN — Requires Clarification` |
| `ngauge_order_id` | Non-personal | `sales_order` | Follows Magento order retention — `UNKNOWN — Requires Clarification` |
| `ngauge_order_link` | Non-personal | `sales_order` | Follows Magento order retention — `UNKNOWN — Requires Clarification` |

---

## Invariants

- `WebhookSender::persistOrder()` is the **only** code path that writes `ngauge_*` columns.
- A single `orderRepository->save()` call is used for both NGauge field updates and order comment attachment — prevents double-save and ensures atomic persistence.
- When `comment_only` mode is enabled, `ngauge_*` columns are never written; only an order history comment is added.
- The `ngauge_order_id` column presence gates the admin "Send to NGauge" button — if it is set, the button is hidden.

---

## Data Retention

`UNKNOWN — Requires Clarification`: No data retention policy is defined within this module for the `ngauge_*` columns. They persist as long as the parent `sales_order` row exists. Magento does not automatically archive or purge orders by default.

---

## Confirmed Facts

- Three columns added to `sales_order` via `db_schema.xml` (declarative schema).
- No new tables are created by this module.
- Customer DOB and gender are transmitted to NGauge (external system) via the webhook payload.
- API key is stored encrypted in Magento `core_config_data`.

---

## Unknowns

1. `UNKNOWN — Requires Clarification`: What is the legal basis (under UK/EU GDPR) for transmitting customer DOB and gender to NGauge?
2. `UNKNOWN — Requires Clarification`: Is NGauge a data processor under a signed DPA (Data Processing Agreement)?
3. `UNKNOWN — Requires Clarification`: What data retention policy applies to NGauge data stored within `sales_order`?
4. `UNKNOWN — Requires Clarification`: Are partial card details (cc_last4, type, expiry) subject to PCI-DSS obligations in this context?

---

## Evidence

- `/modules/magento-orderwebhook/src/etc/db_schema.xml`
- `/modules/magento-orderwebhook/src/Model/WebhookSender.php`
- `/modules/magento-orderwebhook/src/Model/OrderDataBuilder.php`
- `/modules/magento-orderwebhook/src/Block/Adminhtml/Order/NgaugeFields.php`
- `/modules/magento-orderwebhook/src/view/adminhtml/templates/order/view/ngauge_fields.phtml`
- `/modules/magento-orderwebhook/src/etc/adminhtml/system.xml`
