- ingestProject now calls relinkProject after every store - updateCard relinks when scopeScope rule is in the patch - acceptCard, archiveCard, unlinkCommitArchiveCard relink after their change - three owner Server Actions for the tray: relinkProjectAction, linkCommitAction, unlinkCommitAction
54 lines
No EOL
1.4 KiB
TypeScript
54 lines
No EOL
1.4 KiB
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
|
|
import { requireSession } from "@/lib/auth/session";
|
|
import {
|
|
linkCommitManually,
|
|
relinkProject,
|
|
unlinkCommit,
|
|
} from "@/lib/linking/engine";
|
|
|
|
/** See the security note at the top of src/app/actions/cards.ts. */
|
|
async function requireOwner() {
|
|
const session = await requireSession();
|
|
if (session.role !== "owner") throw new Error("Not found");
|
|
return session;
|
|
}
|
|
|
|
export async function relinkProjectAction(input: {
|
|
projectId: string;
|
|
clientSlug: string;
|
|
projectSlug: string;
|
|
}): Promise<{ linked: number; unlinked: number; preserved: number }> {
|
|
await requireOwner();
|
|
const result = await relinkProject(input.projectId);
|
|
|
|
revalidatePath(`/p/${input.clientSlug}/${input.projectSlug}/unassigned`);
|
|
return {
|
|
linked: result.linked,
|
|
unlinked: result.unlinked,
|
|
preserved: result.preserved,
|
|
};
|
|
}
|
|
|
|
export async function linkCommitAction(input: {
|
|
commitId: string;
|
|
cardId: string;
|
|
clientSlug: string;
|
|
projectSlug: string;
|
|
}): Promise<void> {
|
|
await requireOwner();
|
|
await linkCommitManually(input.commitId, input.cardId);
|
|
revalidatePath(`/p/${input.clientSlug}/${input.projectSlug}/unassigned`);
|
|
}
|
|
|
|
export async function unlinkCommitAction(input: {
|
|
commitId: string;
|
|
clientSlug: string;
|
|
projectSlug: string;
|
|
}): Promise<void> {
|
|
await requireOwner();
|
|
await unlinkCommit(input.commitId);
|
|
revalidatePath(`/p/${input.clientSlug}/${input.projectSlug}/unassigned`);
|
|
} |