본문으로 건너뛰기

사이트 운영 모델 (기본 / 독립 / 미러)

MSK 핵심 개념 — 사이트 모델

이 문서는 Multi-SaaS Kit 의 6개 핵심 개념 중 "사이트 모델"(개념 1) 을 설명합니다.

Multi-SaaS Kit 에서 "사이트(Site)" 는 권한 계층(SaaS/Tenant)과 별개의 레이어입니다. 사이트 유형은 SaaS Product 또는 Tenant 레코드의 settings 값으로 판정되며, 판정 로직의 단일 출처(SSOT)는 SiteTypeHelper (platform/web/laravel/core/Base/Site/Support/SiteTypeHelper.php), 도메인 라우팅 바인딩은 ResolveByDomain 미들웨어입니다.

2유형 + 1역할 한눈에​

사이트 유형은 2종(독립/미러) 이며, "기본사이트"는 별개 유형이 아니라 처음 생성된 독립사이트에 붙는 역할입니다(ADR-090 — 옛 "3유형 병렬"은 기각).

구분판정 필드도메인라우트·컨트롤러·뷰"사이트관리" 노출
독립사이트 (Independent, 유형)settings.site={slug} 또는 settings.domains=[...] (폴더 소유)고유 도메인완전 분리 (app/Sites/{Studly}/)✅
미러사이트 (Mirror, 유형)settings.mirror_domains 선언 (폴더 차용)자체 (서브)도메인 필수독립 라우팅 차용 + (Ⅰ)분기/(Ⅱ)마운트✅ (독립으로 resolve)
기본사이트 (Primary, 역할)처음 생성된 독립사이트 (= .env APP_URL host 차지, 자동 추론)메인 도메인공통(/)✅

핵심: 사이트 유형은 "어떤 도메인/코드 구조로 서비스되는가"를 정하며, "누가 관리하는가"인 권한 계층과는 직교(orthogonal)합니다.

기본사이트 (Primary Site)​

.env APP_URL 의 host 를 차지하는 SaaS 1개입니다. 별도의 "독립사이트 slug" 가 없어도 관리 가능 사이트로 인정됩니다.

v1.30.3+ 부터 운영자 입력 없이 자동 추론됩니다 — SiteTypeHelper::detectPrimarySaas() 의 4단계 우선순위:

순위조건비고
1settings.is_primary_site=true1.30.0 backward compat (명시 토글)
2settings.domains 에 .env host 매칭도메인 명시 등록
3SaaS slug == host SLD예: academy.how → academy
4단일 SaaS 프로젝트 → 그 SaaS신규 _template 기본 경로
신규 프로젝트의 기본 동작

make create 로 만든 신규 프로젝트는 보통 ④ 경로로 최초 SaaS 1개가 자동으로 기본사이트가 됩니다. 따라서 모든 프로젝트는 최소 1개의 "관리 가능 사이트"를 SaaS 레벨에 보유합니다.

독립사이트 (Independent Site)​

고유 도메인을 가지며 라우트·컨트롤러·뷰·리소스가 완전히 분리된 별도 사이트입니다.

판정 (SiteTypeHelper::isIndependent()):

  • settings.site 가 default 가 아닌 slug (→ app/Sites/{StudlyName}/ 폴더 보유), 또는
  • settings.domains 가 비어있지 않은 배열 (고유 도메인 명시 등록)

SaaS 계층과 Tenant 계층 양쪽에서 가능합니다. ResolveByDomain 미들웨어가 두 계층 모두 settings.site 를 해석합니다:

계층메서드동작
SaaSbindSaasProduct()saas->settings.site → current.site
TenantbindTenant()tenant->settings.site, 없으면 상위 SaaS 의 site 를 상속 → current.site

즉 Tenant 가 자체 settings.site 를 가지면 그 테넌트만의 독립사이트가 되고, 없으면 상위 SaaS 의 사이트를 따릅니다.

코드 구조 표준은 SaaS 모듈 시스템 (app/Sites/{StudlyName}/) 을 참조하세요.

미러사이트 (Mirror Site)​

