From ca971c1cae45fe45e64427d95aa6576f47744cc6 Mon Sep 17 00:00:00 2001 From: zio Date: Sat, 11 Jul 2026 19:36:27 +0900 Subject: [PATCH] =?UTF-8?q?feat(planning):=20PLANNING=20v3.0=20=EB=A9=80?= =?UTF-8?q?=ED=8B=B0=ED=85=8C=EB=84=8C=EC=8B=9C(=EB=8B=A4=EC=A4=91=20?= =?UTF-8?q?=EC=A0=84=EC=8B=9C=EA=B4=80)=20=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 정체성: 킨텍스 전용 → 다중 전시관 SaaS(KINTEX=테넌트#1, COEX 등 온보딩) - 테넌트/Venue 모델 + 전 엔티티 tenant_id 전파 + fail-closed 격리(공유 스키마+tenant_id 컬럼) - 역할: 플랫폼 슈퍼관리자 vs 테넌트(전시관) 관리자 계층 + 행사 RBAC 3중 - 서브도메인 테넌트 컨텍스트, 기존 데이터 tenant_id=1 백필. DDL은 DA/db-engineer 후속 Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/PLANNING.md | 110 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/docs/PLANNING.md b/docs/PLANNING.md index fadb0aa..da27384 100644 --- a/docs/PLANNING.md +++ b/docs/PLANNING.md @@ -1,11 +1,12 @@ # 킨텍스 자동전시시스템 (Exhibition Automation Platform) 기획서 -> 작성: 기획 에이전트(planner) · 작성일: 2026-07-11 · 버전: **v2.0** +> 작성: 기획 에이전트(planner) · 작성일: 2026-07-11 · 버전: **v3.0** > 근거 문서: `docs/analysis/kintex-website.md` (킨텍스 웹사이트 25개 페이지 + 전시주최자매뉴얼 PDF + 참가업체 매뉴얼 PDF 전수 분석, 2026-07-11) > 근거 문서: `docs/analysis/reroomai-source.md` (ReRoomAI 이미지 파이프라인 소스 분석, 2026-07-11) — 6장 나노바나나 파이프라인 제어 파라미터 확정 근거 > 근거(글로벌 벤치마크, 2026-07-11 크롤링): Eventleaf·VenueSight·Whova·ExpoPlatform(전시관리·부스판매·리드캡처), Eventbase·Pointr·Swapcard·Brella·Grip(wayfinding·비즈매칭), RainFocus·Bizzabo(등록·리벤뉴), ExhibitForce·Ways·FinancialModelsLab·Digitevent(전시 BI/KPI), FindRFP·Procore·4castplus(RFQ/Tender/역경매). 각 §5 모듈에 매핑. > > **v2.0 정체성 확장**: 본 시스템은 "부스 시공 도구"를 넘어 **킨텍스 자동전시시스템(Exhibition Automation Platform)** 이다 — 전시 기획·판매·시공·운영·관람객·사후분석 전 주기를 아우른다. 기존 M2~M5 부스 시공 코어(P0)·나노바나나 파이프라인(§6)·확정 스택(§8)은 **보존**하고, 그 위에 관람객/비즈매칭/마케팅·공개사이트/wayfinding/현장운영/공사 옥션/BI/CMS/관리자 모듈(M10~M18)을 확장한다. +> **v3.0 정체성 확장 — 다중 전시관 SaaS**: 본 시스템은 **킨텍스 전용에서 다중 전시관(Venue) 멀티테넌트 SaaS**로 확장한다. 킨텍스(KINTEX)는 **기준 테넌트(테넌트 #1)** 로 유지되고, 코엑스(COEX) 등 여타 전시관을 테넌트로 온보딩한다. 기능(M1~M18·§5B·§6 나노바나나·§8 확정 스택)은 **전부 보존**하고, 그 위에 **테넌트 격리 레이어(tenant_id 전파·컨텍스트 해소·역할 계층)** 만 얹는다 — 기능은 그대로, 데이터·권한·컨텍스트가 전시관 단위로 분리된다. 상세는 **§1A**, 격리 전략은 **§8-2**. > **문서 소유권**: 본 PLANNING.md는 planner만 수정한다. design.md·타 문서는 이 문서 변경 시 "designer/planner 후속 반영 필요"로만 표기하고 직접 수정하지 않는다. --- @@ -54,6 +55,73 @@ - 킨텍스 임대계약 자체의 법적 체결(전자계약)은 Phase 3 이후 검토 — 초기에는 견적·서류 준비까지만. - 구조계산서의 **구조 안전성 판정 자체를 AI가 대신하지 않는다.** (규정 항목 체크·누락 검출까지만, 최종 판정은 구조기술사/킨텍스) - 관람객 대상 서비스(주차·티켓)는 P2 부가 범위. +- **멀티테넌시(§1A)는 데이터·권한 격리 레이어**이며, 전시관별 신규 도메인 로직(전시관 고유 규정 파서 등) 자동 생성은 Non-Goal — 새 전시관 온보딩은 마스터데이터 입력(§1A-5·§8-2) 수준까지. + +--- + +## 1A. 멀티테넌시 (다중 전시관 SaaS) — v3.0 + +> **핵심 원칙**: 기능·화면·모듈(M1~M18)·나노바나나 파이프라인(§6)·확정 스택(§8)은 **전부 보존**한다. v3.0이 더하는 것은 **① 테넌트(전시관) 모델 ② 전 도메인 엔티티 `tenant_id` 전파와 격리 ③ 테넌트 컨텍스트 해소 ④ 플랫폼/테넌트 2계층 관리자 역할 ⑤ 기존 데이터의 테넌트 #1(KINTEX) 백필**뿐이다. 즉 "무엇을 하는가"는 그대로, "누구의 데이터인가(전시관 단위)"만 분리된다. + +### 1A-1. 테넌트 = 전시관(Venue) 모델 + +**테넌트가 곧 전시관이다.** KINTEX = 테넌트 #1(기준), COEX = 테넌트 #2, … 신규 전시관은 테넌트 #N으로 온보딩. 테넌트 마스터를 **최상위 스코프**로 신설하고, 기존 마스터데이터(홀·요율·규정 룰셋·부스 표준)를 **테넌트 소유(tenant-owned)** 로 재정의한다. + +| 테넌트 마스터 필드 | 내용 | 예 | +|---|---|---| +| `tenant_code` | 전시관 식별 코드(불변) | `KINTEX`, `COEX` | +| `tenant_name` | 전시관 명칭(다국어) | 킨텍스 / KINTEX, 코엑스 / COEX | +| `branding` | 로고·색상·테마 토큰(공유 디자인시스템 위 테넌트 오버라이드) | 로고 URL·프라이머리 컬러 (designer 후속 반영) | +| `domain` / `subdomain` | 접속 도메인(§1A-3 컨텍스트 해소 키) | `kintex.wise.ai.kr`, `coex.wise.ai.kr` | +| `active` | 활성/비활성(온보딩 중·종료 테넌트 게이트) | true/false | +| `locale_default` | 기본 로케일·통화·시간대 | ko-KR / KRW / Asia/Seoul | + +**테넌트 소유 마스터데이터(§7-1 재정의)**: 홀 마스터·요율표·유틸리티 요금·규정 룰셋·부스 표준·등록업체 DB는 **각 전시관이 소유**한다. 킨텍스 홀1~10(§7-1 실측값)은 **테넌트 #1의 자산**이고, 코엑스 홀(A~D홀 등)은 테넌트 #2의 자산으로 별도 등록된다. 즉 §7-1의 킨텍스 실측 마스터는 **테넌트 #1의 초기 시드**로 위치가 재정의되며, 요율(2,250원/㎡ 등)·규정(높이 5m·리깅 6.5~8.5m 등)도 전시관마다 다른 값을 가질 수 있다(코엑스 실측값은 미확보 — 온보딩 시 입력, 근거 없는 추정 금지). + +### 1A-2. `tenant_id` 전파 및 테넌트 격리 + +**전 도메인 엔티티에 `tenant_id`(FK → 테넌트 마스터)를 추가**하고, 모든 조회/쓰기를 `tenant_id`로 스코프한다(횡단 접근 원천 차단). + +| 구분 | 대상 | tenant_id 처리 | +|---|---|---| +| **테넌트 스코프(격리)** | Event·Hall·Booth·DesignPlan·UtilityOrder·RenderJob·Document·Payment · Auction·Quotation·Award · Visitor·Registration·Badge·CheckIn·Lead·Meeting · KpiSnapshot·Content·Microsite · Company(등록업체) · User membership·Role 매핑·AuditLog · MasterData(홀·요율·요금·룰셋·부스표준) | 전 행에 `tenant_id` 컬럼, 전 쿼리 `WHERE tenant_id = :ctx` 강제(§8-2) | +| **전역 참조(공유)** | 시스템 공통코드 중 도메인 불변분(국가·통화·언어 코드 등), 플랫폼 설정 | `tenant_id` 없음(전역) 또는 `tenant_id IS NULL` = 전역 + 테넌트 오버라이드 | +| **테넌트 스코프 참조** | 공종 14분류·유틸리티 요금코드·부스유형 등 전시관마다 다를 수 있는 코드 | `tenant_id` 부여(전역 기본값을 테넌트가 오버라이드) | + +- **격리 규칙(불변)**: 어떤 사용자도 자신이 소속되지 않은 테넌트의 데이터를 **조회·수정·검색·집계할 수 없다**(예외 = 플랫폼 슈퍼관리자, §1A-4). 행사(Event) 단위 RBAC(§2)는 **테넌트 내부로 스코프**된다 — 즉 "행사 격리 ⊂ 테넌트 격리"의 2중 구조. +- **공용 참조 구분**: 코드성 데이터는 "전역(플랫폼 표준) vs 테넌트 오버라이드"를 구분한다. 예: 공종 14분류는 킨텍스 기준을 전역 기본값으로 두되, 전시관이 분류 체계를 달리하면 테넌트 스코프로 오버라이드. +- **크로스-테넌트 집계**: M16 BI의 전 테넌트 통합 지표는 **플랫폼 슈퍼관리자 전용**이며 별도 권한 게이트로만 접근(테넌트 관리자는 자기 전시관 범위만). + +### 1A-3. 테넌트 컨텍스트 해소 (Tenant Context Resolution) + +요청마다 **어느 테넌트인가**를 판별해 컨텍스트에 주입한다(§8-2 필터 계층). + +1. **서브도메인 우선**: `kintex.wise.ai.kr` → 테넌트 #1, `coex.wise.ai.kr` → 테넌트 #2. 게이트웨이/필터가 Host 헤더에서 `tenant_code`를 해소. +2. **사용자 소속 보조**: 로그인 사용자의 테넌트 멤버십으로 판별(서브도메인과 불일치 시 **거부** — 세션 하이재킹·오접속 차단). 다중 테넌트 소속(예: 복수 전시관 운영 대행사)은 명시적 테넌트 선택 후 컨텍스트 고정. +3. **주입**: 해소된 `tenant_id`를 요청 컨텍스트(ThreadLocal/Request scope)에 주입 → 서비스·MyBatis 매퍼가 이를 강제 바인딩(§8-2). 컨텍스트 미해소 요청은 **거부(fail-closed)**. +4. **공개 사이트(M12·M17)**: 서브도메인으로 테넌트 브랜딩·콘텐츠 분기(kintex/coex 공개 홍보 사이트가 각 테넌트 콘텐츠만 노출). + +### 1A-4. 역할 계층 확장 — 플랫폼 vs 테넌트 (2계층) + +기존 6역할(§2) 위에 **관리자 역할을 2계층으로 분리**한다. + +| 계층 | 역할 | 범위 | 권한 | +|---|---|---|---| +| **플랫폼** | **플랫폼 슈퍼관리자(Platform Super Admin)** | **전 테넌트(크로스-테넌트)** | 테넌트 마스터 CRUD·온보딩, 전 테넌트 사용자/감사 통제, 전역 코드·플랫폼 설정, 전 테넌트 BI(§1A-2). GUARDiA 플랫폼 운영 주체(zio) | +| **테넌트(전시관)** | **테넌트 관리자(Venue/Tenant Admin)** | **자기 전시관(단일 테넌트) 내부만** | 자기 전시관의 마스터데이터(홀·요율·규정 룰셋·부스 표준)·사용자·RBAC·감사로그·시스템설정. 예: 킨텍스 관리자 ↔ 코엑스 관리자 상호 격리 | +| **행사(Event)** | 주최자·참가업체·업체·홀매니저(§2 기존 6역할) | 테넌트 내부의 행사·부스 | **테넌트 내부로 스코프된** 기존 행사 RBAC(변경 없음, 단 상위에 tenant 경계 추가) | + +- **재정의**: §2의 기존 "관리자(Admin)" 페르소나는 **v3.0에서 "테넌트 관리자"로 재정의**되고, 그 위에 **플랫폼 슈퍼관리자**가 신설된다. §2-1 백오피스(`admin.`)는 두 계층이 **동일 앱·차등 권한**으로 진입(플랫폼 슈퍼관리자는 테넌트 스위처 보유, 테넌트 관리자는 자기 테넌트 고정). +- **홀매니저**: 킨텍스 홀매니저는 테넌트 #1 내부 계정으로, 코엑스 홀매니저는 테넌트 #2 내부 계정으로 각각 자기 전시관 행사만 열람/승인(크로스-테넌트 불가). + +### 1A-5. 마이그레이션 영향 및 백필 방침 + +- **기존 데이터 = 테넌트 #1(KINTEX)로 백필**: v2.0까지 축적된 전 데이터(행사·홀·부스·옥션·관람객·마스터데이터 등)는 **일괄 `tenant_id = 1(KINTEX)`** 로 백필한다. 킨텍스는 기준 테넌트이므로 기존 운영에 **무중단**. +- **스키마 변경은 설계만 — 임의 DDL 금지**: `tenant_id` 컬럼 추가·FK·인덱스·NOT NULL 제약·백필 DDL은 **db-engineer/DA 후속 트랙**이 수행한다(planner는 설계·영향 범위만 확정). 적용 순서(권고): ① 테넌트 마스터 테이블 신설 + KINTEX 시드(#1) → ② 각 도메인 테이블 `tenant_id` nullable 추가 → ③ 전 행 `1`로 백필 → ④ NOT NULL + FK + `(tenant_id, …)` 복합 인덱스 → ⑤ 애플리케이션 필터(§8-2) 활성화. 멱등 DDL·`sql.init mode=always`+continue-on-error 패턴(§5B-3) 준수. +- **회귀 방지**: 백필 완료 전에는 격리 필터를 강제하지 않고(단일 테넌트 동작 유지), 컬럼·인덱스·백필 검증 후 필터를 켠다(§8-2). 신규 테넌트(COEX) 온보딩은 필터 활성화 이후. +- **미확보 데이터**: 코엑스 등 신규 전시관의 홀 실측·요율·규정은 **온보딩 시 해당 테넌트가 입력**하며, 근거 없는 추정 시드는 금지(§10 R4 정합). + +> **후속 반영 필요**: 본 절의 스키마·필터·온보딩 절차는 `docs/design.md`·`docs/architecture/data.md`·src에 **미반영 상태** — db-engineer/DA/designer 후속 반영 필요(planner는 설계만 확정, 타 문서 직접 수정 안 함). --- @@ -66,10 +134,11 @@ | **장치·시공업체** (Contractor) | 이장치, 킨텍스 등록 장치업체(739개 등록업체 중 전시디자인설치 분류) 실장 | 평면도·입면도·조감도·전기도면 kxwp 제출, D-7 리깅 구조계산서, 현장 시공 | 규정(높이 5m, 방염, 리깅 6.5~8.5m) 반려 리스크, 도면 수정 반복 | 제출 전 자동 규정 검증, 배선/분전반 설계 자동 초안, 고객 컨펌용 예상 사진 | | **킨텍스 운영팀 (홀매니저)** | 최매니저, 행사지원팀. 홀 3개 담당 | 사전업무협의(D-30), 신고서류 검토, 현장 안전 관리(소음 70~75dB, 안전모) | 서류 육안 검수 병목, 행사별 협의 이력 분산, 위반 현장 사후 적발 | 위반 자동 플래깅 대시보드, 협의 이력 일원화, 홀 단위 유틸리티 부하 집계 | | **관람객** (Visitor) — P1로 승격 | 정관람, 일반 관람객/바이어 | 일정 검색 → 사전등록·티켓 → 교통(GTX-A 킨텍스역 도보 3분) → 주차(iparking) → 배지·체크인 → 관람·비즈매칭 | 부스 위치 탐색 불편, 현장 등록 대기 | 사전등록·모바일 배지/QR·wayfinding·비즈매칭·인터랙티브 플로어플랜 | -| **관리자** (Admin) — 신규 | 한관리, 킨텍스 플랫폼 운영 관리자 | 사용자·권한(RBAC)·마스터데이터(홀·요율·규정 룰셋)·감사로그·시스템설정 | 데이터 산재, 권한 통제 부재 | 별도 백오피스에서 전 테넌트/행사 통제, 감사 추적, 룰셋 버전 관리 | +| **테넌트(전시관) 관리자** (Tenant/Venue Admin) — v3.0 재정의 | 한관리, 킨텍스 전시관 운영 관리자 (코엑스는 별도 관리자) | **자기 전시관 내부** 사용자·권한(RBAC)·마스터데이터(홀·요율·규정 룰셋·부스 표준)·감사로그·시스템설정 | 데이터 산재, 권한 통제 부재 | 자기 전시관 백오피스에서 행사 통제·감사·룰셋 버전 관리(타 전시관 격리) | +| **플랫폼 슈퍼관리자** (Platform Super Admin) — v3.0 신규 | 플랫폼(zio) 운영자 | **전 테넌트** 온보딩·테넌트 마스터·전역 코드·크로스-테넌트 감사·통합 BI | (신규 — 다중 전시관 통합 통제 부재) | 테넌트 스위처로 전 전시관 통제, 새 전시관(코엑스 등) 온보딩(§1A-4·§1A-5) | | **일반 대중** (Public) — 신규 | 불특정 다수 잠재 관람객·잠재 주최자 | 킨텍스 전시 홍보 열람, 참가 문의 | 킨텍스 공식 사이트는 정보·서식 다운로드 수준 | SEO·다국어 공개 홍보 사이트(M12), 참가업체 마이크로사이트(M17), 관람 유도 | -**권한 모델**: 행사(Event) 단위 워크스페이스 + 플랫폼 레벨 RBAC(관리자). 주최자가 행사 owner, 참가업체는 부스 단위 멤버, 장치/공사업체는 참가업체·주최자가 초대(등록업체 DB 검증 — 미등록 업체 초대·옥션 응찰 차단), 홀매니저는 킨텍스 내부 계정으로 전체 열람+승인, 관리자는 백오피스에서 크로스-테넌트 통제. 관람객·일반 대중은 공개/셀프서비스 계정(행사 데이터 쓰기 권한 없음, 등록·매칭·조회만). +**권한 모델**: **테넌트(전시관) 격리 ⊃ 행사(Event) 단위 워크스페이스 + 행사 RBAC**의 3중 구조(§1A-4). 최상위에 테넌트 경계가 있고(전시관 간 데이터 원천 차단), 그 안에서 행사 단위 RBAC가 동작한다. 주최자가 행사 owner, 참가업체는 부스 단위 멤버, 장치/공사업체는 참가업체·주최자가 초대(등록업체 DB 검증 — 미등록 업체 초대·옥션 응찰 차단), 홀매니저는 **소속 전시관 내부** 계정으로 자기 전시관 행사 전체 열람+승인. **테넌트 관리자**는 자기 전시관 백오피스에서 통제(타 전시관 격리), **플랫폼 슈퍼관리자**만 크로스-테넌트 통제(§1A-4). 관람객·일반 대중은 공개/셀프서비스 계정(행사 데이터 쓰기 권한 없음, 등록·매칭·조회만) — 접속 서브도메인으로 테넌트가 고정(§1A-3). ### 2-1. 역할별 웹/모바일 포털 분리 (IA·채널 매트릭스) @@ -81,7 +150,8 @@ | **참가업체** | 참가업체 포털 `exhibitor.` — 부스 신청·설계·유틸리티·옥션 발주 | 현장 체크인·**리드캡처(배지 스캔)**·승인 | M3·M4·M5·M10·M11·M15·M9 | Event member(부스 단위) | | **장치/공사업체** | 업체 포털 `contractor.` — 도면 제출·**AI 설계자료 열람·옥션 응찰(견적서 제출)** | 현장 시공·반입 통행증·안전 체크 | M3·M4·M15·M8·M7 | 등록업체 검증 계정 | | **킨텍스 직원(홀매니저·운영)** | 운영 대시보드 `ops.` — 검수·규정 플래그·홀 부하·물류·현장운영 | 현장 검수·안전·혼잡 모니터 | M2·M6·M8·M14·M16 | 내부 계정(행사 전체 열람·승인) | -| **관리자** | 백오피스 `admin.` — 사용자·RBAC·감사로그·마스터데이터·룰셋·시스템설정 | (없음, 웹 전용) | **M18** | 플랫폼 관리자(크로스-테넌트) | +| **테넌트 관리자** | 백오피스 `admin.`(테넌트 컨텍스트 고정) — 자기 전시관 사용자·RBAC·감사로그·마스터데이터·룰셋·시스템설정 | (없음, 웹 전용) | **M18** | 테넌트(전시관) 관리자(단일 테넌트 스코프) | +| **플랫폼 슈퍼관리자** | 백오피스 `admin.`(테넌트 스위처) — 테넌트 마스터·온보딩·전역 코드·크로스-테넌트 감사·통합 BI | (없음, 웹 전용) | **M18 + 테넌트 관리** | 플랫폼 슈퍼관리자(크로스-테넌트, §1A-4) | | **관람객/일반 대중** | 공개 홍보 사이트 `www/expo.` (SEO·다국어) + 관람객 사전등록 | 관람객 앱 — 배지/QR·티켓·wayfinding·비즈매칭·플로어플랜 | M12·M10·M11·M13·M17 | 공개/셀프서비스(쓰기 제한) | - **분리 원칙**: 6개 프론트(organizer·exhibitor·contractor·ops·admin·public+visitor)는 **역할별 번들 분리**로 최소권한·공격면 축소. 공유 디자인 시스템(design.md)·공유 컴포넌트 라이브러리·공유 API 계약을 상속한다. (UI 상세·화면 목록은 designer 후속 반영 필요.) @@ -719,6 +789,8 @@ Render this exhibition booth as if construction is complete. | 규정 룰셋 | 높이 5m, 리깅 6.5~8.5m+구조계산서 D-7, 복층 1/2, 방염, 소음 70~75dB, **이격(인접 벽 30cm·천장 60cm), 조명 반입 금지(지정 조명만 사용)**, 금지작업 목록 | 매뉴얼 → 룰 엔진 코드화 | 확보 | | 회의실 마스터 | 37개 회의실, 시간대별 요금 (P2 범위) | 공개 요율표 | 확보 | +> **v3.0 테넌트 스코프 재정의(§1A-1)**: 위 §7-1 마스터데이터는 모두 **테넌트(전시관) 소유**로 재정의된다 — 표에 기재된 킨텍스 실측값(홀1~10, 2,250원/㎡, 높이 5m·리깅 6.5~8.5m 등)은 **테넌트 #1(KINTEX)의 초기 시드**이며, 코엑스 등 신규 테넌트는 자기 전시관의 홀·요율·유틸리티 요금·규정 룰셋·부스 표준을 **별도 소유·입력**한다(값이 다를 수 있음, 근거 없는 추정 금지). 각 마스터 행에 `tenant_id`가 부여된다(§1A-2). 코엑스 실측값은 미확보 — 온보딩 시 입력(§1A-5). + ### 7-2. 외부 연동 | 대상 | 방식 | 불확실성 | @@ -741,6 +813,13 @@ Render this exhibition booth as if construction is complete. - 경영/관리: `KpiSnapshot(BI 집계) ; Content(CMS 콘텐츠·다국어·버전) ; Microsite(참가업체) ; MasterData(홀·요율·요금·룰셋·버전) ; User·Role·AuditLog(M18)`. - 공간 데이터 공유(불변): Booth 폴리곤·배선 LineString은 M13 wayfinding·M14 부하집계·M16 ㎡당 수익이 동일 PostGIS 원천을 재사용. +**v3.0 추가 엔티티 (멀티테넌시 §1A)**: +- 최상위 테넌트: `Tenant/Venue(전시관: tenant_code·tenant_name(다국어)·branding·domain/subdomain·active·locale_default) 1─N (전 도메인 엔티티)`. 킨텍스=`tenant_id=1`(기준), 코엑스=`tenant_id=2`. +- **`tenant_id` 전파(불변 격리)**: 위 §7-3의 **전 도메인 엔티티**(Event·Hall·Booth·DesignPlan·UtilityOrder·RenderJob·Document·Payment·Company·Auction·Quotation·Award·Visitor·Registration·Badge·CheckIn·Lead·Meeting·KpiSnapshot·Content·Microsite·MasterData·User membership·Role 매핑·AuditLog)에 `tenant_id`(FK → Tenant) 추가. 모든 조회/쓰기는 `WHERE tenant_id = :ctx` 강제(§8-2). +- **참조 데이터 구분**: 전역 공통코드(국가·통화·언어)는 `tenant_id` 없음(전역), 전시관마다 다를 수 있는 코드(공종 14분류·유틸리티 요금코드·부스유형)는 `tenant_id` 부여(전역 기본값 + 테넌트 오버라이드). +- **역할 계층**: `Role`에 플랫폼 슈퍼관리자(크로스-테넌트) vs 테넌트 관리자(단일 테넌트) 계층(§1A-4). User–Tenant 멤버십(다중 소속 허용, 컨텍스트는 단일 고정 §1A-3). +- **마이그레이션**: 기존 전 행 `tenant_id=1(KINTEX)` 백필(§1A-5, DDL은 db-engineer/DA 후속). + --- ## 8. 아키텍처 개요 @@ -830,6 +909,28 @@ graph TB - **옥션 엔진(M15)**: Spring 서비스 계층 + Redis(실시간 순위·라운드 마감 타이머) + WebSocket(순위 푸시). 견적서 PDF 생성은 서류 생성 큐(Redis) 재사용, 나노바나나와 동일 비동기 패턴. - **BI(M16)**: 운영 DB 부하 회피를 위해 집계는 배치/스냅샷(KpiSnapshot) 또는 읽기 전용 복제 권장(구현 트랙 결정). 예측·이상탐지는 §10 R12(외부 API 게이트) 준수 — 온프레미스/승인 모델 범위. +### 8-2. v3.0 멀티테넌트 격리 전략 (§1A 구현 아키텍처) + +확정 스택(§8·§8-1)은 **불변**. 그 위에 테넌트 격리 레이어를 얹는다. + +- **격리 전략 = 공유 스키마 + `tenant_id` 컬럼(단일 DB 유지)**: 현행 단일 DB `kintex_db`를 **유지**하고, 전 도메인 테이블에 `tenant_id` 컬럼을 두어 논리 격리한다. **테넌트별 DB 분리(DB-per-tenant)·스키마 분리는 채택하지 않는다** — 전시관 수(수 개~수십 개) 대비 운영·마이그레이션·배포 비용이 과하고, 크로스-테넌트 BI(§1A-2)·공유 나노바나나 워커·단일 배포 파이프라인과 상충. 공유 스키마 + tenant_id가 GUARDiA 표준(단일 DB·Hikari max 3) 및 SaaS 정석에 정합. + + | 전략 | 채택 | 사유 | + |---|---|---| + | 공유 스키마 + `tenant_id` 컬럼 | **채택** | 단일 `kintex_db` 유지, 운영·배포 단순, 크로스-테넌트 집계 용이, 온보딩 저비용 | + | 스키마-per-tenant | 미채택 | 마이그레이션 N배·커넥션 풀 부담, 이득 대비 과함 | + | DB-per-tenant | 미채택 | 인프라·배포·백업 N배, 소수 전시관에 과대 | + +- **강제 격리 계층 (fail-closed 다층 방어)**: + 1. **컨텍스트 해소 필터**: 게이트웨이/서블릿 필터가 서브도메인·JWT 클레임에서 `tenant_id`를 해소해 요청 컨텍스트에 주입(§1A-3). 미해소·불일치 요청은 **거부**. + 2. **서비스 계층 가드**: 컨텍스트 `tenant_id`를 신뢰 원천으로, 클라이언트가 보낸 tenant 파라미터는 **무시/검증**(위조 차단). + 3. **MyBatis 매퍼 강제 바인딩**: 전 매퍼 SQL에 `AND tenant_id = #{ctxTenantId}` 조건을 **공통 인터셉터/베이스 매퍼**로 주입(개별 쿼리 누락 방지). 쓰기 시 `tenant_id`를 컨텍스트에서 자동 세팅(클라이언트 입력 금지). + 4. **PostGIS 공간 쿼리도 동일**: 부스 폴리곤·배선 라우팅·면적 정산 등 `ST_*` 쿼리도 `tenant_id` 조건 하에서만 수행(전시관 간 공간 데이터 혼입 차단). +- **성능(테넌트 인덱스)**: 격리 쿼리가 항상 `tenant_id`를 선행 조건으로 가지므로 **`(tenant_id, …)` 선두 복합 인덱스**를 표준화(예: `(tenant_id, event_id)`, `(tenant_id, hall_id)`, PostGIS는 `tenant_id` + GiST 부분 인덱스). BI 데이터마트(§M16 Fact/Dim)도 `DimTenant` 추가·`tenant_id` 파티션 키 고려(DA 후속). +- **보안(교차 테넌트 차단)**: 전 계층 tenant 강제 + 감사로그(§5B-1)에 `tenant_id` 기록. 크로스-테넌트 접근은 플랫폼 슈퍼관리자 전용 API로만(명시적 권한 게이트·감사). 나노바나나 오브젝트 스토리지 경로·RenderJob 쿼터(§6-5)도 `tenant_id` 프리픽스로 격리(전시관별 이미지·쿼터 분리). +- **온보딩(새 전시관 추가 절차)**: ① 플랫폼 슈퍼관리자가 테넌트 마스터 생성(tenant_code·subdomain·branding·active=false) → ② 서브도메인·DNS·(선택)브랜딩 테마 등록 → ③ 해당 전시관 마스터데이터 입력(홀·요율·규정 룰셋·부스 표준·등록업체 — 근거 없는 추정 금지, §1A-5) → ④ 테넌트 관리자·홀매니저 계정 발급(OTP 등록) → ⑤ 스모크(격리 검증: 타 테넌트 데이터 불가시 확인) → ⑥ `active=true`. **코드 배포 없이 데이터 온보딩만으로 신규 전시관 오픈**(공유 스키마 이점). +- **후속 반영 필요**: 필터·인터셉터·인덱스·마이그레이션 DDL은 **db-engineer/DA/backend 후속 트랙**(planner 설계만). `docs/architecture/*.md`·`docs/design.md`·src 미반영. + --- ## 9. 로드맵 @@ -889,3 +990,4 @@ graph TB | v1.1 | 2026-07-11 | planner | ReRoomAI 소스 분석 반영. ①§6 나노바나나 파이프라인 제어 파라미터 확정 — 모델 `gemini-3.1-flash-image-preview`(나노바나나 2)·`@google/genai` SDK·image-to-image(inlineData+text parts) 호출 스택, 구조화 사전(BOOTH_TYPES·BOOTH_STYLES·FIXTURE_LAYERS) + "보존/교체 명시 분리" 부스 프롬프트 템플릿(§6-4), Canvas 1024px 전처리·RenderJob 방어 로직(크기 가드·SAFETY·에러 분기·성공 시에만 쿼터 차감)·단계별 로딩 UX 신설(§6-5). ②S6 배선 오버레이 백엔드 래스터 합성 우선 명확화(§6-3). ③§7 마스터 데이터 순증 반영(기본부스 표준 품목·프리미엄 6×3×4m 2kW·조명 반입 금지·이격 30/60cm·옥외 2,849㎡·홀6 93×60×10m·제3전시장 홀11~18). ④§10 R11 해소, R12(Gemini 외부 API 미승인·소유자 승인 게이트) 추가. BACKLOG B-11 done, B-09 정리 | | v1.2 | 2026-07-11 | planner | **기술 스택 확정 — React + Spring Boot 3.x(Java 17) + MyBatis + PostgreSQL(PostGIS), 나노바나나 Python 워커 사이드카. GUARDiA 표준 프레임워크 정렬(사용자 지정).** §8 아키텍처 전면 정합화: 백엔드 FastAPI→Spring Boot 3.x + MyBatis(REST + WebSocket/STOMP, 룰·배치/배선 엔진=서비스 계층 + PostGIS 공간 SQL), 프론트 Next.js→React 18/19(Vite·TS, SVG/WebGL 캔버스), 비동기 큐 Redis 유지 + 이미지 생성은 별도 **Python 워커 사이드카(`tools/nanobanana`, google-genai Python SDK)** 로 분리(Spring이 RenderJob 큐잉→Python 워커 소비·생성→오브젝트 스토리지 적재→WebSocket 완료 푸시, 서류·알림도 동일 큐). Python 워커 유지 근거 명시(ReRoomAI 검증 client.py·Python SDK — Java 재구현 회피). 인증(행사 단위 RBAC+JWT)·오브젝트 스토리지 유지. §8 mermaid 갱신. **기능 범위(M1~M9)·우선순위·나노바나나 파이프라인 로직 불변** — 스택 표기 정합화만 수행 | | **v2.0** | 2026-07-11 | planner | **정체성 확장 — 킨텍스 자동전시시스템(Exhibition Automation Platform).** 글로벌 전시테크 크롤링(Eventleaf·VenueSight·Whova·ExpoPlatform·Eventbase·Pointr·Swapcard·Brella·Grip·RainFocus·ExhibitForce·FindRFP·Procore·4castplus) 근거로 확장. ①§1 비전 재정의(생애주기 폐루프, M15 옥션이 코어를 발주로 연결) ②§2 역할·포털 매트릭스 신설 — 6역할(주최자·참가·업체·홀매니저·관리자·관람객/대중) 웹/모바일 분리(organizer·exhibitor·contractor·ops·admin·public+visitor), 관리자·일반대중 페르소나 추가 ③§4 모듈맵 mermaid 확장(M10~M18) + 우선순위 총괄 ④§5A 신규 모듈 상세: **M15 공사/장치 옥션(P1·핵심, 역경매·견적서(Quotation)=응찰·실시간 순위·종합평가 낙찰·등록업체만 응찰·Auction 1─N Quotation ─ Award·PDF/버전, 입찰 플로우 시퀀스 다이어그램)**, M10 관람객 등록·배지·리드캡처(P1), M12 마케팅·EDM·공개 홍보 사이트(P1·SEO/다국어), M16 경영분석 BI(P2→**P1 승격**, design.md 반영은 designer 후속), M17 CMS(P1), M18 관리자 백오피스(P1), M11 비즈매칭·M13 wayfinding·M14 현장운영(P2) ⑤**M2·M3 3안 생성→선택/병합 UX 구체화**(1·2·3안 다양화, 구역/블록 병합, 병합 후 규정 재검증, 버전 기록) ⑥§7-3 엔티티 확장(Auction/Quotation/Award·Visitor/Badge/Lead·KPI/Content/User) ⑦§8-1 아키텍처 보강(역할별 분리 프론트+SSO/RBAC+공개사이트 SEO/다국어+백오피스+옥션 엔진) ⑧**§5B 공통/시스템관리 레이어(UIWS 표준 이식) 신설** — kintex 스택=UIWS(GUARDiA 표준 프레임워크) 동일 → 시스템관리(사용자·RBAC·공통코드·메뉴·감사로그·시스템설정)와 공통 업무기능(worklog·schedule·message·stats·notice·opinion·search·meeting·report·notification·audit) + 인증(JWT + **2차 인증 OTP TOTP RFC6238** + 로그인 실패 잠금 + admin 비번 env `ADMIN_PASSWORD_ENC` 주입)을 `workspace/uiws` 레퍼런스로 이식, 도메인 모듈은 그 위에 적재. **M18 관리자 시스템을 UIWS 시스템관리와 통합(중복 제거)**, BI/CMS/알림 경계 규칙 정의, Phase 1 선행 기반으로 로드맵 반영. ⑨**§5A M16-1 운영사(킨텍스·venue operator) 관점 수익성/ROI 소절 신설** — 참가업체 관점 ROI(리드 기반)와 명시 구분하고, 킨텍스 관점 7지표(홀·기간별 가동률/매출구성/행사별 P&L·마진/전시장별 ROI·RevPAD·㎡당 수익/참가사 리텐션·LTV/수요예측·수율·가격 최적화/경영진 KPI) + 데이터원(M1·M4·M9·M10·M15) + **BI 데이터마트(스타 스키마 Fact/Dim, DA 후속 트랙)** 정의. **기존 M2~M5 P0 코어·§6 나노바나나 로직·§8 확정 스택 보존.** design.md/타 문서는 미수정 — designer/planner/DA 후속 반영 필요로 표기 | +| **v3.0** | 2026-07-11 | planner | **멀티테넌시(다중 전시관 SaaS) 확장 — 킨텍스 전용 → 다중 전시관, KINTEX=기준 테넌트 #1.** 기존 스코프(부스 코어 M2~M5·도메인 M10~M18·§5B 공통 레이어·§6 나노바나나·§8 확정 스택) **전부 보존**, 격리 레이어만 순증. ①헤더 v3.0 정체성 확장(다중 전시관 SaaS) ②**§1A 멀티테넌시 절 신설** — 테넌트=전시관(Venue) 모델(tenant_code·명칭·branding·domain/subdomain·active·locale, 홀·요율·규정 룰셋·부스표준을 테넌트 소유로 재정의)·`tenant_id` 전파 및 격리(전 도메인 엔티티 격리 vs 전역/테넌트 참조 구분)·테넌트 컨텍스트 해소(서브도메인 kintex/coex.wise.ai.kr 우선 + 사용자 소속 보조, fail-closed 주입)·역할 계층(플랫폼 슈퍼관리자 vs 테넌트 관리자 2계층, 행사 RBAC는 테넌트 내부 스코프)·마이그레이션(기존 데이터 tenant_id=1 백필, DDL은 db-engineer/DA 후속) ③**§2 역할 갱신** — 페르소나 관리자 행을 테넌트 관리자로 재정의 + 플랫폼 슈퍼관리자 신규, 권한 모델을 "테넌트 격리 ⊃ 행사 RBAC" 3중 구조로, §2-1 포털 매트릭스 admin 2계층 분리 ④**§7 데이터모델 갱신** — §7-1 마스터데이터 테넌트 스코프 재정의(킨텍스 실측=테넌트#1 시드), §7-3 Tenant/Venue 엔티티·tenant_id 전파·참조 구분·역할 계층·백필 추가 ⑤**§8-2 멀티테넌트 격리 전략 신설** — 공유 스키마 + tenant_id 컬럼(단일 kintex_db 유지·DB/스키마 분리 미채택, 비교표)·fail-closed 다층 강제(필터→서비스가드→MyBatis 공통 인터셉터→PostGIS)·성능(`(tenant_id,…)` 선두 인덱스)·보안(교차 차단·감사·스토리지/쿼터 격리)·온보딩 6단(코드 배포 없이 데이터 온보딩) ⑥§1 Non-Goal에 온보딩 범위 한정 추가. **design.md·architecture/*.md·src 미수정** — db-engineer/DA/designer 후속 반영 필요로 표기. 근거 없는 코엑스 실측 추정 배제(온보딩 시 입력) |