# Domain Health Diagnostic Tool The Domain Health tool simulates the middleware resolution pipeline for every configured store access method, verifying that each domain, subdomain, and path-based route resolves to the expected store. ## Overview | Aspect | Detail | |--------|--------| | Location | Admin > Diagnostics > Resolution > Domain Health | | URL | `/admin/platform-debug` (select "Domain Health" in sidebar) | | API Endpoint | `GET /api/v1/admin/debug/domain-health` | | Access | Super admin only | ## What It Checks The tool runs four categories of checks against the **live database**: ### 1. Custom Subdomains (StorePlatform) Checks every active `StorePlatform` entry that has a `custom_subdomain` set. | Example | What It Tests | |---------|--------------| | `acme-rewards.rewardflow.lu` | Does `detection_method=subdomain` with `custom_subdomain` + platform context resolve to the expected store? | This is the most critical check because the fail-closed routing policy means a custom subdomain that doesn't resolve will return a 404 rather than falling back to a global lookup. ### 2. Default Subdomains per Platform Checks every active store's default `subdomain` on each platform it belongs to. | Example | What It Tests | |---------|--------------| | `acme.omsflow.lu` | Does `detection_method=subdomain` with `Store.subdomain` + platform context resolve to the expected store? | The middleware first tries `StorePlatform.custom_subdomain`, then falls back to `Store.subdomain` — but **only** if the store has an active `StorePlatform` membership on the detected platform. A store with no membership on that platform will be blocked (fail-closed, prevents cross-tenant leaks). Entries where `custom_subdomain` already equals the store's `subdomain` are de-duplicated (covered by check #1). ### 3. Custom Domains (StoreDomain) Checks every active, verified `StoreDomain` entry. | Example | What It Tests | |---------|--------------| | `wizatech.shop` | Does `detection_method=custom_domain` resolve to the store that owns the domain? | The Platform column shows the platform associated with the `StoreDomain.platform_id` relationship. ### 4. Path-Based Routes Checks every active store's `subdomain` field via path-based resolution. | Example | What It Tests | |---------|--------------| | `/storefront/luxweb/` | Does `detection_method=path` with `subdomain=luxweb` resolve to the correct store? | | `/store/luxweb/` | Same check for the store dashboard path | The Platform column shows all platforms the store is a member of (via `StorePlatform`). !!! note "Path segments use Store.subdomain" Path-based URLs use the store's `subdomain` field, **not** `store_code`. For example, a store with `store_code=LUXWEBSITES` and `subdomain=luxweb` is accessed at `/storefront/luxweb/`, not `/storefront/LUXWEBSITES/`. ## How It Works The tool calls the **same resolution functions** that the live middleware uses: ```mermaid graph LR A[Health Check] -->|builds context dict| B[StoreContextManager.get_store_from_context] B -->|queries DB| C[Store resolved?] C -->|id matches expected| D[PASS] C -->|mismatch or None| E[FAIL] ``` It does **not** make actual HTTP requests. This means it validates database configuration and resolution logic, but cannot detect: - DNS misconfigurations - Reverse proxy / Cloudflare routing issues - SSL certificate problems - Network-level failures ## Reading the Results ### Summary Bar | Counter | Meaning | |---------|---------| | Total Checked | Number of access methods tested | | Passed | Resolved to the expected store | | Failed | Resolution mismatch or store not found | ### Results Table | Column | Description | |--------|-------------| | Status | `pass` or `fail` badge | | Domain | The domain, subdomain, or path being tested | | Type | `custom subdomain`, `default subdomain`, `custom domain`, `path (storefront)`, or `path (store)` | | Platform | Platform code(s) the entry belongs to | | Expected Store | The store code we expect to resolve | | Resolved Store | The store code that actually resolved (or `--` if none) | | Note | Error description for failed entries | ### Common Failure Scenarios | Symptom | Likely Cause | |---------|-------------| | Custom subdomain fails | `StorePlatform.custom_subdomain` doesn't match or `StorePlatform.is_active=false` | | Default subdomain fails | Store has no active `StorePlatform` membership on the detected platform (cross-tenant blocked) | | Custom domain fails | `StoreDomain` not verified, inactive, or store is inactive | | Path-based fails | Store's `subdomain` field is empty or store is inactive | | Resolved store differs from expected | Two stores have conflicting subdomain/domain entries | ## API Response ``` GET /api/v1/admin/debug/domain-health ``` ```json { "total": 36, "passed": 30, "failed": 6, "details": [ { "domain": "acme-rewards.rewardflow.lu", "type": "custom subdomain", "platform_code": "loyalty", "expected_store": "ACME", "resolved_store": "ACME", "status": "pass", "note": "" }, { "domain": "acme.omsflow.lu", "type": "default subdomain", "platform_code": "oms", "expected_store": "ACME", "resolved_store": "ACME", "status": "pass", "note": "" }, { "domain": "/storefront/acme/", "type": "path (storefront)", "platform_code": "oms, loyalty", "expected_store": "ACME", "resolved_store": "ACME", "status": "pass", "note": "" } ] } ``` ## Related Documentation - [Middleware Stack](../../architecture/middleware.md) - Full middleware pipeline reference - [Dev Tools Module](../../modules/dev_tools/index.md) - Other diagnostic tools - [Multi-Tenant System](../../architecture/multi-tenant.md) - Tenant detection architecture