# Contracts (type schemas) for external-services.ncl
#
# Each service contract validates its own fields.
# ExternalServicesConfig uses an open record (..) so new services can be
# added to external-services.ncl without modifying this file.

{
  NatsConfig = {
    enabled            | Bool,
    url                | String,
    token              | String,
    connection_timeout | Number,
    max_reconnects     | Number,
    reconnect_delay    | Number,
    subjects           | { _ : String },
  },

  OllamaConfig = {
    enabled         | Bool,
    base_url        | String,
    default_model   | String,
    request_timeout | Number,
    stream          | Bool,
    keep_alive      | String,
    max_tokens      | Number,
    temperature     | Number,
  },

  S3Config = {
    enabled         | Bool,
    endpoint        | String,
    region          | String,
    bucket          | String,
    access_key      | String,
    secret_key      | String,
    path_style      | Bool,
    upload_prefix   | String,
    max_object_size | Number,
    presign_ttl     | Number,
  },

  # Admin NATS connection — separate credentials and namespace from the
  # general app NATS. Uses nkeys credentials file instead of token.
  NatsAdminNamespace = {
    prefix
      | String
      | doc "Implementation-specific prefix, e.g. 'evol.website'. Never hardcoded in framework code.",

    env
      | String
      | doc "Deployment environment tag: 'prod' | 'staging' | 'dev'. Override via ENV var in k8s.",
  },

  NatsAdminConsumer = {
    name             | String,
    ack_policy       | String | default = "Explicit",
    filter_subjects  | Array String | default = [],
    ..
  },

  NatsAdminJetStream = {
    enabled
      | Bool
      | default = true,

    stream_name
      | String
      | doc "JetStream stream that captures all admin subject traffic for audit log.",

    retention_days
      | Number
      | doc "Message retention period in days."
      | default = 30,

    retention
      | String
      | doc "Retention policy: Limits | Interest | WorkQueue."
      | default = "Limits",

    storage
      | String
      | doc "Storage backend: File | Memory."
      | default = "File",

    max_messages
      | Number
      | doc "Max messages in stream. 0 = unlimited."
      | default = 0,

    max_bytes
      | Number
      | doc "Max bytes in stream. 0 = unlimited."
      | default = 0,

    consumers
      | Array NatsAdminConsumer
      | default = [],
  },

  NatsAdminConfig = {
    enabled
      | Bool
      | default = false,

    url
      | String
      | doc "NATS server URL. Use '${NATS_ADMIN_URL}' to read from env.",

    credentials_file
      | String
      | doc "Path to nkeys credentials file mounted as k8s Secret (e.g. /etc/nats/admin.creds). Never inline the key here.",

    connection_timeout
      | Number
      | doc "Connection timeout in seconds."
      | default = 5,

    max_reconnects
      | Number
      | default = 10,

    reconnect_delay
      | Number
      | doc "Delay between reconnect attempts in seconds."
      | default = 2,

    namespace
      | NatsAdminNamespace
      | doc "Subject namespace. Full subject = '{prefix}.{env}.{subject_leaf}'.",

    subjects
      | { _ : String }
      | doc "Admin subject leaves. Full paths assembled at runtime using namespace. Open record — implementations may extend.",

    jetstream
      | NatsAdminJetStream
      | doc "JetStream configuration for audit log persistence.",

    nkey_seed
      | String
      | doc "NKEY seed for server-to-server authentication. Empty string disables nkey auth."
      | default = "",

    require_signed_messages
      | Bool
      | doc "Reject messages not signed with a trusted NKEY."
      | default = false,

    trusted_nkeys
      | Array String
      | doc "List of trusted NKEY public keys for message signature verification."
      | default = [],
  },

  ExternalServicesConfig = {
    nats       | NatsConfig,
    nats_admin | NatsAdminConfig,
    ollama     | OllamaConfig,
    s3         | S3Config,
    ..
  },
}
