Skip to content

저장소·호스트 네이밍 — 상세 규칙

상태: 확정

적용 대상: Leysys 제품군의 제품·서비스·플랫폼 저장소와 public hostname

정본: 이 문서

요약: 저장소·호스트 네이밍 — 한눈에 보기

1. 결정

저장소 이름은 사용자가 들어오는 surface, 업무 규칙을 소유하는 domain, 실제로 배포되는 component 또는 platform, prototype 전용 repository kind를 구분해서 표현합니다. Public surface의 route identity는 (product, surface-id, device-class?)입니다. Stable client 저장소는 여기에 client-platform을 더하고, prototype 저장소는 별도 terminal suffix인 proto를 사용합니다. 저장소와 DNS는 같은 route identity를 각 목적에 맞게 직렬화합니다.

text
# 사용자 접점
{repository-prefix}-{surface-id}[-{device-class}]-{client-platform}

# prototype
{repository-prefix}-{prototype-scope}[-{device-class}]-proto

# 업무 백엔드
{repository-prefix}-{domain}-{backend-component}

# 공유 실행 기반
{repository-prefix}-{shared-platform}

핵심 결정은 다음과 같습니다.

  1. Leyve는 console, customer-portal, staff-portal, customer-kiosk, staff-kiosk, partner-center, ops-center, www를 기본 surface ID로 사용합니다.
  2. 각 제품은 허용 surface 집합 S(product)를 registry에 따로 등록합니다.
  3. Portal audience가 정확히 하나이고 그 audience를 immutable default로 등록한 제품만 bare portal을 사용할 수 있습니다. Audience가 둘 이상이면 모두 {audience}-portal을 사용합니다.
  4. 관리자와 사용자의 repository·deployable·origin·release 경계가 모두 같고 registry가 승인한 제품만 통합 app surface를 사용할 수 있습니다. app은 platform·component suffix가 아닙니다.
  5. bare kiosk, center는 신규 저장소에서 사용하지 않습니다.
  6. customer는 개인과 사업자 고객을 모두 포함합니다. consumer는 사용하지 않습니다.
  7. staff는 고객사 직원을 뜻합니다. Leysys 본사 운영자는 ops입니다.
  8. 반응형·adaptive 앱은 device class를 생략합니다. 실제 전용 delivery에만 mobile, tablet, desktop 중 하나를 surface 뒤에 붙입니다.
  9. Hostname은 (product, surface, device?) route tuple을 표현하고 실제 ingress owner 저장소는 registry에서 조회합니다.
  10. web, ios, android, macos, windows 같은 platform token은 public hostname에 넣지 않습니다.
  11. surface는 client platform 또는 bff와, domain은 service, api, worker와 결합합니다.
  12. service는 백엔드 업무 서비스이며 full-stack을 뜻하지 않습니다.
  13. Stable 브라우저 surface는 full-stack 구현이어도 -web을 생략하지 않습니다.
  14. -proto는 platform이나 component가 아닌 prototype 전용 suffix이며 -web으로 치환하지 않습니다.
  15. environment는 저장소가 아니라 DNS zone으로, legacy·custom 주소는 alias로 관리합니다.

이 문서는 국제 표준 규격을 주장하지 않습니다. 전 세계 모든 조직에 적용되는 단일 저장소 이름 표준은 없습니다. 널리 쓰이는 customer portal, partner center, backoffice, BFF, bounded context, adaptive UI의 의미를 Leysys 제품군의 사용자·권한·배포 경계에 맞게 고정한 내부 표준입니다.

2. 이름 문법

2.1 사용자 접점

text
{repository-prefix}-{surface-id}[-{device-class}]-{client-platform}

예:

text
leyve-console-web
leyve-customer-portal-ios
leyve-ops-center-android
leyve-customer-portal-mobile-web
leysign-app-web

surface-id는 제품별 registry 집합 S(product)에 등록된 하나의 완성된 식별자입니다. customer-portal처럼 audience와 experience type이 결합된 값도 하나의 surface ID로 취급합니다. portal은 단일 default portal 조건을, app은 unified app 조건을 충족한 제품에서만 등록할 수 있습니다. device class는 파일명·카탈로그 정렬이 surface별로 모이도록 surface ID 뒤에 둡니다.

Prototype 저장소는 제12절의 별도 문법을 사용합니다. proto를 client platform으로 해석하거나 기존 이름에 web을 자동 삽입하지 않습니다.

2.2 업무 백엔드

text
{repository-prefix}-{domain}-{backend-component}

예:

text
leyve-billing-service
leyve-auth-api
leyve-subscription-worker

console, portal, center는 업무 domain이 아닙니다. 접점을 없애도 billing, CRM 같은 업무 능력은 남으므로 surface와 domain을 같은 축으로 취급하지 않습니다.

2.3 Device class가 실제 delivery 경계인 경우

text
{repository-prefix}-{surface-id}-{device-class}-{client-platform}

예:

text
leyve-console-mobile-web
leyve-console-tablet-ios
leyve-staff-kiosk-tablet-android

저장소는 일반적인 분류에서 구체적인 분류 순서인 product → surface → device → platform을 사용합니다. 따라서 사전순으로 나열해도 같은 surface의 반응형·device 전용 저장소가 모입니다.

text
repository-prefix → surface-id → device class(선택) → client-platform
repository-prefix → domain → backend-component

모든 토큰은 영문 소문자 kebab-case를 사용합니다. api, bff, ios처럼 업계에서 통용되는 약어 외에는 임의 축약을 만들지 않습니다.

2.4 Canonical hostname 함수

제품 집합을 P, 제품별 surface ID 집합을 S(p), device class 집합을 D = {ε, mobile, tablet, desktop}, client platform 집합을 K = {web, ios, android, macos, windows}로 둡니다. app ∉ K이며 ε는 반응형·adaptive 기본값입니다. s ∈ S(p)인 public route identity는 Iroute = (p, s, d), stable client repository identity는 Iclient = (p, s, d, k)입니다. Host-bearing surface prototype에는 별도 serializer Rproto를 사용하며 실제 delivery platform은 registry metadata로 소유합니다.

제품별 repository prefix와 환경별 public DNS zone은 문자열로 추론하지 않고 registry 함수 Catalog(P) = (repoPrefix, zones)에 등록합니다.

text
Catalog(leyve).repoPrefix = leyve
Catalog(leyve).zones.production = leyve.net

R(p, s, ε, k) = repoPrefix(p) + "-" + s + "-" + k
R(p, s, d, k) = repoPrefix(p) + "-" + s + "-" + d + "-" + k

