Files
Gnuboard7/plugins/_bundled/sirsoft-message_bizppurio/resources/js/index.ts
T
HeuJung e17731d8cc feat(message_bizppurio): 알림톡 템플릿 라이프사이클 개편 — DB 기반 작성·검수·승인
비즈뿌리오 알림톡 템플릿을 콘솔 위임(발송 전 실시간 조회) 방식에서 시스템 내
작성(draft) → 검수 신청(requested) → 승인(approved) 라이프사이클로 개편한다.
발송 판정의 SSoT 를 DB(bizppurio_templates)로 옮기고 발송 전 실시간 조회를 폐지.

- 알림↔템플릿 바인딩 모델(notification_bindings) 제거, 알림 1건당 템플릿 1행으로 대체
- 검수 신청: template_code 자체 채번(codeCheck 재시도) → kapi add/update → request
- 상태 동기화: 30분 스케줄러 + 수동 새로고침, 승인 전이 시 content 를 approved_content 로 동결
- SMS 본문 언어별 입력 복원(수신자 로케일 발송), SMS 단독 선택 시 알림톡 미발송
- 3면(코어/게시판/이커머스) '비즈뿌리오' 통합 탭 + 플러그인 '알림 템플릿 관리' 화면
- 중복 검수 신청은 서버 원자 선점(claimForInspection 조건부 UPDATE)으로 차단
- admin_basic 1.0.6 / board 1.0.5 / ecommerce 1.1.2: 채널 서브탭 통합 탭 선언(tab_channels) 지원
- 검증: 계획서 대비 5라운드 전수검증, §6.3 실측 매트릭스 Playwright 19 고정,
 PHPUnit 421 / Vitest 228 green, audit 0 error
2026-08-22 22:44:57 +09:00

95 lines
3.0 KiB
TypeScript

/**
* sirsoft-message_bizppurio 플러그인 엔트리포인트.
*
* 플러그인 활성화 시 자동 로드되어 handlerMap 의 커스텀 핸들러를 ActionDispatcher 에
* 등록한다. 핸들러명은 `sirsoft-message_bizppurio.{name}` 네임스페이스를 갖는다.
* (현재 등록 핸들러: insertVariable, uploadTemplateImage — handlers/index.ts 참조.)
*/
import { handlerMap } from './handlers';
const PLUGIN_IDENTIFIER = 'sirsoft-message_bizppurio';
const logger = ((window as any).G7Core?.createLogger?.(`Plugin:${PLUGIN_IDENTIFIER}`)) ?? {
log: (...args: unknown[]) => console.log(`[Plugin:${PLUGIN_IDENTIFIER}]`, ...args),
warn: (...args: unknown[]) => console.warn(`[Plugin:${PLUGIN_IDENTIFIER}]`, ...args),
error: (...args: unknown[]) => console.error(`[Plugin:${PLUGIN_IDENTIFIER}]`, ...args),
};
/**
* handlerMap 의 모든 핸들러를 ActionDispatcher 에 등록합니다.
*
* @param dispatcher 코어 ActionDispatcher 인스턴스
*/
function register(dispatcher: any): void {
Object.entries(handlerMap).forEach(([name, handler]) => {
dispatcher.registerHandler(`${PLUGIN_IDENTIFIER}.${name}`, handler, {
category: 'plugin',
source: PLUGIN_IDENTIFIER,
});
});
logger.log(
`${Object.keys(handlerMap).length} handler(s) registered:`,
Object.keys(handlerMap).map(name => `${PLUGIN_IDENTIFIER}.${name}`),
);
}
/**
* ActionDispatcher 준비 후 핸들러를 등록합니다.
*
* 최초 로드 시 ActionDispatcher 가 아직 없을 수 있으므로 짧게 재시도한다.
*
* @param retry ActionDispatcher 부재 시 재시도 여부
*/
function registerHandlers(retry: boolean): void {
const dispatcher = (window as any).G7Core?.getActionDispatcher?.();
if (dispatcher) {
register(dispatcher);
return;
}
if (!retry) {
logger.warn('ActionDispatcher 를 찾지 못해 핸들러를 등록하지 못했습니다.');
return;
}
let count = 0;
const max = 50; // 최대 5초 (50 * 100ms)
const tick = () => {
const found = (window as any).G7Core?.getActionDispatcher?.();
if (found) {
register(found);
return;
}
if (++count <= max) {
setTimeout(tick, 100);
} else {
logger.error('ActionDispatcher 를 찾지 못해 핸들러 등록에 실패했습니다.');
}
};
tick();
}
/**
* 플러그인 초기화 — DOM 준비 후 핸들러 등록.
*/
export function initPlugin(): void {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => registerHandlers(true));
} else {
const hasDispatcher = !!(window as any).G7Core?.getActionDispatcher?.();
registerHandlers(!hasDispatcher);
}
}
initPlugin();
if (typeof window !== 'undefined') {
(window as any).__SirsoftMessageBizppurio = {
identifier: PLUGIN_IDENTIFIER,
handlers: Object.keys(handlerMap),
initPlugin,
};
}