한국어
저장소·호스트 네이밍 — 상세 규칙
상태: 확정
적용 대상: 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}핵심 결정은 다음과 같습니다.
- Leyve는
console,customer-portal,staff-portal,customer-kiosk,staff-kiosk,partner-center,ops-center,www를 기본 surface ID로 사용합니다. - 각 제품은 허용 surface 집합
S(product)를 registry에 따로 등록합니다. - Portal audience가 정확히 하나이고 그 audience를 immutable default로 등록한 제품만 bare
portal을 사용할 수 있습니다. Audience가 둘 이상이면 모두{audience}-portal을 사용합니다. - 관리자와 사용자의 repository·deployable·origin·release 경계가 모두 같고 registry가 승인한 제품만 통합
appsurface를 사용할 수 있습니다.app은 platform·component suffix가 아닙니다. - bare
kiosk,center는 신규 저장소에서 사용하지 않습니다. 예외는 플랫폼의 본사·파트너 공용 앱center(leyve-center,arenity-center)입니다(2026-10-20 KST 오너 결정). - 고객 audience token은
customer로 통일하며 개인·사업자 고객을 모두 포함합니다. 네이밍에consumer-*를 혼용하지 않습니다. staff는 고객사 직원을 뜻합니다. Leysys 본사 운영자는ops입니다.- 반응형·adaptive 앱은 device class를 생략합니다. 실제 전용 delivery에만
mobile,tablet,desktop중 하나를 surface 뒤에 붙입니다. - Hostname은
(product, surface, device?)route tuple을 표현하고 실제 ingress owner 저장소는 registry에서 조회합니다. web,ios,android,macos,windows같은 platform token은 public hostname에 넣지 않습니다.- surface는 client platform 또는
bff와, domain은service,api,worker와 결합합니다. service는 백엔드 업무 서비스이며 full-stack을 뜻하지 않습니다.- Stable 브라우저 surface는 full-stack 구현이어도 기본 platform인
web을 이름에서 생략합니다. ios,android,macos,windows는 기본이 아닌 platform이므로 이름에 명시합니다.-proto는 platform이나 component가 아닌 prototype 전용 suffix이며 그대로 보존합니다.- 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-appsurface-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-workerconsole, 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.netHostname 역파서는 먼저 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를 순서대로 적용합니다.
- terminal suffix가
web이면 legacy 또는 invalid 이름으로 거부 - 전체 나머지가 등록된
server·gateway이면 shared platform - terminal suffix가
proto이면 등록된 prototype descriptor - terminal suffix가 native platform 또는
bff이면 등록된 surface·device 조합 - terminal suffix가
service·api·worker이면 등록된 domain·component 조합 - 위 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여야 합니다. Bareportal과 그 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-]surfaceendpoint 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.netStaging 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 ingress | leyve-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.netSurface 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를 구현할 때 다음 불변식을 검증 계약으로 삼습니다.
- 저장소 이름이 유일하게 parse되며 client·prototype·surface BFF·domain backend·shared platform 중 정확히 하나의 typed descriptor와 일치하는지
- 계산된 canonical hostname과 배포 설정이 일치하는지
- 각 typed descriptor의 serializer 결과가 전체
owner문자열과 일치하고, canonical FQDN과 ingress owner가 모두 고유한지 - alias가 canonical FQDN 하나만 가리키는지
- platform·component·environment·
prototoken이 canonical endpoint label에 섞이지 않았는지 - BFF·domain backend·worker에 public hostname이 자동 생성되지 않았는지
- bare
portal은 portal audience가 정확히 하나이고 immutable default가 등록된 제품에만 존재하며, 같은 audience의 qualified portal과 함께 canonical로 등록되지 않았는지 appsurface는 repository·deployable·origin·release 경계가 모두 같다는 registry assertion이 있고, 같은 device 범위의 내부console·portal과 함께 canonical로 등록되지 않았는지- explicit terminal suffix가 없을 때만 stable web으로 해석되고,
-web이 신규 canonical 이름에 사용되지 않는지 repositoryRenames의 이전·canonical owner가 각각 유일하고 목표 owner의 typed descriptor와 hostname 변경 여부, 상태, active owner, legacy alias 허용 여부가 일치하는지
3. Surface 의미 모델과 제품별 적용
3.1 Leyve 적용 예시와 정렬 순서
이 절과 §7·§8의 Leyve 목록은 공통 문법을 설명하는 제품 적용 예시입니다. 제품별 허용 접점과 실제 inventory·운영 상태의 정본은 Leyve의 네이밍 적용 문서 (새 탭)와 소유 제품의 배포 설정입니다. 이 공통 예시를 갱신한다는 이유만으로 제품의 접점·배포를 추가하지 않습니다.
Leyve 문서, 카탈로그, 대시보드에서 surface 저장소를 나열할 때는 다음 순서를 사용합니다.
| 순서 | surface ID | canonical 운영 hostname | 정의 |
|---|---|---|---|
| 1 | console | console.leyve.net | 고객사 관리자·실무자가 Leyve 핵심 업무를 수행하는 기본 workspace |
| 2 | customer-portal | customer-portal.leyve.net | 고객이 자신의 정보·계약·서비스를 이용하는 self-service 접점 |
| 3 | staff-portal | staff-portal.leyve.net | 고객사 직원이 개인 업무와 직원 self-service를 처리하는 접점 |
| 4 | customer-kiosk | customer-kiosk.leyve.net | 고객이 공용 단말에서 조회·결제 등 짧은 업무를 처리하는 접점 |
| 5 | staff-kiosk | staff-kiosk.leyve.net | 고객사 직원이 공용 터치 단말에서 출퇴근·휴가 등 빠른 업무를 처리하는 접점 |
| 6 | partner-center | partner-center.leyve.net | 총판·리셀러가 자기 고객·결제·운영을 관리하는 backoffice |
| 7 | ops-center | ops-center.leyve.net | Leysys 본사가 고객·파트너·CRM·결제·정책을 통합 관리하는 backoffice |
| 8 | www | www.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-www3.2 Audience 어휘
| audience | 의미 | 포함하지 않는 대상 |
|---|---|---|
customer | 해당 접점의 서비스를 이용하는 개인·사업자 고객 및 그 대표 사용자 persona | 직원 업무의 staff, 총판·리셀러, Leysys 본사 운영자 |
staff | 고객사 또는 현장 조직 소속자의 employee self-service persona | Leysys 본사 직원, 파트너 관리자 |
partner | Leysys의 총판·리셀러와 그 관리 사용자 | 일반 고객, Leysys 본사 운영자 |
ops | Leysys 본사에서 고객·파트너·플랫폼을 운영하는 사용자 | 고객사 직원, 파트너 사용자 |
voter | Leyvote에서 투표에 참여하는 사용자 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 ID | audience·권한 맥락 | 접점 유형 | 기능과 흐름 |
|---|---|---|---|
console | 고객사 관리자·권한 있는 실무자 | console | 조직의 핵심 업무 실행 |
customer-portal | customer | portal | 고객용 전체 셀프서비스 |
staff-portal | staff | portal | 직원용 전체 셀프서비스 |
customer-kiosk | customer | kiosk | 고객용 최소 업무·짧은 유도 흐름 |
staff-kiosk | staff | kiosk | 직원용 최소 업무·짧은 유도 흐름 |
partner-center | partner | center | 담당 고객·계약·운영 관리 |
ops-center | ops | center | 본사 고객·파트너·플랫폼 운영 |
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.netBare 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.netapp은 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
windowsweb: 브라우저로 제공되는 앱입니다. 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-windowsCSS breakpoint, 레이아웃 차이, 태블릿 사용 비중만으로 저장소를 나누지 않습니다. 브라우저의 viewport나 user-agent만으로 물리 기기 종류를 완전히 증명할 수도 없습니다. 따라서 이름은 하드웨어 감지 결과가 아니라 지원·배포 계약을 뜻하며 runtime 차단 정책은 별도로 정의합니다. iphone, ipad, galaxy 같은 제품명과 m, p, d 축약은 사용하지 않습니다.
허용되는 대표 조합은 다음과 같습니다.
| client platform | device class 생략 | 허용할 수 있는 분리형 device class |
|---|---|---|
web | 반응형 web | mobile, tablet, desktop |
ios | iOS/iPadOS adaptive app | mobile, tablet |
android | Android adaptive app | mobile, tablet |
macos | macOS desktop app | 없음; desktop은 중복이므로 생략 |
windows | Windows adaptive app | tablet, 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로 먼저 결정합니다.
- platform별 delivery 저장소와 공유 package로 분리
- 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, bff | service, api, worker | host-bearing web owner만 canonical host 소유 |
| Domain | service, api, worker | client platform suffix | 없음 |
| Shared platform | server, gateway | surface·domain 전용 suffix | gateway의 예약 api만 명시 가능 |
교차 예외는 다음 두 경우만 인정합니다.
- 한 surface만을 위한 백엔드 조합 계층은
{surface-id}[-{device-class}]-bff로 표현합니다. - 하나의 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-bffBFF에 여러 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-serviceservice는 full-stack을 뜻하지 않습니다.
6.3 api
API 계약과 배포 생명주기가 service 구현과 실제로 분리될 때 사용합니다.
text
leyve-auth-apiservice가 HTTP API를 제공한다는 이유만으로 api 저장소를 추가하지 않습니다. 특정 surface만을 위한 API 조합 계층이라면 bff가 더 정확합니다.
6.4 worker
큐 소비, 배치, 스케줄 작업처럼 비동기 실행이 독립적으로 배포·확장·격리될 때 사용합니다.
text
leyve-billing-worker같은 프로세스에서 실행되는 단순 background job은 별도 저장소로 만들지 않습니다.
6.5 server
여러 업무 영역을 함께 제공하는 공유 백엔드 또는 모놀리스입니다.
text
leyve-serverserver와 service의 차이는 크기가 아니라 소유 경계입니다.
- 여러 업무 영역을 하나의 배포 단위가 소유하면
server - 하나의 bounded context가 독립 배포되면
{domain}-service
leyve-server가 이미 담당하는 기능을 같은 책임의 {domain}-service로 중복 생성하지 않습니다. 분리할 때는 데이터 소유권, 호출 경계, 전환 순서를 ADR에 기록합니다.
6.6 gateway
제품 전체의 공통 ingress, 라우팅, 인증 위임, rate limit 등 경계 기능을 담당합니다.
text
leyve-gatewaygateway에는 domain 업무 규칙을 넣지 않습니다. gateway가 하나의 surface만을 위해 응답을 조합한다면 그 역할은 BFF에 더 가깝습니다.
6.7 Backend hostname 경계
저장소가 배포된다는 이유만으로 public hostname을 자동 생성하지 않습니다.
| component | 기본 network identity |
|---|---|
| surface BFF | web surface와 same-origin인 /api 또는 gateway 뒤의 route |
domain service·api | private zone 또는 platform service discovery |
server | private ingress |
worker | listener가 없으면 hostname 없음 |
gateway | registry가 승인한 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: 권한을 가진 관리자·실무자의 핵심 업무 workspacestaff-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 scope7.5 WWW
www는 로그인 후 핵심 업무를 수행하는 제품 surface가 아니라 불특정 방문자를 위한 공개 홍보·정보 surface입니다.
- 브랜드와 회사 소개
- 제품·기능·가격 안내
- 고객 사례와 콘텐츠
- 게시판, 상담·도입 문의
portal,console등 제품 surface로의 진입
기본 이름은 다음과 같습니다.
text
leyve-wwwwww는 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-console | console.leyve.net |
leyve-customer-portal | customer-portal.leyve.net |
leyve-staff-portal | staff-portal.leyve.net |
leyve-customer-kiosk | customer-kiosk.leyve.net |
leyve-staff-kiosk | staff-kiosk.leyve.net |
leyve-partner-center | partner-center.leyve.net |
leyve-ops-center | ops-center.leyve.net |
leyve-www | www.leyve.net |
Device 전용 delivery는 같은 surface 그룹에 둡니다. Raw 사전순은 같은 surface를 모으지만 device의 업무상 순서까지 보장하지 않으므로 catalog는 별도 ordinal을 사용합니다.
| 저장소 | canonical 운영 hostname |
|---|---|
leyve-customer-portal-mobile | mobile-customer-portal.leyve.net |
leyve-staff-kiosk-tablet | tablet-staff-kiosk.leyve.net |
leyve-ops-center-desktop | desktop-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-workerDomain 저장소는 카탈로그에서 알파벳순으로 나열합니다. Surface 저장소에는 제3.1절의 고정 순서를 적용합니다.
8.4 Shared platform
text
leyve-gateway
leyve-server9. 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 절차를 따릅니다.
- 사용자에게 직접 제공되는 접점인가?
- 공개 홍보·정보 →
www - 관리자와 사용자의 repository·deployable·origin·release 경계가 모두 같음 → registry 승인 후
app - 분리된 고객사 관리자·실무자의 핵심 workspace →
console - 전체 셀프서비스에서 portal audience가 정확히 하나이고 immutable default임 →
portal - Portal audience가 둘 이상인 전체 셀프서비스 →
{audience}-portal - 현장·공용 단말에서 최소 업무를 짧게 처리하고 사용자 세션을 정리하는 접점 →
{audience}-kiosk - 고객·조직·결제 운영 backoffice → audience +
center
- 공개 홍보·정보 →
- 저장소 또는 deployable·build·release와 지원 device 계약이 모두 분리되는가?
- 아니면 device class 생략
- 맞으면 surface 뒤에
mobile,tablet,desktop중 하나 추가 - web이면 독립 canonical host도 필수; native이면 hostname 조건 없음
- prototype 전용 저장소인가?
- 맞으면
{prototype-scope}[-{device-class}]-proto; platform suffix를 덧붙이지 않음 - public 배포가 있으면 delivery platform과 ingress owner를 registry에 명시
- 아니면 stable client·backend 문법을 계속 판정
- 맞으면
- 어느 client platform에 배포하는가?
web이면 suffix 생략ios,android,macos,windows이면 해당 전체 token을 suffix로 명시
- 한 저장소가 둘 이상의 client platform을 함께 산출하는가?
- 맞으면 이름을 만들기 전에 multi-platform architecture ADR 작성
- web인가?
- 맞으면 platform suffix 없이 저장소 이름을 만들고
(surface, device?)로 canonical hostname을 계산한 뒤 owner 중복 검사 - 아니면 자동 public hostname을 만들지 않음
- 맞으면 platform suffix 없이 저장소 이름을 만들고
- 한 surface만을 위한 독립 조합 backend인가?
{surface-id}[-{device-class}]-bff; public host는 자동 생성하지 않음
- 하나의 업무 능력과 규칙을 소유하는가?
{domain}-service
- API 계약 또는 비동기 실행이 별도로 배포되는가?
{domain}-api또는{domain}-worker
- 여러 업무 영역을 함께 제공하는 공유 backend인가?
{repository-prefix}-server
- 제품 전체의 공통 ingress인가?
{repository-prefix}-gateway
- 해당 제품의 기존 공유 backend나 다른 저장소와 책임이 중복되는가?
- 중복이면 새 저장소를 만들지 않고 기존 책임을 사용하거나 extraction ADR을 작성
위 질문에 명확히 답하지 못하면 저장소를 먼저 만들지 않습니다.
11. 피해야 할 이름과 권장 대안
| 피해야 할 이름 | 이유 | 권장 대안 |
|---|---|---|
leyve-portal | Leyve는 portal audience가 복수이고 default portal이 미등록 | leyve-customer-portal 또는 leyve-staff-portal |
leyve-kiosk | audience가 없음 | 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-kiosk | Kiosk는 전용 기기가 아니라 Portal과 나란한 접점 유형 | leyve-customer-kiosk |
leyve-console-service | surface가 domain 규칙을 소유하는 것처럼 보임 | 화면 전용은 leyve-console-bff, 업무는 {domain}-service |
leyve-console-api | surface 조합 API인지 domain API인지 모호함 | 화면 전용은 leyve-console-bff |
leyve-service | 어떤 업무 backend인지 알 수 없음 | leyve-{domain}-service |
leyve-console-app | app을 terminal platform suffix로 잘못 사용 | leyve-console; 실제 통합 surface라면 registry 승인 후 {product}-app |
leyve-console-web | 기본 platform인 web을 불필요하게 명시 | leyve-console |
leyve-console-mobile-web | device 전용 web에도 web을 불필요하게 명시 | leyve-console-mobile |
leyve-mobile-console | device 기준으로 정렬되고 표준 tuple 순서와 다름 | leyve-console-mobile |
leyve-console-iphone | 특정 제품명에 종속 | leyve-console-mobile-ios |
leyve-console-ipad | 특정 제품명에 종속 | leyve-console-tablet-ios |
mobile-portal.leyve.net | Leyve는 portal audience가 복수이고 default portal이 미등록 | mobile-customer-portal.leyve.net |
m-customer-portal.leyve.net | device 축약이 모호함 | mobile-customer-portal.leyve.net |
mobile.customer-portal.leyve.net | device를 별도 DNS 계층으로 만들어 인증서·운영 경계가 복잡함 | mobile-customer-portal.leyve.net |
console-web.leyve.net | platform을 hostname에 노출 | console.leyve.net |
prod.console.leyve.net | environment 위치와 production 기본값이 다름 | console.leyve.net |
mobile-customer-portal.development.leyve.net | dev와 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 종료 시에는 다음 중 실제 소유권 결정에 맞는 방식을 선택합니다.
- prototype 저장소를 reference·archive로 유지하고 stable 저장소를 별도로 운영
- 같은 저장소를 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입니다. 다음 순서를 따릅니다.
- 목표 이름 충돌과 기존 suffix 없는 저장소의 의미를 검사합니다.
repositoryRenames에 이전 owner, canonical owner,hostnameChanged: false, active owner, legacy alias 허용 여부와 상태를 등록합니다.- GitHub 저장소를 rename하고 package·Git remote·CI/CD·배포 프로젝트·IaC·catalog·문서 참조를 canonical owner로 전환합니다.
- 기존 hostname에서 새 owner의 build·deploy·health check를 검증하고 rollback 지점을 유지합니다.
- 전환이 끝나면 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. 참고한 업계 용례와 패턴
- Microsoft — Customer portal administration (새 탭)
- Microsoft — Manage customers in Partner Center (새 탭)
- Microsoft Azure Architecture Center — Backends for Frontends pattern (새 탭)
- Microsoft Azure Architecture Center — Domain analysis (새 탭)
- Backstage — Creating the catalog graph (새 탭)
- Apple Developer — Building apps with a responsive UI (새 탭)
- Android Developers — Adaptive layouts (새 탭)
- RFC 1035 — Preferred name syntax and DNS size limits (새 탭)
- RFC 1123 — Hostname first-character rule (새 탭)
- RFC 9525 — TLS wildcard matching (새 탭)
- AWS Certificate Manager — Wildcard certificate scope (새 탭)
- Google Search Central — Mobile-first indexing and separate URLs (새 탭)
- RFC 6454 — Web origin (새 탭)
- RFC 6265 — Cookie Domain attribute (새 탭)