AI Meta Clean — 의사결정 대화 기록

Goodtek과 ChatGPT가 제품·기술·보안·운영·다국어 방향을 함께 확정한 기록

Product planningArchitecturePrivacy first2026-07-22

01. “영구 보관하지 않음”을 검증 가능한 약속으로

GT

Goodtek

“서버에 영구 보관하지 않음”을 명확히 고지하고, 처리 후 삭제를 검증 가능하게 설계하고 싶습니다.

AI

ChatGPT

파일 수명 정책과 삭제 기록을 분리하겠습니다. 원본·중간 파일은 결과 검증 직후 삭제하고, 결과·보고서는 다운로드 뒤 또는 짧은 TTL 뒤 삭제합니다. DB에는 파일 자체가 아니라 작업·폐기 결과만 남깁니다.

확정
  • 원본·중간 산출물: 결과 검증 직후 삭제
  • 결과·처리 보고서: 다운로드 성공·취소 뒤 즉시 삭제, 미다운로드면 30분 TTL 뒤 삭제
  • worker 정리 작업 + MinIO lifecycle rule로 이중 폐기
  • DB에는 파일 바이트, 파일명, 원본 메타데이터, 토큰 원문을 저장하지 않음
  • DB에는 상태·시각·형식/용량 구간·성공/실패·폐기 결과·최소 운영 통계만 저장

02. C2PA를 “일반 정리”가 아닌 핵심 기능으로

GT

Goodtek

C2PA를 제거하고 일반 정리를 한다는 게 정확히 무엇인가요? C2PA를 처리할 다른 대안이 있나요? 헬퍼를 쓰면 처리 범위가 더 넓어지나요?

AI

ChatGPT

ExifTool은 EXIF/XMP/IPTC 정리에 강합니다. C2PA는 전용 라이브러리로 탐지·제거·검증을 분리하면 처리 범위와 결과 고지를 더 명확하게 관리할 수 있습니다.

대안판단
ExifTool 단독일반 메타데이터에는 적합하지만 C2PA 핵심 기능의 검증 계층이 부족
ExifTool + c2pa-rs일반 메타데이터와 C2PA를 각각 처리·검증 가능
상용 SDK비용과 공급사 종속성이 커 MVP에는 부적합
GT

Goodtek

핵심 기능이므로 c2pa-rs 헬퍼로 구현하는 게 좋겠습니다.

정책 확정
  • ExifTool: EXIF/XMP/IPTC 정리·검증
  • c2pa-rs helper: C2PA 탐지·제거·검증
  • 실행 전과 결과 화면에 출처 증명·검증 가능성 상실을 명시
  • 픽셀 조작, AI 판정 은폐, 플랫폼 라벨·업로드 결과 변경 보장은 제공하지 않음
  • c2pa-rs는 정확한 버전을 고정하고 포맷별 샘플 테스트로 검증

03. 자체 서버와 Podman

GT

Goodtek

자체 서버가 있습니다. Oracle Cloud aarch64 계열, Oracle Linux 9, Podman 사용 가능 환경입니다. Podman과 호스트 직접 설치를 비교해 주세요.

AI

ChatGPT

후보장점한계
호스트 직접 설치초기 구성이 단순의존성 충돌, 권한 분리, 롤백, 재현 가능한 배포가 어려움
rootless Podman서비스별 격리, 최소 권한, 재현성, 롤백초기 컨테이너 구성 필요
GT

Goodtek

Podman으로 확정해 주세요.

확정

Oracle Linux 9 aarch64에서 rootless Podman으로 web, API, worker, PostgreSQL, Redis, MinIO를 분리 운영합니다. worker는 non-root, read-only root filesystem, capability drop, no-new-privileges, 자원 제한, 전용 임시 디렉터리와 내부 네트워크만 사용합니다.

04. 동시 요청, 작업 큐, 진행 상태

GT

Goodtek

웹에서 여러 사용자가 동시에 요청하는 경우에 큐를 사용하지 않으면 문제가 되지 않을까요?

AI

ChatGPT

동기 처리만으로 시작하면 긴 이미지 작업이 요청을 묶고, 동시 사용 시 타임아웃·메모리 압박·처리 순서 문제가 생깁니다.

