# 정책 클래스가 자바독 첫 줄에 적은 주체
/**
 * The September 2025 {@code @oneOf} input rules the platform enforces (design §7.5).
 *
 * <p>{@code @oneOf} lets a schema express "exactly one of these selectors" instead of leaving it to
 * a hand-written validator that each resolver has to remember. The rules are stated here once so
 * the schema gate and the runtime validator cannot disagree about what the directive means.
 */
public final class GraphQlOneOfPolicy {

  /** Directive that marks an input object as one-of. */
  public static final String DIRECTIVE_NAME = "oneOf";

# 강제하는 두 코드와, 자기 파일 밖에서 그것을 부르는 자리
  GraphQlOneOfSchemaGate :
    test · GraphQlOneOfInputValidatorTest.java:103
    test · GraphQlOneOfInputValidatorTest.java:120
    test · GraphQlOneOfInputValidatorTest.java:70
    test · GraphQlOneOfInputValidatorTest.java:71
    test · GraphQlOneOfInputValidatorTest.java:86
src/adapter/inbound/graphql/src/testFixtures/java/dev/caskeleton/adapter/inbound/graphql/testkit/GraphQlSchemaContractSuite.java:41:      GraphQlOneOfSchemaGate.verify(assembled.registry());
  GraphQlOneOfInputValidator :
    test · GraphQlOneOfInputValidatorTest.java:28
    test · GraphQlOneOfInputValidatorTest.java:38
    test · GraphQlOneOfInputValidatorTest.java:40
    test · GraphQlOneOfInputValidatorTest.java:50
    test · GraphQlOneOfInputValidatorTest.java:51
    test · GraphQlOneOfInputValidatorTest.java:60

# 정책을 참조하는 자리
  main · GraphQlOneOfInputValidator.java:35     if (!GraphQlOneOfPolicy.satisfied(present.size())) {
  main · GraphQlOneOfInputValidator.java:37           GraphQlOneOfPolicy.violationMessage(present.size()), present);
  main · GraphQlOneOfSchemaGate.java:46       if (!definition.hasDirective(GraphQlOneOfPolicy.DIRECTIVE_NAME)) {
  main · GraphQlOneOfSchemaGate.java:74                         .hasDirective(GraphQlOneOfPolicy.DIRECTIVE_NAME))
  test · GraphQlOneOfInputValidatorTest.java:125     assertThat(GraphQlOneOfPolicy.DIRECTIVE_NAME).isEqualTo("oneOf");
  test · GraphQlOneOfInputValidatorTest.java:126     assertThat(GraphQlOneOfPolicy.satisfied(1)).isTrue();
  test · GraphQlOneOfInputValidatorTest.java:127     assertThat(GraphQlOneOfPolicy.satisfied(0)).isFalse();
  test · GraphQlOneOfInputValidatorTest.java:128     assertThat(GraphQlOneOfPolicy.satisfied(2)).isFalse();
  test · GraphQlOneOfInputValidatorTest.java:129     assertThat(GraphQlOneOfPolicy.violationMessage(0)).contains("none supplied");

# 이 저장소가 쓰는 graphql-java 판본
  gradle.lockfile:32  com.graphql-java:graphql-java:25.0

# 스키마 파일과 그 안의 oneOf 선언
  src/adapter/inbound/graphql/src/test/resources/graphql-platform/platform.graphqls
  src/adapter/inbound/graphql/src/test/resources/graphql-qualification/qualification.graphqls
  src/adapter/inbound/graphql/src/main/resources/graphql/skeleton.graphqls
  그중 @oneOf 를 선언한 파일 : (없음)

# 그 계약 스위트를 부르는 자리와 그것을 도는 레인
  test · GraphQlCrossModuleContractSuiteTest.java:72
  test · GraphQlCrossModuleContractSuiteTest.java:76
  test · GraphQlCrossModuleContractSuiteTest.java:81
  GraphQlCrossModuleContractSuiteTest:23:@Tag("graphql-contract")
  기본 test 레인이 배제하는 태그 :
    graphql-platform-conventions.gradle:49:    tasks.named('test') {
    graphql-platform-conventions.gradle:50:        useJUnitPlatform {
    graphql-platform-conventions.gradle:51:            excludeTags 'quarantine', 'graphql-performance'
    graphql-platform-conventions.gradle:52:        }

# 두 강제 코드가 인스턴스를 갖지 않는다는 것
  GraphQlOneOfSchemaGate.java:23   private GraphQlOneOfSchemaGate() {}
  GraphQlOneOfInputValidator.java:18   private GraphQlOneOfInputValidator() {}

# 이 계열 타입을 API 표면으로 적어 둔 문서
  architecture/graphql-api-surface.txt:387  dev.caskeleton.adapter.inbound.graphql.schema.GraphQlOneOfInputValidator
  architecture/graphql-api-surface.txt:388  dev.caskeleton.adapter.inbound.graphql.schema.GraphQlOneOfPolicy
  architecture/graphql-api-surface.txt:389  dev.caskeleton.adapter.inbound.graphql.schema.GraphQlOneOfSchemaGate
  architecture/graphql-api-surface.txt:390  dev.caskeleton.adapter.inbound.graphql.schema.GraphQlOneOfViolationException
