Files
llm-wiki/raw/interviews/shared-contract-and-sample-isolation.md

9.1 KiB

title, source_type, status, related_branches, related_projects, tags, created, status_label
title source_type status related_branches related_projects tags created status_label
interview-prep / shared-contract-and-sample-isolation interview-prep raw
feature-skeleton-package-blueprint-contract
ca-skeleton
interview-prep
ca-skeleton
architecture
api-design
clean-architecture
shared-kernel
2026-05-28 collecting

interview-prep: shared-contract-and-sample-isolation

Layer: raw/interviews/ — 면접 질문 원본 수집·연구 노트. 다듬어진 답변은 /interviewizewiki/interview/ 에 별도 작성.

Parent / 부모

질문 / Question

  • 질문 원문: Clean Architecture 템플릿에서 shared-contractsample-ticket 은 각각 어떤 책임을 가지고, 왜 production 도메인과 물리적으로 분리했나요?
  • 출처: 예상 질문.
  • 받은 날짜·맥락: 아직 실제 면접 질문으로 받은 것은 아님.

질문 의도 추론 / Why this question

  • 핵심 평가 대상:
    • "공통이니까 shared 에 넣는다" 라는 common module dumping ground 의 위험을 인식하는지.
    • sample / reference code 가 production dependency 로 새지 않도록 막는 메커니즘 인식.
    • skeleton-wide operational contract 의 범위구체적으로 설명할 수 있는지 (8개 sub-package allowlist).
    • "예시를 들어내도 경계가 남는다" 라는 template repository 의 완성도 기준 인식.
  • 함정 / 흔히 빠지는 답변 패턴:
    • "공통이니까 shared 에 넣는다" — boundary drift 의 시작.
    • "sample 은 참고용이라 어디서나 import 해도 된다" — production 역수입 위험.
    • shared 범위를 구체적으로 설명하지 못하고 "공용 유틸" 처럼 추상적으로 표현.
  • 따라올 만한 후속 질문:
    • error code 나 response envelope 은 왜 domain 이 아니라 shared-contract 인가요?
    • business / domain concept 가 shared-contract 에 들어오면 구체적으로 어떤 문제가 생기나요?
    • sample-ticket 이 production module 에 import 되는 것을 어떻게 감지 하나요? (Gradle vs ArchUnit)
    • sample-ticket 을 아예 지웠을 때 production 코드가 그대로 빌드되는지 어떻게 보장하나요?

