f1b1aa5975
Define full Prisma schema (10 models), run initial migration, build core services (auth, user, group, app, board, permission), Zod validators, type definitions, API response envelope, constants, and seed script.
126 lines
2.8 KiB
TypeScript
126 lines
2.8 KiB
TypeScript
import { prisma } from '../prisma.js';
|
|
import type { CreateGroupInput, UpdateGroupInput } from '$lib/types/group.js';
|
|
|
|
export async function findAll() {
|
|
return prisma.group.findMany({
|
|
orderBy: { name: 'asc' },
|
|
include: {
|
|
_count: { select: { users: true } }
|
|
}
|
|
});
|
|
}
|
|
|
|
export async function findById(id: string) {
|
|
const group = await prisma.group.findUnique({
|
|
where: { id },
|
|
include: {
|
|
_count: { select: { users: true } }
|
|
}
|
|
});
|
|
if (!group) {
|
|
throw new Error(`Group not found: ${id}`);
|
|
}
|
|
return group;
|
|
}
|
|
|
|
export async function findByName(name: string) {
|
|
return prisma.group.findUnique({
|
|
where: { name }
|
|
});
|
|
}
|
|
|
|
export async function findDefaultGroups() {
|
|
return prisma.group.findMany({
|
|
where: { isDefault: true }
|
|
});
|
|
}
|
|
|
|
export async function create(input: CreateGroupInput) {
|
|
const existing = await prisma.group.findUnique({
|
|
where: { name: input.name }
|
|
});
|
|
if (existing) {
|
|
throw new Error(`Group with name "${input.name}" already exists`);
|
|
}
|
|
|
|
return prisma.group.create({
|
|
data: {
|
|
name: input.name,
|
|
description: input.description ?? null,
|
|
isDefault: input.isDefault ?? false
|
|
}
|
|
});
|
|
}
|
|
|
|
export async function update(id: string, input: UpdateGroupInput) {
|
|
await findById(id);
|
|
|
|
if (input.name) {
|
|
const existing = await prisma.group.findFirst({
|
|
where: { name: input.name, NOT: { id } }
|
|
});
|
|
if (existing) {
|
|
throw new Error(`Group with name "${input.name}" already exists`);
|
|
}
|
|
}
|
|
|
|
return prisma.group.update({
|
|
where: { id },
|
|
data: {
|
|
...(input.name !== undefined ? { name: input.name } : {}),
|
|
...(input.description !== undefined ? { description: input.description } : {}),
|
|
...(input.isDefault !== undefined ? { isDefault: input.isDefault } : {})
|
|
}
|
|
});
|
|
}
|
|
|
|
export async function remove(id: string) {
|
|
await findById(id);
|
|
await prisma.group.delete({ where: { id } });
|
|
}
|
|
|
|
export async function addUser(groupId: string, userId: string) {
|
|
const existing = await prisma.userGroup.findUnique({
|
|
where: { userId_groupId: { userId, groupId } }
|
|
});
|
|
if (existing) {
|
|
return existing;
|
|
}
|
|
|
|
return prisma.userGroup.create({
|
|
data: { userId, groupId }
|
|
});
|
|
}
|
|
|
|
export async function removeUser(groupId: string, userId: string) {
|
|
await prisma.userGroup.deleteMany({
|
|
where: { userId, groupId }
|
|
});
|
|
}
|
|
|
|
export async function getGroupMembers(groupId: string) {
|
|
const memberships = await prisma.userGroup.findMany({
|
|
where: { groupId },
|
|
include: {
|
|
user: {
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
displayName: true,
|
|
role: true,
|
|
avatarUrl: true
|
|
}
|
|
}
|
|
}
|
|
});
|
|
return memberships.map((m) => m.user);
|
|
}
|
|
|
|
export async function addUserToDefaultGroups(userId: string) {
|
|
const defaultGroups = await findDefaultGroups();
|
|
const results = await Promise.all(
|
|
defaultGroups.map((group) => addUser(group.id, userId))
|
|
);
|
|
return results;
|
|
}
|