fix: 하네스 제거 및 keycloak 문서 보강
This commit is contained in:
@@ -1 +0,0 @@
|
||||
../../vault/40-publish/interviews/shared-contract-and-sample-isolation.md
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
title: interview-prep / shared-contract-and-sample-isolation
|
||||
source_type: interview-prep
|
||||
status: raw
|
||||
related_branches: [feature-skeleton-package-blueprint-contract]
|
||||
related_projects: [ca-skeleton]
|
||||
tags: [interview-prep, ca-skeleton, architecture, api-design, clean-architecture, shared-kernel]
|
||||
created: 2026-05-28
|
||||
status_label: collecting
|
||||
---
|
||||
|
||||
# interview-prep: shared-contract-and-sample-isolation
|
||||
|
||||
> Layer: `raw/interviews/` — 면접 질문 원본 수집·연구 노트. 다듬어진 답변은 `/interviewize` 후 `wiki/interview/` 에 별도 작성.
|
||||
|
||||
## Parent / 부모
|
||||
|
||||
- [[raw/branch-notes/feature-skeleton-package-blueprint-contract]] — `shared-contract` 와 `sample-ticket` 의 책임 경계 결정 (D6, D7).
|
||||
- [[raw/project-notes/ca-skeleton-operational-contract]] — ca-tmpl skeleton-wide operational contract SSOT.
|
||||
|
||||
## 질문 / Question
|
||||
|
||||
- 질문 원문: Clean Architecture 템플릿에서 `shared-contract` 와 `sample-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 classpath_ 와 _dependency_ 가 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 / 근거
|
||||
|
||||
- [[raw/branch-notes/feature-skeleton-package-blueprint-contract]] — D6, D7 + §Default Module Blueprint + §판정 기준 + Closure.
|
||||
- [[raw/branch-notes/feature-architecture-enforcement-rules]] — D6 (shared-contract package allowlist) + D7 (sample-ticket production 역수입 금지) — _자동 검증_ 측면.
|
||||
- [[raw/errors/archunit-empty-should-anchor-2026-05-27]] — 빈 anchor 와 `allowEmptyShould(true)` 선별 적용.
|
||||
- [[raw/errors/sample-ticket-oauth2-resource-server-dependency-2026-05-27]] — sample 의 _독립 컴파일 대상_ 성격을 보여주는 사례.
|
||||
- [[wiki/concepts/clean-architecture-package-layout]] — module/package layout 일반 개념 (canonical).
|
||||
- [[wiki/projects/ca-tmpl/clean-architecture-package-layout]] — ca-tmpl 적용 (canonical, 갱신 필요).
|
||||
|
||||
## 미해결 / 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`).
|
||||
|
||||
## Related / 관련
|
||||
|
||||
- 관련 면접 질문 (선행/후속): [[raw/interviews/clean-architecture-module-blueprint]] (선행 — module 분리 자체), [[raw/interviews/clean-architecture-boundary-enforcement]] (자매 — 자동 검증 메커니즘).
|
||||
- 영감을 받은 채용공고: (없음).
|
||||
- 관련 블로그 글감: [[raw/blog-topics/clean-architecture-module-blueprint-2026-05-28]] (같은 결정의 글감).
|
||||
- 답변 derive 후 위치: 생성 전. 생성 시 `wiki/interview/architecture/shared-contract-and-sample-isolation.md` 후보.
|
||||
Reference in New Issue
Block a user