Rproto(p, s, ε) = repoPrefix(p) + "-" + s + "-proto"
Rproto(p, s, d) = repoPrefix(p) + "-" + s + "-" + d + "-proto"

Endpoint(s, ε) = s
Endpoint(s, d) = d + "-" + s

Hprod(p, s, d) = Endpoint(s, d) + "." + Zone(p, production)

Hostname 문자열은 route identity까지만 복원하며 web·proto 같은 repository suffix를 복원하지 않습니다. 정확한 전단사는 실제 registry에 등록된 (ingress-owner repository, environment) ↔ canonical hostname에만 성립합니다. 저장소는 왼쪽부터 product → surface → device → kind/platform으로 분류하고, DNS는 zone 왼쪽의 단일 endpoint label에 device → surface 순서로 직렬화합니다.

text
R(leyve, console, ε, web)
= leyve-console-web
↔ console.leyve.net

R(leyve, customer-portal, mobile, web)
= leyve-customer-portal-mobile-web
↔ mobile-customer-portal.leyve.net

Rproto(leyve, customer-portal, mobile)
= leyve-customer-portal-mobile-proto
↔ mobile-customer-portal.leyve.net  # registry owner로 등록된 경우만

Rproto(leyvote, portal, mobile)
= leyvote-portal-mobile-proto
↔ mobile-portal.leyvote.net

Rproto(leysign, app, ε)
= leysign-app-proto
↔ app.leysign.net

역파서는 먼저 full canonical hostname을 예약 endpoint registry에서 조회합니다. 일치하면 그 registry의 owner를 반환하고 일반 surface 이름을 생성하지 않습니다. 예약값이 아니면 저장소 역파서는 먼저 등록된 platform 또는 proto terminal suffix를 제거합니다. 남은 마지막 token이 device 예약어이고 앞부분이 해당 product의 S(p)에 등록된 surface이면 이를 d, 나머지를 s로 읽습니다. DNS 역파서는 production zone을 제거한 단일 endpoint label의 첫 token이 device 예약어이고 나머지가 등록된 surface이면 (d, s), 아니면 등록된 responsive s로 읽습니다. 실제 저장소 owner는 hostname 문자열로 만들지 않고 deployment registry에서 조회합니다. 유일한 route 역함수를 보장하기 위해 다음을 지킵니다.

  • surface ID는 device 예약어와 같거나 mobile-, tablet-, desktop-으로 시작할 수 없고, -mobile, -tablet, -desktop으로 끝날 수도 없습니다.
  • repository prefix와 production zone의 대응은 유일해야 합니다. 같은 zone을 공유해야 하면 product별 subzone 또는 명시적 endpoint registry로 분리합니다.
  • (surface-id, device-class?)는 등록된 조합만 허용하며 한 제품 안에서 고유해야 합니다.
  • portal ∈ S(p)이면 portal audience가 정확히 하나이고 그 audience가 immutable default여야 합니다. Bare portal과 그 default audience의 qualified portal은 동시에 canonical일 수 없습니다.
  • app ∈ S(p)이면 관리자와 포함된 모든 사용자 surface의 repository·deployable·origin·release 경계가 모두 같아야 합니다. 같은 device 범위에 app과 그 내부 console·portal을 동시에 canonical surface로 등록하지 않습니다.
  • 한 canonical hostname의 ingress owner 저장소는 정확히 하나입니다.
  • 한 host-bearing 저장소의 canonical 운영 hostname은 environment별 정확히 하나입니다.
  • surface와 생성된 [device-]surface endpoint label은 소문자 ASCII와 숫자, 하이픈만 쓰고 시작·끝 하이픈과 연속 하이픈을 금지합니다.
  • 생성된 endpoint label 전체가 63 octet 이하이며 ^(?=.{1,63}$)[a-z0-9]+(?:-[a-z0-9]+)*$를 만족해야 합니다.
  • 전체 DNS 이름은 wire format의 255 octet 제한을 넘지 않습니다.
  • device는 축약하지 않고 mobile, tablet, desktop 전체 token만 사용합니다.

m, p, d 같은 한 글자 축약은 사용하지 않습니다. p는 phone·pad·portal·production, d는 desktop·development로 해석될 수 있어 역함수보다 사람의 해석이 모호해집니다.

Responsive와 device 전용 hostname은 모두 zone 바로 아래 한 label이므로 *.leyve.net wildcard 인증서 범위에 포함됩니다. 예를 들어 같은 인증서가 customer-portal.leyve.netmobile-customer-portal.leyve.net을 보호할 수 있습니다. Wildcard 인증서는 apex leyve.net을 보호하지 않으며, 인증서가 이름을 보호한다는 사실만으로 DNS와 CDN alias가 자동 등록되지는 않습니다.

2.5 Environment와 alias 함수

canonical environment 집합을 E = {production, staging, dev}로 두고 제품별 zone을 등록합니다.

text
Zone(leyve, production) = leyve.net
Zone(leyve, staging)    = staging.leyve.net
Zone(leyve, dev)        = dev.leyve.net

H(p, s, d, e) = Endpoint(s, d) + "." + Zone(p, e)
text
customer-portal.leyve.net
customer-portal.staging.leyve.net
customer-portal.dev.leyve.net

mobile-customer-portal.leyve.net
mobile-customer-portal.staging.leyve.net

Staging device host도 zone 바로 아래 한 label이므로 *.staging.leyve.net wildcard 인증서 범위에 포함됩니다. 각 hostname은 별도 DNS·CDN alias와 유일한 ingress owner를 가져야 합니다.

따라서 실제 host deployment registry Vhost에 등록된 pair에 한해 정확한 전단사는 (ingress-owner repository, environment) ↔ canonical environment hostname입니다. environment token은 repo나 canonical endpoint label에 넣지 않습니다. Preview instance 이름은 canonical 집합에 포함하지 않고 별도 registry 규칙으로 생성합니다.

legacy hostname, apex, 짧은 주소, 고객 custom domain은 canonical 집합 밖의 alias입니다. alias는 canonical hostname 하나만 가리키며 alias 문자열로 새 저장소 이름을 만들지 않습니다. 예를 들어 mobile-portal.leyve.net은 flat 문법상 device=mobile, surface=portal로 파싱되지만 bare portal이 미등록이므로 mobile-customer-portal.leyve.net의 legacy alias입니다.

2.6 예약 public endpoint

모든 public hostname이 제품 surface는 아닙니다. 예약 endpoint는 surface 목록과 분리된 registry에서 owner와 예외 문법을 명시합니다.

endpoint역할canonical owner
docs공개 개발·운영 문서현재 owner leyve-docs-protodocs.leyve.net
api제품 외부 API ingressleyve-gatewayapi.leyve.net

