fix(final-docs): exclude dropped mentors from doc access; relative in-app reminder link
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m43s
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m43s
Review follow-ups: mentor.getProjectFinalDocuments now filters droppedAt:null (a dropped mentor no longer sees a team's final docs); reminder linkUrl is relative so the in-app notification does client-side nav (email still absolutized). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -223,7 +223,7 @@ export const mentorRouter = router({
|
|||||||
const isAdmin = ['SUPER_ADMIN', 'PROGRAM_ADMIN'].includes(ctx.user.role)
|
const isAdmin = ['SUPER_ADMIN', 'PROGRAM_ADMIN'].includes(ctx.user.role)
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
const [mentorAssignment, teamMembership] = await Promise.all([
|
const [mentorAssignment, teamMembership] = await Promise.all([
|
||||||
ctx.prisma.mentorAssignment.findFirst({ where: { mentorId: ctx.user.id, projectId: input.projectId }, select: { id: true } }),
|
ctx.prisma.mentorAssignment.findFirst({ where: { mentorId: ctx.user.id, projectId: input.projectId, droppedAt: null }, select: { id: true } }),
|
||||||
ctx.prisma.teamMember.findFirst({ where: { userId: ctx.user.id, projectId: input.projectId }, select: { id: true } }),
|
ctx.prisma.teamMember.findFirst({ where: { userId: ctx.user.id, projectId: input.projectId }, select: { id: true } }),
|
||||||
])
|
])
|
||||||
if (!mentorAssignment && !teamMembership) throw new TRPCError({ code: 'FORBIDDEN', message: 'No access to this project' })
|
if (!mentorAssignment && !teamMembership) throw new TRPCError({ code: 'FORBIDDEN', message: 'No access to this project' })
|
||||||
|
|||||||
@@ -88,10 +88,6 @@ export async function getFinalDocumentStatusForProject(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function baseUrl(): string {
|
|
||||||
return (process.env.NEXTAUTH_URL ?? 'http://localhost:3000').replace(/\/$/, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Build the reminder notification payload for one finalist team lead. */
|
/** Build the reminder notification payload for one finalist team lead. */
|
||||||
async function remindTeam(
|
async function remindTeam(
|
||||||
prisma: PrismaClient,
|
prisma: PrismaClient,
|
||||||
@@ -104,7 +100,7 @@ async function remindTeam(
|
|||||||
message: args.missing.length
|
message: args.missing.length
|
||||||
? `Still needed for "${args.projectTitle}": ${args.missing.join(', ')}.`
|
? `Still needed for "${args.projectTitle}": ${args.missing.join(', ')}.`
|
||||||
: `Please upload the final documents for "${args.projectTitle}".`,
|
: `Please upload the final documents for "${args.projectTitle}".`,
|
||||||
linkUrl: `${baseUrl()}/applicant/documents`,
|
linkUrl: `/applicant/documents`, // relative → client-side nav in-app; email renderer absolutizes
|
||||||
metadata: {
|
metadata: {
|
||||||
projectId: args.projectId,
|
projectId: args.projectId,
|
||||||
projectTitle: args.projectTitle,
|
projectTitle: args.projectTitle,
|
||||||
|
|||||||
Reference in New Issue
Block a user