Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
35 lines
2.2 KiB
JavaScript
35 lines
2.2 KiB
JavaScript
/**
|
|
* portal/app.mjs — 고객 포털 앱 조립.
|
|
*
|
|
* 각 영역(portal/<영역>/api.mjs)은 `register(app, deps)` 를 내보내고 여기서 순서대로 등록된다. deps 는 모든 영역이 공유하는 의존성 묶음이다.
|
|
* deps = { store(lib/db), vault, jobs(작업 엔진), config(설정), hal(HAL 클라이언트), webmaker(어댑터), arimail(어댑터), notify, audit, quota, t, page, badge, statePanel, log }
|
|
* 인증 미들웨어(portal/auth/api.mjs 의 middleware)가 가장 먼저 실행되어 ctx.user·ctx.group·ctx.membership·ctx.session·ctx.sitePerms 를 채운다.
|
|
* 영역 등록 순서: auth → groups → dashboard → commerce → usage → sites → domains → source → mail → backup → relocation → transfer → lifecycle → notifications → audit → ops(내부 운영자 API) → webhooks(HAL 이벤트)
|
|
*/
|
|
import { createApp } from '../lib/http.mjs';
|
|
import { t } from '../lib/i18n.mjs';
|
|
import { page, badge, statePanel, dangerSpec } from './ui/layout.mjs';
|
|
import { join, dirname } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { existsSync } from 'node:fs';
|
|
|
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
/** 영역 목록(파일이 있는 것만 등록 — 병렬 개발 중 아직 없는 영역은 건너뛴다) */
|
|
export const AREAS = ['core', 'auth', 'groups', 'dashboard', 'commerce', 'usage', 'sites', 'domains', 'source', 'mail', 'backup', 'relocation', 'transfer', 'lifecycle', 'notifications', 'auditui', 'ops', 'webhooks', 'help'];
|
|
|
|
/** @param {{areas?:string[]}} [opts] areas 를 주면 그 영역만 등록(테스트에서 다른 영역과 분리) */
|
|
export async function buildApp(deps, opts = {}) {
|
|
const app = createApp({ log: deps.log, onError: deps.onError });
|
|
app.static('/ui', join(HERE, 'ui', 'public'));
|
|
Object.assign(deps, { t, page, badge, statePanel, dangerSpec, app });
|
|
const loaded = [];
|
|
if (opts.before) app.use(opts.before);
|
|
for (const a of (opts.areas || AREAS)) {
|
|
const file = join(HERE, a, 'api.mjs'); if (!existsSync(file)) continue;
|
|
const mod = await import(file); if (typeof mod.register !== 'function') continue;
|
|
await mod.register(app, deps); loaded.push(a);
|
|
}
|
|
deps.log(`[portal] 영역 등록: ${loaded.join(', ')}`);
|
|
return app;
|
|
}
|