harness/plugins/zioinfo/knowledge/kintex/docs/architecture/app.md
DESKTOP-TKLFCPR\ython 6caf43e1ed feat!: v2.0.0 — 4개 플러그인 zioinfo 단일 통합 + 최신 플러그인 기술 적용
- 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>
2026-07-21 20:16:36 +09:00

28 KiB

킨텍스 자동전시시스템 — 애플리케이션 아키텍처 표준 (app.md)

작성: 애플리케이션 아키텍트(AA) · 작성일: 2026-07-11 · 버전: v1.0 · BACKLOG A-1 근거: docs/PLANNING.md v2.0(§2 6역할 포털·§4 모듈맵·§5 M1~M9·§5A M10~M18·§5B 공통레이어·§8 아키텍처)·docs/IMPLEMENTATION_BACKLOG.md(Phase A~E)·_workspace/01_backend_contracts.md(P0 계약)·src/backend 스캐폴드 실측. 스택(확정·불변): React 18/19(Vite·TypeScript) + Spring Boot 3.x(Java 17) + MyBatis + PostgreSQL(PostGIS) + Redis + 나노바나나 Python 워커 사이드카.

문서 소유권: 본 문서는 AA만 수정한다. 구현 에이전트(BE/FE/DB/COM/도메인 devs)는 이 표준을 준수하며, 위반 발견 시 kintex-qa와 함께 시정한다. 교차 문서(system.md·tech.md·data.md·network.md)와의 정합은 링크로 참조하고 직접 수정하지 않는다.


0. 목적과 적용 범위

본 문서는 킨텍스 자동전시시스템의 애플리케이션 구조 일관성을 규정하는 단일 표준이다. 개별 기능 구현 방식이 아니라 모듈 경계·레이어링·패키지·API 규격·공통 컴포넌트·의존성 규칙을 정의한다.

  • 적용 대상: src/backend(Spring Boot) 전 모듈, src/frontend(React) 전 포털, 나노바나나 워커와의 큐 계약, kintex-common(WISE/UIWS 이식) 공통 레이어.
  • 정합 기준: PLANNING §8/§8-1 아키텍처 개요와 정합하며 이를 구체화한다. 상충 시 PLANNING이 상위, 본 문서가 구현 표준.
  • 현행 스캐폴드 정합: 본 표준은 이미 스캐폴드된 실제 구조(§1.2)를 성문화한 것이며, 신규 모듈은 이 패턴을 복제한다. 기존 코드 변경을 요구하지 않는다(성문화·확장).

1. 패키지 구조 표준

1-1. 루트 패키지

전 백엔드 코드는 com.zioinfo.kintex 하위에 둔다(GUARDiA 표준 프레임워크 정렬, WISE=com.zioinfo.* 관례). 최상위는 횡단 관심사(cross-cutting)도메인 모듈(module) 로 나뉜다.

com.zioinfo.kintex
├── KintexApplication                # 부트 진입점
├── common                           # 횡단: 응답봉투·페이징·에러·감사·유틸 (모듈 무의존)
│   ├── ApiResponse / PageResponse
│   ├── error/  (ErrorCode·ApiException·GlobalExceptionHandler)
│   ├── audit/  (감사 AOP·@Audited — Phase B B-2/B-4)
│   └── code/   (공통코드 조회 캐시 — Phase B)
├── config                           # 부트 설정: SecurityConfig·WebSocketConfig·RedisConfig·MyBatisConfig
├── auth                             # 인증/인가: JWT·RBAC·2FA(OTP)·principal·guard (도메인 무관 공용)
│   ├── dto/  ·  mapper/
├── rules                            # 룰 엔진: 규정(compliance)·요율(rate) 룰셋 로딩·평가 (서비스 계층)
├── health                           # 헬스체크
└── module                           # ★도메인 모듈 루트 — 모듈별 서브패키지
    ├── m1  … m9                      # 판매·운영(배정·서류·매칭·정산·물류)
    ├── m2 · m3 · m4 · m5             # ★P0 부스 시공 코어
    ├── m10 · m11 · m12 · m13 · m14   # 관람·참가·마케팅·wayfinding·현장운영
    └── m15 · m16 · m17 · m18         # 옥션·BI·CMS·관리자

