# Configuration And Contract Examples

The examples below are illustrative. Values such as signatures, payload hashes,
and FlatBuffers payload bytes are placeholders unless explicitly stated
otherwise.

## Example `.env`

The repository also includes a ready-to-copy sample file:

- [`../.env.example`](../.env.example)

The sample keeps all secrets blank and shows only the settings needed to boot
the process and expose the main listeners.

## Public Auth HTTP Examples

Start an e-mail challenge:

```bash
curl -X POST http://127.0.0.1:8080/api/v1/public/auth/send-email-code \
  -H 'Content-Type: application/json' \
  -d '{"email":"pilot@example.com"}'
```

Example response:

```json
{
  "challenge_id": "challenge-123"
}
```

Confirm the challenge and register the device public key:

```bash
curl -X POST http://127.0.0.1:8080/api/v1/public/auth/confirm-email-code \
  -H 'Content-Type: application/json' \
  -d '{
    "challenge_id": "challenge-123",
    "code": "123456",
    "client_public_key": "11qYAYdk8v3K6Yw8QK6ZlQ2nP4Wm8Cq5g1H0K8vT9no=",
    "time_zone": "Europe/Kaliningrad"
  }'
```

Example response:

```json
{
  "device_session_id": "device-session-123"
}
```

## Authenticated gRPC Envelope Examples

The authenticated transport is gRPC/protobuf, not JSON over HTTP. The examples
below use protobuf-style JSON only to make the logical envelope readable.
`bytes` fields are shown as base64 strings, matching the standard protobuf JSON
mapping.

Example `ExecuteCommandRequest`:

```json
{
  "protocolVersion": "v1",
  "deviceSessionId": "device-session-123",
  "messageType": "fleet.move",
  "timestampMs": "1775121600000",
  "requestId": "request-123",
  "payloadBytes": "RkxBVEJVRkZFUlNfUEFZTE9BRA==",
  "payloadHash": "5fY6Q8V9mK8x2B7v6v0V0m0i1rQ2QF0rQ8V1Yt1r8Ys=",
  "signature": "3o4v8f3h0Y6I0x1bS7zY+8m0bV1Lk4D3yq8J2n8F1rD7yK9v8M1Q0w2s4a6f8d0Q0m3L6y8R1t5w7x9z0a2cA==",
  "traceId": "trace-123"
}
```

Example `ExecuteCommandResponse`:

```json
{
  "protocolVersion": "v1",
  "requestId": "request-123",
  "timestampMs": "1775121600123",
  "resultCode": "ok",
  "payloadBytes": "RkxBVEJVRkZFUlNfUkVTUE9OU0U=",
  "payloadHash": "wL4n8H1aR2x3M4b5C6d7E8f9G0h1J2k3L4m5N6o7P8Q=",
  "signature": "2Xb7l9m0n1p2q3r4s5t6u7v8w9x0y1z2A3B4C5D6E7F8G9H0J1K2L3M4N5O6P7Q8R9S0T1U2V3W4X5Y6Z7a8b9cQ=="
}
```

Example authenticated self-service request metadata:

```json
{
  "protocolVersion": "v1",
  "deviceSessionId": "device-session-123",
  "messageType": "user.account.get",
  "timestampMs": "1775121600000",
  "requestId": "request-account-123",
  "payloadBytes": "RkxBVEJVRkZFUlNfVVNFUl9SRVFVRVNU",
  "payloadHash": "5fY6Q8V9mK8x2B7v6v0V0m0i1rQ2QF0rQ8V1Yt1r8Ys=",
  "signature": "3o4v8f3h0Y6I0x1bS7zY+8m0bV1Lk4D3yq8J2n8F1rD7yK9v8M1Q0w2s4a6f8d0Q0m3L6y8R1t5w7x9z0a2cA=="
}
```

The external payload remains FlatBuffers. The current `Gateway -> User`
self-service adapter decodes that payload, calls the trusted internal
User Service REST API, then re-encodes the returned account aggregate or error
envelope back into FlatBuffers before signing the response.

Example bootstrap `GatewayEvent` sent after `SubscribeEvents` opens:

```json
{
  "eventType": "gateway.server_time",
  "eventId": "request-123",
  "timestampMs": "1775121600456",
  "payloadBytes": "RkxBVEJVRkZFUlNfU0VSVkVSX1RJTUU=",
  "payloadHash": "2b1U3m4N5p6Q7r8S9t0U1v2W3x4Y5z6A7b8C9d0E1f2=",
  "signature": "4Nf8k2p6s0w4y8A2d6g0j4m8p2t6w0z4C8F2I6L0O4R8U2X6a0d4g8j2m6p0s4v8yA2d6g0j4m8p2t6w0z4C8F2I6A==",
  "requestId": "request-123",
  "traceId": "trace-123"
}
```

## Redis Examples

### Session Cache Record

Example Redis key and JSON value used by the fallback session cache:

```text
gateway:session:device-session-123
```

```json
{
  "device_session_id": "device-session-123",
  "user_id": "user-123",
  "client_public_key": "11qYAYdk8v3K6Yw8QK6ZlQ2nP4Wm8Cq5g1H0K8vT9no=",
  "status": "active"
}
```

### Session Event Stream Entry

Example session snapshot entry:

```bash
redis-cli XADD gateway:session_events '*' \
  device_session_id device-session-123 \
  user_id user-123 \
  client_public_key 11qYAYdk8v3K6Yw8QK6ZlQ2nP4Wm8Cq5g1H0K8vT9no= \
  status active
```

Revocation entry:

```bash
redis-cli XADD gateway:session_events '*' \
  device_session_id device-session-123 \
  user_id user-123 \
  client_public_key 11qYAYdk8v3K6Yw8QK6ZlQ2nP4Wm8Cq5g1H0K8vT9no= \
  status revoked \
  revoked_at_ms 1775121700000
```

### Client Event Stream Entry

User-wide event:

```bash
redis-cli XADD gateway:client-events '*' \
  user_id user-123 \
  event_type game.turn.ready \
  event_id notification-route-123 \
  payload_bytes flatbuffers-game-turn-ready
```

Session-targeted event with correlation:

```bash
redis-cli XADD gateway:client-events '*' \
  user_id user-123 \
  device_session_id device-session-123 \
  event_type fleet.updated \
  event_id event-124 \
  payload_bytes payload-v2 \
  request_id request-123 \
  trace_id trace-123
```

Notes:

- `payload_bytes` in Redis Stream entries must be binary-safe payload data;
- notification-owned payload bytes should follow
  `pkg/schema/fbs/notification.fbs`;
- the gateway derives `timestamp_ms`, recomputes `payload_hash`, and signs the
  outgoing event at delivery time;
- each gateway replica consumes streams with plain `XREAD`, so publishers must
  keep retention bounded with `MAXLEN`.
