From ea75d9f810c4177cf8637c5053ff852ad9ff6178 Mon Sep 17 00:00:00 2001 From: shachar_y Date: Sat, 13 Dec 2025 13:23:29 +0200 Subject: [PATCH 1/4] add permission to rubrics, awards and divisions --- .../resolvers/divisions/division-awards.ts | 31 ++++++++++++++++-- .../divisions/judging/judging-rubrics.ts | 30 +++++++++++++++-- .../graphql/resolvers/divisions/resolver.ts | 32 ++++++++++++++++--- 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts b/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts index 6438bb989..4241074f4 100644 --- a/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts +++ b/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts @@ -1,4 +1,6 @@ import { GraphQLFieldResolver } from 'graphql'; +import { MutationError, MutationErrorCode } from '@lems/types/api/lems'; +import type { GraphQLContext } from '../../apollo-server'; import db from '../../../database'; interface DivisionWithId { @@ -19,20 +21,45 @@ export interface AwardGraphQL { allowNominations: boolean; } +const allowedRoles = new Set(['judge-advisor', 'tournament-manager']); + /** * Resolver for Division.awards field. * Fetches all awards configured for a division. + * Requires user authentication and division assignment. * @param division - The division object containing the id * @param args - Optional arguments to filter results * @param args.allowNominations - Filter by allowNominations + * @param context - GraphQL context containing user information */ export const divisionAwardsResolver: GraphQLFieldResolver< DivisionWithId, - unknown, + GraphQLContext, AwardsArgs, Promise -> = async (division: DivisionWithId, args: AwardsArgs) => { +> = async (division: DivisionWithId, args: AwardsArgs, context: GraphQLContext) => { try { + // Check authentication + if (!context.user) { + throw new MutationError(MutationErrorCode.UNAUTHORIZED, 'Authentication required'); + } + + // Check authorization + if (!allowedRoles.has(context.user.role)) { + throw new MutationError( + MutationErrorCode.FORBIDDEN, + 'User does not have permission to view awards.' + ); + } + + // Check division assignment + if (!context.user.divisions.includes(division.id)) { + throw new MutationError( + MutationErrorCode.FORBIDDEN, + 'User is not assigned to this division' + ); + } + let awards = await db.awards.byDivisionId(division.id).getAll(); // Filter by allowNominations if specified diff --git a/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts b/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts index 49b69530b..c19bcabc4 100644 --- a/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts +++ b/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts @@ -1,5 +1,7 @@ import { GraphQLFieldResolver } from 'graphql'; import { JudgingCategory } from '@lems/database'; +import { MutationError, MutationErrorCode } from '@lems/types/api/lems'; +import type { GraphQLContext } from '../../../apollo-server'; import db from '../../../../database'; import { buildRubricResult, RubricGraphQL } from '../../../utils/rubric-builder'; @@ -12,17 +14,41 @@ interface RubricsArgs { category?: string; } +const allowedRoles = new Set(['judge', 'lead-judge', 'judge-advisor']); + /** * Resolver for Judging.rubrics field. * Fetches rubrics for teams in a division, optionally filtered by team IDs or category. + * Only accessible to lead-judge and judge-advisor roles. */ export const judgingRubricsResolver: GraphQLFieldResolver< JudgingWithDivisionId, - unknown, + GraphQLContext, RubricsArgs, Promise -> = async (judging: JudgingWithDivisionId, args: RubricsArgs) => { +> = async (judging: JudgingWithDivisionId, args: RubricsArgs, context: GraphQLContext) => { try { + // Check authentication + if (!context.user) { + throw new MutationError(MutationErrorCode.UNAUTHORIZED, 'Authentication required'); + } + + // Check authorization + if (!allowedRoles.has(context.user.role)) { + throw new MutationError( + MutationErrorCode.FORBIDDEN, + 'User does not have permission to view rubrics.' + ); + } + + // Check division assignment + if (!context.user.divisions.includes(judging.divisionId)) { + throw new MutationError( + MutationErrorCode.FORBIDDEN, + 'User is not assigned to this division' + ); + } + let rubricsSelector = db.rubrics.byDivision(judging.divisionId); // Apply category filter if provided diff --git a/apps/backend/src/lib/graphql/resolvers/divisions/resolver.ts b/apps/backend/src/lib/graphql/resolvers/divisions/resolver.ts index e57f5e2d2..73c2f981a 100644 --- a/apps/backend/src/lib/graphql/resolvers/divisions/resolver.ts +++ b/apps/backend/src/lib/graphql/resolvers/divisions/resolver.ts @@ -1,19 +1,43 @@ +import { MutationError, MutationErrorCode } from '@lems/types/api/lems'; +import type { GraphQLContext } from '../../apollo-server'; import db from '../../../database'; /** * Query resolver for fetching a single division by ID. - * @throws Error if division ID is not provided or division not found + * Requires user authentication and verified division assignment. + * @throws Error if division ID is not provided, division not found, or user not authorized */ -export const divisionResolver = async (_parent: unknown, args: { id: string }) => { +export const divisionResolver = async ( + _parent: unknown, + args: { id: string }, + context: GraphQLContext +) => { + // Check authentication + if (!context.user) { + throw new MutationError(MutationErrorCode.UNAUTHORIZED, 'Authentication required'); + } + + // Check division assignment if (!args.id) { - throw new Error('Division ID is required'); + throw new MutationError(MutationErrorCode.UNAUTHORIZED, 'Division ID is required'); + } + + // Check if user is assigned to the requested division + if (!context.user.divisions.includes(args.id)) { + throw new MutationError( + MutationErrorCode.FORBIDDEN, + 'User is not assigned to this division' + ); } try { const division = await db.divisions.byId(args.id).get(); if (!division) { - throw new Error(`Division with ID ${args.id} not found`); + throw new MutationError( + MutationErrorCode.UNAUTHORIZED, + `Division with ID ${args.id} not found` + ); } return { From e5cceefc75f83d8a9cf75eaa592e0c51772968c1 Mon Sep 17 00:00:00 2001 From: shachar_y Date: Sat, 13 Dec 2025 23:14:10 +0200 Subject: [PATCH 2/4] CR --- .../resolvers/divisions/division-awards.ts | 57 ++++++++++++++----- .../divisions/judging/judging-rubrics.ts | 31 +--------- .../graphql/resolvers/divisions/resolver.ts | 14 ++--- .../lib/graphql/resolvers/judging/rubric.ts | 16 +++++- libs/types/src/lib/api/lems/graphql-errors.ts | 21 +++++++ 5 files changed, 88 insertions(+), 51 deletions(-) diff --git a/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts b/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts index 4241074f4..175741acd 100644 --- a/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts +++ b/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts @@ -19,9 +19,11 @@ export interface AwardGraphQL { type: 'PERSONAL' | 'TEAM'; isOptional: boolean; allowNominations: boolean; + winnerName?: string; + winnerId?: string; } -const allowedRoles = new Set(['judge-advisor', 'tournament-manager']); +const allowedRoles = new Set(['judge-advisor', 'lead-judge']); /** * Resolver for Division.awards field. @@ -39,11 +41,6 @@ export const divisionAwardsResolver: GraphQLFieldResolver< Promise > = async (division: DivisionWithId, args: AwardsArgs, context: GraphQLContext) => { try { - // Check authentication - if (!context.user) { - throw new MutationError(MutationErrorCode.UNAUTHORIZED, 'Authentication required'); - } - // Check authorization if (!allowedRoles.has(context.user.role)) { throw new MutationError( @@ -52,14 +49,6 @@ export const divisionAwardsResolver: GraphQLFieldResolver< ); } - // Check division assignment - if (!context.user.divisions.includes(division.id)) { - throw new MutationError( - MutationErrorCode.FORBIDDEN, - 'User is not assigned to this division' - ); - } - let awards = await db.awards.byDivisionId(division.id).getAll(); // Filter by allowNominations if specified @@ -81,3 +70,43 @@ export const divisionAwardsResolver: GraphQLFieldResolver< throw error; } }; + +/** + * Resolver for Division.awards.winners field. + * Fetches all awards with their winners for a division. + * Requires user authentication and division assignment. + * @param division - The division object containing the id + * @param _args - Unused arguments + * @param context - GraphQL context containing user information + */ +export const divisionAwardsWinnersResolver: GraphQLFieldResolver< + DivisionWithId, + GraphQLContext, + unknown, + Promise +> = async (division: DivisionWithId, _args: unknown, context: GraphQLContext) => { + try { + const awards = await db.awards.byDivisionId(division.id).getAll(); + + const areAwardsClosed = false; // Placeholder for actual check + const canViewWinners = areAwardsClosed || allowedRoles.has(context.user.role); + + return awards.map(award => ({ + id: award.id, + name: award.name, + index: award.index, + place: award.place, + type: award.type, + isOptional: award.is_optional, + allowNominations: award.allow_nominations, + ...(canViewWinners && { + winnerName: award.winner_name, + winnerId: award.winner_id + }) + })); + + } catch (error) { + console.error('Error fetching awards with winners for division:', division.id, error); + throw error; + } +}; diff --git a/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts b/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts index c19bcabc4..f405a21cc 100644 --- a/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts +++ b/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts @@ -1,9 +1,7 @@ import { GraphQLFieldResolver } from 'graphql'; import { JudgingCategory } from '@lems/database'; -import { MutationError, MutationErrorCode } from '@lems/types/api/lems'; -import type { GraphQLContext } from '../../../apollo-server'; -import db from '../../../../database'; import { buildRubricResult, RubricGraphQL } from '../../../utils/rubric-builder'; +import db from '../../../../database'; interface JudgingWithDivisionId { divisionId: string; @@ -14,8 +12,6 @@ interface RubricsArgs { category?: string; } -const allowedRoles = new Set(['judge', 'lead-judge', 'judge-advisor']); - /** * Resolver for Judging.rubrics field. * Fetches rubrics for teams in a division, optionally filtered by team IDs or category. @@ -23,32 +19,11 @@ const allowedRoles = new Set(['judge', 'lead-judge', 'judge-advisor']); */ export const judgingRubricsResolver: GraphQLFieldResolver< JudgingWithDivisionId, - GraphQLContext, + unknown, RubricsArgs, Promise -> = async (judging: JudgingWithDivisionId, args: RubricsArgs, context: GraphQLContext) => { +> = async (judging: JudgingWithDivisionId, args: RubricsArgs) => { try { - // Check authentication - if (!context.user) { - throw new MutationError(MutationErrorCode.UNAUTHORIZED, 'Authentication required'); - } - - // Check authorization - if (!allowedRoles.has(context.user.role)) { - throw new MutationError( - MutationErrorCode.FORBIDDEN, - 'User does not have permission to view rubrics.' - ); - } - - // Check division assignment - if (!context.user.divisions.includes(judging.divisionId)) { - throw new MutationError( - MutationErrorCode.FORBIDDEN, - 'User is not assigned to this division' - ); - } - let rubricsSelector = db.rubrics.byDivision(judging.divisionId); // Apply category filter if provided diff --git a/apps/backend/src/lib/graphql/resolvers/divisions/resolver.ts b/apps/backend/src/lib/graphql/resolvers/divisions/resolver.ts index 73c2f981a..b58f210c1 100644 --- a/apps/backend/src/lib/graphql/resolvers/divisions/resolver.ts +++ b/apps/backend/src/lib/graphql/resolvers/divisions/resolver.ts @@ -1,4 +1,4 @@ -import { MutationError, MutationErrorCode } from '@lems/types/api/lems'; +import { ResolverError, ResolverErrorCode } from '@lems/types/api/lems'; import type { GraphQLContext } from '../../apollo-server'; import db from '../../../database'; @@ -14,18 +14,18 @@ export const divisionResolver = async ( ) => { // Check authentication if (!context.user) { - throw new MutationError(MutationErrorCode.UNAUTHORIZED, 'Authentication required'); + throw new ResolverError(ResolverErrorCode.UNAUTHORIZED, 'Authentication required'); } // Check division assignment if (!args.id) { - throw new MutationError(MutationErrorCode.UNAUTHORIZED, 'Division ID is required'); + throw new ResolverError(ResolverErrorCode.UNAUTHORIZED, 'Division ID is required'); } // Check if user is assigned to the requested division if (!context.user.divisions.includes(args.id)) { - throw new MutationError( - MutationErrorCode.FORBIDDEN, + throw new ResolverError( + ResolverErrorCode.FORBIDDEN, 'User is not assigned to this division' ); } @@ -34,8 +34,8 @@ export const divisionResolver = async ( const division = await db.divisions.byId(args.id).get(); if (!division) { - throw new MutationError( - MutationErrorCode.UNAUTHORIZED, + throw new ResolverError( + ResolverErrorCode.UNAUTHORIZED, `Division with ID ${args.id} not found` ); } diff --git a/apps/backend/src/lib/graphql/resolvers/judging/rubric.ts b/apps/backend/src/lib/graphql/resolvers/judging/rubric.ts index 6198c1a6c..31af8ee2a 100644 --- a/apps/backend/src/lib/graphql/resolvers/judging/rubric.ts +++ b/apps/backend/src/lib/graphql/resolvers/judging/rubric.ts @@ -1,9 +1,11 @@ import { GraphQLFieldResolver } from 'graphql'; import { hyphensToUnderscores } from '@lems/shared/utils'; +import { ResolverError, ResolverErrorCode } from '@lems/types/api/lems'; import db from '../../../database'; import { toGraphQLId } from '../../utils/object-id-transformer'; import { buildTeamGraphQL, TeamGraphQL } from '../../utils/team-builder'; import { RubricGraphQL } from '../../utils/rubric-builder'; +import { GraphQLContext } from '../../apollo-server'; /** * Resolver for Rubric.team field. @@ -22,16 +24,26 @@ export const rubricTeamResolver: GraphQLFieldResolver< return buildTeamGraphQL(team, rubric.divisionId); }; +const allowedRubricDataRoles = new Set(['judge', 'lead-judge', 'judge-advisor']); + /** * Resolver for Rubric.data field. * Returns the rubric data if it exists. + * Only accessible to users with specific roles. */ export const rubricDataResolver: GraphQLFieldResolver< RubricGraphQL, - unknown, + GraphQLContext, unknown, RubricGraphQL['data'] | null -> = (rubric: RubricGraphQL) => { +> = (rubric: RubricGraphQL, context: GraphQLContext) => { + if (!allowedRubricDataRoles.has(context.user.role)) { + throw new ResolverError( + ResolverErrorCode.FORBIDDEN, + 'User does not have permission to view rubrics data.' + ); + } + return rubric.data || null; }; diff --git a/libs/types/src/lib/api/lems/graphql-errors.ts b/libs/types/src/lib/api/lems/graphql-errors.ts index 778abe88b..60a055bac 100644 --- a/libs/types/src/lib/api/lems/graphql-errors.ts +++ b/libs/types/src/lib/api/lems/graphql-errors.ts @@ -9,6 +9,12 @@ export enum MutationErrorCode { INTERNAL_ERROR = 'INTERNAL_ERROR' } +export enum ResolverErrorCode { + UNAUTHORIZED = 'UNAUTHORIZED', + FORBIDDEN = 'FORBIDDEN', + INTERNAL_ERROR = 'INTERNAL_ERROR' +} + /** * GraphQL mutation error with typed error code and message. * Extends GraphQLError to provide better TypeScript support and consistency. @@ -24,3 +30,18 @@ export class MutationError extends GraphQLError { Object.setPrototypeOf(this, MutationError.prototype); } } + +/** + * GraphQL resolver error with typed error code and message. + * Extends GraphQLError to provide better TypeScript support and consistency. + */ +export class ResolverError extends GraphQLError { + readonly code: ResolverErrorCode; + constructor(code: ResolverErrorCode, message: string) { + super(message, { + extensions: { code, message } as unknown as Record + }); + this.code = code; + Object.setPrototypeOf(this, ResolverError.prototype); + } +} \ No newline at end of file From 6ddd486bdcf072b681554184e518b1cedebfe158 Mon Sep 17 00:00:00 2001 From: shachar_y Date: Wed, 17 Dec 2025 00:09:47 +0200 Subject: [PATCH 3/4] Add division venue query and update related types and resolvers --- .../lib/graphql/resolvers/events/resolver.ts | 38 ++++++++++++++++++- .../src/lib/graphql/resolvers/index.ts | 1 + .../login/graphql/role-info-step.graphql.ts | 4 +- .../login/hooks/use-role-info-options.ts | 6 +-- .../src/lib/api/lems/graphql/event.graphql | 20 ++++++++++ 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/apps/backend/src/lib/graphql/resolvers/events/resolver.ts b/apps/backend/src/lib/graphql/resolvers/events/resolver.ts index bd336d018..c7f4adb0f 100644 --- a/apps/backend/src/lib/graphql/resolvers/events/resolver.ts +++ b/apps/backend/src/lib/graphql/resolvers/events/resolver.ts @@ -27,6 +27,16 @@ interface EventsArgs { endBefore?: string; } +interface DivisionVenueArgs { + id: string; +} + +export interface DivisionVenue { + id: string; + tables: { id: string; name: string }[]; + rooms: { id: string; name: string }[]; +} + export const eventResolvers = { Query: { events: (async (_parent, args: EventsArgs) => { @@ -54,7 +64,33 @@ export const eventResolvers = { console.error('Error fetching event:', error); throw error; } - }) as GraphQLFieldResolver> + }) as GraphQLFieldResolver>, + + divisionVenue: (async (_parent, args: DivisionVenueArgs) => { + if (!args.id) { + throw new Error('Division ID is required'); + } + + try { + const division = await db.divisions.byId(args.id).get(); + + if (!division) { + throw new Error(`Division with ID ${args.id} not found`); + } + + const tables = await db.tables.byDivisionId(args.id).getAll(); + const rooms = await db.rooms.byDivisionId(args.id).getAll(); + + return { + id: division.id, + tables: tables.map(t => ({ id: t.id, name: t.name })), + rooms: rooms.map(r => ({ id: r.id, name: r.name })) + }; + } catch (error) { + console.error('Error fetching division venue:', error); + throw error; + } + }) as GraphQLFieldResolver> } }; diff --git a/apps/backend/src/lib/graphql/resolvers/index.ts b/apps/backend/src/lib/graphql/resolvers/index.ts index 5b1db4d22..9b51d77bf 100644 --- a/apps/backend/src/lib/graphql/resolvers/index.ts +++ b/apps/backend/src/lib/graphql/resolvers/index.ts @@ -62,6 +62,7 @@ export const resolvers = { Query: { events: eventResolvers.Query.events, event: eventResolvers.Query.event, + divisionVenue: eventResolvers.Query.divisionVenue, division: divisionResolver }, Mutation: mutationResolvers, diff --git a/apps/frontend/src/app/[locale]/[event]/login/graphql/role-info-step.graphql.ts b/apps/frontend/src/app/[locale]/[event]/login/graphql/role-info-step.graphql.ts index dfb9580ee..4f848d8fb 100644 --- a/apps/frontend/src/app/[locale]/[event]/login/graphql/role-info-step.graphql.ts +++ b/apps/frontend/src/app/[locale]/[event]/login/graphql/role-info-step.graphql.ts @@ -2,7 +2,7 @@ import { gql } from '@apollo/client'; import type { TypedDocumentNode } from '@apollo/client'; type GetDivisionVenueQuery = { - division: { + divisionVenue: { id: string; tables: { id: string; name: string }[]; rooms: { id: string; name: string }[]; @@ -18,7 +18,7 @@ export const GET_DIVISION_VENUE_QUERY: TypedDocumentNode< GetDivisionVenueQueryVariables > = gql` query GetDivisionVenue($id: String!) { - division(id: $id) { + divisionVenue(id: $id) { id tables { id diff --git a/apps/frontend/src/app/[locale]/[event]/login/hooks/use-role-info-options.ts b/apps/frontend/src/app/[locale]/[event]/login/hooks/use-role-info-options.ts index dc9bcde7a..b9eb4eb68 100644 --- a/apps/frontend/src/app/[locale]/[event]/login/hooks/use-role-info-options.ts +++ b/apps/frontend/src/app/[locale]/[event]/login/hooks/use-role-info-options.ts @@ -48,14 +48,14 @@ export const useRoleInfoOptions = (divisionId: string | undefined): RoleInfoOpti ); return useMemo(() => { - if (!divisionData?.division || !roleInfoType || !volunteerData?.volunteers) return []; + if (!divisionData?.divisionVenue || !roleInfoType || !volunteerData?.volunteers) return []; let allOptions: RoleInfoOption[] = []; if (roleInfoType === 'table' || roleInfoType === 'room') { - if (divisionData?.division) { + if (divisionData?.divisionVenue) { const items = - roleInfoType === 'table' ? divisionData.division.tables : divisionData.division.rooms; + roleInfoType === 'table' ? divisionData.divisionVenue.tables : divisionData.divisionVenue.rooms; allOptions = items.map((item: { id: string; name: string }) => ({ id: item.id, name: item.name diff --git a/libs/types/src/lib/api/lems/graphql/event.graphql b/libs/types/src/lib/api/lems/graphql/event.graphql index 9721adb96..f72fff9bd 100644 --- a/libs/types/src/lib/api/lems/graphql/event.graphql +++ b/libs/types/src/lib/api/lems/graphql/event.graphql @@ -70,4 +70,24 @@ extend type Query { "Event slug to retrieve (alternative to ID)" slug: String ): Event + + """ + Get division venue information (tables and rooms) by division ID. + This query does not require authentication and is used during login. + """ + divisionVenue("Division ID to retrieve venue information for" id: String!): DivisionVenue +} + +""" +Division venue information (tables and rooms) +""" +type DivisionVenue { + "Unique identifier for the division" + id: String! + + "Competition tables assigned to this division" + tables: [Table!]! + + "Judging rooms assigned to this division" + rooms: [Room!]! } From 7062858202db918fc15f7cc36505536232289a66 Mon Sep 17 00:00:00 2001 From: johnmeshulam <55348702+johnmeshulam@users.noreply.github.com> Date: Fri, 19 Dec 2025 12:52:03 +0200 Subject: [PATCH 4/4] removed unneccsary --- .../resolvers/divisions/division-awards.ts | 16 +++------------- .../divisions/judging/judging-rubrics.ts | 1 - 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts b/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts index 175741acd..a043d068b 100644 --- a/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts +++ b/apps/backend/src/lib/graphql/resolvers/divisions/division-awards.ts @@ -1,5 +1,4 @@ import { GraphQLFieldResolver } from 'graphql'; -import { MutationError, MutationErrorCode } from '@lems/types/api/lems'; import type { GraphQLContext } from '../../apollo-server'; import db from '../../../database'; @@ -36,19 +35,11 @@ const allowedRoles = new Set(['judge-advisor', 'lead-judge']); */ export const divisionAwardsResolver: GraphQLFieldResolver< DivisionWithId, - GraphQLContext, + null, AwardsArgs, Promise -> = async (division: DivisionWithId, args: AwardsArgs, context: GraphQLContext) => { +> = async (division: DivisionWithId, args: AwardsArgs) => { try { - // Check authorization - if (!allowedRoles.has(context.user.role)) { - throw new MutationError( - MutationErrorCode.FORBIDDEN, - 'User does not have permission to view awards.' - ); - } - let awards = await db.awards.byDivisionId(division.id).getAll(); // Filter by allowNominations if specified @@ -91,7 +82,7 @@ export const divisionAwardsWinnersResolver: GraphQLFieldResolver< const areAwardsClosed = false; // Placeholder for actual check const canViewWinners = areAwardsClosed || allowedRoles.has(context.user.role); - return awards.map(award => ({ + return awards.map(award => ({ id: award.id, name: award.name, index: award.index, @@ -104,7 +95,6 @@ export const divisionAwardsWinnersResolver: GraphQLFieldResolver< winnerId: award.winner_id }) })); - } catch (error) { console.error('Error fetching awards with winners for division:', division.id, error); throw error; diff --git a/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts b/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts index f405a21cc..82ef05f52 100644 --- a/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts +++ b/apps/backend/src/lib/graphql/resolvers/divisions/judging/judging-rubrics.ts @@ -15,7 +15,6 @@ interface RubricsArgs { /** * Resolver for Judging.rubrics field. * Fetches rubrics for teams in a division, optionally filtered by team IDs or category. - * Only accessible to lead-judge and judge-advisor roles. */ export const judgingRubricsResolver: GraphQLFieldResolver< JudgingWithDivisionId,