1-2. 모듈 내부 구조 (표준 레이아웃 — 스캐폴드 실측)

각 도메인 모듈 module.mN은 아래 4계층을 고정 서브패키지로 둔다. M2가 정본 참조 패턴이다.

module.mN
├── MNController              # REST 진입 — 얇게 유지(가드·바인딩·위임만)
├── MNService                 # 서비스 인터페이스(계약)
├── MNServiceImpl             # 서비스 구현(비즈니스 로직·트랜잭션 경계)
├── dto/                      # 요청/응답 DTO — record 우선(불변)
│   └── *Dto / *Request / *Response
├── mapper/                   # MyBatis 매퍼 인터페이스(@Mapper)
│   └── MNMapper (XML은 resources/mybatis/mapper/)
├── MNProperties (선택)       # @ConfigurationProperties 모듈 설정
└── domain/ (선택)            # 순수 도메인 모델·값객체(엔티티 매핑 시)

명명 규칙: 서비스는 인터페이스(FloorplanService) + 구현(FloorplanServiceImpl) 분리(스캐폴드 실측). 컨트롤러는 <도메인명>Controller. DTO는 record 우선(불변·직렬화 안정). 모듈 접두어 mN은 패키지에만 쓰고 클래스명은 도메인 어휘(Floorplan·Design·Utility·RenderJob·Auction·Visitor…)를 쓴다.

1-3. 리소스 레이아웃

src/backend/src/main/resources
├── application.yml                          # 시크릿·엔드포인트는 env 플레이스홀더만(하드코딩 금지)
├── mybatis/mapper/**/*.xml                  # 공간 SQL(ST_*) 포함 매퍼 XML — mapper-locations로 로드
└── rulesets/                                # 버전 관리 룰셋 데이터(코드 아님)
    ├── compliance-v1.json (compliance-v1.0)
    └── rates-v1.json (rates-v1.0)

2. 레이어링 표준 (controller / service / mapper / domain / dto)

2-1. 레이어 책임 경계

레이어 책임 금지
Controller HTTP 바인딩, 입력 검증(@Valid), RBAC 가드 호출, 서비스 위임, ApiResponse 래핑 비즈니스 로직·SQL·트랜잭션·매퍼 직접 호출
Service (interface+Impl) 비즈니스 규칙, 트랜잭션 경계(@Transactional), 룰 엔진 호출, 매퍼 오케스트레이션, 도메인 예외 발생 HTTP 타입(HttpServletRequest 등) 참조, 매퍼 XML 로직 침범
Mapper (MyBatis) DB 접근, 공간 SQL(ST_*) 바인딩. 인터페이스+XML 쌍 비즈니스 분기, DTO 조립(원시 Map/도메인 반환까지)
DTO 계층·경계 데이터 전달(record 불변) 로직·영속 어노테이션
domain / 값객체(선택) 순수 도메인 모델·계산(엔티티 매핑 시) 프레임워크 의존

2-2. 계층 관통 흐름 (표준)

Controller ──(가드: EventAccessGuard)──► Service(interface)
                                            └► ServiceImpl ──► Mapper(@Mapper) ──► PostgreSQL/PostGIS
                                                          └──► RuleEngine(rules)       (공간 SQL은 XML)
                                                          └──► RedisTemplate(비동기 큐/실시간)
                                            결과 DTO ◄── ServiceImpl ◄── Mapper(Map/도메인)
Controller ──► ApiResponse.ok(dto)   |   예외 ──► GlobalExceptionHandler ──► ApiResponse.fail
  • 컨트롤러는 가드 호출 → 서비스 위임 → 봉투 래핑만 한다(FloorplanController가 정본). 로직이 컨트롤러에 새면 위반.
  • 서비스는 매퍼가 반환한 원시(Map<String,Object>/도메인)를 DTO로 조립한다. 매퍼는 DTO 조립을 하지 않는다.
  • 공간 연산(부스 폴리곤·트렌치 KNN·배선 LineString·면적)은 서비스가 아니라 매퍼 XML의 PostGIS SQL로 수행하고 서비스는 스칼라/GeoJSON 결과만 사용한다(스캐폴드 BoothMapper·WiringMapper 계약).

