kintex/tools/nanobanana/_workspace/01_worker_contract.md
zio 9987d958db feat(v2.0): 자동전시시스템 하네스 재구성 + PLANNING v2.0 + 백엔드 스캐폴드 + 평면도 자산
PLANNING v2.0: 자동전시시스템 재정의, 6역할 웹/모바일 분리, 도메인 M10~M18(옥션 M15·관람객 M10·마케팅/공개사이트 M12·BI M16(운영사 ROI 포함)·CMS M17·관리자 M18), WISE/UIWS 공통·시스템관리 레이어 §5B(2FA OTP), 옥션/견적서/역경매, M2/M3 3안 생성→선택/병합. design.md v1.1(Stitch 정합·SCR 매핑).

하네스 재구성: 전문 에이전트 17종(아키텍트 AA·SA·TA·DA·NA / 공통 common-dev / 코어 backend·frontend·db / 도메인 bidding·visitor·cms·bi·admin / AI ai-dev·visualizer / QA·devops) + kintex-impl-orchestrator v2.0(Phase A~E) + IMPLEMENTATION_BACKLOG v2.0 + CLAUDE.md.

백엔드 스캐폴드: Spring Boot 3.2.5(com.zioinfo.kintex) + JWT/RBAC + WebSocket + 버전형 룰엔진 + M2~M5 컨트롤러(M3 사전검증·M4 견적·M5 RenderJob 실구현, 공간경로 501 대기). compileJava SUCCESS.

자산: 평면도 JPG 15장 + 매니페스트(R4 트렌치·CAD 해소). CAD 93MB·build는 gitignore.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 17:32:40 +09:00

8.9 KiB

나노바나나 워커 ↔ 백엔드 RenderJob 계약 (v1)

대상: tools/nanobanana/worker.py(Python 워커 사이드카) ↔ Spring Boot 백엔드(M5-1). 근거: PLANNING §6(나노바나나 파이프라인 v1.2) · §8(아키텍처) · IMPLEMENTATION_BACKLOG S-4/M5-1~M5-3. 이 문서는 큐 메시지 형식완료 이벤트 형식의 단일 출처다. 백엔드 M5 계약과 정합해야 한다.


1. 파이프라인 위치

Spring Boot(M5-1)               Redis                     Python 워커(S-4 / M5-2·M5-3)          오브젝트 스토리지 / WebSocket
─────────────────              ───────                   ─────────────────────────           ──────────────────────────
RenderJob 발행 ──LPUSH────▶  list: kintex:renderjobs  ──BLPOP──▶  worker.process_job()
                                                                    │  scene → build_booth_prompt
                                                                    │  → render_shot (생성형)
                                                                    │  또는 S6 → render_wiring_overlay_raster (래스터)
                                                                    │  → 이미지 + 메타데이터
                                                                    ├──put──▶ object storage (이미지 + .meta.json 사이드카)
                                                                    └──PUBLISH──▶ channel: kintex:renderjob:events
                                                                                       │
Spring 구독 ◀──완료 이벤트────────────────────────────────────────────────────────────┘
   └─ WebSocket/STOMP 로 프론트에 진행·완료 푸시
  • 워커는 상태 기계의 소비자일 뿐, RenderJob 원본(상태·쿼터·캐시)의 소유는 백엔드(PostgreSQL RenderJob 테이블)다.
  • 워커는 결과 이미지·메타데이터를 오브젝트 스토리지에 적재하고 완료 이벤트만 발행한다. DB 상태 전이는 백엔드가 이벤트를 받아 수행한다.

2. 큐 메시지 — RenderJob (백엔드 → 워커)

  • 큐: Redis list kintex:renderjobs (env NANOBANANA_QUEUE).
  • 인입: LPUSH / 소비: BLPOP(워커, timeout 폴링).
  • 페이로드: UTF-8 JSON 1건.
필드 타입 필수 설명
job_id string RenderJob PK(백엔드 발급). 이벤트·산출물 키의 상관 ID.
event_id string 행사 ID. 스토리지 경로·쿼터 스코프.
booth_id string 부스 ID. 스토리지 경로·상관.
shot_preset string S1~S7 (PLANNING §6-3). S6은 래스터 합성 경로.
scene object ✔* PLANNING §6-2 scene 스키마(hall·booth·design·lighting·wiring). 생성형 샷 필수.
seed int 컷 간 일관성(B-12). 생략 시 참조체인 일관성 폴백.
reference_image string 참조 이미지 경로/URI(빈 부스 실측·간이 렌더). 구조 보존. 목 모드는 무시.
layers string[] 활성 레이어(furniture·lighting·electrical·network). 생략 시 샷별 기본값.
wiring object ✔** S6 전용. scene.wiring 미제공 시 사용. {power,network,plumbing}[].
hall_dims_m [number,number] S6 좌표계 기준(m). 생략 시 booth.size_m → hall.dims_m 폴백.
options object px_per_m(S6), kinds(S6 렌더 레이어) 등 렌더 옵션.

* 생성형 샷(S1~S5,S7)은 scene 필수. ** S6은 scene.wiring 또는 최상위 wiring 중 하나 필수.

예:

