/* portal/usage/public/allocate.js — 서비스별 보장량 배정 변경(§13.3). 구매 총량·사용 중·다른 서비스 배정·예약·미배정·변경 후 값을 함께 보인다. */ (() => { const el = document.getElementById('alloc'); const subject = el.dataset.subject; const esc = aw.esc; const fmt = (n, unit) => (unit.startsWith('bytes') ? (n >= 1024 ** 3 ? (n / 1024 ** 3).toFixed(2) + ' GB' : n >= 1024 ** 2 ? (n / 1024 ** 2).toFixed(0) + ' MB' : n + ' B') : Number(n).toLocaleString('ko-KR')); const GB = 1024 ** 3; async function load() { try { const d = await aw.api('GET', `/api/usage/allocate/${encodeURIComponent(subject)}`); el.innerHTML = `

${esc(d.subject.label)} · ${esc(d.subject.name)}

월간 항목은 ${esc(d.nextResetText)} 에 초기화됩니다. 실제 사용량보다 작게 줄일 수 없고, 월간 항목은 이번 달 누적보다 작게 줄일 수 없습니다.

` + d.resources.map((r) => { const bytes = r.unit.startsWith('bytes'); const step = bytes ? GB : 1; return `

${esc(r.label)}${r.monthly ? ' (월간)' : ''}

구매 총량
${esc(r.texts.purchased)}
이 서비스 사용 중(배정)
${esc(r.texts.mine)} ○ ${esc(r.mineState)}
다른 서비스 배정
${esc(r.texts.others)}
진행 중 작업 예약
${esc(r.texts.reserved)}
미배정
${esc(r.texts.unallocated)}
실제 사용${r.monthly ? '(이번 달 누적)' : ''}
${esc(r.texts.used)}${r.measuredAt ? ` 계측 ${aw.fmt(r.measuredAt)}` : ''}${r.stale ? ' ! 정보 확인 지연 — 늘릴 수 없음' : ''}
${r.limit ? `
제한
${r.limit.limited ? '100% 제한 적용 중' : r.limit.level + '% 경고'}
` : ''}

허용 범위 ${fmt(r.floor, r.unit)} ~ ${fmt(r.max, r.unit)} (미배정 ${esc(r.texts.unallocated)} 안에서)

`; }).join(''); el.querySelectorAll('form').forEach((f) => { f.onsubmit = async (ev) => { ev.preventDefault(); const res = f.closest('[data-res]').dataset.res; const r = d.resources.find((x) => x.resource === res); const v = Number(f.querySelector('input').value); const amount = r.unit.startsWith('bytes') ? Math.round(v * GB) : Math.round(v); const errEl = f.querySelector('.err'); errEl.textContent = ''; try { const out = await aw.api('POST', `/api/usage/allocate/${encodeURIComponent(subject)}`, { resource: res, amount }); aw.markClean(); aw.toast(`${r.label} 배정을 ${fmt(out.before, r.unit)} → ${fmt(out.after, r.unit)} 로 바꿨습니다`); load(); } catch (e) { errEl.textContent = e.message + (e.detail?.cleanupNeeded ? ` (정리 필요: ${fmt(e.detail.cleanupNeeded, r.unit)})` : e.detail?.shortage ? ` (부족: ${fmt(e.detail.shortage, r.unit)})` : ''); } }; }); } catch (e) { aw.state(el, e.status === 403 ? 'forbidden' : e.status === 404 ? 'empty' : 'failed', e.message, { retry: load }); } } load(); })();