From cc0757d0a04964a40977eae45d822d4e23e4d7e7 Mon Sep 17 00:00:00 2001 From: gunshiz Date: Thu, 10 Sep 2026 19:24:42 +0700 Subject: [PATCH] fix : no startup sync --- README.md | 10 +++++----- backend/discord.ts | 23 +++++------------------ tests/deployment-contract.test.ts | 8 ++++++++ 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 8e523f9..4a3b50c 100644 --- a/README.md +++ b/README.md @@ -121,12 +121,12 @@ refetch authoritative state; SSE never contains page content and is not the source of truth. The Discord catalog worker watches the private channel configured by -`DISCORD_CHANNEL_ID`. It parses Lunaris `Version Change` announcements and -then fetches and synchronizes the latest version reported by Lunaris. On startup -it checks recent channel history, so it does not need to poll Lunaris while idle. +`DISCORD_CHANNEL_ID`. It parses new Lunaris `Version Change` announcements and +then fetches and synchronizes the latest version reported by Lunaris. Startup +only connects the listener; it does not replay channel history or start a sync. Worker and sync results are sent to `DISCORD_LOG_CHANNEL_ID`. Enable the Discord -Message Content intent and grant the bot View Channel, Read Message History, and -Send Messages in the configured channels. +Message Content intent and grant the bot View Channel and Send Messages in the +configured channels. Public snapshots use a shared Redis-backed Next.js cache. Admin routes remain dynamic. SSE streams send a 90-second heartbeat and close after 30 minutes so diff --git a/backend/discord.ts b/backend/discord.ts index 635918e..5b160cc 100644 --- a/backend/discord.ts +++ b/backend/discord.ts @@ -1,5 +1,4 @@ import { - ChannelType, Client, Events, GatewayIntentBits, @@ -144,10 +143,10 @@ async function drain(): Promise { } } -function enqueue(version: string, source: "history" | "message"): void { +function enqueue(version: string): void { if (!pendingVersion || compareLunarisVersions(version, pendingVersion) > 0) { pendingVersion = version; - log("version_queued", { version, source }); + log("version_queued", { version, source: "message" }); } if (!runner) { runner = drain().finally(() => { @@ -156,13 +155,13 @@ function enqueue(version: string, source: "history" | "message"): void { } } -function handleMessage(message: Message, source: "history" | "message"): void { +function handleMessage(message: Message): void { if (message.channelId !== channelId || message.author.id === client.user?.id) return; const change = parseLunarisVersionChange(messageText(message)); - if (change) enqueue(change.targetVersion, source); + if (change) enqueue(change.targetVersion); } -client.on(Events.MessageCreate, (message) => handleMessage(message, "message")); +client.on(Events.MessageCreate, handleMessage); client.on(Events.Error, (cause) => log("discord_error", { error: cause.message })); client.on(Events.Warn, (message) => log("discord_warning", { message })); @@ -186,18 +185,6 @@ try { if (!shutdown.signal.aborted) { log("discord_ready", { userId: client.user?.id, channelId }); await notify("worker ready", { userId: client.user?.id, channelId }); - - const channel = await client.channels.fetch(channelId); - if ( - !channel || - (channel.type !== ChannelType.GuildText && - channel.type !== ChannelType.GuildAnnouncement) - ) { - throw new Error("DISCORD_CHANNEL_ID must identify a guild text channel."); - } - const messages = await channel.messages.fetch({ limit: 25 }); - for (const message of messages.values()) handleMessage(message, "history"); - await stopped; } } finally { diff --git a/tests/deployment-contract.test.ts b/tests/deployment-contract.test.ts index 75a9610..e155bf7 100644 --- a/tests/deployment-contract.test.ts +++ b/tests/deployment-contract.test.ts @@ -180,4 +180,12 @@ describe("environment template contract", () => { expect(deployment).toContain('drop: ["ALL"]'); expect(rbac).toContain("buzz-sheet-discord-worker"); }); + + it("syncs only for new Discord version announcements", async () => { + const worker = await repositoryFile("backend/discord.ts"); + + expect(worker).toContain("client.on(Events.MessageCreate, handleMessage)"); + expect(worker).not.toContain("channel.messages.fetch"); + expect(worker).not.toContain('source: "history"'); + }); });