28 KiB
킨텍스 자동전시시스템 — 애플리케이션 아키텍처 표준 (app.md)
작성: 애플리케이션 아키텍트(AA) · 작성일: 2026-07-11 · 버전: v1.0 · BACKLOG A-1 근거:
docs/PLANNING.mdv2.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}
- M2
- 플랫폼(비행사) 리소스:
/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 반려)
- 스택트레이스·내부 세부 미노출 —
error.message는 사람이 읽을 요약만, 상세는 서버 로그. (server.error.include-*: never+ GlobalExceptionHandler.) - 민감정보 응답 완전 제외 — IP·SSH·비밀번호·
os_pw_enc·해시·내부 식별자. 사용자/업체는 이름·역할·번호 등 비민감 필드만. GEMINI_API_KEY는 백엔드가 다루지 않는다 — 나노바나나 Python 워커 전용. M5는 큐 발행까지만.- AI 생성 이미지 응답은 항상
watermarkRequired:true+watermarkText+notice(계약·심사 서류 사용 금지) 포함(제거 불가, PLANNING §6-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에 추가(WISETotpService이식).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.auditAOP로 전수 기록(§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 정합). WISETB_AUDIT_LOG스키마 이식.
7-4. 공통코드 (Phase B)
common.code가 코드 그룹/상세를 캐시 제공(홀·부스유형·공종 14분류·유틸리티 요금코드 등 도메인 코드 포함). 권위는 M18(system). 도메인 모듈은 하드코딩 대신 공통코드 조회.
7-5. 룰셋(버전 관리 데이터)
rules가rulesets/*.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(envRENDER_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) 추가 시 본 표준 준수 확인:
- 패키지
com.zioinfo.kintex.module.mN+ 4계층(Controller·Service/Impl·dto·mapper) 생성(§1-2). - 컨트롤러는 가드→위임→
ApiResponse래핑만(§2-2, FloorplanController 패턴 복제). - 경로
/api/events/{eventId}/…(행사 스코프) 또는/api/admin/**(플랫폼)(§5-1). - DTO는 record, 목록은
PageResponse, 오류는ApiException+ErrorCode(§5-2/5-3). - 공간 데이터는 M2/M4 매퍼 권위 재사용(§3-2), 신규 지오메트리만 자기 매퍼 XML(PostGIS).
- 크로스 모듈은 상대
Service인터페이스로만, §4-2 방향 준수·순환 금지(이벤트 디커플). - 실시간은
/topic/<도메인>/<id>STOMP, 비동기는 Redis 큐(§8/§9). - 감사 대상 액션에
@Audited(§7-3), 알림은notification이벤트 발행(§7-6). - 보안 불변 5종(§5-6) 자체 점검 → QA 반려 방지.
- 미완 구간은
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.mdv2.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 정합. |