feat(tkuser): 알림 시스템 이관 system1-factory → tkuser

- Phase 1: tkuser에 알림 CRUD, Push/ntfy 발송, 내부 알림 API 추가
- Phase 2: notifyHelper URL을 tkuser-api:3000으로 전환 (system2, tkpurchase, tksafety, system1)
- Phase 3: notification-bell.js API 도메인 tkuser로 변경 + 캐시 버스팅 v=4
- Phase 4: system1에서 알림 코드 제거 (routes, controllers, models, utils)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Hyungi Ahn
2026-03-17 15:56:41 +09:00
parent afa10c044f
commit 84cf222b81
30 changed files with 244 additions and 172 deletions

View File

@@ -0,0 +1,39 @@
// utils/cache.js - NodeCache 기반 간소화 캐시
const NodeCache = require('node-cache');
const memoryCache = new NodeCache({
stdTTL: 600,
checkperiod: 120,
useClones: false
});
const get = async (key) => {
try {
return memoryCache.get(key) || null;
} catch (error) {
console.warn(`캐시 조회 오류 (${key}):`, error.message);
return null;
}
};
const set = async (key, value, ttl = 600) => {
try {
memoryCache.set(key, value, ttl);
return true;
} catch (error) {
console.warn(`캐시 저장 오류 (${key}):`, error.message);
return false;
}
};
const del = async (key) => {
try {
memoryCache.del(key);
return true;
} catch (error) {
console.warn(`캐시 삭제 오류 (${key}):`, error.message);
return false;
}
};
module.exports = { get, set, del };

View File

@@ -0,0 +1,31 @@
// utils/ntfySender.js — ntfy HTTP POST 래퍼
const NTFY_BASE_URL = process.env.NTFY_BASE_URL || 'http://ntfy:80';
const NTFY_PUBLISH_TOKEN = process.env.NTFY_PUBLISH_TOKEN;
const TKFB_BASE_URL = process.env.TKFB_BASE_URL || 'https://tkfb.technicalkorea.net';
async function sendNtfy(userId, { title, body, url }) {
if (!NTFY_PUBLISH_TOKEN) return;
const topic = `tkfactory-user-${userId}`;
const headers = {
'Authorization': `Bearer ${NTFY_PUBLISH_TOKEN}`,
'Title': title || '',
'Tags': 'bell',
};
if (url) {
headers['Click'] = url.startsWith('http') ? url : `${TKFB_BASE_URL}${url}`;
}
try {
const resp = await fetch(`${NTFY_BASE_URL}/${topic}`, {
method: 'POST',
headers,
body: body || '',
});
if (!resp.ok) console.warn(`[ntfy] ${userId} 발송 실패: ${resp.status}`);
} catch (e) {
console.error(`[ntfy] ${userId} 발송 오류:`, e.message);
}
}
module.exports = { sendNtfy };