Fix owner card creation number allocation
This commit is contained in:
parent
9cb25b266e
commit
d9f6ac0fad
5 changed files with 58 additions and 2 deletions
50
src/app/actions/cards.test.ts
Normal file
50
src/app/actions/cards.test.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { createCard } from "@/app/actions/cards";
|
||||
import { requireSession } from "@/lib/auth/session";
|
||||
import { getServerPb } from "@/lib/pb/server";
|
||||
import { resolveWorkArea } from "@/lib/work-areas/server";
|
||||
|
||||
vi.mock("next/cache", () => ({ revalidatePath: vi.fn() }));
|
||||
vi.mock("@/lib/auth/session", () => ({ requireSession: vi.fn() }));
|
||||
vi.mock("@/lib/pb/server", () => ({ getServerPb: vi.fn() }));
|
||||
vi.mock("@/lib/work-areas/server", () => ({ resolveWorkArea: vi.fn() }));
|
||||
vi.mock("@/app/actions/activity", () => ({ logActivity: vi.fn() }));
|
||||
|
||||
describe("owner card creation", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
vi.mocked(requireSession).mockResolvedValue({ userId: "owner-1", role: "owner", clientId: "" });
|
||||
vi.mocked(resolveWorkArea).mockResolvedValue("area-1");
|
||||
});
|
||||
|
||||
it("assigns the next project card number when creating a card", async () => {
|
||||
const create = vi.fn(async () => ({ id: "new-card" }));
|
||||
const cards = {
|
||||
getFirstListItem: vi.fn(async () => ({ position: 1000 })),
|
||||
getFullList: vi.fn(async () => [{ number: 0 }, { number: 5 }, { number: 3 }]),
|
||||
create,
|
||||
};
|
||||
vi.mocked(getServerPb).mockResolvedValue({ collection: () => cards } as never);
|
||||
|
||||
const result = await createCard({
|
||||
projectId: "project-1",
|
||||
columnId: "inbox-1",
|
||||
title: "Prepare a delivery note",
|
||||
clientSlug: "mega-infrastructure",
|
||||
projectSlug: "mega-dashboard",
|
||||
areaId: "area-1",
|
||||
});
|
||||
|
||||
expect(result).toEqual({ id: "new-card" });
|
||||
expect(cards.getFullList).toHaveBeenCalledWith({
|
||||
filter: 'project = "project-1"',
|
||||
fields: "number",
|
||||
});
|
||||
expect(create).toHaveBeenCalledWith(expect.objectContaining({
|
||||
project: "project-1",
|
||||
work_area: "area-1",
|
||||
number: 6,
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
|
@ -58,6 +58,10 @@ export async function createCard(input: {
|
|||
sort: "-position",
|
||||
})
|
||||
.catch(() => null);
|
||||
const numbered = await pb.collection("cards").getFullList<CardRecord>({
|
||||
filter: `project = "${input.projectId}"`,
|
||||
fields: "number",
|
||||
});
|
||||
|
||||
const card = await pb.collection("cards").create<CardRecord>({
|
||||
project: input.projectId,
|
||||
|
|
@ -71,6 +75,7 @@ export async function createCard(input: {
|
|||
created_by_role: "owner",
|
||||
accepted: true,
|
||||
archived: false,
|
||||
number: nextCardNumber(numbered.map((existing) => existing.number)),
|
||||
});
|
||||
|
||||
await logActivity({
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ describe("parseBrief — it is a whitelist, not a parser", () => {
|
|||
number: 1,
|
||||
});
|
||||
|
||||
const brief = parseBrief(hostile, turns) as Record<string, unknown>;
|
||||
const brief = parseBrief(hostile, turns) as unknown as Record<string, unknown>;
|
||||
|
||||
expect(brief.priority).toBeUndefined();
|
||||
expect(brief.accepted).toBeUndefined();
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ function card(overrides: Partial<CardRecord> = {}): CardRecord {
|
|||
updated: "2026-01-01 00:00:00.000Z",
|
||||
project: "p1",
|
||||
column: "col1",
|
||||
work_area: "",
|
||||
title: "Refactor billing modal",
|
||||
description: "",
|
||||
position: 0,
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ describe("a hostile brief cannot escalate", () => {
|
|||
created_by_role: "owner",
|
||||
});
|
||||
|
||||
const brief = parseBrief(hostile, []) as Record<string, unknown>;
|
||||
const brief = parseBrief(hostile, []) as unknown as Record<string, unknown>;
|
||||
|
||||
for (const forbidden of [
|
||||
"priority",
|
||||
|
|
|
|||
Loading…
Reference in a new issue