# External System Gateway Refinement — Design

**Date**: 2026-03-16
**Component**: External System Gateway (`docs/requirements/Component-ExternalSystemGateway.md`)
**Status**: Approved

## Problem

The External System Gateway doc lacked specification for the invocation protocol, authentication methods, call timeouts, error classification for store-and-forward decisions, and database connection management.

## Decisions

### Invocation Protocol
- **HTTP/REST only** with **JSON** serialization. The ESG is an HTTP client with predefined endpoints.
- Method definitions include HTTP method (GET/POST/PUT/DELETE) and relative path.
- Parameters serialized as JSON body (POST/PUT) or query parameters (GET/DELETE).

### Outbound Authentication
- Two modes per external system definition:
  - **API Key**: Configurable header name and key value.
  - **Basic Auth**: Username and password, sent as standard HTTP Authorization header.

### Call Timeouts
- **Per-system timeout** — one timeout value applies to all methods on a given external system.
- Defined in the external system definition.

### Dual Call Modes
- **`ExternalSystem.Call()`**: Synchronous request/response. All failures (transient and permanent) return to the script. No S&F buffering. Use when the script needs the result.
- **`ExternalSystem.CachedCall()`**: Fire-and-forget with S&F on transient failure. Use for outbound data pushes where deferred delivery is acceptable.
- Mirrors the existing `Database.Connection()` / `Database.CachedWrite()` pattern.

### Error Classification
- **Transient failures** (connection errors, timeouts, HTTP 5xx): `CachedCall` buffers for retry; `Call` returns error to script.
- **Permanent failures** (HTTP 4xx): Always returned to the calling script regardless of call mode. Logged to Site Event Logging.
- S&F buffer only accepts transient failures to avoid accumulating unrecoverable requests.

### Database Connection Pooling
- Standard ADO.NET connection pooling per named connection. No custom pool logic.
- Pool tuning via connection string parameters if needed.

### Serialization
- JSON only, consistent with REST-only decision.

## Affected Documents

| Document | Change |
|----------|--------|
| `docs/requirements/Component-ExternalSystemGateway.md` | Updated External System Definition fields. Added sections: External System Call Modes (dual-mode API), Invocation Protocol, Call Timeout & Error Handling, Database Connection Management. |
| `docs/requirements/Component-StoreAndForward.md` | Clarified that only transient failures are buffered; 4xx errors are not queued. |
| `docs/requirements/Component-SiteRuntime.md` | Updated Script Runtime API with `ExternalSystem.Call()` and `ExternalSystem.CachedCall()`. |
| `docs/requirements/HighLevelReqs.md` | Updated script capabilities (Section 4.4) to reflect dual call modes. |

## Alternatives Considered

- **SOAP support**: Rejected — REST covers modern integrations; SOAP systems can be fronted by a thin REST wrapper.
- **OAuth2 client credentials**: Rejected — adds token lifecycle complexity at every site for marginal benefit; can be handled by a gateway/proxy.
- **Per-method timeouts**: Rejected — external systems tend to have consistent latency; per-system is the right granularity.
- **All failures retryable**: Rejected — retrying 4xx errors pollutes the S&F buffer with requests that will never succeed.
- **Custom connection pooling**: Rejected — ADO.NET pooling is battle-tested and handles this scenario natively.
- **XML serialization option**: Rejected — JSON-only is consistent with REST-only; XML systems can use a wrapper.
- **Per-method sync/cached flag**: Rejected — the same method may need synchronous calls in one script and cached in another. Script author chooses per invocation.
