From 66d3b5e997c369a35a5c8af52ef928f6cf70f2b3 Mon Sep 17 00:00:00 2001 From: MythEclipse Date: Sat, 6 Jun 2026 03:06:00 +0700 Subject: [PATCH] refactor: remove unused anchorRoleId parameter from DiscordRoleRepository and decentralize type definitions --- bun.lock | 3 +++ package.json | 3 ++- src/discord/bot.ts | 4 ++-- src/index.ts | 2 +- src/services/boosterRoleService.ts | 32 ++++--------------------- src/services/discordRoleRepository.ts | 15 ++++++++---- src/services/drizzleBoosterRoleStore.ts | 20 +++++++++++++++- 7 files changed, 43 insertions(+), 36 deletions(-) diff --git a/bun.lock b/bun.lock index 7871604..e128ec3 100644 --- a/bun.lock +++ b/bun.lock @@ -10,6 +10,7 @@ "drizzle-orm": "latest", "postgres": "latest", "winston": "^3.19.0", + "zod": "^4.4.3", }, "devDependencies": { "@types/bun": "^1.3.14", @@ -275,6 +276,8 @@ "ws": ["ws@8.20.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w=="], + "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + "@discordjs/rest/@discordjs/collection": ["@discordjs/collection@2.1.1", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="], "@discordjs/rest/@sapphire/snowflake": ["@sapphire/snowflake@3.5.5", "", {}, "sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ=="], diff --git a/package.json b/package.json index 58933f7..97a9a61 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "discord.js": "latest", "drizzle-orm": "latest", "postgres": "latest", - "winston": "^3.19.0" + "winston": "^3.19.0", + "zod": "^4.4.3" }, "devDependencies": { "@types/bun": "^1.3.14", diff --git a/src/discord/bot.ts b/src/discord/bot.ts index e052748..4cfe2dd 100644 --- a/src/discord/bot.ts +++ b/src/discord/bot.ts @@ -16,7 +16,7 @@ export function attachBotHandlers(client: Client, config: AppConfig): void { const service = new BoosterRoleService( store, - new DiscordRoleRepository(interaction.guild, config.boosterRoleAnchorRoleId), + new DiscordRoleRepository(interaction.guild), { anchorPosition: resolveAnchorPosition(interaction.guild, config.boosterRoleAnchorRoleId) } ); @@ -28,7 +28,7 @@ export function attachBotHandlers(client: Client, config: AppConfig): void { client.on("guildMemberUpdate", async (oldMember, newMember) => { const service = new BoosterRoleService( store, - new DiscordRoleRepository(newMember.guild, config.boosterRoleAnchorRoleId), + new DiscordRoleRepository(newMember.guild), { anchorPosition: resolveAnchorPosition(newMember.guild, config.boosterRoleAnchorRoleId) } ); diff --git a/src/index.ts b/src/index.ts index 6fc3e3b..21af714 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,7 +27,7 @@ client.once("clientReady", () => { startBoostCleanup( client, store, - (guild) => new DiscordRoleRepository(guild, config.boosterRoleAnchorRoleId), + (guild) => new DiscordRoleRepository(guild), { intervalMs: config.boostCleanupIntervalMs, boosterEligibilityRoleId: config.boosterEligibilityRoleId, diff --git a/src/services/boosterRoleService.ts b/src/services/boosterRoleService.ts index b0713a8..cdec001 100644 --- a/src/services/boosterRoleService.ts +++ b/src/services/boosterRoleService.ts @@ -7,38 +7,16 @@ import { normalizeHexColor, normalizeOptionalHexColor, validateRoleName, - type ExistingRole, type ManagedRoleIdentity } from "../domain/roleGuards"; import { ValidationError, NotFoundError } from "../domain/errors"; -export type BoosterRoleRecord = { - guildId: string; - userId: string; - roleId: string; - name: string; - color: string | null; - color2: string | null; - icon: string | null; - createdAt: number; - updatedAt: number; -}; +import type { BoosterRoleRecord, BoosterRoleStore } from "./drizzleBoosterRoleStore"; +import type { RoleRepository } from "./discordRoleRepository"; -export type BoosterRoleStore = { - findByUser(guildId: string, userId: string): Promise; - findByGuild(guildId: string): Promise; - create(record: BoosterRoleRecord): Promise; - delete(guildId: string, userId: string): Promise; -}; - -export type RoleRepository = { - listRoles(): Promise; - createRole(input: { name: string; color: string | null; colors?: { primaryColor: string; secondaryColor?: string; tertiaryColor?: string } | null; permissions: string[]; position: number }): Promise<{ id: string }>; - updateRole(roleId: string, input: { name?: string; color?: string | null; colors?: { primaryColor: string; secondaryColor?: string; tertiaryColor?: string } | null; icon?: string | null }): Promise; - assignRole(userId: string, roleId: string): Promise; - removeRole(userId: string, roleId: string): Promise; - deleteRole(roleId: string): Promise; -}; +// Re-export for consumers that import from this module +export type { BoosterRoleRecord, BoosterRoleStore }; +export type { RoleRepository } from "./discordRoleRepository"; export type RoleIcon = { contentType: string; diff --git a/src/services/discordRoleRepository.ts b/src/services/discordRoleRepository.ts index d36dba3..63f21a6 100644 --- a/src/services/discordRoleRepository.ts +++ b/src/services/discordRoleRepository.ts @@ -1,10 +1,17 @@ import type { ColorResolvable, Guild, Role, RoleColorsResolvable } from "discord.js"; -import type { RoleRepository } from "./boosterRoleService"; +import type { ExistingRole } from "../domain/roleGuards"; + +export type RoleRepository = { + listRoles(): Promise; + createRole(input: { name: string; color: string | null; colors?: { primaryColor: string; secondaryColor?: string; tertiaryColor?: string } | null; permissions: string[]; position: number }): Promise<{ id: string }>; + updateRole(roleId: string, input: { name?: string; color?: string | null; colors?: { primaryColor: string; secondaryColor?: string; tertiaryColor?: string } | null; icon?: string | null }): Promise; + assignRole(userId: string, roleId: string): Promise; + removeRole(userId: string, roleId: string): Promise; + deleteRole(roleId: string): Promise; +}; export class DiscordRoleRepository implements RoleRepository { - constructor(private readonly guild: Guild, anchorRoleId: string | null) { - void anchorRoleId; - } + constructor(private readonly guild: Guild) {} async listRoles() { await this.guild.roles.fetch(); diff --git a/src/services/drizzleBoosterRoleStore.ts b/src/services/drizzleBoosterRoleStore.ts index 6861045..ea1a38a 100644 --- a/src/services/drizzleBoosterRoleStore.ts +++ b/src/services/drizzleBoosterRoleStore.ts @@ -1,6 +1,24 @@ import { and, eq } from "drizzle-orm"; import { boosterRoles } from "../db/schema"; -import type { BoosterRoleRecord, BoosterRoleStore } from "./boosterRoleService"; + +export type BoosterRoleRecord = { + guildId: string; + userId: string; + roleId: string; + name: string; + color: string | null; + color2: string | null; + icon: string | null; + createdAt: number; + updatedAt: number; +}; + +export type BoosterRoleStore = { + findByUser(guildId: string, userId: string): Promise; + findByGuild(guildId: string): Promise; + create(record: BoosterRoleRecord): Promise; + delete(guildId: string, userId: string): Promise; +}; type SelectQuery = { where(condition: unknown): QueryWithLimit & Promise;