refactor(chat): remove guest history synchronization
This commit is contained in:
@@ -1,84 +0,0 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { Result } from "@/utils/result";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
getDeviceId: vi.fn(),
|
||||
getLocalMessages: vi.fn(),
|
||||
syncGuestHistory: vi.fn(),
|
||||
clearLocalMessages: vi.fn(),
|
||||
getGuestChatOwnerKey: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/data/storage/auth", () => ({
|
||||
AuthStorage: {
|
||||
getInstance: () => ({ getDeviceId: mocks.getDeviceId }),
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("@/data/repositories/chat_repository_loader", () => ({
|
||||
loadChatRepository: async () => ({
|
||||
getLocalMessages: mocks.getLocalMessages,
|
||||
syncGuestHistory: mocks.syncGuestHistory,
|
||||
clearLocalMessages: mocks.clearLocalMessages,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("@/data/storage/navigation", () => ({
|
||||
NavigationStorage: {
|
||||
getGuestChatOwnerKey: mocks.getGuestChatOwnerKey,
|
||||
},
|
||||
}));
|
||||
|
||||
import { syncGuestHistoriesToUser } from "../guest-history-sync";
|
||||
|
||||
describe("syncGuestHistoriesToUser", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
mocks.getDeviceId.mockResolvedValue(Result.ok("device-1"));
|
||||
mocks.getGuestChatOwnerKey.mockResolvedValue(null);
|
||||
mocks.clearLocalMessages.mockResolvedValue(Result.ok(undefined));
|
||||
});
|
||||
|
||||
it("groups guest history by character and clears only successful caches", async () => {
|
||||
mocks.getLocalMessages.mockImplementation(async (identity: string) =>
|
||||
Result.ok([
|
||||
{
|
||||
id: `${identity}:message`,
|
||||
role: "user",
|
||||
type: "text",
|
||||
content: identity,
|
||||
createdAt: "2026-07-20T00:00:00.000Z",
|
||||
},
|
||||
]),
|
||||
);
|
||||
mocks.syncGuestHistory.mockImplementation(
|
||||
async (request: { characterId: string }) =>
|
||||
request.characterId === "elio"
|
||||
? Result.ok(undefined)
|
||||
: Result.err(new Error("offline")),
|
||||
);
|
||||
|
||||
await syncGuestHistoriesToUser(["elio", "maya-tan"]);
|
||||
|
||||
expect(mocks.syncGuestHistory).toHaveBeenCalledTimes(2);
|
||||
expect(mocks.syncGuestHistory).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ characterId: "elio" }),
|
||||
);
|
||||
expect(mocks.syncGuestHistory).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ characterId: "maya-tan" }),
|
||||
);
|
||||
expect(mocks.clearLocalMessages).toHaveBeenCalledOnce();
|
||||
expect(mocks.clearLocalMessages).toHaveBeenCalledWith(
|
||||
"device:device-1::character:elio",
|
||||
);
|
||||
});
|
||||
|
||||
it("skips characters without guest messages", async () => {
|
||||
mocks.getLocalMessages.mockResolvedValue(Result.ok([]));
|
||||
|
||||
await syncGuestHistoriesToUser(["elio"]);
|
||||
|
||||
expect(mocks.syncGuestHistory).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,65 +0,0 @@
|
||||
import { AuthStorage } from "@/data/storage/auth";
|
||||
import { NavigationStorage } from "@/data/storage/navigation";
|
||||
import { loadChatRepository } from "@/data/repositories/chat_repository_loader";
|
||||
import { ChatSyncRequestSchema } from "@/data/schemas/chat";
|
||||
import { buildChatConversationKey } from "@/lib/chat/chat_cache_keys";
|
||||
import { Logger } from "@/utils/logger";
|
||||
import { Result } from "@/utils/result";
|
||||
|
||||
const log = new Logger("StoresChatGuestHistorySync");
|
||||
|
||||
export async function syncGuestHistoriesToUser(
|
||||
characterIds: readonly string[],
|
||||
): Promise<void> {
|
||||
const deviceResult = await AuthStorage.getInstance().getDeviceId();
|
||||
const savedOwnerKey = await NavigationStorage.getGuestChatOwnerKey();
|
||||
const ownerKey =
|
||||
savedOwnerKey ??
|
||||
(Result.isOk(deviceResult) && deviceResult.data
|
||||
? `device:${deviceResult.data}`
|
||||
: null);
|
||||
if (!ownerKey) return;
|
||||
|
||||
const repository = await loadChatRepository();
|
||||
await Promise.allSettled(
|
||||
[...new Set(characterIds)].map(async (characterId) => {
|
||||
const cacheIdentity = buildChatConversationKey(ownerKey, characterId);
|
||||
const messagesResult = await repository.getLocalMessages(cacheIdentity);
|
||||
if (Result.isErr(messagesResult) || messagesResult.data.length === 0) return;
|
||||
|
||||
const messages = messagesResult.data.flatMap((message) => {
|
||||
if (message.role !== "user" && message.role !== "assistant") return [];
|
||||
return [{
|
||||
role: message.role,
|
||||
content: message.content,
|
||||
timestamp: normalizeTimestamp(message.createdAt),
|
||||
}];
|
||||
});
|
||||
if (messages.length === 0) return;
|
||||
|
||||
const request = ChatSyncRequestSchema.parse({ characterId, messages });
|
||||
const syncResult = await repository.syncGuestHistory(request);
|
||||
if (Result.isErr(syncResult)) {
|
||||
log.warn("[chat-sync] guest history sync failed", {
|
||||
characterId,
|
||||
error: syncResult.error,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const clearResult = await repository.clearLocalMessages(cacheIdentity);
|
||||
if (Result.isErr(clearResult)) {
|
||||
log.warn("[chat-sync] guest history cleanup failed", {
|
||||
characterId,
|
||||
error: clearResult.error,
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeTimestamp(value: string): string {
|
||||
const parsed = new Date(value);
|
||||
return Number.isNaN(parsed.getTime())
|
||||
? new Date().toISOString()
|
||||
: parsed.toISOString();
|
||||
}
|
||||
Reference in New Issue
Block a user