forked from bai/curriculum-project-hub
feat(database): init database folder frontend and permission
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* GroupResolver port(契约 C2)。
|
||||
*
|
||||
* 权限计算只依赖这一个查询:"用户 → 所属 Group(含全部祖先)"。
|
||||
* Group 系统(需求系统二:全局、无限嵌套)由别的团队交付;调用方只依赖此
|
||||
* port,真身到位后替换实现,不换调用点。
|
||||
*/
|
||||
|
||||
import type { PrismaClient } from "@prisma/client";
|
||||
|
||||
export interface GroupResolver {
|
||||
resolveMemberGroupIds(userId: string): Promise<readonly string[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 过渡实现:读 hub 既有 Team(org 内、扁平无嵌套 → "祖先即自身")。
|
||||
* 需求 3.2 的祖先递归语义在嵌套 Group 落地前无从谈起;此实现保证权限引擎
|
||||
* 的 Group 通路今天就是真的,而不是 mock。
|
||||
*/
|
||||
export function createTeamGroupResolver(
|
||||
prisma: PrismaClient,
|
||||
organizationId: string,
|
||||
): GroupResolver {
|
||||
return {
|
||||
async resolveMemberGroupIds(userId) {
|
||||
const memberships = await prisma.teamMembership.findMany({
|
||||
where: {
|
||||
userId,
|
||||
revokedAt: null,
|
||||
team: { organizationId, archivedAt: null },
|
||||
},
|
||||
select: { teamId: true },
|
||||
});
|
||||
return memberships.map((m) => m.teamId);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** 单测 mock:静态 用户→组 映射。 */
|
||||
export function createStaticGroupResolver(
|
||||
map: Readonly<Record<string, readonly string[]>>,
|
||||
): GroupResolver {
|
||||
return {
|
||||
async resolveMemberGroupIds(userId) {
|
||||
return map[userId] ?? [];
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user