# ADR-000: Discovery Baseline — magento-orderwebhook

> **Status:** Accepted
> **Date:** 2026-02-26 (Europe/London)
> **Author:** AI-assisted engineering review
> **Scope:** Read-only discovery audit — no code changes made

---

## Context

This ADR captures the discovered architecture state of `PortalPeople_OrderWebhook` as found during initial documentation audit. It records confirmed facts, unknowns, and follow-up actions required before the module can be considered fully documented and production-safe.

---

## Confirmed Facts

1. Module ID: `PortalPeople_OrderWebhook`. PSR-4 namespace: `PortalPeople\OrderWebhook\`.
2. Package version: `1.0.15` (composer.json) — `setup_version` in `module.xml` is `1.0.0` (conflict).
3. Purpose: Sends Magento order data as a JSON webhook to the NGauge platform on order placement and status change.
4. Two observers: `OrderPlaceAfter` (event: `sales_order_place_after`) and `OrderSaveAfter` (event: `sales_order_save_after`).
5. `OrderPlaceAfter` skips admin-created orders using `empty($order->getRemoteIp())`.
6. `OrderSaveAfter` fires only on status change TO `'processing'`.
7. `WebhookSender` is the single point of HTTP dispatch, retry logic, and persistence.
8. Static re-entrancy guard (`private static bool $sending = false`) prevents recursive observer loops.
9. Exponential backoff retry: `sleep(pow(2, $attempt))`, default 3 retries.
10. API key stored encrypted (`Magento\Config\Model\Config\Backend\Encrypted`); decrypted via `EncryptorInterface`.
11. `EncryptorInterface` is resolved via `ObjectManager::getInstance()` in `WebhookSender::sendRequest()` — anti-pattern.
12. `OrderDataBuilder` includes customer DOB and gender in the webhook payload (special-category/personal data sent to external system).
13. `shipping_date` and `shipping_message` sourced from magento-deliverydates; null if module absent.
14. Three columns added to `sales_order` via declarative schema: `ngauge_order_no`, `ngauge_order_id`, `ngauge_order_link`.
15. Single `orderRepository->save()` persists NGauge fields and order comment atomically.
16. `comment_only` mode: skips writing `ngauge_*` fields; adds NGauge response as order comment only.
17. Once `ngauge_order_id` is set, admin UI "Send to NGauge" button is hidden.
18. `ResendWebhook` admin controller (ACL: `PortalPeople_OrderWebhook::config`) sends `manual_resend` event.
19. CLI command `order:webhook:test [ORDER_ID]` sends `test_webhook` event, shows masked config.
20. `NgaugeFields` admin block uses deprecated `Magento\Framework\Registry`.
21. Default NGauge base URL: `https://ahshub.portalpeople.app`.
22. `composer.json` `extra.bootstrap` references `PortalPeople\\NgaugeBackupSql\\Module` — wrong namespace.
23. `src/README.md` incorrectly states `order_updated` fires on "processing, complete, or shipped" — code fires only on `'processing'`.
24. No PHPUnit tests or test configuration found.
25. Logging is PSR-3, conditional on `order_webhook/general/log_enabled`. Both observers wrap `execute()` in try/catch.

---

## Unknowns

1. `UNKNOWN — Requires Clarification`: What is the canonical version of this module? `composer.json` v1.0.15 vs `module.xml` `setup_version="1.0.0"`.
2. `UNKNOWN — Requires Clarification`: What is the correct `extra.bootstrap` value? Is it `PortalPeople\\OrderWebhook\\Module` or should the key be removed?
3. `UNKNOWN — Requires Clarification`: Are `shipping_date` and `shipping_message` methods always available on the order object in all deployment environments?
4. `UNKNOWN — Requires Clarification`: Is `comment_only` mode active in production?
5. `UNKNOWN — Requires Clarification`: Full NGauge API response schema — field names and types not confirmed from external documentation.
6. `UNKNOWN — Requires Clarification`: What is the legal basis (UK/EU GDPR) for transmitting customer DOB and gender to NGauge?
7. `UNKNOWN — Requires Clarification`: Is NGauge a data processor under a signed DPA?
8. `UNKNOWN — Requires Clarification`: Are partial card details (cc_last4, type, expiry) subject to PCI-DSS obligations in this context?
9. `UNKNOWN — Requires Clarification`: What log file does the PSR-3 logger write to?
10. `UNKNOWN — Requires Clarification`: Is there a staging NGauge environment for testing?
11. `UNKNOWN — Requires Clarification`: What happens when `EncryptorInterface` decryption fails? Is the exception caught?
12. `UNKNOWN — Requires Clarification`: Does `OrderSaveAfter` fire correctly for admin orders when status transitions to `processing` (depends on Magento `orig_data` being set on admin save)?

---

## Follow-up Actions

1. Align version strings: `composer.json`, `module.xml` `setup_version`, `src/README.md`.
2. Correct or remove `extra.bootstrap` reference in `composer.json`.
3. Replace `ObjectManager::getInstance()` in `WebhookSender::sendRequest()` with constructor injection.
4. Correct `src/README.md` — document accurate trigger conditions for `order_updated`.
5. Obtain NGauge API contract and document response schema in `docs/API.md`.
6. Document GDPR legal basis and DPA status for DOB/gender/card data transmission to NGauge in `docs/GDPR.md`.
7. Confirm whether magento-deliverydates is a required dependency; add soft dependency to `module.xml` if so.
8. Replace deprecated `Magento\Framework\Registry` in `NgaugeFields` block with layout argument injection.
9. Add PHPUnit tests for `WebhookSender` retry logic, `OrderDataBuilder`, and observer conditions.
10. Clarify `comment_only` mode expected production state; document in `docs/WORKFLOW.md`.

---

## Evidence

- `/modules/magento-orderwebhook/composer.json`
- `/modules/magento-orderwebhook/src/etc/module.xml`
- `/modules/magento-orderwebhook/src/etc/events.xml`
- `/modules/magento-orderwebhook/src/etc/db_schema.xml`
- `/modules/magento-orderwebhook/src/etc/config.xml`
- `/modules/magento-orderwebhook/src/etc/di.xml`
- `/modules/magento-orderwebhook/src/etc/adminhtml/system.xml`
- `/modules/magento-orderwebhook/src/Observer/OrderPlaceAfter.php`
- `/modules/magento-orderwebhook/src/Observer/OrderSaveAfter.php`
- `/modules/magento-orderwebhook/src/Model/WebhookSender.php`
- `/modules/magento-orderwebhook/src/Model/OrderDataBuilder.php`
- `/modules/magento-orderwebhook/src/Controller/Adminhtml/Order/ResendWebhook.php`
- `/modules/magento-orderwebhook/src/Console/Command/TestWebhookCommand.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/README.md`
