feat: Introduce and separate `BOOT` audit log category from `SYSTEM`, defaulting both to disabled.

This commit is contained in:
이정수 2026-03-27 17:53:00 +09:00
parent 47dc4ab124
commit 0ccbbf9d31
11 changed files with 42 additions and 29 deletions

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "AuditChannel" ALTER COLUMN "disabledCategories" SET DEFAULT ARRAY['SYSTEM']::TEXT[];

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "AuditChannel" ALTER COLUMN "disabledCategories" SET DEFAULT ARRAY['BOOT', 'SYSTEM']::TEXT[];

View File

@ -98,7 +98,7 @@ enum DeleteCondition {
model AuditChannel {
guildId String @id
channelId String
disabledCategories String[] @default([])
disabledCategories String[] @default(["BOOT", "SYSTEM"])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

View File

@ -56,7 +56,8 @@ export default {
.setDescriptionLocalizations({ ko: '설정할 카테고리' })
.setRequired(true)
.addChoices(
{ name: 'SYSTEM (Boot, Generic Errors)', value: 'SYSTEM' },
{ name: 'SYSTEM (System Errors)', value: 'SYSTEM' },
{ name: 'BOOT (Bot Online Notifications)', value: 'BOOT' },
{ name: 'VOICE (Voice Channels)', value: 'VOICE' },
{ name: 'PERMISSION (Permission Issues)', value: 'PERMISSION' },
{ name: 'INVITE (Invite Tracking)', value: 'INVITE' },

View File

@ -25,7 +25,7 @@ export default {
client.guilds.cache.forEach(guild => {
auditLogService.log(guild, {
category: 'SYSTEM',
category: 'BOOT',
severity: 'INFO',
title: 'Bot Online',
description: `Kord has successfully started or reconnected.`

View File

@ -215,6 +215,7 @@ export const en: TranslationSchema = {
defaultGeneratorName: ' Create Channel',
auditCategories: {
SYSTEM: 'System',
BOOT: 'Boot',
VOICE: 'Voice',
PERMISSION: 'Permission',
INVITE: 'Invite',

View File

@ -215,6 +215,7 @@ export const ko: TranslationSchema = {
defaultGeneratorName: ' 채널 생성하기',
auditCategories: {
SYSTEM: '시스템',
BOOT: '부팅',
VOICE: '음성',
PERMISSION: '권한',
INVITE: '초대',

View File

@ -132,6 +132,7 @@ export interface TranslationSchema {
defaultGeneratorName: string;
auditCategories: {
SYSTEM: string;
BOOT: string;
VOICE: string;
PERMISSION: string;
INVITE: string;

View File

@ -2,7 +2,7 @@ import { Guild, EmbedBuilder, TextChannel, Colors } from 'discord.js';
import { prisma } from '../database';
export type AuditSeverity = 'INFO' | 'WARN' | 'ERROR';
export type AuditCategory = 'SYSTEM' | 'VOICE' | 'PERMISSION' | 'INVITE' | 'MIMIC';
export type AuditCategory = 'SYSTEM' | 'BOOT' | 'VOICE' | 'PERMISSION' | 'INVITE' | 'MIMIC';
export interface AuditLogPayload {
category: AuditCategory;
@ -70,7 +70,12 @@ export class AuditLogService {
async setChannel(guildId: string, channelId: string): Promise<void> {
await prisma.auditChannel.upsert({
where: { guildId },
create: { guildId, channelId },
create: {
guildId,
channelId,
// 기본적으로 부팅 로그(BOOT)와 시스템 로그(SYSTEM)는 받지 않도록 설정
disabledCategories: ['BOOT', 'SYSTEM']
},
update: { channelId },
});
}

View File

@ -130,7 +130,7 @@ export class SetupWizardRenderer {
embed.setTitle(t(locale, 'commands.setup.step4.title'))
.setDescription(t(locale, 'commands.setup.step4.desc'));
const categories: ('SYSTEM' | 'VOICE' | 'PERMISSION' | 'INVITE')[] = ['SYSTEM', 'VOICE', 'PERMISSION', 'INVITE'];
const categories: ('BOOT' | 'SYSTEM' | 'VOICE' | 'PERMISSION' | 'INVITE')[] = ['BOOT', 'SYSTEM', 'VOICE', 'PERMISSION', 'INVITE'];
const row1 = new ActionRowBuilder<ButtonBuilder>();
categories.forEach(cat => {
@ -200,7 +200,7 @@ export class SetupWizardRenderer {
// 감사 로그 카테고리 요약
let catStr = 'None';
if (audit?.channelId) {
const allCats: ('SYSTEM' | 'VOICE' | 'PERMISSION' | 'INVITE')[] = ['SYSTEM', 'VOICE', 'PERMISSION', 'INVITE'];
const allCats: ('BOOT' | 'SYSTEM' | 'VOICE' | 'PERMISSION' | 'INVITE')[] = ['BOOT', 'SYSTEM', 'VOICE', 'PERMISSION', 'INVITE'];
const enabled = allCats.filter(c => !audit.disabledCategories.includes(c));
catStr = enabled.map(c => t(locale, `commands.setup.auditCategories.${c}`)).join(', ');
}

View File

@ -1734,28 +1734,6 @@ __metadata:
languageName: node
linkType: hard
"Kord@workspace:.":
version: 0.0.0-use.local
resolution: "Kord@workspace:."
dependencies:
"@prisma/client": "npm:6.4.1"
"@types/jest": "npm:^30.0.0"
"@types/node": "npm:^25.5.0"
"@typescript-eslint/eslint-plugin": "npm:^8.57.2"
"@typescript-eslint/parser": "npm:^8.57.2"
discord.js: "npm:^14.25.1"
dotenv: "npm:^17.3.1"
eslint: "npm:^10.1.0"
ioredis: "npm:^5.10.1"
jest: "npm:^30.3.0"
prettier: "npm:^3.8.1"
prisma: "npm:6.4.1"
ts-jest: "npm:^29.4.6"
tsx: "npm:^4.21.0"
typescript: "npm:^6.0.2"
languageName: unknown
linkType: soft
"abbrev@npm:^4.0.0":
version: 4.0.0
resolution: "abbrev@npm:4.0.0"
@ -3627,6 +3605,28 @@ __metadata:
languageName: node
linkType: hard
"kord@workspace:.":
version: 0.0.0-use.local
resolution: "kord@workspace:."
dependencies:
"@prisma/client": "npm:6.4.1"
"@types/jest": "npm:^30.0.0"
"@types/node": "npm:^25.5.0"
"@typescript-eslint/eslint-plugin": "npm:^8.57.2"
"@typescript-eslint/parser": "npm:^8.57.2"
discord.js: "npm:^14.25.1"
dotenv: "npm:^17.3.1"
eslint: "npm:^10.1.0"
ioredis: "npm:^5.10.1"
jest: "npm:^30.3.0"
prettier: "npm:^3.8.1"
prisma: "npm:6.4.1"
ts-jest: "npm:^29.4.6"
tsx: "npm:^4.21.0"
typescript: "npm:^6.0.2"
languageName: unknown
linkType: soft
"leven@npm:^3.1.0":
version: 3.1.0
resolution: "leven@npm:3.1.0"