{
  "version": 1,
  "state": "002-edge-proxy-uncontainerized",
  "title": "Give the browser one entry point",
  "purpose": "A browser should not need to know where every backend lives. For developers who have traced the baseline workflow, this chapter uses a reverse proxy to establish one public entry point and investigates why REST traffic and streaming traffic need separate attention.",
  "entryAssumptions": "The baseline exposes services on separate local ports.",
  "concepts": [
    "An origin is a scheme, host and port. A reverse proxy forwards requests; a WebSocket upgrade keeps a streaming connection open."
  ],
  "runtimePrerequisites": "Use the state quickstart for tool versions, generation, start and stop commands. Run one local state at a time because ports and generated output directories are shared.",
  "entryMode": "combined",
  "transitions": [
    {
      "from": "001-baseline-uncontainerized-parity",
      "carriesForward": "Trace the browser, trade service, event transport, processor, database and position view as one business workflow.",
      "motivation": "The baseline exposes services on separate local ports.",
      "increment": "Route UI, REST and streaming traffic through one NGINX edge while retaining the baseline business flow.",
      "objectiveIds": [
        "trace-increment",
        "interpret-evidence"
      ],
      "evidence": "The browser uses one public origin while NGINX forwards to several services. A working account request alone does not establish that streaming upgrades work. Routing and business processing fail at different boundaries. A live HTTP endpoint does not establish a healthy event path."
    }
  ],
  "before": "The baseline exposes services on separate local ports.",
  "after": "Route UI, REST and streaming traffic through one NGINX edge while retaining the baseline business flow.",
  "objectives": [
    {
      "id": "trace-increment",
      "outcome": "Map an account request and a streaming connection from the browser\u2019s public origin to their separate upstream services."
    },
    {
      "id": "interpret-evidence",
      "outcome": "Explain the evidence boundary: Routing and business processing fail at different boundaries. A live HTTP endpoint does not establish a healthy event path."
    }
  ],
  "walkthrough": [
    {
      "id": "observe",
      "objectiveIds": [
        "trace-increment"
      ],
      "availability": "available",
      "action": "Open the proxied UI at the address in the quickstart. In browser Network tools reload accounts, submit a trade and inspect the streaming connection. Compare the public request paths with the upstream services in the topology.",
      "expected": "The browser uses one public origin while NGINX forwards to several services. A working account request alone does not establish that streaming upgrades work.",
      "references": [
        "/specs/edge-proxy-uncontainerized/quickstart",
        "/specs/edge-proxy-uncontainerized/system/architecture",
        "/specs/edge-proxy-uncontainerized/system/runtime-topology"
      ]
    },
    {
      "id": "challenge",
      "objectiveIds": [
        "interpret-evidence"
      ],
      "availability": "available",
      "action": "In Network tools compare a normal REST response with the streaming connection handshake. If the blotter does not update, check the upstream service and proxy routing separately before retrying the trade.",
      "expected": "Routing and business processing fail at different boundaries. A live HTTP endpoint does not establish a healthy event path.",
      "references": [
        "/specs/edge-proxy-uncontainerized/spec"
      ]
    }
  ],
  "assessments": [
    {
      "objectiveIds": [
        "trace-increment",
        "interpret-evidence"
      ],
      "question": "Which connection would you inspect when accounts load but the trade blotter stops updating?",
      "guidance": "Identify the streaming route and upgrade behavior, and distinguish it from the account REST route. Explain which upstream logs would narrow the failure."
    }
  ],
  "limitations": [
    "Routing and business processing fail at different boundaries. A live HTTP endpoint does not establish a healthy event path.",
    "This is an educational local demonstration. Passing its checks does not establish production readiness, financial settlement, or correctness under every failure mode."
  ],
  "coaching": [
    {
      "objectiveIds": [
        "trace-increment",
        "interpret-evidence"
      ],
      "diagnosticQuestion": "How did the baseline browser find each backend, and what constitutes an origin?",
      "predictionPrompt": "Predict whether a successful account request establishes that streaming updates will also work.",
      "hints": [
        "Compare the browser-visible host and path for the REST and streaming connections.",
        "Inspect the WebSocket handshake and its upstream route separately from a normal REST response."
      ],
      "misconception": "One working route proves every connection through the proxy is healthy.",
      "evidenceToRequest": "Ask for the two observed connection paths and handshake/result, and an explanation of the corresponding upstream services."
    }
  ]
}
