다크모드
FE handoff — 상품 선택·결제·워크스페이스 활성화
기준 흐름
- 회원가입 확인 →
/onboarding/products - 업무 프리셋 선택 → 상품별 추가/제거 → 사용 규모 입력
- 월 공급가액·VAT·합계 및 결제 방법 확인
- 활성화 성공 →
/workspace/home - 워크스페이스 사이드바는 entitlement가 있는 모듈만 렌더링
- 사이드바
상품 관리에서 같은 구성 화면으로 재진입 - 기존 고객 진입은
/onboarding/products?mode=manage이며 현재 entitlement를 편집 초깃값으로 사용 - 이 경로는
administration/app-view의 자식으로 등록되어 계정·계약 헤더와 aside를 유지한다. - 상품 추가는 즉시, 제거는 다음 결제일 예약 변경으로 구분해 표시
- 신규 Company의 기본 결제 방법은
invoice이며 저장된 결제수단 조회가 연결되기 전에는 임의의 카드를 표시하지 않는다. - 화면의 Company 명칭은
useAccountContext().company에서 읽고Goldnus문자열을 고정하지 않는다. - 레거시 결제수단·결제내역·계약현황 라우트는 가짜 카드와 계약을 렌더하지 않고
/onboarding/products?mode=manage로 redirect한다. administration aside에는 단일상품·계약 관리항목만 노출한다. - 정상 승인·결제 실패·활성화 지연 제어는
?qa=1에서만 노출하고 일반 고객 화면에서는 숨긴다.
계정별 출시 검수 노출
src/composables/productCatalog.js의 implementationStage가 기술 준비도 SSOT다. src/composables/prototypeCompanyAccess.js가 principal의 Company slug/email을 full-preview | implemented-only | entitlement 프로필로 해석하고, useModuleSubscription()이 아래 소비 표면을 제공한다.
표시명과 한·영 용어는 src/composables/productVocabulary.js가 SSOT다. PRODUCT_VOCABULARY의 21개 포트폴리오와 PRODUCT_MODULES의 실행 상품을 합치지 않는다. candidate 어휘를 메뉴·주문·route guard에 자동 노출하면 안 된다.
상품 카드는 한국어 product.name을 제목으로, product.englishName을 바로 아래 subtitle-sm text-neutral-moderate 보조 텍스트로 표시한다. 별도 로컬 CSS나 색상값을 만들지 않는다. 분류는 5개 도메인을 기본으로 하고, 프로퍼티는 PRODUCT_GROUPS의 거래·분양과 운영 제품군을 한 단계 더 사용한다.
availableProducts,availableBundles: 상품 선택·Office 생성에 사용할 노출 허용 목록enabledModules: 워크스페이스 메뉴와 상품 route guard가 사용할 활성 목록hasFullPreviewAccess: CRM 등 catalog 밖 preview 앱 판정isProductExposed(key): hidden product mutation 방지
Goldnus Company 관리자는 server-core 상품 전체를 활성화해 검수한다. Goldnus 직원은 노출 필터 뒤 기존 Office module 배정을 계속 적용한다. Leysys는 catalog 전체와 preview 앱을 검수한다. 일반 계정은 기존 entitlement 흐름을 유지한다.
적용 위치는 워크스페이스 홈 HomePag.vue, aside AppAsideOrg.vue, 상품 선택 ProductOnboardingPag.vue, Office 생성 SheetCreateOfficeArt.vue, AI 비서 링크 AssistantMainOrg.vue, authSession.js route guard다. /crm, /notice, /complaint, /access-control, /calendar, /building은 requiresFullPreviewForPath()를 통과한 Leysys 프로필에서만 직접 열 수 있다.
상품 변경 시 화면에 보이지 않는 기존 module key를 제거 목록으로 해석하면 안 된다. useProductOnboarding()은 currentVisibleModules만 사용자 draft와 비교하고 preservedHiddenModules + draftModules를 서버 checkout의 desired set으로 보낸다. 숨은 상품 토글 입력도 무시한다.
prototype 구현 표면
- 카탈로그/프리셋/권한:
src/composables/useModuleSubscription.js - 구성/가격/결제 상태:
src/composables/useProductOnboarding.js - Supabase seam:
src/composables/productSubscriptionRepo.js - 화면:
src/components/onboarding/products/ProductOnboardingPag.vue - 라우트 셸:
src/router/index.js의 administration 자식/onboarding/products; 화면 루트는 중첩된<main>을 피하기 위해 일반<div>를 사용한다. - 메뉴 게이트:
src/components/workspace/AppAsideOrg.vue - 단계 표시:
src/registry/vue/stepper/*(leysys-designEDS 정본 소비) - 추천 구성은
radio radio-card radio-md radio-primary, 개별 상품은checkbox checkbox-card checkbox-md checkbox-primary정본을 사용한다. 두 표면 모두bg-neutral-minimal을 명시하고, 선택 상태를 별도ring-2로 중첩하지 않는다. - 상품 구성 단계의 우측 요약은
card card-md card-filled card-inset-edged한 개로 구성한다. 모바일에서는 상품 목록 아래로 이동하고 데스크톱에서는lg:sticky사이드 카드로 유지한다. quantities.units와quantities.users는input-group의 짧은 숫자 입력과 inline-end 단위(개,명)로 표시한다.inputmode="numeric",min="1",step="1"을 유지한다.- 같은 카드에서 선택 상품 수와
combinedEstimatedTotal의 VAT 포함 월 예상 이용료를 표시한다. 단계 2의결제 확인하기와이전도 card footer가 소유하며, 페이지 공용 footer는 단계 2에서 렌더하지 않는다. contract-management는 독립 상품이다.contract-billing은PRODUCT_MODULES, Workspace, route entitlement guard에 등록하지 않는다. Billing Core에는 별도 entitlement가 없다.- 과거
/contract-billing/*URL은 호환 route 하나에서/sales/console/transaction으로 redirect한다. 이 route에는moduleKey: contract-billing이나 전용 component를 다시 추가하지 않는다. - 화면에는
임대차관리,회계증빙관리,전자문서 발행,판매·매출채권,구매·매입채무,고정자산관리,고객관계관리를 정식명으로 사용한다. - 영문 UI는
Facility Management,Sales & Accounts Receivable,Procurement & Accounts Payable,Source Document Management,Workflow & Approvals를 사용한다. - 실행 제품
accounting-source-documents는/accounting-source-documents/,accountingSourceDocument*,accounting_source_documents를 같은 도메인 식별자로 사용하며finance*나taxEvidence*alias를 만들지 않는다. supporting-documents는 별도 후보 제품이다. 실행 catalog·route·entitlement에 자동 추가하지 않는다.contract-to-cash는contract-management와sales를 함께 선택하는 편의 preset이다. 화면 아이콘은 EDS/Material 공식contract심볼을 사용하며 별도 로컬 아이콘을 만들지 않는다.- 판매·매출채권, 관리비관리, 임대차관리는 Billing Core의 EDS 패턴과 순수 계산 capability를 재사용할 수 있지만 서로의 store·원장·RPC를 공유하지 않는다. 경계 정본은
docs/decisions/BILLING-FAMILY-BOUNDED-CONTEXTS-2026-07-19.md다.
Supabase 환경에서는 catalog를 읽고 checkout RPC가 반환한 서버 금액과 상태를 사용한다. Vitest 또는 Supabase env가 없는 환경만 mock repository를 사용한다. product_entitlements hydrate 이후에도 isModuleEnabled(key) 소비 표면은 유지한다. 실제품에서는 라우트 자체에도 entitlement guard를 추가해 URL 직접 입력을 차단해야 한다.
구현된 예외 상태
payment_failed: 결제 단계 유지, 오류 Alert와 재시도 제공provisioning: 완료 단계에서 지연 상태 표시, 기존 entitlement 유지active: 신규 구독 활성화 또는 계약 변경 접수 완료- 기존 고객 제거:
pendingChange.effectiveAt까지 메뉴 접근 유지
UX 후속 검증
- 모바일에서 노출 상품 탐색 밀도와 요약 카드까지의 스크롤 길이. 선택 카드는 흰 표면과 1px 상태 테두리를 유지해야 한다.
- 프리셋 변경 시 사용자가 직접 조정한 상품을 덮어쓸지 확인하는 규칙
- 실제 계약 API 기준의 일할 과금·크레딧 금액 표시
- 관리자 승인 대기와 결제수단 변경 sheet
- provisioning 상태 polling, timeout, 재시도 및 알림
셸 회귀 검증
src/router/__tests__/globalIaIntegrity.spec.js에서/onboarding/products의 matched route chain에 administration layout이 포함되는지 검사한다.- 데스크톱·모바일에서 워크스페이스
상품·계약 관리진입 후 계정·계약 메뉴와 Leyve 홈이 유지되어야 한다. productCatalog.spec.js,prototypeCompanyAccess.spec.js,workspaceNav.spec.js,moduleRouteAccess.spec.js,authSession.spec.js,useProductOnboarding.spec.js가 준비도 분류, 계정 프로필, 메뉴·직접 URL, 숨은 entitlement 보존을 고정한다.