사이트 목록·생성·상세, 관리형/외부 배포, 배포 방식 변경, 도메인·HTTPS, Source 옵션과 Webmaker 도입 수정(SSO, 프로젝트↔사이트 구분, 삭제 영향 확인, 동시 편집 충돌, 발행 경로) (§7~§12·§0.2)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
a1cde81332
commit
b1c06a0304
@@ -0,0 +1,11 @@
|
||||
/** portal/webmaker/api.mjs — Webmaker 연동 라우트: 내 프로젝트 목록(/api/webmaker/projects), AI Wallet(/api/webmaker/wallet), 연동 상태(운영자 /internal/ops/webmaker). SSO 진입은 portal/sites/api.mjs 의 /sso/webmaker. */
|
||||
import { requireGroup } from '../auth/guard.mjs';
|
||||
import { HttpError } from '../../lib/http.mjs';
|
||||
import { verifyCtx } from '../../lib/serviceauth.mjs';
|
||||
import { loginFor } from './adapter.mjs';
|
||||
export async function register(app, deps) {
|
||||
const wm = () => { if (!deps.webmaker) throw new HttpError(503, 'service_unreachable', 'Webmaker 연동이 설정되지 않았습니다'); return deps.webmaker; };
|
||||
app.get('/api/webmaker/projects', async (ctx) => { requireGroup(ctx); try { const projects = await wm().listProjects(loginFor(ctx.user, ctx.group)); const linked = new Set(deps.store.all('SELECT webmaker_project_id FROM sites WHERE group_id=? AND webmaker_project_id IS NOT NULL AND lifecycle<>\'deleted\'', ctx.group.id).map((r) => r.webmaker_project_id)); return { ok: true, projects: projects.map((p) => ({ ...p, link: p.link || (linked.has(p.id) ? { siteId: deps.store.get('SELECT id FROM sites WHERE webmaker_project_id=?', p.id)?.id } : null) })) }; } catch (e) { if (e.code === 'service_unreachable') return ctx.json({ ok: false, error: 'service_unreachable', message: 'Webmaker 에 연결할 수 없습니다(정보 확인 지연)' }, 503); throw e; } });
|
||||
app.get('/api/webmaker/wallet', async (ctx) => { requireGroup(ctx); try { const w = await wm().credits(loginFor(ctx.user, ctx.group)); return { ok: true, wallet: w.credit, unit: w.unit, note: 'AI Wallet 은 AI 생성·수정 비용에만 쓰이며 호스팅 디스크·트래픽·메일 사용량과 분리됩니다' }; } catch (e) { if (e.code === 'service_unreachable') return ctx.json({ ok: false, error: 'service_unreachable', message: 'Webmaker 에 연결할 수 없습니다(정보 확인 지연)' }, 503); throw e; } });
|
||||
app.get('/internal/ops/webmaker', async (ctx) => { const v = await verifyCtx(ctx, (id) => (['hal', 'portal'].includes(id) ? deps.vault.get('service:' + id) : null)); if (!v.ok) throw new HttpError(401, 'service_auth_failed', v.reason); let health = null; try { health = await wm().health(); } catch (e) { health = { ok: false, error: e.code || e.message }; } return { ok: true, health, provisioning: deps.webmaker ? deps.webmaker.provisioningInfo() : null, ssoIssued24h: deps.store.get('SELECT COUNT(*) AS n FROM sso_tickets WHERE issued_at>?', new Date(Date.now() - 86400000).toISOString()).n }; });
|
||||
}
|
||||
Reference in New Issue
Block a user