2-3. 트랜잭션·읽기 정책

  • 쓰기 서비스 메서드는 @Transactional, 조회는 @Transactional(readOnly=true).
  • 낙관적 잠금: 배치·설계 등 버전 있는 리소스는 version 불일치 시 CONFLICT(409). (LayoutSaveRequest·DesignSaveRequest에 version 존재.)
  • BI(M16): 운영 DB 직조회 금지 — KpiSnapshot/데이터마트(스타 스키마) 또는 읽기 전용 경로로 격리(PLANNING §8-1·M16-1, 상세는 data.md DA 트랙).

3. 모듈 경계와 분류

3-1. 모듈 3계열 + 공통 레이어

계열 모듈 패키지 우선순위 비고
공통 레이어(선행 기반) 인증·시스템관리·공통업무기능 auth·common·module.m18(system)·공통 모듈 P1(전 모듈 선행) §5B WISE/UIWS 이식
P0 부스 시공 코어(불변·심장) M2 플로어플랜·M3 부스설계·M4 유틸리티·M5 나노바나나 module.m2~m5 P0 스캐폴드 완비
판매·운영 M1 배정견적·M6 서류·M7 매칭·M9 정산·M8 물류 module.m1·m6·m7·m9·m8 P1/P2
발주·계약 M15 공사/장치 옥션 module.m15 P1(핵심 플로우) 폐루프 연결고리
관람·참가·마케팅 M10 관람객·M11 매칭·M12 마케팅/공개사이트·M13 wayfinding·M14 현장운영 module.m10~m14 P1/P2
경영·콘텐츠·관리 M16 BI·M17 CMS·M18 관리자 module.m16·m17·m18 P1

3-2. 공간 데이터 공유 원칙 (불변)

M2(부스 폴리곤)→M3(부스 내부)→M4(배선)→M5(시각화)는 하나의 PostGIS 공간 데이터 모델을 공유한다. M13 wayfinding·M14 부하집계·M16 ㎡당 수익은 동일 원천(Booth 폴리곤·Wiring LineString)을 재사용한다. → 공간 지오메트리 소유는 M2/M4 매퍼가 권위이며, 소비 모듈은 조회만 한다(중복 저장 금지).

3-3. 권위(ownership) 경계 — 중복 제거 (PLANNING §5B-2 규칙)

관심사 권위 모듈 소비 모듈(읽기/이벤트)
경영·수익 지표 M16 BI 대시보드·포털
일상 업무보고·통계 공통 report/stats
콘텐츠·공지 발행 M17 CMS 공개사이트·사이니지
사내 알림성 공지 공통 notice
알림 발송 채널 공통 notification(단일화) M10·M12·M15(이벤트 발행)
사용자·역할·공통코드·감사·마스터데이터 M18(=system) 전 모듈(RBAC·룰셋 공급)
규정·요율 룰셋 rules + M18(버전 관리) M1·M2·M3·M4

4. 의존성 규칙 (참조 방향·순환 금지)

4-1. 허용 참조 방향 (단방향)

module.mN  ──►  rules · auth · common          (횡단 계층 참조 허용)
module.mN  ──►  module.mK   (오직 §4-2 표에 명시된 방향만, 하위→상위 데이터 소비)
common     ──►  (무의존)     ★common은 어떤 module·auth·rules도 참조하지 않는다
auth       ──►  common       (에러·봉투만)
rules      ──►  common
config     ──►  auth · common (보안/웹소켓/레디스 배선)

철칙: common은 순수 횡단 유틸(봉투·에러·감사·페이징)로 어떤 도메인/인증/룰도 모른다. 도메인 모듈이 common을 참조하지, 그 역은 없다.

4-2. 모듈 간 참조(도메인) — 명시 방향만 허용