GT

Goodtek

동시 사용자 수를 예측하기 어렵고 MVP 이후 확장을 고려해서 Redis/메시지 큐 + worker를 해야 할 것 같습니다.

확정

Redis + BullMQ + 독립 NestJS worker를 사용합니다. API는 업로드 검증과 작업 생성까지만, worker는 탐지·정리·검증·폐기를 담당합니다. PostgreSQL은 job state의 source of truth입니다.

GT

Goodtek

Polling은 아닌 것 같습니다. MVP라도 구조를 약하게 하면 안 됩니다. WebSocket을 쓰면 여러 사용자의 요청을 잘 찾아 완료 시 다운로드를 알리고, 진행 바가 올라가는 흐름이 가능한가요?

AI

ChatGPT

가능합니다. 인증된 세션만 job별 Socket.IO room을 구독하게 하고, worker가 Redis에 상태 이벤트를 발행합니다. 연결이 끊겨도 PostgreSQL의 현재 상태를 다시 보내 UI를 복구합니다.

후보판단
Polling불필요한 요청과 지연이 있어 제외
SSE + Redis단방향 상태 전달은 가능하지만 향후 확장성이 상대적으로 낮음
WebSocket + Redis작업별 room, 재연결, 다중 인스턴스 fan-out에 적합
GT

Goodtek

향후를 고려해서 WebSocket + Redis로 하고 싶습니다.

확정

NestJS Socket.IO gateway + Socket.IO Redis adapter를 사용합니다. UI는 업로드 → 대기열 → 처리 → 검증 → 완료 → 다운로드 버튼 표시 흐름이며 polling을 사용하지 않습니다.

05. 임시 파일 저장소와 운영 데이터

GT

Goodtek

RustFS라는 서비스도 있다던데 같이 비교해 주세요.

AI

ChatGPT

후보장점판단
MinIOS3 호환, lifecycle rule, 운영 문서와 사례 성숙권장
RustFSRust 기반, 성장 가능성lifecycle·운영 성숙도가 상대적으로 낮음
호스트 파일시스템단순격리·수명·확장 관리가 어려움
GT

Goodtek

MinIO로 확정할게요. 이력은 중요하고 향후 운영 통계로도 활용해야 서비스 존속성을 판단할 수 있기 때문에 DB도 설치하는 게 좋겠습니다.

확정
  • private MinIO를 Podman 내부 서비스로 운영하고 외부에 공개하지 않음
  • PostgreSQL에 작업 상태·시각·형식/용량 구간·성공/실패·폐기 결과·운영 통계 저장
  • 파일, 파일명, 원본 메타데이터, 토큰 원문은 DB에 저장하지 않음
GT

Goodtek

만들려고 하는 서비스에 더 적절한 ORM을 솔직한 평가로 다시 확인해 보세요.

AI

ChatGPT

후보판단
Prismaschema·migration·타입 안정성과 향후 운영 기능 확장에 가장 균형적
DrizzleSQL 친화적이지만 현재 서비스에서 Prisma보다 뚜렷한 이점이 적음
raw SQL만제어력은 높으나 migration·타입 관리 비용이 큼
GT

Goodtek

Prisma로 확정할게요.

확정

PostgreSQL + Prisma를 사용합니다. schema, client, reviewed migration은 packages/database에 두며, 배포 중 db push는 사용하지 않습니다.

06. API 구조, 업로드·다운로드, 세션 보안

GT

Goodtek

Next.js Route Handlers가 문제가 생기는 지점은 어느 시점인가요? NestJS 도입은 왜 권장하지 않는가요? 보일러플레이트도 크지 않고, 향후 API 분리에도 유리하지 않나요?

AI

ChatGPT

단순 MVP에서는 Route Handlers만으로 충분하지만, 스트리밍 업로드, 다운로드 권한, WebSocket, Redis fan-out, worker 경계, 향후 외부 API 확장에서 복잡도가 커집니다. NestJS는 이 서비스의 API·gateway·worker 경계를 명확히 만들고 독립 API 확장에 유리합니다.

GT

Goodtek

