feat(team-mode): add team mailbox ack with tests

This commit is contained in:
YeonGyu-Kim
2026-04-28 10:46:24 +09:00
parent 07368b4685
commit 3f69333939
2 changed files with 79 additions and 0 deletions
@@ -0,0 +1,45 @@
/// <reference types="bun-types" />
import { describe, expect, test } from "bun:test"
import { mkdtemp, readdir } from "node:fs/promises"
import { randomUUID } from "node:crypto"
import { tmpdir } from "node:os"
import path from "node:path"
import { TeamModeConfigSchema } from "../../../config/schema/team-mode"
import { getInboxDir, resolveBaseDir } from "../team-registry/paths"
import { ackMessages } from "./ack"
import { sendMessage } from "./send"
async function createBaseDirectory(): Promise<string> {
return await mkdtemp(path.join(tmpdir(), "team-mailbox-ack-"))
}
describe("ackMessages", () => {
test("moves inbox files into processed and stays idempotent", async () => {
// given
const config = TeamModeConfigSchema.parse({ base_dir: await createBaseDirectory() })
const teamRunId = randomUUID()
const messageId = randomUUID()
await sendMessage({
version: 1,
messageId,
from: "lead",
to: "m1",
kind: "message",
body: "hello",
timestamp: 100,
}, teamRunId, config, { isLead: true, activeMembers: ["m1"] })
// when
await ackMessages(teamRunId, "m1", [messageId], config)
await ackMessages(teamRunId, "m1", [messageId], config)
// then
const inboxDir = getInboxDir(resolveBaseDir(config), teamRunId, "m1")
const inboxEntries = await readdir(inboxDir)
const processedEntries = await readdir(path.join(inboxDir, "processed"))
expect(inboxEntries).not.toContain(`${messageId}.json`)
expect(processedEntries).toContain(`${messageId}.json`)
})
})
@@ -0,0 +1,34 @@
import { mkdir, rename } from "node:fs/promises"
import path from "node:path"
import type { TeamModeConfig } from "../../../config/schema/team-mode"
import { getInboxDir, resolveBaseDir } from "../team-registry/paths"
export async function ackMessages(
teamRunId: string,
memberName: string,
messageIds: string[],
config: TeamModeConfig,
): Promise<void> {
const baseDir = resolveBaseDir(config)
const inboxDir = getInboxDir(baseDir, teamRunId, memberName)
const processedDir = path.join(inboxDir, "processed")
await mkdir(processedDir, { recursive: true, mode: 0o700 })
for (const messageId of messageIds) {
const messageFileName = `${messageId}.json`
const sourcePath = path.join(inboxDir, messageFileName)
const targetPath = path.join(processedDir, messageFileName)
try {
await rename(sourcePath, targetPath)
} catch (error) {
const err = error as NodeJS.ErrnoException
if (err.code === "ENOENT") {
continue
}
throw error
}
}
}