docs는 surface가 아니지만 registry가 같은 web name shape로 명시적으로 mapping합니다. api는 gateway endpoint이므로 일반 surface 역함수에 넣지 않습니다. 예약 endpoint에는 device class를 붙이지 않으며 새 값은 ADR과 registry 변경 없이 만들지 않습니다. Owner가 -proto 저장소여도 suffix를 hostname에 넣거나 -web으로 바꾸지 않으며 제12절을 따릅니다.

2.7 Origin, cookie와 검색 경계

customer-portal.leyve.netmobile-customer-portal.leyve.net은 host가 다르므로 서로 다른 web origin입니다. 별도 device hostname을 만들 때는 CORS, 브라우저 storage, CSP, OAuth·SAML callback과 WebAuthn RP ID를 별도 origin 기준으로 검토합니다.

인증 cookie는 기본적으로 Domain을 생략한 host-only cookie를 사용합니다. 편의를 위해 .leyve.net 전체에 session cookie를 공유하지 않습니다. Surface 간 SSO가 필요하면 중앙 인증 redirect와 code exchange를 사용하고 cookie 공유는 별도 보안 검토를 거칩니다.

검색에 노출되는 같은 콘텐츠를 responsive와 device 전용 URL로 함께 제공하면 responsive 단일 URL을 우선 검토합니다. 실제 별도 HTML을 유지해야 할 때만 Google의 canonical·alternate 관계, 동등한 콘텐츠·metadata와 페이지별 redirect 규칙을 적용합니다.

2.8 Registry와 자동 검증

Stable client 후보 집합을 Aclient ⊆ {(p,s,d,k) | p∈P, s∈S(p), d∈D, k∈K}로 두고 prototype은 별도 repositoryKind=prototype descriptor로 등록합니다. 실제 public host 배포 집합 Vhost에는 delivery platform이 web이고 product surface 또는 예약 endpoint와 environment가 모두 등록된 artifact pair (a,e)만 넣습니다. 모든 곱집합을 자동 생성하지 않고 실제 artifact와 host deployment pair만 등록합니다. 운영 registry는 repository kind, delivery platform, endpoint와 owner를 machine-readable하게 소유해야 합니다.

yaml
products:
  leyve:
    repositoryPrefix: leyve
    zones:
      production: leyve.net
      staging: staging.leyve.net
      dev: dev.leyve.net
    portalAudiences: [customer, staff]
    defaultPortalAudience: null
  leyvote:
    repositoryPrefix: leyvote
    zones:
      production: leyvote.net
    portalAudiences: [voter]
    defaultPortalAudience: voter
    defaultPortalAudienceImmutable: true
  leysign:
    repositoryPrefix: leysign
    zones:
      production: leysign.net
    unifiedApp:
      surface: app
      sharedBoundaries: [repository, deployable, origin, release]

deviceOrder:
  responsive: 0
  mobile: 10
  tablet: 20
  desktop: 30
platformOrder: {web: 10, ios: 20, android: 30, macos: 40, windows: 50}
repositoryKindOrder: {client: 10, prototype: 90}
reservedEndpointOrder: {docs: 10, api: 20}
surfaceOrder:
  leyve:
    console: 10
    customer-portal: 20
    staff-portal: 30
    customer-kiosk: 40
    staff-kiosk: 50
    partner-center: 60
    ops-center: 70
    www: 80
  leyvote:
    portal: 10
  leysign:
    app: 10

reservedEndpoints:
  docs:
    owner: leyve-docs-proto
    hostname: docs.leyve.net
  api:
    owner: leyve-gateway
    hostname: api.leyve.net

artifacts:
  - owner: leyve-console-web
    repositoryKind: client
    product: leyve
    surface: console
    device: responsive
    deliveryPlatform: web
  - owner: leyve-docs-proto
    repositoryKind: prototype
    product: leyve
    endpoint: docs
    deliveryPlatform: web
  - owner: leyvote-portal-mobile-proto
    repositoryKind: prototype
    product: leyvote
    surface: portal
    device: mobile
    deliveryPlatform: web
  - owner: leysign-app-proto
    repositoryKind: prototype
    product: leysign
    surface: app
    device: responsive
    deliveryPlatform: web

hostDeployments:
  - artifact: leyve-console-web
    environments: [production, staging, dev]
  - artifact: leyve-docs-proto
    environments: [production]
  - artifact: leyvote-portal-mobile-proto
    environments: [production]
  - artifact: leysign-app-proto
    environments: [production]

aliases:
  - hostname: leyve.net
    canonical: www.leyve.net

Surface artifact의 문서·catalog 표시 순서는 다음처럼 계산합니다.

text
platformOrdinal(a) = platformOrder[a.clientPlatform]       # stable client
platformOrdinal(a) = platformOrder[a.deliveryPlatform]     # metadata가 있는 prototype
platformOrdinal(a) = 0                                     # delivery metadata가 없는 prototype

sortKey(a) = (
  surfaceOrder[a.product][a.surface],
  deviceOrder[a.device],
  repositoryKindOrder[a.repositoryKind],
  platformOrdinal(a)
)

Reserved endpoint artifact는 이 surface 정렬식에 넣지 않고 reservedEndpointOrder를 사용합니다. Raw filename 사전순은 surface 그룹 탐색에만 사용하고 device·kind·platform의 업무상 순서를 결정하지 않습니다.

CI lint는 다음 불변식을 검사합니다.

  1. 저장소 이름이 유일하게 parse되며 surface artifact는 등록된 surface·device·repository kind와 client platform 또는 prototype delivery metadata를, 예약 endpoint artifact는 등록된 endpoint·owner·repository kind·delivery metadata를 가지는지
  2. 계산된 canonical hostname과 배포 설정이 일치하는지
  3. canonical FQDN과 ingress owner가 모두 고유하고 owner suffix가 registry와 일치하는지
  4. alias가 canonical FQDN 하나만 가리키는지
  5. platform·component·environment·proto token이 canonical endpoint label에 섞이지 않았는지
  6. BFF·domain backend·worker에 public hostname이 자동 생성되지 않았는지
  7. bare portal은 portal audience가 정확히 하나이고 immutable default가 등록된 제품에만 존재하며, 같은 audience의 qualified portal과 함께 canonical로 등록되지 않았는지
  8. app surface는 repository·deployable·origin·release 경계가 모두 같다는 registry assertion이 있고, 같은 device 범위의 내부 console·portal과 함께 canonical로 등록되지 않았는지

3. Leyve 기본 Surface 체계와 제품별 확장

3.1 Leyve 고정 목록과 정렬 순서

