Skip to content

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

상태: 확정

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

정본: Leysys Docs의 이 문서. 제품별 적용·구현 상태는 각 제품 문서가 소유합니다.

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

2026-10-01 KST에 Leyve Docs에서 공통 정본을 이관했습니다. 후속 사용자 결정에 따라 customer 표기를 재확인하고, Portal·Kiosk를 나란한 접점 유형으로 정리했습니다. 기존 surface ID·저장소·hostname·route tuple은 이 문서 정리로 변경하지 않습니다. 문서 소유권을 함께 확인합니다.

1. 결정 ​

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

이 문법의 product는 Leyve·LeyVote 같은 플랫폼, 프로덕트 또는 단독 브랜드의 route namespace입니다. 특정 플랫폼·브랜드에 속하지 않는 회사 공용 도구는 leysys를 namespace로 씁니다(예: leysys-pricebook, leysys-design). 업무 모듈 키(vote, crm)나 결제 catalog의 product_key와 같은 식별자라는 뜻은 아닙니다. client-platform은 web·iOS 같은 실행 환경, shared-platform은 server·gateway 같은 공유 실행 기반의 기술 분류입니다. 고객이 구매하는 플랫폼·Core·모듈과 기술 문법의 platform을 서로 치환하지 않습니다.

업무 모듈은 업무 상태·규칙의 소유 경계이고 repository·service는 코드·배포 경계입니다. 서로 1:1이어야 한다는 규칙은 없습니다. 한 저장소가 여러 모듈을 구현하거나 한 모듈이 여러 배포 구성 요소를 사용할 수 있으므로 N:M 관계와 실제 소유권을 제품 아키텍처에서 설명합니다.

