Skip to content

Commit

Permalink
Refactor Membership, PointEntry, and Marathon repositories to extend …
Browse files Browse the repository at this point in the history
…a default repository structure, simplifying unique parameter handling and improving code maintainability
  • Loading branch information
jthoward64 committed Jan 6, 2025
1 parent 338f8ec commit 3bc5465
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 667 deletions.
2 changes: 1 addition & 1 deletion packages/portal/graphql/graphql-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export type introspection_types = {
'Float': unknown;
'FundraisingAssignmentNode': { kind: 'OBJECT'; name: 'FundraisingAssignmentNode'; fields: { 'amount': { name: 'amount'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; } }; 'createdAt': { name: 'createdAt'; type: { kind: 'SCALAR'; name: 'LuxonDateTime'; ofType: null; } }; 'entry': { name: 'entry'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'FundraisingEntryNode'; ofType: null; }; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'GlobalId'; ofType: null; }; } }; 'person': { name: 'person'; type: { kind: 'OBJECT'; name: 'PersonNode'; ofType: null; } }; 'updatedAt': { name: 'updatedAt'; type: { kind: 'SCALAR'; name: 'LuxonDateTime'; ofType: null; } }; }; };
'FundraisingEntryNode': { kind: 'OBJECT'; name: 'FundraisingEntryNode'; fields: { 'amount': { name: 'amount'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; } }; 'amountOverride': { name: 'amountOverride'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'amountUnassigned': { name: 'amountUnassigned'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'Float'; ofType: null; }; } }; 'assignments': { name: 'assignments'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'FundraisingAssignmentNode'; ofType: null; }; }; }; } }; 'batchType': { name: 'batchType'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'BatchType'; ofType: null; }; } }; 'batchTypeOverride': { name: 'batchTypeOverride'; type: { kind: 'ENUM'; name: 'BatchType'; ofType: null; } }; 'createdAt': { name: 'createdAt'; type: { kind: 'SCALAR'; name: 'LuxonDateTime'; ofType: null; } }; 'dailyDepartmentNotification': { name: 'dailyDepartmentNotification'; type: { kind: 'OBJECT'; name: 'DailyDepartmentNotificationNode'; ofType: null; } }; 'donatedByOverride': { name: 'donatedByOverride'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'donatedByText': { name: 'donatedByText'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'donatedOn': { name: 'donatedOn'; type: { kind: 'SCALAR'; name: 'LuxonDateTime'; ofType: null; } }; 'donatedOnOverride': { name: 'donatedOnOverride'; type: { kind: 'SCALAR'; name: 'LuxonDateTime'; ofType: null; } }; 'donatedToOverride': { name: 'donatedToOverride'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'donatedToText': { name: 'donatedToText'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'id': { name: 'id'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'GlobalId'; ofType: null; }; } }; 'notes': { name: 'notes'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'solicitationCode': { name: 'solicitationCode'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'OBJECT'; name: 'SolicitationCodeNode'; ofType: null; }; } }; 'solicitationCodeOverride': { name: 'solicitationCodeOverride'; type: { kind: 'OBJECT'; name: 'SolicitationCodeNode'; ofType: null; } }; 'updatedAt': { name: 'updatedAt'; type: { kind: 'SCALAR'; name: 'LuxonDateTime'; ofType: null; } }; }; };
'FundraisingEntryResolverFilterFields': { name: 'FundraisingEntryResolverFilterFields'; enumValues: 'amount' | 'amountUnassigned' | 'batchType' | 'createdAt' | 'donatedBy' | 'donatedOn' | 'donatedTo' | 'solicitationCode' | 'teamId' | 'updatedAt'; };
'FundraisingEntryResolverFilterFields': { name: 'FundraisingEntryResolverFilterFields'; enumValues: 'amount' | 'amountUnassigned' | 'batchType' | 'createdAt' | 'donatedBy' | 'donatedOn' | 'donatedTo' | 'solicitationCode' | 'updatedAt'; };
'FundraisingEntryResolverFilterGroup': { kind: 'INPUT_OBJECT'; name: 'FundraisingEntryResolverFilterGroup'; isOneOf: false; inputFields: [{ name: 'children'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'FundraisingEntryResolverFilterGroup'; ofType: null; }; }; }; }; defaultValue: "[]" }, { name: 'filters'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'FundraisingEntryResolverFilterItem'; ofType: null; }; }; }; }; defaultValue: "[]" }, { name: 'operator'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'FilterGroupOperator'; ofType: null; }; }; defaultValue: null }]; };
'FundraisingEntryResolverFilterItem': { kind: 'INPUT_OBJECT'; name: 'FundraisingEntryResolverFilterItem'; isOneOf: false; inputFields: [{ name: 'field'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'FundraisingEntryResolverFilterFields'; ofType: null; }; }; defaultValue: null }, { name: 'filter'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'INPUT_OBJECT'; name: 'SomeFilter'; ofType: null; }; }; defaultValue: null }]; };
'FundraisingEntryResolverSearchFilter': { kind: 'INPUT_OBJECT'; name: 'FundraisingEntryResolverSearchFilter'; isOneOf: false; inputFields: [{ name: 'fields'; type: { kind: 'LIST'; name: never; ofType: { kind: 'NON_NULL'; name: never; ofType: { kind: 'ENUM'; name: 'FundraisingEntryResolverFilterFields'; ofType: null; }; }; }; defaultValue: null }, { name: 'query'; type: { kind: 'NON_NULL'; name: never; ofType: { kind: 'SCALAR'; name: 'NonEmptyString'; ofType: null; }; }; defaultValue: null }]; };
Expand Down
100 changes: 19 additions & 81 deletions packages/server/src/repositories/marathon/MarathonRepository.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,37 @@
import { Service } from "@freshgum/typedi";
import { Marathon, MarathonHour, Prisma, PrismaClient } from "@prisma/client";
import type { SortDirection } from "@ukdanceblue/common";
import { NotFoundError, optionOf } from "@ukdanceblue/common/error";
import { Err, Ok, Option, Result } from "ts-results-es";