PLANNING §4 모듈맵의 데이터 흐름을 코드 의존으로 옮긴다. 화살표 방향으로만 참조(소비자→생산자 조회, 순환 금지).

소비 모듈 참조(생산) 모듈 목적
M3 → M2 부스 좌표·행사 역참조
M4 → M2 트렌치·부스 지오메트리
M5 → M2·M3·M4 씬 컴파일 입력(scene)
M15 → M2·M3·M4·M5·M7 옥션 자료 패키지·등록업체 검증
M9 → M1·M4·M15 정산 대상(배정·유틸·낙찰)
M13 → M2 wayfinding 지오메트리
M14 → M4·M10 부하·체크인 파생
M16 → 전 모듈 지표 소비(읽기 전용/스냅샷)
M12 → M10·M17 세그먼트·콘텐츠
  • 순환 금지: 위 표에 역방향이 필요하면 직접 참조 대신 이벤트(알림 큐)·공유 식별자로 디커플. 예: M15 낙찰→M9는 M15가 M9를 호출하는 것이 아니라 도메인 이벤트/발주 링크로 전달(순환 회피).
  • 모듈 간 결합은 서비스 인터페이스로만: mK.MKService를 주입해 쓰고, 상대 모듈의 mapper·ServiceImpl·dto 내부를 직접 참조하지 않는다(계약 경유).
  • 공간 원천은 M2/M4 매퍼가 권위(§3-2) — 타 모듈은 그 서비스로 조회.
  • 검증: 빌드 타임 아키텍처 테스트(ArchUnit 권장, tech.md TA 트랙)로 common→module 역참조·모듈 순환을 CI에서 차단.

5. REST API 설계 표준