{
  "job_id": "rj_01H...",
  "event_id": "evt_2026_kes",
  "booth_id": "A-102",
  "shot_preset": "S2",
  "seed": 12345,
  "reference_image": "s3://kintex/refs/hall7_empty.jpg",
  "scene": {
    "hall": {"id": "제1전시장 7홀", "dims_m": [126, 90], "ceiling_m": 12},
    "booth": {"id": "A-102", "size_m": [6, 3], "type": "independent"},
    "design": {"signage": {"text": "주식회사 가디아"}, "brand_color": "#0052A5"},
    "lighting": {"mode": "night", "color_temp_k": 4000},
    "render_hints": {"style": "tech"}
  }
}

3. 완료 이벤트 (워커 → 백엔드)

  • 채널: Redis pub/sub kintex:renderjob:events (env NANOBANANA_EVENT_CHANNEL).
  • 발행: PUBLISH. 백엔드가 구독해 WebSocket/STOMP로 릴레이(§8).
  • 페이로드: UTF-8 JSON 1건.
필드 타입 설명
type string renderjob.completed | renderjob.failed.
job_id string 상관 ID.
event_id / booth_id / shot_preset string 에코백.
status string DONE(생성/합성 성공) | FAILED.
image_ref object 산출물 참조(§4). 실패 시 null.
meta object 이미지 메타데이터(§5). 실패 시 부분.
error object {code, message} — 실패 시. 스택트레이스·키 미포함.
emitted_at string(ISO-8601 UTC) 이벤트 발행 시각.
  • 에러 코드(친화적 분류, PLANNING §6-5): AUTH(키 무효) · QUOTA(429·쿼터) · SAFETY · BAD_REQUEST · RENDER_ERROR.
  • 쿼터는 성공(DONE) 시에만 차감 — 백엔드가 완료 이벤트 수신 시 처리(실패는 소모 안 함).

4. image_ref — 산출물 참조

{
  "backend": "local" | "s3" | "gcs",
  "key": "evt_2026_kes/A-102/rj_01H..._S2.png",
  "uri": "file:///.../output/visualizations/evt_2026_kes/A-102/rj_01H..._S2.png",
  "sidecar_key": "evt_2026_kes/A-102/rj_01H..._S2.png.meta.json",
  "content_type": "image/png"
}
  • 사이드카 .meta.json은 이미지와 항상 함께 적재된다(결정적, B-03).
  • 기본 백엔드는 로컬 파일시스템(NANOBANANA_OUTPUT_DIR, degraded 오브젝트 스토리지). 운영 시 S3/GCS 어댑터로 교체.

5. meta — 이미지 메타데이터 (§6-6 워터마크·고지 필수)

client.build_metadata 산출 + 워커 증강:

필드 설명
generated_at 생성 시각(ISO-8601 UTC).
schema_hash scene 스키마 SHA-256(정렬 직렬화). 동일 해시 캐시 키(§6-4).
model_version 모델명(gemini-3.1-flash-image-preview 등) 또는 mock.
shot_preset 샷 프리셋.
seed 시드(있으면).
render_path generative | backend_raster_composite(S6).
watermark_required 항상 true.
watermark_text "AI 생성 예상 이미지 — 실제 시공 결과와 다를 수 있음".
notice "계약·심사 서류 사용 금지(도면만 유효)".
live true(실 Gemini 호출) | false(목/degraded).
degraded true면 플레이스홀더(G1 미승인·목 모드).

6. G1 게이트 — 실 Gemini 호출 조건 (PLANNING R12)

조건 결과
NANOBANANA_LIVE=1 그리고 GEMINI_API_KEY 존재 실 호출(생성형 샷 → NanoBananaClient.render_shot).
그 외(기본) 목/degraded 모드 — 플레이스홀더 이미지 + 정상 메타데이터. 파이프라인 구조는 성립.
  • 목 모드는 키·네트워크 없이 동작한다. GEMINI_API_KEY불필요하며 어디에도 로그·기록하지 않는다.
  • S6(래스터 합성)은 G1과 무관 — 항상 로컬 PIL 결정적 합성(생성형 아님). 목/live 모두 동일 경로.
  • 소유자 승인(G1) 확정 후 NANOBANANA_LIVE=1 + 서버 env GEMINI_API_KEY 설정으로 무코드변경 전환.

7. 환경변수

변수 기본값 용도
NANOBANANA_LIVE (미설정=목) 1일 때만 실 Gemini 호출 시도(+키 필요).
GEMINI_API_KEY 실 호출 시에만. 코드·로그·이벤트·응답 기록 금지.
NANOBANANA_MODEL gemini-3.1-flash-image-preview 모델 오버라이드(client.MODEL_NAME).
REDIS_URL redis://localhost:6379/0 큐/이벤트 연결(지연 연결).
NANOBANANA_QUEUE kintex:renderjobs RenderJob 큐 리스트 키.
NANOBANANA_EVENT_CHANNEL kintex:renderjob:events 완료 이벤트 pub/sub 채널.
NANOBANANA_OUTPUT_DIR output/visualizations 로컬 오브젝트 스토리지 루트.

8. 운영 불변식

  1. 지연 연결: Redis 미기동이어도 import·process_job(job) 직접 호출은 성립(스모크·단위 테스트용).
  2. 결정적 사이드카: 모든 산출물에 .meta.json 동반(§5).
  3. 성공 시에만 쿼터 차감: 실패 이벤트는 소모 신호 아님.
  4. 비밀 미노출: 이벤트·로그·에러에 키·IP·스택트레이스 금지(§6-5, GUARDiA 보안 제약).
  5. S6 결정성: 배선 오버레이는 생성 모델 미개입(좌표 정합 목적).