답변 재료 / Raw answer material

  • 사실 1 (근거: feature-skeleton-package-blueprint-contract.md D6 + §Default Module Blueprint): shared-contract 는 8개 sub-package 만 허용 — response/, error/, headers/, logging/, tracing/, metrics/, registry/, annotation/. 모두 skeleton-wide operational contract (운영 계약).
  • 사실 2 (근거: feature-skeleton-package-blueprint-contract.md §판정 기준 "Forbidden: business/domain concept가 shared-contract 또는 adapter module로 이동"): business / domain concept 는 shared-contract 진입 금지. 위반 시 ArchUnit shared_contract_contains_only_operational_contract_packages rule 실패.
  • 사실 3 (근거: feature-skeleton-package-blueprint-contract.md D7 + feature-architecture-enforcement-rules.md D7): sample-ticket 은 fixture / sample consumer. production module 이 import / dependency 선언 시 Gradle verifyCleanArchitectureDependencies 와 ArchUnit production_code_does_not_depend_on_sample_ticket 양쪽 에서 실패.
  • 사실 4 (근거: feature-skeleton-package-blueprint-contract.md Closure §actually-implemented): production package root 가 dev.caskeleton 으로 rename + reference code 가 sample-ticket/src/main/java/dev/caskeleton/sample/ticket/... 로 격리 + production module 은 package-info.java + skeleton anchor 중심.
  • 사실 5 (근거: 파생 에러 raw/errors/sample-ticket-oauth2-resource-server-dependency-2026-05-27): sample-ticket 은 독립 컴파일 대상 — production module 의 external dependency 가 자동 전파되지 않으므로 sample 의 build.gradle 에 명시 필요. (InvalidBearerTokenException import 누락 → spring-boot-starter-oauth2-resource-server 명시 추가.)
  • 내가 직접 한 경험:
    • 기존 reference code (blog domain — User, Post, Service, Repository, Controller, Mapper) 전체를 sample-ticket 아래로 격리.
    • production module 의 *Service, *Repository, *Controller완전히 사라진 상태 에서 ArchUnit 의 빈 anchor failure 발생 → allowEmptyShould(true) 선별 적용 — raw/errors/archunit-empty-should-anchor-2026-05-27.
    • sample-ticket 격리 후 spring-boot-starter-oauth2-resource-server 누락 compile failure 해결.
  • 트레이드오프:
    • shared-contract 범위 좁힘: 좁히면 중복 코드 가 생길 수 있음 (각 adapter 가 비슷한 utility 를 가짐), 넓히면 domain concept 가 흘러들 위험. ca-tmpl 은 중복 비용 < boundary drift 비용 으로 판단해 좁게.
    • sample 격리 비용: sample 이 별도 module 이라 build classpathdependency 가 production 과 분리됨. 사례에서 OAuth2 resource-server starter 명시 누락처럼 실수가 가능. 격리 비용을 감수하는 이유 는 production 역수입 방지가 더 큰 위험이라는 판단.
    • canonical extraction 의 trade-off: shared-contract 의 registry (error code / header / metric) 가 어느 branch 에서 어떤 API 로 채워질지는 후속 (feature-contract-registry-governance 등) — 본 branch 는 범위와 forbidden 까지만 잡고 내용 자체 는 미정.
  • 한계 / "이건 안 해봤다":
    • 실제 ticket fixture 시나리오 (CRUD + 인증 + 권한) 가 완성됐다 고 말하지 않음 — reference code 격리와 compile/test 검증까지만.
    • shared-contract 의 실제 contract API (response envelope shape, error code 표준) 는 후속 branch (feature-api-contract-baseline, feature-contract-registry-governance) 범위.
    • 운영 배포 없음 — feature-skeleton-package-blueprint-contract.md Closure §prod-verified: 없음.

Sources / 근거

미해결 / Unknown

  • 모르는 것: shared-contract 의 registry (error code / header / metric) 구체 API 는 어느 branch 에서 어떤 형태로 채울지 — feature-contract-registry-governance, feature-api-contract-baseline 후속.
  • 모르는 것: sample-ticket 이 실제 ticket fixture 로 완성 될 때 production module 과 어떤 compile / test relationship 을 유지할지 — feature-sample-domain-contract-fixture 후속.
  • 확인 방법: 후속 branch 결과 + canonical wiki 정제.

답변 경계 / Answer boundary

  • 자신 있게 말할 수 있는 범위:
    • shared-contract 의 8 sub-package allowlist 와 forbidden (business/domain concept).
    • sample-ticket 의 production 역수입 금지를 Gradle + ArchUnit 양쪽 으로 막은 메커니즘.
    • reference code 격리 작업 (package rename, dependency 재선언, ArchUnit allowEmptyShould 조정) 의 직접 수행 범위.
  • "이 부분은 공식 문서를 다시 보고 답변드리겠습니다" 라고 해야 하는 부분:
    • 특정 회사 / 조직의 shared kernel / common module 표준 정책 (DDD bounded context 와의 관계).
    • error code / header / metric 표준화의 업계 best practice (RFC 7807, OpenTelemetry semantic conventions 등) — 본 branch 는 범위 만 잡았고 내용 은 후속 branch.
  • 절대 과장하지 말 것:
    • sample-ticket실제 ticket 시나리오 (CRUD + 인증 + 권한)완성됐다 고 표현 금지 — 현재는 reference 격리와 compile/test 검증 범위.
    • 운영 배포 검증인 것처럼 말하지 말 것 — locally-verified 등급.
    • shared-contract 범위를 기억 으로 답하지 말고 8 sub-package 를 정확히 (response/error/headers/logging/tracing/metrics/registry/annotation).