- harness·zio-harness·proposal-builder·zioinfo → plugins/zioinfo (git mv 히스토리 보존) - 스킬 4·커맨드 3(/zioinfo:pmo·proposal·wiki)·에이전트 15·graphify 훅·knowledge 통합 - 신규: /zioinfo:wiki (graphify LLM wiki — graphify-out/wiki/ 커뮤니티별 아티클) - 신규: ZIO WISE 테마 (themes/zioinfo.json, experimental) - manifest 최신화: $schema·displayName(ZIO INFOTECH Suite)·experimental.themes - marketplace.json 단일 엔트리, 루트 plugin.json 제거 - CLAUDE.md·PROJECT_MAP·docs/plugins.md·README 3종·CHANGELOG·설치가이드 pptx 재구성 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
358 lines
29 KiB
Markdown
358 lines
29 KiB
Markdown
# 킨텍스 자동전시시스템 — 시스템 아키텍처 · 비기능요건(NFR)
|
||
|
||
> 산출: 시스템 아키텍트(SA) · 작성일: 2026-07-11 · 대상 백로그: `IMPLEMENTATION_BACKLOG.md` **A-2**
|
||
> 정합 근거: [`../PLANNING.md`](../PLANNING.md) v2.0 §2(6역할)·§7(데이터·연동)·§8(아키텍처)·§10(리스크) · [`../IMPLEMENTATION_BACKLOG.md`](../IMPLEMENTATION_BACKLOG.md) · [`../analysis/reroomai-source.md`](../analysis/reroomai-source.md)(나노바나나 워커)
|
||
> 확정 스택(불변): React 18/19(Vite·TS) + Spring Boot 3.x(Java 17)+MyBatis + PostgreSQL(PostGIS) + Redis + 나노바나나 Python 워커. — `../DEVELOPMENT_GUIDE.md` §1, `../PLANNING.md` §8
|
||
> **문서 소유권**: 본 문서는 SA(시스템 아키텍처·NFR·구성·배포 토폴로지)만 정본. 애플리케이션 경계/API 표준=AA([`app.md`](app.md), A-1), 기술 표준/빌드·관측성=TA([`tech.md`](tech.md), A-3), 전사 ERD/공간·마스터·BI마트=DA([`data.md`](data.md), A-4), DMZ/방화벽/부하분산=NA([`network.md`](network.md), A-5). 본 문서는 그 상위 시스템 관점만 다루며 세부는 각 문서로 위임(교차참조).
|
||
|
||
---
|
||
|
||
## 0. 선행 게이트 (SA 반영 — 착수 전 소유자 확인)
|
||
|
||
| 게이트 | 내용 | 시스템 아키텍처 영향 |
|
||
|---|---|---|
|
||
| **G1** | 나노바나나(Gemini `generativelanguage.googleapis.com`) 외부 호출 승인(PLANNING R12) | 미승인 시 나노바나나 워커는 **목(mock)/degraded 모드**로 기동(구조·큐·워터마크 계약은 유지, 실이미지 생성만 차단). 승인 시 워커 서비스에만 `GEMINI_API_KEY` env 주입(§6-4). **아웃바운드 방화벽 정책은 워커 서브넷 한정** — NA 확정 |
|
||
| **G2** | 배포 대상 서버·포트(GUARDiA 인프라와 **별개 도메인**) | 배포 토폴로지(§4)의 물리 매핑·도메인·포트·TLS는 G2 확정 후 Phase E에서 실체화. 본 문서는 **논리 토폴로지**를 확정하고 물리값은 플레이스홀더(`<kintex-domain>`) 처리 |
|
||
|
||
> 두 게이트는 **아키텍처 설계를 막지 않는다** — 논리 구성·NFR·용량 산정은 게이트와 무관하게 확정하고, 물리 실체화(실호출·실배포)만 게이트에 종속시킨다.
|
||
|
||
---
|
||
|
||
## 1. 시스템 개요
|
||
|
||
킨텍스 자동전시시스템은 전시 생애주기(판매·기획 → 설계·시각화 → 발주·계약 → 참가·관람 → 현장운영 → 사후·경영)를 하나의 데이터·계정 체계로 자동화하는 **베뉴 운영 플랫폼**이다. 시스템은 **6개 역할별 분리 프론트 + 단일 공유 Spring Boot 백엔드 + 나노바나나 Python 워커 사이드카**를 **SSO·역할 RBAC** 위에 얹고, **PostGIS 공간 데이터 · Redis 비동기 큐 · 오브젝트 스토리지**를 공유 자원으로 둔다.
|
||
|
||
**아키텍처 대원칙 (PLANNING §4·§8 정합)**
|
||
1. **단일 공간 데이터 모델** — 부스 폴리곤·트렌치 포인트·배선 LineString을 PostGIS 지오메트리로 일원화. 시각화(M5)·검증(M2)·정산(M9)·wayfinding(M13)·BI(M16)가 같은 원천을 재사용.
|
||
2. **이미지 생성 전면 비동기** — Spring이 RenderJob을 Redis 큐에 발행 → Python 워커가 소비·생성 → 오브젝트 스토리지 적재 → WebSocket 완료 푸시. 백엔드는 오케스트레이션·상태만, `GEMINI_API_KEY`는 워커 전유.
|
||
3. **역할별 프론트 분리** — 최소권한·공격면 축소. 공유 디자인 시스템·컴포넌트·API 계약을 상속(중복 구현 금지).
|
||
4. **룰셋은 코드가 아닌 버전 데이터** — 요율·규정을 버전 파일로 두어 킨텍스 연 단위 개정을 무중단 반영.
|
||
5. **공개 vs 내부 보안영역 분리** — 공개 홍보/관람객(비인증·쓰기제한)과 내부 백오피스(관리자·크로스테넌트)를 물리·논리로 격리.
|
||
|
||
---
|
||
|
||
## 2. 논리 아키텍처 (컴포넌트 구성도)
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph EDGE["엣지 / 공개영역 (DMZ)"]
|
||
CDN[CDN · 정적 캐시<br/>공개 이미지·번들·플로어플랜]
|
||
WAF[WAF / Reverse Proxy · nginx<br/>TLS 종단·라우팅·레이트리밋]
|
||
end
|
||
|
||
subgraph FRONT["역할별 분리 프론트 (React·Vite·TS, 공유 디자인시스템)"]
|
||
FO[organizer. 주최자 콘솔]
|
||
FE[exhibitor. 참가업체 포털]
|
||
FC[contractor. 업체 포털·옥션]
|
||
FM[ops. 운영 대시보드]
|
||
FA[admin. 관리자 백오피스<br/>★내부 전용]
|
||
FP[www/expo. 공개 홍보 사이트<br/>SSR/SSG·SEO·다국어]
|
||
FV[관람객 모바일/웹<br/>배지·wayfinding·매칭]
|
||
end
|
||
|
||
subgraph GATE["SSO · 역할 RBAC · API 진입"]
|
||
SSO[JWT SSO + TOTP 2FA<br/>플랫폼·행사 이중 RBAC 평가]
|
||
end
|
||
|
||
subgraph BACKEND["공유 Spring Boot 3.x 백엔드 (Java 17·MyBatis)"]
|
||
API[REST + WebSocket/STOMP]
|
||
RULE[룰 엔진 · 요율/규정 버전셋]
|
||
LAYOUT[배치·배선 엔진 · PostGIS 공간 SQL]
|
||
AUC[옥션 엔진 M15 · 라운드·순위·낙찰스코어]
|
||
BI[BI 집계 M16 · KpiSnapshot]
|
||
CMS[CMS·다국어 M17]
|
||
PUBSVC[공개 API · 사전등록·조회 read-only]
|
||
end
|
||
|
||
subgraph ASYNC["비동기 처리"]
|
||
REDIS[(Redis<br/>작업 큐·순위·타이머·캐시·쿼터·세션)]
|
||
NBW[나노바나나 Python 워커<br/>tools/nanobanana · google-genai]
|
||
DOCW[서류·PDF·EDM 워커<br/>동일 큐 계약]
|
||
end
|
||
|
||
subgraph DATA["데이터 계층"]
|
||
PG[(PostgreSQL + PostGIS<br/>업무·공간 데이터)]
|
||
RPL[(읽기 복제본<br/>BI·공개조회 오프로드)]
|
||
OBJ[(오브젝트 스토리지<br/>도면·생성이미지·서식·콘텐츠)]
|
||
end
|
||
|
||
subgraph EXT["외부 시스템 / 게이트"]
|
||
GEM[Google Gemini<br/>나노바나나 · ★G1]
|
||
CLA[Anthropic Claude<br/>AiTextRouter · env only]
|
||
PGPAY[PG 결제 · 세금계산서]
|
||
KXWP[kxwp/kxfp 작업신고<br/>파일 릴레이]
|
||
CCPY[등록업체 DB 739]
|
||
EVT[행사일정 시스템]
|
||
end
|
||
|
||
CDN --> WAF
|
||
FP -.CDN 캐시.-> CDN
|
||
FO & FE & FC & FM & FA & FP & FV --> WAF --> SSO --> API
|
||
WAF -->|공개 read-only| PUBSVC
|
||
API --> RULE & LAYOUT & AUC & BI & CMS
|
||
API --> REDIS
|
||
REDIS --> NBW & DOCW
|
||
NBW --> OBJ
|
||
NBW -.WebSocket 완료푸시.-> API
|
||
NBW -.★G1.-> GEM
|
||
DOCW --> OBJ
|
||
API --> PG
|
||
BI --> RPL
|
||
PUBSVC --> RPL
|
||
API -.AiTextRouter.-> CLA
|
||
API --> PGPAY
|
||
API -.파일 릴레이.-> KXWP
|
||
API --- CCPY & EVT
|
||
PG -.복제.-> RPL
|
||
```
|
||
|
||
### 2-1. 컴포넌트 책임 (시스템 관점)
|
||
|
||
| 컴포넌트 | 실행 단위 | 책임 | 확장 방식 |
|
||
|---|---|---|---|
|
||
| **역할별 프론트 6종+공개** | nginx 정적 서빙(역할별 dist 번들) | organizer·exhibitor·contractor·ops·admin(내부)·public/visitor. SPA. 데스크톱=설계·에디터, 모바일=현장·조회·승인 | CDN + 정적 스케일(무상태) |
|
||
| **공개 홍보 사이트(M12·M17)** | SSR/SSG 렌더 경로 + CDN | SEO·다국어(한/영/중/일)·hreflang·사이트맵, 공개 플로어플랜(M2 부산물) | CDN 캐시·정적 재생성, 인증영역과 별도 |
|
||
| **공유 백엔드(Spring Boot jar)** | `java -jar`(systemd, N 인스턴스) | REST+WebSocket, 룰/배치/배선/옥션/BI/CMS 서비스, 큐 발행·상태·콜백 | **수평 확장(무상태)** — 세션·순위·타이머는 Redis 외부화 |
|
||
| **나노바나나 워커** | Python 데몬(systemd, M 인스턴스) | Redis 큐 소비 → Gemini image-to-image → 워터마크 후처리 → OBJ 적재 → WebSocket 콜백. 재시도·비용상한·스키마해시 캐시·쿼터(성공 시 차감) | **큐 깊이 기반 수평 확장**(GPU/비용 독립 스케일) |
|
||
| **서류·PDF·EDM 워커** | Python/Java 데몬(동일 큐 계약) | 서식(HWP/PDF)·견적서 PDF(M15)·EDM 발송 비동기 | 큐 깊이 기반 확장 |
|
||
| **Redis** | 관리형/전용 노드(HA) | 작업 큐, 옥션 실시간 순위·라운드 마감 타이머, 응답 캐시·스키마해시 캐시, RenderJob 쿼터, WebSocket 세션 상관 | Sentinel/Cluster(§3-2) |
|
||
| **PostgreSQL+PostGIS** | 프라이머리 + 읽기 복제 | 업무·공간 데이터 단일 진실원천(Flyway 스키마) | 프라이머리 수직 + 읽기 복제 수평(BI·공개조회 오프로드) |
|
||
| **오브젝트 스토리지** | S3 호환/파일 스토어 | 도면·생성이미지·서식·콘텐츠·마이크로사이트 자산 | 스토리지 독립 확장 + CDN 프론팅 |
|
||
|
||
> **AA 위임**: 모듈 경계·패키지·API 표준·응답 봉투는 [`app.md`](app.md). 본 표는 **배포 단위·확장 특성** 관점만.
|
||
|
||
---
|
||
|
||
## 3. 비기능요건(NFR)
|
||
|
||
> 정량 목표는 킨텍스 실측(홀당 200~600부스, 홀 10개, 대형 행사 수만 관람객)과 PLANNING §10 리스크(R6 이미지 비용·지연)를 근거로 산정. 값은 **초기 목표치**이며 파일럿(Phase 1) 실측으로 보정한다.
|
||
|
||
### 3-1. 확장성 (Scalability)
|
||
|
||
| 항목 | 설계 | 근거·목표 |
|
||
|---|---|---|
|
||
| **백엔드 수평 확장** | Spring 인스턴스 무상태화 — JWT(자족적)·세션 없음, 옥션 순위·타이머·쿼터·캐시는 **Redis 외부화**. WebSocket은 STOMP+Redis 브로커 릴레이(다중 인스턴스 팬아웃) | 인스턴스 N대 로드밸런싱, 무중단 스케일아웃 |
|
||
| **워커 독립 확장** | 나노바나나·서류·EDM 워커는 백엔드와 **분리 스케일** — 큐 깊이(대기 Job 수) 기반 인스턴스 증감 | 이미지 생성 피크(행사 오픈 전 대량 컨펌)를 백엔드 응답성과 무관하게 흡수 |
|
||
| **읽기 부하 오프로드** | BI 집계·공개사이트 조회·플로어플랜 열람은 **읽기 복제본** 라우팅. 운영 프라이머리는 쓰기 트랜잭션 보호 | BI(M16) 무거운 집계가 운영 DB를 압박하지 않음(PLANNING §8-1) |
|
||
| **공개 트래픽 흡수** | 공개 홍보 사이트·공개 플로어플랜·이미지는 **CDN·SSG 캐시**로 오리진 오프로드. 사전등록만 오리진 write | 관람객 트래픽 급증(행사 D-데이) 시 오리진 보호 |
|
||
| **데이터 파티셔닝 여지** | 행사(Event) 단위 격리(§5) → 대량 데이터(리드·체크인·RenderJob)는 행사·기간 파티션 가능(DA 후속) | 다년·다행사 누적 확장 |
|
||
| **멀티테넌시** | 행사 단위 워크스페이스 + 플랫폼 RBAC. 신규 행사는 데이터·권한만 추가(코드·인프라 불변) | 무제한 행사 온보딩 |
|
||
|
||
### 3-2. 가용성 · HA (Availability)
|
||
|
||
| 계층 | HA 설계 | 목표 |
|
||
|---|---|---|
|
||
| **프론트/공개** | 정적 번들 CDN 다중 엣지 + nginx 다중화 | 단일 노드 장애 무영향 |
|
||
| **백엔드** | 최소 2 인스턴스 + 헬스체크(`GET /health`) 로드밸런싱. 롤링 배포(무중단) | 무중단 배포·인스턴스 장애 격리 |
|
||
| **Redis** | Sentinel(자동 failover) 또는 Cluster. 큐 손실 방지 위해 **AOF 지속화** + 소비자 ACK/재큐 | 프라이머리 다운 시 자동 승격, 진행 중 Job 유실 0 |
|
||
| **PostgreSQL** | 프라이머리-스탠바이 스트리밍 복제 + 자동 failover(Patroni/관리형). PITR 백업 | RPO 최소·RTO 분 단위 |
|
||
| **워커** | 무상태 소비자 N대. 처리 중 죽으면 **가시성 타임아웃 후 재큐**(멱등 Job) | 워커 장애가 사용자 응답 차단 안 함(비동기) |
|
||
| **오브젝트 스토리지** | 복제·버전 관리 스토리지 | 자산 내구성 보장 |
|
||
| **Fail-Safe 배포** | 백업 → 배포 → 헬스체크(200) → 실패 시 롤백(이전 jar 유지). clean bootJar 검증 후 교체 | 깨진 배포가 서비스 중단 유발 안 함(`../BUILD_DEPLOY.md`) |
|
||
| **degraded 모드** | G1 미승인/Gemini 장애 시 워커 목 응답(구조·워터마크 유지). Claude 실패 시 Ollama 폴백(AiTextRouter). PG 복제 지연 시 프라이머리 폴백 | 외부 의존 장애 시에도 코어 기능 유지 |
|
||
|
||
> **HA 목표 SLO(초기)**: 코어 인증·설계·조회 경로 **99.5%**(행사 성수기 99.9% 지향). 나노바나나 생성은 **best-effort 비동기**(SLA 대상 아님, 큐 소진 목표만). — 구체 SLO/알림 임계는 TA 관측성([`tech.md`](tech.md))과 연계.
|
||
|
||
### 3-3. 성능 (Performance)
|
||
|
||
**(a) 대량 부스 · 공간 연산**
|
||
|
||
| 시나리오 | 부하 특성 | 설계 대응 | 목표 |
|
||
|---|---|---|---|
|
||
| 플로어플랜 3안 생성(M2) | 홀당 200~600부스 제약 솔버 | 결정적 솔버(비-LLM) + 서비스 계층 연산, LLM은 조건 해석만. 무거운 생성은 필요 시 비동기화 | 3안 생성 수 분 내(PLANNING 목표) |
|
||
| 규정 검증·최단 배선(M2/M4) | PostGIS 버퍼·거리·KNN(`<->`) 연산 | 공간 인덱스(GiST) + 매퍼 XML `ST_*` 최적화. 홀 단위 스코프 쿼리 | 배치·배선 상호작용 P95 < 2s |
|
||
| 부스 목록·조회 | 대형 행사 수천 부스 그리드 | 페이지네이션(PageResponse) + 읽기 복제 + 캐시 | 목록 P95 < 500ms |
|
||
|
||
**(b) 이미지 생성 큐 (나노바나나)**
|
||
|
||
| 항목 | 산정 | 설계 |
|
||
|---|---|---|
|
||
| 생성 지연 | 단건 평균 ~40s(design 배지), Gemini 왕복 의존 | **전면 비동기** — 사용자는 진행 배지·WebSocket 완료 푸시 수신. 동기 대기 없음 |
|
||
| 대량 동시 요청 | 홀당 200~600부스 × S1·S7 자동(PLANNING R6) | **자동 생성은 S1·S7 한정**, 나머지 온디맨드. **동일 스키마해시 캐시**로 재생성 회피. 행사별 **RenderJob 쿼터**(성공 시에만 차감) |
|
||
| 처리량 스케일 | 워커 M대 병렬, 큐 깊이 기반 증감 | 피크 시 워커 스케일아웃으로 큐 소진 시간 제어. Gemini 쿼터·비용 상한은 워커 레벨 관리 |
|
||
| 전처리 절감 | 도면/현장사진 클라이언트 Canvas **긴 쪽 1024px 다운스케일 + JPEG 0.85**(ReRoomAI 실증) | 전송량·모델 비용·지연 동시 절감 |
|
||
| S6 배선 오버레이 | 좌표 정확성 목적 | **백엔드 래스터 합성 우선**(Gemini 미경유 결정적 산출) — 생성 비용·지연에서 제외 |
|
||
|
||
**(c) 공개사이트 트래픽**
|
||
|
||
| 항목 | 설계 | 목표 |
|
||
|---|---|---|
|
||
| 공개 홍보/플로어플랜 | SSR/SSG + CDN 캐시, 오리진 캐시 미스만 read-replica | 캐시 히트 P95 < 200ms, 트래픽 스파이크 CDN 흡수 |
|
||
| 사전등록 write | 오리진 write(멱등·중복 등록 가드) + 큐잉 완충(배지 발급 비동기) | 등록 급증 시 write 완충 |
|
||
| 실시간 옥션 순위(M15) | Redis 정렬셋 순위 + WebSocket 델타 푸시, 라운드 마감 타이머 | 순위 갱신 < 1s, 다중 인스턴스 팬아웃 |
|
||
|
||
### 3-4. 용량 산정 (Capacity — 초기 근사)
|
||
|
||
> 단일 대형 행사 기준. 킨텍스 대형 홀(홀7/8 각 510부스, 홀9/10 ~600부스), 대형 행사 관람객 수만 명 가정. **Phase 1 파일럿 실측으로 교정**.
|
||
|
||
| 자원 | 산정 기준 | 초기 용량 |
|
||
|---|---|---|
|
||
| **부스 데이터** | 대형 행사 3,000~5,000부스 × (폴리곤 + DesignPlan 버전 + UtilityOrder 배선) | 행사당 수만 지오메트리 레코드 — GiST 인덱스 필수 |
|
||
| **RenderJob/이미지** | 부스 3,000 × 자동 2샷(S1·S7) + 온디맨드 α, 이미지 평균 0.5~2MB(1024px) | 행사당 ~수천~1만 이미지, 수 GB~수십 GB → OBJ + CDN. 캐시로 재생성 억제 |
|
||
| **리드·체크인(M10)** | 관람객 수만 × 체크인 이벤트 + 참가업체 리드캡처 | 행사당 수만~수십만 이벤트 로우 → 파티셔닝 후보(개인정보 §5) |
|
||
| **동시 사용자** | 설계 피크(주최자·업체) 수백 + 공개/관람객 수천~수만(D-데이) | 인증영역 수백 동시(백엔드 N대) / 공개영역 CDN 흡수 |
|
||
| **Redis** | 큐 대기 Job + 옥션 순위셋 + 캐시 + 쿼터 카운터 | 수 GB. 큐 백로그 상한·모니터링 |
|
||
| **DB 연결풀** | 공유 백엔드 다인스턴스 × Hikari 풀 | **Hikari max 제한 + PgBouncer 권고**(GUARDiA 실측 교훈: 공유 PG `max_connections` 포화 방지). 인스턴스 수 × 풀 ≤ PG 상한 |
|
||
| **오브젝트 스토리지** | 도면 + 이미지 + 서식 + 콘텐츠, 다년 누적 | 행사당 수십 GB, 보존정책(§5-3) 기반 아카이빙 |
|
||
|
||
---
|
||
|
||
## 4. 배포 토폴로지
|
||
|
||
> **논리 토폴로지 확정**. 물리 서버·도메인·포트·TLS는 **G2 확정 후 Phase E**(`E-DEP`, `kintex-devops-dev`)에서 실체화. DMZ/방화벽/부하분산 세부는 NA([`network.md`](network.md)).
|
||
|
||
### 4-1. 배포 존(Zone) 구성
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph PUBZ["공개 존 (DMZ / 인터넷 노출)"]
|
||
LB1[Reverse Proxy / WAF · nginx · TLS]
|
||
CDNZ[CDN 엣지]
|
||
PUBFE[공개 프론트 · SSR/SSG 정적]
|
||
end
|
||
subgraph APPZ["애플리케이션 존 (내부망)"]
|
||
APPFE[인증 프론트 정적 서빙<br/>organizer·exhibitor·contractor·ops]
|
||
APPBE[공유 백엔드 jar × N · systemd]
|
||
WKZ[워커 데몬 × M · systemd<br/>나노바나나 · 서류/EDM]
|
||
end
|
||
subgraph MGMTZ["관리 존 (내부 전용 · 접근 제한)"]
|
||
ADMFE[admin. 백오피스 프론트]
|
||
end
|
||
subgraph DATAZ["데이터 존 (내부, 최심부)"]
|
||
PGZ[(PostgreSQL+PostGIS<br/>프라이머리+스탠바이)]
|
||
RPLZ[(읽기 복제본)]
|
||
REDISZ[(Redis HA)]
|
||
OBJZ[(오브젝트 스토리지)]
|
||
end
|
||
subgraph EGRESS["아웃바운드 게이트 (워커/백엔드 한정)"]
|
||
OUT[허용 아웃바운드<br/>Gemini(G1)·Claude·PG결제·kxwp]
|
||
end
|
||
CDNZ --> PUBFE
|
||
LB1 --> PUBFE & APPFE & ADMFE
|
||
APPFE & ADMFE --> APPBE
|
||
APPBE --> PGZ & REDISZ & RPLZ & OBJZ
|
||
WKZ --> REDISZ & OBJZ
|
||
WKZ --> OUT
|
||
APPBE --> OUT
|
||
PGZ -.복제.-> RPLZ
|
||
```
|
||
|
||
### 4-2. 배포 단위(산출물) — `../BUILD_DEPLOY.md` §1 정합
|
||
|
||
| 단위 | 빌드 | 산출물 | 실행 | 배포 존 |
|
||
|---|---|---|---|---|
|
||
| 인증 프론트 6종 | `vite build`(역할별 번들) | `dist/`(organizer·exhibitor·contractor·ops·admin) | nginx 정적(SPA 폴백) | APP존(admin은 MGMT존) |
|
||
| 공개 프론트 | SSR/SSG 빌드 | 정적/렌더 번들 | CDN + 엣지 렌더 | 공개존 |
|
||
| 공유 백엔드 | `./gradlew bootJar`(JDK17) | `kintex-*.jar` | `java -jar` systemd × N | APP존 |
|
||
| 나노바나나 워커 | (빌드 없음) | `tools/nanobanana` | 큐 소비 데몬 systemd × M | APP존(아웃바운드 게이트) |
|
||
| 서류/EDM 워커 | — | 워커 모듈 | 큐 소비 데몬 | APP존 |
|
||
|
||
- **배포 흐름**(GUARDiA 표준 준용): `workspace/kintex` → git push → Gitea(`zio/kintex`) → webhook → deploy_server → 빌드(`bootJar`·`vite build`) → Flyway 마이그 → jar 재기동·dist 배포 → 헬스 게이트(`GET /health` 200) → 실패 시 롤백.
|
||
- **systemd 유닛**: 백엔드 jar · 워커 데몬 각각 유닛(부팅 자동기동·재시작). AI env drop-in(`ANTHROPIC_API_KEY`·`ADMIN_PASSWORD_ENC`)은 표준 프레임워크 §7 방식. **`GEMINI_API_KEY`는 나노바나나 워커 유닛에만** 주입(백엔드·프론트 미취급).
|
||
- **nginx vhost**: `<kintex-domain>` → `/`=프론트 정적, `/api/`·`/ws`=백엔드 포트. 관리자 백오피스(admin.)는 **별도 vhost + 접근 제한**(§5-1). TLS certbot. — 도메인·포트=G2.
|
||
- **환경 분리**: dev / staging / prod. staging에서 헬스·마이그·경계면 검증 후 prod 승격(운영 배포는 소유자 승인 필수).
|
||
|
||
> CI/CD 파이프라인 상세(deploy_server·롤백·webhook)는 **Phase E `kintex-devops-dev`** 정본. TA([`tech.md`](tech.md))의 빌드·관측성 표준과 연계.
|
||
|
||
---
|
||
|
||
## 5. 보안영역 · 데이터 보존 · 개인정보 경계
|
||
|
||
### 5-1. 보안영역 분리 (공개 vs 내부 백오피스)
|
||
|
||
| 영역 | 대상 | 노출 | 인증 | 격리 |
|
||
|---|---|---|---|---|
|
||
| **공개 영역** | www/expo 홍보사이트, 공개 플로어플랜, 사전등록, 관람객 앱 | 인터넷(DMZ) | 비인증 또는 셀프서비스(쓰기 제한) | 별도 렌더 경로·read-only API·행사 데이터 write 불가 |
|
||
| **인증 업무 영역** | organizer·exhibitor·contractor·ops | 인증 후 접근 | JWT SSO + TOTP 2FA + 행사 RBAC | 행사 단위 데이터 격리(§5-2) |
|
||
| **관리 영역(백오피스)** | admin. — 사용자·RBAC·마스터데이터·룰셋·감사로그·크로스테넌트 | **내부 전용**(웹 전용, 모바일 미제공) | ADMIN 역할 + 2FA 필수 + **접근 제한**(내부망/허용 IP — NA 확정) | 별도 vhost·존, 공개영역과 물리·논리 분리 |
|
||
|
||
- **최소권한·공격면 축소**: 6개 프론트 번들 분리로 역할별 코드·권한 최소화. 백오피스는 공개 인터넷에 노출하지 않는다.
|
||
- **이중 RBAC 평가**: 플랫폼 레벨(관리자)과 행사 레벨(주최자/참가/업체/홀매니저)을 JWT 클레임(`roles` eventId→역할, `hm` 홀매니저)으로 이중 평가. `/api/admin/**`·`/api/system/**` = `hasRole(ADMIN)`(PLANNING §5B-1, `../DEVELOPMENT_GUIDE.md` §4).
|
||
- **인증 스택(UIWS 표준 이식)**: JWT(HS256) + TOTP(RFC6238 SHA1·30s·6자리·±1) 2차 인증 + 로그인 실패 잠금 + admin 비번 env(`ADMIN_PASSWORD_ENC` AES-256-GCM + 별도 키파일 재시드, `admin123` 하드코딩 금지). 대상: 관리자·홀매니저·주최자·업체(내부/발주 권한) 2FA 필수, 관람객 셀프서비스 선택.
|
||
|
||
### 5-2. 데이터 격리 (행사 단위 · 영업비밀)
|
||
|
||
- **행사(Event) 단위 워크스페이스**: 부스 설계는 경쟁사에 민감(PLANNING R10). 부스 데이터 접근은 **소유 참가업체 + 주최자 + 홀매니저**로 한정. 모든 도메인 경로는 `{eventId}` 스코프 + RBAC 가드.
|
||
- **옥션(M15) 자료 격리**: AI 설계자료(M2~M5)는 옥션 초대된 **킨텍스 등록업체(M7 검증 통과)**만 열람. 미등록 업체 응찰 원천 차단(`NOT_REGISTERED_COMPANY` 403).
|
||
- **BI 관점 격리**: 참가업체 관점 ROI(자기 부스)와 운영사 관점 수익성(전 행사)은 **별도 대시보드·권한**으로 격리(PLANNING M16-1).
|
||
|
||
### 5-3. 개인정보 경계 · 데이터 보존
|
||
|
||
| 데이터 | 개인정보 등급 | 처리 원칙 | 보존 |
|
||
|---|---|---|---|
|
||
| 관람객 등록·배지·체크인·리드(M10) | **개인정보(PLANNING R10)** | 수집 시 **동의** 필수. 리드 접근은 감사로그(`TB_AUDIT_LOG`) 전수 기록. 참가업체는 자기 리드만 | **보존정책 명시**(행사 후 N개월, 동의 철회·삭제권 지원 — DA 확정) |
|
||
| 부스 설계·도면·생성이미지 | 참가업체 자산·영업비밀 | 행사 단위 격리, 응답에서 내부 식별자·해시 shape 제외 | **행사 종료 후 보존 정책 별도**(참가업체 자산, PLANNING §8) |
|
||
| 결제·정산(M9) | 금융·과세 정보 | PG 위임(카드정보 비보관), 세금계산서 연동 | 법정 보존 기간 준수 |
|
||
| 자격증명·비밀·API키 | 최고 민감 | **응답·로그·에러·커밋에 절대 노출 금지**. `GEMINI_API_KEY`·`ANTHROPIC_API_KEY`·OTP 시크릿·비번 해시 미노출. AES-256-GCM 저장, 비번 BCrypt | env only, DB·코드 미기록 |
|
||
| AI 생성 이미지 | 오인 위험(R1) | **워터마크 강제**("AI 생성 예상 이미지…") + 메타데이터. 계약·심사 서류 자동 배제. 제거 불가 | 캐시·스키마해시 관리 |
|
||
|
||
- **보안 불변(위반=QA 반려)**: 스택트레이스 차단(`GlobalExceptionHandler`·`DataAccessException` 핸들러), 민감필드 응답 제외, AI 워터마크 항상 포함, 등록업체 응찰 가드, admin env 시드. — `../DEVELOPMENT_GUIDE.md` §5 계약.
|
||
- **감사 추적**: 승인·낙찰(M15)·설계 변경·룰셋 개정·리드 접근(개인정보) 전수 `TB_AUDIT_LOG` 기록(PLANNING §5B-1).
|
||
|
||
---
|
||
|
||
## 6. 연동 아키텍처
|
||
|
||
### 6-1. SSO · 역할 RBAC (6역할)
|
||
|
||
- **단일 JWT SSO** 위에 플랫폼 레벨 + 행사 레벨 권한 이중 평가. 6역할: 주최자·참가업체·장치/공사업체·킨텍스 직원(홀매니저·운영)·관리자·관람객/일반대중.
|
||
- 역할별 프론트는 동일 SSO·API 계약을 상속하되 **번들·도메인 분리**. 백오피스(admin.)는 내부 전용·2FA 필수(§5-1).
|
||
- 등록업체 계정은 **M7 등록업체 DB 검증** 통과분만 초대·옥션 응찰. 관람객·일반대중은 셀프서비스(쓰기 제한).
|
||
- 인증 상세 계약은 [`app.md`](app.md)(AA)·`../DEVELOPMENT_GUIDE.md` §4.
|
||
- **Open SSO(OIDC/Keycloak) 도입 + 인사·조직 API 연동**은 별도 정본 [`sso-hr-integration.md`](sso-hr-integration.md)(SA) — 기존 JWT+2FA를 삭제 없이 **공존(SSO 1차 인증→앱 JWT 브로커, 로컬 폴백)**, 직원·조직은 `HrDirectoryClient` 어댑터로 조달(로컬 스냅샷 폴백). 관람객/외부는 SSO 제외(셀프서비스 유지).
|
||
|
||
### 6-2. 외부 게이트 (아웃바운드 통제)
|
||
|
||
| 연동 | 경로 | 통제 | 게이트 |
|
||
|---|---|---|---|
|
||
| **나노바나나(Gemini)** | 나노바나나 **워커 전용** 아웃바운드 → `generativelanguage.googleapis.com` | `GEMINI_API_KEY` 워커 env only. 워커 서브넷만 아웃바운드 허용(NA). 미승인 시 목/degraded | **G1** |
|
||
| **Claude(텍스트 AI)** | 백엔드 `AiTextRouter` → `api.anthropic.com` | `ANTHROPIC_API_KEY` env only(코드·DB·로그·응답 미기록). **실패 시 Ollama 폴백** | 승인됨(예외) |
|
||
| **PG 결제(M9)** | 백엔드 → 국내 PG(카드·계좌·세금계산서) | 카드정보 비보관(PG 위임), 결제 콜백 검증 | — |
|
||
| **kxwp/kxfp 작업신고(M6)** | **파일 릴레이**(제출용 파일 생성 + 업로드 안내) | 폐쇄형·API 미공개(R3). 초기 수동 릴레이, 정식 API는 킨텍스 협의(Phase 3) | — |
|
||
| **등록업체 DB(739)** | 주기 수집 → 자체 DB화 | 공개 데이터 수집, 추후 공식 피드 | — |
|
||
| **행사일정 시스템** | 공개 캘린더 수집 → 가용성 역산 | 정확 가용성은 킨텍스 내부 데이터 협의 | — |
|
||
| **CDN** | 공개 자산·이미지 프론팅 | 공개 read-only 자산만 | — |
|
||
|
||
- **아웃바운드 원칙**: 인터넷 아웃바운드는 **워커·백엔드 특정 경로만 허용**(화이트리스트). 그 외 외부 API 금지(GUARDiA 보안 제약, `../DEVELOPMENT_GUIDE.md` §5). 세부 방화벽 규칙은 NA([`network.md`](network.md)).
|
||
|
||
### 6-3. 비동기 큐 계약 (Redis)
|
||
|
||
- Spring 백엔드는 RenderJob·서류·EDM·알림을 **Redis 큐에 발행**하고 상태만 관리. 워커가 소비·처리·완료 콜백(WebSocket). **Java 재구현 대신 얇은 큐 계약으로 결합**(PLANNING §8, google-genai는 Python SDK → 워커 유지).
|
||
- 큐 신뢰성: AOF 지속화 + 소비자 ACK + 가시성 타임아웃 재큐(멱등 Job). 쿼터·순위·타이머·캐시도 Redis(§2-1).
|
||
|
||
---
|
||
|
||
## 7. 아키텍처 결정 요약 (ADR-lite)
|
||
|
||
| # | 결정 | 이유 | 대안·트레이드오프 |
|
||
|---|---|---|---|
|
||
| 1 | 나노바나나를 **Python 워커 사이드카**로 분리 | google-genai=Python SDK, ReRoomAI 검증 방어로직 이식(Java 재구현 회피). 이미지 생성 독립 스케일 | Java 통합(재검증 비용·강결합) 배제 |
|
||
| 2 | **역할별 프론트 번들 분리** | 최소권한·공격면 축소, 공개/백오피스 격리 | 단일 SPA(권한 혼재·공격면 확대) 배제. 공유 디자인/API로 중복 완화 |
|
||
| 3 | 백엔드 **무상태 + Redis 외부화** | 수평 확장·무중단 배포·다중 인스턴스 WebSocket 팬아웃 | 인메모리 상태(ReRoomAI Map 방식) — 재시작·다중인스턴스 취약(§reroomai (F)) 배제 |
|
||
| 4 | **읽기 복제 오프로드**(BI·공개조회) | 운영 프라이머리 보호(PLANNING §8-1) | 단일 DB 직조회(BI 부하 전파) 배제 |
|
||
| 5 | **CDN + SSG**로 공개 트래픽 흡수 | 관람객 스파이크·SEO·다국어 | 오리진 직서빙(스파이크 취약) 배제 |
|
||
| 6 | 룰셋 **버전 데이터** 분리 | 연 단위 요율·규정 개정 무중단 반영 | 코드 하드코딩(배포 필요) 배제 |
|
||
| 7 | S6 배선 오버레이 **백엔드 래스터 우선** | 좌표 정확성(생성 왜곡 배제)·비용/지연 제외 | Gemini 생성(재질·색 왜곡) 배제 |
|
||
|
||
---
|
||
|
||
## 8. 교차참조
|
||
|
||
- 기획 정본: [`../PLANNING.md`](../PLANNING.md) §2·§7·§8·§10
|
||
- 구현 백로그: [`../IMPLEMENTATION_BACKLOG.md`](../IMPLEMENTATION_BACKLOG.md) Phase A~E
|
||
- **Open SSO · 인사(조직) API 연동(SA)**: [`sso-hr-integration.md`](sso-hr-integration.md) — OIDC/Keycloak·HrDirectoryClient·3자 매핑·이행(coexist→cutover)
|
||
- 나노바나나 파이프라인 근거: [`../analysis/reroomai-source.md`](../analysis/reroomai-source.md)
|
||
- 애플리케이션 아키텍처(AA·A-1): [`app.md`](app.md) — 모듈 경계·API 표준·패키지
|
||
- 기술 표준(TA·A-3): [`tech.md`](tech.md) — 빌드·배포·관측성·AiTextRouter
|
||
- 데이터 아키텍처(DA·A-4): [`data.md`](data.md) — 전사 ERD·공간·마스터·BI 마트
|
||
- 네트워크 아키텍처(NA·A-5): [`network.md`](network.md) — DMZ/방화벽/부하분산/아웃바운드
|
||
- 개발 표준: [`../DEVELOPMENT_GUIDE.md`](../DEVELOPMENT_GUIDE.md) · 빌드/배포: [`../BUILD_DEPLOY.md`](../BUILD_DEPLOY.md)
|
||
|
||
---
|
||
|
||
## 9. 변경 이력
|
||
|
||
| 버전 | 일자 | 작성자 | 내용 |
|
||
|---|---|---|---|
|
||
| v1.0 | 2026-07-11 | SA | 최초 작성(A-2) — 시스템 구성도(역할별 프론트·공유 백엔드·백오피스·공개사이트·나노바나나 워커·Redis·PostGIS), 논리/배포 토폴로지, NFR(확장성·HA·성능(대량부스·이미지큐·공개트래픽)·용량 산정), 연동 아키텍처(SSO/RBAC 6역할·PG결제·kxwp 릴레이·외부 게이트 Claude/Gemini), 보안영역(공개 vs 백오피스)·데이터 보존·개인정보 경계, G1/G2 게이트, ADR-lite. PLANNING §8 정합·확정 스택 준수. AA/TA/DA/NA 교차참조 |
|