5-1. 경로·버전

  • 베이스: /api. 공개(비인증) 홍보/워커 경로는 /api/public/**·/api/internal/** 접두어로 분리.
  • 행사 스코프 리소스: /api/events/{eventId}/… 하위에 배치(모든 도메인 리소스는 {eventId} 스코프). 중첩 예:
    • M2 …/events/{eventId}/halls/{hallId}/layout
    • M3 …/events/{eventId}/booths/{boothId}/design
    • M4 …/events/{eventId}/booths/{boothId}/utility
    • M5 …/events/{eventId}/booths/{boothId}/render · …/events/{eventId}/render-jobs/{jobId}
  • 플랫폼(비행사) 리소스: /api/admin/**(M18·백오피스, hasRole(ADMIN) 게이트), /api/auth/**(인증), /api/me/**(개인).
  • 버전 정책: P0/P1은 무접두 /api(단일 버전). 파괴적 변경 시에만 /api/v2/… 도입. 계약 진화는 후방호환 우선(필드 추가는 non-breaking, 제거·의미변경만 버전 상향). 룰셋·계약 semver는 페이로드의 rulesetVersion으로 별도 표기(코드 API 버전과 분리).
  • 동사 규약: 자원 CRUD는 표준 HTTP 메서드. 비 CRUD 액션은 하위 동사 세그먼트(/validate·/auto-generate·/precheck·/quote·/wiring·/order·/render)로 표현(스캐폴드 실측 패턴). 액션은 POST.

5-2. 응답 봉투 (ApiResponse — 스캐폴드 정본)

모든 REST 응답은 common.ApiResponse<T>를 사용한다(예외 없음).

{ "success": true,  "data": { ... }, "error": null }
{ "success": false, "data": null,    "error": { "code": "FORBIDDEN", "message": "요약 메시지" } }
  • 성공은 컨트롤러가 ApiResponse.ok(dto). 실패는 던지고(ApiException) GlobalExceptionHandler가 봉투로 변환(컨트롤러에서 실패 봉투 수동 조립 금지).
  • 목록: common.PageResponse<T> = { items, page, size, total }. (P0 갤러리/워크스페이스처럼 소량 고정 목록은 배열 직접 반환 허용 — 계약 §0-1.)

5-3. 오류 코드 → HTTP (ErrorCode enum — 안정 계약)

common.error.ErrorCode가 코드↔HTTP 단일 매핑. 신규 코드는 여기에만 추가한다.

code 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 서버 오류(요약만)
  • 미구현 지점ApiException.notImplemented(...)(501) 표준 사용 — 계약은 확정하되 매퍼/워커 대기 구간 표시(스캐폴드 관례).
  • 도메인 확장 코드(옥션 마감·배지 만료 등)는 계열 접두 없이 ErrorCode에 추가하고 본 표에 반영(AA 승인).

5-4. 페이징·정렬·필터

  • 쿼리 파라미터: page(0-base)·size(기본 20, 상한 100)·sort=field,asc|desc. 응답은 PageResponse<T>.
  • 필터는 명시 쿼리 파라미터(자유 텍스트 SQL 금지). 통합검색(공통 search)은 별도 검색 서비스 경유.

5-5. 인증 헤더·공개 경로

  • Authorization: Bearer <JWT>(HS256). 클레임: sub(userId)·name·roles(eventId→역할)·hm(홀매니저)·(Phase B 확장) plat(플랫폼 역할 ADMIN 등)·otp(2FA 통과 플래그).
  • 무상태(SessionCreationPolicy.STATELESS). CSRF disable, CORS는 config에서 관리.
  • 공개(permitAll): GET /health, POST /api/auth/login, /ws/**, POST /api/internal/render/callback(워커 토큰), (Phase D) /api/public/**(공개 홍보사이트 조회). 그 외 전부 인증.
  • 내부 워커 콜백은 X-Worker-Token(env) 검증. 공개사이트는 읽기 전용(행사 데이터 쓰기 불가).

5-6. 보안 불변 (API 계약 강제 — 위반 시 QA 반려)

  1. 스택트레이스·내부 세부 미노출error.message는 사람이 읽을 요약만, 상세는 서버 로그. (server.error.include-*: never + GlobalExceptionHandler.)
  2. 민감정보 응답 완전 제외 — IP·SSH·비밀번호·os_pw_enc·해시·내부 식별자. 사용자/업체는 이름·역할·번호 등 비민감 필드만.
  3. GEMINI_API_KEY는 백엔드가 다루지 않는다 — 나노바나나 Python 워커 전용. M5는 큐 발행까지만.
  4. AI 생성 이미지 응답은 항상 watermarkRequired:true+watermarkText+notice(계약·심사 서류 사용 금지) 포함(제거 불가, PLANNING §6-5).
  5. admin 비번은 env ADMIN_PASSWORD_ENC(AES-256-GCM)+별도 키파일 주입, admin123 하드코딩 금지(§5B-3).

6. 인증·인가 아키텍처 (이중 RBAC)

PLANNING §2 6역할·§8-1 SSO 이중 권한을 코드 모델로 표준화한다. 인증 스택은 WISE/UIWS 표준 이식(JWT+2FA/OTP), 그 위에 킨텍스 행사 RBAC를 얹는다(재설계 금지).

6-1. 이중 권한 평가

계층 대상 저장/평가 게이트
플랫폼 역할(platform) ADMIN(백오피스), 셀프서비스(VISITOR/PUBLIC) JWT plat 클레임 + Spring hasRole /api/admin/**=hasRole(ADMIN)(§5B-1)
행사 역할(event) ORGANIZER·EXHIBITOR·CONTRACTOR·HALL_MANAGER JWT roles(eventId→역할)·hm, KintexPrincipal.roleFor(eventId) EventAccessGuard.requireRole(...)
  • 현행 스캐폴드(P0): EventRole(4역할) + KintexPrincipal.hallManager 플래그 + EventAccessGuard(require/requireEventAccess/requireRole). 이 4역할 게이트가 정본.
  • Phase B 확장: 플랫폼 역할(ADMIN)·관람객 셀프서비스 계정·2FA(OTP)·로그인 실패 잠금을 auth에 추가(WISE TotpService 이식). EventRole은 유지, 플랫폼 역할은 별도 축으로 평가(직교).

6-2. 가드 사용 규약 (컨트롤러 표준)

guard.requireEventAccess(principal, eventId);                        // 열람: 멤버 or 홀매니저
guard.requireRole(principal, eventId, EventRole.ORGANIZER);          // 편집/액션: 역할 한정
guard.requireRole(principal, eventId, EventRole.ORGANIZER, HALL_MANAGER); // 복수 허용
  • 열람=행사 멤버 or 홀매니저 / 편집·액션=역할별(계약 §0-5). 홀매니저는 전 행사 열람+승인(hasAccess가 항상 true).
  • 등록업체 게이트(불변): CONTRACTOR 초대 수락·M15 응찰은 companyRegistrationNo 킨텍스 등록업체 검증 필수 → 미등록 NOT_REGISTERED_COMPANY(403). M7이 검증 권위.
  • 가드는 컨트롤러에서 호출한다(서비스 진입 전). 서비스는 이미 인가된 것으로 가정하되, 크로스-모듈 호출 시 재검증이 필요하면 호출 측이 책임.

6-3. 개인정보·감사

  • 리드캡처(M10)·관람객 데이터는 개인정보 — 동의·보존정책 필수(PLANNING R10). 접근은 소유 참가업체+주최자+홀매니저로 한정.
  • 감사 대상(§5B-1): 승인·낙찰(M15)·설계 변경·룰셋 개정·리드 접근을 common.audit AOP로 전수 기록(§7-3).

7. 공통 컴포넌트 표준 (kintex-common / WISE 정합)

공통 레이어는 workspace/uiws(WISE=GUARDiA 표준 프레임워크) 이식을 원칙으로 하되, 아래 컴포넌트는 kintex 스캐폴드가 이미 정의한 계약을 정본으로 삼는다(재설계 금지, 이식 시 정합).

7-1. 응답 봉투·페이징

  • common.ApiResponse<T>(record: success·data·error{code,message})·common.PageResponse<T>. §5-2 정본. 모든 응답 필수.

7-2. 예외 체계

  • common.error.ErrorCode(enum, HTTP 매핑) → ApiException(코드+요약 메시지) → @RestControllerAdvice GlobalExceptionHandler(봉투 변환·로그 격리). 3자 세트가 표준(§5-3). 신규 예외는 ApiException+ErrorCode만 사용(RuntimeException 남발 금지 — 최종 방어선만 INTERNAL).

7-3. 감사 AOP (Phase B B-2/B-4)

  • common.audit.@Audited 어노테이션 + AOP 어드바이스로 상태 변경 API를 TB_AUDIT_LOG에 기록(액터·행사·대상·before/after 요약·룰셋 버전). 민감정보·비번·스택트레이스 미기록(§5-6 정합). WISE TB_AUDIT_LOG 스키마 이식.

7-4. 공통코드 (Phase B)

  • common.code가 코드 그룹/상세를 캐시 제공(홀·부스유형·공종 14분류·유틸리티 요금코드 등 도메인 코드 포함). 권위는 M18(system). 도메인 모듈은 하드코딩 대신 공통코드 조회.

7-5. 룰셋(버전 관리 데이터)

  • rulesrulesets/*.json(compliance·rate)을 로드·평가. 코드가 아닌 데이터 — 개정 시 파일 교체·rulesetVersion 리포트 기록(감사·면책, PLANNING R2). 연산자: lte·gte·between·isTrue·eq·lteHall·excludesAll.

7-6. 알림 단일화 (§5B-2)

  • 발송 채널은 공통 notification 단일. 도메인 모듈(M10·M12·M15)은 직접 발송하지 않고 이벤트를 발행한다(마감 리마인더·낙찰·승인·결제 알림). WebSocket 실시간 경로는 §8.

7-7. 프론트 공통(FE, Phase B B-4)

  • 2FA 화면·공통코드·검색바·그리드·달력·모달·파일업로드는 공유 컴포넌트 라이브러리로(WISE 이식, design.md 토큰 정합). 역할별 포털이 상속(중복 구현 금지).

8. WebSocket 이벤트 규격 (STOMP)

config.WebSocketConfig 정본. 실시간 진행/이벤트 푸시는 STOMP over WebSocket으로만 한다(REST 폴링 지양).

  • 핸드셰이크: GET /ws(SockJS). 공개 경로(핸드셰이크 후 STOMP CONNECT 헤더에 JWT 전달 — 인가는 구독 시점 평가).
  • prefix: 서버→클라 브로드캐스트 /topic, 클라→서버 /app.
  • 토픽 네이밍 표준: /topic/<도메인>/<식별자>.
토픽 이벤트 발행 시점 대상
/topic/render/{jobId} RenderJobDto(DONE/FAILED) 워커 콜백 relay(M5) 발행 멤버
/topic/auction/{auctionId} 순위/라운드 마감(M15) 응찰·타이머 옥션 참여 업체
/topic/events/{eventId}/notifications 알림(승인·마감·결제) 공통 notification 행사 멤버
/topic/events/{eventId}/checkin 입장/혼잡(M10·M14) 체크인 홀매니저/주최자
  • 페이로드는 REST DTO 재사용(RenderJobDto 등) — 별도 WS 전용 스키마 금지(계약 일원화).
  • 인가: 구독 대상이 행사/부스 스코프면 CONNECT 시 신원 + 구독 시 접근 검증(민감 토픽 무단 구독 차단). 브로드캐스트에도 §5-6 민감정보 제외 동일 적용.
  • 나노바나나·서류·알림은 동일 비동기 패턴: REST가 Redis 큐 발행 → 워커/서비스 처리 → WS 완료 푸시.

9. 비동기·큐 계약 (Redis · Python 워커)

  • RenderJob 큐: kintex:renderjob:queue(env RENDER_QUEUE_KEY). 백엔드가 scene 페이로드(§6-2 PLANNING) leftPush → Python 워커 소비. 상태 kintex:renderjob:job:{jobId}, 쿼터 kintex:renderjob:quota:{eventId}(스캐폴드 실측 키).
  • 성공 시에만 쿼터 차감(PLANNING §6-5). 실패 에러는 safeError로 요약만 통과(스택트레이스 유입 차단).
  • 워커 결합은 얇은 큐 계약으로만 — 백엔드는 큐잉·상태·콜백·WS relay만, 나노바나나 실호출·방어 로직은 워커(§6-4 PLANNING). GEMINI_API_KEY 백엔드 미접촉.
  • 옥션 실시간 순위·라운드 마감 타이머, 서류/알림 생성도 Redis 재사용(동일 패턴). BI 집계는 배치/스냅샷(§2-3).
  • G1 게이트: Gemini 외부 호출 미승인 시에도 큐잉/상태는 동작(목/degraded). 실호출·배포는 소유자 승인 후.

10. 역할별 프론트/백엔드 모듈화 원칙

10-1. 프론트 — 역할별 번들 분리 (PLANNING §2-1·§8-1)

6개 프론트를 역할별 번들·도메인/서브패스 분리로 배포해 최소권한·공격면 축소. 공유 디자인 시스템·공유 컴포넌트·공유 API 계약을 상속(중복 구현 금지).

프론트 도메인(예) 주 사용 모듈 채널
주최자 콘솔 organizer. M1·M2·M6·M15·M16·M12 데스크톱 주력
참가업체 포털 exhibitor. M3·M4·M5·M10·M11·M15·M9 데스크톱+모바일(리드캡처)
업체 포털 contractor. M3·M4·M15·M8·M7 데스크톱+모바일(현장)
운영 대시보드 ops. M2·M6·M8·M14·M16 데스크톱+모바일(검수)
관리자 백오피스 admin. M18 웹 전용
공개/관람객 www·expo. M12·M10·M11·M13·M17 공개 SEO/SSR + 관람객 모바일
  • 공유 계층(모노레포 워크스페이스 권장): packages/api-client(계약 타입·fetch 래퍼·ApiResponse 언랩), packages/ui(공유 컴포넌트·디자인 토큰 tokens.css), packages/auth(JWT·2FA·라우팅 가드). 각 포털 앱은 이를 의존(역참조 금지).
  • 기술 표준(스캐폴드): React 18 + Vite + TS, react-router-dom·@tanstack/react-query(서버 상태)·zustand(클라 상태)·@stomp/stompjs+sockjs-client(WS). 상세 빌드·라우팅은 tech.md(TA).
  • 공개 홍보사이트(M12/M17): SEO/SSR·다국어(한/영/중/일)·CDN — 인증 앱과 별도 렌더 경로(공개 성능·검색 노출). 쓰기 불가.

10-2. 백엔드 — 단일 공유 모놀리식(모듈러) (PLANNING §8-1)

  • 공유 Spring Boot 백엔드 1개(모든 포털이 SSO+RBAC로 접근). 역할별로 백엔드를 쪼개지 않는다 — 모듈러 모놀리스(module.mN 경계 + §4 의존 규칙)로 경계를 코드 레벨에서 강제.
  • API 노출은 경로 접두(/api/events/**·/api/admin/**·/api/public/**)와 RBAC로 역할별 표면을 나눈다(별도 서비스 아님).
  • 장래 서비스 분리가 필요하면 §4 모듈 경계가 분할선(느슨한 결합·이벤트 디커플이 선행 조건).

11. 신규 모듈 추가 체크리스트 (구현 에이전트용)

새 도메인 모듈(mN) 추가 시 본 표준 준수 확인:

  1. 패키지 com.zioinfo.kintex.module.mN + 4계층(Controller·Service/Impl·dto·mapper) 생성(§1-2).
  2. 컨트롤러는 가드→위임→ApiResponse 래핑만(§2-2, FloorplanController 패턴 복제).
  3. 경로 /api/events/{eventId}/…(행사 스코프) 또는 /api/admin/**(플랫폼)(§5-1).
  4. DTO는 record, 목록은 PageResponse, 오류는 ApiException+ErrorCode(§5-2/5-3).
  5. 공간 데이터는 M2/M4 매퍼 권위 재사용(§3-2), 신규 지오메트리만 자기 매퍼 XML(PostGIS).
  6. 크로스 모듈은 상대 Service 인터페이스로만, §4-2 방향 준수·순환 금지(이벤트 디커플).
  7. 실시간은 /topic/<도메인>/<id> STOMP, 비동기는 Redis 큐(§8/§9).
  8. 감사 대상 액션에 @Audited(§7-3), 알림은 notification 이벤트 발행(§7-6).
  9. 보안 불변 5종(§5-6) 자체 점검 → QA 반려 방지.
  10. 미완 구간은 ApiException.notImplemented(...)(501)로 계약만 확정(스캐폴드 관례).

12. 교차 아키텍처 참조 (링크)

  • 시스템·NFR·배포 토폴로지 → docs/architecture/system.md(SA)
  • 기술 표준·빌드/관측성·AiTextRouter → docs/architecture/tech.md(TA)
  • 전사 ERD·공간데이터·마스터·BI 데이터마트 → docs/architecture/data.md(DA)
  • DMZ/내부망·방화벽·외부 아웃바운드(Gemini) → docs/architecture/network.md(NA)
  • P0 백엔드 API 계약(정본 예시) → _workspace/01_backend_contracts.md
  • 기획·모듈 정의 → docs/PLANNING.md v2.0 · 실행 → docs/IMPLEMENTATION_BACKLOG.md

13. 변경 이력

버전 일자 작성자 내용
v1.0 2026-07-11 AA 최초 — A-1. 패키지 구조(com.zioinfo.kintex)·4계층 레이어링·모듈 경계(P0 코어 M2~M5·도메인 M10~M18·공통 레이어 §5B)·의존성 규칙(common 무의존·모듈 단방향·순환 금지)·REST 표준(경로/버전/봉투/에러/페이징/인증)·이중 RBAC(플랫폼+행사)·WebSocket STOMP 규격·공통 컴포넌트(WISE 정합)·Redis 큐 계약·역할별 프론트 번들 분리 + 모듈러 모놀리스 백엔드. 스캐폴드(src/backend) 실측 정합, PLANNING v2.0 §8 정합.