forked from EduCraft/curriculum-project-hub
feat: add paginated project discovery
This commit is contained in:
@@ -53,6 +53,13 @@ export interface ArchiveFeishuChatBindingInput {
|
||||
readonly actorFeishuOpenId: string;
|
||||
}
|
||||
|
||||
export interface RenameProjectForActorInput {
|
||||
readonly organizationId: string;
|
||||
readonly projectId: string;
|
||||
readonly actorFeishuOpenId: string;
|
||||
readonly name: string;
|
||||
}
|
||||
|
||||
export interface CreateFolderInput {
|
||||
readonly organizationId: string;
|
||||
readonly name: string;
|
||||
@@ -131,6 +138,44 @@ export async function moveProjectToFolder(
|
||||
});
|
||||
}
|
||||
|
||||
export async function renameProjectForActor(
|
||||
prisma: PrismaClient,
|
||||
input: RenameProjectForActorInput,
|
||||
): Promise<{ readonly projectId: string; readonly name: string }> {
|
||||
const name = requireNonEmpty(input.name, "project name");
|
||||
const project = await prisma.project.findUnique({
|
||||
where: { id: input.projectId },
|
||||
select: { id: true, organizationId: true, name: true },
|
||||
});
|
||||
if (project === null) throw new Error(`project not found: ${input.projectId}`);
|
||||
if (project.organizationId !== input.organizationId) {
|
||||
throw new Error(`project ${project.id} does not belong to organization ${input.organizationId}`);
|
||||
}
|
||||
const actor = await requireProjectManager(prisma, project.id, project.organizationId, input.actorFeishuOpenId);
|
||||
const updated = await prisma.$transaction(async (tx) => {
|
||||
await lockActiveOrganization(tx, project.organizationId);
|
||||
const current = await tx.project.findUniqueOrThrow({
|
||||
where: { id: project.id },
|
||||
select: { name: true },
|
||||
});
|
||||
const renamed = await tx.project.update({
|
||||
where: { id: project.id },
|
||||
data: { name },
|
||||
select: { id: true, name: true },
|
||||
});
|
||||
await tx.auditEntry.create({
|
||||
data: {
|
||||
projectId: project.id,
|
||||
actorUserId: actor.userId,
|
||||
action: "project.renamed",
|
||||
metadata: { oldName: current.name, newName: name, actorVia: actor.via },
|
||||
},
|
||||
});
|
||||
return renamed;
|
||||
});
|
||||
return { projectId: updated.id, name: updated.name };
|
||||
}
|
||||
|
||||
export async function createProjectFromOrgAdmin(
|
||||
prisma: PrismaClient,
|
||||
input: CreateOrgAdminProjectInput,
|
||||
@@ -494,12 +539,12 @@ async function ensureOrganizationProjectSettingsTx(
|
||||
|
||||
async function ensureInboxFolder(prisma: Prisma.TransactionClient, organizationId: string): Promise<{ readonly id: string }> {
|
||||
const existing = await prisma.folder.findFirst({
|
||||
where: { organizationId, parentId: null, name: "Inbox", archivedAt: null },
|
||||
where: { organizationId, kind: "SYSTEM_INBOX", archivedAt: null },
|
||||
select: { id: true },
|
||||
});
|
||||
if (existing !== null) return existing;
|
||||
return prisma.folder.create({
|
||||
data: { organizationId, name: "Inbox", sortKey: "000000" },
|
||||
data: { organizationId, name: "Inbox", kind: "SYSTEM_INBOX", sortKey: "000000" },
|
||||
select: { id: true },
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user