feat(admin): integrate Next.js admin panel (admin-next/) from feat/nextjs-admin
- Add admin-next/: full Next.js + Prisma + shadcn admin panel (45 API routes, 76 components) - docker-compose: tg_shop_admin service (port 3000, shared db/shop.db, prisma), bot talks to it via ADMIN_CHAT_URL=http://tg_shop_admin:3000/api/chat - tor-proxy now proxies onion admin to tg_shop_admin:3000 (new panel) - chatbotService: ADMIN_CHAT_URL default = http://tg_shop_admin:3000/api/chat (removed localhost:3100 anachronism) - .env admin secrets gitignored (admin-next/.env)
This commit is contained in:
38
admin-next/src/lib/chatbot-config.ts
Executable file
38
admin-next/src/lib/chatbot-config.ts
Executable file
@@ -0,0 +1,38 @@
|
||||
// Shared chatbot config cache — used by admin/chatbot and chat routes
|
||||
|
||||
let _cachedAt = 0;
|
||||
let _cachedConfig: Record<string, string> | null = null;
|
||||
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
|
||||
|
||||
export function invalidateChatbotCache() {
|
||||
_cachedAt = 0;
|
||||
_cachedConfig = null;
|
||||
}
|
||||
|
||||
export function resetCacheTimestamp() {
|
||||
_cachedAt = 0;
|
||||
}
|
||||
|
||||
export async function getChatbotConfig(): Promise<Record<string, string>> {
|
||||
const now = Date.now();
|
||||
if (_cachedConfig && now - _cachedAt < CACHE_TTL) {
|
||||
return _cachedConfig;
|
||||
}
|
||||
|
||||
// Dynamic import to avoid circular dependency
|
||||
const { db } = await import('@/lib/db');
|
||||
const rows = await db.siteSetting.findMany({
|
||||
where: {
|
||||
key: { startsWith: 'chatbot_' },
|
||||
},
|
||||
});
|
||||
|
||||
const config: Record<string, string> = {};
|
||||
for (const row of rows) {
|
||||
config[row.key] = row.value;
|
||||
}
|
||||
|
||||
_cachedConfig = config;
|
||||
_cachedAt = now;
|
||||
return config;
|
||||
}
|
||||
Reference in New Issue
Block a user