feat(hk): explain background updates with protected content links and retry details
CI / check (push) Failing after 1m34s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped

This commit is contained in:
Simo committed 2026-09-13 19:41:25 +02:00
1 parent dd7613850e
commit c5c9941768
42 files changed
+1542 -145

No files matched your search

+14
View File
@@ -51,6 +51,8 @@ vi.mock("@/lib/db", async () => {
requestHash: String(hash),
resultJson: null,
});
} else if (sql.startsWith("SELECT CAST(LAST_INSERT_ID() AS CHAR)")) {
return [[{ id: "9007199254740993" }]];
} else if (sql.startsWith("SELECT id,request_hash")) {
return [[state.operations.get(params.join(":"))]];
} else if (sql.startsWith("UPDATE cms_operations")) {
@@ -121,6 +123,18 @@ describe("news saves", () => {
expect(state.notify).toHaveBeenCalledOnce();
expect(state.effects).toHaveLength(1);
});
it("stores safe article context for background deliveries without the body", async () => {
expect((await createArticle(form())).ok).toBe(true);
const result = JSON.parse(
[...state.operations.values()][0].resultJson ?? "null",
);
expect(result).toEqual({
ok: true,
articleId: "9007199254740993",
articleTitle: "Test news",
});
expect(result).not.toHaveProperty("fullStory");
});
it("returns success when cache refresh fails after the article commits", async () => {
state.invalidate.mockRejectedValue(Error("cache unavailable"));
await expect(createArticle(form())).resolves.toMatchObject({ ok: true });
+10 -3
View File
@@ -1,7 +1,7 @@
"use server";
import { createHash, randomUUID } from "node:crypto";
import { and, eq, ne } from "drizzle-orm";
import { and, eq, ne, sql } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
import { getTranslations } from "next-intl/server";
@@ -128,6 +128,13 @@ export async function createArticle(
updatedAt: now,
publishedAt: fields.status === "published" ? now : null,
});
const [createdRows] = await tx.execute(
sql`SELECT CAST(LAST_INSERT_ID() AS CHAR) AS id`,
);
const articleId = (createdRows as unknown as Array<{ id: string }>)[0]
?.id;
if (!articleId || !/^[1-9][0-9]*$/.test(articleId))
throw new Error("Article identity unavailable");
await enqueueEffect(tx, operationId, "news.refresh");
if (input.status === "published")
notification = {
@@ -136,7 +143,7 @@ export async function createArticle(
target: input.title,
details: slug,
};
return { ok: true };
return { ok: true, articleId, articleTitle: input.title };
},
);
} catch (error) {
@@ -219,7 +226,7 @@ export async function updateArticle(
.where(eq(WebsiteArticles.id, id));
await recordHistory(tx, "news", historyId, staff.id, historyBefore);
await enqueueEffect(tx, operationId, "news.refresh");
return { ok: true };
return { ok: true, articleId: String(id), articleTitle: input.title };
},
);
} catch (error) {