Leyve 문서, 카탈로그, 대시보드에서 surface 저장소를 나열할 때는 다음 순서를 사용합니다.

순서surface IDcanonical 운영 hostname정의
1consoleconsole.leyve.net고객사 관리자·실무자가 Leyve 핵심 업무를 수행하는 기본 workspace
2customer-portalcustomer-portal.leyve.net고객이 자신의 정보·계약·서비스를 이용하는 self-service 접점
3staff-portalstaff-portal.leyve.net고객사 직원이 개인 업무와 직원 self-service를 처리하는 접점
4customer-kioskcustomer-kiosk.leyve.net고객이 공용 단말에서 조회·결제 등 짧은 업무를 처리하는 접점
5staff-kioskstaff-kiosk.leyve.net고객사 직원이 공용 터치 단말에서 출퇴근·휴가 등 빠른 업무를 처리하는 접점
6partner-centerpartner-center.leyve.net총판·리셀러가 자기 고객·결제·운영을 관리하는 backoffice
7ops-centerops-center.leyve.netLeysys 본사가 고객·파트너·CRM·결제·정책을 통합 관리하는 backoffice
8wwwwww.leyve.net불특정 방문자에게 브랜드·제품 정보와 문의 경로를 제공하는 공개 접점

권장 카탈로그 정렬값은 각각 10, 20, 30, 40, 50, 60, 70, 80입니다.

아래 목록은 stable web client를 새로 만들 때의 기본 projection이며 현재 ingress owner inventory가 아닙니다. 실제 hostname owner는 environment별 registry에서 하나만 선택합니다.

text
leyve-console-web

leyve-customer-portal-web
leyve-staff-portal-web

leyve-customer-kiosk-web
leyve-staff-kiosk-web

leyve-partner-center-web
leyve-ops-center-web

leyve-www-web

3.2 Audience 어휘

audience의미포함하지 않는 대상
customerLeyve와 이용·계약 관계인 개인·사업자 계정 및 그 대표 사용자 persona총판·리셀러, Leysys 본사 운영자
staff고객사 또는 현장 조직 소속자의 employee self-service personaLeysys 본사 직원, 파트너 관리자
partnerLeysys의 총판·리셀러와 그 관리 사용자일반 고객, Leysys 본사 운영자
opsLeysys 본사에서 고객·파트너·플랫폼을 운영하는 사용자고객사 직원, 파트너 사용자
voterLeyvote에서 투표에 참여하는 사용자 persona투표 개설자·운영 관리자

consumer는 일반적으로 최종 개인 소비자의 뉘앙스가 강합니다. Leyve 고객에는 개인사업자와 법인사업자가 포함되므로 더 넓고 계약 관계가 분명한 customer를 사용합니다.

staff는 회사의 내부 직원이라는 상대적 표현이므로 주체를 반드시 고정해야 합니다. Leyve 네이밍에서 staff는 고객사 직원이고, Leysys 본사 직원은 ops입니다.

voter처럼 제품별 audience token이 hostname에서 생략되더라도 registry의 의미 모델에서는 제거하지 않습니다. Leyvote의 portalvoter audience가 없다는 뜻이 아니라, 유일한 immutable default라서 surface serializer에서만 생략했다는 뜻입니다.

3.3 Experience type 어휘

experience type판정 기준
portal사용자가 자기 정보·계약·서비스를 조회하거나 요청하는 self-service
kiosk공유 단말, 짧은 세션, 터치 중심, 제한된 빠른 업무라는 사용 방식
center다른 고객·조직·결제·운영 대상을 관리하는 역할 기반 backoffice

portalcenter는 화면 모양이 아니라 권한 방향으로 구분합니다.

  • portal: 자신의 정보와 서비스를 이용합니다.
  • center: 관리 권한으로 다른 대상과 운영 흐름을 관리합니다.

kiosk는 태블릿의 동의어가 아닙니다. 휴대폰·태블릿·데스크톱 어느 크기에서도 구현될 수 있으며, 공유 단말과 짧은 흐름이라는 사용 방식이 핵심입니다.

3.4 허용 조합

Leyve 기본 surface 문법으로 허용하는 audience × experience type 조합은 다음 여섯 개입니다.

text
customer + portal
staff    + portal
customer + kiosk
staff    + kiosk
partner  + center
ops      + center

Leyve의 consolewww는 audience 접두어를 붙이지 않는 독립 surface입니다.

다른 제품에서 portal audience가 정확히 하나이고 그 audience를 immutable default로 registry에 등록했다면 audience를 생략한 portal을 product-local canonical surface로 사용할 수 있습니다. 여러 audience 중 하나만 default로 정하는 것으로는 부족합니다. Audience가 둘 이상이면 모든 portal에 {audience}-portal을 사용합니다.

text
leyvote-portal-mobile-proto ↔ mobile-portal.leyvote.net

Bare portal{default-audience}-portal을 동시에 canonical로 등록하지 않습니다. 두 번째 portal audience가 생기면 기존 audience를 포함해 모두 qualified 이름으로 migration하고, 기존 bare hostname은 원래 audience의 legacy alias로만 유지하며 다른 audience에 재할당하지 않습니다.

다음 조합은 신규 저장소에서 사용하지 않습니다.

text
kiosk
center
consumer-portal
consumer-kiosk
staff-center
admin-center

새로운 audience × experience 조합이 필요하면 이름부터 만들지 말고 사용자, 권한, 데이터 범위, 독립 배포 필요성을 ADR로 먼저 확정합니다.

3.5 Unified App Surface

app은 audience와 experience type을 조합한 이름이 아니라 여러 역할 방향을 하나로 묶는 product-local composite surface입니다.

관리자·console 흐름과 사용자·portal 흐름이 다음 네 경계를 모두 공유할 때만 product registry에 app을 surface로 등록할 수 있습니다.

text
same repository
AND same deployable
AND same origin
AND same release boundary

권한과 route가 다르더라도 위 경계가 같으면 하나의 app 안에서 RBAC로 구분할 수 있습니다. 하나라도 분리되면 app을 사용하지 않고 console과 product portal 규칙에 따른 surface로 나눕니다. 같은 device 범위에서 app과 그 내부 의미인 console·portal을 동시에 canonical로 등록하지 않습니다.

text
leysign-app-proto ↔ app.leysign.net

app은 surface ID입니다. console-app처럼 terminal platform·component suffix로 사용하거나 PWA·full-stack 구현이라는 이유만으로 선택하지 않습니다.

4. Client platform과 Device class

4.1 Client platform

현재 승인된 client platform은 다음 다섯 가지입니다.

