Files
lms-web-fe/src/lms-renderer/features/platforms/platformControl.ts
T
2026-08-03 14:06:06 +09:00

106 lines
4.3 KiB
TypeScript

import { LMS_API_BASE_URL } from '../../config/appConfig'
import type { PlatformControlActionResponse, PlatformOption } from './types'
type AuthFetch = (input: RequestInfo | URL, init?: RequestInit, options?: { invalidateOnRefreshFailure?: boolean }) => Promise<Response>
export type PlatformControlWarningPayload = {
type: 'platform.control.warning'
sessionId: string
platformId?: string | null
instructorPlatformId?: string | null
endsAt: string
warningAt: string
}
export type PlatformControlGrantedPayload = {
type: 'platform.control.granted'
sessionId: string
startedAt: string
endsAt: string
warningAt: string
}
export type PlatformControlTerminatedPayload = {
type: 'platform.control.terminated'
sessionId: string
platformId?: string | null
instructorPlatformId?: string | null
reason: string
message: string
endedAt: string
}
export function isPlatformUnavailable(platform: PlatformOption): boolean {
return (
platform.state === 'locked' ||
platform.action === '연결 불가' ||
platform.status.includes('연결 불가') ||
platform.status.includes('연결 끊김') ||
(platform.connection ? !platform.connection.headscaleOnline || !platform.connection.agentHealthy : false)
)
}
export function getPlatformDotClass(platform: PlatformOption): string {
if (isPlatformUnavailable(platform)) return 'bg-[#ef4444] shadow-[0_0_6px_rgba(239,68,68,0.55)]'
if (platform.state === 'reserved' || platform.control?.status === 'QUEUED') return 'bg-[#f59e0b] shadow-[0_0_6px_rgba(245,158,11,0.55)]'
return 'bg-[#2fbda0] shadow-[0_0_6px_rgba(47,189,160,0.55)]'
}
export async function fetchPlatformStatuses(fetchWithFreshAuth: AuthFetch, platformIds: string[]): Promise<Array<Partial<PlatformOption> & { id: string }>> {
const response = await fetchWithFreshAuth(`${LMS_API_BASE_URL}/platform-control/platforms/statuses`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ platformIds })
}, { invalidateOnRefreshFailure: false })
if (!response.ok) return []
const payload = await response.json() as { platforms?: Array<Partial<PlatformOption> & { id: string }> }
return payload.platforms ?? []
}
export async function connectPlatformControl(fetchWithFreshAuth: AuthFetch, platformId: string): Promise<{ environmentConfigOverride?: unknown }> {
const response = await fetchWithFreshAuth(`${LMS_API_BASE_URL}/platform-control/platforms/${encodeURIComponent(platformId)}/connect`, {
method: 'POST',
})
if (!response.ok) throw new Error('platform-connect failed')
return response.json() as Promise<{ environmentConfigOverride?: unknown }>
}
export async function releasePlatformControl(fetchWithFreshAuth: AuthFetch, platformId: string): Promise<void> {
const response = await fetchWithFreshAuth(`${LMS_API_BASE_URL}/platform-control/platforms/${encodeURIComponent(platformId)}/release`, {
method: 'POST',
})
if (!response.ok) throw new Error('platform-release failed')
}
export async function extendPlatformControl(
fetchWithFreshAuth: AuthFetch,
platformId: string,
): Promise<PlatformControlActionResponse> {
const response = await fetchWithFreshAuth(`${LMS_API_BASE_URL}/platform-control/platforms/${encodeURIComponent(platformId)}/extend`, {
method: 'POST',
})
const payload = await response.json().catch(() => null) as PlatformControlActionResponse | { message?: string } | null
if (!response.ok) {
throw new Error(payload && 'message' in payload && payload.message ? payload.message : '제어 시간 연장에 실패했습니다.')
}
return payload as PlatformControlActionResponse
}
export async function requestOrCancelPlatformControl(
fetchWithFreshAuth: AuthFetch,
platform: PlatformOption
): Promise<{ method: 'POST' | 'DELETE'; payload: PlatformControlActionResponse | null }> {
const controlStatus = platform.control?.status
const method = controlStatus === 'QUEUED' ? 'DELETE' : 'POST'
const suffix = controlStatus === 'QUEUED' ? 'queue' : 'request'
const response = await fetchWithFreshAuth(`${LMS_API_BASE_URL}/platform-control/platforms/${encodeURIComponent(platform.id)}/${suffix}`, {
method,
})
if (!response.ok) throw new Error('platform-control failed')
const payload = await response.json().catch(() => null) as PlatformControlActionResponse | null
return { method, payload }
}