39 KiB
KINTEX AI 전시·행사시스템 — 설계서
- 문서 종류: 설계서(System Design Document)
- 프로젝트: KINTEX AI 전시·행사시스템 (KINTEX AI Exhibition & Event System)
- 작성일: 2026-07-12 · 버전: v1.0
- 근거 문서:
docs/PLANNING.md(v3.4) ·docs/design.md(v2.4) ·docs/architecture/{app,system,tech,data,network,sso-hr-integration}.md·docs/COMMON_CODES.md· 실제 구현 스키마(FlywayV1~V49) · 실제 컨트롤러(REST 계약)- 보안: 본 문서에는 자격증명·비밀번호·SSH·내부 IP·시크릿을 기재하지 않는다.
- 비고: 본 설계서는 구현된 스키마·API 계약을 정본으로 삼고, 계획(설계 완료·미구현) 항목은 그 취지를 명시한다.
목차
- 시스템 아키텍처
- 애플리케이션 아키텍처(레이어·모듈·의존성)
- 데이터 설계
- API 설계
- 화면 설계
- AI 설계(§8A)
- 인증·인가 설계
- 네트워크·보안영역 설계
- 비기능 요구사항(NFR)
1. 시스템 아키텍처
1-1. 전체 구성
6개 역할별 분리 프론트(React·Vite·TS) + 단일 공유 Spring Boot 백엔드 + 나노바나나 Python 워커 사이드카를 SSO·역할 RBAC 위에 얹고, PostGIS·Redis 큐·오브젝트 스토리지를 공유한다.
[엣지/DMZ] CDN · WAF/nginx(TLS 종단)
│
[역할별 프론트] organizer · exhibitor · contractor · ops · admin(내부) · public/visitor
│ (SSO · 역할 RBAC 게이트)
[공유 Spring Boot 백엔드] REST + WebSocket(STOMP)
│ 룰 엔진(요율/규정) · 배치·배선 엔진(PostGIS) · 옥션 엔진(M15) · BI 집계(M16) · CMS(M17) · 공개 API
│
[비동기] Redis 큐 → 나노바나나 워커(google-genai) · 서류/PDF/EDM 워커 → 오브젝트 스토리지
│ (완료 시 WebSocket 푸시)
[데이터] PostgreSQL + PostGIS (프라이머리 + 읽기 복제) · 오브젝트 스토리지
1-2. 대원칙(5)
- 단일 공간 데이터 모델 — 부스 폴리곤·트렌치 포인트·배선 경로를 PostGIS로 일원화(설계·시각화·검증·정산·wayfinding·BI가 동일 원천 재사용).
- 이미지 생성 전면 비동기 — Spring이 RenderJob을 Redis 큐에 발행 → Python 워커가 Gemini로 생성 → 오브젝트 스토리지 적재 → WebSocket 완료 푸시.
GEMINI_API_KEY는 워커 전유(백엔드 미취급). - 역할별 프론트 분리 — 최소권한·공격면 축소, 공유 디자인 시스템·컴포넌트·API 계약 상속.
- 룰셋 = 버전 관리 데이터 — 규정(높이·방염·하중)·요율을 코드가 아닌
rulesets/*.json+ master_data로 관리(연 단위 개정 무중단 반영). - 공개 vs 내부 백오피스 보안영역 분리(§8).
1-3. 배포 토폴로지(존)
- 공개 존(DMZ): Reverse Proxy/WAF·nginx·TLS, CDN, 공개 프론트 SSR/SSG, 공개 API GW(화이트리스트 엔드포인트만), PG 콜백.
- 애플리케이션 존(내부망): 인증 프론트 정적 서빙(organizer·exhibitor·contractor·ops), 공유 백엔드 jar × N(systemd, 무상태 수평 확장), 워커 데몬 × M.
- 관리 존(내부 전용): admin 백오피스(웹 전용, VPN/허용 IP + 2FA 강제).
- 데이터 존(최내곽): PostgreSQL+PostGIS(프라이머리+스탠바이)·읽기 복제·Redis HA·오브젝트 스토리지. 아웃바운드 없음(유출 경로 제거).
물리 서버·도메인·포트는 G2 게이트 확정 후 Phase E에서 실체화(개발 도메인은
kintex.zioinfo.co.kr, 포트 8021). 근거: architecture/system.md·network.md.
2. 애플리케이션 아키텍처(레이어·모듈·의존성)
2-1. 패키지 구조
루트 com.zioinfo.kintex. 횡단 계층 + 도메인 모듈:
common(응답봉투·페이징·에러·감사 AOP·공통코드 캐시 — 무의존),config(Security·WebSocket·Redis·MyBatis),auth(JWT·RBAC·2FA/OTP·가드),rules(규정·요율 룰셋 로딩·평가),system(시스템관리),work(공통 업무),module(도메인 m2~m5 등).- 리소스:
application.yml(env 플레이스홀더),mybatis/mapper/**/*.xml(공간 SQLST_*),rulesets/(compliance·rates JSON = 데이터).
2-2. 레이어링 표준
| 계층 | 책임 | 금지 |
|---|---|---|
| Controller | HTTP 바인딩·@Valid·RBAC 가드 호출·서비스 위임·ApiResponse 래핑 |
비즈니스 로직·SQL·트랜잭션·매퍼 직접 호출 |
| Service(interface+Impl) | 비즈니스 규칙·@Transactional 경계·룰 엔진 호출·매퍼 오케스트레이션·DTO 조립 |
HTTP 타입 참조 |
| Mapper(MyBatis) | DB 접근·공간 SQL(ST_*) 바인딩 | 비즈니스 분기·DTO 조립 |
| DTO(record) / domain | 불변 전송 객체 / 순수 값객체(프레임워크 무의존) | — |
- 공간 연산은 매퍼 XML의 PostGIS SQL로 수행(서비스는 스칼라/GeoJSON 결과만 사용). 조회
readOnly=true, 버전 리소스는 낙관적 잠금(불일치=409).
2-3. 의존성 규칙(단방향·순환 금지)
module.mN→rules·auth·common(횡단 허용).common은 무의존.- 모듈 간 명시 방향만: M3→M2, M4→M2, M5→M2·M3·M4, M15→M2·M3·M4·M5·M7, M9→M1·M4·M15, M13→M2, M14→M4·M10, M16→전 모듈(읽기), M12→M10·M17.
- 역방향 필요 시 직접 참조 금지 → 도메인 이벤트·공유 식별자로 디커플(예: M15 낙찰→M9는 발주 링크). 모듈 간 결합은 서비스 인터페이스로만. 검증 = ArchUnit 빌드타임 아키텍처 테스트(역참조·순환 CI 차단).
- 백엔드는 단일 공유 모듈러 모놀리스(역할별로 쪼개지 않음) — 모듈 경계 + 의존 규칙으로 코드 레벨 강제, 노출 표면은 경로 접두 + RBAC로 분리.
근거: architecture/app.md.
3. 데이터 설계
3-1. 데이터 표준(명명·타입)
- 테이블/컬럼: PostgreSQL 무인용 소문자
snake_case, PK<엔티티>_id(도메인은 UUID), WISE 이식 테이블은 정본 PK 유지. - 지오메트리
geom/<용도>_geom, 암호화 PII<필드>_enc, 코드 컬럼status/<의미>_code, 시각*_at(timestamptz, UTC 저장/Asia/Seoul 표시), 금액numeric(KRW). - DTO(camelCase) ↔ 컬럼(snake_case): MyBatis
map-underscore-to-camel-case=true. - 응답 제외(불변):
*_enc·password_hash·otp_secret·내부 IP/SSH·내부 식별자는 API 응답 완전 제외.
3-2. FK 최소화 원칙 (소유자 지시 2026-07-12)
- 원칙: "FK는 최소화, 공통코드로 관리." 신규 도메인/테넌트 테이블은 물리
FOREIGN KEY를 두지 않고, 참조무결성은 애플리케이션 레이어 검증 +*_id소프트 참조 명명으로 보장. - 근거: ① 멀티테넌트 복합 PK(
(tenant_id, id)) 전환 시 단일 id FK가UNIQUE(id)보조제약을 강제하는 마찰 ② MyBatis가 조인·삭제 순서 제어 ③ 멱등ON CONFLICT시드 순서 자유 ④ 부스 재배치(replaceBooths) 시 자식 재지정 빈번(V3utility_order·render_job이 이미 소프트 참조 = 정본 사례). - 물리 FK 예외 화이트리스트(그 외 신규 FK 신설 금지): (W1)
common_code.grp_code, (W2)sys_menu.parent_id(self), (W3)sys_role_permission, (W4)sys_role_menu— 전역 시스템/RBAC 무결성 필수분만. - 소프트 참조 보완: 임계 트랜잭션(낙찰·정산) 명시적 부모 존재 검증, 삭제는 서비스가 자식 선처리(soft-delete
use_yn='N'우선), 논리참조 인덱스(tenant_id, <ref>_id), 야간 고아 스캔(DQ 게이트).
3-3. 공통코드 표준
- 범주형 컬럼(상태·유형·심각도 등 열거 가능 소수값)은 자유문자열/DB enum이 아닌
common_code_group/common_code로 관리. 컬럼엔 코드값(영문 상수)만 저장, 표시명(한글)은 조인/캐시. DBENUM물리타입 지양. - 코드 vs 마스터 경계: 열거 가능 소수값=공통코드(BOOTH_TYPE·RENDER_STATUS·SHOT_PRESET 등), 다건·CRUD·버전 대상=마스터/룰셋(홀·요율·규정 룰셋·등록업체). 정본 =
docs/COMMON_CODES.md. - 확정 코드그룹 예:
EVENT_ROLE(ORGANIZER·EXHIBITOR·CONTRACTOR·HALL_MANAGER),PORTAL_ROLE,BOOTH_TYPE(independent·assembled),COMPLIANCE_SEVERITY(block·warn·pass),RENDER_STATUS(QUEUED·RUNNING·DONE·FAILED),SHOT_PRESET(S1~S7),VERIFY_METHOD(EMAIL·OTP).
3-4. 공간 데이터 표준
- SRID
0(홀 로컬 평면 데카르트 좌표, 단위 미터). 지리좌표(4326) 아님,geometry(geography 아님). - 부스 =
Polygon, 트렌치 =Point(+ 배선 run은 LineString), 배선 =LineString/MultiLineString. 전geomGiST 인덱스 필수. - 저장 전
ST_IsValid·닫힌 링·홀 내포 검증(실패 시 400). 미실측 트렌치는is_assumed=true플래그(PLANNING R4). - 파생 연산: 최단 배선(라우팅), 통로 폭 검증(버퍼), 면적 정산(ST_Area)이 모두 SQL 수준에서 수행.
3-5. 핵심 엔티티(구현 스키마 기준)
신원·마스터(V2)
app_user(id·email·display_name·password_hash(BCrypt, 응답 제외)·hall_manager·otp_secret(응답 제외)·failed_login_count·locked_until·status) — V7에서 otp_enabled·verify_method·role_code·dept_id·last_login_at 순증, V26에서 tenant_id 순증.company(id·registration_no(사업자번호, 초대 검증 키)·name·category(14분류)·region·registered(미등록 응찰 차단)).event·hall(exhibition_center·label·width/depth/height_m·area_m2·floor_load_t_per_m2·floor_type·booth_capacity·has_gas·is_assumed_trench)·hall_assignment.event_member(event_id·user_id·role_code(ORGANIZER·EXHIBITOR·CONTRACTOR·HALL_MANAGER)·booth_id·company_id) — 행사 단위 RBAC 멤버십.booth_standard(assembled·premium spec jsonb)·master_data(RATE·UTILITY_FEE·COMPLIANCE + ruleset_version).
공간 코어(V3, P0)
trench(hall_id·geom(Point)·supply_power/water/air/network/gas·is_assumed).hall_exit(geom(Point)·clearance_m — 비상구 이격 버퍼).layout(event_id·hall_id·version·status, UNIQUE(event_id,hall_id,version)).booth(layout_id·booth_no·booth_type·geom(Polygon)·size_w/d_m·height_m·floor_load_t_per_m2·premium).design_plan(booth_id·version·status·spec jsonb, UNIQUE(booth_id,version)).utility_order(event_id·booth_id(소프트 참조)·quote jsonb·wiring(MultiLineString)·location_diagram_url).render_job(event_id·booth_id(소프트)·shot_preset(S1~S7)·status·image_url·schema_hash·model_version·error_message(요약만)).
옥션 M15(V16)
auction(event_id·category·auction_type(reverse/rfq)·award_criteria(lowest/comprehensive)·weight_price/reputation/delivery·round·deadline·material_package_id·materials).auction_invite(등록업체만, UNIQUE(auction_id,company_id) — 미등록 원천 차단).bid(=Quotation: subtotal·vat·total·lead_days·valid_until·terms·linesjsonb·version·status, UNIQUE(auction_id,company_id) — 재응찰 시 버전 증가).award(옥션당 1건, bid_id·reason·awarded_by — 감사 추적)·company_reputation(rating·jobs_done·claim_rate).- 봉인 입찰: 마감 전 경쟁 견적 비공개(서비스 레이어 강제 마스킹), 마감 후 발주자 전체 공개.
관람·발주·정산·콘텐츠(V14~V24 등)
- M6:
event_milestone·required_document·document_review_issue(V14). M8:dock·dock_reservation(V15),logistics_*(V33). - M10:
visitor_registration·lead(V17). M12:edm_campaign·sponsorship_package·sponsorship_sponsor(V18). 공개:exhibit_inquiry(V20)·visitor_guide·transport_info(V43). - M17 CMS:
cms_content·cms_translation·microsite(V19),cms_content_version·cms_media(V21). - M9:
invoice·invoice_payment(V24),invoice_refund·tax_invoice(V34). M1 판매:booth_sale(V27). 결재:approval·approval_line·approval_history(V29).
공통·시스템관리(V7·V8·V37)
common_code_group/common_code·sys_menu·sys_role/sys_permission/sys_role_permission·sys_setting·audit_log(actor·action·target·summary·ruleset_version·result·ip_hint)(V7).- 공통 업무(V8):
worklog·schedule·message/message_recipient·notice·opinion/opinion_comment·meeting/meeting_action·report·notification. - 시스템 기초(V37):
dept·sys_program·sys_role_menu·sys_auth_policy·login_history·error_log. 기타:login_slide(V11)·holiday(V41)·sys_message(V48)·mail_log(V36)·webhook_*(V35)·ai_config(V30).
멀티테넌시(V26·V31)
tenant(id(slug: kintex·coex)·name·domain·status). KINTEX = 테넌트 #1 시드.- 핵심 테이블
tenant_id순증(NOT NULL DEFAULT 'kintex'백필, 회귀 0) +(tenant_id, …)선두 복합 인덱스. V31에서 테넌트 루트(event·hall·app_user)를PRIMARY KEY (tenant_id, id)복합 PK로 전환.
3-6. 마이그레이션 요약(Flyway V1~V49)
| 버전 | 주제 | 주요 산출 |
|---|---|---|
| V1 | 확장 | PostGIS·pgcrypto 등 extension |
| V2 | 신원·마스터 | app_user·company·event·hall·hall_assignment·event_member·booth_standard·master_data |
| V3 | 공간 코어(P0) | trench·hall_exit·layout·booth·design_plan·utility_order·render_job(+GiST) |
| V4·V5·V6 | 마스터 시드 | 홀 마스터·트렌치 그리드·마스터/데모 시드 |
| V7 | 시스템관리·보안 | common_code(_group)·sys_menu·sys_role/permission·sys_setting·audit_log |
| V8 | 공통 업무 | worklog·schedule·message·notice·opinion·meeting·report·notification |
| V9 | 공개 인증 | password_reset |
| V10 | 시드 | 10년치 행사 시드 |
| V11·V12·V13 | 부가 | login_slide·TOTP 2FA·카탈로그/대시보드 인덱스 |
| V14 | M6 | event_milestone·required_document·document_review_issue |
| V15 | M8 | dock·dock_reservation |
| V16 | M15 옥션 | auction·auction_invite·bid·award·company_reputation(+시드) |
| V17 | M10 | visitor_registration·lead |
| V18 | M12 | edm_campaign·sponsorship_package·sponsorship_sponsor |
| V19 | M17 CMS | cms_content·cms_translation·microsite |
| V20 | 공개 사이트 | exhibit_inquiry |
| V21 | 확장 | cms_content_version·cms_media(체크인·리드·CMS 확장) |
| V23 | 일정 보강 | schedule 확장 |
| V24 | M9 정산 | invoice·invoice_payment |
| V25 | M1 | 홀 배정 확장 |
| V26 | 멀티테넌시 1단계 | tenant + 핵심 테이블 tenant_id 순증·복합 인덱스 |
| V27 | 부스 판매 | booth_sale |
| V28 | 옥션 부가 | BOQ·옥션 수수료 |
| V29 | 결재 | approval·approval_line·approval_history |
| V30 | AI | ai_config |
| V31 | 테넌트 표준 | 테넌트 루트 복합 PK((tenant_id, id)) 전환 |
| V32 | 시드 | 2026 하반기 킨텍스 행사 |
| V33 | M8 확장 | logistics_equipment/request·rental_item/order·inbound |
| V34 | M9 확장 | invoice_refund·tax_invoice |
| V35 | 자동화 | webhook_subscription·delivery·inbound·edm_followup_log |
| V36 | 메일 | mail_log |
| V37 | 시스템 기초 | dept·sys_program·sys_role_menu·sys_auth_policy·login_history·error_log |
| V38·V39 | 데모 | full·realism 데모 시드 |
| V41·V42 | 마스터/데모 | holiday(2050)·대량 데모 시드 |
| V43 | 관람 가이드 | visitor_guide·transport_info + v_event_calendar·v_event_monthly_summary(뷰) |
| V44 | 성능 | 성능 인덱스 |
| V45·V46·V47 | 부가/데모 | 프로필 사진·포스터 로컬 에셋·라이브 행사 폐루프 시드 |
| V48 | 메시지 | sys_message(템플릿) |
| V49 | 데모 | 빈 테이블 데모 시드 |
멱등(
IF NOT EXISTS·ON CONFLICT) + 비파괴 순증 원칙. V22·V40은 결번.
3-7. VIEW/MVIEW/배치 전략
v_*VIEW: 실시간 파생·경량 조인·상태 산출(예v_event_calendar— 날짜→UPCOMING/ONGOING/ENDED 산출로 별도 상태 컬럼 불필요). tenant_id 필터·민감 컬럼 미노출.mv_*MATERIALIZED VIEW: 무겁고 실시간성 낮은 집계(BI KPI·가동률·리드/ROI). 새로고침 전략 명시(야간 배치·REFRESH ... CONCURRENTLY·mview 인덱스).- BI 데이터마트(M16): 스타 스키마
FACT_BOOKING/SETTLEMENT/UTILITY/AUCTION/VISITOR+DIM_DATE/HALL/EVENT/EXHIBITOR+KPI_SNAPSHOT(built_at 각인). 별도mart스키마, 야간 ETL 또는 읽기 복제. 운영 DB 직조회 금지. - 배치 카탈로그(J1~J9): mview 새로고침·KPI 스냅샷·마감 알림/할일·EDM/옥션 통지·세션 만료 정리·고아 검출(DQ)·PII 보존/파기(행사종료+1년)·행사 crawl·정산 롤업. 공통 요건: 멱등·분산락·실패 격리·감사·테넌트 스코프.
근거: architecture/data.md.
4. API 설계
4-1. 표준
- 베이스
/api. 공개=/api/public/**, 워커=/api/internal/**, 행사 스코프=/api/events/{eventId}/…, 플랫폼 관리=/api/admin/**(hasRole ADMIN), 인증=/api/auth/**. 비-CRUD 액션은 하위 동사 세그먼트(POST). - 응답 봉투
ApiResponse<T>{success·data·error{code,message}}, 목록PageResponse<T>{items·page·size·total}. - ErrorCode→HTTP: VALIDATION 400 · UNAUTHORIZED 401 · FORBIDDEN 403 · NOT_FOUND 404 · CONFLICT 409 · COMPLIANCE_BLOCKED 422 · RENDER_QUOTA_EXCEEDED 429 · NOT_REGISTERED_COMPANY 403 · NOT_IMPLEMENTED 501 · INTERNAL 500.
4-2. 도메인별 주요 엔드포인트(실제 컨트롤러 기준)
| 도메인 | 베이스 경로 | 컨트롤러 |
|---|---|---|
| 인증(로그인·2FA·비번찾기·프로필사진·앱무결성) | /api/auth, /api/auth/app-integrity |
AuthController·PublicAuthController·TwoFactorController·ProfilePhotoController·AppIntegrityController |
| M2 플로어플랜 | /api/events/{eventId}/halls/{hallId}/layout |
FloorplanController |
| M3 부스 설계 | /api/events/{eventId}/booths/{boothId}/design |
DesignController |
| M4 유틸리티 | /api/events/{eventId}/booths/{boothId}/utility |
UtilityController |
| M5 렌더잡 | /api/events/{eventId}(render), /api/internal/render(워커 콜백) |
RenderJobController·RenderWorkerCallbackController |
| M15 옥션 | /api/auctions, /api/contractor |
AuctionController·ContractorController |
| M1 홀 배정·부스 판매 | /api/halls, /api/booth-sales, /api/events(catalog) |
HallAssignController·BoothSalesController·EventCatalogController |
| M6 서류·마일스톤 | /api/events/{eventId}(document) |
DocumentController |
| M8 물류 | /api/events/{eventId}, /api/events/{eventId}/logistics |
LogisticsController·LogisticsExtController |
| M9 정산 | /api/settlement |
SettlementController |
| M10 관람객·리드 | /api/visitors 등(VisitorController) |
VisitorController |
| M12 마케팅 | /api/events/{eventId}(marketing) |
MarketingController |
| M16 BI·분석 | /api/analytics, /api/events/{eventId}/analytics, /api/events/{eventId}/dashboard, /api/admin/dashboard |
AnalyticsController·AnalyticsOverviewController·DashboardController·AdminDashboardController |
| M17 CMS·마이크로사이트 | /api/cms/contents, /api/cms/media, /api/exhibitors/{exhibitorId}/microsite |
CmsContentController·CmsMediaController·MicrositeController |
| 공개 사이트·가이드·AI 도우미 | /api/public, /api/public/cms, /api/public/microsites, /api/public/ai |
PublicSiteController·PublicGuideController·PublicCmsController·PublicMicrositeController·VisitorAssistantController |
| 현장 운영 | /api/events/{eventId}/ops |
OpsController |
| 공통 업무(§5B) | /api/work/{worklogs,schedules,messages,notices,opinions,search,meetings,reports,stats,approvals,notifications} |
Worklog·Schedule·Message·Notice·Opinion·Search·Meeting·Report·Stats·Approval·Notification Controller |
| 시스템관리(M18) | /api/admin/{users,roles,roles/{role}/menus,programs,depts,companies,settings,audit,login-history,error-log,mail-config,notify-config,system-health,rulesets,auth-policy} |
SysUser·Role·RoleMenu·Program·Dept·Company·Setting·AuditLog·LoginHistory·ErrorLog·MailConfig·NotifyConfig·SystemHealth·AdminRuleset·AuthPolicy Controller |
| 테넌트 | /api/admin/tenants |
TenantAdminController |
| AI 설정·NL 질의 | /api/admin/ai, /api/ai |
AiConfigController·NlQueryController |
| 웹훅 | /api/webhooks/in, /api/admin/webhooks |
WebhookInbound·WebhookAdmin Controller |
| 헬스 | /health, /api/home |
HealthController·HomeController |
4-3. WebSocket(STOMP)·큐 계약
GET /ws(SockJS), prefix/topic(서버→클라)·/app(클라→서버). 토픽/topic/render/{jobId}·/topic/auction/{auctionId}·/topic/events/{eventId}/notifications·checkin. 페이로드는 REST DTO 재사용.- Redis 큐: RenderJob 큐
kintex:renderjob:queue, 상태...:job:{jobId}, 쿼터...:quota:{eventId}. 성공 시에만 쿼터 차감. G1 미승인 시에도 큐잉/상태는 동작(목/degraded).
근거: architecture/app.md, 실제 controller 매핑.
5. 화면 설계
5-1. 화면 총괄
design.md v2.4 집계 총 89화면 — 웹 코어·도메인 52(SCR-01~51, SCR-HOME) + 관리자 10(SCR-A1~A10) + 공개사이트 8(SCR-P1~P8) + 3-트랙 관문 4(SCR-T0~T3) + 모바일 15(SCR-M1~M15). 역할 약칭: 주=주최자·참=참가업체·장=장치/공사업체·홀=킨텍스 직원·관=관리자·대=일반 대중/관람객.
5-2. 웹 코어·도메인(대표)
| SCR | 화면 | 모듈 | 역할 |
|---|---|---|---|
| SCR-01 | 로그인 & 행사 워크스페이스 선택 | 공통 | 전 |
| SCR-HOME | 로그인 후 메인 홈(랜딩 대시보드) | 공통·§5B·M1·M12 | 전 |
| SCR-02 | 주최자 대시보드(D-데이 마일스톤 타임라인) | M1·M6 | 주 |
| SCR-03 | 부스 배치 에디터(DnD+AI 자동배치+규정 오버레이) | M2 | 주 |
| SCR-04 | 배치안 비교(S7 홀 전경 조감) | M2·M5 | 주 |
| SCR-05 | 참가업체 부스 홈 | M3·M6 | 참 |
| SCR-06 | 부스 설계 스튜디오(스펙→나노바나나 4샷+before/after) | M3·M5 | 참·장 |
| SCR-07 | 유틸리티 배선 뷰(트렌치 오버레이+자동 견적) | M4 | 참·장 |
| SCR-08 | 유틸리티 신청 요약·위치표시도 | M4b | 참 |
| SCR-09 | 장치업체 규정 검증 리포트 | M3 | 장 |
| SCR-10/11 | 홀매니저 승인 큐 / 검수 상세 | M2·M3·M6 | 홀 |
| SCR-12 | 시각화 갤러리(S1~S7) | M5 | 전 |
| SCR-13 | 경영분석 대시보드 | M16 | 주·홀·관 |
| SCR-18~29 | 홀배정·부스판매·정산·서류·매칭·물류·옥션(개설·응찰·견적서·낙찰) | M1·M6·M7·M8·M9·M15 | 역할별 |
| SCR-30~37 | 관람객 등록·체크인·리드·EDM·스폰서십·CMS·마이크로사이트·다국어 | M10·M12·M17 | 역할별 |
| SCR-38 | 업체 수주 부스 대시보드 | 업체포털 | 장 |
| SCR-39~48 | §5B 공통 업무(업무일지·일정·쪽지·공지·의견·검색·회의록·업무보고·알림·마이페이지) | §5B | 전 |
| SCR-49~51 | 회원가입·비밀번호 재설정·2차 인증(OTP) 설정 | §5B-3 | 전 |
5-3. 관리자 백오피스(SCR-A*, M18·§5B-1, MDI 적용)
SCR-A1 사용자 · A2 역할·권한(RBAC) · A3 공통코드 · A4 메뉴 · A5 감사로그 · A6 시스템설정 · A7 마스터데이터(홀·요율·요금·부스표준·등록업체) · A8 규정 룰셋 버전 · A9 테넌트 온보딩(플랫폼 슈퍼관리자) · A10 AI 플랫폼 설정(AiConfig).
5-4. 공개 홍보 사이트(SCR-P*, MDI 비적용·SEO/다국어)
SCR-P1 홈 · P2 행사 상세 · P3 공개 인터랙티브 플로어플랜 · P4 관람객 사전등록 · P5 마이크로사이트 공개 뷰 · P6 참가/부스 문의 · P7 입장권 예매(티켓팅) · P8 예매 확인·취소.
5-5. 3-트랙 IA(§3C, SCR-T*)
코엑스 3-사이트 IA를 킨텍스 단일 도메인 위에 visitor / business / agency 3-트랙 얕은 진입 레이어로 정형화. 신규 라우트 4개(/=SCR-T0 관문, /visitor=T1, /business=T2, /agency=T3)만 추가하고 기존 딥라우트·MDI·티켓 공개 라우트는 불변(회귀 0).
- SCR-T0 관문(
/, 미인증): 제품 히어로 + 3-트랙 대형 분기 카드(관람 1순위) + 행사 하이라이트 레일. - SCR-T1 visitor: 세련된 마케팅 홈페이지로 격상, 중심 = 대화형 AI 관람 도우미(히어로 정중앙 자연어 입력창 + 예시 질문칩). 라이트/다크 토글(공개 예외).
- SCR-T2 business: B2B 실무 톤, 주최자(홀 임대)/참가업체(부스 신청) 2-분기 가치 제안 + 임대 절차 스텝 → 로그인 CTA.
- SCR-T3 agency: 옥션/역경매 차별점 강조, 등록업체 안내(739개사·14분류·미등록 시공 엄금) + 진행 중 공사 옥션 공고 리스트 → 등록업체 로그인 CTA.
- 공개 셸: PublicShell + 상단 3-트랙 전환 탭(TrackSwitcher), 좌측 "KINTEX AI 전시·행사시스템" 워드마크, 우측 언어(한/영/중/일)·로그인. 서브도메인 테넌트 컨텍스트 하 해당 테넌트 콘텐츠만 노출.
5-6. 역할 → 랜딩·메뉴 결정 규칙(웹·모바일 공통)
- 미인증 기본 진입 = visitor 공개 관람 랜딩(SCR-T0). 인증 후 역할 매핑 트랙의 전용 메인으로 랜딩:
- primaryTrack 우선순위: 내부-admin > 내부-ops > business > agency > visitor.
- 랜딩: ADMIN→관리 메인(SCR-16) / MANAGER·HALL_MANAGER→운영 메인 / ORGANIZER·EXHIBITOR→비즈니스 메인(SCR-T2) / CONTRACTOR→에이전시 메인(SCR-T3) / VISITOR→관람객 메인(SCR-T1).
- 좌측 메뉴 그룹(GROUPS: ops·design·visitor·finance·work·system)은 트랙 필터로 노출/숨김.
system그룹은 ADMIN만. - 모바일 하단 탭바는 역할별 4~5탭 구성.
5-7. 디자인 시스템(요약)
- 브랜드: 킨텍스 CI 블루 계열 B2B 실무 톤. AI 생성물은 항상 "AI 생성/초안" 라벨.
- 컬러 토큰(kx):
primary-600 #0066B3(주 브랜드),primary-700 #004C86,ai-accent #6D4AFF(AI 전용), success#0E8A5F·warning#B45309·error#D92D20,canvas-bg #1C2536(에디터 다크 서피스), 배선 전기#EF4444/네트워크#3B82F6/급배수#22C55E. WCAG AA 이상. - 타이포: Pretendard(숫자·좌표 tabular), Display 28 / H1 24 / Body 14, 테이블 행 44px(모바일 48).
- 컴포넌트: StatusBadge(작성중→제출→AI검토→승인→반려→시공→검수), DdayChip(D-3 warning), ViolationFlag(차단 빨강/경고 주황 + 도면 위 번호 핀 1:1), AI 라벨(보라 외곽선), 생성 이미지 상시 고지문(제거 불가). 라운드 버튼 4px/카드 8px(상한)/칩 pill. 12컬럼·컨테이너 max 1440px.
- MDI 셸: 좌측 사이드바(240px)+상단 문서 탭바+DocumentHost, ShellFooter 36px. 메뉴 클릭=탭 열기(라우트 이동 아님), 비활성 탭 상태 보존, 최대 12탭, 세션
localStorage(kintex.mdi.{role}.{eventId}). MDI 적용=관리자·주최자·참가·장치·홀매니저 / 비적용=공개(P·T)·모바일. - 캘린더: WISE(UIWS
CalendarView) 패턴 문자 그대로 — 월 6주×7열, 기간 이벤트=가로 spanning bar, "+N" 팝업, 전시장 세그먼트 필터는 홀 마스터 센터 distinct 동적 옵션(하드코딩 금지). - 반응형·다크모드: 웹 1440px(설계·에디터·대시보드)/모바일 390px(조회·승인·현장). 다크모드 Phase 1 미지원(에디터 캔버스만 다크), 공개 마케팅 T1은 예외적 토글. 전 화면 풀블리드·공백 없는 반응형(전역 NFR).
5-8. 모바일(SCR-M*, Expo/RN 390px)
조회·승인·현장 전용(캔버스 편집 미제공, 뷰어+승인 액션만). 하단 탭 4개. SCR-M1 시공업체 현장 체크리스트 · M2 홀매니저 현장 검수 · M3 역할별 홈 · M4 리드캡처(배지 스캔) · M5 관람객 홈·배지/QR · M6 wayfinding · M7 플로어플랜·부스 검색 · M8 비즈매칭 · M9 세션·아젠다 · M10 반입 통행증·안전 · M11 알림센터 · M12 서류·승인 조회 · M13 옥션 순위 · M14 티켓 예매 · M15 내 티켓 지갑.
5-9. Stitch 연동
전 화면 Stitch 경유(프로젝트 9385904003821333054, 디자인 시스템 "Precision Enterprise AI"). 생성 화면 = stitch_kintex_ai_system_architect/(각 디렉터리 code.html·screen.png). design.md가 토큰·컴포넌트 권위(상충 시 design.md 우선). 신규 정의 SCR-HOME·SCR-T0~T3는 미생성(designer Stitch 의뢰 대상).
근거: design.md v2.4 §1~§4, PLANNING §2-3.
6. AI 설계(§8A — 사용성 & 토큰 최소화)
6-1. 사용성 표준(U1~U7)
전 화면 공통 인라인 AI 진입점(AiAssistant) + 예시 질문 칩 + 원탭 액션 + 다음 명령 제시(규칙 기반 우선) + 구조화 카드 + 근거 인용(출처 레코드 링크, 근거 없으면 "모름" 폴백) + 대화 히스토리(요약 압축) + 접근성/다국어/모바일/음성. 관람객·업무 사용자가 단일 AiAssistant + 단일 /ai/ask 계약 공유, 노출 위치·칩·허용 액션만 역할/트랙으로 스코프.
6-2. 토큰 최소화 6원칙(P1~P6)
- P1 결정론 우선 라우팅: 사실 조회형(일정·교통·주차·마감일·요금·부스 위치·통계)은 DB/뷰가 직접 응답(LLM 미호출). LLM은 요약·추천·자연어 종합에만.
- P2 소형모델 우선 티어링: 온프레미스 소형(Ollama qwen3:1.7b/llama3.2:1b) → 난도·실패 시 Claude 승급(AiTextRouter).
- P3 RAG 발췌: top_k 제한·컬럼 프로젝션으로 짧은 컨텍스트만(전체 문서/테이블 주입 금지).
- P4 캐싱: 응답 캐시(의도+파라미터+tenant+locale, TTL)·프롬프트 프리픽스·기간 요약 재사용.
- P5 출력 상한·구조화: max_tokens 상한 + JSON/카드 구조화.
- P6 집계는 SQL로: 통계·랭킹·추이는 데이터마트 SQL이 산출, LLM은 설명·해석만.
6-3. 계약·측정
- 단일 계약
POST /ai/ask: 입력{question, contextRef, locale, history}, 출력{answerCard, citations[], followups[], route(direct|small|escalated), usage(tokens·cached)}. - IntentRouter는 규칙 테이블(공통코드)로 관리, 사실조회 의도는 DB 리졸버 매핑, 미매핑만 LLM 경로. 캐시 키
hash(intent+params+tenant_id+locale). - AI 프로바이더: Claude 기본(
api.anthropic.com, 키 env only) + AiTextRouter(실패 시 Ollama 폴백) + AiConfig 설정 화면(하드코딩 금지). 나노바나나(Gemini)는 별도 이미지 파이프라인(본 절 토큰 원칙 대상 아님, G1 게이트). - 측정지표(
ai_usage_log적재, tenant/모듈 비용 귀속): LLM 우회율 ≥40%·소형모델 처리율 ≥70%·캐시 적중률 ≥30%·평균 입력 ≤1500/출력 ≤400·근거 인용률 ≥95%(초기 가설).
근거: PLANNING §8A. 현행 visitor-assistant DB 근거 응답·AiTextRouter 폴백과 정합(표준화).
7. 인증·인가 설계
7-1. 현행(구현) — JWT + RBAC + 2FA
- JWT(HS256): 클레임 sub·name·roles(eventId→역할)·hm(홀매니저)·plat(플랫폼 역할)·otp. STATELESS·CSRF disable. 공개(permitAll):
GET /health·POST /api/auth/login·/ws/**·/api/internal/render/callback·(Phase D)/api/public/**. - 이중 RBAC: 플랫폼 역할(JWT
plat+hasRole) × 행사 역할(JWTroles/hm+EventAccessGuard.requireRole). 열람=행사 멤버 or 홀매니저, 편집·액션=역할별. 등록업체 게이트(불변): CONTRACTOR 응찰은 등록업체 검증 필수(미등록=NOT_REGISTERED_COMPANY 403). - 2차 인증(TOTP RFC6238): SHA1·30s·6자리·±1 윈도우. 최초 QR 등록, 마이페이지 재설정/해제, 관리자 OTP 초기화. 대상 = 업무 사용자 필수, 일반 관람객 미강제(승격 시 필수 전환).
- 로그인 실패 잠금(failed_login_count·locked_until) + 관리자 해제. admin 비밀번호 = env
ADMIN_PASSWORD_ENC(AES-256-GCM) + 별도 키파일 주입, 기동 시 BCrypt 재시드(admin123하드코딩 금지). - 민감 컬럼(
password_hash·otp_secret)은 API 응답에서 완전 제외.
7-2. 계정 체계(단일 통합 + 가입 트랙 분리)
- 계정/RBAC는 단일 통합, 가입 트랙만 분리: 업무 트랙(B2B, 승인/초대+2FA 필수) vs 관람객 트랙(B2C, 간편가입/게스트 예매·2FA 미강제). 관람객→바이어/참가 승격은 단일 계정 등급 상향(리드·비즈매칭·재방문 이력 연속성 유지).
7-3. Open SSO / HR 연동 (계획 — 설계 완료·미구현)
- 프로토콜: OIDC(Authorization Code + PKCE) 우선 + SAML 2.0 옵션. IdP = Keycloak 자체 호스팅(온프레미스, 내부망 IdP — 외부 API 금지 비해당).
- 기존 JWT+2FA와 공존(교체 아님): SSO는 로그인 게이트웨이만 교체, 성공 후 백엔드가 기존
JwtService.issue()로 동일 형태 앱 JWT를 브로커 발급 → 전 화면·RBAC·행사 스코프 불변./api/auth/oidc/callback만 신설, 로컬 로그인 폴백 유지(IdP 장애 대비). - 2FA: IdP realm이 OTP 제공 시 위임(이중 2FA 방지), 미구성·로컬 폴백은 기존 TotpService 유지.
- HR 연동: 어댑터
HrDirectoryClient(+Mock)로 외부 HR API를 정본 조달 + 로컬 읽기 캐시 스냅샷(미가용 시 degraded). PII 최소(주민번호·연락처·급여 미수집), 삭제는 소프트. 전역 역할·hall_manager는 IdP 그룹/클레임 매핑, 행사 역할(event_member)은 로컬 권위 유지. - 3자 매핑: SSO subject(
sub) ↔ HR 사번(empNo) ↔ 로컬app_user.id(연결 테이블user_identity). 이메일 단독 매칭 금지, 충돌 시 자동 병합 금지·관리자 수동 링크. JIT 프로비저닝(첫 SSO 로그인 시 password_hash 없이 생성). - 이행: 피처플래그(
sso.enabled) 4단계(준비→coexist→pilot→cutover→정착), 각 단계 롤백 게이트. 신설 모델(user_identity·hr_dept_snapshot·hr_emp_snapshot·hr_sync_log·dept.source)은 DA/backend 인계 백로그(미구현).
근거: architecture/sso-hr-integration.md, PLANNING §5B-3, 실제 스키마.
8. 네트워크·보안영역 설계
8-1. 존 모델(4계층 + 관리 존)
| 존 | 구성 | 인바운드 | 아웃바운드 |
|---|---|---|---|
| 엣지(무신뢰) | CDN·WAF/DDoS | 인터넷 80/443 | DMZ LB |
| DMZ(공개) | 공개 LB(TLS 종단)·public SSR·visitor 게이트웨이·공개 API GW·PG 콜백 | 엣지에서만 | 내부망 API GW(제한), 데이터 존 직결 금지 |
| 내부망(인증·운영) | 내부 LB·SSO 게이트·내부 API GW·공유 백엔드 | DMZ(허용 API)·관리 존(IP/VPN) | 데이터 존·AI 워커·승인 아웃바운드 |
| AI 워커 존 | Redis 큐·나노바나나 워커·Ollama | 내부망(큐 소비만) | 데이터 존(OBJ), Gemini egress 단일 경로만 |
| 데이터 존(최내곽) | PostgreSQL+PostGIS·오브젝트 스토리지·BI 읽기 복제 | 내부망·AI 워커(서비스 계정만) | 없음(전면 차단) |
| 관리 존 | 배스천·관측성·백업 | 운영자 VPN/허용 IP | 대상 존 SSH·수집 |
- 핵심 규칙: DMZ → 데이터 존 직접 접근 절대 금지(내부망 백엔드 API 경유). 데이터 존 아웃바운드 없음.
8-2. 공개 vs 내부 백오피스 분리
- DMZ: 공개 홍보 사이트(
www./expo., SSR·CDN·SEO·다국어·비인증·쓰기 없음), 관람객 앱(visitor.·쓰기 제한). - 내부망(인증):
organizer.·exhibitor.·contractor.(등록업체 검증). 내부망(운영):ops.(IP/VPN 제한). 관리:admin.(M18) = VPN/허용 IP allowlist + 2FA 강제 + 감사로그 전량 + 웹 전용. - 공개(DMZ) 3원칙: 쓰기 없음 · 데이터 존 직결 불가 · 캐시/CDN 적극.
8-3. 방화벽·LB·TLS·아웃바운드
- 기본 정책 = DROP(default-deny). DB 포트(5432)·Redis·OBJ 인터넷 미노출. DMZ↔내부망은 HTTPS/API만.
- WAF: OWASP Top10, 업로드 확장자·MIME·크기 이중 검증, PG 콜백 IP allowlist+서명 검증, admin·옥션 레이트리밋 강화.
- LB: 공개 LB(DMZ) / 내부 LB(백엔드, 무상태 JWT 라운드로빈+헬스체크) / WebSocket 스티키. TLS는 LB 종단(HSTS·TLS1.2+), 존 간 mTLS 옵션.
- 아웃바운드 게이트(승인 4목적지):
api.anthropic.com(승인, 실패 시 Ollama 폴백)·generativelanguage.googleapis.com(G1 미승인, 워커에서만)·PG 결제·SMTP. 그 외 전량 차단. 키 격리=네트워크 격리(Gemini 키=워커 존, Claude/PG 키=백엔드, 데이터 존 무아웃바운드).
8-4. 보안 불변(위반 = QA 반려)
① 스택트레이스 미노출(요약만) ② 민감정보(자격증명·PII) 응답 완전 제외 ③ GEMINI_API_KEY 백엔드 미취급(M5는 큐 발행까지만) ④ AI 이미지 항상 워터마크·고지 강제 ⑤ admin 비번 env 주입 ⑥ 크로스-테넌트 접근은 플랫폼 슈퍼관리자 전용 API(감사).
근거: architecture/network.md·app.md, CLAUDE.md 보안 제약.
9. 비기능 요구사항(NFR)
9-1. 성능·용량
- 플로어플랜 3안 생성 수 분 내, 배치·배선 상호작용 P95 < 2s, 부스 목록 P95 < 500ms, 이미지 단건 평균 ~40s(비동기·SLA 대상 아님), 공개 캐시 히트 P95 < 200ms, 옥션 순위 갱신 < 1s.
- 대형 행사 3,000~5,000부스(홀당 200~600). Hikari max =
${DB_POOL_MAX:3}+ PgBouncer 권고(공유 PG 포화 방지).
9-2. 가용성
- 코어 인증·설계·조회 경로 HA SLO 99.5%(성수기 99.9% 지향). 백엔드 무상태 수평 확장(세션·순위·타이머·쿼터·캐시 Redis 외부화), Redis HA(Sentinel/Cluster+AOF), PG 프라이머리+읽기 복제(BI·공개조회 오프로드).
9-3. 기술 표준(핀 버전)
- 백엔드: Java 17 · Spring Boot 3.2.5 · Gradle · MyBatis 3.0.3(JPA 금지,
@MapperScan(annotationClass=Mapper.class)) · jjwt 0.12.5 · UTF-8 강제. - 프론트: React 18.3.1 · Vite 5.4.8 · TypeScript 5.6.2(strict) · react-router-dom 6 · @tanstack/react-query 5 · zustand 4(Redux 금지). 빌드
tsc -b && vite build(타입 에러=빌드 실패). - 워커: Python 3.11+ · google-genai ·
gemini-3.1-flash-image-preview. 실 호출은NANOBANANA_LIVE=1+GEMINI_API_KEY동시 충족 시만(기본 목/degraded). - 데이터: PostgreSQL+PostGIS(
kintex_db)·Redis·오브젝트 스토리지·Flyway. - 관측성: Actuator+Micrometer 권고(
/actuator/health배포 게이트·/metrics). 로그 보안 불변(자격증명·IP·PII·스택트레이스 금지,include-stacktrace:never).
9-4. 접근성·국제화
- WCAG AA 이상, 차트 색 외 패턴/라벨 병기, KPI·표 aria-label, 키보드 포커스 링
primary-6002px, 전 아이콘 선(stroke) SVG(이모지 금지), i18n 키 분리(한/영/중/일 로케일 숫자/통화/날짜 포맷),prefers-reduced-motion준수.
근거: architecture/system.md·tech.md, design.md 전역 NFR.
후속 산출 명시: 본 설계서와 개발계획서(
01_개발계획서.md)는 개발 착수 시점 산출물이다. 사용자지침서·운영자지침서는 UI 정렬 안정화 이후 별도 산출한다(deliverables 갱신 정책상 완성+QA 통과 후 최신 메뉴를 반영해야 하므로 이번 범위에서 제외).