import {
handleRepositoryError,
type RepositoryError,
type SimpleUniqueParam,
} from "#repositories/shared.js";

const marathonBooleanKeys = [] as const;
type MarathonBooleanKey = (typeof marathonBooleanKeys)[number];
export type UniqueMarathonParam = SimpleUniqueParam | { year: string };

const marathonDateKeys = [
"startDate",
"endDate",
"createdAt",
"updatedAt",
] as const;
type MarathonDateKey = (typeof marathonDateKeys)[number];

const marathonIsNullKeys = [] as const;
type MarathonIsNullKey = (typeof marathonIsNullKeys)[number];

const marathonNumericKeys = [] as const;
type MarathonNumericKey = (typeof marathonNumericKeys)[number];

const marathonOneOfKeys = ["year"] as const;
type MarathonOneOfKey = (typeof marathonOneOfKeys)[number];

const marathonStringKeys = [] as const;
type MarathonStringKey = (typeof marathonStringKeys)[number];

export type MarathonOrderKeys =
| "year"
| "startDate"
| "endDate"
| "createdAt"
| "updatedAt";

export type MarathonFilters = FilterItems<
MarathonBooleanKey,
MarathonDateKey,
MarathonIsNullKey,
MarathonNumericKey,
MarathonOneOfKey,
MarathonStringKey
>;

// type UniqueParam = { id: number } | { uuid: string };
export type UniqueMarathonParam =
| { id: number }
| { uuid: string }
| { year: string };
import type {
FieldsOfListQueryArgs,
ListMarathonsArgs,
} from "@ukdanceblue/common";

import { prismaToken } from "#lib/typediTokens.js";
import { buildDefaultRepository } from "#repositories/Default.js";

