refactor: rename mascot to chatbot across entire codebase
Build & Deploy / build-and-push (discord-gateway) (push) Failing after 30s
Build & Deploy / build-and-push (backend) (push) Failing after 2m28s
Build & Deploy / build-and-push (proxy) (push) Successful in 2m28s
Build & Deploy / build-and-push (discord-gateway) (push) Failing after 30s
Build & Deploy / build-and-push (backend) (push) Failing after 2m28s
Build & Deploy / build-and-push (proxy) (push) Successful in 2m28s
- Backend: mascot-chat module → chatbot, routes /mascot/chat → /chat - Shared schema: pgMascotChatMessagesTable → pgChatbotMessagesTable - Frontend: MascotProvider/useMascot → ChatbotProvider/useChatbot - Gateway schema: update exports to match shared schema - Docs: update all .md references (CLAUDE.md, README, specs, plans) - All API routes, controller names, service classes, types renamed Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
bd9e7d8151
commit
977a6f9653
@@ -10,7 +10,7 @@ import { createAnalysisRouter } from "../modules/analysis/index.js";
|
||||
import { createConfigRouter } from "../modules/config/index.js";
|
||||
import { createDashboardRouter } from "../modules/dashboard/index.js";
|
||||
import { createHealthRouter } from "../modules/health/index.js";
|
||||
import { createMascotChatRouter } from "../modules/mascot-chat/index.js";
|
||||
import { createChatbotRouter } from "../modules/chatbot/index.js";
|
||||
import { createMediaRouter } from "../modules/media/index.js";
|
||||
import { createMessagesRouter } from "../modules/messages/index.js";
|
||||
import { createRecordingsRouter } from "../modules/recordings/index.js";
|
||||
@@ -64,7 +64,7 @@ export function createHttpApp(): Express {
|
||||
app.use("/api", createDashboardRouter());
|
||||
app.use("/api", createMessagesRouter());
|
||||
app.use("/api", createAnalysisRouter());
|
||||
app.use("/api", createMascotChatRouter());
|
||||
app.use("/api", createChatbotRouter());
|
||||
app.use("/api", createRecordingsRouter());
|
||||
app.use("/api", createUiStateRouter());
|
||||
app.use("/api", createMediaRouter());
|
||||
|
||||
+12
-12
@@ -1,15 +1,15 @@
|
||||
import { createChildLogger } from "@bete/shared/logger";
|
||||
import type { Request, Response } from "express";
|
||||
import { asyncHandler } from "../../shared/middlewares/index.js";
|
||||
import { mascotChatService } from "./mascot-chat.service.js";
|
||||
import { chatbotService } from "./chatbot.service.js";
|
||||
|
||||
const logger = createChildLogger("mascot-chat.controller");
|
||||
const logger = createChildLogger("chatbot.controller");
|
||||
|
||||
interface AuthenticatedRequest extends Request {
|
||||
userId?: string;
|
||||
}
|
||||
|
||||
export const handleMascotChat = asyncHandler(
|
||||
export const handleChatbotChat = asyncHandler(
|
||||
async (req: Request, res: Response) => {
|
||||
const { message, context } = req.body as {
|
||||
message: string;
|
||||
@@ -29,26 +29,26 @@ export const handleMascotChat = asyncHandler(
|
||||
|
||||
logger.debug(
|
||||
{ userId, messageLength: message.length, context },
|
||||
"Received mascot chat message",
|
||||
"Received chatbot chat message",
|
||||
);
|
||||
|
||||
// Process message & generate response
|
||||
const response = await mascotChatService.processMessage(
|
||||
const response = await chatbotService.processMessage(
|
||||
message,
|
||||
context,
|
||||
userId,
|
||||
);
|
||||
|
||||
// Save conversation to database
|
||||
await mascotChatService.saveConversation({
|
||||
await chatbotService.saveConversation({
|
||||
userId,
|
||||
userMessage: message,
|
||||
mascotResponse: response,
|
||||
botResponse: response,
|
||||
context,
|
||||
timestamp: new Date(),
|
||||
});
|
||||
|
||||
logger.info({ userId }, "Mascot chat processed successfully");
|
||||
logger.info({ userId }, "Chatbot chat processed successfully");
|
||||
|
||||
res.status(200).json({
|
||||
response,
|
||||
@@ -57,12 +57,12 @@ export const handleMascotChat = asyncHandler(
|
||||
},
|
||||
);
|
||||
|
||||
export const getMascotChatHistory = asyncHandler(
|
||||
export const getChatbotHistory = asyncHandler(
|
||||
async (req: Request, res: Response) => {
|
||||
const userId = (req as AuthenticatedRequest).userId || "anonymous";
|
||||
const limit = Math.min(parseInt(req.query.limit as string, 10) || 50, 100);
|
||||
|
||||
const history = await mascotChatService.getChatHistory(userId, limit);
|
||||
const history = await chatbotService.getChatHistory(userId, limit);
|
||||
|
||||
res.status(200).json({
|
||||
history,
|
||||
@@ -71,11 +71,11 @@ export const getMascotChatHistory = asyncHandler(
|
||||
},
|
||||
);
|
||||
|
||||
export const clearMascotChatHistory = asyncHandler(
|
||||
export const clearChatbotHistory = asyncHandler(
|
||||
async (req: Request, res: Response) => {
|
||||
const userId = (req as AuthenticatedRequest).userId || "anonymous";
|
||||
|
||||
await mascotChatService.clearChatHistory(userId);
|
||||
await chatbotService.clearChatHistory(userId);
|
||||
|
||||
res.status(200).json({
|
||||
message: "Chat history cleared successfully",
|
||||
+20
-20
@@ -1,11 +1,11 @@
|
||||
import { pgMascotChatMessagesTable, pgMessagesTable } from "@bete/shared";
|
||||
import { pgChatbotMessagesTable, pgMessagesTable } from "@bete/shared";
|
||||
import { createChildLogger } from "@bete/shared/logger";
|
||||
import { and, desc, eq, type SQL, sql } from "drizzle-orm";
|
||||
import { getDatabase } from "../../shared/database/index.js";
|
||||
|
||||
const logger = createChildLogger("mascot-chat.repository");
|
||||
const logger = createChildLogger("chatbot.repository");
|
||||
|
||||
export interface MascotChatContext {
|
||||
export interface ChatbotContext {
|
||||
messageCount?: number;
|
||||
activeParticipants?: number;
|
||||
lastActivity?: string;
|
||||
@@ -17,17 +17,17 @@ export interface MascotChatContext {
|
||||
export interface SaveConversationInput {
|
||||
userId: string;
|
||||
userMessage: string;
|
||||
mascotResponse: string;
|
||||
context?: MascotChatContext;
|
||||
botResponse: string;
|
||||
context?: ChatbotContext;
|
||||
timestamp: Date;
|
||||
}
|
||||
|
||||
export interface MascotChatHistoryRow {
|
||||
export interface ChatbotHistoryRow {
|
||||
id: string;
|
||||
user_id: string;
|
||||
user_message: string;
|
||||
mascot_response: string;
|
||||
context: MascotChatContext | null;
|
||||
bot_response: string;
|
||||
context: ChatbotContext | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
@@ -38,14 +38,14 @@ export interface ServerInsights {
|
||||
warned: number;
|
||||
}
|
||||
|
||||
export class MascotChatRepository {
|
||||
export class ChatbotRepository {
|
||||
async saveConversation(input: SaveConversationInput): Promise<void> {
|
||||
const db = getDatabase();
|
||||
|
||||
await db.insert(pgMascotChatMessagesTable).values({
|
||||
await db.insert(pgChatbotMessagesTable).values({
|
||||
user_id: input.userId,
|
||||
user_message: input.userMessage,
|
||||
mascot_response: input.mascotResponse,
|
||||
bot_response: input.botResponse,
|
||||
context: (input.context ?? {}) as Record<string, unknown>,
|
||||
created_at: input.timestamp,
|
||||
});
|
||||
@@ -56,27 +56,27 @@ export class MascotChatRepository {
|
||||
async getChatHistory(
|
||||
userId: string,
|
||||
limit: number,
|
||||
): Promise<MascotChatHistoryRow[]> {
|
||||
): Promise<ChatbotHistoryRow[]> {
|
||||
const db = getDatabase();
|
||||
|
||||
const rows = await db
|
||||
.select()
|
||||
.from(pgMascotChatMessagesTable)
|
||||
.where(eq(pgMascotChatMessagesTable.user_id, userId))
|
||||
.orderBy(desc(pgMascotChatMessagesTable.created_at))
|
||||
.from(pgChatbotMessagesTable)
|
||||
.where(eq(pgChatbotMessagesTable.user_id, userId))
|
||||
.orderBy(desc(pgChatbotMessagesTable.created_at))
|
||||
.limit(limit);
|
||||
|
||||
logger.debug({ userId, count: rows.length }, "Chat history fetched");
|
||||
return rows.reverse() as unknown as MascotChatHistoryRow[];
|
||||
return rows.reverse() as unknown as ChatbotHistoryRow[];
|
||||
}
|
||||
|
||||
async clearChatHistory(userId: string): Promise<void> {
|
||||
const db = getDatabase();
|
||||
|
||||
const deleted = await db
|
||||
.delete(pgMascotChatMessagesTable)
|
||||
.where(eq(pgMascotChatMessagesTable.user_id, userId))
|
||||
.returning({ id: pgMascotChatMessagesTable.id });
|
||||
.delete(pgChatbotMessagesTable)
|
||||
.where(eq(pgChatbotMessagesTable.user_id, userId))
|
||||
.returning({ id: pgChatbotMessagesTable.id });
|
||||
|
||||
logger.info(
|
||||
{ userId, deletedRows: deleted.length },
|
||||
@@ -135,4 +135,4 @@ export class MascotChatRepository {
|
||||
}
|
||||
}
|
||||
|
||||
export const mascotChatRepository = new MascotChatRepository();
|
||||
export const chatbotRepository = new ChatbotRepository();
|
||||
@@ -0,0 +1,22 @@
|
||||
import express, { type Router } from "express";
|
||||
import { validateBody } from "../../shared/middlewares/index.js";
|
||||
import {
|
||||
clearChatbotHistory,
|
||||
getChatbotHistory,
|
||||
handleChatbotChat,
|
||||
} from "./chatbot.controller.js";
|
||||
import { chatRequestSchema } from "./chatbot.schema.js";
|
||||
|
||||
export function createChatbotRouter(): Router {
|
||||
const router = express.Router();
|
||||
|
||||
router.post(
|
||||
"/chat",
|
||||
validateBody(chatRequestSchema),
|
||||
handleChatbotChat,
|
||||
);
|
||||
router.get("/chat/history", getChatbotHistory);
|
||||
router.delete("/chat/history", clearChatbotHistory);
|
||||
|
||||
return router;
|
||||
}
|
||||
+17
-17
@@ -1,18 +1,18 @@
|
||||
import { createChildLogger } from "@bete/shared/logger";
|
||||
import { config } from "../../shared/config/index.js";
|
||||
import type {
|
||||
MascotChatContext,
|
||||
MascotChatHistoryRow,
|
||||
ChatbotContext,
|
||||
ChatbotHistoryRow,
|
||||
SaveConversationInput,
|
||||
} from "./mascot-chat.repository.js";
|
||||
import { mascotChatRepository } from "./mascot-chat.repository.js";
|
||||
} from "./chatbot.repository.js";
|
||||
import { chatbotRepository } from "./chatbot.repository.js";
|
||||
|
||||
const logger = createChildLogger("mascot-chat.service");
|
||||
const logger = createChildLogger("chatbot.service");
|
||||
|
||||
class MascotChatService {
|
||||
class ChatbotService {
|
||||
async processMessage(
|
||||
message: string,
|
||||
context: MascotChatContext | undefined,
|
||||
context: ChatbotContext | undefined,
|
||||
userId: string,
|
||||
): Promise<string> {
|
||||
logger.info(
|
||||
@@ -20,7 +20,7 @@ class MascotChatService {
|
||||
"processMessage called",
|
||||
);
|
||||
const recentContext = await this.getRecentConversationContext(userId);
|
||||
const serverInsights = await mascotChatRepository.getServerInsights(
|
||||
const serverInsights = await chatbotRepository.getServerInsights(
|
||||
context?.guildId,
|
||||
context?.channelId,
|
||||
);
|
||||
@@ -39,29 +39,29 @@ class MascotChatService {
|
||||
|
||||
async saveConversation(input: SaveConversationInput): Promise<void> {
|
||||
logger.info({ userId: input.userId }, "saveConversation called");
|
||||
await mascotChatRepository.saveConversation(input);
|
||||
await chatbotRepository.saveConversation(input);
|
||||
}
|
||||
|
||||
async getChatHistory(
|
||||
userId: string,
|
||||
limit: number,
|
||||
): Promise<MascotChatHistoryRow[]> {
|
||||
): Promise<ChatbotHistoryRow[]> {
|
||||
logger.debug({ userId, limit }, "getChatHistory called");
|
||||
return mascotChatRepository.getChatHistory(userId, limit);
|
||||
return chatbotRepository.getChatHistory(userId, limit);
|
||||
}
|
||||
|
||||
async clearChatHistory(userId: string): Promise<void> {
|
||||
logger.info({ userId }, "clearChatHistory called");
|
||||
await mascotChatRepository.clearChatHistory(userId);
|
||||
await chatbotRepository.clearChatHistory(userId);
|
||||
}
|
||||
|
||||
private async getRecentConversationContext(
|
||||
userId: string,
|
||||
): Promise<string[]> {
|
||||
const history = await mascotChatRepository.getChatHistory(userId, 3);
|
||||
const history = await chatbotRepository.getChatHistory(userId, 3);
|
||||
return history.flatMap((row) => [
|
||||
`User: ${row.user_message}`,
|
||||
`Mascot: ${row.mascot_response}`,
|
||||
`Bot: ${row.bot_response}`,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class MascotChatService {
|
||||
flagged: number;
|
||||
warned: number;
|
||||
}): string {
|
||||
return `Kamu lagi ngobrol sama mascot Discord Watcher — temen ngobrol yang tau keadaan server.
|
||||
return `Kamu lagi ngobrol sama chatbot Discord Watcher — temen ngobrol yang tau keadaan server.
|
||||
|
||||
Data server saat ini:
|
||||
- Pesan: ${insights.total_messages}
|
||||
@@ -92,7 +92,7 @@ Gaya ngobrol:
|
||||
private buildHistoryMessages(
|
||||
recentContext: string[],
|
||||
): Array<{ role: "user" | "assistant"; content: string }> {
|
||||
// recentContext is alternating User/Mascot messages
|
||||
// recentContext is alternating User/Bot messages
|
||||
return recentContext.map((text) => {
|
||||
if (text.startsWith("User: ")) {
|
||||
return { role: "user" as const, content: text.slice(6) };
|
||||
@@ -178,4 +178,4 @@ Gaya ngobrol:
|
||||
}
|
||||
}
|
||||
|
||||
export const mascotChatService = new MascotChatService();
|
||||
export const chatbotService = new ChatbotService();
|
||||
@@ -0,0 +1 @@
|
||||
export { createChatbotRouter } from "./chatbot.routes.js";
|
||||
@@ -1 +0,0 @@
|
||||
export { createMascotChatRouter } from "./mascot-chat.routes.js";
|
||||
@@ -1,22 +0,0 @@
|
||||
import express, { type Router } from "express";
|
||||
import { validateBody } from "../../shared/middlewares/index.js";
|
||||
import {
|
||||
clearMascotChatHistory,
|
||||
getMascotChatHistory,
|
||||
handleMascotChat,
|
||||
} from "./mascot-chat.controller.js";
|
||||
import { chatRequestSchema } from "./mascot-chat.schema.js";
|
||||
|
||||
export function createMascotChatRouter(): Router {
|
||||
const router = express.Router();
|
||||
|
||||
router.post(
|
||||
"/mascot/chat",
|
||||
validateBody(chatRequestSchema),
|
||||
handleMascotChat,
|
||||
);
|
||||
router.get("/mascot/chat/history", getMascotChatHistory);
|
||||
router.delete("/mascot/chat/history", clearMascotChatHistory);
|
||||
|
||||
return router;
|
||||
}
|
||||
Reference in New Issue
Block a user