fix(chat): make cloud the only truth for charts, synastry, and pin/archive
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled

Local fallbacks were creating fake saves and resurrecting deleted rows.
Pin and archive now live on chat_sessions so they follow the account.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-01 21:38:21 +08:00
co-authored by Cursor
parent 31c7b48261
commit ce6a8a7e72
16 changed files with 390 additions and 153 deletions
+10 -1
View File
@@ -1,7 +1,7 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
import { chatSessionCreateSchema, chatSessionWriteSchema, writeChatSession, type ChatSessionWrite } from "../src/lib/chat-session-write-contract.ts";
import { chatSessionCreateSchema, chatSessionMetadataPatchSchema, chatSessionWriteSchema, writeChatSession, type ChatSessionWrite } from "../src/lib/chat-session-write-contract.ts";
const sessionId = "11111111-1111-4111-8111-111111111111";
const values = {
@@ -111,6 +111,15 @@ test("chat session schema keeps structured thinking sections on assistant messag
assert.equal(parsed.messages[0]?.thinkingSections?.[0]?.heading, "统一参数与原始结构");
});
test("metadata patch accepts pin and archive fields without a transcript", () => {
assert.deepEqual(chatSessionMetadataPatchSchema.parse({ pinned: true }), { pinned: true });
assert.deepEqual(
chatSessionMetadataPatchSchema.parse({ archived_at: "2026-09-01T00:00:00.000Z" }),
{ archived_at: "2026-09-01T00:00:00.000Z" },
);
assert.deepEqual(chatSessionMetadataPatchSchema.parse({ archived_at: null }), { archived_at: null });
});
test("chat session writes use same-origin API instead of browser-to-Supabase requests", async () => {
const calls: Array<{ url: string; init?: RequestInit }> = [];
await writeChatSession(sessionId, metadataPatch, "update", async (url, init) => {