NestJS를 도입하는 것으로 확정해 주세요.

확정
  • apps/web: Next.js + TypeScript UI
  • apps/api: NestJS HTTP API + Socket.IO gateway
  • apps/worker: NestJS BullMQ worker
  • 핵심 파일 처리 API를 Next.js Route Handlers 중심으로 구성하지 않음
AI

ChatGPT

브라우저는 MinIO에 직접 접근하지 않고, API가 매직 바이트·파일 크기를 검증한 뒤 private MinIO로 스트리밍합니다. 다운로드도 API가 일회성 토큰을 원자적으로 확인한 뒤 스트리밍합니다.

GT

Goodtek

좋습니다. 보안에는 타협이 없죠. 그렇게 할게요.

확정
  • 256-bit 무작위 opaque session cookie, HttpOnly/Secure/SameSite=Lax
  • DB에는 session cookie hash만 저장
  • 일회성 고엔트로피 download token을 API가 원자적으로 검증
  • Caddy body-size boundary + NestJS Redis 기반 rate limit
  • 업로드·job 생성·다운로드·Socket.IO handshake를 각각 제한
  • 원시 IP·파일명·토큰·원본 메타데이터를 로그에 남기지 않음

07. Caddy, 관측성, 비밀 관리, CI/CD

GT

Goodtek

이미 서버에 Caddy가 호스트 웹서버로 사용 중입니다.

AI

ChatGPT