text
# 사용자 접점
{repository-prefix}-{surface-id}[-{device-class}][-{non-default-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는 신규 저장소에서 사용하지 않습니다. 예외는 플랫폼의 본사·파트너 공용 앱 center(leyve-center, arenity-center)입니다(2026-10-20 KST 오너 결정).
  6. 고객 audience token은 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 구현이어도 기본 platform인 web을 이름에서 생략합니다.
  14. ios, android, macos, windows는 기본이 아닌 platform이므로 이름에 명시합니다.
  15. -proto는 platform이나 component가 아닌 prototype 전용 suffix이며 그대로 보존합니다.
  16. environment는 저장소가 아니라 DNS zone으로, legacy·custom 주소는 alias로 관리합니다.

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

2. 이름 문법 ​

2.1 사용자 접점 ​

text
web    = {repository-prefix}-{surface-id}[-{device-class}]
native = {repository-prefix}-{surface-id}[-{device-class}]-{native-platform}

예:

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

surface-id는 제품별 registry 집합 S(product)에 등록된 하나의 완성된 식별자입니다. customer-portal·customer-kiosk처럼 audience와 접점 유형을 결합한 값도 하나의 surface ID로 취급합니다. portal과 kiosk는 같은 접점 유형 위치를 차지하고, 전용 기기는 그 뒤의 별도 위치에 둡니다. 이름 문법이 모든 audience × 유형 조합을 강제하지 않습니다. portal은 단일 default portal 조건을, app은 unified app 조건을 충족한 제품에서만 등록할 수 있습니다. device class는 파일명·카탈로그 정렬이 surface별로 모이도록 surface ID 뒤에 둡니다. Terminal platform suffix가 없으면 web, 있으면 등록된 native platform으로 해석합니다.

Prototype 저장소는 제12절의 별도 문법을 사용합니다. proto를 client platform으로 해석하거나 -proto를 단순히 제거해 stable 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
web    = {repository-prefix}-{surface-id}-{device-class}
native = {repository-prefix}-{surface-id}-{device-class}-{native-platform}

예:

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

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

text
repository-prefix → surface-id → device class(선택) → non-default 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}, 이름에 명시하는 platform 집합을 Kexplicit = K − {web}로 둡니다. 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

Rclient(p, s, ε, web) = repoPrefix(p) + "-" + s
Rclient(p, s, d, web) = repoPrefix(p) + "-" + s + "-" + d

Rclient(p, s, ε, k) = repoPrefix(p) + "-" + s + "-" + k       # k ∈ Kexplicit
Rclient(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까지만 복원하며 client platform·proto 같은 repository kind를 복원하지 않습니다. 정확한 전단사는 실제 registry에 등록된 (ingress-owner repository, environment) ↔ canonical hostname에만 성립합니다. 저장소는 왼쪽부터 product → surface → device → kind/platform으로 분류하고, DNS는 zone 왼쪽의 단일 endpoint label에 device → surface 순서로 직렬화합니다.

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

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

Rclient(leyve, console, ε, ios)
= leyve-console-ios
# native client이므로 public hostname 자동 생성 없음

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

Hostname 역파서는 먼저 full canonical hostname을 예약 endpoint registry에서 조회합니다. 일치하면 그 registry의 owner와 environment를 반환하고 일반 surface 이름을 생성하지 않습니다. 예약값이 아니면 모든 등록 Zone(p, e) 중 dot boundary에서 일치하는 가장 긴 suffix를 유일하게 선택해 (p, e)를 복원합니다. 남은 단일 endpoint label의 첫 token이 device 예약어이고 나머지가 S(p)에 등록된 surface이면 (d, s), 아니면 등록된 responsive s로 읽습니다. 예약 endpoint는 S(p)에 넣지 않습니다.

Repository 역파서는 product prefix를 유일하게 제거한 뒤 다음 typed branch를 순서대로 적용합니다.

  1. terminal suffix가 web이면 legacy 또는 invalid 이름으로 거부
  2. 전체 나머지가 등록된 server·gateway이면 shared platform
  3. terminal suffix가 proto이면 등록된 prototype descriptor
  4. terminal suffix가 native platform 또는 bff이면 등록된 surface·device 조합
  5. terminal suffix가 service·api·worker이면 등록된 domain·component 조합
  6. 위 suffix가 없을 때만 등록된 surface·device 조합의 stable web

각 branch는 typed registry의 exact match가 정확히 하나일 때만 유효합니다. 실제 hostname owner는 repository 문자열로 만들지 않고 deployment registry에서 조회합니다. 유일한 역함수를 보장하기 위해 다음을 지킵니다.

  • surface ID는 device 예약어와 같거나 mobile-, tablet-, desktop-으로 시작할 수 없습니다.
  • suffix 없는 web과의 유일한 역파싱을 위해 surface ID는 device, native platform, repository kind, backend component 예약 token으로 끝날 수 없습니다. 현재 예약 suffix는 web, mobile, tablet, desktop, ios, android, macos, windows, proto, bff, service, api, worker, server, gateway입니다.
  • Prototype scope도 device token으로 끝날 수 없습니다. Product surface가 아닌 prototype scope는 별도 descriptor로 등록하고 전체 serializer 결과가 다른 branch와 충돌하지 않는지 검사합니다.
  • repository prefix와 제품의 대응, 그리고 각 zone 문자열과 (product, environment)의 대응은 유일해야 합니다. leyve.net과 staging.leyve.net처럼 zone이 중첩될 수 있으므로 역파서는 가장 긴 dot-boundary suffix를 선택합니다. 같은 zone 문자열을 둘 이상의 tuple에 등록하지 않습니다.
  • (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.net과 mobile-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-proto ↔ docs.leyve.net
api제품 외부 API ingressleyve-gateway ↔ api.leyve.net

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

2.7 Origin, cookie와 검색 경계 ​

customer-portal.leyve.net과 mobile-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와 자동 검증 ​

아래 YAML은 등록 모델의 예시이며 실제 배포 inventory나 운영 registry 파일이 아닙니다. 이 문서의 hostname·owner 예시는 배포 완료의 증거가 아닙니다. 실제 사용 여부·owner·DNS는 각 제품의 배포 설정과 운영 확인 결과로 검증합니다. 아래 CI 항목은 구현할 검증 계약이며, 이 문서 이관에서 운영 registry나 validator의 배포·실행을 확인한 것은 아닙니다.

Stable client 후보 집합을 Aclient ⊆ {(p,s,d,k) | p∈P, s∈S(p), d∈D, k∈K}로 두고 prototype은 별도 repositoryKind=prototype descriptor로 등록합니다. 실제 public host 배포 집합 Vhost는 clientPlatform=web인 client, deliveryPlatform=web인 host-bearing prototype, 명시적으로 등록된 reserved endpoint owner의 artifact·environment pair 합집합입니다. Gateway 같은 shared platform도 reserved endpoint owner로 등록된 경우에만 이 집합에 들어갑니다. 모든 곱집합을 자동 생성하지 않고 실제 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
    domains: [auth, billing, crm, subscription]
    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
  surface-bff: 20
  prototype: 90
  domain-backend: 100
  shared-platform: 110
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
    environment: production
  api:
    owner: leyve-gateway
    hostname: api.leyve.net
    environment: production

artifacts:
  - owner: leyve-console
    repositoryKind: client
    product: leyve
    surface: console
    device: responsive
    clientPlatform: web
  - owner: leyve-console-bff
    repositoryKind: surface-bff
    product: leyve
    surface: console
    device: responsive
    backendComponent: bff
  - owner: leyve-billing-service
    repositoryKind: domain-backend
    product: leyve
    domain: billing
    backendComponent: service
  - owner: leyve-server
    repositoryKind: shared-platform
    product: leyve
    sharedPlatform: server
  - owner: leyve-gateway
    repositoryKind: shared-platform
    product: leyve
    sharedPlatform: gateway
  - 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
    environments: [production, staging, dev]
  - artifact: leyve-docs-proto
    environments: [production]
  - artifact: leyvote-portal-mobile-proto
    environments: [production]
  - artifact: leysign-app-proto
    environments: [production]
  - artifact: leyve-gateway
    environments: [production]

repositoryRenames:
  - previousOwner: leyve-console-web
    canonicalOwner: leyve-console
    reason: omit-default-web-platform
    hostnameChanged: false
    activeOwner: leyve-console
    legacyAliasAccepted: false
    status: completed

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

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

text
platformOrdinal(a) = platformOrder[a.clientPlatform]       # stable client; web은 이름에서 생략
platformOrdinal(a) = platformOrder[a.deliveryPlatform]     # metadata가 있는 prototype
platformOrdinal(a) = 0                                     # client가 아닌 surface artifact

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

이 정렬식은 client·surface BFF·surface prototype에만 적용합니다. Reserved endpoint artifact는 reservedEndpointOrder를, domain backend와 shared platform은 각 typed catalog의 순서를 사용합니다. Raw filename 사전순은 surface 그룹 탐색에만 사용하고 device·kind·platform의 업무상 순서를 결정하지 않습니다.

운영 registry의 validator를 구현할 때 다음 불변식을 검증 계약으로 삼습니다.

  1. 저장소 이름이 유일하게 parse되며 client·prototype·surface BFF·domain backend·shared platform 중 정확히 하나의 typed descriptor와 일치하는지
  2. 계산된 canonical hostname과 배포 설정이 일치하는지
  3. 각 typed descriptor의 serializer 결과가 전체 owner 문자열과 일치하고, canonical FQDN과 ingress owner가 모두 고유한지
  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로 등록되지 않았는지
  9. explicit terminal suffix가 없을 때만 stable web으로 해석되고, -web이 신규 canonical 이름에 사용되지 않는지
  10. repositoryRenames의 이전·canonical owner가 각각 유일하고 목표 owner의 typed descriptor와 hostname 변경 여부, 상태, active owner, legacy alias 허용 여부가 일치하는지

3. Surface 의미 모델과 제품별 적용 ​

3.1 Leyve 적용 예시와 정렬 순서 ​

이 절과 §7·§8의 Leyve 목록은 공통 문법을 설명하는 제품 적용 예시입니다. 제품별 허용 접점과 실제 inventory·운영 상태의 정본은 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

leyve-customer-portal
leyve-staff-portal

leyve-customer-kiosk
leyve-staff-kiosk

leyve-partner-center
leyve-ops-center

leyve-www

3.2 Audience 어휘 ​

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

2026-10-01 KST 사용자 결정으로 고객 audience token은 customer로 통일하고 consumer-portal·consumer-kiosk를 혼용하지 않습니다. 개인·개인사업자·법인사업자 고객을 모두 포함합니다. 이는 내부 네이밍 선택이며 consumer를 사업자가 아닌 고객으로 한정하거나 일반 업무·법률·기술 용어에서 금지하는 결정이 아닙니다.

end user는 실제 사용자라는 역할 설명입니다. Console의 실무자와 staff도 end user일 수 있으므로 customer의 동의어나 별도 대체 audience로 사용하지 않습니다. 플랫폼과 계약한 고객사와 그 고객사가 서비스를 제공하는 최종 고객은 같은 권한 주체가 아닙니다. 제품 문서는 customer 관계의 기준점·계약·대리권·데이터 범위를 명시합니다. 실제 Leyve 적용은 Leyve 네이밍 (새 탭)이 소유합니다.

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

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

3.3 Audience·접점 유형·전용 기기 ​

Surface의 의미는 아래 항목으로 설명합니다. Route identity는 기존 (product, surface-id, device-class?)를 유지합니다. 이 설명을 이유로 새 runtime schema나 권한 enum을 자동 추가하지 않습니다.

항목의미예
audience누구의 업무·권한 맥락인가customer, staff, partner, ops
접점 유형어떤 업무 범위와 흐름을 제공하는가console, center, portal, kiosk
device class실제로 분리된 delivery가 지원하는 전용 기기mobile, tablet, desktop; 반응형은 생략
세션·권한 계약접점에서 어떤 인증·접근·종료·초기화를 보장하는가제품 runtime이 소유하는 세션 수명과 데이터 접근 범위
접점 유형판정 기준
console고객사 관리자·권한 있는 실무자가 자기 조직의 핵심 업무와 설정을 운영하는 workspace
center서비스 운영자·파트너가 관리 권한으로 담당 고객·조직·계약·운영을 관리하는 backoffice
portal해당 사용자에게 허용된 전체 셀프서비스 기능을 탐색하고 이어서 이용하는 접점
kiosk현장·공용 단말에서 선정된 최소 기능을 짧은 유도 흐름으로 처리하는 접점

네 유형은 네이밍의 같은 위치에 놓습니다. 이 분류는 사용자가 받는 업무 범위·흐름·권한·세션을 함께 설명합니다. 사람의 소속이나 화면 모양만으로 유형을 고르지 않습니다. 같은 사람도 다른 업무 맥락에서 여러 접점을 이용할 수 있습니다. www는 공개 안내 접점이고, app은 §3.5의 조건을 충족하는 통합 접점 ID입니다.

Console과 Center의 차이는 고객 tenant 내부의 업무 실행 권한과 provider·partner의 고객·플랫폼 운영 권한입니다. Portal의 전체 기능도 해당 audience의 권한 범위 안에서만 제공합니다. Console·Center의 모든 기능을 Portal에 넣는다는 뜻은 아닙니다.

Portal과 Kiosk는 업무 기능을 공유할 수 있지만 별도 접점 유형입니다. Kiosk를 Portal의 하위 모드로 고정하거나 customer-portal-kiosk처럼 기기 suffix 위치에 넣지 않습니다. 태블릿·대형 단말 등 기기 크기와 무관하게 최소 업무·짧은 흐름이 핵심입니다. 같은 태블릿에서도 전체 셀프서비스는 Portal, 선택한 최소 업무는 Kiosk로 구분합니다.

공통 업무 규칙·데이터·권한 검증은 재사용하고, 각 접점은 화면 흐름과 세션 수명을 소유합니다. Kiosk는 완료·취소·timeout·사용자 교대 시 사용자 세션과 개인정보를 정리해야 합니다. 이름이 인증 완료나 세션 초기화의 구현 증거가 되지는 않으며 소유 runtime에서 검증합니다. 선택한 기능·인증 방법·보조 운영자의 권한은 제품이 정의하고, 접점 유형만으로 새 권한을 부여하지 않습니다.

3.4 등록 Surface의 의미 매핑 ​

다음은 공통 문법의 Leyve 적용 예입니다. 각 제품의 접점 정의와 실제 배포 현황은 제품 문서가 소유합니다. 이 표의 정리는 기존 ID·host·repository를 rename하거나 배포를 선언하지 않습니다.

surface IDaudience·권한 맥락접점 유형기능과 흐름
console고객사 관리자·권한 있는 실무자console조직의 핵심 업무 실행
customer-portalcustomerportal고객용 전체 셀프서비스
staff-portalstaffportal직원용 전체 셀프서비스
customer-kioskcustomerkiosk고객용 최소 업무·짧은 유도 흐름
staff-kioskstaffkiosk직원용 최소 업무·짧은 유도 흐름
partner-centerpartnercenter담당 고객·계약·운영 관리
ops-centeropscenter본사 고객·파트너·플랫폼 운영
www불특정 방문자공개 안내공개 열람

접점 유형과 물리적인 저장소·배포 경계는 구분합니다. 유형이 다르다는 이유만으로 모든 조합의 저장소·hostname을 만들지 않으며, 제품이 실제 코드·인증·세션·배포·릴리스 경계를 정하고 registry에 필요한 접점을 등록합니다.

Leyve의 console과 www는 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

예외로 플랫폼은 본사·파트너 공용 앱 하나를 bare center로 등록합니다. leyve-center(center.leyve.net)는 Leyve와 그 프로덕트(LeyVote 등)를, arenity-center(center.arenity.net)는 Arenity와 그 프로덕트(ArenVote)를 맡습니다. 두 앱 모두 Leysys 본사(ops)와 파트너(partner)가 조직 자격으로 범위를 나눠 씁니다. 같은 이름으로 다른 audience의 접점을 만들지 않고, 본사용·파트너용을 따로 배포할 때는 ops-center·partner-center를 씁니다. 프로덕트와 단독 브랜드는 center를 두지 않고 회사 공용 namespace leysys에도 center를 두지 않습니다(2026-10-20 · 10-21 KST 오너 결정).

새 접점이 필요하면 audience·접점 유형·기능 범위·세션·권한과 데이터 범위·독립 배포 필요성을 먼저 기록하고 product registry에 완성된 surface ID를 등록합니다. 이름만으로 새 권한을 부여하지 않습니다.

3.5 Unified App Surface ​

app은 여러 audience와 업무 역할을 하나로 묶는 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로 표준 목록에 추가합니다. 기본 platform web은 저장소 이름에서 생략하고 ios, android, macos, windows만 terminal suffix로 명시합니다. mac, win 같은 축약은 사용하지 않습니다. app은 client platform이 아니므로 terminal platform suffix로 사용하지 않습니다. 제3.5절의 조건을 충족한 제품이 surface 위치에 등록한 app은 이 금지와 다릅니다.

4.2 반응형·adaptive 기본값 ​

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

text
leyve-console           # 기본 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
leyve-console-tablet
leyve-console-desktop

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
Surface기본 web(suffix 생략), ios, android, macos, windows, bffservice, api, workerhost-bearing web owner만 canonical host 소유
Domainservice, api, workerclient platform suffix없음
Shared platformserver, gatewaysurface·domain 전용 suffixgateway의 예약 api만 명시 가능

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

  1. 한 surface만을 위한 백엔드 조합 계층은 {surface-id}[-{device-class}]-bff로 표현합니다.
  2. 하나의 domain을 위한 화면이 실제로 독립 제품·진입점·배포 단위라면 ADR 승인 후 먼저 별도 surface ID를 S(product)에 등록하고 일반 web·native serializer를 사용합니다. 등록하지 않은 domain token을 suffix 없는 web surface로 직접 해석하지 않습니다.

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

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 → 기본 web 이름인 {surface-id}
  • 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

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

  • 여러 업무 영역을 하나의 배포 단위가 소유하면 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입니다.

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

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

7.2 Customer Portal과 Staff Portal ​

customer-portal은 개인·개인사업자·법인사업자 고객이 자신의 정보와 서비스를 이용하는 접점입니다. 해당 고객에게 허용된 전체 셀프서비스 기능을 탐색하고 이어서 처리합니다. mobile·tablet 전용 디자인도 기능을 최소화하는 표기가 아니며, 각 전용 delivery의 지원 기능과 권한은 제품이 명시합니다.

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

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

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

7.3 Customer Kiosk와 Staff Kiosk ​

customer-kiosk는 고객이 공용 또는 현장 단말에서 선정된 최소 기능을 짧은 유도 흐름으로 처리하는 접점입니다. Portal과 공통 업무 기능을 공유하되 화면 흐름·세션 수명을 별도로 소유합니다. 다음은 선택 가능한 업무 예이며 모든 Kiosk에 전부 제공하는 필수 목록이 아닙니다.

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

staff-kiosk는 고객사 직원이 공용 단말에서 선정된 최소 업무를 빠르게 처리하는 접점입니다.

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

태블릿에서 주로 사용하더라도 기본 이름은 각각 leyve-customer-kiosk, leyve-staff-kiosk입니다. tablet 전용 저장소·빌드·배포가 따로 있을 때만 leyve-customer-kiosk-tablet ↔ tablet-customer-kiosk.leyve.net 또는 leyve-staff-kiosk-tablet ↔ tablet-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
  → partner-center-bff
    → customer / partner / billing domain

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

7.5 WWW ​

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

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

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

text
leyve-www

www는 surface이고 생략된 기본 client platform은 web입니다. Canonical hostname은 www.leyve.net입니다. Canonical surface hostname을 바꾸면 저장소 identity도 함께 검토하는 migration이며, 단순 legacy·custom alias 추가는 저장소 이름에 영향을 주지 않습니다.

SSR 서버, 게시판 조회, 문의 폼, 이메일 전송 route가 있어도 주 제공물이 브라우저 앱이고 서버 기능이 그 surface를 지원한다면 기본 web 이름인 leyve-www입니다.

8. 표준 저장소 예시 ​

8.1 Web surface ​

저장소canonical 운영 hostname
leyve-consoleconsole.leyve.net
leyve-customer-portalcustomer-portal.leyve.net
leyve-staff-portalstaff-portal.leyve.net
leyve-customer-kioskcustomer-kiosk.leyve.net
leyve-staff-kioskstaff-kiosk.leyve.net
leyve-partner-centerpartner-center.leyve.net
leyve-ops-centerops-center.leyve.net
leyve-wwwwww.leyve.net

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

저장소canonical 운영 hostname
leyve-customer-portal-mobilemobile-customer-portal.leyve.net
leyve-staff-kiosk-tablettablet-staff-kiosk.leyve.net
leyve-ops-center-desktopdesktop-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}]
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을 붙이지 않습니다. 등록된 surface에 terminal suffix가 없으면 stable web으로 판정합니다. Prototype은 별도 -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
    • 전체 셀프서비스에서 portal audience가 정확히 하나이고 immutable default임 → portal
    • Portal audience가 둘 이상인 전체 셀프서비스 → {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이면 suffix 생략
    • ios, android, macos, windows이면 해당 전체 token을 suffix로 명시
  5. 한 저장소가 둘 이상의 client platform을 함께 산출하는가?
    • 맞으면 이름을 만들기 전에 multi-platform architecture ADR 작성
  6. web인가?
    • 맞으면 platform suffix 없이 저장소 이름을 만들고 (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인가?
  • {repository-prefix}-server
  1. 제품 전체의 공통 ingress인가?
  • {repository-prefix}-gateway
  1. 해당 제품의 기존 공유 backend나 다른 저장소와 책임이 중복되는가?
  • 중복이면 새 저장소를 만들지 않고 기존 책임을 사용하거나 extraction ADR을 작성

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

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

피해야 할 이름이유권장 대안
leyve-portalLeyve는 portal audience가 복수이고 default portal이 미등록leyve-customer-portal 또는 leyve-staff-portal
leyve-kioskaudience가 없음leyve-customer-kiosk
leysys-center회사 공용 namespace에는 center를 두지 않음(2026-10-20 KST)플랫폼별 leyve-center · arenity-center
leyve-consumer-portal고객 audience를 customer로 통일한 명명 결정과 불일치leyve-customer-portal
leyve-customer-portal-kioskKiosk는 전용 기기가 아니라 Portal과 나란한 접점 유형leyve-customer-kiosk
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; 실제 통합 surface라면 registry 승인 후 {product}-app
leyve-console-web기본 platform인 web을 불필요하게 명시leyve-console
leyve-console-mobile-webdevice 전용 web에도 web을 불필요하게 명시leyve-console-mobile
leyve-mobile-consoledevice 기준으로 정렬되고 표준 tuple 순서와 다름leyve-console-mobile
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.netdev와 development를 혼용mobile-customer-portal.dev.leyve.net

12. Prototype 전용 suffix -proto ​

-proto는 web, 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과 leyve-console-proto가 동시에 같은 hostname을 소유할 수 없으며, 환경별 ingress owner는 registry에 정확히 하나만 등록합니다. Prototype이 별도 public 배포를 필요로 하면 preview·staging zone 또는 명시적인 별도 endpoint를 등록합니다.

-proto를 기계적으로 제거해 stable 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 조건

기존 stable web 저장소는 다음 식으로 새 canonical 이름에 전환합니다.

text
{prefix}-{surface}-web          → {prefix}-{surface}
{prefix}-{surface}-{device}-web → {prefix}-{surface}-{device}

이 전환은 canonical hostname을 바꾸지 않는 repository-only rename입니다. 다음 순서를 따릅니다.

  1. 목표 이름 충돌과 기존 suffix 없는 저장소의 의미를 검사합니다.
  2. repositoryRenames에 이전 owner, canonical owner, hostnameChanged: false, active owner, legacy alias 허용 여부와 상태를 등록합니다.
  3. GitHub 저장소를 rename하고 package·Git remote·CI/CD·배포 프로젝트·IaC·catalog·문서 참조를 canonical owner로 전환합니다.
  4. 기존 hostname에서 새 owner의 build·deploy·health check를 검증하고 rollback 지점을 유지합니다.
  5. 전환이 끝나면 rename 상태를 완료로 바꾸고 새 참조에서 legacy owner 사용을 lint로 막습니다.

충돌하거나 한 저장소가 여러 delivery를 소유하면 자동 변환하지 않고 ADR로 결정합니다. Native platform, -proto, -bff, backend component suffix는 이 migration에서 제거하지 않습니다. Hostname이 그대로이므로 DNS·인증서·CORS·cookie·인증·provider callback 설정은 기본적으로 변경하지 않습니다.

상태는 planned → cutover → completed 단방향으로 전환합니다. planned에서는 previous owner만, cutover와 completed에서는 canonical owner만 active일 수 있습니다. Inventory validator는 planned·cutover에서 registry에 exact match하는 previous owner만 legacy alias로 분류할 수 있고, canonical parser의 정상 이름으로 만들지는 않습니다. completed에서는 legacy alias 허용을 끄고 terminal -web 이름을 거부합니다. 어느 상태에서도 두 owner를 동시에 active로 등록하지 않습니다.

별도 migration에서 canonical hostname도 바뀐다면 새 DNS와 인증서를 먼저 검증하고, 애플리케이션·인증·provider 설정을 바꾼 뒤 ingress owner를 전환합니다. 기존 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. 참고한 업계 용례와 패턴 ​