# KINTEX ↔ GUARDiA 표준 프레임워크 정합 매핑

> 킨텍스 자동전시시스템이 **GUARDiA 표준 프레임워크(UIMS/WISE 기준)** 를 어떻게 준수·차용·차이 처리하는지의 단일 참조.
> 정본 표준: `workspace/_framework/GUARDIA_STANDARD_FRAMEWORK.md` · WISE 적용 명세: `workspace/_framework/WISE_APPLY_SPEC.md` (둘 다 읽기 전용).
> 이 문서는 킨텍스 관점의 **매핑·갭**만 기록한다(표준 원문 복제 금지).

---

## 0. 요약

| 축 | 표준(GUARDiA/UIMS) | KINTEX 상태 |
|----|--------------------|-------------|
| 스택 | Spring Boot 3.5 Java17 + React18/19 Vite + MyBatis + PostgreSQL | ✅ 준수 (+ PostGIS·Redis·나노바나나 Python 워커 = 도메인 확장) |
| 인증 | JWT + 2FA(OTP) + 로그인 실패 잠금 + admin 비번 env | ✅ 준수 (행사 단위 RBAC 로 역할 모델 확장) |
| 공통 모듈 | worklog·schedule·message·stats·system·notice·… | ✅ WISE 이식 (`work/*`·`system/*` 패키지) |
| 디자인 | WISE 토큰·선(stroke) SVG·chief-designer 리드 | ✅ 준수 |
| AI | 프로바이더 선택형 + AiTextRouter 폴백 + DuckDB 학습 | ◐ Claude 기본 + AiConfig 전환(설계) — 나노바나나(Gemini)는 **승인된 이미지 예외** |
| 보안 | 외부 API 금지(anthropic 예외)·AES-256-GCM·감사로그 | ✅ 준수 (+ Gemini 이미지 예외·AI 이미지 워터마크 강제) |
| 배포 | workspace→repos(fresh)→Gitea→webhook→systemd→nginx | ✅ 준수 (분리형: 프론트 dist→nginx / 백엔드 jar→8021) |
| 스키마 | Flyway/sql.init 멱등·mode·누출차단 | ◐ Flyway 사용 — GUARDiA sql.init 갭은 §4 참조 |

범례: ✅ 완전 준수 · ◐ 부분/설계 · ✕ 미준수.

---

## 1. 스택 정합

- **일치**: Spring Boot 3.x(Java 17)·MyBatis·React(Vite/TS)·PostgreSQL·단일 Gitea repo·systemd·nginx.
- **킨텍스 확장(표준 상위집합)**:
  - **PostGIS** — 부스 폴리곤·트렌치 포인트·배선 LineString 공간 연산(표준엔 없음, 도메인 필수).
  - **Redis 작업 큐** — RenderJob·서류·알림 비동기(`kintex:renderjob:queue`).
  - **나노바나나 Python 워커** — Gemini 이미지 생성 사이드카(별도 systemd `kintex-nanobanana.service`). 백엔드는 큐 발행만, 키는 워커 env 전용.
- **패키징 차이**: 표준은 "단일 jar(프론트→백엔드 static 번들)". 킨텍스는 **역할별 프론트 번들 분리**(PLANNING §2-1)라 nginx 정적 서빙 + 백엔드 API 분리를 기본으로 한다. → 표준의 *의도*(무중단·헬스게이트 배포)는 유지, 물리 패키징만 분리형.

## 2. 인증 정합 (JWT + 2FA)

- **일치**: `Authorization: Bearer <JWT>`(HS256), 2단계 로그인(`/api/auth/login` → `verify-otp`), admin 비번 env(`ADMIN_PASSWORD_ENC`+`ADMIN_KEY_FILE`) 재시드, 로그인 실패 잠금.
- **확장**: RBAC 가 전역 역할이 아니라 **행사(event) 스코프 역할**(`ORGANIZER·EXHIBITOR·CONTRACTOR·HALL_MANAGER`) — JWT 클레임 `roles`=eventId→역할, `hm`=홀매니저. `/api/admin/**`=ADMIN 게이트는 표준 그대로.
- **공개 경로**: `GET /health`·`POST /api/auth/login`·`/ws/**`·`POST /api/internal/render/callback`(워커 토큰). 그 외 인증 필요.

## 3. 공통 모듈 정합 (WISE 이식)

킨텍스 백엔드 `work/*`·`system/*` 패키지에 WISE 공통 레이어를 이식했다(컨트롤러 실측):

| 표준 모듈 | KINTEX 경로 |
|-----------|-------------|
| worklog | `work/worklog` (`/api/work/...`) |
| schedule | `work/schedule` |
| message | `work/message` |
| stats | `work/stats` (`GET /api/work/stats/worklog`) |
| notice | `work/notice` (`/api/work/notices`) |
| opinion | `work/opinion` |
| search | `work/search` |
| meeting | `work/meeting` |
| report | `work/report` |
| notification | `work/notification` (`/api/work/notifications/unread-count`) |
| system(사용자·역할·공통코드·메뉴·설정·감사) | `system/*` + `common/audit` (`/api/common/**`·`/api/admin/**`) |

이식 하네스: 신규 공통 모듈 필요 시 `uiws-port-orchestrator`(기존 솔루션 전파) 패턴 준용. 킨텍스는 `kintex-common-dev` 에이전트가 담당.

