fix(api): bind daily and synastry charts to stored profiles
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled

Stop accepting client-supplied birth data on those paths, and cap session writes plus location lookups so a logged-in caller cannot farm compute.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-19 19:39:01 +08:00
co-authored by Cursor
parent 40a595045e
commit c38f11dbd3
16 changed files with 548 additions and 39 deletions
+22
View File
@@ -77,6 +77,24 @@ test("owner or validation failures are not retried", async () => {
assert.equal(attempts, 1);
});
test("session writes reject oversized transcripts before they reach storage", () => {
const oversized = chatSessionWriteSchema.safeParse({
...values,
messages: [{ role: "user", text: "字".repeat(16_001) }],
});
const tooMany = chatSessionWriteSchema.safeParse({
...values,
messages: Array.from({ length: 201 }, () => ({ role: "user" as const, text: "你好" })),
});
const tooMuchText = chatSessionWriteSchema.safeParse({
...values,
messages: Array.from({ length: 20 }, () => ({ role: "user" as const, text: "字".repeat(12_000) })),
});
assert.equal(oversized.success, false);
assert.equal(tooMany.success, false);
assert.equal(tooMuchText.success, false);
});
test("session API owns create and update while answer UI keeps sync failures out of reply errors", () => {
const page = readFileSync(new URL("../src/app/page.tsx", import.meta.url), "utf8");
const collectionRoute = readFileSync(new URL("../src/app/api/sessions/route.ts", import.meta.url), "utf8");
@@ -87,6 +105,10 @@ test("session API owns create and update while answer UI keeps sync failures out
assert.match(collectionRoute, /export async function POST/);
assert.match(itemRoute, /export async function PATCH/);
assert.match(itemRoute, /\.eq\("user_id", user\.id\)/);
assert.match(collectionRoute, /readChatSessionJson/);
assert.match(itemRoute, /readChatSessionJson/);
assert.match(collectionRoute, /ChatSessionBodyTooLargeError/);
assert.match(itemRoute, /ChatSessionBodyTooLargeError/);
});