text
web
ios
android
macos
windows
  • web: 브라우저로 제공되는 앱입니다. SPA, SSR, SSG를 모두 포함하며 정적 파일만을 뜻하지 않습니다.
  • ios: iOS/iPadOS 계열에서 제공되는 native 또는 hybrid 앱입니다.
  • android: Android 계열에서 제공되는 native 또는 hybrid 앱입니다.
  • macos: macOS에서 제공되는 native 또는 hybrid desktop 앱입니다.
  • windows: Windows에서 제공되는 native 또는 hybrid 앱입니다.

linux, visionos 등 새로운 client platform은 저장소에서 먼저 사용하지 않고 ADR로 표준 목록에 추가합니다. mac, win 같은 축약은 사용하지 않습니다. app은 client platform이 아니므로 terminal platform suffix로 사용하지 않습니다. 제3.5절의 조건을 충족한 제품이 surface 위치에 등록한 app은 이 금지와 다릅니다.

4.2 반응형·adaptive 기본값

device class가 없으면 해당 platform이 지원하는 화면 크기에 반응형 또는 adaptive로 대응한다는 뜻입니다.

text
leyve-console-web       # 지원하는 web 화면 크기에 반응
leyve-console-ios       # 지원하는 iOS/iPadOS 화면 크기에 적응
leyve-console-android   # 지원하는 Android mobile/tablet 화면 크기에 적응
leyve-console-macos     # macOS desktop 앱
leyve-console-windows   # 지원하는 Windows desktop/tablet 화면 크기에 적응

4.3 별도 delivery에만 Device class 추가

허용하는 device class는 다음 세 가지뿐입니다.

text
mobile
tablet
desktop

다음 조건이 모두 실제로 성립할 때만 추가합니다.

  • 독립 저장소 또는 독립 deployable과 build·release 경계
  • 해당 device class만 지원한다는 명시적 product contract
  • 다른 device class와 독립된 운영·rollback 필요성
  • client platform이 web이면 독립 canonical hostname
text
leyve-console-mobile-web
leyve-console-tablet-web
leyve-console-desktop-web

leyve-console-mobile-ios
leyve-console-tablet-ios

leyve-console-mobile-android
leyve-console-tablet-android

leyve-console-tablet-windows
leyve-console-desktop-windows

CSS breakpoint, 레이아웃 차이, 태블릿 사용 비중만으로 저장소를 나누지 않습니다. 브라우저의 viewport나 user-agent만으로 물리 기기 종류를 완전히 증명할 수도 없습니다. 따라서 이름은 하드웨어 감지 결과가 아니라 지원·배포 계약을 뜻하며 runtime 차단 정책은 별도로 정의합니다. iphone, ipad, galaxy 같은 제품명과 m, p, d 축약은 사용하지 않습니다.

허용되는 대표 조합은 다음과 같습니다.

client platformdevice class 생략허용할 수 있는 분리형 device class
web반응형 webmobile, tablet, desktop
iosiOS/iPadOS adaptive appmobile, tablet
androidAndroid adaptive appmobile, tablet
macosmacOS desktop app없음; desktop은 중복이므로 생략
windowsWindows adaptive apptablet, desktop

desktop-ios, desktop-android, mobile-macos, tablet-macos처럼 platform이 지원하지 않는 조합은 사용하지 않습니다. desktop-macos는 의미상 가능하지만 macos와 중복이므로 생략합니다.

4.4 여러 client platform을 함께 빌드하는 저장소

현재 표준은 하나의 저장소가 하나의 client platform delivery boundary를 가진다고 가정합니다. Capacitor, React Native, Flutter, Electron, Tauri 등으로 한 저장소에서 둘 이상의 platform 산출물을 함께 만든다면 다음 중 하나를 아키텍처 ADR로 먼저 결정합니다.

  1. platform별 delivery 저장소와 공유 package로 분리
  2. multi-platform monorepo를 유지하고 새로운 표준 token을 추가

이 결정 전에는 platform 위치의 -app, -mobile, 하나의 임의 platform suffix를 사용하지 않습니다. 현재 문서는 multi-platform repository name을 미리 승인하지 않습니다.

5. Scope와 Component 호환 규칙

scope 종류권장 component 또는 platform기본적으로 피할 조합자동 public hostname
Surfaceweb, ios, android, macos, windows, bffservice, api, workerweb만 canonical host 소유
Domainservice, api, workerclient platform suffix없음
Shared platformserver, gatewaysurface·domain 전용 suffixgateway의 예약 api만 명시 가능

교차 예외는 다음 두 경우만 인정합니다.

  1. 한 surface만을 위한 백엔드 조합 계층은 {surface-id}[-{device-class}]-bff로 표현합니다.
  2. 하나의 domain을 위한 화면이 실제로 독립 제품·진입점·배포 단위라면 ADR 승인 후 {domain}-{client-platform}을 사용할 수 있습니다.

따라서 아래 이름은 기본적으로 만들지 않습니다.

text
leyve-console-service
leyve-ops-center-service
leyve-partner-center-service
leyve-console-api
leyve-ops-center-api

화면별 인증 흐름, 읽기 모델, API 조합은 BFF가 담당하고 핵심 업무 규칙과 데이터 불변식은 domain service 또는 기존 leyve-server가 담당합니다.

6. Backend component 정의

6.1 bff

Backend for Frontend입니다. 특정 surface가 필요로 하는 인증 흐름, 여러 API의 조합, 응답 변환, 화면 전용 읽기 모델을 담당합니다.

text
leyve-console-bff
leyve-customer-portal-bff
leyve-ops-center-bff

BFF에 여러 domain의 핵심 업무 규칙을 복제하지 않습니다. surface마다 이름을 맞추기 위해 빈 BFF 저장소를 미리 만들지도 않습니다.

다음 서버 코드는 BFF로 분류하지 않습니다.

  • web 저장소와 함께 배포되는 SSR, form action, surface 지원 route → 계속 {surface-id}-web
  • durable 결제 callback·webhook·업무 mutation → 해당 domain service 또는 worker
  • provider adapter와 provider secret 소유 → 해당 공통 domain/platform backend

BFF는 surface 전용 조합 계층이지 surface에 필요한 모든 서버 코드의 통칭이 아닙니다.

6.2 service

하나의 bounded context와 업무 규칙을 소유하고 독립적으로 배포되는 백엔드 서비스입니다.

text
leyve-billing-service
leyve-crm-service
leyve-subscription-service

service는 full-stack을 뜻하지 않습니다.

6.3 api

API 계약과 배포 생명주기가 service 구현과 실제로 분리될 때 사용합니다.

text
leyve-auth-api

service가 HTTP API를 제공한다는 이유만으로 api 저장소를 추가하지 않습니다. 특정 surface만을 위한 API 조합 계층이라면 bff가 더 정확합니다.

