포털 중심 데이터 모델(core)과 영역 테스트 도우미

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
zzabisagent-lab
2026-10-26 11:04:32 +00:00
co-authored by Claude Fable 5.1
parent c7aea8d419
commit 8607f19e62
3 changed files with 141 additions and 3 deletions
+5 -3
View File
@@ -15,14 +15,16 @@ import { existsSync } from 'node:fs';
const HERE = dirname(fileURLToPath(import.meta.url));
/** 영역 목록(파일이 있는 것만 등록 — 병렬 개발 중 아직 없는 영역은 건너뛴다) */
export const AREAS = ['auth', 'groups', 'dashboard', 'commerce', 'usage', 'sites', 'domains', 'source', 'mail', 'backup', 'relocation', 'transfer', 'lifecycle', 'notifications', 'auditui', 'ops', 'webhooks', 'help'];
export const AREAS = ['core', 'auth', 'groups', 'dashboard', 'commerce', 'usage', 'sites', 'domains', 'source', 'mail', 'backup', 'relocation', 'transfer', 'lifecycle', 'notifications', 'auditui', 'ops', 'webhooks', 'help'];
export async function buildApp(deps) {
/** @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 = [];
for (const a of AREAS) {
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);