import { useState, useEffect } from 'react'; import { Card } from '../../shared/ui/Card'; import { apiClient } from '../../shared/api/client'; import { Info, Cpu, Database, Server, Hash, Calendar, RefreshCw, AlertTriangle, CheckCircle2, ChevronLeft, ChevronRight } from 'lucide-react'; interface VersionInfo { status: string; version: string; node_version: string; platform: string; arch: string; timestamp: string; } interface UpdateEntry { version: string; date: string; title: string; changes: string[]; type: 'feature' | 'fix' | 'urgent' | 'patch'; } interface RemoteVersion { current: string; latest: string | null; needsUpdate: boolean; latestInfo: UpdateEntry | null; history: UpdateEntry[]; error?: string; } export function VersionPage() { const [healthIcon, setHealthInfo] = useState(null); const [remoteInfo, setRemoteInfo] = useState(null); const [loading, setLoading] = useState(true); const [checkingRemote, setCheckingRemote] = useState(false); const [updating, setUpdating] = useState(false); const [updateResult, setUpdateResult] = useState<{ success: boolean; message: string } | null>(null); const [currentPage, setCurrentPage] = useState(1); const ITEMS_PER_PAGE = 5; const fetchVersion = async () => { setLoading(true); try { // Add timestamp to prevent caching const res = await apiClient.get(`/health?t=${Date.now()}`); setHealthInfo(res.data); } catch (err) { console.error('Failed to fetch version info', err); } finally { setLoading(false); } }; const fetchRemoteVersion = async () => { setCheckingRemote(true); try { const res = await apiClient.get(`/system/version/remote?t=${Date.now()}`); setRemoteInfo(res.data); } catch (err) { console.error('Failed to fetch remote version info', err); } finally { setCheckingRemote(false); setCurrentPage(1); } }; useEffect(() => { fetchVersion(); fetchRemoteVersion(); }, []); const handleUpdate = async () => { if (!remoteInfo?.latest) return; const info = remoteInfo.latestInfo; const changelog = info ? `\n\n[주요 변경 내역]\n${info.changes.map(c => `- ${c}`).join('\n')}` : ''; if (!confirm(`시스템을 v${info?.version || remoteInfo.latest} 버전으로 업데이트하시겠습니까?${changelog}\n\n업데이트 중에는 시스템이 일시적으로 중단될 수 있습니다.`)) { return; } setUpdating(true); setUpdateResult(null); try { const res = await apiClient.post('/system/version/update', { targetTag: remoteInfo.latest }); setUpdateResult({ success: true, message: res.data.message }); // Success: Wait a bit for server to settle, then refresh let countdown = 5; const timer = setInterval(() => { countdown -= 1; if (countdown <= 0) { clearInterval(timer); window.location.reload(); } else { setUpdateResult({ success: true, message: `${res.data.message} (${countdown}초 후 페이지가 새로고침됩니다.)` }); } }, 1000); } catch (err: any) { console.error('Update failed', err); setUpdateResult({ success: false, message: err.response?.data?.error || '업데이트 요청 중 오류가 발생했습니다.' }); setUpdating(false); } }; // Source of truth for versioning comes from the API const currentVersion = remoteInfo?.current || healthIcon?.version || '0.4.0.0'; const buildDate = '2026-01-25'; // IMPORTANT: needsUpdate should be true if remote has a higher version than local const needsUpdate = !!remoteInfo?.needsUpdate; return (

시스템 관리 - 버전 정보

플랫폼 및 서버의 현재 릴리즈 버전을 확인하고 업데이트를 관리합니다.

{/* Update Alert Banner - Enhanced Visibility with Details */} {needsUpdate && !updateResult && remoteInfo?.latestInfo && (

{remoteInfo.latestInfo.type === 'urgent' ? '신속한 시스템 업데이트가 필요합니다' : '새로운 플랫폼 기능이 준비되었습니다'}

{remoteInfo.latestInfo.type}

현재: v{currentVersion} 차기: {remoteInfo.latest}

{/* Detailed Changes from Tag Message */}

{remoteInfo.latestInfo.title}

    {remoteInfo.latestInfo.changes.map((c, i) => (
  • {c}
  • ))}
)} {/* Update Result Message */} {updateResult && (
{updateResult.success ? : }

{updateResult.message}

)}
{/* Frontend Platform Version */}

Frontend Platform

Smart IMS 클라이언트

현재 버전 v{currentVersion}
빌드 일자 {buildDate}
아키텍처 React Agentic Architecture
{/* Backend Server Version */}

Backend Core

IMS 서비스 엔진

런타임 환경 {loading ? 'Checking...' : healthIcon?.node_version ? `Node.js ${healthIcon.node_version}` : 'N/A'}
운영 체제 {loading ? '...' : healthIcon?.platform ? `${healthIcon.platform} (${healthIcon.arch})` : 'Unknown'}
서버 타임스탬프 {loading ? '...' : healthIcon?.timestamp || 'Unknown'}
엔진 상태 {loading ? '...' : healthIcon?.status === 'ok' ? 'Running' : 'Offline'}
{/* Remote Info Status (Debug/Info) */} {remoteInfo && (
원격 저장소 상태: {remoteInfo.error ? `오류 (${remoteInfo.error})` : '정상'}
{!remoteInfo.error && ( 최신 배포 태그: {remoteInfo.latest || '없음'} )}
)} {/* Release History Section */}

업데이트 히스토리

{remoteInfo?.history && remoteInfo.history.length > 0 ? ( <> {remoteInfo.history .slice((currentPage - 1) * ITEMS_PER_PAGE, currentPage * ITEMS_PER_PAGE) .map((entry, idx) => (
{entry.type} v{entry.version}

{entry.title}

{entry.date}
    {entry.changes.map((change, i) => (
  • {change}
  • ))}
))} {/* Pagination Controls */} {remoteInfo.history.length > ITEMS_PER_PAGE && (
{Array.from({ length: Math.ceil(Math.min(50, remoteInfo.history.length) / ITEMS_PER_PAGE) }).map((_, i) => ( ))}
)} ) : (
원격 저장소에서 업데이트 내역을 가져오는 중이거나 내역이 없습니다.
)}
{/* Bottom Integrity Banner */}

Platform Integrity

Smart IMS 플랫폼은 데이터 보안과 시스템 안정성을 최우선으로 설계되었습니다. 모든 모듈은 Sokuree 아키텍처 표준을 준수하며, 암호화 키 관리 시스템(L2 Protection)에 의해 보호되고 있습니다.

); } // Internal Local Components if not available in shared/ui function ShieldCheck({ size, className }: { size?: number, className?: string }) { return ( ); } function Box({ size, className }: { size?: number, className?: string }) { return ( ); }