@Service([prismaToken])
export class MarathonRepository {
constructor(private prisma: PrismaClient) {}
export class MarathonRepository extends buildDefaultRepository<
PrismaClient["marathon"],
SimpleUniqueParam,
FieldsOfListQueryArgs<ListMarathonsArgs>
>("Marathon", {}) {
constructor(protected readonly prisma: PrismaClient) {
super(prisma);
}

public uniqueToWhere(by: SimpleUniqueParam) {
return MarathonRepository.simpleUniqueToWhere(by);
}

async findMarathonByUnique(
param: UniqueMarathonParam
Expand Down Expand Up @@ -111,41 +84,6 @@ export class MarathonRepository {
}
}

listMarathons({
filters,
order,
skip,
take,
}: {
filters?: readonly MarathonFilters[] | undefined | null;
order?:
| readonly [key: MarathonOrderKeys, sort: SortDirection][]
| undefined
| null;
skip?: number | undefined | null;
take?: number | undefined | null;
}) {
const where = buildMarathonWhere(filters);
const orderBy = buildMarathonOrder(order);

return this.prisma.marathon.findMany({
where,
orderBy,
skip: skip ?? undefined,
take: take ?? undefined,
});
}

countMarathons({
filters,
}: {
filters?: readonly MarathonFilters[] | undefined | null;
}) {
const where = buildMarathonWhere(filters);

return this.prisma.marathon.count({ where });
}

async getMarathonHours(
param: UniqueMarathonParam
): Promise<Result<MarathonHour[], RepositoryError>> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,32 @@
import { Service } from "@freshgum/typedi";
import { Prisma, PrismaClient } from "@prisma/client";
import type { SortDirection } from "@ukdanceblue/common";

const marathonHourBooleanKeys = [] as const;
type MarathonHourBooleanKey = (typeof marathonHourBooleanKeys)[number];
type MarathonHourUniqueParam = SimpleUniqueParam;

const marathonHourDateKeys = [
"shownStartingAt",
"createdAt",
"updatedAt",
] as const;
type MarathonHourDateKey = (typeof marathonHourDateKeys)[number];

const marathonHourIsNullKeys = [] as const;
type MarathonHourIsNullKey = (typeof marathonHourIsNullKeys)[number];

const marathonHourNumericKeys = [] as const;
type MarathonHourNumericKey = (typeof marathonHourNumericKeys)[number];

const marathonHourOneOfKeys = ["marathonYear"] as const;
type MarathonHourOneOfKey = (typeof marathonHourOneOfKeys)[number];

const marathonHourStringKeys = ["title", "details", "durationInfo"] as const;
type MarathonHourStringKey = (typeof marathonHourStringKeys)[number];

export type MarathonHourOrderKeys =
| "title"
| "details"
| "durationInfo"
| "marathonYear"
| "shownStartingAt"
| "createdAt"
| "updatedAt";

export type MarathonHourFilters = FilterItems<
MarathonHourBooleanKey,
MarathonHourDateKey,
MarathonHourIsNullKey,
MarathonHourNumericKey,
MarathonHourOneOfKey,
MarathonHourStringKey
>;

type UniqueParam = { id: number } | { uuid: string };
import type {
FieldsOfListQueryArgs,
ListMarathonHoursArgs,
} from "@ukdanceblue/common";

import { prismaToken } from "#lib/typediTokens.js";
import { buildDefaultRepository } from "#repositories/Default.js";
import type { SimpleUniqueParam } from "#repositories/shared.js";

@Service([prismaToken])
export class MarathonHourRepository {
constructor(private prisma: PrismaClient) {}
export class MarathonHourRepository extends buildDefaultRepository<
PrismaClient["marathonHour"],
SimpleUniqueParam,
FieldsOfListQueryArgs<ListMarathonHoursArgs>
>("MarathonHour", {}) {
constructor(protected readonly prisma: PrismaClient) {
super(prisma);
}

public uniqueToWhere(by: SimpleUniqueParam) {
return MarathonHourRepository.simpleUniqueToWhere(by);
}

findMarathonHourByUnique(param: UniqueParam) {
findMarathonHourByUnique(param: MarathonHourUniqueParam) {
return this.prisma.marathonHour.findUnique({ where: param });
}

Expand All @@ -64,42 +40,7 @@ export class MarathonHourRepository {
});
}

listMarathonHours({
filters,
order,
skip,
take,
}: {
filters?: readonly MarathonHourFilters[] | undefined | null;
order?:
| readonly [key: MarathonHourOrderKeys, sort: SortDirection][]
| undefined
| null;
skip?: number | undefined | null;
take?: number | undefined | null;
}) {
const where = buildMarathonHourWhere(filters);
const orderBy = buildMarathonHourOrder(order);

return this.prisma.marathonHour.findMany({
where,
orderBy,
skip: skip ?? undefined,
take: take ?? undefined,
});
}

countMarathonHours({
filters,
}: {
filters?: readonly MarathonHourFilters[] | undefined | null;
}) {
const where = buildMarathonHourWhere(filters);

return this.prisma.marathonHour.count({ where });
}

async getMaps(param: UniqueParam) {
async getMaps(param: MarathonHourUniqueParam) {
const rows = await this.prisma.marathonHour.findUnique({
where: param,
include: {
Expand All @@ -118,7 +59,7 @@ export class MarathonHourRepository {
}: {
title: string;
details?: string | undefined | null;
marathon: UniqueParam;
marathon: MarathonHourUniqueParam;
shownStartingAt: Date;
durationInfo: string;
}) {
Expand All @@ -134,7 +75,7 @@ export class MarathonHourRepository {
}

updateMarathonHour(
param: UniqueParam,
param: MarathonHourUniqueParam,
{
title,
details,
Expand All @@ -144,7 +85,7 @@ export class MarathonHourRepository {
}: {
title?: string | undefined;
details?: string | undefined | null;
marathon?: UniqueParam | undefined;
marathon?: MarathonHourUniqueParam | undefined;
shownStartingAt?: Date | undefined;
durationInfo?: string | undefined;
}
Expand Down Expand Up @@ -172,7 +113,7 @@ export class MarathonHourRepository {
}
}

deleteMarathonHour(param: UniqueParam) {
deleteMarathonHour(param: MarathonHourUniqueParam) {
try {
return this.prisma.marathonHour.delete({ where: param });
} catch (error) {
Expand All @@ -187,7 +128,10 @@ export class MarathonHourRepository {
}
}

addMap(param: UniqueParam, image: { id: number } | { uuid: string }) {
addMap(
param: MarathonHourUniqueParam,
image: { id: number } | { uuid: string }
) {
try {
return this.prisma.marathonHour.update({
where: param,
Expand All @@ -209,7 +153,10 @@ export class MarathonHourRepository {
}
}

removeMap(param: UniqueParam, image: { id: number } | { uuid: string }) {
removeMap(
param: MarathonHourUniqueParam,
image: { id: number } | { uuid: string }
) {
try {
return this.prisma.marathonHour.update({
where: param,
Expand Down
42 changes: 13 additions & 29 deletions packages/server/src/repositories/membership/MembershipRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,24 @@ import {
type SimpleUniqueParam,
} from "#repositories/shared.js";

const membershipBooleanKeys = [] as const;
type MembershipBooleanKey = (typeof membershipBooleanKeys)[number];

const membershipDateKeys = ["createdAt", "updatedAt"] as const;
type MembershipDateKey = (typeof membershipDateKeys)[number];

const membershipIsNullKeys = [] as const;
type MembershipIsNullKey = (typeof membershipIsNullKeys)[number];

const membershipNumericKeys = [] as const;
type MembershipNumericKey = (typeof membershipNumericKeys)[number];

const membershipOneOfKeys = [] as const;
type MembershipOneOfKey = (typeof membershipOneOfKeys)[number];

const membershipStringKeys = [] as const;
type MembershipStringKey = (typeof membershipStringKeys)[number];

export type MembershipFilters = FilterItems<
MembershipBooleanKey,
MembershipDateKey,
MembershipIsNullKey,
MembershipNumericKey,
MembershipOneOfKey,
MembershipStringKey
>;

type UniqueMembershipParam = { id: number } | { uuid: string };

import { prismaToken } from "#lib/typediTokens.js";
import { buildDefaultRepository } from "#repositories/Default.js";

@Service([prismaToken])
export class MembershipRepository {
constructor(private prisma: PrismaClient) {}
export class MembershipRepository extends buildDefaultRepository<
PrismaClient["membership"],
SimpleUniqueParam,
never
>("Membership", {}) {
constructor(protected readonly prisma: PrismaClient) {
super(prisma);
}

public uniqueToWhere(by: SimpleUniqueParam) {
return MembershipRepository.simpleUniqueToWhere(by);
}

async findMembershipByUnique(
param: UniqueMembershipParam,
Expand Down
Loading

0 comments on commit 3bc5465

Please sign in to comment.