# JSON Body Pointer Rewrite
#
# Rewrites a JSON request body with JSON Pointer extract, replace, add, and
# remove, and the response body with remove and extract.
#
# Usage:
#   cargo run -p praxis-proxy -- -c examples/configs/payload-processing/json-body.yaml
#
#   curl -X POST http://localhost:8080/v1/chat \
#     -H "Content-Type: application/json" \
#     -d '{"model":"old","secret":"s3cret","prompt":"hi","stream":true,"user":{"id":1},"internal":"drop-me"}'
#
# The upstream sees model=forced-model, original_model=old, tenant=acme,
# X-Stream=true, no secret, and extracted_model=old and
# extracted_user={"id":1} (round-tripped through metadata and structured
# metadata via a second filter). The client response omits internal.

listeners:
  - name: default
    address: "127.0.0.1:8080"
    filter_chains:
      - rewrite

filter_chains:
  - name: rewrite
    filters:
      - filter: json_body
        request_extract:
          - pointer: /model
            metadata: original.model
          - pointer: /stream
            header: X-Stream
          - pointer: /user
            structured_metadata:
              namespace: json_body
              key: user
        request_replace:
          - pointer: /model
            value: forced-model
        request_add:
          - pointer: /tenant
            value: acme
          - pointer: /original_model
            metadata: original.model
        request_remove:
          - /secret
        response_remove:
          - /internal
        response_extract:
          - pointer: /prompt
            metadata: response.prompt
          - pointer: /user
            structured_metadata:
              namespace: json_body
              key: response_user
        max_body_bytes: 1048576 # 1 MiB — sized for chat-completions payloads
        on_invalid: reject

      # Second json_body: proves metadata and structured metadata from the
      # first filter are visible downstream by injecting them as body fields.
      - filter: json_body
        request_add:
          - pointer: /extracted_model
            metadata: original.model
          - pointer: /extracted_user
            structured_metadata:
              namespace: json_body
              key: user
        on_invalid: reject

      - filter: router
        routes:
          - path_prefix: "/"
            cluster: echo

      - filter: load_balancer
        clusters:
          - name: echo
            endpoints:
              - "127.0.0.1:3000"

insecure_options:
  allow_private_endpoints: true # example proxies to local backends