6.4 worker

큐 소비, 배치, 스케줄 작업처럼 비동기 실행이 독립적으로 배포·확장·격리될 때 사용합니다.

text
leyve-billing-worker

같은 프로세스에서 실행되는 단순 background job은 별도 저장소로 만들지 않습니다.

6.5 server

여러 업무 영역을 함께 제공하는 공유 백엔드 또는 모놀리스입니다.

text
leyve-server

serverservice의 차이는 크기가 아니라 소유 경계입니다.

  • 여러 업무 영역을 하나의 배포 단위가 소유하면 server
  • 하나의 bounded context가 독립 배포되면 {domain}-service

leyve-server가 이미 담당하는 기능을 같은 책임의 {domain}-service로 중복 생성하지 않습니다. 분리할 때는 데이터 소유권, 호출 경계, 전환 순서를 ADR에 기록합니다.

6.6 gateway

제품 전체의 공통 ingress, 라우팅, 인증 위임, rate limit 등 경계 기능을 담당합니다.

text
leyve-gateway

gateway에는 domain 업무 규칙을 넣지 않습니다. gateway가 하나의 surface만을 위해 응답을 조합한다면 그 역할은 BFF에 더 가깝습니다.

6.7 Backend hostname 경계

저장소가 배포된다는 이유만으로 public hostname을 자동 생성하지 않습니다.

component기본 network identity
surface BFFweb surface와 same-origin인 /api 또는 gateway 뒤의 route
domain service·apiprivate zone 또는 platform service discovery
serverprivate ingress
workerlistener가 없으면 hostname 없음
gatewayregistry가 승인한 public api.leyve.net

외부 API는 api.leyve.net/{domain-or-version}/... 같은 단일 ingress에서 라우팅합니다. billing-service.leyve.net처럼 domain backend를 public DNS에 직접 노출하거나 repository 이름만으로 public endpoint를 추론하지 않습니다. Native iOS·Android·macOS·Windows client도 hostname을 자동 소유하지 않습니다. Universal Link나 App Link는 연결된 web surface의 canonical host를 명시적으로 재사용합니다.

7. Surface별 경계

7.1 Console

console은 고객사 관리자와 권한을 가진 실무자가 Leyve의 핵심 업무를 수행하는 기본 workspace입니다.

  • 자기 조직의 상품·업무 모듈 사용
  • 고객사 내부 운영, 회계, 임대차, 관리비 등 핵심 업무
  • 고객사 사용자·권한·설정 관리

console은 Leysys 본사 최고 관리 화면이 아닙니다. 본사 운영 화면은 ops-center입니다.

consolestaff-portal 사용자가 일부 겹칠 수는 있지만 목적이 다릅니다.

  • console: 권한을 가진 관리자·실무자의 핵심 업무 workspace
  • staff-portal: 직원 개인의 신청·조회 중심 self-service

7.2 Customer Portal과 Staff Portal

customer-portal은 개인·개인사업자·법인사업자 고객이 자신의 정보와 서비스를 이용하는 접점입니다.

staff-portal은 고객사 직원이 개인 기기에서 급여명세, 휴가, 근무 정보 등 자신의 직원 업무를 이어서 처리하는 접점입니다.

둘 다 self-service이지만 audience와 인증·권한 경계가 다르므로 이름을 분리합니다. 같은 사람이 법인 고객의 대표 사용자이면서 그 조직의 직원일 수는 있습니다. 이 경우 사람의 소속 하나로 surface를 고르지 않고 현재 수행하는 업무·권한 컨텍스트로 고릅니다.

  • 계약 계정, 고객 정보, 고객이 구매한 서비스의 self-service → customer-portal
  • 급여, 휴가, 근태 등 employee self-service → staff-portal

7.3 Customer Kiosk와 Staff Kiosk

customer-kiosk는 고객이 공용 또는 현장 단말에서 사용하는 접점입니다.

  • 일반 조회와 안내
  • 본인 확인 후 결제
  • 접수·발급 등 짧은 업무
  • 완료 또는 timeout 후 세션·개인정보 초기화

staff-kiosk는 고객사 직원이 공용 단말에서 빠르게 사용하는 업무 접점입니다.

  • 출근·퇴근 기록
  • 휴가 신청·잔여 휴가 확인
  • 근무 상태 확인
  • 최소 권한과 짧은 세션

태블릿에서 주로 사용하더라도 기본 이름은 각각 leyve-customer-kiosk-web, leyve-staff-kiosk-web입니다. tablet 전용 저장소·빌드·배포가 따로 있을 때만 leyve-customer-kiosk-tablet-webtablet-customer-kiosk.leyve.net 또는 leyve-staff-kiosk-tablet-webtablet-staff-kiosk.leyve.net을 사용합니다.

7.4 Partner Center와 Ops Center

두 center는 CRM, 고객, 결제 같은 유사한 기능을 사용하지만 관리 권한과 데이터 범위가 다릅니다.

partner-center

총판·리셀러가 자신의 사업 범위 안에서 운영합니다.

  • 자기 조직과 산하 고객 관리
  • 고객 계약·구독·사용량 확인
  • 소속 직원과 권한 관리
  • Leysys에 납부할 결제·청구·정산 확인

ops-center

Leysys 본사가 플랫폼 전체를 운영합니다.

  • 직접 고객과 파트너 관리
  • 고객·파트너 CRM, 계약, 구독, 결제 내역
  • 파트너 청구·수납·정산
  • 운영 예외 처리, 정책, 감사, 최고 관리자 기능

본사 영업, 재무, 고객 지원은 우선 ops-center 내부 모듈과 역할로 구분합니다. 별도 팀, 권한 경계, 제품 책임자, 배포 주기, 장애 격리가 실제로 필요해질 때만 독립 surface를 검토합니다.

두 center는 같은 domain backend를 사용할 수 있지만 tenant와 권한 범위는 반드시 백엔드가 검증합니다.

text
partner-center-web
  → partner-center-bff
    → customer / partner / billing domain

ops-center-web
  → ops-center-bff
    → 같은 domain, Leysys operations scope

7.5 WWW

www는 로그인 후 핵심 업무를 수행하는 제품 surface가 아니라 불특정 방문자를 위한 공개 홍보·정보 surface입니다.

  • 브랜드와 회사 소개
  • 제품·기능·가격 안내
  • 고객 사례와 콘텐츠
  • 게시판, 상담·도입 문의
  • portal, console 등 제품 surface로의 진입

기본 이름은 다음과 같습니다.

text
leyve-www-web

