2026-03-02 14:48:42 +09:00
@ extends ( 'layouts.app' )
@ section ( 'title' , 'Google Cloud AI 활용 가이드' )
@ push ( 'styles' )
< style >
. gai - card { background : #fff; border-radius: 12px; border: 1px solid #e2e8f0; overflow: hidden; }
. gai - card - header { padding : 16 px 20 px ; border - bottom : 1 px solid #f1f5f9; }
. gai - badge { display : inline - flex ; align - items : center ; gap : 4 px ; padding : 2 px 10 px ; border - radius : 9999 px ; font - size : 11 px ; font - weight : 600 ; }
. gai - badge - blue { background : #dbeafe; color: #1d4ed8; }
. gai - badge - green { background : #dcfce7; color: #166534; }
. gai - badge - purple { background : #f3e8ff; color: #7c3aed; }
. gai - badge - amber { background : #fef3c7; color: #92400e; }
. gai - badge - red { background : #fee2e2; color: #991b1b; }
. gai - badge - cyan { background : #cffafe; color: #155e75; }
. gai - badge - gray { background : #f1f5f9; color: #475569; }
. gai - icon - circle { display : flex ; align - items : center ; justify - content : center ; border - radius : 50 % ; flex - shrink : 0 ; }
. gai - flow { display : flex ; align - items : stretch ; gap : 0 ; overflow - x : auto ; }
. gai - flow - item { flex : 1 ; min - width : 120 px ; text - align : center ; position : relative ; padding : 16 px 8 px ; }
. gai - flow - item : not ( : last - child ) :: after { content : '' ; position : absolute ; right : - 6 px ; top : 50 % ; transform : translateY ( - 50 % ); width : 0 ; height : 0 ; border - top : 8 px solid transparent ; border - bottom : 8 px solid transparent ; border - left : 10 px solid #4285f4; z-index: 1; }
. gai - flow - num { display : inline - flex ; align - items : center ; justify - content : center ; width : 28 px ; height : 28 px ; border - radius : 50 % ; color : #fff; font-size: 12px; font-weight: 700; margin-bottom: 6px; }
. gai - quote { border - left : 3 px solid #4285f4; padding: 12px 16px; background: #eff6ff; border-radius: 0 8px 8px 0; font-style: italic; }
. gai - service - card { padding : 16 px ; border - radius : 10 px ; border : 1 px solid ; transition : transform 0.15 s ease ; }
. gai - service - card : hover { transform : translateY ( - 2 px ); }
. gai - code { background : #1e293b; color: #e2e8f0; padding: 12px 16px; border-radius: 8px; font-size: 12px; font-family: 'Courier New', monospace; overflow-x: auto; white-space: pre; line-height: 1.6; }
</ style >
@ endpush
@ section ( 'content' )
< div class = " space-y-6 " >
{{ -- 페이지 헤더 -- }}
< div class = " flex items-center justify-between " >
< div >
< h1 class = " text-2xl font-bold text-gray-900 " > Google Cloud AI 활용 가이드 </ h1 >
< p class = " mt-1 text-sm text-gray-500 " > SAM에서 활용 중인 Google Cloud AI 서비스 총정리 | @ codebridge - x . com </ p >
</ div >
< div class = " flex items-center gap-3 " >
< span class = " text-xs text-gray-400 " > CodeBridgeX | 2026.03 </ span >
2026-03-02 15:15:06 +09:00
< a href = " { { route('google-cloud.ai-guide.download') }} "
class = " inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 transition-colors "
title = " PPTX 다운로드 " >
< svg class = " w-4 h-4 " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z " /></ svg >
PPTX
</ a >
2026-03-02 14:48:42 +09:00
</ div >
</ div >
{{ -- ─── 핵심 요약 4 카드 ─── -- }}
< div class = " flex gap-4 " style = " flex-wrap: wrap; " >
< div class = " bg-white rounded-lg shadow-sm border border-gray-200 p-5 " style = " flex: 1 1 200px; max-width: 280px; " >
< div class = " flex items-center gap-2 text-sm text-gray-500 " >
< svg class = " w-4 h-4 text-blue-500 " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z " /></ svg >
음성 인식
</ div >
< div class = " text-lg font-bold text-gray-900 mt-1 " > Speech - to - Text </ div >
< div class = " text-sm text-gray-500 mt-0.5 " > V1 + V2 Chirp 2 자동 폴백 </ div >
</ div >
< div class = " bg-white rounded-lg shadow-sm border border-gray-200 p-5 " style = " flex: 1 1 200px; max-width: 280px; " >
< div class = " flex items-center gap-2 text-sm text-gray-500 " >
< svg class = " w-4 h-4 text-emerald-500 " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z " /></ svg >
AI 분석
</ div >
< div class = " text-lg font-bold text-emerald-600 mt-1 " > Gemini 2.0 Flash </ div >
< div class = " text-sm text-gray-500 mt-0.5 " > 재무 분석 , 회의 요약 , 명함 OCR </ div >
</ div >
< div class = " bg-white rounded-lg shadow-sm border border-gray-200 p-5 " style = " flex: 1 1 200px; max-width: 280px; " >
< div class = " flex items-center gap-2 text-sm text-gray-500 " >
< svg class = " w-4 h-4 text-amber-500 " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4 " /></ svg >
클라우드 저장
</ div >
< div class = " text-lg font-bold text-gray-900 mt-1 " > Cloud Storage </ div >
< div class = " text-sm text-gray-500 mt-0.5 " > 음성 / 파일 백업 , 서명 URL </ div >
</ div >
< div class = " bg-white rounded-lg shadow-sm border border-gray-200 p-5 " style = " flex: 1 1 200px; max-width: 280px; " >
< div class = " flex items-center gap-2 text-sm text-gray-500 " >
< svg class = " w-4 h-4 text-purple-500 " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z " />< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M15 12a3 3 0 11-6 0 3 3 0 016 0z " /></ svg >
설정 관리
</ div >
< div class = " text-lg font-bold text-purple-600 mt-1 " > AI Config </ div >
< div class = " text-sm text-gray-500 mt-0.5 " > 다중 Provider , 토큰 / 비용 추적 </ div >
</ div >
</ div >
{{ -- ─── Section 1 : SAM AI 아키텍처 개요 ─── -- }}
< div class = " gai-card " >
< div class = " gai-card-header " >
< h2 class = " text-base font-semibold text-gray-800 " > SAM AI 아키텍처 개요 </ h2 >
< p class = " text-xs text-gray-400 mt-0.5 " > Google Cloud 기반 AI 서비스 통합 구조 </ p >
</ div >
< div class = " p-5 " >
{{ -- 아키텍처 다이어그램 -- }}
< div class = " p-4 bg-gray-50 border border-gray-200 rounded-lg mb-5 " style = " overflow-x: auto; " >
< pre class = " text-xs text-gray-700 leading-relaxed " style = " font-family: 'Courier New', monospace; white-space: pre; " >
┌─────────────────────────────────────────────────────────────────────┐
│ SAM 관리자 ( MNG ) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 회의록 │ │ 음성녹음 │ │ 상담메모 │ │ 재무분석 │ │
│ │ 시스템 │ │ 분석 │ │ STT 입력 │ │ AI리포트 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │
│ ┌────▼────────────▼────────────▼────────────▼─────┐ │
│ │ GoogleCloudService │ │
│ │ ┌─────────────┐ ┌───────────────┐ │ │
│ │ │ STT V2 │ │ STT V1 │ │ │
│ │ │ ( Chirp 2 ) │ │ ( latest_long ) │ ← 자동폴백 │ │
│ │ └──────┬──────┘ └───────┬───────┘ │ │
│ │ └────────┬────────┘ │ │
│ │ ┌─────────────┼──────────────┐ │ │
│ │ │ Speaker │ GCS Upload │ │ │
│ │ │ Diarization │ / Download │ │ │
│ │ └─────────────┴──────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
└──────────────────────────┼─────────────────────────────────────────┘
│
┌──────────▼──────────┐
│ Google Cloud APIs │
│ │
│ Speech - to - Text │
│ Cloud Storage │
│ Vertex AI ( Gemini ) │
└─────────────────────┘ </ pre >
</ div >
{{ -- 서비스 매핑 테이블 -- }}
< div class = " text-sm font-medium text-gray-700 mb-2 " > SAM 서비스 & harr ; Google Cloud API 매핑 </ div >
< table class = " w-full text-sm " >
< thead >
< tr class = " border-b-2 border-gray-200 " >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " style = " width: 22%; " > SAM 서비스 </ th >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " style = " width: 22%; " > Google Cloud API </ th >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " style = " width: 20%; " > 모델 / 엔진 </ th >
< th class = " text-center py-2 px-3 text-gray-600 font-medium " style = " width: 12%; " > 상태 </ th >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " > 소스 파일 </ th >
</ tr >
</ thead >
< tbody >
@ php
$services = [
[ 'sam' => '회의록 자동 생성' , 'api' => 'Speech-to-Text' , 'model' => 'Chirp 2 / latest_long' , 'status' => '운영중' , 'file' => 'MeetingMinuteService' ],
[ 'sam' => '음성 녹음 분석' , 'api' => 'Speech-to-Text' , 'model' => 'Chirp 2 + Gemini' , 'status' => '운영중' , 'file' => 'AiVoiceRecordingService' ],
[ 'sam' => '상담 메모 음성 입력' , 'api' => 'Speech-to-Text' , 'model' => 'V1 latest_long' , 'status' => '운영중' , 'file' => 'GoogleCloudService' ],
2026-03-03 08:09:06 +09:00
[ 'sam' => '재무 AI 리포트' , 'api' => 'Vertex AI (Gemini)' , 'model' => 'gemini-2.5-flash' , 'status' => '운영중' , 'file' => 'AiReportService (API)' ],
[ 'sam' => '명함 OCR' , 'api' => 'Gemini API' , 'model' => 'gemini-2.5-flash' , 'status' => '운영중' , 'file' => 'GeminiService' ],
2026-03-02 14:48:42 +09:00
[ 'sam' => '오디오 백업/저장' , 'api' => 'Cloud Storage' , 'model' => 'Standard Class' , 'status' => '운영중' , 'file' => 'GoogleCloudStorageService' ],
[ 'sam' => 'AI 설정 관리' , 'api' => '—' , 'model' => '다중 Provider' , 'status' => '운영중' , 'file' => 'AiConfig (Model)' ],
[ 'sam' => '토큰/비용 추적' , 'api' => '—' , 'model' => 'USD/KRW 환산' , 'status' => '운영중' , 'file' => 'AiTokenHelper' ],
];
@ endphp
@ foreach ( $services as $svc )
< tr class = " border-b border-gray-100 hover:bg-gray-50 " >
< td class = " py-2.5 px-3 font-medium text-gray-800 " > {{ $svc [ 'sam' ] }} </ td >
< td class = " py-2.5 px-3 text-gray-600 " > {{ $svc [ 'api' ] }} </ td >
< td class = " py-2.5 px-3 text-gray-500 text-xs " > {{ $svc [ 'model' ] }} </ td >
< td class = " py-2.5 px-3 text-center " >
< span class = " gai-badge gai-badge-green " > {{ $svc [ 'status' ] }} </ span >
</ td >
< td class = " py-2.5 px-3 text-xs text-gray-400 font-mono " > {{ $svc [ 'file' ] }} </ td >
</ tr >
@ endforeach
</ tbody >
</ table >
</ div >
</ div >
{{ -- ─── Section 2 : Speech - to - Text ( 음성 인식 ) ─── -- }}
< div class = " gai-card " >
< div class = " gai-card-header " >
< div class = " flex items-center gap-2 " >
< div class = " gai-icon-circle " style = " width: 28px; height: 28px; background: #4285f4; " >
< svg class = " w-3.5 h-3.5 text-white " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z " /></ svg >
</ div >
< div >
< h2 class = " text-base font-semibold text-gray-800 " > Speech - to - Text & mdash ; 음성 인식 </ h2 >
< p class = " text-xs text-gray-400 mt-0.5 " > V2 Chirp 2 & rarr ; V1 latest_long 자동 폴백 전략 </ p >
</ div >
</ div >
</ div >
< div class = " p-5 " >
{{ -- V2 vs V1 비교 -- }}
< div class = " flex gap-4 mb-5 " style = " flex-wrap: wrap; " >
< div class = " gai-service-card border-blue-200 bg-blue-50 " style = " flex: 1 1 280px; " >
< div class = " flex items-center gap-2 mb-3 " >
< span class = " gai-badge gai-badge-blue " > V2 ( Primary ) </ span >
< span class = " text-xs text-gray-400 " > Chirp 2 모델 </ span >
</ div >
< div class = " space-y-2 text-sm " >
< div class = " flex items-start gap-2 " >< span class = " text-blue-500 mt-0.5 " >& #9654;</span> <span class="text-gray-700">Chirp 2 — Google 최신 음성 인식 모델</span></div>
< div class = " flex items-start gap-2 " >< span class = " text-blue-500 mt-0.5 " >& #9654;</span> <span class="text-gray-700">Batch Recognize API (비동기 처리)</span></div>
< div class = " flex items-start gap-2 " >< span class = " text-blue-500 mt-0.5 " >& #9654;</span> <span class="text-gray-700">Speaker Diarization (화자 분리) 내장</span></div>
< div class = " flex items-start gap-2 " >< span class = " text-blue-500 mt-0.5 " >& #9654;</span> <span class="text-gray-700">Speech Adaptation — phrase hints 지원</span></div>
< div class = " flex items-start gap-2 " >< span class = " text-blue-500 mt-0.5 " >& #9654;</span> <span class="text-gray-700">자동 구두점, 단어별 타임스탬프</span></div>
</ div >
< div class = " mt-3 text-xs text-blue-700 font-medium " > 메서드 : speechToTextV2 () </ div >
</ div >
< div class = " gai-service-card border-gray-200 bg-gray-50 " style = " flex: 1 1 280px; " >
< div class = " flex items-center gap-2 mb-3 " >
< span class = " gai-badge gai-badge-gray " > V1 ( Fallback ) </ span >
< span class = " text-xs text-gray-400 " > latest_long 모델 </ span >
</ div >
< div class = " space-y-2 text-sm " >
< div class = " flex items-start gap-2 " >< span class = " text-gray-400 mt-0.5 " >& #9654;</span> <span class="text-gray-700">latest_long — 안정적인 기본 모델</span></div>
< div class = " flex items-start gap-2 " >< span class = " text-gray-400 mt-0.5 " >& #9654;</span> <span class="text-gray-700">LongRunningRecognize API (비동기)</span></div>
< div class = " flex items-start gap-2 " >< span class = " text-gray-400 mt-0.5 " >& #9654;</span> <span class="text-gray-700">Speaker Diarization (2~6명)</span></div>
< div class = " flex items-start gap-2 " >< span class = " text-gray-400 mt-0.5 " >& #9654;</span> <span class="text-gray-700">WEBM_OPUS, 48kHz, 2ch 인코딩</span></div>
< div class = " flex items-start gap-2 " >< span class = " text-gray-400 mt-0.5 " >& #9654;</span> <span class="text-gray-700">V2 실패 시 자동 폴백으로 안정성 확보</span></div>
</ div >
< div class = " mt-3 text-xs text-gray-500 font-medium " > 메서드 : speechToTextWithDiarization () </ div >
</ div >
</ div >
{{ -- 자동 폴백 플로우 -- }}
< div class = " text-sm font-medium text-gray-700 mb-3 " > 자동 폴백 흐름 ( speechToTextWithDiarizationAuto ) </ div >
< div class = " gai-flow " style = " margin-bottom: 16px; " >
@ php
$sttFlow = [
[ 'num' => 1 , 'title' => 'GCS 업로드' , 'desc' => '오디오 → gs://' , 'color' => '#ea4335' ],
[ 'num' => 2 , 'title' => 'V2 Chirp 2' , 'desc' => '최신 모델 시도' , 'color' => '#4285f4' ],
[ 'num' => 3 , 'title' => '성공?' , 'desc' => '결과 확인' , 'color' => '#fbbc04' ],
[ 'num' => 4 , 'title' => 'V1 폴백' , 'desc' => '실패 시 V1' , 'color' => '#34a853' ],
[ 'num' => 5 , 'title' => '파싱' , 'desc' => '화자별 세그먼트' , 'color' => '#4285f4' ],
];
@ endphp
@ foreach ( $sttFlow as $step )
< div class = " gai-flow-item " >
< div class = " gai-flow-num " style = " background: { { $step['color'] }}; " > {{ $step [ 'num' ] }} </ div >
< div class = " font-semibold text-gray-800 text-sm " > {{ $step [ 'title' ] }} </ div >
< div class = " text-xs text-gray-500 mt-1 " > {{ $step [ 'desc' ] }} </ div >
</ div >
@ endforeach
</ div >
{{ -- Speaker Diarization 설명 -- }}
< div class = " p-4 bg-amber-50 border border-amber-200 rounded-lg " >
< div class = " flex items-center gap-2 mb-2 " >
< svg class = " w-4 h-4 text-amber-600 " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z " /></ svg >
< span class = " font-semibold text-amber-800 text-sm " > Speaker Diarization & mdash ; 화자 분리 </ span >
</ div >
< p class = " text-xs text-gray-600 leading-relaxed " > 회의 녹음에서 각 발화자를 자동 식별합니다 . 최소 2 명 ~ 최대 6 명까지 지원하며 , 결과는 < code class = " px-1 py-0.5 bg-amber-100 rounded text-xs " > [ 화자 1 ] 텍스트 </ code > 형태의 세그먼트로 반환됩니다 . SentencePiece 토크나이저 결과를 자연어로 재결합하는 후처리가 포함됩니다 .</ p >
</ div >
</ div >
</ div >
{{ -- ─── Section 3 : 회의록 자동 생성 시스템 ─── -- }}
< div class = " gai-card " >
< div class = " gai-card-header " >
< div class = " flex items-center gap-2 " >
< div class = " gai-icon-circle " style = " width: 28px; height: 28px; background: #34a853; " >
< svg class = " w-3.5 h-3.5 text-white " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z " /></ svg >
</ div >
< div >
< h2 class = " text-base font-semibold text-gray-800 " > 회의록 자동 생성 시스템 </ h2 >
< p class = " text-xs text-gray-400 mt-0.5 " > MeetingMinuteService & mdash ; 녹음 & rarr ; STT & rarr ; Gemini 요약 </ p >
</ div >
</ div >
</ div >
< div class = " p-5 " >
{{ -- 처리 플로우 -- }}
< div class = " gai-flow mb-5 " >
@ php
$meetingFlow = [
[ 'num' => 1 , 'title' => '녹음' , 'desc' => '브라우저 WebRTC' , 'color' => '#ea4335' ],
[ 'num' => 2 , 'title' => 'GCS 업로드' , 'desc' => '오디오 백업' , 'color' => '#fbbc04' ],
[ 'num' => 3 , 'title' => 'STT 변환' , 'desc' => '화자 분리 포함' , 'color' => '#4285f4' ],
[ 'num' => 4 , 'title' => 'Gemini 요약' , 'desc' => 'AI 자동 요약' , 'color' => '#34a853' ],
[ 'num' => 5 , 'title' => '회의록 저장' , 'desc' => 'DB 기록' , 'color' => '#9334e9' ],
];
@ endphp
@ foreach ( $meetingFlow as $step )
< div class = " gai-flow-item " >
< div class = " gai-flow-num " style = " background: { { $step['color'] }}; " > {{ $step [ 'num' ] }} </ div >
< div class = " font-semibold text-gray-800 text-sm " > {{ $step [ 'title' ] }} </ div >
< div class = " text-xs text-gray-500 mt-1 " > {{ $step [ 'desc' ] }} </ div >
</ div >
@ endforeach
</ div >
{{ -- 기능 카드 -- }}
< div class = " flex gap-4 " style = " flex-wrap: wrap; " >
< div class = " p-4 bg-green-50 border border-green-200 rounded-lg " style = " flex: 1 1 200px; " >
< div class = " font-semibold text-gray-800 text-sm mb-2 " > 핵심 기능 </ div >
< div class = " space-y-1.5 text-xs text-gray-600 " >
< div class = " flex items-center gap-1.5 " >< span class = " text-green-500 " >& #10003;</span> 브라우저 내 실시간 녹음 (WebM/Opus)</div>
< div class = " flex items-center gap-1.5 " >< span class = " text-green-500 " >& #10003;</span> 화자별 발화 자동 분리 (2~6명)</div>
< div class = " flex items-center gap-1.5 " >< span class = " text-green-500 " >& #10003;</span> Gemini AI 회의 내용 자동 요약</div>
< div class = " flex items-center gap-1.5 " >< span class = " text-green-500 " >& #10003;</span> 회의록 검색/필터/페이지네이션</div>
< div class = " flex items-center gap-1.5 " >< span class = " text-green-500 " >& #10003;</span> 화자 이름 수동 편집 기능</div>
</ div >
</ div >
< div class = " p-4 bg-blue-50 border border-blue-200 rounded-lg " style = " flex: 1 1 200px; " >
< div class = " font-semibold text-gray-800 text-sm mb-2 " > 데이터 구조 </ div >
< div class = " space-y-1.5 text-xs text-gray-600 " >
< div >< code class = " px-1 py-0.5 bg-blue-100 rounded " > meeting_minutes </ code > 회의 메타 정보 </ div >
< div >< code class = " px-1 py-0.5 bg-blue-100 rounded " > meeting_minute_segments </ code > 화자별 세그먼트 </ div >
< div > 상태 : draft & rarr ; recording & rarr ; processing & rarr ; completed </ div >
< div > GCS URI로 원본 오디오 보관 </ div >
< div > full_transcript + ai_summary 저장 </ div >
</ div >
</ div >
< div class = " p-4 bg-purple-50 border border-purple-200 rounded-lg " style = " flex: 1 1 200px; " >
< div class = " font-semibold text-gray-800 text-sm mb-2 " > 사용되는 API </ div >
< div class = " space-y-1.5 text-xs text-gray-600 " >
< div >< span class = " gai-badge gai-badge-blue " style = " font-size: 10px; " > STT </ span > Speech - to - Text V2 </ div >
< div >< span class = " gai-badge gai-badge-green " style = " font-size: 10px; " > AI </ span > Gemini 2.0 Flash </ div >
< div >< span class = " gai-badge gai-badge-amber " style = " font-size: 10px; " > GCS </ span > Cloud Storage </ div >
< div class = " text-gray-400 mt-1 " > 인증 : Service Account ( OAuth 2.0 ) </ div >
</ div >
</ div >
</ div >
</ div >
</ div >
{{ -- ─── Section 4 : 음성 녹음 분석 ─── -- }}
< div class = " gai-card " >
< div class = " gai-card-header " >
< div class = " flex items-center gap-2 " >
< div class = " gai-icon-circle " style = " width: 28px; height: 28px; background: #ea4335; " >
< svg class = " w-3.5 h-3.5 text-white " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z " /></ svg >
</ div >
< div >
< h2 class = " text-base font-semibold text-gray-800 " > 음성 녹음 분석 </ h2 >
< p class = " text-xs text-gray-400 mt-0.5 " > AiVoiceRecordingService & mdash ; 녹음 & rarr ; STT & rarr ; Gemini 분석 </ p >
</ div >
</ div >
</ div >
< div class = " p-5 " >
< div class = " flex gap-4 " style = " flex-wrap: wrap; " >
< div style = " flex: 1 1 340px; " >
< div class = " text-sm font-medium text-gray-700 mb-3 " > 처리 파이프라인 </ div >
< div class = " space-y-3 " >
@ php
$pipeline = [
[ 'step' => '1. 오디오 수신' , 'desc' => 'Base64 인코딩된 WebM/Opus 오디오를 수신' , 'icon' => '🔊' ],
[ 'step' => '2. GCS 업로드' , 'desc' => 'Google Cloud Storage에 원본 백업 (gs://bucket/recordings/...)' , 'icon' => '☁' ],
[ 'step' => '3. STT 변환' , 'desc' => 'V2 Chirp 2 → V1 자동 폴백으로 텍스트 변환' , 'icon' => '💬' ],
[ 'step' => '4. Gemini 분석' , 'desc' => 'AI가 음성 내용을 분석/요약하여 인사이트 생성' , 'icon' => '🤖' ],
[ 'step' => '5. 결과 저장' , 'desc' => 'transcript_text + analysis_text를 DB에 저장' , 'icon' => '💾' ],
];
@ endphp
@ foreach ( $pipeline as $p )
< div class = " flex items-start gap-3 p-3 bg-gray-50 rounded-lg " >
< span class = " text-lg shrink-0 " > {{ $p [ 'icon' ] }} </ span >
< div >
< div class = " font-semibold text-gray-800 text-sm " > {{ $p [ 'step' ] }} </ div >
< div class = " text-xs text-gray-500 mt-0.5 " > {{ $p [ 'desc' ] }} </ div >
</ div >
</ div >
@ endforeach
</ div >
</ div >
< div style = " flex: 1 1 280px; " >
< div class = " text-sm font-medium text-gray-700 mb-3 " > 인터뷰 템플릿 기능 </ div >
< div class = " p-4 bg-red-50 border border-red-200 rounded-lg mb-3 " >
< p class = " text-xs text-gray-600 leading-relaxed " > 음성 녹음 시 < strong > 인터뷰 템플릿 </ strong > 을 선택하면 , Gemini가 해당 템플릿의 질문 항목에 맞춰 음성 내용을 구조화된 분석 결과로 변환합니다 .</ p >
</ div >
< div class = " text-sm font-medium text-gray-700 mb-2 " > 데이터 모델 </ div >
< table class = " w-full text-xs " >
< tbody >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-2 font-medium text-gray-700 " > 테이블 </ td >
< td class = " py-2 px-2 text-gray-500 font-mono " > ai_voice_recordings </ td >
</ tr >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-2 font-medium text-gray-700 " > 상태값 </ td >
< td class = " py-2 px-2 text-gray-500 " > pending & rarr ; processing & rarr ; completed / failed </ td >
</ tr >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-2 font-medium text-gray-700 " > 저장 항목 </ td >
< td class = " py-2 px-2 text-gray-500 " > GCS URI , 원본 텍스트 , 분석 결과 , 소요 시간 </ td >
</ tr >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-2 font-medium text-gray-700 " > 파일 보관 </ td >
< td class = " py-2 px-2 text-gray-500 " > 생성일로부터 7 일 ( file_expiry_date ) </ td >
</ tr >
</ tbody >
</ table >
</ div >
</ div >
</ div >
</ div >
{{ -- ─── Section 5 : Gemini AI 활용 ─── -- }}
< div class = " gai-card " >
< div class = " gai-card-header " >
< div class = " flex items-center gap-2 " >
< div class = " gai-icon-circle " style = " width: 28px; height: 28px; background: #fbbc04; " >
< svg class = " w-3.5 h-3.5 text-white " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z " /></ svg >
</ div >
< div >
< h2 class = " text-base font-semibold text-gray-800 " > Gemini AI 활용 </ h2 >
< p class = " text-xs text-gray-400 mt-0.5 " > Vertex AI & mdash ; 재무 분석 리포트 , 회의 요약 , 명함 OCR </ p >
</ div >
</ div >
</ div >
< div class = " p-5 " >
< div class = " flex gap-4 mb-5 " style = " flex-wrap: wrap; " >
{{ -- 재무 분석 -- }}
< div class = " gai-service-card border-emerald-200 bg-emerald-50 " style = " flex: 1 1 260px; " >
< div class = " flex items-center gap-2 mb-2 " >
< span class = " gai-badge gai-badge-green " > 운영중 </ span >
< span class = " font-semibold text-gray-800 text-sm " > AI 재무 분석 리포트 </ span >
</ div >
< p class = " text-xs text-gray-600 mb-3 " > 테넌트의 비즈니스 데이터 ( 지출 , 매출 , 매입 , 입출금 , 카드 / 계좌 , 미수금 ) 를 자동 수집하여 일간 / 주간 / 월간 분석 리포트를 생성합니다 .</ p >
< div class = " space-y-1 text-xs text-gray-500 " >
< div >< strong > 서비스 :</ strong > AiReportService ( API 프로젝트 ) </ div >
2026-03-03 08:09:06 +09:00
< div >< strong > 모델 :</ strong > gemini - 2.5 - flash ( Vertex AI ) </ div >
2026-03-02 14:48:42 +09:00
< div >< strong > 분석 영역 :</ strong > 지출 , 매출 , 매입 , 입출금 , 카드 / 계좌 , 미수금 </ div >
< div >< strong > API :</ strong > < code class = " px-1 bg-emerald-100 rounded " > POST / v1 / reports / ai / generate </ code ></ div >
</ div >
</ div >
{{ -- 회의 요약 -- }}
< div class = " gai-service-card border-blue-200 bg-blue-50 " style = " flex: 1 1 260px; " >
< div class = " flex items-center gap-2 mb-2 " >
< span class = " gai-badge gai-badge-blue " > 운영중 </ span >
< span class = " font-semibold text-gray-800 text-sm " > 회의 내용 AI 요약 </ span >
</ div >
< p class = " text-xs text-gray-600 mb-3 " > STT로 변환된 회의 전문을 Gemini에 전달하여 핵심 내용 , 결정 사항 , 후속 조치 항목을 자동으로 요약합니다 .</ p >
< div class = " space-y-1 text-xs text-gray-500 " >
< div >< strong > 서비스 :</ strong > MeetingMinuteService ( MNG ) </ div >
2026-03-03 08:09:06 +09:00
< div >< strong > 모델 :</ strong > gemini - 2.5 - flash </ div >
2026-03-02 14:48:42 +09:00
< div >< strong > 입력 :</ strong > 화자별 세그먼트 전체 텍스트 </ div >
< div >< strong > 출력 :</ strong > ai_summary 필드에 저장 </ div >
</ div >
</ div >
{{ -- 명함 OCR -- }}
< div class = " gai-service-card border-purple-200 bg-purple-50 " style = " flex: 1 1 260px; " >
< div class = " flex items-center gap-2 mb-2 " >
< span class = " gai-badge gai-badge-purple " > 운영중 </ span >
< span class = " font-semibold text-gray-800 text-sm " > 명함 OCR </ span >
</ div >
< p class = " text-xs text-gray-600 mb-3 " > 명함 이미지를 Gemini Vision에 전달하여 이름 , 직함 , 회사 , 전화번호 , 이메일 등을 자동 추출합니다 .</ p >
< div class = " space-y-1 text-xs text-gray-500 " >
< div >< strong > 서비스 :</ strong > GeminiService ( MNG ) </ div >
< div >< strong > 메서드 :</ strong > extractBusinessCard () </ div >
< div >< strong > 입력 :</ strong > 명함 이미지 파일 </ div >
< div >< strong > 출력 :</ strong > 구조화된 연락처 정보 JSON </ div >
</ div >
</ div >
</ div >
{{ -- 토큰 사용량 추적 -- }}
< div class = " p-4 bg-amber-50 border border-amber-200 rounded-lg " >
< div class = " flex items-center gap-2 mb-2 " >
< svg class = " w-4 h-4 text-amber-600 " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z " /></ svg >
< span class = " font-semibold text-amber-800 text-sm " > 토큰 사용량 & amp ; 비용 추적 ( AiTokenHelper ) </ span >
</ div >
< div class = " flex gap-4 " style = " flex-wrap: wrap; " >
< div class = " text-xs text-gray-600 " style = " flex: 1 1 200px; " >
< p class = " mb-2 " > 모든 Gemini API 호출 시 토큰 사용량과 비용을 자동으로 기록합니다 .</ p >
< div class = " space-y-1 " >
< div >< strong > 테이블 :</ strong > < code class = " px-1 bg-amber-100 rounded " > ai_token_usages </ code ></ div >
< div >< strong > 기록 항목 :</ strong > provider , model , menu , input / output tokens </ div >
< div >< strong > 비용 계산 :</ strong > < code class = " px-1 bg-amber-100 rounded " > ai_pricing_configs </ code > 테이블의 단가 참조 </ div >
</ div >
</ div >
< div class = " text-xs text-gray-600 " style = " flex: 1 1 200px; " >
< div class = " font-medium text-gray-700 mb-1 " > 비용 계산 흐름 </ div >
< div class = " gai-code " style = " font-size: 11px; " > AiTokenHelper :: record (
provider : 'gemini' ,
2026-03-03 08:09:06 +09:00
model : 'gemini-2.5-flash' ,
2026-03-02 14:48:42 +09:00
menu : 'meeting-minutes' ,
inputTokens : 1520 ,
outputTokens : 350 ,
costUsd : 0.00012
); </ div >
</ div >
</ div >
</ div >
</ div >
</ div >
{{ -- ─── Section 6 : Cloud Storage ( GCS ) ─── -- }}
< div class = " gai-card " >
< div class = " gai-card-header " >
< div class = " flex items-center gap-2 " >
< div class = " gai-icon-circle " style = " width: 28px; height: 28px; background: #0f9d58; " >
< svg class = " w-3.5 h-3.5 text-white " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4 " /></ svg >
</ div >
< div >
< h2 class = " text-base font-semibold text-gray-800 " > Cloud Storage ( GCS ) </ h2 >
< p class = " text-xs text-gray-400 mt-0.5 " > GoogleCloudStorageService & mdash ; 파일 업로드 , 다운로드 , 서명 URL </ p >
</ div >
</ div >
</ div >
< div class = " p-5 " >
< div class = " flex gap-4 " style = " flex-wrap: wrap; " >
{{ -- 용도별 정리 -- }}
< div style = " flex: 1 1 320px; " >
< div class = " text-sm font-medium text-gray-700 mb-3 " > SAM에서의 GCS 활용 </ div >
< table class = " w-full text-sm " >
< thead >
< tr class = " border-b-2 border-gray-200 " >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " > 용도 </ th >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " > 저장 경로 </ th >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " > 설명 </ th >
</ tr >
</ thead >
< tbody >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-3 font-medium text-gray-800 text-xs " > 회의록 녹음 </ td >
< td class = " py-2 px-3 text-xs text-gray-500 font-mono " > meetings / { tenant } / { id } /</ td >
< td class = " py-2 px-3 text-xs text-gray-500 " > WebM 오디오 원본 </ td >
</ tr >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-3 font-medium text-gray-800 text-xs " > 음성 녹음 </ td >
< td class = " py-2 px-3 text-xs text-gray-500 font-mono " > recordings / { tenant } /</ td >
< td class = " py-2 px-3 text-xs text-gray-500 " > 분석용 음성 파일 </ td >
</ tr >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-3 font-medium text-gray-800 text-xs " > 상담 음성 </ td >
< td class = " py-2 px-3 text-xs text-gray-500 font-mono " > consultations / { tenant } /</ td >
< td class = " py-2 px-3 text-xs text-gray-500 " > 10 MB 이상 자동 백업 </ td >
</ tr >
</ tbody >
</ table >
</ div >
{{ -- 서비스 메서드 -- }}
< div style = " flex: 1 1 280px; " >
< div class = " text-sm font-medium text-gray-700 mb-3 " > 주요 메서드 ( 2 개 서비스 ) </ div >
< div class = " space-y-3 " >
< div class = " p-3 bg-green-50 border border-green-200 rounded-lg " >
< div class = " text-xs font-bold text-green-800 mb-1 " > GoogleCloudService ( MNG ) </ div >
< div class = " space-y-1 text-xs text-gray-600 " >
< div >< code class = " bg-green-100 px-1 rounded " > uploadToStorage () </ code > 로컬 & rarr ; GCS </ div >
< div >< code class = " bg-green-100 px-1 rounded " > uploadBase64Audio () </ code > Base64 & rarr ; GCS </ div >
< div >< code class = " bg-green-100 px-1 rounded " > downloadFromStorage () </ code > GCS & rarr ; 스트림 </ div >
< div >< code class = " bg-green-100 px-1 rounded " > deleteFromStorage () </ code > GCS 파일 삭제 </ div >
</ div >
</ div >
< div class = " p-3 bg-cyan-50 border border-cyan-200 rounded-lg " >
< div class = " text-xs font-bold text-cyan-800 mb-1 " > GoogleCloudStorageService ( MNG ) </ div >
< div class = " space-y-1 text-xs text-gray-600 " >
< div >< code class = " bg-cyan-100 px-1 rounded " > upload () </ code > 파일 업로드 ( URI 반환 ) </ div >
< div >< code class = " bg-cyan-100 px-1 rounded " > getSignedUrl () </ code > 서명 다운로드 URL ( 60 분 ) </ div >
< div >< code class = " bg-cyan-100 px-1 rounded " > delete () </ code > 파일 삭제 </ div >
< div >< code class = " bg-cyan-100 px-1 rounded " > isAvailable () </ code > 사용 가능 여부 </ div >
</ div >
</ div >
</ div >
</ div >
</ div >
{{ -- 설정 우선순위 -- }}
< div class = " mt-4 p-4 bg-gray-50 border border-gray-200 rounded-lg " >
< div class = " text-sm font-medium text-gray-700 mb-2 " > GCS 설정 우선순위 </ div >
< div class = " gai-code " style = " font-size: 11px; " > 1. DB 설정 ( ai_configs 테이블의 활성화된 gcs provider )
↓ 없으면
2. 환경변수 ( . env : GCS_BUCKET_NAME , GCS_SERVICE_ACCOUNT_PATH )
↓ 없으면
3. 레거시 파일 ( / sales / apikey / gcs_config . txt , google_service_account . json ) </ div >
</ div >
</ div >
</ div >
{{ -- ─── Section 7 : AI 설정 관리 시스템 ─── -- }}
< div class = " gai-card " >
< div class = " gai-card-header " >
< div class = " flex items-center gap-2 " >
< div class = " gai-icon-circle " style = " width: 28px; height: 28px; background: #7c3aed; " >
< svg class = " w-3.5 h-3.5 text-white " fill = " none " stroke = " currentColor " viewBox = " 0 0 24 24 " >< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z " />< path stroke - linecap = " round " stroke - linejoin = " round " stroke - width = " 2 " d = " M15 12a3 3 0 11-6 0 3 3 0 016 0z " /></ svg >
</ div >
< div >
< h2 class = " text-base font-semibold text-gray-800 " > AI 설정 관리 시스템 </ h2 >
< p class = " text-xs text-gray-400 mt-0.5 " > AiConfig & mdash ; 다중 Provider 관리 , 연결 테스트 , 토글 활성화 </ p >
</ div >
</ div >
</ div >
< div class = " p-5 " >
{{ -- Provider 테이블 -- }}
< div class = " text-sm font-medium text-gray-700 mb-3 " > 지원 Provider </ div >
< div class = " flex gap-4 mb-5 " style = " flex-wrap: wrap; " >
@ php
$providers = [
2026-03-03 08:09:06 +09:00
[ 'name' => 'Gemini' , 'provider' => 'gemini' , 'model' => 'gemini-2.5-flash' , 'use' => '명함 OCR, 회의 요약, 음성 분석' , 'color' => 'blue' , 'auth' => 'Vertex AI / API Key' ],
2026-03-02 14:48:42 +09:00
[ 'name' => 'Claude' , 'provider' => 'claude' , 'model' => 'claude-sonnet-4-20250514' , 'use' => 'AI 재무 분석 (예비)' , 'color' => 'purple' , 'auth' => 'API Key' ],
[ 'name' => 'OpenAI' , 'provider' => 'openai' , 'model' => 'gpt-4o' , 'use' => '범용 AI (예비)' , 'color' => 'green' , 'auth' => 'API Key' ],
[ 'name' => 'GCS' , 'provider' => 'gcs' , 'model' => '—' , 'use' => '음성 녹음 백업, 파일 저장' , 'color' => 'cyan' , 'auth' => 'Service Account' ],
];
@ endphp
@ foreach ( $providers as $prov )
< div class = " p-3 border rounded-lg " style = " flex: 1 1 220px; border-color: var(--tw-border-opacity, 1); { { $prov['color'] === 'blue' ? 'border-color: #93c5fd; background: #eff6ff;' : ( $prov['color'] === 'purple' ? 'border-color: #c4b5fd; background: #f5f3ff;' : ( $prov['color'] === 'green' ? 'border-color: #86efac; background: #f0fdf4;' : 'border-color: #67e8f9; background: #ecfeff;')) }} " >
< div class = " flex items-center gap-2 mb-2 " >
< span class = " gai-badge gai-badge- { { $prov['color'] }} " > {{ $prov [ 'name' ] }} </ span >
< span class = " text-xs text-gray-400 font-mono " > {{ $prov [ 'provider' ] }} </ span >
</ div >
< div class = " space-y-1 text-xs text-gray-600 " >
< div >< strong > 모델 :</ strong > {{ $prov [ 'model' ] }} </ div >
< div >< strong > 용도 :</ strong > {{ $prov [ 'use' ] }} </ div >
< div >< strong > 인증 :</ strong > {{ $prov [ 'auth' ] }} </ div >
</ div >
</ div >
@ endforeach
</ div >
{{ -- DB 구조 -- }}
< div class = " text-sm font-medium text-gray-700 mb-2 " > 데이터베이스 구조 </ div >
< table class = " w-full text-sm mb-4 " >
< thead >
< tr class = " border-b-2 border-gray-200 " >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " style = " width: 25%; " > 테이블 </ th >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " style = " width: 30%; " > 설명 </ th >
< th class = " text-left py-2 px-3 text-gray-600 font-medium " > 주요 컬럼 </ th >
</ tr >
</ thead >
< tbody >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-3 font-mono text-xs text-gray-800 " > ai_configs </ td >
< td class = " py-2 px-3 text-xs text-gray-600 " > Provider별 설정 </ td >
< td class = " py-2 px-3 text-xs text-gray-500 " > name , provider , api_key , model , is_active , options ( JSON ) </ td >
</ tr >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-3 font-mono text-xs text-gray-800 " > ai_token_usages </ td >
< td class = " py-2 px-3 text-xs text-gray-600 " > 토큰 사용량 추적 </ td >
< td class = " py-2 px-3 text-xs text-gray-500 " > provider , model , menu , input / output_tokens , cost_usd , cost_krw </ td >
</ tr >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-3 font-mono text-xs text-gray-800 " > ai_pricing_configs </ td >
< td class = " py-2 px-3 text-xs text-gray-600 " > 모델별 단가 설정 </ td >
< td class = " py-2 px-3 text-xs text-gray-500 " > provider , model , input_price_per_1m , output_price_per_1m </ td >
</ tr >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-3 font-mono text-xs text-gray-800 " > ai_reports </ td >
< td class = " py-2 px-3 text-xs text-gray-600 " > AI 분석 리포트 </ td >
< td class = " py-2 px-3 text-xs text-gray-500 " > report_type ( daily / weekly / monthly ), content , status </ td >
</ tr >
< tr class = " border-b border-gray-100 " >
< td class = " py-2 px-3 font-mono text-xs text-gray-800 " > ai_voice_recordings </ td >
< td class = " py-2 px-3 text-xs text-gray-600 " > 음성 녹음 </ td >
< td class = " py-2 px-3 text-xs text-gray-500 " > gcs_uri , transcript_text , analysis_text , duration_seconds </ td >
</ tr >
</ tbody >
</ table >
{{ -- 관리 UI 안내 -- }}
< div class = " gai-quote " >
< span class = " text-sm text-blue-800 " > AI 설정 관리 페이지 : < strong > 시스템 관리 & gt ; AI 설정 </ strong > ( < code class = " px-1 bg-blue-100 rounded text-xs " >/ system / ai - config </ code > ) & mdash ; Provider별 추가 / 수정 / 삭제 , 활성화 토글 , 연결 테스트 가능 </ span >
</ div >
</ div >
</ div >
{{ -- ─── Section 8 : 관련 소스 파일 정리 ─── -- }}
< div class = " gai-card " style = " border-color: #c7d2fe; " >
< div class = " gai-card-header " style = " background: #eff6ff; border-bottom-color: #dbeafe; " >
< h2 class = " text-base font-semibold text-blue-900 " > 관련 소스 파일 & amp ; 문서 </ h2 >
< p class = " text-xs text-blue-400 mt-0.5 " > SAM Google Cloud AI 관련 전체 파일 매핑 </ p >
</ div >
< div class = " p-5 " >
< div class = " flex gap-5 " style = " flex-wrap: wrap; " >
{{ -- 서비스 파일 -- }}
< div style = " flex: 1 1 300px; " >
< div class = " flex items-center gap-2 mb-3 " >
< span class = " gai-badge gai-badge-blue " > 서비스 ( MNG ) </ span >
</ div >
< div class = " space-y-2 " >
@ php
$mngFiles = [
[ 'file' => 'app/Services/GoogleCloudService.php' , 'desc' => 'STT V1/V2, Speaker Diarization, GCS 업로드/다운로드' ],
[ 'file' => 'app/Services/GoogleCloudStorageService.php' , 'desc' => 'GCS 전용 서비스 (서명 URL, 설정 우선순위)' ],
[ 'file' => 'app/Services/MeetingMinuteService.php' , 'desc' => '회의록 생성/수정/삭제, STT+Gemini 파이프라인' ],
[ 'file' => 'app/Services/AiVoiceRecordingService.php' , 'desc' => '음성 녹음 처리, 인터뷰 템플릿 분석' ],
[ 'file' => 'app/Services/GeminiService.php' , 'desc' => 'Gemini API 호출 (명함 OCR 등)' ],
[ 'file' => 'app/Helpers/AiTokenHelper.php' , 'desc' => '토큰 사용량 기록, 비용 계산 (USD/KRW)' ],
];
@ endphp
@ foreach ( $mngFiles as $f )
< div class = " p-2.5 bg-blue-50 border border-blue-100 rounded-lg " >
< div class = " font-mono text-xs text-blue-800 " > {{ $f [ 'file' ] }} </ div >
< div class = " text-xs text-gray-500 mt-0.5 " > {{ $f [ 'desc' ] }} </ div >
</ div >
@ endforeach
</ div >
</ div >
{{ -- 모델 & API 파일 -- }}
< div style = " flex: 1 1 300px; " >
< div class = " flex items-center gap-2 mb-3 " >
< span class = " gai-badge gai-badge-purple " > 모델 & amp ; API </ span >
</ div >
< div class = " space-y-2 " >
@ php
$modelFiles = [
[ 'file' => 'app/Models/System/AiConfig.php' , 'desc' => 'AI 설정 모델 (Provider별 활성 조회)' ],
[ 'file' => 'app/Models/Juil/MeetingMinute.php' , 'desc' => '회의록 모델 (상태 관리, 관계)' ],
[ 'file' => 'app/Models/AiVoiceRecording.php' , 'desc' => '음성 녹음 모델 (파일 만료, 상태)' ],
];
$apiFiles = [
[ 'file' => 'api/app/Services/AiReportService.php' , 'desc' => '재무 분석 리포트 생성 (Gemini Vertex AI)' ],
[ 'file' => 'config/gcs.php' , 'desc' => 'GCS 환경변수 설정 매핑' ],
[ 'file' => 'config/services.php' , 'desc' => 'Google Cloud 서비스 설정 (credentials, bucket)' ],
];
@ endphp
@ foreach ( $modelFiles as $f )
< div class = " p-2.5 bg-purple-50 border border-purple-100 rounded-lg " >
< div class = " font-mono text-xs text-purple-800 " > {{ $f [ 'file' ] }} </ div >
< div class = " text-xs text-gray-500 mt-0.5 " > {{ $f [ 'desc' ] }} </ div >
</ div >
@ endforeach
@ foreach ( $apiFiles as $f )
< div class = " p-2.5 bg-green-50 border border-green-100 rounded-lg " >
< div class = " font-mono text-xs text-green-800 " > {{ $f [ 'file' ] }} </ div >
< div class = " text-xs text-gray-500 mt-0.5 " > {{ $f [ 'desc' ] }} </ div >
</ div >
@ endforeach
< div class = " flex items-center gap-2 mt-3 mb-2 " >
< span class = " gai-badge gai-badge-gray " > 문서 </ span >
</ div >
< div class = " p-2.5 bg-gray-50 border border-gray-200 rounded-lg " >
< div class = " font-mono text-xs text-gray-700 " > docs / guides / ai - config - settings . md </ div >
< div class = " text-xs text-gray-500 mt-0.5 " > AI 및 스토리지 설정 기술문서 </ div >
</ div >
< div class = " p-2.5 bg-gray-50 border border-gray-200 rounded-lg " >
< div class = " font-mono text-xs text-gray-700 " > docs / features / ai / README . md </ div >
< div class = " text-xs text-gray-500 mt-0.5 " > AI 분석 리포트 기능 명세 </ div >
</ div >
</ div >
</ div >
</ div >
{{ -- 한 줄 요약 -- }}
< div class = " mt-6 p-4 bg-blue-50 border border-blue-200 rounded-lg text-center " >
< div class = " text-lg font-bold text-blue-900 " >
Google Cloud AI & mdash ; SAM의 핵심 자동화 엔진
</ div >
< p class = " text-sm text-blue-600 mt-2 " > Speech - to - Text + Gemini + Cloud Storage = 음성 / 문서 / 분석 완전 자동화 </ p >
< p class = " text-xs text-blue-400 mt-1 " > ( 주 ) 코드브릿지엑스 | @ codebridge - x . com </ p >
</ div >
</ div >
</ div >
</ div >
@ endsection