기존 Caddy를 재사용합니다. Caddy만 외부에 공개하고, /는 Next.js web, /api/*/socket.io는 NestJS API로 reverse proxy합니다. web/API는 loopback, PostgreSQL·Redis·MinIO는 내부 네트워크에만 둡니다.

GT

Goodtek

Prometheus/Grafana는 별도 서버에 설치하고 메트릭 endpoint만 제공하겠습니다. 이미 self-hosted Infisical이 있고, CI/CD는 GitHub Actions + self-hosted runner를 사용할 예정입니다.

AI

ChatGPT

별도 Prometheus가 private metrics endpoint를 pull하고 Grafana는 기존 Prometheus를 사용하면 됩니다. 배포는 GitHub Actions OIDC로 Infisical의 짧은 수명 자격증명을 받고, 필요한 값만 Podman Secret으로 동기화하는 방식이 안전합니다.

확정
  • 서비스 내부에 Prometheus/Grafana를 새로 두지 않음
  • 별도 운영 서버가 private metrics endpoint를 pull
  • metric label·로그에 민감 식별자 미포함
  • GitHub Actions OIDC → Infisical machine identity → Podman Secret → rolling restart
  • 앱 컨테이너는 Infisical에 직접 접근하지 않음
  • production self-hosted runner는 PR 빌드에 사용하지 않고 보호된 branch/environment에 한정

08. UI 기술과 DESIGN.md

AI

ChatGPT

UI는 Tailwind CSS + shadcn/ui를 권장합니다. 빠르게 접근성 있는 기반을 만들되, 제품 고유 규칙은 별도 디자인 기준 문서로 관리하는 편이 좋습니다.

GT

Goodtek

좋습니다. 그런데 디자인은 DESIGN.md 파일 구조를 활용해서 컨트롤하는 것을 빼먹은 것 같습니다.

AI

ChatGPT

맞습니다. 루트 DESIGN.md를 디자인의 단일 기준 문서로 두겠습니다. Tailwind와 shadcn/ui는 구현 수단이며, 새 화면·상태·공용 컴포넌트·문구 변경은 같은 변경에서 DESIGN.md를 갱신합니다.

확정
  • 루트 DESIGN.md가 디자인 토큰, 컴포넌트 계약, 화면 상태, 접근성, 다국어, 문구 원칙의 단일 기준
  • 업로드·메타데이터 확인·처리 진행·다운로드·폐기·C2PA 경고의 필수 상태를 관리
  • 모바일 safe-area, 키보드 focus, screen reader, reduced motion 검토 기준 포함
  • 향후 세부 와이어프레임은 docs/design/으로 확장 가능하되 핵심 기준은 DESIGN.md에 유지

09. 글로벌 언어, 라우팅, 우측 하단 설정 버튼

GT

Goodtek

글로벌 사이트로 운영할 겁니다. 영어, 한국어, 일본어, 한국어 가능하도록 만들어 주세요.

AI

ChatGPT

중복된 한국어는 우선 영어·한국어·일본어로 해석했습니다. 다국어 구현은 Next.js App Router와 잘 맞는 next-intl을 권장합니다.

GT

Goodtek

저는 대한민국 사람이니 루트 /를 한국어 기본으로 하고, 나머지는 브라우저 언어를 탐지해 들어가게 해주세요. 언어 변경 모듈은 우측 하단에 넣고 변경 데이터는 localStorage에 저장해 기억하게 해주세요. goodtek.xyz의 우측 하단 설정 플로팅 버튼을 참조하면 좋겠습니다.

AI

ChatGPT

언어 선택은 localStorage에 저장하고 SSR의 언어 깜빡임을 막기 위해 비민감 locale cookie에도 동기화하겠습니다. 다만 “항상 한국어 루트”와 “첫 방문 자동 브라우저 언어 라우팅”은 우선순위를 정해야 합니다.

GT

Goodtek

중국어는 왜 뺐나요?

AI

ChatGPT

처음에는 한국어 중복 표기로 해석했기 때문입니다. 중국어를 제외할 이유는 없습니다. 간체 중국어를 추가하고, 번체 중국어는 대만·홍콩을 별도 지원할 때 확장할 수 있습니다.

GT

Goodtek

4개로 하겠습니다.

GT

Goodtek

첫 방문 때는 브라우저 언어를 보고 라우팅합니다. 한국어는 /ko가 붙지 않고 그냥 루트에서 움직입니다.

AI

ChatGPT

그 규칙으로 수정하겠습니다. 첫 방문에는 Next.js middleware가 Accept-Language를 읽어 한국어는 /, 영어는 /en, 일본어는 /ja, 간체 중국어는 /zh-CN으로 보냅니다. 직접 선택한 언어는 이후 브라우저 언어보다 우선합니다.

GT

Goodtek

next-intl로 확정하세요.

확정
  • 지원 언어: 한국어, English, 日本語, 简体中文
  • 경로: /, /en, /ja, /zh-CN
  • 첫 방문: Accept-Language 기반 라우팅, 미지원 언어는 영어로
  • 재방문: 사용자가 직접 선택해 localStorage + locale cookie에 저장한 언어 우선
  • 공유한 명시적 locale URL은 해당 경로 우선
  • 우측 하단 설정 플로팅 버튼에서 한국어, English, 日本語, 简体中文 제공
  • next-intl로 모든 사용자 노출 문구를 관리

10. 최종 확정 아키텍처

AI

ChatGPT

확정된 서비스 경계와 데이터 흐름입니다.

Browser
  │
  ▼
Host Caddy
  ├─ /, /en, /ja, /zh-CN → Next.js web + next-intl
  ├─ /api/*, /socket.io  → NestJS API + Socket.IO gateway
  │                         ├─ PostgreSQL (job state, session hash, 통계)
  │                         ├─ Redis (BullMQ, rate limit, fan-out)
  │                         └─ private MinIO (단기 파일)
  │                                  ▲
  └──────────────────────── NestJS BullMQ worker
                                     ├─ c2pa-rs helper
                                     └─ ExifTool
최종 결정 요약
  1. Next.js + TypeScript web, NestJS API/Socket.IO, NestJS worker
  2. pnpm Workspace + Turborepo 모노레포
  3. Redis + BullMQ, PostgreSQL + Prisma, private MinIO
  4. ExifTool + c2pa-rs helper
  5. Oracle Linux 9 aarch64 + rootless Podman + 기존 host Caddy
  6. 세션 cookie + 일회성 다운로드 token + Redis rate limit
  7. GitHub Actions OIDC + self-hosted runner + Infisical + Podman Secret
  8. 별도 Prometheus/Grafana가 private metrics를 수집
  9. Tailwind CSS + shadcn/ui + root DESIGN.md
  10. next-intl, 한국어/영어/일본어/간체 중국어, 첫 방문 브라우저 언어 라우팅