www는 surface이고 web은 client platform이므로 두 토큰은 중복이 아닙니다. Canonical hostname은 www.leyve.net입니다. Canonical surface hostname을 바꾸면 저장소 identity도 함께 검토하는 migration이며, 단순 legacy·custom alias 추가는 저장소 이름에 영향을 주지 않습니다.

SSR 서버, 게시판 조회, 문의 폼, 이메일 전송 route가 있다는 사실만으로 web을 빼지 않습니다. 주 제공물이 브라우저 앱이고 서버 기능이 그 surface를 지원한다면 leyve-www-web입니다.

8. 표준 저장소 예시

8.1 Web surface

저장소canonical 운영 hostname
leyve-console-webconsole.leyve.net
leyve-customer-portal-webcustomer-portal.leyve.net
leyve-staff-portal-webstaff-portal.leyve.net
leyve-customer-kiosk-webcustomer-kiosk.leyve.net
leyve-staff-kiosk-webstaff-kiosk.leyve.net
leyve-partner-center-webpartner-center.leyve.net
leyve-ops-center-webops-center.leyve.net
leyve-www-webwww.leyve.net

Device 전용 delivery는 같은 surface 그룹에 둡니다. Raw 사전순은 같은 surface를 모으지만 device의 업무상 순서까지 보장하지 않으므로 catalog는 별도 ordinal을 사용합니다.

저장소canonical 운영 hostname
leyve-customer-portal-mobile-webmobile-customer-portal.leyve.net
leyve-staff-kiosk-tablet-webtablet-staff-kiosk.leyve.net
leyve-ops-center-desktop-webdesktop-ops-center.leyve.net

8.2 Surface BFF

필요한 surface에만 생성합니다.

text
leyve-console-bff
leyve-customer-portal-bff
leyve-partner-center-bff

위 목록은 대표 예시이며 surface별 BFF 생성 체크리스트가 아닙니다. 실제 독립 조합 계층이 없으면 BFF 저장소도 만들지 않습니다.

8.3 Domain backend

text
leyve-auth-service
leyve-billing-service
leyve-crm-service
leyve-subscription-worker

Domain 저장소는 카탈로그에서 알파벳순으로 나열합니다. Surface 저장소에는 제3.1절의 고정 순서를 적용합니다.

8.4 Shared platform

text
leyve-gateway
leyve-server

9. Web과 Backend 판정

web은 정적 배포 방식이 아니라 사용자에게 제공되는 client platform을 뜻합니다.

저장소 책임이름
브라우저 UI가 주 제공물이며 SSR·서버 route가 surface를 지원leyve-{surface-id}[-{device-class}]-web
prototype 전용 탐색·검증 저장소leyve-{prototype-scope}[-{device-class}]-proto
한 surface 전용 API 조합 계층이 독립 배포leyve-{surface-id}[-{device-class}]-bff
하나의 업무 domain과 규칙을 독립 소유leyve-{domain}-service
여러 domain을 하나의 공유 backend가 소유leyve-server

브라우저 UI와 server route가 같은 stable client 저장소에 있거나 full-stack framework를 사용해도 주 delivery가 web surface이면 -web을 유지합니다. Suffix 없는 leyve-{surface-id}는 repository kind를 판별할 수 없어 신규 stable 저장소에서 허용하지 않습니다. Prototype은 suffix 없는 예외가 아니라 별도 -proto 문법이며 제12절을 따릅니다. Durable 업무 규칙과 데이터 소유권이 커지면 domain backend 경계로 분리하고, 같은 저장소에 남기는 결정은 architecture ADR로 기록하되 저장소 suffix는 바꾸지 않습니다.

독립 결제 callback·webhook·provider adapter를 web 또는 BFF 책임으로 흡수하지 않습니다. 이 코드는 provider-neutral domain service, worker 또는 공통 platform 경계에 둡니다.

app을 terminal platform·component suffix로 사용하지 않고, -service를 full-stack 의미로 사용하지 않습니다. Registry에 승인된 unified app surface는 제3.5절을 따릅니다.

10. 생성 판단 순서

새 저장소와 hostname을 만들기 전에 다음 순서로 판단합니다.

먼저 docs, api 같은 예약 public endpoint인지 확인합니다. 예약 endpoint이면 아래 surface·domain 판단 흐름으로 이름을 유추하지 않고 제2.6절의 명시적 owner·metadata·hostname registry 절차를 따릅니다.

  1. 사용자에게 직접 제공되는 접점인가?
    • 공개 홍보·정보 → www
    • 관리자와 사용자의 repository·deployable·origin·release 경계가 모두 같음 → registry 승인 후 app
    • 분리된 고객사 관리자·실무자의 핵심 workspace → console
    • 자기 정보·서비스 self-service에서 portal audience가 정확히 하나이고 immutable default임 → portal
    • Portal audience가 둘 이상인 self-service → {audience}-portal
    • 공유 단말의 짧은 터치 업무 → audience + kiosk
    • 고객·조직·결제 운영 backoffice → audience + center
  2. 저장소 또는 deployable·build·release와 지원 device 계약이 모두 분리되는가?
    • 아니면 device class 생략
    • 맞으면 surface 뒤에 mobile, tablet, desktop 중 하나 추가
    • web이면 독립 canonical host도 필수; native이면 hostname 조건 없음
  3. prototype 전용 저장소인가?
    • 맞으면 {prototype-scope}[-{device-class}]-proto; platform suffix를 덧붙이지 않음
    • public 배포가 있으면 delivery platform과 ingress owner를 registry에 명시
    • 아니면 stable client·backend 문법을 계속 판정
  4. 어느 client platform에 배포하는가?
    • web, ios, android, macos, windows
  5. 한 저장소가 둘 이상의 client platform을 함께 산출하는가?
    • 맞으면 이름을 만들기 전에 multi-platform architecture ADR 작성
  6. web인가?
    • 맞으면 (surface, device?)로 canonical hostname을 계산하고 owner 중복 검사
    • 아니면 자동 public hostname을 만들지 않음
  7. 한 surface만을 위한 독립 조합 backend인가?
    • {surface-id}[-{device-class}]-bff; public host는 자동 생성하지 않음
  8. 하나의 업무 능력과 규칙을 소유하는가?
    • {domain}-service
  9. API 계약 또는 비동기 실행이 별도로 배포되는가?
    • {domain}-api 또는 {domain}-worker
  10. 여러 업무 영역을 함께 제공하는 공유 backend인가?
  • leyve-server
  1. 제품 전체의 공통 ingress인가?
  • leyve-gateway
  1. 기존 leyve-server나 다른 저장소와 책임이 중복되는가?
  • 중복이면 새 저장소를 만들지 않고 기존 책임을 사용하거나 extraction ADR을 작성

