151 lines
3.8 KiB
TypeScript
151 lines
3.8 KiB
TypeScript
import { mutation, query } from "./_generated/server";
|
|
import { v } from "convex/values";
|
|
import { nowIso } from "./_utils/time";
|
|
import type { MutationCtx, QueryCtx } from "./_generated/server";
|
|
|
|
async function assertWorkspaceMember(
|
|
ctx: QueryCtx | MutationCtx,
|
|
userId: string,
|
|
workspaceId: string,
|
|
) {
|
|
const membership = await ctx.db
|
|
.query("workspace_members")
|
|
.withIndex("by_workspace_user", (q) =>
|
|
q.eq("workspace_id", workspaceId).eq("user_id", userId),
|
|
)
|
|
.first();
|
|
if (!membership) {
|
|
throw new Error("无权访问该工作空间");
|
|
}
|
|
return membership;
|
|
}
|
|
|
|
export const getById = query({
|
|
args: {
|
|
userId: v.string(),
|
|
workspaceId: v.string(),
|
|
id: v.string(),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
await assertWorkspaceMember(ctx, args.userId, args.workspaceId);
|
|
return await ctx.db
|
|
.query("pages")
|
|
.withIndex("by_page_id", (q) => q.eq("id", args.id))
|
|
.first();
|
|
},
|
|
});
|
|
|
|
export const listByWorkspace = query({
|
|
args: {
|
|
userId: v.string(),
|
|
workspaceId: v.string(),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
await assertWorkspaceMember(ctx, args.userId, args.workspaceId);
|
|
return await ctx.db
|
|
.query("pages")
|
|
.withIndex("by_workspace", (q) => q.eq("workspace_id", args.workspaceId))
|
|
.collect();
|
|
},
|
|
});
|
|
|
|
export const create = mutation({
|
|
args: {
|
|
userId: v.string(),
|
|
id: v.string(),
|
|
workspaceId: v.string(),
|
|
parentId: v.union(v.string(), v.null()),
|
|
title: v.string(),
|
|
accessScope: v.union(
|
|
v.literal("private"),
|
|
v.literal("shared"),
|
|
v.literal("public"),
|
|
),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
await assertWorkspaceMember(ctx, args.userId, args.workspaceId);
|
|
const ts = nowIso();
|
|
await ctx.db.insert("pages", {
|
|
id: args.id,
|
|
workspace_id: args.workspaceId,
|
|
parent_id: args.parentId,
|
|
title: args.title,
|
|
access_scope: args.accessScope,
|
|
block_ids: [],
|
|
child_page_ids: [],
|
|
asset_ids: [],
|
|
created_by: args.userId,
|
|
created_at: ts,
|
|
updated_at: ts,
|
|
deleted_at: null,
|
|
});
|
|
return { ok: true, id: args.id };
|
|
},
|
|
});
|
|
|
|
export const rename = mutation({
|
|
args: {
|
|
userId: v.string(),
|
|
workspaceId: v.string(),
|
|
id: v.string(),
|
|
title: v.string(),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
await assertWorkspaceMember(ctx, args.userId, args.workspaceId);
|
|
const page = await ctx.db
|
|
.query("pages")
|
|
.withIndex("by_page_id", (q) => q.eq("id", args.id))
|
|
.first();
|
|
if (!page) throw new Error("页面不存在");
|
|
await ctx.db.patch(page._id, {
|
|
title: args.title,
|
|
updated_at: nowIso(),
|
|
});
|
|
return { ok: true };
|
|
},
|
|
});
|
|
|
|
export const move = mutation({
|
|
args: {
|
|
userId: v.string(),
|
|
workspaceId: v.string(),
|
|
id: v.string(),
|
|
parentId: v.union(v.string(), v.null()),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
await assertWorkspaceMember(ctx, args.userId, args.workspaceId);
|
|
const page = await ctx.db
|
|
.query("pages")
|
|
.withIndex("by_page_id", (q) => q.eq("id", args.id))
|
|
.first();
|
|
if (!page) throw new Error("页面不存在");
|
|
await ctx.db.patch(page._id, {
|
|
parent_id: args.parentId,
|
|
updated_at: nowIso(),
|
|
});
|
|
return { ok: true };
|
|
},
|
|
});
|
|
|
|
export const archive = mutation({
|
|
args: {
|
|
userId: v.string(),
|
|
workspaceId: v.string(),
|
|
id: v.string(),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
await assertWorkspaceMember(ctx, args.userId, args.workspaceId);
|
|
const page = await ctx.db
|
|
.query("pages")
|
|
.withIndex("by_page_id", (q) => q.eq("id", args.id))
|
|
.first();
|
|
if (!page) throw new Error("页面不存在");
|
|
const ts = nowIso();
|
|
await ctx.db.patch(page._id, {
|
|
deleted_at: ts,
|
|
updated_at: ts,
|
|
});
|
|
return { ok: true };
|
|
},
|
|
});
|