chore : deploy
SpecialSource Frontend CD / deploy (push) Successful in 7s

This commit is contained in:
sungjin.choi
2026-07-14 11:23:13 +09:00
parent f65ea396b6
commit 21e2e34d01
+33 -34
View File
@@ -175,8 +175,8 @@ const todayUnique = ref(0);
const activeNow = ref(0);
let analyticsTimer = null;
// 🟢 [NEW] NAS 생존 여부 실시간 판단용 반응형 변수
const isNasOnline = ref(true);
// 🟢 [NEW] 워커 표지판을 담을 반응형 변수 (기본값: nas)
const currentServerSource = ref('nas');
const menuItems = [
{ id: 'main', name: 'HOME' },
@@ -188,36 +188,32 @@ const menuItems = [
const isLoggedIn = computed(() => !!authToken.value);
// 🟢 [NEW] 현재 활성화된 서버 판별 엔진 (시간 + API 생존 여부 조합)
const currentServerSource = computed(() => {
const currentHour = new Date().getUTCHours() + 9; // 한국 표준시(KST) 보정
const localHour = currentHour % 24;
// 1. 밤 12시 ~ 아침 8시 사이 (워커가 퇴근시키고 파이어베이스로 무조건 우회하는 정기 백업 시간대)
if (localHour >= 0 && localHour < 8) {
return 'firebase_backup';
}
// 2. 낮 시간대인데 NAS 통신이 끊겼거나 오류가 나서 파이어베이스 우회 대피소로 긴급 이동된 상태
if (!isNasOnline.value) {
return 'firebase_failover';
}
// 3. 낮 시간대에 NAS 서버가 건강하게 서비스를 전달하고 있는 최고 권한 메인 노드 상태
return 'nas_main';
});
// 🟢 [NEW] 터미널 콘솔 감성의 문자열 맵핑 출력 기믹
// 🟢 [NEW] 헤더 상태에 따른 터미널 UI 텍스트 변환
const currentServerSourceDisplay = computed(() => {
if (currentServerSource.value === 'firebase_backup') {
return 'NODE:FB_NIGHT_MODE';
if (currentServerSource.value === 'firebase_night') {
return 'HOST: FIREBASE (NIGHT)';
}
if (currentServerSource.value === 'firebase_failover') {
return 'NODE:FB_FAILOVER';
return 'HOST: FIREBASE (FAILOVER)';
}
return 'NODE:NAS_ACTIVE';
return 'HOST: GNET-NAS (LOCAL)';
});
// 🟢 [NEW] 워커가 날려준 'x-served-by' 헤더를 직접 읽어 판별하는 핵심 감지 엔진
const detectRealtimeServerSource = async () => {
try {
// 0바이트 짜리 초고속 HEAD 요청을 내 도메인으로 전송하여 헤더만 가볍게 긁어옴
const res = await fetch(window.location.origin, { method: 'HEAD' });
const servedBy = res.headers.get('x-served-by');
if (servedBy) {
currentServerSource.value = servedBy; // 'nas', 'firebase_night', 'firebase_failover' 적용
}
} catch (err) {
console.error("실시간 서버 소스 판별 실패:", err);
}
};
const rawAscii = `
███████╗██████╗ ███████╗ ██████╗██╗ █████╗ ██╗
██╔════╝██╔══██╗██╔════╝██╔════╝██║██╔══██╗██║
@@ -242,7 +238,6 @@ const formattedAscii = computed(() => {
return rawAscii.replace(/ /g, '<span class="bg-block">█</span>');
});
// 🟢 [MODIFY] 30초 간격으로 스펙을 긁어올 때 NAS가 건강하게 응답하는지 체크하는 유효성 로직 추가
const fetchAnalyticsData = async () => {
try {
const apiBaseUrl = import.meta.env.VITE_API_URL || '';
@@ -250,11 +245,9 @@ const fetchAnalyticsData = async () => {
if (res.data) {
todayUnique.value = res.data.todayUnique || 0;
activeNow.value = res.data.activeNow || 0;
isNasOnline.value = true; // 🟢 정상 동작 확인 -> 'NODE:NAS_ACTIVE' 출력 보장
}
} catch (err) {
console.error("관제 통계 데이터 로드 실패:", err);
isNasOnline.value = false; // 🟢 에러 발생 시 자동으로 비상망 배지('NODE:FB_FAILOVER')로 교체
}
};
@@ -403,9 +396,15 @@ const handleLoginSubmit = async () => {
onMounted(() => {
fetchVideos();
fetchAnalyticsData();
analyticsTimer = setInterval(fetchAnalyticsData, 30000);
// 🟢 [NEW] 부팅 시 표지판 헤더를 확인하여 소스지 즉시 감지
detectRealtimeServerSource();
analyticsTimer = setInterval(() => {
fetchAnalyticsData();
detectRealtimeServerSource(); // 30초마다 생존 여부 및 경로 실시간 트래킹
}, 30000);
const globaljQuery = window.$;
if (globaljQuery && terminalRef.value) {
@@ -563,13 +562,13 @@ onUnmounted(() => {
transition: 0.3s;
}
/* NAS 활성화 상태 (그린 계열/현재 테마 컬러 적용) */
.server-badge.nas_main {
.server-badge.nas {
color: var(--tui-color);
text-shadow: 0 0 5px var(--tui-glow);
border-color: var(--tui-border);
}
/* 정기 야간 Firebase 백업 작동 상태 (호박색) */
.server-badge.firebase_backup {
.server-badge.firebase_night {
color: #ffb000;
text-shadow: 0 0 5px rgba(255, 176, 0, 0.6);
border-color: rgba(255, 176, 0, 0.3);
@@ -818,7 +817,7 @@ iframe { width: 100%; height: 180px; border-radius: 4px; }
50% { opacity: 1; text-shadow: 0 0 8px var(--tui-glow); }
}
/* 🟢 [NEW] 비상 Failover 점멸 애니메이션 */
/* 🟢 [NEW] 비상 Failover 점멸 애니메이션 */
@keyframes badgeBlink {
0%, 100% { opacity: 0.6; box-shadow: 0 0 5px rgba(255, 59, 59, 0.2); }
50% { opacity: 1; box-shadow: 0 0 15px rgba(255, 59, 59, 0.6); text-shadow: 0 0 12px #ff3b3b; }