Injecting dynamic values for a specific schema to validate against

Hello,

I have the following yaml file that I would like to validate using dry-rb.

---
environment: # required
  test: # should be dynamic
    service_credentials: "test_credentials" # required
  stage:
    service_credentials: "stage_credentials"
  prod:
    service_credentials: "prod_credentials"

My goal is to create a schema that can validate the above configuration using dynamic fields. In particular, those dynamic values, like test, stage, etc., can be injected or not. In the first case, the validation should fail if the dynamic field is not present.

The first attempt was to create a contract like the following but I think is not the best solution.

class EnvironmentContract < Dry::Validation::Contract
  params do 
    required(:environment).hash do
      optional(:test).hash do
        required(:service_credentials).filled(:str?)
      end
      optional(:preprod).hash do
          required(:service_credentials).filled(:str?)
      end
      optional(:prod).hash do
        required(:service_credentials).filled(:str?)
      end
    end
  end
end

Are you able to suggest me a way to achieve that?

Additionally, changing params to scheme in EnvironmentContract makes the validation to fail. Reading the documentation, I’ve noticed that the only difference between the two is that the latter does not perform coercion but it’s obscure to me why it’s failing.

Thanks for your support,
Lorenzo