- Implemented AbsenceNotifyView for notifying absence with session details. - Created AnalyticsView for displaying group analytics and managing students at risk. - Added ClassAttendanceView for marking attendance in classes. - Defined new schemas for analytics and attendance in shared package.
53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
import type { PrismaClient } from '@generated/prisma/client';
|
|
import type {
|
|
ProblemDetails,
|
|
Result,
|
|
UpdateStudentStatus,
|
|
UpdateStudentStatusResult,
|
|
} from '@gruperly/shared';
|
|
import { err, ok } from '@gruperly/shared';
|
|
import { noGroupAccessProblem, notFoundResourceProblem } from '@/http/problem-builders';
|
|
import prisma from '@/lib/prisma';
|
|
|
|
type UpdateAttendeeStatusDeps = {
|
|
db?: Pick<PrismaClient, 'attendee'>;
|
|
};
|
|
|
|
export class UpdateAttendeeStatus {
|
|
constructor(private readonly deps: UpdateAttendeeStatusDeps = {}) {}
|
|
|
|
async execute(
|
|
studentId: string,
|
|
userId: string,
|
|
payload: UpdateStudentStatus,
|
|
): Promise<Result<UpdateStudentStatusResult, ProblemDetails>> {
|
|
const db = this.deps.db ?? prisma;
|
|
|
|
const attendee = await db.attendee.findUnique({
|
|
where: { id: studentId },
|
|
include: { group: { include: { members: { where: { userId } } } } },
|
|
});
|
|
|
|
if (!attendee) {
|
|
return err(notFoundResourceProblem('Attendee', studentId));
|
|
}
|
|
|
|
const isOwner = attendee.group.createdById === userId;
|
|
const isMember = attendee.group.members.length > 0;
|
|
if (!isOwner && !isMember) {
|
|
return err(noGroupAccessProblem());
|
|
}
|
|
|
|
if (attendee.status === payload.status) {
|
|
return ok({ attendeeId: studentId, status: payload.status });
|
|
}
|
|
|
|
const updated = await db.attendee.update({
|
|
where: { id: studentId },
|
|
data: { status: payload.status },
|
|
select: { id: true, status: true },
|
|
});
|
|
|
|
return ok({ attendeeId: updated.id, status: updated.status });
|
|
}
|
|
} |