## 4. 스키마 무결성 — Flyway 갭 (GUARDiA schema-integrity 패턴 요약)

GUARDiA 다수 솔루션은 `sql.init.mode=never` + schema.sql 후행 확장 때문에 **누락 테이블**(`relation "x" does not exist`) 500 장애를 겪었고, 검증된 수복 패턴은:
1. **시드 멱등화** — 유니크 인덱스로 `INSERT ... ON CONFLICT DO NOTHING` (재적용 안전).
2. `sql.init.mode=always` + `continue-on-error` — 후행 추가 DDL 도 재기동 시 적용.
3. **DataAccessException 핸들러** — DB 오류를 요약 메시지로 변환(스택트레이스·relation 명 누출 차단).
4. 누락 테이블은 **레이어로 드러남** — 매퍼 `FROM`/`JOIN` 을 전수 추출해 한 번에 역설계.

**킨텍스는 Flyway 순번 마이그레이션을 쓰므로 위 문제의 구조적 원인이 없다**(마이그레이션이 곧 스키마 권위). 남는 갭은 아래 3개뿐:

| 갭 | GUARDiA 교훈 | 킨텍스 가드 |
|----|--------------|-------------|
| 시드 비멱등 | 재적용 시 중복키 | Flyway 마이그레이션의 시드는 `ON CONFLICT DO NOTHING`/`MERGE` 로 작성. repeatable 마이그(`R__`)는 자체 멱등. |
| baseline 오적용 | 기존 DB 에 V1 재실행 | `baseline-on-migrate=true` + 운영 DB 는 baseline 버전 명시. 신규 마이그 번호 = 현재 최대+1(pre-push 훅 충돌검사). |
| DB 오류 누출 | 스택트레이스 노출 | 표준 `@RestControllerAdvice`(ApiResponse.error 요약) 로 DataAccessException→`INTERNAL` 요약 매핑. **relation/컬럼명 응답 금지**(API_GUIDE §5). |

→ 결론: 킨텍스는 **sql.init 이 아니라 Flyway** 이므로 GUARDiA "mode=always" 이식은 불필요. 대신 (a) 시드 멱등, (b) baseline 규율, (c) DB 오류 요약 핸들러 3개만 유지하면 동등한 무결성을 얻는다.

## 5. AI 정합

- **Claude 기본 + 설정형 전환**: 표준 `AiTextRouter`/`AiConfig`(Claude→Qwen3→소형 폴백)를 킨텍스 AI(부스 배치·규정검증 보조·매칭·자연어조회·서류검수·챗봇)에 적용(설계, `kintex-ai-dev`).
- **나노바나나(Gemini) 이미지**: 표준의 "외부 API 금지"에 대한 **별도 승인 예외**(G1 게이트, `GEMINI_API_KEY` 워커 env only). 텍스트 AI 의 anthropic 예외와 동일 취급 — 키 미커밋·미로그·미응답.
- **AI 생성 이미지 워터마크 강제**(§SECURITY): 표준에 없는 킨텍스 고유 불변 — M5 응답에 `watermarkRequired:true` 항상 포함.

## 6. 배포 정합

- **일치**: `workspace→repos(fresh git init)→Gitea(zio/kintex)→webhook→deploy_server→systemd→nginx`, Fail-Safe(백업→배포→헬스게이트 `GET /health` 200→롤백), 서버 빌드 직렬(OOM 방지).
- **킨텍스 블록**: `deploy/deploy_server_kintex_block.py`(정본 사본) — 포트 8021, 프론트 dist→`/var/www/kintex`, 백엔드 bootJar→`/opt/kintex/app/app.jar`, `kintex.service`+`kintex-nanobanana.service` 재기동, Flyway 자동 적용, `deploy_kintex.sh` 원자교체·헬스체크·롤백.
- **도메인/포트**: 개발 `kintex.zioinfo.co.kr`→101.79.17.164:8021 / 운영 `kintex.wise.ai.kr`(후속).
- **경량 push**: `scripts/push_kintex.py`(env-only 자격증명, fresh init, bundle→SFTP→push).

## 7. 차용한 GUARDiA 자산 (이 정합 작업으로 kintex 에 추가)

| kintex 파일 | 원본 패턴 | 용도 |
|-------------|-----------|------|
| `tools/test/kintex_smoke_test.py` | `scripts/check/run_full_test.py` | 8021 스모크/회귀(health+라우터등록+로그인 프로브) |
| `scripts/push_kintex.py` | `scripts/push/push_any_repo.py` | 단일 repo 경량 push(env-only) |
| `docs/GUARDIA_ALIGNMENT.md` | `_framework/*` | 본 정합 매핑 |
| `docs/SECURITY.md` | CLAUDE.md 보안 제약 | 킨텍스 관점 보안 불변 |
| `docs/OPS_RUNBOOK.md` | GUARDiA 운영/헬스체크 관행 | 헬스·재기동·롤백 런북 |

> 원본 GUARDiA 자산은 **읽기 전용**으로 참조했고 수정하지 않았다. 킨텍스 사본은 kintex 컨텍스트(포트 8021·도메인·나노바나나·PostGIS)로 재작성.
