- SessionStart hook (scripts/graphify_setup.py): auto-install graphifyy[sql], build knowledge graph on first run (graphify extract --code-only, local AST), incremental graphify update thereafter — install-only smartness - knowledge/kintex/: all 183 KINTEX md docs bundled (planning/design/analysis) - knowledge/guardia/: distilled GUARDiA-wide knowledge from 2,483 md files (solutions-catalog, standard-framework, operations-cicd, lessons-learned; credentials/IP-free curated) - SKILL.md: graph-first codebase query rules + knowledge base loading guide Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
27 KiB
킨텍스 자동전시시스템 — 기술 표준 (Technical Architecture)
작성: 기술 아키텍트(TA) · 작성일: 2026-07-11 · 버전: v1.0 근거:
docs/PLANNING.mdv2.0(§8 확정 스택·§8-1 아키텍처 보강·§10 리스크)·docs/IMPLEMENTATION_BACKLOG.md(A-3)·실측 스캐폴드(src/backend/build.gradle·src/backend/src/main/resources/application.yml·src/frontend/package.json·tools/nanobanana/)·.claude/agents/kintex-ai-dev.md교차참조: 앱 아키텍처docs/architecture/app.md(A-1) · 시스템/NFRdocs/architecture/system.md(A-2) · 데이터docs/architecture/data.md(A-4) · 네트워크docs/architecture/network.md(A-5) 문서 소유권: 본 tech.md는 TA만 수정한다. 확정 스택·버전·빌드/배포·개발표준·관측성·AI 프로바이더 표준의 단일 출처(SSOT)다. 스택 변경은 본 문서 개정을 선행한다.
0. 이 문서의 위치
Phase A(아키텍처·거버넌스) 4개 표준 문서 중 기술 표준(A-3) 이다. 애플리케이션 경계·레이어(app.md), NFR·토폴로지(system.md), 데이터 모델(data.md), 네트워크(network.md)와 정합한다. 본 문서는 "무엇을 어떤 버전으로, 어떻게 빌드·배포·개발·관측하는가"의 기술 규범을 확정한다. 기능 범위·모듈 우선순위는 PLANNING이 권위이며 본 문서는 그 위 기술 계층만 다룬다.
핵심 원칙 4가지:
- 실측 스캐폴드 정합 — 이미 스캐폴드된 실제 스택(Spring Boot 3.2.5·React 18.3.1·google-genai 워커)에 표기를 맞춘다. "3.x" 같은 느슨한 표기 대신 핀 버전을 SSOT로 둔다.
- GUARDiA/UIWS 표준 정렬 — kintex는
zio/kintex독립 저장소이나 GUARDiA 표준 프레임워크(UIWS)와 스택·인증·AI 프로바이더 패턴을 공유한다. - 보안 불변 우선 — 시크릿 env-only, 스택트레이스·자격증명·PII 미노출, AES-256-GCM은 코드보다 상위 제약(§10, PLANNING §10·보안 불변).
- 결정론과 폐쇄망 우선 — 규정/요율은 버전 관리 데이터, AI는 온프레미스 폴백 필수, 외부 아웃바운드는 승인된 도메인만.
1. 확정 기술 스택 (버전 표준·SSOT)
아래 버전은 실측 스캐폴드에서 채택된 값이다. 임의 상향/하향 금지 — 변경은 TA 승인 + 본 표 개정 후.
1-1. 백엔드 (Spring Boot · Java 17 · MyBatis)
src/backend/build.gradle 기준.
| 항목 | 표준 값 | 근거/비고 |
|---|---|---|
| 언어/런타임 | Java 17 (sourceCompatibility/targetCompatibility = 17) |
GUARDiA 표준(전 솔루션 Java 17 정렬). Java 21 금지 |
| 프레임워크 | Spring Boot 3.2.5 | 핀 버전. org.springframework.boot 플러그인 |
| 의존성 관리 | io.spring.dependency-management 1.1.4 |
Spring Boot BOM 정렬 |
| 빌드 도구 | Gradle (wrapper 동봉 gradlew/gradlew.bat) |
시스템 Gradle 미의존, wrapper 고정 |
| 그룹/패키지 | com.zioinfo.kintex / rootProject kintex-backend |
GUARDiA 네이밍 규약 |
| 버전 | 0.1.0-SNAPSHOT |
SemVer, 릴리스 시 -SNAPSHOT 제거 |
| ORM | MyBatis mybatis-spring-boot-starter 3.0.3 |
Spring Boot 3.2.x 호환 핀. JPA 금지(공간 SQL은 매퍼 XML) |
| DB 드라이버 | org.postgresql:postgresql (runtimeOnly, BOM 관리) |
PostGIS 함수는 ST_* 매퍼 XML |
| 캐시/큐 | spring-boot-starter-data-redis |
RenderJob·서류·알림 큐 + 옥션 실시간 순위 |
| 실시간 | spring-boot-starter-websocket (STOMP) |
RenderJob 완료·옥션 순위 푸시 |
| 인증 | spring-boot-starter-security + jjwt 0.12.5 (api/impl/jackson) |
JWT HS256 + RBAC + TOTP 2FA |
| 검증 | spring-boot-starter-validation |
DTO Bean Validation |
| 보일러플레이트 | Lombok (compileOnly + annotationProcessor) | |
| 테스트 | spring-boot-starter-test + spring-security-test, JUnit Platform |
|
| 인코딩 | UTF-8 강제 (JavaCompile.options.encoding = 'UTF-8') |
Windows javac CP949 한글 리터럴 손상 방지 — 불변, 전 모듈 유지 |
MyBatis 규약(application.yml 기준):
mapper-locations: classpath*:mybatis/mapper/**/*.xmlmap-underscore-to-camel-case: true,jdbc-type-for-null: NULL@MapperScan은 GUARDiA 표준(annotationClass = Mapper.class) — 빈 누락 크래시 방지(다른 솔루션 회귀 이력). db-engineer가 공간 SQL 매퍼 XML 소유.
Hikari 풀 표준: maximum-pool-size = ${DB_POOL_MAX:3}. 공유 PostgreSQL 보호(GUARDiA 표준). kintex 전용 DB kintex_db라도 서버 공용 PG면 캡 유지. 상향 필요 시 SA(system.md)·DA와 합의.
1-2. 프론트엔드 (React · Vite · TypeScript)
src/frontend/package.json·vite.config.ts·tsconfig.json 기준.
| 항목 | 표준 값 | 비고 |
|---|---|---|
| UI 라이브러리 | React 18.3.1 (react/react-dom) |
PLANNING "18/19" 중 18.3.1 확정 채택 |
| 빌드/번들러 | Vite 5.4.8 + @vitejs/plugin-react 4.3.2 |
dev 서버 :5173, /api·/ws 프록시 |
| 언어 | TypeScript 5.6.2 (strict: true) |
noUnusedLocals/noUnusedParameters/noFallthroughCasesInSwitch 켬 |
| 라우팅 | react-router-dom 6.26.2 |
역할별 포털 라우팅 |
| 서버 상태 | @tanstack/react-query 5.59.0 |
API 캐싱·재검증 표준. 수동 fetch 지양 |
| 클라이언트 상태 | zustand 4.5.5 |
전역 상태(경량). Redux 금지 |
| 실시간 | @stomp/stompjs 7.0.0 + sockjs-client 1.6.1 |
백엔드 STOMP 정합 |
| 경로 별칭 | @/* → src/* (vite alias + tsconfig paths) |
상대경로 지옥 회피 |
| 모듈 타입 | "type": "module" (ESM), target ES2020 |
빌드 스크립트(package.json): build = "tsc -b && vite build", typecheck/lint = "tsc --noEmit". 타입 에러는 빌드 실패 — CI 게이트.
역할별 프론트 분리(PLANNING §2-1·§8-1): organizer·exhibitor·contractor·ops·admin(인증) + public/visitor(공개). 번들 분리 방식은 designer/FE 트랙 결정(모노레포 다중 진입점 vs 서브패스). 공유 디자인 시스템(design.md)·공유 컴포넌트·공유 API 계약은 상속(중복 구현 금지). 현재 스캐폴드는 단일 Vite 앱(src/frontend) — 분리 실행 시 본 표준의 라이브러리 버전을 전 번들이 공유한다.
1-3. 나노바나나 Python 워커 (사이드카)
tools/nanobanana/ 기준. PLANNING §8 "Python 워커 유지 근거"(google-genai는 Python SDK, ReRoomAI 검증 client.py 재사용 — Java 재구현 회피).
| 항목 | 표준 값 | 비고 |
|---|---|---|
| 런타임 | Python 3.11+ (개발 실측 3.14 __pycache__) |
배포는 3.11/3.12 LTS 권장(3.14는 개발 로컬) |
| 이미지 SDK | google-genai (pip install google-genai) |
Gemini image-to-image. 지연 임포트(무네트워크 import 성립) |
| 모델 | gemini-3.1-flash-image-preview (나노바나나 2, env NANOBANANA_MODEL) |
하드코딩 아님, env 오버라이드 |
| 이미지 처리 | Pillow(PIL) | S6 배선 오버레이 결정적 래스터 합성·목 플레이스홀더 |
| 큐/이벤트 | redis (redis.from_url, BLPOP 소비 + pub/sub 발행) |
지연 연결 |
| 실행 | python -m tools.nanobanana.worker (루프) / --smoke (무네트워크) |
워커 불변식(worker.py 헤더): ①G1 게이트 — 실 Gemini 호출은 NANOBANANA_LIVE=1 + GEMINI_API_KEY 동시 충족 시만, 기본 목/degraded. ②지연 연결 — Redis 미기동이어도 process_job() 직접 호출 성립. ③S6은 생성형 아님(항상 로컬 PIL). ④비밀 미노출(키/IP/스택트레이스 미기록).
의존성 관리 표준: 현재 워커에 requirements.txt 부재 — 배포 전 tools/nanobanana/requirements.txt(google-genai·Pillow·redis 핀 버전) 추가 필요(§9 백로그). devops-dev(DEV) 담당.
1-4. 데이터·인프라
| 항목 | 표준 값 | 비고 |
|---|---|---|
| DB | PostgreSQL + PostGIS (kintex_db) |
공간 데이터 일원화(부스 폴리곤·트렌치 포인트·배선 LineString). 상세 DA/data.md |
| 캐시/큐/실시간 | Redis | 작업 큐 + 옥션 라운드 타이머 + 순위 |
| 오브젝트 스토리지 | 로컬 FS(기본 degraded 어댑터) → S3/GCS(운영) | ObjectStore.save_image() 반환 계약 유지하며 어댑터 교체 |
| 마이그레이션 | 미확정 — B-0 백로그는 Flyway 명시(현 build.gradle 미포함) | §3-1 참조. TA 결정: Flyway 채택 권고 |
2. 통합 계약 (백엔드 ↔ 워커 ↔ 프론트)
2-1. RenderJob 큐 계약 (Spring → Redis → Python 워커)
Spring 백엔드가 RenderJob을 Redis 리스트에 push → 워커가 BLPOP 소비 → 오브젝트 스토리지 적재 → pub/sub 이벤트 발행 → 백엔드 구독 → WebSocket(STOMP) 프론트 푸시. 계약 단일 출처: tools/nanobanana/_workspace/01_worker_contract.md.
★ 실측 불일치(리스크 R-T1, §10): 큐/채널 키 기본값이 백엔드와 워커에서 다르다.
application.yml:kintex.render.queue-key = kintex:renderjob:queueworker.py:NANOBANANA_QUEUE 기본 = kintex:renderjobs,EVENT_CHANNEL 기본 = kintex:renderjob:events양측 모두 env 오버라이드 가능하나 기본값 불일치는 배포 시 조용한 무처리(silent no-op) 위험. 표준 확정: 큐 키
kintex:renderjob:queue, 이벤트 채널kintex:renderjob:events로 통일하고 배포 env(RENDER_QUEUE_KEY/NANOBANANA_QUEUE/NANOBANANA_EVENT_CHANNEL)를 동일 값으로 명시 주입. BE·VIZ·DEV가01_worker_contract.md에 최종 키를 고정한다.
2-2. WebSocket(STOMP) 계약
- 백엔드
WebSocketConfig(STOMP) — 프론트@stomp/stompjs+sockjs-client. dev는 Vite 프록시/ws(ws:true). - 이벤트:
renderjob.completed/renderjob.failed(워커→백엔드→구독 클라), 옥션 순위 푸시(M15). 페이로드에image_ref·meta(live/degraded 플래그) 포함, 비밀·스택트레이스 미포함.
2-3. API 응답 봉투
실측: common/ApiResponse.java·common/PageResponse.java·common/error/GlobalExceptionHandler.java 존재. 표준 응답 봉투 + 페이지 봉투 + 전역 예외 핸들러로 에러 응답 표준화(스택트레이스 미노출, ErrorCode 코드+요약 메시지만). 상세 계약은 app.md(A-1) 소유 — 본 문서는 정합만 명시.
3. 빌드·배포 표준
3-1. 백엔드 빌드 (Gradle · 단일 jar)
- 빌드:
./gradlew clean bootJar→ 단일 실행 jar(build/libs/kintex-backend-<ver>.jar). GUARDiA 단일 jar 표준. - 프론트→백엔드 static 번들(GUARDiA 표준 옵션): 운영 배포는 역할별 프론트 번들을 백엔드 static 리소스 또는 nginx 정적 서빙 중 택1. 역할별 프론트 분리(§1-2)이므로 백오피스/포털별 별도 정적 서빙 + 공유 백엔드 jar 토폴로지가 기본(system.md 확정). 공개사이트(M12/M17)는 SEO·다국어로 별도 렌더 경로(SSR/정적 생성).
- 테스트:
./gradlew test(JUnit Platform). compileJava·test 통과가 배포 게이트. - 마이그레이션(TA 결정): B-0가 Flyway를 명시하나 현 build.gradle 미포함. Flyway 채택 권고 —
org.flywaydb:flyway-core+flyway-database-postgresql(PostGIS 정합) 추가,db/migration/V__*.sql(PostGIS 확장·공간 인덱스 포함). 시드/후행 테이블은 GUARDiA 교훈(멱등화 + 누출 차단) 준수 — sql.initmode=never후행 추가 테이블 미적용 회귀(schema-integrity 하네스 교훈) 방지. DB 스키마 상세는 DA/data.md.
3-2. 프론트 빌드 (Vite)
npm ci && npm run build(=tsc -b && vite build) →dist/. 타입 에러 시 실패.- 역할별 번들 분리 시 각 진입점 빌드 산출물을 도메인/서브패스별 배포.
- ★로컬 rollup win32 크래시 함정(리스크 R-T2, §10): GUARDiA 전 프로젝트에서 로컬 Windows rollup 네이티브 렌더 크래시가 반복 관측됨(homepage-renewal·CMS 등). 표준 대응: (1) CI/서버 빌드(Linux) 신뢰 — 서버
npm run build가 권위. (2) 로컬 검증은tsc --noEmit(typecheck)로 대체하거나 esbuild 경로. (3)package-lock.json커밋으로npm ci재현성 확보. (4) 로컬 크래시가 서버 빌드 성공을 막지 않음 — 서버 번들 검증(최신 청크 diff)로 마무리.
3-3. 워커 배포 (systemd 서비스)
- 별도 프로세스(사이드카). systemd 유닛으로 상주(
ExecStart=python -m tools.nanobanana.worker),Restart=on-failure. - env(
EnvironmentFile또는 drop-in):REDIS_URL·NANOBANANA_QUEUE·NANOBANANA_EVENT_CHANNEL·NANOBANANA_OUTPUT_DIR·(G1 승인 후)NANOBANANA_LIVE=1·GEMINI_API_KEY. GEMINI_API_KEY는 워커 env에만(백엔드 미보유 — application.yml 주석 명시). GUARDiA 서버는 명령줄 인자 기동 서비스가 많아 systemd drop-in EnvironmentFile 방식 채택(기존 ExecStart 불변, guardia-claude-ai 트랙 패턴). - 미승인(G2/G1 전) 기본 목/degraded 모드로 상주 가능(무네트워크).
3-4. CI/CD 파이프라인
GUARDiA 표준 흐름 정렬(솔루션 푸시 구조 메모리):
workspace/kintex (개발·SSOT)
→ repos/kintex (fresh git init — 모노레포 히스토리 상속 금지, bundle 비대화 방지)
→ Gitea zio/kintex (push)
→ webhook :9999 (deploy_server.py)
→ 서버 빌드(gradlew bootJar + npm build + 워커 배포) → systemd 재시작 → health 게이트
- 선행 게이트 G2(BACKLOG): 배포 대상 서버·포트(GUARDiA 인프라와 별개 도메인) 확정 전 Phase E 착수 금지.
- 함정(GUARDiA 교훈, 배포블록 반영 필수): ①
repos/kintex는 반드시 freshgit init(모노레포.git상속 시 bundle 1.5GB 회귀). ②deploy_server.py에 kintex 블록 추가 시 서버/opt/zioinfo/deploy_server.py사본 반영 +zioinfo-deploy재시작 필수(로컬만 고치면 웹훅 1ms no-op). ③백엔드 jar만이 아니라 워커 서비스도 배포 대상(별도 systemd). ④health 200 확인이 완료 게이트.
3-5. 환경변수 표준 (시크릿 env-only)
application.yml은 모든 시크릿을 플레이스홀더로만 주입(하드코딩 금지, 주석 명시).
| env | 용도 | 소비자 |
|---|---|---|
DB_URL/DB_USER/DB_PASSWORD |
PostgreSQL(PostGIS) | 백엔드 |
DB_POOL_MAX (기본 3) |
Hikari 캡 | 백엔드 |
REDIS_HOST/REDIS_PORT/REDIS_PASSWORD |
Redis | 백엔드 |
REDIS_URL |
Redis(워커) | 워커 |
JWT_SECRET(≥32B)/JWT_ACCESS_TTL |
JWT HS256 | 백엔드 |
RENDER_QUEUE_KEY/NANOBANANA_QUEUE |
큐 키(통일) | 백엔드/워커 |
NANOBANANA_EVENT_CHANNEL |
이벤트 채널 | 워커/백엔드 |
RENDER_EVENT_QUOTA(기본 500) |
행사별 생성 쿼터 | 백엔드 |
NANOBANANA_LIVE/GEMINI_API_KEY |
G1 승인 후 실 Gemini | 워커 전용 |
ANTHROPIC_API_KEY |
Claude AI(§6) | 백엔드 |
ADMIN_PASSWORD_ENC + 키파일 |
admin 비번(AES-256-GCM) | 백엔드 |
VITE_BACKEND_ORIGIN/VITE_API_BASE |
프론트 오리진/프록시 | 프론트 |
admin 비번(B-1·GUARDiA 표준): admin123 등 평문 시드 금지. ADMIN_PASSWORD_ENC(AES-256-GCM) + 별도 키파일 주입, 최초 기동 재시드(guardia-claude-ai guardia_master.key 패턴).
4. 개발 표준
4-1. 코드 스타일
- Java: Google Java Style 기준(4-space, 100~120 col). Lombok 활용(
@Getter/@RequiredArgsConstructor/@Slf4j), 필드 주입 금지(생성자 주입). 패키지 = 모듈별(module.m2·module.m5·auth·common·config) — app.md 경계 준수. UTF-8 소스 필수(build.gradle 강제). - TypeScript:
strict전면.any지양(불가피 시 주석). 컴포넌트 함수형, hooks 규약. 서버 상태는 react-query, 전역은 zustand.@/*별칭 사용. - Python(워커): PEP 8 + type hints(
from __future__ import annotations). 방어적 임포트(SDK/redis 지연). 비밀 미노출 규약(에러 메시지 300자 절단·키 미기록) 유지.
4-2. 테스트 표준
- 백엔드: JUnit 5 + spring-security-test. 단위(서비스·룰엔진·요율 계산) + 슬라이스(
@WebMvcTest/@MyBatisTest) + 통합(핵심 왕복). 필수 테스트(GUARDiA feedback_test_required): 임포트/컴파일 검증 + 라우트 확인 + curl 응답. 룰엔진(규정·요율)·PostGIS 공간 SQL은 결정적 테스트 필수. - 프론트:
tsc --noEmit게이트(현 최소선). 확장 시 Vitest + Testing Library 권고(현 미도입). - 워커:
python -m tools.nanobanana.worker --smoke(무네트워크 스모크) — 목 잡 S2 + S6 래스터 처리·사이드카 확인. CI 필수 게이트. - AI/외부 호출: 목/degraded 경로가 무네트워크로 통과해야 함(폐쇄망·미승인 대비).
4-3. 브랜치·커밋 규약
- 브랜치:
main(보호) + 작업 브랜치(feat/·fix/·chore/). main 직접 커밋 금지(작업 브랜치 → PR). 기본 브랜치 push는origin HEAD:main(BI repo master 함정 교훈 — repo별 기본 브랜치 확인). - 커밋(Conventional Commits):
type(scope): summary. type =feat/fix/docs/refactor/test/chore/build/perf. scope = 모듈(m2·m5·auth·worker·bidding). 커밋 메시지 영어(kintex-ai-dev·visualizer 산출 규약). 예:feat(m5): add renderjob quota guard. - 커밋 금지 대상: 시크릿·
.env·CAD zip(gitignore)·build 산출물..gitignore준수(.gradle/·build/·*.log·.env). - 커밋/푸시 타이밍: 사용자·오케스트레이터 명시 요청 시에만.
4-4. 저장소·문서 규약
- kintex는 독립 저장소(
zio/kintex) — GUARDiA ITSM(관공서 관제)과 별개 도메인. R12 게이트상 Gemini 외부호출은 kintex 독립성과 무관하게 소유자 승인 선행. - 아키텍처 문서는
docs/architecture/. PLANNING(planner)·design(designer) 소유권 존중 — 본 문서는 직접 수정하지 않고 교차참조.
5. 성능·관측성 표준
5-1. 로깅
- 백엔드: SLF4J/Logback(Spring Boot 기본).
logging.level.root: INFO,com.zioinfo.kintex: DEBUG(개발). 운영은 INFO로 하향(envLOGGING_LEVEL_*오버라이드). 구조화(JSON) 로깅은 관측성 승격 시 권고. - 로그 보안 불변: 자격증명·IP·SSH·PII·스택트레이스 로그 금지. 워커는 예외 요약만(
type(e).__name__), 키 미기록.include-stacktrace: never유지. - 상관관계: 요청별 traceId(MDC) 표준화 권고 — 옥션·RenderJob 비동기 흐름 추적.
5-2. 메트릭·트레이싱 (Observability)
- 표준(Micrometer + Actuator 권고):
spring-boot-starter-actuator추가(현 미포함) →/actuator/health(배포 게이트),/actuator/metrics, Prometheus/actuator/prometheus(GUARDiA guardia-rag/metrics패턴 정렬). - 핵심 지표: RenderJob 처리량·지연·실패율(목/live 구분), 큐 적체(Redis 리스트 길이), 옥션 순위 계산 지연, PostGIS 공간 쿼리 지연, Hikari 풀 사용률, AI 프로바이더 폴백 발생률(Claude→Ollama).
- 트레이싱: OpenTelemetry(OTel)는 관측성 트랙 승격 시(GreenOps/observability-platform 패턴). 초기는 로그 상관관계 + Actuator 메트릭.
- health 계약: 배포 후
/actuator/health200이 완료 게이트(§3-4). 워커는 하트비트/최근 처리 시각을 이벤트/로그로 관측(전용 health 엔드포인트 부재 — 큐 소비 로그로 감시).
5-3. 성능 표준·부하 목표
PLANNING §10 리스크(R6 이미지 비용·지연) 정렬:
- 이미지 생성(R6): 홀당 200~600부스 동시 생성 시 비용/지연 급증. 표준: 자동 생성은 S1·S7 한정 + 온디맨드 + 스키마 해시 캐시(client.py 캐시) + 행사별 쿼터(
RENDER_EVENT_QUOTA기본 500). 워커는 성공 시에만 쿼터 차감(worker 방어 로직). - PostGIS 대량 배치: 부스 폴리곤·배선 LineString 대량 연산은 공간 인덱스(GiST) 전제. 배치 배치도 생성·정산 집계는 트랜잭션 분할.
- BI 집계(M16, PLANNING §8-1): 운영 DB 부하 회피 — 배치/스냅샷(KpiSnapshot) 또는 읽기 전용 복제. 실시간 대시보드 직접 집계 지양.
- 비동기 우선: 이미지·서류·알림·PDF(옥션 견적서)는 전면 Redis 큐 경유(동기 블로킹 금지).
6. AI 프로바이더 기술 표준 (Claude 기본 + 설정형 전환)
근거:
.claude/agents/kintex-ai-dev.md·GUARDiA guardia-claude-ai 트랙·UIWS 패턴. 나노바나나(Gemini 이미지)는 별개(visualizer·§1-3·G1 게이트) — 본 절은 텍스트/지능 AI(부스배치 조건해석·규정검증 보조·예측·매칭·서류검수·챗봇).
6-1. 프로바이더 라우팅 아키텍처
UIWS 표준 3-컴포넌트(현 스캐폴드 미구현 — AI 모듈 착수 시 신설):
ClaudeTextClient: Anthropic Claude API(api.anthropic.com— 소유자 승인 예외 2026-07-03) 호출. 키는 envANTHROPIC_API_KEY에서만 로드(코드·DB·로그·커밋·응답 기록 금지).AiTextRouter: 프로바이더 선택·폴백 오케스트레이션. 기본 Claude → 실패 시 Ollama 자동 폴백(온프레미스 소형:qwen3:1.7b·llama3.2:1b등). 하드코딩 금지.AiConfig/AiConfigService+ 설정 화면: 런타임 프로바이더/모델 전환(화이트리스트claude-*기본 + 승인된 Ollama). generation_model·temperature·top_k·enabled 설정.
6-2. 폴백·폐쇄망·결정론
- Ollama 폴백 필수(폐쇄망·Claude 장애 대비). RAM 제약 준수 — 서버 가용 ~2GB, 대형 모델 금지(소형만, project_ollama_ram_constraint).
- 결정론 기능(분류·추출·서류검수): 구조화 출력(
format:json). 환각 방지 — 근거 없는 답변 보류·인용(guardia-ai-trust 정렬). - 부스 배치(M2): 생성형 LLM이 배치를 만드는 것이 아니라 제약 솔버/휴리스틱이 3안 생성, LLM은 조건 해석·설명에만(kintex-ai-dev 규약).
6-3. 외부 아웃바운드 게이트 (불변)
| 도메인 | 상태 | 조건 |
|---|---|---|
api.anthropic.com |
승인(2026-07-03 소유자 예외) | Claude 텍스트 AI. 키 env-only, 실패 시 Ollama 폴백 |
generativelanguage.googleapis.com |
미승인 게이트 G1(PLANNING R12) | 나노바나나. M5 실호출 착수 전 소유자 승인 선행. 미승인 시 목/degraded |
| 그 외 외부 API | 금지 | GUARDiA 보안 불변 |
네트워크 아웃바운드 화이트리스트·프록시는 network.md(A-5) 소유. 본 문서는 AI 게이트만 확정.
7. 보안 기술 표준 (불변 요약)
PLANNING §10·GUARDiA 보안 불변 정렬(상세는 app.md/network.md):
- 시크릿 env-only — 코드·DB·커밋·로그·응답 기록 금지. application.yml 플레이스홀더만.
- 자격증명·PII·스택트레이스 미노출 — API 응답/에러/로그/이벤트.
include-stacktrace: never, 워커 에러 요약만. - AES-256-GCM — admin 비번(
ADMIN_PASSWORD_ENC)·민감 자격증명. 별도 키파일. - 인증(B-1): JWT(HS256, jjwt 0.12.5) + RBAC(6역할·행사 단위) + TOTP 2FA(RFC6238) + 로그인 실패 잠금. UIWS 이식.
- AI 워터마크(R1): 나노바나나 전 이미지 "AI 생성 예상 — 실제 시공과 다를 수 있음" 고지 강제(worker 목/live 공통). 계약·심사 서류 자동 배제.
- 등록업체 게이트(M15): 미등록 업체 옥션 응찰 원천 차단(M7 검증).
8. 기술 리스크 · PoC
PLANNING §10(R1~R12)의 기술 실행 리스크를 TA 관점으로 구체화. 도메인/법적 리스크(R1·R2·R8·R9·R10)는 PLANNING 소유.
8-1. TA 신규/구체화 리스크
| # | 리스크 | 영향 | 완화·PoC |
|---|---|---|---|
| R-T1 | 큐/이벤트 키 기본값 불일치(§2-1) — application.yml kintex:renderjob:queue vs worker.py kintex:renderjobs |
높음(배포 시 조용한 무처리) | 키 통일(kintex:renderjob:queue/kintex:renderjob:events) + 01_worker_contract.md 고정 + 배포 env 명시. PoC: 백엔드 push → 워커 소비 → WebSocket 완료 왕복 스모크 |
| R-T2 | 로컬 rollup win32 크래시(§3-2) — Windows Vite 빌드 네이티브 렌더 크래시(GUARDiA 반복 관측) | 중간(로컬 개발 저해) | 서버 빌드 신뢰 + tsc --noEmit 로컬 게이트 + package-lock.json 커밋(npm ci 재현) |
| R-T3 | PostGIS 대량 배치 성능 — 홀당 200~600부스 폴리곤·배선 최단경로·통로버퍼 검증 대량 연산 | 중간 | GiST 공간 인덱스 + 매퍼 XML ST_* 튜닝 + 배치 분할. PoC: 600부스 배치도 생성·규정검증 SQL 부하 측정(DA 협업) |
| R-T4 | 이미지 큐 부하(PLANNING R6) — 대량 동시 RenderJob 비용·지연 | 중간 | S1/S7 한정 자동생성 + 스키마 해시 캐시 + 행사 쿼터(500) + 워커 동시성 제한. PoC: 목 모드 N=500 잡 큐 처리량·적체 측정(무비용) |
| R-T5 | Flyway 부재(§3-1·B-0 명시) — 마이그레이션 도구 미결정, 후행 테이블 미적용 회귀(GUARDiA schema-integrity 교훈) | 중간 | Flyway 채택 + 멱등 스키마 + 누출 차단. DA와 확정 |
| R-T6 | 워커 requirements.txt 부재(§1-3) — 의존성 핀 미고정 | 낮음 | tools/nanobanana/requirements.txt 추가(google-genai·Pillow·redis 핀). DEV 담당 |
| R-T7 | AiTextRouter/AiConfig 미구현(§6-1) — AI 프로바이더 표준 코드 부재 | 낮음(설계 확정, 착수 대기) | AI 모듈 착수 시 UIWS 패턴 이식. Ollama 폴백 무네트워크 검증 |
8-2. 권장 PoC 순서 (TA 실행 가능·Bash)
- 워커 스모크(무네트워크·무비용) —
python -m tools.nanobanana.worker --smoke. S2 목 + S6 래스터 사이드카 확인. 즉시 실행 가능. - 큐 왕복 PoC(R-T1) — 로컬 Redis + 백엔드 push + 워커 소비 스모크(키 통일 검증).
- PostGIS 배치 PoC(R-T3) — 600부스 합성 데이터로 배치·검증 공간 SQL EXPLAIN ANALYZE.
- 이미지 큐 부하 PoC(R-T4) — 목 모드 500잡 처리량·적체.
본 구현은 구현 에이전트(BE·VIZ·DB·AI)가 표준대로 수행. TA는 PoC 스크립트 실행·표준 개선만.
9. 미결 사항 (구현 착수 전 확정 필요)
| # | 항목 | 담당 | Phase |
|---|---|---|---|
| 1 | 큐/이벤트 키 통일(R-T1) → 01_worker_contract.md 고정 |
BE·VIZ·DEV | B/C |
| 2 | Flyway 채택·마이그레이션 구조(R-T5) | DA·DB·TA | B-0 |
| 3 | Actuator/Micrometer 관측성 의존성 추가(§5-2) | DEV·TA | B |
| 4 | 워커 requirements.txt 핀(R-T6) |
DEV | C-M5 |
| 5 | 역할별 프론트 번들 분리 방식(§1-2) 확정 | DES·FE | C/D |
| 6 | AiTextRouter/AiConfig 이식(§6-1) |
AI·BE | D |
| 7 | 배포 서버·포트·도메인(G2) | DEV·SA | E |
| 8 | Gemini 외부호출 승인(G1) | 소유자 | C-M5 |
10. 변경 이력
| 버전 | 일자 | 작성자 | 내용 |
|---|---|---|---|
| v1.0 | 2026-07-11 | TA | 최초 작성(A-3). 실측 스캐폴드 정합 — 확정 스택 핀 버전(Spring Boot 3.2.5·MyBatis 3.0.3·jjwt 0.12.5·React 18.3.1·Vite 5.4.8·TS 5.6.2·google-genai 워커) SSOT화, 빌드·배포(Gradle 단일 jar·Vite·워커 systemd·CI/CD)·개발표준(코드스타일·테스트·Conventional Commits·브랜치)·관측성(로깅·Actuator/Micrometer·성능목표)·AI 프로바이더(Claude 기본+AiTextRouter/AiConfig+Ollama 폴백·외부 아웃바운드 게이트)·기술 리스크7종(R-T1~R-T7)+PoC 확정. ★실측 불일치 발견: 큐 키 기본값 백엔드/워커 상이(R-T1) — 통일 표준 제시. app.md/system.md/data.md/network.md 교차참조 |