위 질문에 명확히 답하지 못하면 저장소를 먼저 만들지 않습니다.

11. 피해야 할 이름과 권장 대안

피해야 할 이름이유권장 대안
leyve-portal-webLeyve는 portal audience가 복수이고 default portal이 미등록leyve-customer-portal-web 또는 leyve-staff-portal-web
leyve-kiosk-webaudience가 없음leyve-customer-kiosk-web
leyve-center-web운영 주체가 없음leyve-ops-center-web
leyve-consumer-portal-web사업자 고객을 충분히 포괄하지 못함leyve-customer-portal-web
leyve-console-servicesurface가 domain 규칙을 소유하는 것처럼 보임화면 전용은 leyve-console-bff, 업무는 {domain}-service
leyve-console-apisurface 조합 API인지 domain API인지 모호함화면 전용은 leyve-console-bff
leyve-service어떤 업무 backend인지 알 수 없음leyve-{domain}-service
leyve-console-appapp을 terminal platform suffix로 잘못 사용leyve-console-web; 실제 통합 surface라면 registry 승인 후 {product}-app-web
leyve-consolehost-bearing web인데 platform이 없음leyve-console-web
leyve-console-mobiledevice class만 있고 platform이 없음leyve-console-mobile-web
leyve-mobile-console-webdevice 기준으로 정렬되고 표준 tuple 순서와 다름leyve-console-mobile-web
leyve-console-iphone특정 제품명에 종속leyve-console-mobile-ios
leyve-console-ipad특정 제품명에 종속leyve-console-tablet-ios
mobile-portal.leyve.netLeyve는 portal audience가 복수이고 default portal이 미등록mobile-customer-portal.leyve.net
m-customer-portal.leyve.netdevice 축약이 모호함mobile-customer-portal.leyve.net
mobile.customer-portal.leyve.netdevice를 별도 DNS 계층으로 만들어 인증서·운영 경계가 복잡함mobile-customer-portal.leyve.net
console-web.leyve.netplatform을 hostname에 노출console.leyve.net
prod.console.leyve.netenvironment 위치와 production 기본값이 다름console.leyve.net
mobile-customer-portal.development.leyve.netdevdevelopment를 혼용mobile-customer-portal.dev.leyve.net

12. Prototype 전용 suffix -proto

-protoweb, ios, service 같은 platform·component가 아니라 prototype 저장소를 표시하는 독립 terminal suffix입니다. Hostname 계산에서는 -proto를 제외하지만 저장소 이름에서는 그대로 보존합니다.

text
prototype repository = {repository-prefix}-{prototype-scope}[-{device-class}]-proto
prototype endpoint   = [{device-class}-]{registered-product-surface}

예를 들어 registry가 해당 prototype을 ingress owner로 등록한 환경에서는 다음처럼 연결할 수 있습니다.

text
leyve-console-proto                 ↔ console.leyve.net
leyve-customer-portal-mobile-proto  ↔ mobile-customer-portal.leyve.net
leyve-docs-proto                    ↔ docs.leyve.net  # reserved endpoint
leyvote-portal-mobile-proto         ↔ mobile-portal.leyvote.net
leysign-app-proto                   ↔ app.leysign.net

이 연결은 hostname에서 proto를 역산한다는 뜻이 아닙니다. 같은 route identity의 leyve-console-webleyve-console-proto가 동시에 같은 hostname을 소유할 수 없으며, 환경별 ingress owner는 registry에 정확히 하나만 등록합니다. Prototype이 별도 public 배포를 필요로 하면 preview·staging zone 또는 명시적인 별도 endpoint를 등록합니다.

-proto-web으로 기계적으로 치환하거나 platform token을 자동 삽입하지 않습니다. Prototype 종료 시에는 다음 중 실제 소유권 결정에 맞는 방식을 선택합니다.

  1. prototype 저장소를 reference·archive로 유지하고 stable 저장소를 별도로 운영
  2. 같은 저장소를 stable delivery로 전환해야 할 명확한 이유가 있을 때만 migration ADR로 rename

-proto.net, stable이 .com이라는 자동 TLD 규칙도 두지 않습니다. Product와 environment의 zone은 registry가 결정합니다. 기존 prototype 이름이 있다는 이유로 registry 조건 없는 bare portal, kiosk, center, app 또는 surface-specific service를 신규 저장소에 복제하지 않습니다.

13. 예외와 변경 관리

이 체계는 저장소 수를 기계적으로 늘리기 위한 목록이 아닙니다. 독립적인 코드 소유권과 배포 경계가 있을 때 이름을 부여하는 규칙입니다.

기본 조합에서 벗어나거나 기존 저장소를 분리·통합·rename할 때는 ADR에 다음을 기록합니다.

  • 해결하려는 문제
  • 사용자와 권한 범위
  • 코드와 데이터 소유권
  • 빌드·배포·장애 격리 경계
  • 호출 방향과 인증·권한 검증 위치
  • 기존 저장소와의 중복 제거 계획
  • 이름을 선택한 이유와 검토한 대안
  • GitHub·CI·배포·DNS·인증서·문서 전환 순서
  • allowed host, CORS, CSP, OAuth·SAML callback, WebAuthn RP ID, cookie scope 영향
  • 결제 callback·webhook 등 provider allowlist와 POST 병행 수신 계획
  • canonical·alternate URL, redirect·proxy 기간, 관측 지표와 rollback 조건

전환할 때는 새 DNS와 인증서를 먼저 검증하고, 애플리케이션·인증·provider 설정을 바꾼 뒤 repo와 CI/CD 연결을 전환합니다. 기존 GET·HEAD 주소는 308 redirect alias로 유지할 수 있지만, callback·webhook POST는 provider 설정 전환이 끝날 때까지 redirect에 의존하지 않고 proxy 또는 병행 수신합니다.

단일 default portal에 두 번째 audience가 추가되면 기존 bare surface와 hostname의 의미를 원래 audience로 동결하고, 기존·신규 portal 모두 {audience}-portal canonical identity로 전환합니다. Bare hostname은 원래 audience의 legacy alias로만 유지하고 새 default에 재할당하지 않습니다. Audience가 다시 하나로 줄어도 자동으로 bare 이름으로 되돌리지 않습니다.

Unified app 경계가 분리되면 console과 portal 규칙에 따른 저장소·hostname을 각각 생성합니다. 기존 app hostname은 route-aware legacy router 또는 alias로만 유지하고 어느 한 surface의 canonical 이름으로 재할당하지 않습니다. 이후 재통합도 자동 복귀가 아니라 새 ADR 대상입니다.

14. 참고한 업계 용례와 패턴