독립사이트의 표면 변형(귀속) 입니다 — 독립사이트의 코드/라우팅을 차용하되, 자체 (서브)도메인 보유가 필수인 opt-in 사이트입니다. 폴더를 소유하지 않으므로(차용) 독립사이트와 구분됩니다.

  • 선언: 독립 레코드의 settings.mirror_domains (map, 예: { "bible.scripture.how": "bible" }). 독립의 settings.domains 와 별도 키입니다.
  • 분기 2모드 (병행 가능):
    • (Ⅰ) 도메인별 분기 — 같은 route 에 도메인 기준으로 테마/로고/일부 영역만 분기. 구현: settings.custom_theme → ViewThemeResolver 가 resources/views/{saas,tenants}/{slug}/ 우선 탐색.
    • (Ⅱ) route 마운트 — 차용 사이트의 특정 route 를 자체 도메인 루트에 마운트(예: bible.scripture.how/ → scripture.how/bible). 구현: 글로벌 pre-routing MountMirrorRoute + MirrorHostResolver. 정규 경로(scripture.how/bible)와 additive(둘 다 동작).
  • 귀속: 미러 도메인은 그 독립사이트로 resolve 되어 데이터·관리·감사가 독립사이트에 자동 귀속됩니다(별개 레코드 아님).
옛 정의 주의

"미러 = 도메인 없는 테마 오버레이" 는 옛 정의이며 ADR-090 이 supersede 했습니다. settings.custom_theme 는 미러의 정의 필드가 아니라 모드Ⅰ 브랜딩 메커니즘입니다. 미러는 항상 자체 (서브)도메인을 가집니다.

"사이트관리" 노출 게이트​

운영자 관리페이지에서 '사이트 관리' 메뉴(내장 게시판 공지/FAQ/1:1문의, 광고/애널리틱스 등 "사이트 단위 설정")가 보일지 여부는 다음 게이트가 결정합니다:

SiteTypeHelper::isManageableSite()  (= currentContextIsManageableSite())
→ 독립사이트 : true
→ 기본사이트(독립의 역할) : true
→ 미러 도메인 : true ← 독립 레코드로 resolve → 자연 포함 (미러 설정·감사 = 독립사이트의 것)
→ 비독립 Tenant/Org : false ← 상위(독립사이트/Platform) 설정 상속

이 게이트는 SaaS/Tenant 패널의 Filament Resource shouldRegisterNavigation() / canAccess() 에서 사용됩니다.

어떤 유형을 쓸까? (결정 트리)​

완전히 다른 라우트/페이지/데이터가 필요한가?
├─ 예 → 독립사이트 (settings.site + app/Sites/{Studly}/, 고유 도메인)
└─ 아니오 → 기본사이트(첫 독립사이트) 그대로 사용 (.env APP_URL)

[옵션] 독립사이트를 자체 (서브)도메인으로도 노출하고 싶은가? (라우팅 공유, 도메인/브랜딩/마운트만 다름)
└─ 예 → 미러사이트 추가 (settings.mirror_domains, opt-in)
├─ 도메인별 테마/로고만 분기 → 모드Ⅰ (custom_theme)
└─ 특정 route 를 자체 도메인 루트에 마운트 → 모드Ⅱ (route 마운트)

미러는 항상 독립사이트 위에 얹힙니다(라우팅은 독립 차용, 도메인/브랜딩/마운트만 변형). 데이터·관리·감사는 독립사이트에 귀속됩니다.

코드 SSOT & 관련 문서​

  • platform/web/laravel/core/Base/Site/Support/SiteTypeHelper.php — 사이트 유형 판정, detectPrimarySaas, isManageableSite
  • platform/web/laravel/core/Base/Site/Support/MirrorHostResolver.php · core/Base/Routing/Middleware/MountMirrorRoute.php — 미러 도메인 resolve + route 마운트
  • platform/web/laravel/core/Base/Routing/Middleware/ResolveByDomain.php — 도메인 → current.site 바인딩
  • 설계 결정: ADR-090 (사이트 모델 — 독립/미러 2유형 + 기본 역할 + 미러 route 마운트; ADR-023 의 3유형 정식화를 supersede), ADR-024 (SaaS 모듈 표준 구조), ADR-029 (Project-per-SaaS)
  • 관련 아키텍처: SaaS 모듈 시스템, 멀티 테넌시, 권한 계층