From 0dac8f282abc46892c79033426b030b2f7a70f39 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Thu, 21 Aug 2025 21:16:55 +0200 Subject: [PATCH 01/24] feat: async local storage for service method context --- src/services/ServiceMethod.ts | 131 ++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 54 deletions(-) diff --git a/src/services/ServiceMethod.ts b/src/services/ServiceMethod.ts index e5e080dfa..130e37203 100644 --- a/src/services/ServiceMethod.ts +++ b/src/services/ServiceMethod.ts @@ -8,6 +8,7 @@ import type { z } from 'zod' import type { Prisma, PrismaClient } from '@prisma/client' import type { SessionMaybeUser } from '@/auth/Session' import type { AutherStaticFieldsBound } from '@/auth/auther/Auther' +import { AsyncLocalStorage } from 'async_hooks' /** * This is the type for the prisma client that is passed to the service method. @@ -66,16 +67,19 @@ export type ServiceMethodArguments< export type ServiceMethodExecuteArgs< ParamsSchema extends z.ZodTypeAny | undefined, DataSchema extends z.ZodTypeAny | undefined, + OpensTransaction extends boolean, > = { - session: SessionMaybeUser | null, + session?: SessionMaybeUser | null, + prisma?: PrismaPossibleTransaction, bypassAuth?: boolean, } & ServiceMethodParamsData /** * This is the type for the argument that are passed to the execute method of a service method. */ -export type ServiceMethodExecuteArgsUnsafe = { - session: SessionMaybeUser | null, +export type ServiceMethodExecuteArgsUnsafe = { + session?: SessionMaybeUser | null, + prisma?: PrismaPossibleTransaction, bypassAuth?: boolean, } & ServiceMethodParamsDataUnsafe @@ -117,14 +121,15 @@ export type ServiceMethodType< ParamsSchema extends z.ZodTypeAny | undefined, DataSchema extends z.ZodTypeAny | undefined, > = { + (args: ServiceMethodExecuteArgs): Promise, /** * Pass a specific prisma client to the service method. Usefull when using the service method inside a transaction. * @note * @param client */ client: (client: PrismaPossibleTransaction) => { - execute: (args: ServiceMethodExecuteArgs) => Promise, - executeUnsafe: (args: ServiceMethodExecuteArgsUnsafe) => Promise, + execute: (args: ServiceMethodExecuteArgs) => Promise, + executeUnsafe: (args: ServiceMethodExecuteArgsUnsafe) => Promise, }, /** * Use the global prisma client for the service method. @@ -138,6 +143,15 @@ export type ServiceMethodType< dataSchema?: DataSchema, } +export type Context = { prisma: PrismaClient | Prisma.TransactionClient, session: SessionMaybeUser | null } + +const asyncLocalStorage = new AsyncLocalStorage() + +function withContext(defaultContext: Partial, callback: (context: Context) => T): T { + const context = asyncLocalStorage.getStore() ?? { prisma: defaultContext.prisma ?? globalPrisma, session: defaultContext.session ?? null } + return asyncLocalStorage.run(context, () => callback(context)) +} + /** * Wrapper for creating service methods. It handles validation, authorization, and errors for you. * @@ -166,84 +180,93 @@ export function ServiceMethod< // I.e. if the params/data are present when they should be and vice versa. // This is needed to help typescript infer the correct types for the arguments. const expectedArgsArePresent = ( - args: ServiceMethodExecuteArgsUnsafe - ): args is ServiceMethodExecuteArgs => { + args: ServiceMethodExecuteArgsUnsafe + ): args is ServiceMethodExecuteArgs => { const paramsMatch = Boolean(args.params) === Boolean(config.paramsSchema) const dataMatches = Boolean(args.data) === Boolean(config.dataSchema) return paramsMatch && dataMatches } - const client = (prisma: PrismaPossibleTransaction) => { - const executeUnsafe = async (args: ServiceMethodExecuteArgsUnsafe) => { - // First, validate parameters (if any). - if (args.params) { - if (!config.paramsSchema) { - throw new Smorekopp('BAD PARAMETERS', 'Service method recieved params, but has no params schema.') - } - - // TODO: Decide if this should be a validation or a schema. - // For now it's just a schema because it's simpler. - const paramsParse = config.paramsSchema.safeParse(args.params) + async function executeUnsafe(args: ServiceMethodExecuteArgsUnsafe) { + // First, validate parameters (if any). + if (args.params) { + if (!config.paramsSchema) { + throw new Smorekopp('BAD PARAMETERS', 'Service method recieved params, but has no params schema.') + } - if (!paramsParse.success) { - console.log(config.paramsSchema) - console.log(args.params) - console.log(paramsParse) // TODO: This needs to be returned to give good error message. - throw new Smorekopp('BAD PARAMETERS', 'Invalid params passed to service method.') - } + // TODO: Decide if this should be a validation or a schema. + // For now it's just a schema because it's simpler. + const paramsParse = config.paramsSchema.safeParse(args.params) - args.params = paramsParse.data + if (!paramsParse.success) { + // TODO: This needs to be returned to give good error message. + throw new Smorekopp('BAD PARAMETERS', 'Invalid params passed to service method.') } - // Then, validate data (if any). - if (args.data) { - if (!config.dataSchema) { - throw new Smorekopp( - 'BAD DATA', 'Service method recieved data, but has no dataValidation or dataSchema.' - ) - } - const parse = zfd.formData(config.dataSchema).safeParse(args.data) - if (!parse.success) { - console.log(parse.error) - throw new ParseError(parse) - } - args.data = parse.data - } + args.params = paramsParse.data + } - // Then, determine if the correct properties are present. - // This gives the correct type for "args" if the check succeeds. - if (!expectedArgsArePresent(args)) { - throw new Smorekopp('SERVER ERROR', 'Service method recieved invalid arguments.') + // Then, validate data (if any). + if (args.data) { + if (!config.dataSchema) { + throw new Smorekopp( + 'BAD DATA', 'Service method recieved data, but has no dataValidation or dataSchema.' + ) + } + const parse = zfd.formData(config.dataSchema).safeParse(args.data) + if (!parse.success) { + throw new ParseError(parse) } + args.data = parse.data + } + + // Then, determine if the correct properties are present. + // This gives the correct type for "args" if the check succeeds. + if (!expectedArgsArePresent(args)) { + throw new Smorekopp('SERVER ERROR', 'Service method recieved invalid arguments.') + } + + return withContext({ prisma: args.prisma, session: args.session }, async ({ prisma, session }) => { + session ??= Session.empty() // Then, authorize user. // This has to be done after the validation because the auther might use the data to authorize the user. if (!args.bypassAuth) { - const authRes = (await config.auther(args)).auth(args.session ?? Session.empty()) + const authRes = (await config.auther(args)).auth(session) if (!authRes.authorized) { throw new Smorekopp(authRes.status, authRes.getErrorMessage) } } + const isAppropriateClient = (prisma: PrismaClient | Prisma.TransactionClient): prisma is PrismaPossibleTransaction => + !config.opensTransaction || "$transaction" in prisma + + if (!isAppropriateClient(prisma)) { + throw new Smorekopp( + 'SERVER ERROR', + 'Service method that opens a transaction cannot be called from within a transaction..' + ) + } + // Finally, call the method. return prismaErrorWrapper(() => config.method({ ...args, prisma, - session: args.session ?? Session.empty(), + session, })) - } + }) + } + executeUnsafe.client = (prisma: PrismaPossibleTransaction) => { return { - executeUnsafe, - execute: (args: ServiceMethodExecuteArgs) => executeUnsafe(args), + executeUnsafe: (args: ServiceMethodExecuteArgsUnsafe) => executeUnsafe({ prisma, ...args }), + execute: (args: ServiceMethodExecuteArgs) => executeUnsafe({ prisma, ...args }), } } + executeUnsafe.newClient = () => executeUnsafe.client(globalPrisma) + executeUnsafe.dataSchema = config.dataSchema + executeUnsafe.paramsSchema = config.paramsSchema - return { - client, - newClient: () => client(globalPrisma), - dataSchema: config.dataSchema, - paramsSchema: config.paramsSchema, - } + return executeUnsafe } From 7c83790c33eed002c02d161736c986a2ac38a501 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Thu, 21 Aug 2025 21:37:02 +0200 Subject: [PATCH 02/24] style: linting --- src/app/_components/User/UserList/UserRow.tsx | 2 +- .../(permissions)/group-permissions/page.tsx | 2 +- src/auth/authoptions.ts | 2 +- src/auth/getUser.ts | 2 +- .../seeder/src/dobbelOmega/dobbelOmega.ts | 2 +- src/prisma/seeder/src/seeder.ts | 2 +- src/services/ServiceMethod.ts | 61 ++++++++++++------- src/services/groups/committees/create.ts | 2 +- src/services/groups/committees/methods.ts | 4 +- src/services/groups/committees/read.ts | 4 +- src/services/shop/purchase/methods.ts | 2 +- 11 files changed, 51 insertions(+), 34 deletions(-) diff --git a/src/app/_components/User/UserList/UserRow.tsx b/src/app/_components/User/UserList/UserRow.tsx index 69bb9e379..6fc25ba01 100644 --- a/src/app/_components/User/UserList/UserRow.tsx +++ b/src/app/_components/User/UserList/UserRow.tsx @@ -1,7 +1,7 @@ import styles from './UserRow.module.scss' import UserDisplayName from '@/components/User/UserDisplayName' -import type { UserPagingReturn } from '@/services/users/Types' import { useRouter } from 'next/navigation' +import type { UserPagingReturn } from '@/services/users/Types' type PropTypes = { user: UserPagingReturn diff --git a/src/app/admin/(permissions)/group-permissions/page.tsx b/src/app/admin/(permissions)/group-permissions/page.tsx index 0f3c97d40..6b74b3bb8 100644 --- a/src/app/admin/(permissions)/group-permissions/page.tsx +++ b/src/app/admin/(permissions)/group-permissions/page.tsx @@ -1,9 +1,9 @@ import styles from './page.module.scss' +import PermissionCheckbox from './PermissionCheckbox' import { readPermissionMatrixAction } from '@/actions/permissions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { PermissionConfig } from '@/services/permissions/config' import type { Permission } from '@prisma/client' -import PermissionCheckbox from './PermissionCheckbox' export default async function PermissionGroups() { const permissionMatrix = unwrapActionReturn(await readPermissionMatrixAction()) diff --git a/src/auth/authoptions.ts b/src/auth/authoptions.ts index a332c556d..f1f97ecf1 100644 --- a/src/auth/authoptions.ts +++ b/src/auth/authoptions.ts @@ -7,10 +7,10 @@ import prisma from '@/prisma' import { readMembershipsOfUser } from '@/services/groups/memberships/read' import { updateEmailForFeideAccount } from '@/services/auth/feideAccounts/update' import { UserMethods } from '@/services/users/methods' +import { PermissionMethods } from '@/services/permissions/methods' import CredentialsProvider from 'next-auth/providers/credentials' import { decode } from 'next-auth/jwt' import type { AuthOptions } from 'next-auth' -import { PermissionMethods } from '@/services/permissions/methods' export const authOptions: AuthOptions = { providers: [ diff --git a/src/auth/getUser.ts b/src/auth/getUser.ts index 57dd2b387..8929606c1 100644 --- a/src/auth/getUser.ts +++ b/src/auth/getUser.ts @@ -1,13 +1,13 @@ import '@pn-server-only' import { authOptions } from './authoptions' import checkMatrix from '@/utils/checkMatrix' +import { PermissionMethods } from '@/services/permissions/methods' import { getServerSession } from 'next-auth' import { notFound, redirect } from 'next/navigation' import type { Matrix } from '@/utils/checkMatrix' import type { Permission } from '@prisma/client' import type { MembershipFiltered } from '@/services/groups/memberships/Types' import type { UserFiltered } from '@/services/users/Types' -import { PermissionMethods } from '@/services/permissions/methods' type GetUserArgsType = { requiredPermissions?: Matrix, diff --git a/src/prisma/seeder/src/dobbelOmega/dobbelOmega.ts b/src/prisma/seeder/src/dobbelOmega/dobbelOmega.ts index 2eb17d535..4a1d90669 100644 --- a/src/prisma/seeder/src/dobbelOmega/dobbelOmega.ts +++ b/src/prisma/seeder/src/dobbelOmega/dobbelOmega.ts @@ -8,10 +8,10 @@ import migrateMailAliases from './migrateMailAlias' import migrateEvents from './migrateEvents' import { UserMigrator } from './migrateUsers' import migrateCommittees from './migrateCommittees' +import seedProdPermissions from './seedProdPermissions' import manifest from '@/seeder/src/logger' import { PrismaClient as PrismaClientVeven } from '@/prisma-dobbel-omega/client' import type { PrismaClient as PrismaClientPn } from '@prisma/client' -import seedProdPermissions from './seedProdPermissions' /** * !DobbelOmega! diff --git a/src/prisma/seeder/src/seeder.ts b/src/prisma/seeder/src/seeder.ts index c66ceaddf..557586b57 100644 --- a/src/prisma/seeder/src/seeder.ts +++ b/src/prisma/seeder/src/seeder.ts @@ -24,8 +24,8 @@ import seedDevJobAds from './development/seedDevJobAds' import seedDevEvents from './development/seedDevEvents' import seedEvents from './seedEvent' import seedCabin from './seedCabin' -import { PrismaClient } from '@prisma/client' import seedPermissions from './seedPermissions' +import { PrismaClient } from '@prisma/client' export default async function seed( shouldMigrate: boolean, diff --git a/src/services/ServiceMethod.ts b/src/services/ServiceMethod.ts index 130e37203..0000881f1 100644 --- a/src/services/ServiceMethod.ts +++ b/src/services/ServiceMethod.ts @@ -4,11 +4,11 @@ import { prismaErrorWrapper } from './prismaCall' import { default as globalPrisma } from '@/prisma' import { Session } from '@/auth/Session' import { zfd } from 'zod-form-data' +import { AsyncLocalStorage } from 'async_hooks' import type { z } from 'zod' import type { Prisma, PrismaClient } from '@prisma/client' import type { SessionMaybeUser } from '@/auth/Session' import type { AutherStaticFieldsBound } from '@/auth/auther/Auther' -import { AsyncLocalStorage } from 'async_hooks' /** * This is the type for the prisma client that is passed to the service method. @@ -148,7 +148,10 @@ export type Context = { prisma: PrismaClient | Prisma.TransactionClient, session const asyncLocalStorage = new AsyncLocalStorage() function withContext(defaultContext: Partial, callback: (context: Context) => T): T { - const context = asyncLocalStorage.getStore() ?? { prisma: defaultContext.prisma ?? globalPrisma, session: defaultContext.session ?? null } + const context = asyncLocalStorage.getStore() ?? { + prisma: defaultContext.prisma ?? globalPrisma, + session: defaultContext.session ?? null + } return asyncLocalStorage.run(context, () => callback(context)) } @@ -187,11 +190,20 @@ export function ServiceMethod< return paramsMatch && dataMatches } + // Guard to check if the prisma client can be used for this service method. + const isAppropriateClient = ( + prisma: PrismaClient | Prisma.TransactionClient + ): prisma is PrismaPossibleTransaction => + !config.opensTransaction || '$transaction' in prisma + async function executeUnsafe(args: ServiceMethodExecuteArgsUnsafe) { // First, validate parameters (if any). if (args.params) { if (!config.paramsSchema) { - throw new Smorekopp('BAD PARAMETERS', 'Service method recieved params, but has no params schema.') + throw new Smorekopp( + 'BAD PARAMETERS', + 'Service method recieved params, but has no params schema.', + ) } // TODO: Decide if this should be a validation or a schema. @@ -200,7 +212,10 @@ export function ServiceMethod< if (!paramsParse.success) { // TODO: This needs to be returned to give good error message. - throw new Smorekopp('BAD PARAMETERS', 'Invalid params passed to service method.') + throw new Smorekopp( + 'BAD PARAMETERS', + 'Invalid params passed to service method.', + ) } args.params = paramsParse.data @@ -210,7 +225,8 @@ export function ServiceMethod< if (args.data) { if (!config.dataSchema) { throw new Smorekopp( - 'BAD DATA', 'Service method recieved data, but has no dataValidation or dataSchema.' + 'BAD DATA', + 'Service method recieved data, but has no dataValidation or dataSchema.', ) } const parse = zfd.formData(config.dataSchema).safeParse(args.data) @@ -223,12 +239,22 @@ export function ServiceMethod< // Then, determine if the correct properties are present. // This gives the correct type for "args" if the check succeeds. if (!expectedArgsArePresent(args)) { - throw new Smorekopp('SERVER ERROR', 'Service method recieved invalid arguments.') + throw new Smorekopp( + 'SERVER ERROR', + 'Service method recieved invalid arguments.', + ) } return withContext({ prisma: args.prisma, session: args.session }, async ({ prisma, session }) => { session ??= Session.empty() + if (!isAppropriateClient(prisma)) { + throw new Smorekopp( + 'SERVER ERROR', + 'Service method that opens a transaction cannot be called from within a transaction.', + ) + } + // Then, authorize user. // This has to be done after the validation because the auther might use the data to authorize the user. if (!args.bypassAuth) { @@ -239,16 +265,6 @@ export function ServiceMethod< } } - const isAppropriateClient = (prisma: PrismaClient | Prisma.TransactionClient): prisma is PrismaPossibleTransaction => - !config.opensTransaction || "$transaction" in prisma - - if (!isAppropriateClient(prisma)) { - throw new Smorekopp( - 'SERVER ERROR', - 'Service method that opens a transaction cannot be called from within a transaction..' - ) - } - // Finally, call the method. return prismaErrorWrapper(() => config.method({ ...args, @@ -258,12 +274,13 @@ export function ServiceMethod< }) } - executeUnsafe.client = (prisma: PrismaPossibleTransaction) => { - return { - executeUnsafe: (args: ServiceMethodExecuteArgsUnsafe) => executeUnsafe({ prisma, ...args }), - execute: (args: ServiceMethodExecuteArgs) => executeUnsafe({ prisma, ...args }), - } - } + // Add the old api interface for backwards compatibility. + executeUnsafe.client = (prisma: PrismaPossibleTransaction) => ({ + executeUnsafe: (args: ServiceMethodExecuteArgsUnsafe) => + executeUnsafe({ prisma, ...args }), + execute: (args: ServiceMethodExecuteArgs) => + executeUnsafe({ prisma, ...args }), + }) executeUnsafe.newClient = () => executeUnsafe.client(globalPrisma) executeUnsafe.dataSchema = config.dataSchema executeUnsafe.paramsSchema = config.paramsSchema diff --git a/src/services/groups/committees/create.ts b/src/services/groups/committees/create.ts index 5d5c59fd3..4d2ce8b02 100644 --- a/src/services/groups/committees/create.ts +++ b/src/services/groups/committees/create.ts @@ -5,9 +5,9 @@ import { createArticle } from '@/services/cms/articles/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { ImageMethods } from '@/services/images/methods' +import { GroupType } from '@prisma/client' import type { ExpandedCommittee } from './Types' import type { CreateCommitteeTypes } from './validation' -import { GroupType } from '@prisma/client' export async function createCommittee(rawdata: CreateCommitteeTypes['Detailed']): Promise { const { name, shortName, logoImageId } = createCommitteeValidation.detailedValidate(rawdata) diff --git a/src/services/groups/committees/methods.ts b/src/services/groups/committees/methods.ts index 28423ec9c..7aea30c20 100644 --- a/src/services/groups/committees/methods.ts +++ b/src/services/groups/committees/methods.ts @@ -1,10 +1,10 @@ -import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { CommitteeAuthers } from './authers' import { CommitteeConfig } from './config' +import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { ImageMethods } from '@/services/images/methods' import { ServiceMethod } from '@/services/ServiceMethod' -import { z } from 'zod' import { articleRealtionsIncluder } from '@/cms/articles/ConfigVars' +import { z } from 'zod' export namespace CommitteeMethods { diff --git a/src/services/groups/committees/read.ts b/src/services/groups/committees/read.ts index 9fdc957a0..1cdf3127e 100644 --- a/src/services/groups/committees/read.ts +++ b/src/services/groups/committees/read.ts @@ -2,11 +2,11 @@ import prisma from '@/prisma' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { articleRealtionsIncluder } from '@/services/cms/articles/ConfigVars' +import { UserConfig } from '@/services/users/config' +import { ImageMethods } from '@/services/images/methods' import type { ExpandedArticle } from '@/services/cms/articles/Types' import type { CmsParagraph } from '@prisma/client' import type { ExpandedCommittee, ExpandedCommitteeWithCover } from './Types' -import { UserConfig } from '@/services/users/config' -import { ImageMethods } from '@/services/images/methods' export async function readCommittees(): Promise { return await prismaCall(() => prisma.committee.findMany({ diff --git a/src/services/shop/purchase/methods.ts b/src/services/shop/purchase/methods.ts index d3665e3fc..5d08ba983 100644 --- a/src/services/shop/purchase/methods.ts +++ b/src/services/shop/purchase/methods.ts @@ -5,8 +5,8 @@ import { ServerError } from '@/services/error' import { ServiceMethod } from '@/services/ServiceMethod' import { UserMethods } from '@/services/users/methods' import { UserConfig } from '@/services/users/config' -import { PurchaseMethod } from '@prisma/client' import { PermissionMethods } from '@/services/permissions/methods' +import { PurchaseMethod } from '@prisma/client' export namespace PurchaseMethods { export const createByStudentCard = ServiceMethod({ From 9164022a33a3d4240c28ca763b30205a2ec32137 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Thu, 21 Aug 2025 22:40:31 +0200 Subject: [PATCH 03/24] refactor: simplify service method calls --- src/actions/action.ts | 12 ++++-- src/actions/visibility/read.ts | 2 +- src/app/api/apiHandler.ts | 18 ++++----- src/app/lockers/[id]/page.tsx | 2 +- src/auth/Session.ts | 6 +-- src/auth/VevenAdapter.ts | 4 +- src/auth/authoptions.ts | 6 +-- src/auth/getUser.ts | 2 +- .../seeder/src/development/seedDevEvents.ts | 6 ++- .../seeder/src/development/seedDevJobAds.ts | 3 +- src/services/admission/methods.ts | 3 +- src/services/api-keys/methods.ts | 6 +-- src/services/applications/periods/methods.ts | 7 ++-- src/services/auth/methods.ts | 19 ++++----- src/services/cabin/booking/methods.ts | 39 +++++++------------ src/services/cabin/pricePeriod/methods.ts | 28 ++++--------- src/services/cabin/product/methods.ts | 9 ++--- src/services/dots/methods.ts | 7 ++-- src/services/events/registration/methods.ts | 5 +-- src/services/groups/committees/create.ts | 2 +- src/services/groups/committees/methods.ts | 7 ++-- src/services/groups/committees/read.ts | 2 +- src/services/groups/committees/update.ts | 2 +- src/services/groups/interestGroups/methods.ts | 2 +- src/services/groups/memberships/create.ts | 6 +-- src/services/groups/memberships/destroy.ts | 4 +- src/services/groups/memberships/update.ts | 2 +- src/services/groups/methods.ts | 8 ++-- src/services/images/collections/read.ts | 2 +- src/services/images/methods.ts | 7 +--- src/services/lockers/reservations/methods.ts | 5 +-- .../email/systemMail/resetPassword.tsx | 3 +- src/services/ombul/create.ts | 2 +- src/services/permissions/methods.ts | 7 +--- src/services/shop/purchase/methods.ts | 6 +-- src/services/users/methods.ts | 8 ++-- tests/services/apiKeys.test.ts | 12 +++--- tests/services/jobads.test.ts | 30 +++++++------- 38 files changed, 127 insertions(+), 174 deletions(-) diff --git a/src/actions/action.ts b/src/actions/action.ts index eb4a08fba..b8dc127a8 100644 --- a/src/actions/action.ts +++ b/src/actions/action.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { safeServerCall } from './safeServerCall' import { Session } from '@/auth/Session' import type { ActionReturn } from './Types' -import type { ServiceMethodType } from '@/services/ServiceMethod' +import type { ServiceMethodExecuteArgs, ServiceMethodType } from '@/services/ServiceMethod' import type { z } from 'zod' // This function is overloaded to allow for different combinations of parameters and data. @@ -39,8 +39,8 @@ export function action< // Letting the arguments to the actual function be unknown is safer as anything can be passed to it form the client. // The action and service method will validate the parameter and data before it is used. // - // For convinience this function is given a return type that is more specific. The return type is a function that - // has arguments witch match the underlying service method. This makes programming easier as intellisesne can + // For convenience this function is given a return type that is more specific. The return type is a function that + // has arguments witch match the underlying service method. This makes programming easier as Intellisense can // help and errors are caught at compile time. const actionUnsafe = async (params?: unknown, data?: unknown) => { const session = await Session.fromNextAuth() @@ -51,7 +51,11 @@ export function action< data = undefined } - return safeServerCall(() => serviceMethod.newClient().executeUnsafe({ session, params, data })) + return safeServerCall(() => serviceMethod({ + session, + params, + data, + } as unknown as ServiceMethodExecuteArgs)) } // If the service method has a params schema, we require the params to be passed to the action. diff --git a/src/actions/visibility/read.ts b/src/actions/visibility/read.ts index 75f68363d..3533188c2 100644 --- a/src/actions/visibility/read.ts +++ b/src/actions/visibility/read.ts @@ -17,7 +17,7 @@ export async function readVisibilityForAdminAction(id: number): Promise readVisibilityCollapsed(id)), // TODO: Fix Authing here. The bypass should be false - safeServerCall(() => GroupMethods.readGroupsStructured.newClient().execute({ session: null, bypassAuth: true })) + safeServerCall(() => GroupMethods.readGroupsStructured({ session: null, bypassAuth: true })) ]) if (!visibilityRes.success || !groupsRes.success) return createActionError('UNKNOWN ERROR', 'noe gikk galt') diff --git a/src/app/api/apiHandler.ts b/src/app/api/apiHandler.ts index 6a53eff1a..134302858 100644 --- a/src/app/api/apiHandler.ts +++ b/src/app/api/apiHandler.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { Session } from '@/auth/Session' import { getHttpErrorCode, ServerError, Smorekopp } from '@/services/error' import type { ErrorCode, ErrorMessage } from '@/services/error' -import type { ServiceMethodType } from '@/services/ServiceMethod' +import type { ServiceMethodExecuteArgs, ServiceMethodType } from '@/services/ServiceMethod' import type { SessionNoUser } from '@/auth/Session' import type { z } from 'zod' @@ -45,15 +45,11 @@ export function apiHandler< // TODO: I think I will rewrite this to be easier to read return async (req: Request, { params: rawParams }: { params: Promise }) => await apiHandlerGeneric(req, async session => { + let data + if (serviceMethod.dataSchema) { try { - const rawdata = await req.json() - - return serviceMethod.newClient().executeUnsafe({ - params: params ? params(await rawParams) : undefined, - data: rawdata, - session, - }) + data = await req.json() } catch (error) { if (error instanceof SyntaxError) { throw new ServerError('BAD DATA', 'The API only accepts valid json data.') @@ -62,11 +58,11 @@ export function apiHandler< } } - return serviceMethod.newClient().executeUnsafe({ + return serviceMethod({ params: params ? params(await rawParams) : undefined, - data: undefined, + data, session, - }) + } as unknown as ServiceMethodExecuteArgs) }) } diff --git a/src/app/lockers/[id]/page.tsx b/src/app/lockers/[id]/page.tsx index 6b3f93eeb..0e6c0fcfe 100644 --- a/src/app/lockers/[id]/page.tsx +++ b/src/app/lockers/[id]/page.tsx @@ -33,7 +33,7 @@ export default async function Locker({ params }: PropTypes) { const reservation = locker.data.LockerReservation[0] const groupName = (isReserved && reservation.group) ? inferGroupName(checkGroupValidity(reservation.group)) : '' - const groups = await GroupMethods.readGroupsOfUser.newClient().execute({ + const groups = await GroupMethods.readGroupsOfUser({ session: null, bypassAuth: true, params: { diff --git a/src/auth/Session.ts b/src/auth/Session.ts index 6f5919bf0..023ba5e09 100644 --- a/src/auth/Session.ts +++ b/src/auth/Session.ts @@ -71,7 +71,7 @@ export class Session { public static async fromNextAuth(): Promise | Session<'HAS_USER'>> { const { user = null, - permissions = await PermissionMethods.readDefaultPermissions.newClient().execute({ + permissions = await PermissionMethods.readDefaultPermissions({ session: null, bypassAuth: true, }), @@ -87,7 +87,7 @@ export class Session { * If the key is null, the session will be cratedwith only default permissios */ public static async fromApiKey(keyAndIdEncoded: string | null): Promise> { - const defaultPermissions = await PermissionMethods.readDefaultPermissions.newClient().execute({ + const defaultPermissions = await PermissionMethods.readDefaultPermissions({ session: null, bypassAuth: true, }) @@ -99,7 +99,7 @@ export class Session { let apiKeyFetch try { - apiKeyFetch = await ApiKeyMethods.readWithHash.newClient().execute({ + apiKeyFetch = await ApiKeyMethods.readWithHash({ session: null, bypassAuth: true, params: { id } diff --git a/src/auth/VevenAdapter.ts b/src/auth/VevenAdapter.ts index 1a1730b5e..933380203 100644 --- a/src/auth/VevenAdapter.ts +++ b/src/auth/VevenAdapter.ts @@ -105,7 +105,7 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { async getUser(id) { console.log('get id') - const user = await UserMethods.readOrNull.newClient().execute({ + const user = await UserMethods.readOrNull({ params: { id: Number(id) }, session: null, bypassAuth: true, @@ -117,7 +117,7 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { async getUserByEmail(email) { console.log('get email') console.log(email) - const user = await UserMethods.readOrNull.newClient().execute({ + const user = await UserMethods.readOrNull({ params: { email }, session: null, bypassAuth: true, diff --git a/src/auth/authoptions.ts b/src/auth/authoptions.ts index f1f97ecf1..b8211d23e 100644 --- a/src/auth/authoptions.ts +++ b/src/auth/authoptions.ts @@ -127,7 +127,7 @@ export const authOptions: AuthOptions = { } // Trigger is undefined for subsequent calls case undefined: { - const dbUser = await UserMethods.read.newClient().execute({ + const dbUser = await UserMethods.read({ params: { id: token.user.id }, session: null, bypassAuth: true, @@ -165,12 +165,12 @@ export const authOptions: AuthOptions = { return { provider, - user: await UserMethods.read.newClient().execute({ + user: await UserMethods.read({ params: { id: userId }, session: null, bypassAuth: true, }), - permissions: await PermissionMethods.readPermissionsOfUser.newClient().execute({ + permissions: await PermissionMethods.readPermissionsOfUser({ bypassAuth: true, session: null, params: { diff --git a/src/auth/getUser.ts b/src/auth/getUser.ts index 8929606c1..8c356269e 100644 --- a/src/auth/getUser.ts +++ b/src/auth/getUser.ts @@ -92,7 +92,7 @@ export async function getUser({ }: GetUserArgsType = {}): Promise> { const { user = null, - permissions = await PermissionMethods.readDefaultPermissions.newClient().execute({ + permissions = await PermissionMethods.readDefaultPermissions({ session: null, bypassAuth: true, }), diff --git a/src/prisma/seeder/src/development/seedDevEvents.ts b/src/prisma/seeder/src/development/seedDevEvents.ts index c06dc7192..795877636 100644 --- a/src/prisma/seeder/src/development/seedDevEvents.ts +++ b/src/prisma/seeder/src/development/seedDevEvents.ts @@ -17,7 +17,8 @@ export default async function seedDevEvents(prisma: PrismaClient) { } }) - const bedpres = await EventMethods.create.client(prisma).execute({ + const bedpres = await EventMethods.create({ + prisma, session: null, bypassAuth: true, data: { @@ -37,7 +38,8 @@ export default async function seedDevEvents(prisma: PrismaClient) { } }) - await EventMethods.create.client(prisma).execute({ + await EventMethods.create({ + prisma, session: null, bypassAuth: true, data: { diff --git a/src/prisma/seeder/src/development/seedDevJobAds.ts b/src/prisma/seeder/src/development/seedDevJobAds.ts index 2a894857b..6b61e876e 100644 --- a/src/prisma/seeder/src/development/seedDevJobAds.ts +++ b/src/prisma/seeder/src/development/seedDevJobAds.ts @@ -51,7 +51,8 @@ export default async function seedDevJobAds(prisma: PrismaClient) { ] for (const jobAd of jobAdData) { - const restult = await JobadMethods.create.client(prisma).execute({ + const restult = await JobadMethods.create({ + prisma, data: { ...jobAd, companyId: 1, diff --git a/src/services/admission/methods.ts b/src/services/admission/methods.ts index e654b4f69..05b0d1eb6 100644 --- a/src/services/admission/methods.ts +++ b/src/services/admission/methods.ts @@ -49,8 +49,7 @@ export namespace AdmissionMethods { }) // check if user has taken all admissions - const userTrials = await readTrial.newClient().execute({ - session, + const userTrials = await readTrial({ params: { userId: data.userId }, diff --git a/src/services/api-keys/methods.ts b/src/services/api-keys/methods.ts index 751f60514..177ca6b70 100644 --- a/src/services/api-keys/methods.ts +++ b/src/services/api-keys/methods.ts @@ -77,7 +77,7 @@ export namespace ApiKeyMethods { if (!apiKey) throw new ServerError('BAD PARAMETERS', 'Api key does not exist') return { ...apiKey, - ...await updateIfExpired.client(prisma).execute({ + ...await updateIfExpired({ params: apiKey, session: null, bypassAuth: true, @@ -98,7 +98,7 @@ export namespace ApiKeyMethods { return await Promise.all(apiKeys.map(async apiKey => ({ ...apiKey, - ...await updateIfExpired.client(prisma).execute({ + ...await updateIfExpired({ params: apiKey, session: null, bypassAuth: true, @@ -125,7 +125,7 @@ export namespace ApiKeyMethods { return { ...apiKey, - ...await updateIfExpired.client(prisma).execute({ + ...await updateIfExpired({ params: apiKey, session: null, bypassAuth: true, diff --git a/src/services/applications/periods/methods.ts b/src/services/applications/periods/methods.ts index 5a4ce75ff..ead3e74e9 100644 --- a/src/services/applications/periods/methods.ts +++ b/src/services/applications/periods/methods.ts @@ -49,7 +49,7 @@ export namespace ApplicationPeriodMethods { paramsSchema: z.object({ name: z.string() }), - method: async ({ prisma, data, params, session }) => { + method: async ({ prisma, data, params }) => { const period = await prisma.applicationPeriod.update({ where: { name: params.name }, data: { @@ -90,12 +90,11 @@ export namespace ApplicationPeriodMethods { }) await Promise.all( removeApplications.map(async application => - await ApplicationMethods.destroy.newClient().execute({ + await ApplicationMethods.destroy({ params: { userId: application.userId, commiteeParticipationId: application.applicationPeriodCommiteeId }, - session, }) ) ) @@ -129,7 +128,7 @@ export namespace ApplicationPeriodMethods { }), auther: () => ApplicationPeriodAuthers.removeAllApplicationTexts.dynamicFields({}), method: async ({ prisma, params, session }) => { - const period = await read.client(prisma).execute({ + const period = await read({ params: { name: params.name }, session }) diff --git a/src/services/auth/methods.ts b/src/services/auth/methods.ts index 85459bb12..dc317f2c2 100644 --- a/src/services/auth/methods.ts +++ b/src/services/auth/methods.ts @@ -29,7 +29,7 @@ export namespace AuthMethods { const iat = new Date(payload.iat * 1000) - const user = await UserMethods.read.client(prisma).execute({ + const user = await UserMethods.read({ params: { id: userId, }, @@ -92,18 +92,14 @@ export namespace AuthMethods { }), dataSchema: UserSchemas.updatePassword, auther: ({ params }) => AuthAuthers.resetPassword.dynamicFields(params), - method: async ({ prisma, params, data, session }) => { - const userId = await verifyResetPasswordToken.client(prisma).executeUnsafe({ - params, - session, - }) + method: async ({ params, data }) => { + const userId = await verifyResetPasswordToken({ params }) - UserMethods.updatePassword.client(prisma).execute({ + UserMethods.updatePassword({ params: { id: userId, }, data, - session, bypassAuth: true, }) } @@ -112,14 +108,13 @@ export namespace AuthMethods { export const sendResetPasswordEmail = ServiceMethod({ dataSchema: AuthSchemas.sendResetPasswordEmail, auther: () => AuthAuthers.sendResetPasswordEmail.dynamicFields({}), - method: async ({ prisma, data, session }) => { + method: async ({ data }) => { console.log(data) try { - const user = await UserMethods.read.client(prisma).executeUnsafe({ + const user = await UserMethods.read({ params: { - email: data.email + email: data.email, }, - session, bypassAuth: true, }) diff --git a/src/services/cabin/booking/methods.ts b/src/services/cabin/booking/methods.ts index dfb230bfd..5f94378a0 100644 --- a/src/services/cabin/booking/methods.ts +++ b/src/services/cabin/booking/methods.ts @@ -56,11 +56,10 @@ export namespace CabinBookingMethods { }), auther: ServerOnlyAuther, dataSchema: CabinBookingSchemas.createBookingUserAttached, - method: async ({ prisma, params, data, session }) => { + method: async ({ prisma, params, data }) => { // TODO: Prevent Race conditions - const latestReleaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod.client(prisma).execute({ - session, + const latestReleaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true, }) @@ -72,9 +71,8 @@ export namespace CabinBookingMethods { throw new ServerError('BAD PARAMETERS', 'Hytta kan ikke bookes etter siste slippdato.') } - if (!await cabinAvailable.client(prisma).execute({ + if (!await cabinAvailable({ params: data, - session, bypassAuth: true, })) { throw new ServerError('BAD PARAMETERS', 'Hytta er ikke tilgjengelig i den perioden.') @@ -125,10 +123,7 @@ export namespace CabinBookingMethods { throw new ServerError('BAD PARAMETERS', 'Sengebookinger må inneholde minst ett produkt.') } - const pricePeriods = await CabinPricePeriodMethods.readMany.client(prisma).execute({ - bypassAuth: true, - session, - }) + const pricePeriods = await CabinPricePeriodMethods.readMany({ bypassAuth: true }) const priceObjects = calculateCabinBookingPrice({ pricePeriods, @@ -170,11 +165,10 @@ export namespace CabinBookingMethods { }), auther: ServerOnlyAuther, dataSchema: CabinBookingSchemas.createBookingUserAttached, - method: async ({ prisma, params, data, session }) => { - const result = await create.client(prisma).execute({ + method: async ({ prisma, params, data }) => { + const result = await create({ params, data, - session, bypassAuth: true, }) @@ -214,15 +208,14 @@ export namespace CabinBookingMethods { userId: params.userId, }), dataSchema: CabinBookingSchemas.createBookingUserAttached, - method: async ({ prisma, params, data, session }) => - createBookingWithUser.client(prisma).execute({ + method: async ({ params, data }) => + createBookingWithUser({ params: { userId: params.userId, bookingType: BookingType.CABIN, bookingProducts: params.bookingProducts, }, data, - session, bypassAuth: true, }) }) @@ -236,15 +229,14 @@ export namespace CabinBookingMethods { userId: params.userId, }), dataSchema: CabinBookingSchemas.createBookingUserAttached, - method: async ({ prisma, params, data, session }) => - createBookingWithUser.client(prisma).execute({ + method: async ({ params, data }) => + createBookingWithUser({ params: { userId: params.userId, bookingType: BookingType.BED, bookingProducts: params.bookingProducts, }, data, - session, bypassAuth: true, }) }) @@ -256,15 +248,14 @@ export namespace CabinBookingMethods { }), auther: ServerOnlyAuther, dataSchema: CabinBookingSchemas.createBookingNoUser, - method: async ({ prisma, params, data, session }) => { - const result = await create.client(prisma).execute({ + method: async ({ prisma, params, data }) => { + const result = await create({ params, data: { ...data, numberOfMembers: 0, numberOfNonMembers: 0, }, - session, bypassAuth: true, }) @@ -298,13 +289,12 @@ export namespace CabinBookingMethods { }), auther: () => CabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}), dataSchema: CabinBookingSchemas.createBookingNoUser, - method: async ({ prisma, params, data, session }) => createBookingNoUser.client(prisma).execute({ + method: async ({ params, data }) => createBookingNoUser({ params: { bookingType: BookingType.CABIN, bookingProducts: params.bookingProducts, }, data, - session, bypassAuth: true, }) }) @@ -315,13 +305,12 @@ export namespace CabinBookingMethods { }), auther: () => CabinBookingAuthers.createBedBookingNoUser.dynamicFields({}), dataSchema: CabinBookingSchemas.createBookingNoUser, - method: async ({ prisma, params, data, session }) => createBookingNoUser.client(prisma).execute({ + method: async ({ params, data }) => createBookingNoUser({ params: { bookingType: BookingType.BED, bookingProducts: params.bookingProducts, }, data, - session, bypassAuth: true, }) }) diff --git a/src/services/cabin/pricePeriod/methods.ts b/src/services/cabin/pricePeriod/methods.ts index 731c7e1b8..51994fc41 100644 --- a/src/services/cabin/pricePeriod/methods.ts +++ b/src/services/cabin/pricePeriod/methods.ts @@ -11,11 +11,8 @@ export namespace CabinPricePeriodMethods { export const create = ServiceMethod({ auther: () => CabinPricePeriodAuthers.create.dynamicFields({}), dataSchema: CabinPricePeriodSchemas.createPricePeriod, - method: async ({ prisma, data, session }) => { - const currentReleaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod.client(prisma).execute({ - bypassAuth: true, - session, - }) + method: async ({ prisma, data }) => { + const currentReleaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) if (currentReleaseDate && currentReleaseDate.releaseUntil >= data.validFrom) { throw new ServerError( @@ -67,11 +64,8 @@ export namespace CabinPricePeriodMethods { paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params, session }) => { - const currentReleasePeriod = await CabinReleasePeriodMethods.getCurrentReleasePeriod.client(prisma).execute({ - bypassAuth: true, - session, - }) + method: async ({ prisma, params }) => { + const currentReleasePeriod = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) const pricePeriod = await prisma.pricePeriod.findUniqueOrThrow({ where: params, @@ -94,11 +88,8 @@ export namespace CabinPricePeriodMethods { export const readPublicPeriods = ServiceMethod({ auther: () => CabinPricePeriodAuthers.readPublicPeriods.dynamicFields({}), - method: async ({ prisma, session }) => { - const releaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod.client(prisma).execute({ - bypassAuth: true, - session, - }) + method: async ({ prisma }) => { + const releaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) const [currentPeriod, futurePeriods] = await Promise.all([ prisma.pricePeriod.findFirstOrThrow({ @@ -130,11 +121,8 @@ export namespace CabinPricePeriodMethods { export const readUnreleasedPeriods = ServiceMethod({ auther: () => CabinPricePeriodAuthers.read.dynamicFields({}), - method: async ({ prisma, session }) => { - const releaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod.client(prisma).execute({ - bypassAuth: true, - session, - }) + method: async ({ prisma }) => { + const releaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) return prisma.pricePeriod.findMany({ where: { validFrom: { diff --git a/src/services/cabin/product/methods.ts b/src/services/cabin/product/methods.ts index 00e634e76..f276ebe73 100644 --- a/src/services/cabin/product/methods.ts +++ b/src/services/cabin/product/methods.ts @@ -31,7 +31,7 @@ export namespace CabinProductMethods { id: data.pricePeriodId, } }), - CabinReleasePeriodMethods.getCurrentReleasePeriod.client(prisma).execute({ + CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true, session }) @@ -61,11 +61,8 @@ export namespace CabinProductMethods { export const readActive = ServiceMethod({ auther: () => CabinProductAuthers.read.dynamicFields({}), - method: async ({ prisma, session }) => { - const pricePeriods = await CabinPricePeriodMethods.readPublicPeriods.client(prisma).execute({ - bypassAuth: true, - session, - }) + method: async ({ prisma }) => { + const pricePeriods = await CabinPricePeriodMethods.readPublicPeriods({ bypassAuth: true }) return await prisma.cabinProduct.findMany({ where: { diff --git a/src/services/dots/methods.ts b/src/services/dots/methods.ts index d229f607c..057e260ae 100644 --- a/src/services/dots/methods.ts +++ b/src/services/dots/methods.ts @@ -40,10 +40,9 @@ const create = ServiceMethod({ accuserId: z.number(), }), opensTransaction: true, - method: async ({ prisma, params, data: { value, ...data }, session }) => { - const activeDots = await readForUser.client(prisma).execute({ - params: { userId: data.userId, onlyActive: true }, - session, + method: async ({ prisma, params, data: { value, ...data } }) => { + const activeDots = await readForUser({ + params: { userId: data.userId, onlyActive: true } }) const dotData : { expiresAt: Date }[] = [] diff --git a/src/services/events/registration/methods.ts b/src/services/events/registration/methods.ts index 19af4a235..63c2afa7d 100644 --- a/src/services/events/registration/methods.ts +++ b/src/services/events/registration/methods.ts @@ -204,10 +204,9 @@ export namespace EventRegistrationMethods { take: z.number().optional(), type: z.nativeEnum(EventRegistrationConfig.REGISTRATION_READER_TYPE).optional(), }), - method: async ({ prisma, params, session }): Promise => { - const defaultImage = await ImageMethods.readSpecial.client(prisma).execute({ + method: async ({ prisma, params }): Promise => { + const defaultImage = await ImageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, - session, }) const skipTake = await calculateTakeSkip(prisma, params) diff --git a/src/services/groups/committees/create.ts b/src/services/groups/committees/create.ts index 4d2ce8b02..fb8786bc7 100644 --- a/src/services/groups/committees/create.ts +++ b/src/services/groups/committees/create.ts @@ -13,7 +13,7 @@ export async function createCommittee(rawdata: CreateCommitteeTypes['Detailed']) const { name, shortName, logoImageId } = createCommitteeValidation.detailedValidate(rawdata) let defaultLogoImageId: number if (!logoImageId) { - defaultLogoImageId = await ImageMethods.readSpecial.client(prisma).execute({ + defaultLogoImageId = await ImageMethods.readSpecial({ params: { special: 'DAFAULT_COMMITTEE_LOGO' }, session: null //TODO: pass session }).then(res => res.id) } diff --git a/src/services/groups/committees/methods.ts b/src/services/groups/committees/methods.ts index 7aea30c20..c28e3a4ab 100644 --- a/src/services/groups/committees/methods.ts +++ b/src/services/groups/committees/methods.ts @@ -22,7 +22,7 @@ export namespace CommitteeMethods { z.object({ shortName: z.string() }) ]), method: async ({ prisma, params }) => { - const defaultImage = await ImageMethods.readSpecial.client(prisma).execute({ + const defaultImage = await ImageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, session: null, bypassAuth: true @@ -99,10 +99,9 @@ export namespace CommitteeMethods { shortName: z.string(), active: z.boolean().optional(), }), - method: async ({ prisma, session, params }) => { - const defaultImage = await ImageMethods.readSpecial.client(prisma).execute({ + method: async ({ prisma, params }) => { + const defaultImage = await ImageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, - session, }) diff --git a/src/services/groups/committees/read.ts b/src/services/groups/committees/read.ts index 1cdf3127e..833dd150d 100644 --- a/src/services/groups/committees/read.ts +++ b/src/services/groups/committees/read.ts @@ -90,7 +90,7 @@ export async function readCommitteeParagraph(shortName: string) : Promise res.id) } diff --git a/src/services/groups/interestGroups/methods.ts b/src/services/groups/interestGroups/methods.ts index 93d1da797..ef6089669 100644 --- a/src/services/groups/interestGroups/methods.ts +++ b/src/services/groups/interestGroups/methods.ts @@ -76,7 +76,7 @@ export namespace InterestGroupMethods { dataSchema: InterestGroupSchemas.update, auther: async ({ params }) => InterestGroupAuthers.update.dynamicFields({ groupId: ( - await read.newClient().execute({ + await read({ params: { id: params.id }, session: null, bypassAuth: true, diff --git a/src/services/groups/memberships/create.ts b/src/services/groups/memberships/create.ts index 5c271fa1d..da4c23bc5 100644 --- a/src/services/groups/memberships/create.ts +++ b/src/services/groups/memberships/create.ts @@ -18,7 +18,7 @@ export async function createMembershipForUser( throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await GroupMethods.readCurrentGroupOrder.newClient().execute({ + const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ session: null, bypassAuth: true, params: { @@ -65,7 +65,7 @@ export async function createMembershipsForGroup( if (!await canEasilyManageMembershipOfGroup(groupId)) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await GroupMethods.readCurrentGroupOrder.newClient().execute({ + const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ session: null, bypassAuth: true, params: { @@ -113,7 +113,7 @@ export async function createMembershipsForUser( if (!await canEasilyManageMembershipOfGroups(data.map(group => group.groupId))) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const ordersMap = await GroupMethods.readCurrentGroupOrders.newClient().execute({ + const ordersMap = await GroupMethods.readCurrentGroupOrders({ session: null, bypassAuth: true, params: { diff --git a/src/services/groups/memberships/destroy.ts b/src/services/groups/memberships/destroy.ts index be62cd702..5fe713d31 100644 --- a/src/services/groups/memberships/destroy.ts +++ b/src/services/groups/memberships/destroy.ts @@ -19,7 +19,7 @@ export async function destoryMembershipOfUser({ if (!await canEasilyManageMembershipOfGroup(groupId)) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await GroupMethods.readCurrentGroupOrder.newClient().execute({ + const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ bypassAuth: true, session: null, params: { @@ -48,7 +48,7 @@ export async function destroyMembershipOfUsers( if (!await canEasilyManageMembershipOfGroup(groupId)) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await GroupMethods.readCurrentGroupOrder.newClient().execute({ + const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ session: null, bypassAuth: true, params: { diff --git a/src/services/groups/memberships/update.ts b/src/services/groups/memberships/update.ts index 048787876..d83782eae 100644 --- a/src/services/groups/memberships/update.ts +++ b/src/services/groups/memberships/update.ts @@ -18,7 +18,7 @@ export async function updateMembership({ active?: boolean }): Promise { const order = (orderArg && typeof orderArg === 'number') ? orderArg : ( - await GroupMethods.readCurrentGroupOrder.newClient().execute({ + await GroupMethods.readCurrentGroupOrder({ bypassAuth: true, session: null, params: { diff --git a/src/services/groups/methods.ts b/src/services/groups/methods.ts index 6bc53dce7..93fd11650 100644 --- a/src/services/groups/methods.ts +++ b/src/services/groups/methods.ts @@ -268,7 +268,7 @@ export namespace GroupMethods { export const readGroupsStructured = ServiceMethod({ auther: () => GroupAuthers.read.dynamicFields({}), - method: async ({ prisma, session }) => { + method: async () => { const groupsStructured: GroupsStructured = { CLASS: { ...GroupTypesConfig.CLASS, @@ -296,10 +296,8 @@ export namespace GroupMethods { }, } satisfies GroupsStructured - const groupExpanded = await readGroupsExpanded.client(prisma).execute({ - bypassAuth: true, - session, - }) + const groupExpanded = await readGroupsExpanded({ bypassAuth: true }) + groupExpanded.forEach(group => { groupsStructured[group.groupType].groups.push(group) }) diff --git a/src/services/images/collections/read.ts b/src/services/images/collections/read.ts index 79d318417..10d77513e 100644 --- a/src/services/images/collections/read.ts +++ b/src/services/images/collections/read.ts @@ -68,7 +68,7 @@ export async function readImageCollectionsPage( ...cursorPageingSelection(page) })) - const lensCamera = await ImageMethods.readSpecial.client(prisma).execute({ + const lensCamera = await ImageMethods.readSpecial({ params: { special: 'DEFAULT_IMAGE_COLLECTION_COVER' }, diff --git a/src/services/images/methods.ts b/src/services/images/methods.ts index cf50250b6..78292c940 100644 --- a/src/services/images/methods.ts +++ b/src/services/images/methods.ts @@ -78,19 +78,16 @@ export namespace ImageMethods { }), dataSchema: ImageSchemas.createMany, method: async ({ - prisma, params: { useFileName, collectionId }, data, - session, }) => { console.log('data', data) for (const file of data.files) { console.log('file', file) const name = useFileName ? file.name.split('.')[0] : undefined - await create.client(prisma).execute({ + await create({ params: { collectionId }, data: { file, name, alt: file.name.split('.')[0], licenseId: data.licenseId, credit: data.credit }, - session }) } } @@ -198,7 +195,7 @@ export namespace ImageMethods { }) if (!image) { - return await createSourceless.client(prisma).execute( + return await createSourceless( { params: { name: special, special }, session } ) } diff --git a/src/services/lockers/reservations/methods.ts b/src/services/lockers/reservations/methods.ts index 7623a254a..9072ea204 100644 --- a/src/services/lockers/reservations/methods.ts +++ b/src/services/lockers/reservations/methods.ts @@ -26,7 +26,7 @@ export namespace LockerReservationMethods { // TODO: Use authers for authing in stead of this // Verify that user is in group if (data.groupId) { - const groupUsers = await GroupMethods.readUsersOfGroups.newClient().execute({ + const groupUsers = await GroupMethods.readUsersOfGroups({ session: null, bypassAuth: true, params: { @@ -108,8 +108,7 @@ export namespace LockerReservationMethods { // Verify that user is in group if (data.groupId) { - const groupUsers = await GroupMethods.readUsersOfGroups.client(prisma).execute({ - session, + const groupUsers = await GroupMethods.readUsersOfGroups({ bypassAuth: true, params: { groups: [{ groupId: data.groupId, admin: false }] diff --git a/src/services/notifications/email/systemMail/resetPassword.tsx b/src/services/notifications/email/systemMail/resetPassword.tsx index 962511f19..425a4274e 100644 --- a/src/services/notifications/email/systemMail/resetPassword.tsx +++ b/src/services/notifications/email/systemMail/resetPassword.tsx @@ -10,9 +10,8 @@ export async function sendResetPasswordMail(email: string) { const emailParsed = z.string().email().parse(email) try { - const user = await UserMethods.read.newClient().execute({ + const user = await UserMethods.read({ params: { email: emailParsed }, - session: null, bypassAuth: true, }) diff --git a/src/services/ombul/create.ts b/src/services/ombul/create.ts index f9e782919..7ca0de738 100644 --- a/src/services/ombul/create.ts +++ b/src/services/ombul/create.ts @@ -43,7 +43,7 @@ export async function createOmbul( // create coverimage const ombulCoverCollection = await readSpecialImageCollection('OMBULCOVERS') - const coverImage = await ImageMethods.create.client(prisma).execute({ + const coverImage = await ImageMethods.create({ params: { collectionId: ombulCoverCollection.id, }, diff --git a/src/services/permissions/methods.ts b/src/services/permissions/methods.ts index d02f2ce2d..4044de137 100644 --- a/src/services/permissions/methods.ts +++ b/src/services/permissions/methods.ts @@ -22,12 +22,9 @@ export namespace PermissionMethods { paramsSchema: z.object({ userId: z.number(), }), - method: async ({ prisma, session, params }) => { + method: async ({ prisma, params }) => { const [defaultPermissions, groupPermissions] = await Promise.all([ - readDefaultPermissions.client(prisma).execute({ - bypassAuth: true, - session, - }), + readDefaultPermissions({}), prisma.membership.findMany({ where: { userId: params.userId, diff --git a/src/services/shop/purchase/methods.ts b/src/services/shop/purchase/methods.ts index 5d08ba983..bcd826167 100644 --- a/src/services/shop/purchase/methods.ts +++ b/src/services/shop/purchase/methods.ts @@ -13,11 +13,10 @@ export namespace PurchaseMethods { auther: async ({ data }) => { let user try { - user = await UserMethods.read.newClient().execute({ + user = await UserMethods.read({ params: { studentCard: data.studentCard, }, - session: null, bypassAuth: true, }) } catch (e) { @@ -27,8 +26,7 @@ export namespace PurchaseMethods { throw e } - const permissions = await PermissionMethods.readPermissionsOfUser.newClient().execute({ - session: null, + const permissions = await PermissionMethods.readPermissionsOfUser({ bypassAuth: true, params: { userId: user.id, diff --git a/src/services/users/methods.ts b/src/services/users/methods.ts index c5a28cf0c..5e74e236a 100644 --- a/src/services/users/methods.ts +++ b/src/services/users/methods.ts @@ -95,10 +95,9 @@ export namespace UserMethods { username: z.string(), }), auther: ({ params }) => UserAuthers.readProfile.dynamicFields({ username: params.username }), - method: async ({ prisma, params, session }) => { - const defaultProfileImage = await ImageMethods.readSpecial.client(prisma).execute({ + method: async ({ prisma, params }) => { + const defaultProfileImage = await ImageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, - session, }) const user = await prisma.user.findUniqueOrThrow({ where: { username: params.username.toLowerCase() }, @@ -113,8 +112,7 @@ export namespace UserMethods { })) const memberships = await readMembershipsOfUser(user.id) - const permissions = await PermissionMethods.readPermissionsOfUser.client(prisma).execute({ - session, + const permissions = await PermissionMethods.readPermissionsOfUser({ bypassAuth: true, params: { userId: user.id diff --git a/tests/services/apiKeys.test.ts b/tests/services/apiKeys.test.ts index 5b5e212c0..a830fc425 100644 --- a/tests/services/apiKeys.test.ts +++ b/tests/services/apiKeys.test.ts @@ -16,7 +16,7 @@ describe('api keys', () => { user: null, }) - const createdApiKey = await ApiKeyMethods.create.newClient().execute({ + const createdApiKey = await ApiKeyMethods.create({ data: { name: 'Min api nøkkel', }, @@ -28,7 +28,7 @@ describe('api keys', () => { permissions: [], }) - const readApiKeyResult = await ApiKeyMethods.read.newClient().execute({ + const readApiKeyResult = await ApiKeyMethods.read({ params: createdApiKey, session, }) @@ -38,7 +38,7 @@ describe('api keys', () => { permissions: [], }) - await ApiKeyMethods.update.newClient().execute({ + await ApiKeyMethods.update({ params: createdApiKey, data: { permissions: ['APIKEY_ADMIN'], @@ -59,7 +59,7 @@ describe('api keys', () => { // so there should probably be a system in place to run the same test // with different session objects. test('create, read and update api key with unauthenticated user', async () => { - const createdApiKeyPromise = ApiKeyMethods.create.newClient().execute({ + const createdApiKeyPromise = ApiKeyMethods.create({ data: { name: 'Min api nøkkel', }, @@ -68,7 +68,7 @@ describe('api keys', () => { expect(createdApiKeyPromise).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) expect(await prisma.apiKey.count()).toEqual(0) - const readApiKeyPromise = ApiKeyMethods.read.newClient().execute({ + const readApiKeyPromise = ApiKeyMethods.read({ params: { id: 1, }, @@ -76,7 +76,7 @@ describe('api keys', () => { }) expect(readApiKeyPromise).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) - const updateApiKeyPromise = ApiKeyMethods.update.newClient().execute({ + const updateApiKeyPromise = ApiKeyMethods.update({ params: { id: 1, }, diff --git a/tests/services/jobads.test.ts b/tests/services/jobads.test.ts index 53e8ae3c4..7b1c369fe 100644 --- a/tests/services/jobads.test.ts +++ b/tests/services/jobads.test.ts @@ -39,7 +39,7 @@ afterEach(async () => { const jobAds = await prisma.jobAd.findMany() await Promise.all(jobAds.map(jobAd => - JobadMethods.destroy.newClient().execute({ + JobadMethods.destroy({ params: { id: jobAd.id }, @@ -51,7 +51,7 @@ afterEach(async () => { describe('job ads', () => { test('create with unauthenticated user', async () => { - expect(JobadMethods.create.newClient().execute({ + expect(JobadMethods.create({ data: CREATE_JOB_AD, session: Session.empty() })).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) @@ -70,7 +70,7 @@ describe('job ads', () => { user: null, }) - await JobadMethods.create.newClient().execute({ data: CREATE_JOB_AD, session }) + await JobadMethods.create({ data: CREATE_JOB_AD, session }) const res = await prisma.jobAd.findFirst({}) expect(res).toMatchObject(CREATE_JOB_AD) @@ -78,19 +78,19 @@ describe('job ads', () => { test('(create and then) read with unauthenticated user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create.newClient().execute({ + const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, session: null, bypassAuth: true }) - expect(JobadMethods.read.newClient().execute({ params: { idOrName: createRes.id }, session: Session.empty() })) + expect(JobadMethods.read({ params: { idOrName: createRes.id }, session: Session.empty() })) .rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) }) test('(create and then) read with authorized user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create.newClient().execute({ + const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, session: null, bypassAuth: true @@ -102,19 +102,19 @@ describe('job ads', () => { user: null, }) - const readRes = await JobadMethods.read.newClient().execute({ params: { idOrName: createRes.id }, session }) + const readRes = await JobadMethods.read({ params: { idOrName: createRes.id }, session }) expect(readRes).toMatchObject(CREATE_JOB_AD) }) test('update with unauthenticated user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create.newClient().execute({ + const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, session: null, bypassAuth: true }) - expect(JobadMethods.update.newClient().execute({ + expect(JobadMethods.update({ params: { id: createRes.id, }, @@ -128,7 +128,7 @@ describe('job ads', () => { test('update with authorized user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create.newClient().execute({ + const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, session: null, bypassAuth: true @@ -140,7 +140,7 @@ describe('job ads', () => { user: null, }) - await JobadMethods.update.newClient().execute({ + await JobadMethods.update({ params: { id: createRes.id, }, @@ -154,13 +154,13 @@ describe('job ads', () => { test('destroy with unauthenticated user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create.newClient().execute({ + const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, session: null, bypassAuth: true }) - expect(JobadMethods.destroy.newClient().execute({ params: { id: createRes.id }, session: Session.empty() })) + expect(JobadMethods.destroy({ params: { id: createRes.id }, session: Session.empty() })) .rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) const count = await prisma.jobAd.count() @@ -169,7 +169,7 @@ describe('job ads', () => { test('destroy with authorized user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create.newClient().execute({ + const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, session: null, bypassAuth: true @@ -181,7 +181,7 @@ describe('job ads', () => { user: null, }) - await JobadMethods.destroy.newClient().execute({ params: { id: createRes.id }, session }) + await JobadMethods.destroy({ params: { id: createRes.id }, session }) const count = await prisma.jobAd.count() expect(count).toBe(0) From c9e828aa8d76547104d2801015a3a2d73ca236fd Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 22 Aug 2025 21:46:03 +0200 Subject: [PATCH 04/24] refactor: new action files in services --- src/services/admission/actions.ts | 6 + src/services/api-keys/actions.ts | 13 ++ src/services/applications/actions.ts | 12 ++ src/services/applications/periods/actions.ts | 15 ++ src/services/auth/actions.ts | 9 + src/services/cabin/actions.ts | 32 +++ src/services/career/companies/actions.ts | 12 ++ src/services/career/jobAds/actions.ts | 14 ++ src/services/cms/articleCategories/actions.ts | 60 ++++++ src/services/cms/articleSections/actions.ts | 58 ++++++ src/services/cms/articles/actions.ts | 69 +++++++ src/services/cms/images/actions.ts | 79 ++++++++ src/services/cms/links/actions.ts | 39 ++++ src/services/cms/paragraphs/actions.ts | 61 ++++++ src/services/dots/actions.ts | 10 + src/services/education/courses/actions.ts | 9 + src/services/education/schools/actions.ts | 96 +++++++++ src/services/events/actions.ts | 14 ++ src/services/events/registration/actions.ts | 11 + src/services/events/tags/actions.ts | 14 ++ src/services/groups/actions.ts | 9 + src/services/groups/committees/actions.ts | 51 +++++ src/services/groups/interestGroups/actions.ts | 12 ++ src/services/groups/memberships/actions.ts | 76 +++++++ .../groups/studyProgrammes/actions.ts | 47 +++++ src/services/images/actions.ts | 24 +++ src/services/images/collections/actions.ts | 115 +++++++++++ src/services/licenses/actions.ts | 12 ++ src/services/lockers/actions.ts | 16 ++ src/services/mail/actions.ts | 188 ++++++++++++++++++ src/services/mail/alias/actions.ts | 59 ++++++ src/services/mail/list/actions.ts | 50 +++++ .../mail/mailAddressExternal/actions.ts | 50 +++++ src/services/news/actions.ts | 85 ++++++++ src/services/notifications/actions.ts | 24 +++ src/services/notifications/channel/actions.ts | 68 +++++++ .../notifications/subscription/actions.ts | 54 +++++ src/services/ombul/actions.ts | 124 ++++++++++++ src/services/omegaOrder/actions.ts | 27 +++ src/services/omegaid/actions.ts | 32 +++ src/services/omegaquotes/actions.ts | 43 ++++ src/services/permissions/actions.ts | 10 + src/services/screens/actions.ts | 71 +++++++ src/services/screens/pages/actions.ts | 69 +++++++ src/services/sendmail/actions.ts | 24 +++ src/services/shop/actions.ts | 19 ++ src/services/users/actions.ts | 44 ++++ src/services/visibility/actions.ts | 161 +++++++++++++++ 48 files changed, 2197 insertions(+) create mode 100644 src/services/admission/actions.ts create mode 100644 src/services/api-keys/actions.ts create mode 100644 src/services/applications/actions.ts create mode 100644 src/services/applications/periods/actions.ts create mode 100644 src/services/auth/actions.ts create mode 100644 src/services/cabin/actions.ts create mode 100644 src/services/career/companies/actions.ts create mode 100644 src/services/career/jobAds/actions.ts create mode 100644 src/services/cms/articleCategories/actions.ts create mode 100644 src/services/cms/articleSections/actions.ts create mode 100644 src/services/cms/articles/actions.ts create mode 100644 src/services/cms/images/actions.ts create mode 100644 src/services/cms/links/actions.ts create mode 100644 src/services/cms/paragraphs/actions.ts create mode 100644 src/services/dots/actions.ts create mode 100644 src/services/education/courses/actions.ts create mode 100644 src/services/education/schools/actions.ts create mode 100644 src/services/events/actions.ts create mode 100644 src/services/events/registration/actions.ts create mode 100644 src/services/events/tags/actions.ts create mode 100644 src/services/groups/actions.ts create mode 100644 src/services/groups/committees/actions.ts create mode 100644 src/services/groups/interestGroups/actions.ts create mode 100644 src/services/groups/memberships/actions.ts create mode 100644 src/services/groups/studyProgrammes/actions.ts create mode 100644 src/services/images/actions.ts create mode 100644 src/services/images/collections/actions.ts create mode 100644 src/services/licenses/actions.ts create mode 100644 src/services/lockers/actions.ts create mode 100644 src/services/mail/actions.ts create mode 100644 src/services/mail/alias/actions.ts create mode 100644 src/services/mail/list/actions.ts create mode 100644 src/services/mail/mailAddressExternal/actions.ts create mode 100644 src/services/news/actions.ts create mode 100644 src/services/notifications/actions.ts create mode 100644 src/services/notifications/channel/actions.ts create mode 100644 src/services/notifications/subscription/actions.ts create mode 100644 src/services/ombul/actions.ts create mode 100644 src/services/omegaOrder/actions.ts create mode 100644 src/services/omegaid/actions.ts create mode 100644 src/services/omegaquotes/actions.ts create mode 100644 src/services/permissions/actions.ts create mode 100644 src/services/screens/actions.ts create mode 100644 src/services/screens/pages/actions.ts create mode 100644 src/services/sendmail/actions.ts create mode 100644 src/services/shop/actions.ts create mode 100644 src/services/users/actions.ts create mode 100644 src/services/visibility/actions.ts diff --git a/src/services/admission/actions.ts b/src/services/admission/actions.ts new file mode 100644 index 000000000..a428c561f --- /dev/null +++ b/src/services/admission/actions.ts @@ -0,0 +1,6 @@ +'use server' + +import { action } from '@/actions/action' +import { AdmissionMethods } from '@/services/admission/methods' + +export const createAdmissionTrialAction = action(AdmissionMethods.createTrial) diff --git a/src/services/api-keys/actions.ts b/src/services/api-keys/actions.ts new file mode 100644 index 000000000..8a2274ffd --- /dev/null +++ b/src/services/api-keys/actions.ts @@ -0,0 +1,13 @@ +'use server' + +import { action } from '@/actions/action' +import { ApiKeyMethods } from '@/services/api-keys/methods' + +export const createApiKeyAction = action(ApiKeyMethods.create) + +export const destroyApiKeyAction = action(ApiKeyMethods.destroy) + +export const readApiKeysAction = action(ApiKeyMethods.readMany) +export const readApiKeyAction = action(ApiKeyMethods.read) + +export const updateApiKeyAction = action(ApiKeyMethods.update) diff --git a/src/services/applications/actions.ts b/src/services/applications/actions.ts new file mode 100644 index 000000000..7b39df1a6 --- /dev/null +++ b/src/services/applications/actions.ts @@ -0,0 +1,12 @@ +'use server' + +import { action } from '@/actions/action' +import { ApplicationMethods } from '@/services/applications/methods' + +export const createApplicationAction = action(ApplicationMethods.create) + +export const destroyApplicationAction = action(ApplicationMethods.destroy) + +export const readApplicationsForUserAction = action(ApplicationMethods.readForUser) + +export const updateApplicationAction = action(ApplicationMethods.update) diff --git a/src/services/applications/periods/actions.ts b/src/services/applications/periods/actions.ts new file mode 100644 index 000000000..a941d7a1b --- /dev/null +++ b/src/services/applications/periods/actions.ts @@ -0,0 +1,15 @@ +'use server' + +import { action } from '@/actions/action' +import { ApplicationPeriodMethods } from '@/services/applications/periods/methods' + +export const createApplicationPeriodAction = action(ApplicationPeriodMethods.create) + +export const destroyApplicationPeriodAction = action(ApplicationPeriodMethods.destroy) +export const removeAllApplicationTextsAction = action(ApplicationPeriodMethods.removeAllApplicationTexts) + +export const readApplicationPeriodsAction = action(ApplicationPeriodMethods.readAll) +export const readApplicationPeriodAction = action(ApplicationPeriodMethods.read) +export const readNumberOfApplicationsAction = action(ApplicationPeriodMethods.readNumberOfApplications) + +export const updateApplicationPeriodAction = action(ApplicationPeriodMethods.update) diff --git a/src/services/auth/actions.ts b/src/services/auth/actions.ts new file mode 100644 index 000000000..b25fd7781 --- /dev/null +++ b/src/services/auth/actions.ts @@ -0,0 +1,9 @@ +'use server' + +import { action } from '@/actions/action' +import { AuthMethods } from '@/services/auth/methods' + +export const verifyResetPasswordTokenAction = action(AuthMethods.verifyResetPasswordToken) +export const resetPasswordAction = action(AuthMethods.resetPassword) +export const sendResetPasswordEmailAction = action(AuthMethods.sendResetPasswordEmail) +export const verifyEmailAction = action(AuthMethods.verifyEmail) diff --git a/src/services/cabin/actions.ts b/src/services/cabin/actions.ts new file mode 100644 index 000000000..8f8fdfbd6 --- /dev/null +++ b/src/services/cabin/actions.ts @@ -0,0 +1,32 @@ +'use server' + +import { action } from '@/actions/action' +import { CabinBookingMethods } from '@/services/cabin/booking/methods' +import { CabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' +import { CabinProductMethods } from '@/services/cabin/product/methods' +import { CabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' + +export const createReleasePeriodAction = action(CabinReleasePeriodMethods.create) +export const readReleasePeriodsAction = action(CabinReleasePeriodMethods.readMany) +export const updateReleasePeriodAction = action(CabinReleasePeriodMethods.update) +export const destroyReleasePeriodAction = action(CabinReleasePeriodMethods.destroy) + +export const createPricePeriodAction = action(CabinPricePeriodMethods.create) +export const destoryPricePeriodAction = action(CabinPricePeriodMethods.destroy) +export const readPricePeriodsAction = action(CabinPricePeriodMethods.readMany) +export const readPublicPricePeriodsAction = action(CabinPricePeriodMethods.readPublicPeriods) +export const readUnreleasedPricePeriodsAction = action(CabinPricePeriodMethods.readUnreleasedPeriods) + +export const createCabinBookingUserAttachedAction = action(CabinBookingMethods.createCabinBookingUserAttached) +export const createBedBookingUserAttachedAction = action(CabinBookingMethods.createBedBookingUserAttached) +export const createCabinBookingNoUserAction = action(CabinBookingMethods.createCabinBookingNoUser) +export const createBedBookingNoUserAction = action(CabinBookingMethods.createBedBookingNoUser) +export const readCabinAvailabilityAction = action(CabinBookingMethods.readAvailability) +export const readCabinBookingsAction = action(CabinBookingMethods.readMany) +export const readCabinBookingAction = action(CabinBookingMethods.read) + +export const readCabinProductsAction = action(CabinProductMethods.readMany) +export const readCabinProductsActiveAction = action(CabinProductMethods.readActive) +export const readCabinProductAction = action(CabinProductMethods.read) +export const createCabinProductAction = action(CabinProductMethods.create) +export const createCabinProductPriceAction = action(CabinProductMethods.createPrice) diff --git a/src/services/career/companies/actions.ts b/src/services/career/companies/actions.ts new file mode 100644 index 000000000..c9b88dab6 --- /dev/null +++ b/src/services/career/companies/actions.ts @@ -0,0 +1,12 @@ +'use server' + +import { action } from '@/actions/action' +import { CompanyMethods } from '@/services/career/companies/methods' + +export const createCompanyAction = action(CompanyMethods.create) + +export const destroyCompanyAction = action(CompanyMethods.destroy) + +export const readCompanyPageAction = action(CompanyMethods.readPage) + +export const updateComanyAction = action(CompanyMethods.update) diff --git a/src/services/career/jobAds/actions.ts b/src/services/career/jobAds/actions.ts new file mode 100644 index 000000000..bfa11fca5 --- /dev/null +++ b/src/services/career/jobAds/actions.ts @@ -0,0 +1,14 @@ +'use server' + +import { action } from '@/actions/action' +import { JobadMethods } from '@/services/career/jobAds/methods' + +export const createJobAdAction = action(JobadMethods.create) + +export const destroyJobAdAction = action(JobadMethods.destroy) + +export const readJobAdAction = action(JobadMethods.read) +export const readActiveJobAdsAction = action(JobadMethods.readActive) +export const readInactiveJobAdsPageAction = action(JobadMethods.readInactivePage) + +export const updateJobAdAction = action(JobadMethods.update) diff --git a/src/services/cms/articleCategories/actions.ts b/src/services/cms/articleCategories/actions.ts new file mode 100644 index 000000000..c5d6bf966 --- /dev/null +++ b/src/services/cms/articleCategories/actions.ts @@ -0,0 +1,60 @@ +'use server' + +import { createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import type { ArticleCategoryWithCover, + ExpandedArticleCategoryWithCover, ExpandedArticleCategory } from '@/cms/articleCategories/Types' +import { createArticleCategory } from '@/services/cms/articleCategories/create' +import { destroyArticleCategory } from '@/services/cms/articleCategories/destroy' +import { readArticleCategories, readArticleCategory } from '@/services/cms/articleCategories/read' +import { updateArticleCategory } from '@/services/cms/articleCategories/update' +import { createArticleCategoryValidation, updateArticleCategoryValidation } from '@/services/cms/articleCategories/validation' +import type { CreateArticleCategoryTypes, UpdateArticleCategoryTypes } from '@/services/cms/articleCategories/validation' + +export async function createArticleCategoryAction( + rawData: FormData | CreateArticleCategoryTypes['Type'] +): Promise> { + //TODO: check permission + const parse = createArticleCategoryValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createArticleCategory(data)) +} + +export async function destroyArticleCategoryAction(id: number): Promise> { + // TODO: Cheek for visibility type edit of user. + return await safeServerCall(() => destroyArticleCategory(id)) +} + +export async function readArticleCategoriesAction(): Promise> { + //TODO: only read categories that user has visibility + return await safeServerCall(() => readArticleCategories()) +} + +export async function readArticleCategoryAction(name: string): Promise> { + //TODO: only read if right visibility + return await safeServerCall(() => readArticleCategory(name)) +} + +export async function updateArticleCategoryVisibilityAction( + // disable eslint rule temporarily until function is implemented + // eslint-disable-next-line @typescript-eslint/no-unused-vars + id: number, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + visibility: unknown +): Promise> { + throw new Error('Not implemented') +} + +export async function updateArticleCategoryAction( + id: number, + rawData: FormData | UpdateArticleCategoryTypes['Type'] +): Promise> { + const parse = updateArticleCategoryValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => updateArticleCategory(id, data)) +} diff --git a/src/services/cms/articleSections/actions.ts b/src/services/cms/articleSections/actions.ts new file mode 100644 index 000000000..e1ffc6671 --- /dev/null +++ b/src/services/cms/articleSections/actions.ts @@ -0,0 +1,58 @@ +'use server' + +import { createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import type { ArticleSectionPart, ExpandedArticleSection } from '@/cms/articleSections/Types' +import { createArticleSection } from '@/services/cms/articleSections/create' +import { destroyArticleSection } from '@/services/cms/articleSections/destroy' +import { readArticleSection } from '@/services/cms/articleSections/read' +import { addArticleSectionPart, removeArticleSectionPart, updateArticleSection } from '@/services/cms/articleSections/update' +import { createArticleSectionValidation } from '@/services/cms/articleSections/validation' +import type { CreateArticleSectionTypes } from '@/services/cms/articleSections/validation' +import type { ArticleSection, Position } from '@prisma/client' + +export async function createArticleSectionAction( + rawData: FormData | CreateArticleSectionTypes['Type'], +): Promise> { + //TODO: Auth on general cms permission + const parse = createArticleSectionValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createArticleSection(data)) +} + +export async function destroyArticleSectionAction(nameOrId: string): Promise> { + //Auth by visibility + return await safeServerCall(() => destroyArticleSection(nameOrId)) +} + +export async function readArticleSectionAction(name: string): Promise> { + //TODO: Auth by visibility + return await safeServerCall(() => readArticleSection(name)) +} + +export async function updateArticleSectionAction(name: string, changes: { + imageSize?: number, + imagePosition?: Position, +}): Promise> { + //Todo: Auth by visibilty + return await safeServerCall(() => updateArticleSection(name, changes)) +} + +export async function addArticleSectionPartAction( + name: string, + part: ArticleSectionPart +): Promise> { + //Todo: Auth by visibilty + return await safeServerCall(() => addArticleSectionPart(name, part)) +} + +export async function removeArticleSectionPartAction( + name: string, + part: ArticleSectionPart +): Promise> { + //TODO: Auth by visibility + return await safeServerCall(() => removeArticleSectionPart(name, part)) +} diff --git a/src/services/cms/articles/actions.ts b/src/services/cms/articles/actions.ts new file mode 100644 index 000000000..b5683b37b --- /dev/null +++ b/src/services/cms/articles/actions.ts @@ -0,0 +1,69 @@ +'use server' + +import { createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import type { ExpandedArticle } from '@/cms/articles/Types' +import { createArticle } from '@/services/cms/articles/create' +import { destroyArticle } from '@/services/cms/articles/destroy' +import { readArticle } from '@/services/cms/articles/read' +import { addSectionToArticle, moveSectionOrder, updateArticle } from '@/services/cms/articles/update' +import { createArticleValidation, updateArticleValidation } from '@/services/cms/articles/validation' +import type { CreateArticleTypes, UpdateArticleTypes } from '@/services/cms/articles/validation' +import type { ArticleSectionPart } from '@/services/cms/articleSections/Types' +import type { Article, ArticleSection } from '@prisma/client' + +export async function createArticleAction( + rawData: FormData | CreateArticleTypes['Type'], + categoryId?: number, +): Promise> { + //TODO: auth on permission or visibility to categoryId + + const parse = createArticleValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createArticle(data, categoryId)) +} + +export async function destroyArticleAction(id: number): Promise> { + //TODO: auth + return await safeServerCall(() => destroyArticle(id)) +} + +export async function readArticleAction(idOrName: number | { + name: string, + category: string +}): Promise> { + //TODO: auth + return await safeServerCall(() => readArticle(idOrName)) +} + +export async function updateArticleAction( + id: number, + rawData: FormData | UpdateArticleTypes['Type'] +): Promise> { + //TODO: auth on visability + const parse = updateArticleValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => updateArticle(id, data)) +} + +export async function addSectionToArticleAction( + id: number, + include: Partial> +): Promise> { + //TODO: auth on visability + return await safeServerCall(() => addSectionToArticle(id, include)) +} + +export async function moveSectionOrderAction( + id: number, + sectionId: number, + direction: 'UP' | 'DOWN' +): Promise> { + //TODO: auth on visability + return await safeServerCall(() => moveSectionOrder(id, sectionId, direction)) +} diff --git a/src/services/cms/images/actions.ts b/src/services/cms/images/actions.ts new file mode 100644 index 000000000..21d8865af --- /dev/null +++ b/src/services/cms/images/actions.ts @@ -0,0 +1,79 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import type { ExpandedCmsImage } from '@/cms/images/Types' +import { createCmsImage } from '@/services/cms/images/create' +import { readCmsImage, readSpecialCmsImage } from '@/services/cms/images/read' +import type { ExpandedCmsImage } from '@/services/cms/images/Types' +import { updateCmsImage, updateCmsImageConfig } from '@/services/cms/images/update' +import { baseCmsImageValidation } from '@/services/cms/images/validation' +import type { ValidationTypes } from '@/services/Validation' +import { SpecialCmsImage } from '@prisma/client' +import type { CmsImage, Image, ImageSize } from '@prisma/client' + +export async function createCmsImageAction( + rawData: FormData | CreateCmsImageActionTypes['Type'], + image?: Image, +): Promise> { + //TODO: Auth route (very few people should be able to create stand alone cmsImages...) + const parse = createCmsImageActionValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createCmsImage(data, image)) +} + +/** + * A action to read a cms image including the image associated with it + * @param name - name of the cms image the image + * @returns + */ +export async function readCmsImageAction(name: string): Promise> { + //TODO: auth on visibilty + return await safeServerCall(() => readCmsImage(name)) +} + +/** + * Action to reads a special cmsImage, if it does not exist it creates it + * @param special SpecialCmsImage + * @returns ActionReturn + */ +export async function readSpecialCmsImageAction(special: SpecialCmsImage): Promise> { + if (!Object.values(SpecialCmsImage).includes(special)) { + return createActionError('BAD PARAMETERS', `${special} is not special`) + } + const specialRes = await safeServerCall(() => readSpecialCmsImage(special)) + if (!specialRes.success) { + if (specialRes.errorCode === 'NOT FOUND') { + return await safeServerCall(() => createCmsImage({ + name: special, + special, + })) + } + return specialRes + } + const cmsImage = specialRes.data + //TODO: Auth on visibilty + return { success: true, data: cmsImage } +} + +export async function updateCmsImageAction(cmsImageId: number, imageId: number): Promise> { + //TODO: Auth on visibility (or permission if special) + return await safeServerCall(() => updateCmsImage(cmsImageId, imageId)) +} + +export async function updateCmsImageConfigAction( + cmsImageId: number, + config: {imageSize: ImageSize} +): Promise> { + //TODO: Auth on visibility (or permission if special) + return await safeServerCall(() => updateCmsImageConfig(cmsImageId, config)) +} + +export const createCmsImageActionValidation = baseCmsImageValidation.createValidation({ + keys: ['name'], + transformer: data => data, +}) +export type CreateCmsImageActionTypes = ValidationTypes diff --git a/src/services/cms/links/actions.ts b/src/services/cms/links/actions.ts new file mode 100644 index 000000000..5bd70e40f --- /dev/null +++ b/src/services/cms/links/actions.ts @@ -0,0 +1,39 @@ +'use server' + +import { action } from '@/actions/action' +import { createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { createCmsLink } from '@/services/cms/links/create' +import { readSpecialCmsLink } from '@/services/cms/links/read' +import { updateCmsLink } from '@/services/cms/links/update' +import { createCmsLinkValidation, updateCmsLinkValidation } from '@/services/cms/links/validation' +import type { CreateCmsLinkTypes, UpdateCmsLinkTypes } from '@/services/cms/links/validation' +import type { CmsLink } from '@prisma/client' + +export async function createCmsLinkAction( + rawData: FormData | CreateCmsLinkTypes['Type'] +): Promise> { + //TODO: Auth on permission to create cms + const parse = createCmsLinkValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createCmsLink(data)) +} + +export const readSpecialCmsLinkAction = action(readSpecialCmsLink) + +export async function updateCmsLinkAction( + id: number, + rawData: FormData | UpdateCmsLinkTypes['Type'] +): Promise> { + //TODO: auth on visibility + const parse = updateCmsLinkValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + if (data.url && data.url.includes('.') && !data.url.startsWith('http://') && !data.url.startsWith('https://')) { + data.url = `https://${data.url}` + } + return await safeServerCall(() => updateCmsLink(id, data)) +} diff --git a/src/services/cms/paragraphs/actions.ts b/src/services/cms/paragraphs/actions.ts new file mode 100644 index 000000000..38c49144a --- /dev/null +++ b/src/services/cms/paragraphs/actions.ts @@ -0,0 +1,61 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { createCmsParagraph } from '@/services/cms/paragraphs/create' +import { readCmsParagraph, readSpecialCmsParagraph } from '@/services/cms/paragraphs/read' +import { updateCmsParagraphContents } from '@/services/cms/paragraphs/update' +import { baseCmsParagraphValidation } from '@/services/cms/paragraphs/validation' +import type { ValidationTypes } from '@/services/Validation' +import { SpecialCmsParagraph } from '@prisma/client' +import type { CmsParagraph } from '@prisma/client' + +export async function createCmsParagraphAction( + rawData: FormData | CreateCmsParagraphActionTypes['Type'] +): Promise> { + //TDOD: Auth on cms permission (few should be able to create a paragraph standalone) + const parse = createCmsParagraphActionValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createCmsParagraph(data)) +} + +export async function readCmsParagraphAction(name: string): Promise> { + //TODO: Auth on visibility (or permission if special) + return await safeServerCall(() => readCmsParagraph(name)) +} + +/** + * This action reads a special paragraph from the database, if it does not exist it will create it + * @param special - special paragraph to read + * @returns - the paragraph + */ +export async function readSpecialCmsParagraphAction(special: SpecialCmsParagraph): Promise> { + if (!Object.values(SpecialCmsParagraph).includes(special)) { + return createActionError('BAD PARAMETERS', `${special} is not special`) + } + + const specialRes = await safeServerCall(() => readSpecialCmsParagraph(special)) + if (specialRes.success) return specialRes + if (specialRes.errorCode === 'NOT FOUND') { + return await safeServerCall(() => createCmsParagraph({ + name: special, + special, + })) + } + return specialRes +} + +export async function updateCmsParagraphAction(id: number, contentMd: string): Promise> { + //TODO: Auth on visibility + return await safeServerCall(() => updateCmsParagraphContents(id, contentMd)) +} + +export const createCmsParagraphActionValidation = baseCmsParagraphValidation.createValidation({ + keys: ['name'], + transformer: data => data +}) + +export type CreateCmsParagraphActionTypes = ValidationTypes diff --git a/src/services/dots/actions.ts b/src/services/dots/actions.ts new file mode 100644 index 000000000..c755cd645 --- /dev/null +++ b/src/services/dots/actions.ts @@ -0,0 +1,10 @@ +'use server' + +import { action } from '@/actions/action' +import { dotMethods } from '@/services/dots/methods' + +export const createDotAction = action(dotMethods.create) + +export const readDotPageAction = action(dotMethods.readPage) + +export const readDotWrappersForUserAction = action(dotMethods.readWrappersForUser) diff --git a/src/services/education/courses/actions.ts b/src/services/education/courses/actions.ts new file mode 100644 index 000000000..bc4dd5e77 --- /dev/null +++ b/src/services/education/courses/actions.ts @@ -0,0 +1,9 @@ +'use server' + +import { safeServerCall } from '@/actions/safeServerCall' +import type { CreateCourseTypes } from '@/education/courses/validation' + +export async function createCourseAction(rawdata: FormData | CreateCourseTypes['Type']) { + console.log('createCourseAction', rawdata) + return safeServerCall(async () => ({ success: false })) +} diff --git a/src/services/education/schools/actions.ts b/src/services/education/schools/actions.ts new file mode 100644 index 000000000..7389059f2 --- /dev/null +++ b/src/services/education/schools/actions.ts @@ -0,0 +1,96 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import type { ExpandedSchool, SchoolCursor, SchoolFiltered } from '@/education/schools/Types' +import { createSchoolValidation, updateSchoolValidation } from '@/education/schools/validation' +import type { CreateSchoolTypes, UpdateSchoolTypes } from '@/education/schools/validation' +import type { ReadPageInput } from '@/lib/paging/Types' +import { createSchool } from '@/services/education/schools/create' +import { destroySchool } from '@/services/education/schools/destroy' +import { readSchool, readSchools, readSchoolsPage, readStandardSchools } from '@/services/education/schools/read' +import { updateSchool } from '@/services/education/schools/update' + +export async function createSchoolAction( + rawdata: FormData | CreateSchoolTypes['Type'] +): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCHOOLS_ADMIN']] + }) + if (!authorized) return createActionError(status) + + const parse = createSchoolValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createSchool(data)) +} + +export async function destroySchoolAction(id: number): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCHOOLS_ADMIN']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => destroySchool(id)) +} + +export async function readSchoolsPageAction( + pageReadInput: ReadPageInput +): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCHOOLS_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readSchoolsPage(pageReadInput)) +} + +export async function readStandardSchoolsAction(): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCHOOLS_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readStandardSchools()) +} + +export async function readSchoolsAction({ + onlyNonStandard +}: { + onlyNonStandard: boolean +}): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCHOOLS_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readSchools({ onlyNonStandard })) +} + +export async function readSchoolAction(shortname: string): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCHOOLS_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readSchool(shortname)) +} + +export async function updateSchoolAction( + id: number, + rawdata: FormData | UpdateSchoolTypes['Type'] +): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCHOOLS_ADMIN']] + }) + if (!authorized) return createActionError(status) + + const parse = updateSchoolValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => updateSchool(id, data)) +} diff --git a/src/services/events/actions.ts b/src/services/events/actions.ts new file mode 100644 index 000000000..0f780f0cb --- /dev/null +++ b/src/services/events/actions.ts @@ -0,0 +1,14 @@ +'use server' + +import { action } from '@/actions/action' +import { EventMethods } from '@/services/events/methods' + +export const createEventAction = action(EventMethods.create) + +export const destroyEventAction = action(EventMethods.destroy) + +export const readCurrentEventsAction = action(EventMethods.readManyCurrent) +export const readEventAction = action(EventMethods.read) +export const readArchivedEventsPageAction = action(EventMethods.readManyArchivedPage) + +export const updateEventAction = action(EventMethods.update) diff --git a/src/services/events/registration/actions.ts b/src/services/events/registration/actions.ts new file mode 100644 index 000000000..2d760678b --- /dev/null +++ b/src/services/events/registration/actions.ts @@ -0,0 +1,11 @@ +'use server' + +import { action } from '@/actions/action' +import { EventRegistrationMethods } from '@/services/events/registration/methods' + +export const createEventRegistrationAction = action(EventRegistrationMethods.create) +export const createGuestEventRegistrationAction = action(EventRegistrationMethods.createGuest) +export const readManyEventRegistrationAction = action(EventRegistrationMethods.readMany) +export const eventRegistrationReadManyDetailedAction = action(EventRegistrationMethods.readManyDetailed) +export const eventRegistrationUpdateNotesAction = action(EventRegistrationMethods.updateNotes) +export const eventRegistrationDestroyAction = action(EventRegistrationMethods.destroy) diff --git a/src/services/events/tags/actions.ts b/src/services/events/tags/actions.ts new file mode 100644 index 000000000..fbeb08743 --- /dev/null +++ b/src/services/events/tags/actions.ts @@ -0,0 +1,14 @@ +'use server' + +import { action } from '@/actions/action' +import { EventTagMethods } from '@/services/events/tags/methods' + +export const createEventTagAction = action(EventTagMethods.create) + +export const destroyEventTagAction = action(EventTagMethods.destroy) + +export const readEventTagsAction = action(EventTagMethods.readAll) +export const readSpecialEventTagAction = action(EventTagMethods.readSpecial) +export const readEventTagAction = action(EventTagMethods.read) + +export const updateEventTagAction = action(EventTagMethods.update) diff --git a/src/services/groups/actions.ts b/src/services/groups/actions.ts new file mode 100644 index 000000000..ce4f39d41 --- /dev/null +++ b/src/services/groups/actions.ts @@ -0,0 +1,9 @@ +'use server' + +import { action } from '@/actions/action' +import { GroupMethods } from '@/services/groups/methods' + +export const readGroupsAction = action(GroupMethods.readGroups) +export const readGroupExpandedAction = action(GroupMethods.readGroupExpanded) +export const readGroupsExpandedAction = action(GroupMethods.readGroupsExpanded) +export const readGroupsStructuredAction = action(GroupMethods.readGroupsStructured) diff --git a/src/services/groups/committees/actions.ts b/src/services/groups/committees/actions.ts new file mode 100644 index 000000000..87b1f1ba4 --- /dev/null +++ b/src/services/groups/committees/actions.ts @@ -0,0 +1,51 @@ +'use server' + +import { action } from '@/actions/action' +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createCommittee } from '@/services/groups/committees/create' +import { CommitteeMethods } from '@/services/groups/committees/methods' +import type { ExpandedCommittee } from '@/services/groups/committees/Types' +import { updateCommittee } from '@/services/groups/committees/update' +import { createCommitteeValidation, updateCommitteeValidation } from '@/services/groups/committees/validation' +import type { CreateCommitteeTypes, UpdateCommitteeTypes } from '@/services/groups/committees/validation' + +export async function createCommitteeAction( + rawData: FormData | CreateCommitteeTypes['Type'] +): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['COMMITTEE_CREATE']], + shouldRedirect: false, + }) + + if (!authorized) return createActionError(status) + + const parse = createCommitteeValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + + return await safeServerCall(() => createCommittee(parse.data)) +} + +export const readCommitteesAction = action(CommitteeMethods.readCommittees) +export const readCommitteeAction = action(CommitteeMethods.readCommittee) +export const readCommitteeArticleAction = action(CommitteeMethods.readCommitteArticle) +export const readCommitteeParagraphAction = action(CommitteeMethods.readCommitteeParagraph) +export const readCommitteeMembersAction = action(CommitteeMethods.readCommitteeMembers) + +export async function updateCommitteeAction( + id: number, + rawdata: FormData | UpdateCommitteeTypes['Type'] +) { + const { status, authorized } = await getUser({ + requiredPermissions: [['COMMITTEE_UPDATE']] + }) + if (!authorized) return createActionError(status) + + const parse = updateCommitteeValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => updateCommittee(id, data)) +} diff --git a/src/services/groups/interestGroups/actions.ts b/src/services/groups/interestGroups/actions.ts new file mode 100644 index 000000000..75d59dfe8 --- /dev/null +++ b/src/services/groups/interestGroups/actions.ts @@ -0,0 +1,12 @@ +'use server' + +import { action } from '@/actions/action' +import { InterestGroupMethods } from '@/services/groups/interestGroups/methods' + +export const createInterestGroupAction = action(InterestGroupMethods.create) + +export const destroyInterestGroupAction = action(InterestGroupMethods.destroy) + +export const readInterestGroupsAction = action(InterestGroupMethods.readMany) + +export const updateInterestGroupAction = action(InterestGroupMethods.update) diff --git a/src/services/groups/memberships/actions.ts b/src/services/groups/memberships/actions.ts new file mode 100644 index 000000000..f0cc9f44f --- /dev/null +++ b/src/services/groups/memberships/actions.ts @@ -0,0 +1,76 @@ +'use server' + +import { createActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createMembershipsForGroup } from '@/services/groups/memberships/create' +import { destoryMembershipOfUser } from '@/services/groups/memberships/destroy' +import type { ExpandedMembership } from '@/services/groups/memberships/Types' +import { updateMembership } from '@/services/groups/memberships/update' + +/** + * WARNING: This action will lead to error if used with group types not in CanEasalyManageMembership + */ +export async function createMembershipsForGroupAction({ + groupId, + users +}: { + groupId: number, + users: { + userId: number, + admin: boolean + }[] +}): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['GROUP_ADMIN']] + }) + if (!authorized) return createActionError(status) + + return safeServerCall(() => createMembershipsForGroup(groupId, users)) +} + +/** + * WARNING: Do not use this action, usually you want updateMemebershipInactivate + * @param + * @returns + */ +export async function destroyMembership({ + groupId, + userId, + orderArg, +}: { + groupId: number, + userId: number, + orderArg: number +}): Promise> { + //TODO: make function to check that. user is admin of group + + return await safeServerCall(() => destoryMembershipOfUser({ + groupId, + userId, + orderArg + })) +} + +export async function updateMembershipAdminAcion(membership: { + groupId: number + userId: number +}, admin: boolean): Promise> { + //TODO: make function to check that user is admin of group + return await safeServerCall(() => updateMembership({ + ...membership, + orderArg: 'ACTIVE' + }, { admin })) +} + +export async function updateMembershipActiveAction(membership: { + groupId: number + userId: number +}, active: boolean): Promise> { + //TODO: make function to check that user is admin of group + return await safeServerCall(() => updateMembership({ + ...membership, + orderArg: 'ACTIVE' + }, { active })) +} diff --git a/src/services/groups/studyProgrammes/actions.ts b/src/services/groups/studyProgrammes/actions.ts new file mode 100644 index 000000000..78eea4ed7 --- /dev/null +++ b/src/services/groups/studyProgrammes/actions.ts @@ -0,0 +1,47 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createStudyProgramme } from '@/services/groups/studyProgrammes/create' +import { readStudyProgrammes } from '@/services/groups/studyProgrammes/read' +import { updateStudyProgramme } from '@/services/groups/studyProgrammes/update' +import { createStudyProgrammeValidation, updateStudyProgrammeValidation } from '@/services/groups/studyProgrammes/validation' +import type { StudyProgramme } from '@prisma/client' + +export async function createStudyProgrammeAction(rawdata: FormData): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['STUDY_PROGRAMME_CREATE']], + }) + if (!authorized) return createActionError(status) + + const parse = createStudyProgrammeValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + + return await safeServerCall(() => createStudyProgramme(parse.data)) +} + +export async function readStudyProgrammesAction(): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['STUDY_PROGRAMME_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readStudyProgrammes()) +} + +export async function updateStudyProgrammeAction(id: number, rawdata: FormData): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['STUDY_PROGRAMME_UPDATE']], + }) + if (!authorized) return createActionError(status) + + const parse = updateStudyProgrammeValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + + return await safeServerCall(() => updateStudyProgramme({ + ...parse.data, + id, + })) +} diff --git a/src/services/images/actions.ts b/src/services/images/actions.ts new file mode 100644 index 000000000..100e44681 --- /dev/null +++ b/src/services/images/actions.ts @@ -0,0 +1,24 @@ +'use server' + +import { action } from '@/actions/action' +import { ImageMethods } from '@/services/images/methods' + +export const createImageAction = action(ImageMethods.create) +export const createImagesAction = action(ImageMethods.createMany) + +export const destroyImageAction = action(ImageMethods.destroy) + +/** + * Read one image. +*/ +export const readImageAction = action(ImageMethods.read) +/** + * Read one page of images. + */ +export const readImagesPageAction = action(ImageMethods.readPage) +/** + * Read one special image. + */ +export const readSpecialImageAction = action(ImageMethods.readSpecial) + +export const updateImageAction = action(ImageMethods.update) diff --git a/src/services/images/collections/actions.ts b/src/services/images/collections/actions.ts new file mode 100644 index 000000000..0eb5601f4 --- /dev/null +++ b/src/services/images/collections/actions.ts @@ -0,0 +1,115 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { checkVisibility } from '@/auth/checkVisibility' +import { getUser } from '@/auth/getUser' +import { getVisibilityFilter } from '@/auth/getVisibilityFilter' +import type { ReadPageInput } from '@/lib/paging/Types' +import { createImageCollection } from '@/services/images/collections/create' +import { destroyImageCollection } from '@/services/images/collections/destroy' +import { + readImageCollection, + readImageCollectionsPage, + readSpecialImageCollection } from '@/services/images/collections/read' +import type { ExpandedImageCollection, + ImageCollectionCursor, + ImageCollectionPageReturn } from '@/services/images/collections/Types' +import { updateImageCollection } from '@/services/images/collections/update' +import { createImageCollectionValidation, updateImageCollectionValidation } from '@/services/images/collections/validation' +import type { CreateImageCollectionTypes, UpdateImageCollectionTypes } from '@/services/images/collections/validation' +import { includeVisibility } from '@/services/visibility/read' +import type { VisibilityCollapsed } from '@/services/visibility/Types' +import { SpecialCollection } from '@prisma/client' +import type { ImageCollection } from '@prisma/client' + +export async function createImageCollectionAction( + rawdata: FormData | CreateImageCollectionTypes['Type'] +): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['IMAGE_COLLECTION_CREATE']] + }) + if (!authorized) return createActionError(status) + + const parse = createImageCollectionValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + return await safeServerCall(() => createImageCollection(data)) +} + +export async function destroyImageCollectionAction(collectionId: number): Promise> { + //TODO: Visibility check + + return await safeServerCall(() => destroyImageCollection(collectionId)) +} + +/** + * Action that reads an image collection by id or name + * @param idOrName - the id or name of the image collection + * @returns the image collection in actionrturn + */ +export async function readImageCollectionAction( + idOrName: number | string +): Promise> { + const collection = await safeServerCall(() => includeVisibility( + () => readImageCollection(idOrName), + data => data.visibilityId + )) + if (!collection.success) return collection + if (!checkVisibility(await getUser(), collection.data.visibility, 'REGULAR')) { + return createActionError('UNAUTHORIZED', 'You do not have permission to view this collection') + } + + return collection +} + +/** + * Action that returns a page of image collections, orders by createdAt (and then name) + * @param page - the page to read of the Page type + * @returns - A page of image collections + */ +export async function readImageCollectionsPageAction( + readPageInput: ReadPageInput +): Promise> { + const { memberships, permissions } = await getUser() + const visibilityFilter = getVisibilityFilter(memberships, permissions) + console.log(visibilityFilter) + return await safeServerCall(() => readImageCollectionsPage(readPageInput, visibilityFilter)) +} + +/** + * Reads a "special" collection read on this in the docs. If it does not exist it will create it. + * @param special - the special collection to read + * @returns the special collection + */ +export async function readSpecialImageCollectionAction(special: SpecialCollection): Promise> { + //Check that the collection actually is a special collection, as the paramter is only a compile time type check + if (!Object.values(SpecialCollection).includes(special)) { + return createActionError('BAD PARAMETERS', `${special} is not special`) + } + + //TODO: Auth special image collections on permission (not visibility) + //TODO: Check permission associated with the special collection + return await safeServerCall(() => readSpecialImageCollection(special)) +} + +/** + * A action that updates an image collection + * @param collectionId - the id of the collection to update + * @param coverImageId - the id of the image to set as the cover image (optional) + * @param rawdata - the data to update the collection with + * @returns - the updated collection in ActionReturn + */ +export async function updateImageCollectionAction( + collectionId: number, + coverImageId: number | undefined, + rawdata: FormData | UpdateImageCollectionTypes['Type'] +): Promise> { + const parse = updateImageCollectionValidation.typeValidate(rawdata) + + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => updateImageCollection(collectionId, coverImageId, data)) +} diff --git a/src/services/licenses/actions.ts b/src/services/licenses/actions.ts new file mode 100644 index 000000000..1de4702bb --- /dev/null +++ b/src/services/licenses/actions.ts @@ -0,0 +1,12 @@ +'use server' + +import { action } from '@/actions/action' +import { LicenseMethods } from '@/services/licenses/methods' + +export const createLicenseAction = action(LicenseMethods.create) + +export const destroyLicenseAction = action(LicenseMethods.destroy) + +export const readAllLicensesAction = action(LicenseMethods.readAll) + +export const updateLicenseAction = action(LicenseMethods.update) diff --git a/src/services/lockers/actions.ts b/src/services/lockers/actions.ts new file mode 100644 index 000000000..670617f02 --- /dev/null +++ b/src/services/lockers/actions.ts @@ -0,0 +1,16 @@ +'use server' + +import { action } from '@/actions/action' +import { LockerLocationMethods } from '@/services/lockers/locations/methods' +import { LockerMethods } from '@/services/lockers/methods' +import { LockerReservationMethods } from '@/services/lockers/reservations/methods' + +export const createLockerLocationAction = action(LockerLocationMethods.create) +export const readAllLockerLocationsAction = action(LockerLocationMethods.readAll) + +export const createLockerAction = action(LockerMethods.create) +export const readLockerAction = action(LockerMethods.read) +export const readLockerPageAction = action(LockerMethods.readPage) + +export const updateLockerReservationAction = action(LockerReservationMethods.update) +export const createLockerReservationAction = action(LockerReservationMethods.create) diff --git a/src/services/mail/actions.ts b/src/services/mail/actions.ts new file mode 100644 index 000000000..a6a105113 --- /dev/null +++ b/src/services/mail/actions.ts @@ -0,0 +1,188 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { readMailAliases } from '@/services/mail/alias/read' +import { + createAliasMailingListRelation, + createMailingListExternalRelation, + createMailingListGroupRelation, + createMailingListUserRelation } from '@/services/mail/create' +import { + destroyAliasMailingListRelation, + destroyMailingListExternalRelation, + destroyMailingListGroupRelation, + destroyMailingListUserRelation } from '@/services/mail/destroy' +import { readMailingLists } from '@/services/mail/list/read' +import { readMailAddressExternal } from '@/services/mail/mailAddressExternal/read' +import { readMailTraversal } from '@/services/mail/read' +import type { MailListTypes } from '@/services/mail/Types' +import { + createAliasMailingListValidation, + createMailingListExternalValidation, + createMailingListGroupValidation, + createMailingListUserValidation } from '@/services/mail/validation' +import type { CreateAliasMailingListType, + CreateMailingListExternalType, + CreateMailingListGroupType, + CreateMailingListUserType } from '@/services/mail/validation' +import type { UserFiltered } from '@/services/users/Types' +import type { MailAliasMailingList, + MailingListGroup, + MailingListMailAddressExternal, + MailingListUser, MailAddressExternal, MailAlias, MailingList } from '@prisma/client' + +export async function createAliasMailingListRelationAction(formdata: FormData): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_ALIAS_CREATE']] + }) + if (!authorized) return createActionError(status) + + const parse = createAliasMailingListValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => createAliasMailingListRelation(parse.data)) +} + +export async function createMailingListExternalRelationAction(formdata: FormData): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_EXTERNAL_ADDRESS_CREATE']] + }) + if (!authorized) return createActionError(status) + + const parse = createMailingListExternalValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => createMailingListExternalRelation(parse.data)) +} + +export async function createMailingListUserRelationAction(formdata: FormData): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_USER_CREATE']] + }) + if (!authorized) return createActionError(status) + + const parse = createMailingListUserValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => createMailingListUserRelation(parse.data)) +} + +export async function createMailingListGroupRelationAction(formdata: FormData): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_GROUP_CREATE']] + }) + if (!authorized) return createActionError(status) + + const parse = createMailingListGroupValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => createMailingListGroupRelation(parse.data)) +} + +export async function destroyAliasMailingListRelationAction(formdata: FormData | CreateAliasMailingListType['Type']): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_ALIAS_DESTROY']] + }) + if (!authorized) return createActionError(status) + + const parse = createAliasMailingListValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => destroyAliasMailingListRelation(parse.data)) +} + +export async function destroyMailingListExternalRelationAction(formdata: FormData | CreateMailingListExternalType['Type']): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_EXTERNAL_ADDRESS_DESTROY']] + }) + if (!authorized) return createActionError(status) + + const parse = createMailingListExternalValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => destroyMailingListExternalRelation(parse.data)) +} + +export async function destroyMailingListUserRelationAction(formdata: FormData | CreateMailingListUserType['Type']): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_USER_DESTROY']], + }) + if (!authorized) return createActionError(status) + + const parse = createMailingListUserValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => destroyMailingListUserRelation(parse.data)) +} + +export async function destroyMailingListGroupRelationAction(formdata: FormData | CreateMailingListGroupType['Type']): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_GROUP_DESTROY']] + }) + if (!authorized) return createActionError(status) + + const parse = createMailingListGroupValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => destroyMailingListGroupRelation(parse.data)) +} + +export async function readMailFlowAction(filter: MailListTypes, id: number) { + const { authorized, status } = await getUser({ + requiredPermissions: [ + ['MAILINGLIST_READ'], + ['MAILALIAS_READ'], + ['MAILADDRESS_EXTERNAL_READ'], + ['GROUP_READ'], + ], + }) + + if (!authorized) return createActionError(status) + + return safeServerCall(() => readMailTraversal({ + filter, + id, + })) +} + +export async function readMailOptions(): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [ + ['MAILINGLIST_READ'], + ['MAILALIAS_READ'], + ['MAILADDRESS_EXTERNAL_READ'], + ], + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(async () => { + const results = await Promise.all([ + readMailAliases(), + readMailingLists(), + readMailAddressExternal(), + ]) + + return { + alias: results[0], + mailingList: results[1], + mailaddressExternal: results[2], + users: [] + } + }) +} diff --git a/src/services/mail/alias/actions.ts b/src/services/mail/alias/actions.ts new file mode 100644 index 000000000..461b0e794 --- /dev/null +++ b/src/services/mail/alias/actions.ts @@ -0,0 +1,59 @@ +'use server' + +import type { ActionReturn } from '@/actions//Types' +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createMailAlias } from '@/services/mail/alias/create' +import { destroyMailAlias } from '@/services/mail/alias/destroy' +import { readMailAliases } from '@/services/mail/alias/read' +import { updateMailAlias } from '@/services/mail/alias/update' +import { createMailAliasValidation, destoryMailAliasValidation, updateMailAliasValidation } from '@/services/mail/alias/validation' +import type { MailAlias } from '@prisma/client' + +export async function createMailAliasAction(rawdata: FormData): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILALIAS_CREATE']] + }) + if (!authorized) return createActionError(status) + + const parse = createMailAliasValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => createMailAlias(parse.data)) +} + +export async function destroyMailAliasAction(id: number): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILALIAS_DESTORY']], + }) + if (!authorized) return createActionError(status) + + const parse = destoryMailAliasValidation.typeValidate({ id }) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => destroyMailAlias(parse.data.id)) +} + +export async function readMailAliasesAction(): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILALIAS_READ']] + }) + if (!authorized) return createActionError(status) + + return safeServerCall(() => readMailAliases()) +} + +export async function updateMailAliasAction(rawdata: FormData): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILALIAS_UPDATE']], + }) + if (!authorized) return createActionError(status) + + const parsed = updateMailAliasValidation.typeValidate(rawdata) + if (!parsed.success) return createZodActionError(parsed) + + return await safeServerCall(() => updateMailAlias(parsed.data)) +} diff --git a/src/services/mail/list/actions.ts b/src/services/mail/list/actions.ts new file mode 100644 index 000000000..6ab44f858 --- /dev/null +++ b/src/services/mail/list/actions.ts @@ -0,0 +1,50 @@ +'use server' + +import type { ActionReturn } from '@/actions//Types' +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createMailingList } from '@/services/mail/list/create' +import { destroyMailingList } from '@/services/mail/list/destroy' +import { updateMailingList } from '@/services/mail/list/update' +import { createMailingListValidation, readMailingListValidation, updateMailingListValidation } from '@/services/mail/list/validation' +import type { MailingList } from '@prisma/client' + +export async function createMailingListAction(rawdata: FormData): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_CREATE']] + }) + if (!authorized) return createActionError(status) + + const parse = createMailingListValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => createMailingList(parse.data)) +} + +export async function destroyMailingListAction(id: number): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_DESTROY']], + }) + if (!authorized) return createActionError(status) + + const parse = readMailingListValidation.typeValidate({ id }) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => destroyMailingList(parse.data.id)) +} + +export async function updateMailingListAction(data: FormData): +Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILINGLIST_UPDATE']], + }) + if (!authorized) return createActionError(status) + + const parse = updateMailingListValidation.typeValidate(data) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => updateMailingList(parse.data)) +} diff --git a/src/services/mail/mailAddressExternal/actions.ts b/src/services/mail/mailAddressExternal/actions.ts new file mode 100644 index 000000000..094298cc1 --- /dev/null +++ b/src/services/mail/mailAddressExternal/actions.ts @@ -0,0 +1,50 @@ +'use server' + +import type { ActionReturn } from '@/actions//Types' +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createMailAddressExternal } from '@/services/mail/mailAddressExternal/create' +import { destroyMailAddressExternal } from '@/services/mail/mailAddressExternal/destroy' +import { updateMailAddressExternal } from '@/services/mail/mailAddressExternal/update' +import { createMailAddressExternalValidation, readMailAddressExternalValidation, updateMailAddressExternalValidation } from '@/services/mail/mailAddressExternal/validation' +import type { MailAddressExternal } from '@prisma/client' + +export async function createMailAddressExternalAction(rawdata: FormData): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILADDRESS_EXTERNAL_CREATE']] + }) + if (!authorized) return createActionError(status) + + const parse = createMailAddressExternalValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => createMailAddressExternal(parse.data)) +} + +export async function destroyMailAddressExternalAction(id: number): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILADDRESS_EXTERNAL_DESTROY']], + }) + if (!authorized) return createActionError(status) + + const parse = readMailAddressExternalValidation.typeValidate({ id }) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => destroyMailAddressExternal(parse.data.id)) +} + +export async function updateMailAddressExternalAction(data: FormData): +Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAILADDRESS_EXTERNAL_UPDATE']], + }) + if (!authorized) return createActionError(status) + + const parse = updateMailAddressExternalValidation.typeValidate(data) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => updateMailAddressExternal(parse.data)) +} diff --git a/src/services/news/actions.ts b/src/services/news/actions.ts new file mode 100644 index 000000000..bea3f9f8d --- /dev/null +++ b/src/services/news/actions.ts @@ -0,0 +1,85 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import type { ReadPageInput } from '@/lib/paging/Types' +import { createNews } from '@/services/news/create' +import { destroyNews } from '@/services/news/destroy' +import { readNews, readNewsCurrent, readOldNewsPage } from '@/services/news/read' +import type { ExpandedNewsArticle, NewsCursor, SimpleNewsArticle } from '@/services/news/Types' +import { updateNews } from '@/services/news/update' +import { createNewsArticleValidation, updateNewsArticleValidation } from '@/services/news/validation' +import type { CreateNewsArticleTypes, UpdateNewsArticleTypes } from '@/services/news/validation' +import { dispatchSpecialNotification } from '@/services/notifications/create' + +export async function createNewsAction( + rawdata: FormData | CreateNewsArticleTypes['Type'] +): Promise> { + //TODO: check for can create news permission + const parse = createNewsArticleValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createNews(data)) +} + +export async function destroyNewsAction(id: number): Promise>> { + //TODO: check auth + return await safeServerCall(() => destroyNews(id)) +} + +export async function readOldNewsPageAction( + readPageImput: ReadPageInput +): Promise> { + //TODO: only read news with right visibility + return await safeServerCall(() => readOldNewsPage(readPageImput)) +} + +export async function readNewsCurrentAction(): Promise> { + //TODO: only read news with right visibility + return await safeServerCall(() => readNewsCurrent()) +} + +export async function readNewsAction(idOrName: number | { + articleName: string + order: number +}): Promise> { + //TODO: only read news if right visibility + return await safeServerCall(() => readNews(idOrName)) +} + +export async function updateNewsAction( + id: number, + rawdata: FormData | UpdateNewsArticleTypes['Type'] +): Promise>> { + //TODO: auth + const parse = updateNewsArticleValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + return await safeServerCall(() => updateNews(id, data)) +} + +export async function publishNewsAction( + // disable eslint rule temporarily until todo is resolved + // eslint-disable-next-line @typescript-eslint/no-unused-vars + id: number, + // disable eslint rule temporarily until todo is resolved + // eslint-disable-next-line @typescript-eslint/no-unused-vars + shouldPublish: boolean +): Promise>> { + dispatchSpecialNotification( + 'NEW_NEWS_ARTICLE', + 'Nyhet🗞️: ', + 'Starten av artikkelen her kanskje?' + ) + + return createActionError('UNKNOWN ERROR', 'Not implemented') +} + +// disable eslint rule temporarily until todo is resolved +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export async function updateVisibilityAction(id: number, visible: unknown): Promise> { + //TODO: add visible field to news + return createActionError('UNKNOWN ERROR', 'Not implemented') +} diff --git a/src/services/notifications/actions.ts b/src/services/notifications/actions.ts new file mode 100644 index 000000000..417eae41d --- /dev/null +++ b/src/services/notifications/actions.ts @@ -0,0 +1,24 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { dispatchNotification } from '@/services/notifications/create' +import { createNotificaionValidation } from '@/services/notifications/validation' +import type { Notification } from '@prisma/client' + +export async function dispatchNotificationAction(formdata: FormData): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['NOTIFICATION_CREATE']], + }) + if (!authorized) return createActionError(status) + + const parse = createNotificaionValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(() => dispatchNotification(parse.data)) +} diff --git a/src/services/notifications/channel/actions.ts b/src/services/notifications/channel/actions.ts new file mode 100644 index 000000000..5e9cbcfe1 --- /dev/null +++ b/src/services/notifications/channel/actions.ts @@ -0,0 +1,68 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createNotificationChannel } from '@/services/notifications/channel/create' +import { readNotificationChannels } from '@/services/notifications/channel/read' +import { updateNotificationChannel } from '@/services/notifications/channel/update' +import { createNotificaionChannelValidation, parseMethods, updateNotificaionChannelValidation } from '@/services/notifications/channel/validation' +import type { ExpandedNotificationChannel } from '@/services/notifications/Types' + +export async function createNotificationChannelAction(rawdata: FormData): +Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['NOTIFICATION_CHANNEL_CREATE']] + }) + + if (!authorized) return createActionError(status) + + const typeParsed = createNotificaionChannelValidation.typeValidate(rawdata) + if (!typeParsed.success) return createZodActionError(typeParsed) + + return safeServerCall(() => { + const availableParsed = parseMethods(rawdata, 'availableMethods') + const defaultParsed = parseMethods(rawdata, 'defaultMethods') + + return createNotificationChannel({ + ...typeParsed.data, + availableMethods: availableParsed, + defaultMethods: defaultParsed, + }) + }) +} + +export async function readNotificationChannelsAction(): + Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['NOTIFICATION_CHANNEL_READ']], + userRequired: false, + }) + + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readNotificationChannels()) +} + +export async function updateNotificationChannelAction(formdata: FormData): +Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['NOTIFICATION_CHANNEL_UPDATE']] + }) + if (!authorized) return createActionError(status) + + const parse = updateNotificaionChannelValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + + return safeServerCall(async () => { + const availableMethods = parseMethods(formdata, 'availableMethods') + const defaultMethods = parseMethods(formdata, 'defaultMethods') + + return updateNotificationChannel({ + ...parse.data, + availableMethods, + defaultMethods, + }) + }) +} diff --git a/src/services/notifications/subscription/actions.ts b/src/services/notifications/subscription/actions.ts new file mode 100644 index 000000000..cc080dd2c --- /dev/null +++ b/src/services/notifications/subscription/actions.ts @@ -0,0 +1,54 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { readUserSubscriptions } from '@/services/notifications/subscription/read' +import type { MinimizedSubscription, Subscription } from '@/services/notifications/subscription/Types' +import { updateSubscriptions } from '@/services/notifications/subscription/update' +import { parseSubscriptionMatrix, updateSubscriptionValidation } from '@/services/notifications/subscription/validation' + +export async function readSubscriptionsAction(userId?: number): +Promise> { + const { authorized, status, user, permissions } = await getUser({ + requiredPermissions: [ + ['NOTIFICATION_CHANNEL_READ'], + ['NOTIFICATION_SUBSCRIPTION_READ'], + ], + userRequired: true, + }) + + if (!authorized) return createActionError(status) + + if (!userId) { + userId = user.id + } + + if (userId !== user.id && !permissions.includes('NOTIFICATION_SUBSCRIPTION_READ_OTHER')) { + return createActionError('UNAUTHORIZED') + } + + return await safeServerCall(() => readUserSubscriptions(userId)) +} + +export async function updateSubscriptionsAction(userId: number, subscriptions: MinimizedSubscription[]): +Promise> { + const { authorized, status, user, permissions } = await getUser({ + requiredPermissions: [['NOTIFICATION_SUBSCRIPTION_UPDATE']], + userRequired: true, + }) + if (!authorized) return createActionError(status) + + if (userId !== user.id && !permissions.includes('NOTIFICATION_SUBSCRIPTION_UPDATE_OTHER')) { + return createActionError('UNAUTHORIZED') + } + + const parse = parseSubscriptionMatrix(subscriptions) + if (!parse.success) return createZodActionError(parse) + + const userParse = updateSubscriptionValidation.typeValidate({ userId }) + if (!userParse.success) return createZodActionError(userParse) + + return await safeServerCall(() => updateSubscriptions(userParse.data.userId, parse.data)) +} diff --git a/src/services/ombul/actions.ts b/src/services/ombul/actions.ts new file mode 100644 index 000000000..a04a046d7 --- /dev/null +++ b/src/services/ombul/actions.ts @@ -0,0 +1,124 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createOmbul } from '@/services/ombul/create' +import { destroyOmbul } from '@/services/ombul/destroy' +import { readLatestOmbul, readOmbul, readOmbuls } from '@/services/ombul/read' +import type { ExpandedOmbul } from '@/services/ombul/Types' +import { updateOmbul, updateOmbulFile } from '@/services/ombul/update' +import { createOmbulValidation, updateOmbulFileValidation, updateOmbulValidation } from '@/services/ombul/validation' +import type { CreateOmbulTypes, UpdateOmbulFileTypes, UpdateOmbulTypes } from '@/services/ombul/validation' +import type { Ombul } from '@prisma/client' + +/** + * Create a new Ombul. + * @param rawData includes a pdf file with the ombul issue optionaly year and issueNumber + * @param CoverImageId is the id of the Image that will be used as the cover of the ombul + */ +export async function createOmbulAction(rawdata: FormData | CreateOmbulTypes['Type']): Promise> { + //Auth route + const { status, authorized } = await getUser({ + requiredPermissions: [['OMBUL_CREATE']] + }) + if (!authorized) return createActionError(status) + + const parse = createOmbulValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createOmbul(data)) +} + +export async function destroyOmbulAction(id: number): Promise> { + const { status, authorized } = await getUser({ + requiredPermissions: [['OMBUL_DESTROY']] + }) + + if (!authorized) return createActionError(status) + + return await safeServerCall(() => destroyOmbul(id)) +} + +export async function readLatestOmbulAction(): Promise> { + //Auth route + const { status, authorized } = await getUser({ + requiredPermissions: [['OMBUL_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readLatestOmbul()) +} + +export async function readOmbulAction(idOrNameAndYear: number | { + name: string, + year: number, +}): Promise> { + //Auth route + const { status, authorized } = await getUser({ + requiredPermissions: [['OMBUL_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readOmbul(idOrNameAndYear)) +} + +export async function readOmbulsAction(): Promise> { + //Auth route + const { status, authorized } = await getUser({ + requiredPermissions: [['OMBUL_READ']] + }) + if (!authorized) { + return createActionError(status) + } + return await safeServerCall(() => readOmbuls()) +} + +/** + * A action to update an ombul + * @param id - The id of the ombul to update + * @param rawdata - The new data for the ombul including: name, year, issueNumber, description, + * @returns The updated ombul + */ +export async function updateOmbulAction( + id: number, + rawdata: FormData | UpdateOmbulTypes['Type'] +): Promise> { + // Auth route + const { status, authorized } = await getUser({ + requiredPermissions: [['OMBUL_UPDATE']] + }) + if (!authorized) return createActionError(status) + + //Parse the data + const parse = updateOmbulValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => updateOmbul(id, data)) +} + +/** + * A action that updates the ombul file (i.e. the pdf file) of an ombul + * @param id - The id of the ombul to update + * @param rawData - The new data for the new ombul file with field name 'file' + * @returns The updated ombul + */ +export async function updateOmbulFileAction( + id: number, + rawData: FormData | UpdateOmbulFileTypes['Type'] +): Promise> { + // auth route + const { status, authorized } = await getUser({ + requiredPermissions: [['OMBUL_UPDATE']] + }) + if (!authorized) return createActionError(status) + + const parse = updateOmbulFileValidation.typeValidate(rawData) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => updateOmbulFile(id, data)) +} diff --git a/src/services/omegaOrder/actions.ts b/src/services/omegaOrder/actions.ts new file mode 100644 index 000000000..ffaf7e19e --- /dev/null +++ b/src/services/omegaOrder/actions.ts @@ -0,0 +1,27 @@ +'use server' + +import { createActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createOmegaOrder } from '@/services/omegaOrder/create' +import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' +import type { OmegaOrder } from '@prisma/client' + +export async function createOmegaOrderAction(): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['OMEGA_ORDER_CREATE']] + }) + if (!authorized) return createActionError(status) + + return safeServerCall(createOmegaOrder) +} + +export async function readCurrentOmegaOrderAction(): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['OMEGA_ORDER_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readCurrentOmegaOrder()) +} diff --git a/src/services/omegaid/actions.ts b/src/services/omegaid/actions.ts new file mode 100644 index 000000000..1e97786ec --- /dev/null +++ b/src/services/omegaid/actions.ts @@ -0,0 +1,32 @@ +'use server' + +import { createActionError } from '@/actions/error' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { ServerError } from '@/services/error' +import { generateOmegaId } from '@/services/omegaid/generate' + +export async function generateOmegaIdAction(): Promise> { + const { user, authorized, status } = await getUser({ + userRequired: true, + }) + + if (!authorized) return createActionError(status) + + const token = generateOmegaId(user) + + return { + success: true, + data: token, + } +} + +export async function readOmegaJWTPublicKey(): Promise { + const key = process.env.JWT_PUBLIC_KEY + + if (!key) { + throw new ServerError('INVALID CONFIGURATION', 'The JWT_PUBLIC_KEY must be set') + } + + return key +} diff --git a/src/services/omegaquotes/actions.ts b/src/services/omegaquotes/actions.ts new file mode 100644 index 000000000..8fe7ae274 --- /dev/null +++ b/src/services/omegaquotes/actions.ts @@ -0,0 +1,43 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import type { ReadPageInput } from '@/lib/paging/Types' +import { createQuote } from '@/services/omegaquotes/create' +import { readQuotesPage } from '@/services/omegaquotes/read' +import type { OmegaquoteCursor, OmegaquoteFiltered } from '@/services/omegaquotes/Types' +import { createOmegaquotesValidation } from '@/services/omegaquotes/validation' +import type { CreateOmegaguotesTypes } from '@/services/omegaquotes/validation' +import type { OmegaQuote } from '@prisma/client' + +export async function createQuoteAction( + rawdata: FormData | CreateOmegaguotesTypes['Type'] +): Promise> { + const { user, status, authorized } = await getUser({ + requiredPermissions: [['OMEGAQUOTES_WRITE']], + userRequired: true, + }) + if (!authorized) return createActionError(status) + + const parse = createOmegaquotesValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + const results = await safeServerCall(() => createQuote(user.id, data)) + + return results +} + +export async function readQuotesPageAction( + readPageInput: ReadPageInput +): Promise> { + //TODO: REFACTOR when new permission system is working + const { status, authorized } = await getUser({ + requiredPermissions: [['OMEGAQUOTES_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readQuotesPage(readPageInput)) +} diff --git a/src/services/permissions/actions.ts b/src/services/permissions/actions.ts new file mode 100644 index 000000000..7028e1ba8 --- /dev/null +++ b/src/services/permissions/actions.ts @@ -0,0 +1,10 @@ +'use server' + +import { action } from '@/actions/action' +import { PermissionMethods } from '@/services/permissions/methods' + +export const readPermissionOfGroupAction = action(PermissionMethods.readPermissionsOfGroup) +export const readPermissionMatrixAction = action(PermissionMethods.readPermissionMatrix) +export const readDefaultPermissionsAction = action(PermissionMethods.readDefaultPermissions) +export const updateDefaultPermissionsAction = action(PermissionMethods.updateDefaultPermissions) +export const updateGroupPermissionAction = action(PermissionMethods.updateGroupPermission) diff --git a/src/services/screens/actions.ts b/src/services/screens/actions.ts new file mode 100644 index 000000000..064f75d85 --- /dev/null +++ b/src/services/screens/actions.ts @@ -0,0 +1,71 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { RequirePermission } from '@/auth/auther/RequirePermission' +import { Session } from '@/auth/Session' +import { createScreen } from '@/services/screens/create' +import { destroyScreen } from '@/services/screens/destroy' +import { readScreen, readScreens } from '@/services/screens/read' +import type { ScreenPageMoveDirection } from '@/services/screens/Types' +import { movePageInScreen, updateScreen } from '@/services/screens/update' +import { createScreenValidation, updateScreenValidation } from '@/services/screens/validation' +import type { CreateScreenTypes, UpdateScreenTypes } from '@/services/screens/validation' +import type { Screen } from '@prisma/client' + +export const adminScreenAuther = RequirePermission.staticFields({ permission: 'SCREEN_ADMIN' }) +export const readScreenAuther = RequirePermission.staticFields({ permission: 'SCREEN_READ' }) + +export async function createScreenAction(formdata: CreateScreenTypes['Type']): Promise> { + const authRes = adminScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) + if (!authRes.authorized) return createActionError(authRes.status) + + const parse = createScreenValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createScreen(data)) +} + +export async function destroyScreenAction(id: number): Promise> { + const authRes = adminScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) + if (!authRes.authorized) return createActionError(authRes.status) + + return await safeServerCall(() => destroyScreen(id)) +} + +export async function readScreenAction(id: number): Promise> { + const authRes = readScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) + if (!authRes.authorized) return createActionError(authRes.status) + + return await safeServerCall(() => readScreen(id)) +} + +export async function readScreensAction(): Promise> { + const authRes = readScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) + if (!authRes.authorized) return createActionError(authRes.status) + + return await safeServerCall(() => readScreens()) +} + +export async function updateScreenAction(id: number, formdata: UpdateScreenTypes['Type']): Promise> { + const authRes = adminScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) + if (!authRes.authorized) return createActionError(authRes.status) + + const parse = updateScreenValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => updateScreen(id, data)) +} + +export async function movePageInScreenAction( + id: {screen: number, page: number}, + direction: ScreenPageMoveDirection +): Promise> { + const authRes = adminScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) + if (!authRes.authorized) return createActionError(authRes.status) + + return await safeServerCall(() => movePageInScreen(id, direction)) +} diff --git a/src/services/screens/pages/actions.ts b/src/services/screens/pages/actions.ts new file mode 100644 index 000000000..3ceab6eac --- /dev/null +++ b/src/services/screens/pages/actions.ts @@ -0,0 +1,69 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { createPage } from '@/services/screens/pages/create' +import { destroyPage } from '@/services/screens/pages/destroy' +import { readPage, readPages } from '@/services/screens/pages/read' +import type { ExpandedScreenPage } from '@/services/screens/pages/Types' +import { updatePage } from '@/services/screens/pages/update' +import { updatePageValidation } from '@/services/screens/pages/validation' +import type { UpdatePageTypes } from '@/services/screens/pages/validation' +import { createScreenValidation } from '@/services/screens/validation' +import type { CreateScreenTypes } from '@/services/screens/validation' +import type { ScreenPage } from '@prisma/client' + +export async function createPageAction(formdata: CreateScreenTypes['Type']): Promise> { + const { status, authorized } = await getUser({ + requiredPermissions: [['SCREEN_ADMIN']] + }) + if (!authorized) return createActionError(status) + + const parse = createScreenValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => createPage(data)) +} + +export async function destroyPageAction(id: number): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCREEN_ADMIN']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => destroyPage(id)) +} + +export async function readPageAction(id: number): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCREEN_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readPage(id)) +} + +export async function readPagesAction(): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCREEN_READ']] + }) + if (!authorized) return createActionError(status) + + return await safeServerCall(() => readPages()) +} + +export async function updatePageAction(id: number, formdata: UpdatePageTypes['Type']): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['SCREEN_ADMIN']] + }) + if (!authorized) return createActionError(status) + + const parse = updatePageValidation.typeValidate(formdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => updatePage(id, data)) +} diff --git a/src/services/sendmail/actions.ts b/src/services/sendmail/actions.ts new file mode 100644 index 000000000..3c616bd2b --- /dev/null +++ b/src/services/sendmail/actions.ts @@ -0,0 +1,24 @@ +'use server' + +import { createActionError, createZodActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { getUser } from '@/auth/getUser' +import { sendMail as transportSendMail } from '@/services/notifications/email/send' +import { sendEmailValidation } from '@/services/notifications/email/validation' + +export default async function sendMail(rawdata: FormData): Promise> { + const { authorized, status } = await getUser({ + requiredPermissions: [['MAIL_SEND']], + }) + + if (!authorized) { + return createActionError(status) + } + + const parse = sendEmailValidation.typeValidate(rawdata) + if (!parse.success) return createZodActionError(parse) + const data = parse.data + + return await safeServerCall(() => transportSendMail(data)) +} diff --git a/src/services/shop/actions.ts b/src/services/shop/actions.ts new file mode 100644 index 000000000..5f415cce1 --- /dev/null +++ b/src/services/shop/actions.ts @@ -0,0 +1,19 @@ +'use server' + +import { action } from '@/actions/action' +import { ProductMethods } from '@/services/shop/product/methods' +import { ShopMethods } from '@/services/shop/shop/methods' + +export const readProductsAction = action(ProductMethods.readMany) +export const readProductAction = action(ProductMethods.read) +export const createProductAction = action(ProductMethods.create) +export const updateProductAction = action(ProductMethods.update) + +export const createProductForShopAction = action(ProductMethods.createForShop) +export const updateProductForShopAction = action(ProductMethods.updateForShop) + +export const createShopProductConnectionAction = action(ProductMethods.createShopConnection) + +export const readShopsAction = action(ShopMethods.readMany) +export const readShopAction = action(ShopMethods.read) +export const createShopAction = action(ShopMethods.create) diff --git a/src/services/users/actions.ts b/src/services/users/actions.ts new file mode 100644 index 000000000..d2d08285d --- /dev/null +++ b/src/services/users/actions.ts @@ -0,0 +1,44 @@ +'use server' + +import { action } from '@/actions/action' +import { GroupMethods } from '@/services/groups/methods' +import { UserMethods } from '@/services/users/methods' + +/** + * A action that creates a user by the given data. It will also hash the password + * @param rawdata - The user to create + * @returns - The created user + */ +export const createUserAction = action(UserMethods.create) + +/** + * Action to destroy a user by the given id + * @param id - The id of the user to destroy + * @returns + */ +export const destroyUserAction = action(UserMethods.destroy) + +/** + * A action to read a page of users with the given details (filtering) + * @param readPageInput - This is a) the page to read and b) the details to filter by like + * name and groups + * @returns + */ +export const readUserPageAction = action(UserMethods.readPage) + +/** + * Action meant to read the profile of a user. + * A profile is a user with more information about them attached. + * @param username - The username of the user to read + * @returns - The profile of the user + */ +export const readUserProfileAction = action(UserMethods.readProfile) + +export const readUserAction = action(UserMethods.read) + +export const readGroupsForPageFilteringAction = action(GroupMethods.readGroupsExpanded) + +export const updateUserAction = action(UserMethods.update) +export const registerNewEmailAction = action(UserMethods.registerNewEmail) +export const registerUser = action(UserMethods.register) +export const registerStudentCardInQueueAction = action(UserMethods.registerStudentCardInQueue) diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts new file mode 100644 index 000000000..f300655cb --- /dev/null +++ b/src/services/visibility/actions.ts @@ -0,0 +1,161 @@ +'use server' + +import { createActionError } from '@/actions/error' +import { safeServerCall } from '@/actions/safeServerCall' +import type { ActionReturn } from '@/actions/Types' +import { checkVisibility } from '@/auth/checkVisibility' +import { getUser } from '@/auth/getUser' +import { GroupTypesConfig } from '@/services/groups/config' +import { GroupMethods } from '@/services/groups/methods' +import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' +import { PurposeTextsConfig } from '@/services/visibility/ConfigVars' +import { readVisibilityCollapsed } from '@/services/visibility/read' +import type { GroupMatrix, VisibilityLevelType } from '@/services/visibility/Types' +import type { GroupType } from '@prisma/client' + +export type VisibilityRequiermentForAdmin = { + name: string + groups: (ExpandedGroup & { + selected: boolean + })[] +} + +export type VisibilityStructuredForAdmin = { + published: boolean + purpose: string +} & ( + { + type: 'REGULAR' + groups: GroupsStructured + regular: VisibilityRequiermentForAdmin[] + admin: VisibilityRequiermentForAdmin[] + } | { + type: 'SPECIAL' + message: string + regular: string + admin: string + } +) + +export async function readVisibilityForAdminAction(id: number): Promise> { + const [visibilityRes, groupsRes] = await Promise.all([ + safeServerCall(() => readVisibilityCollapsed(id)), + // TODO: Fix Authing here. The bypass should be false + safeServerCall(() => GroupMethods.readGroupsStructured({ session: null, bypassAuth: true })) + ]) + if (!visibilityRes.success || !groupsRes.success) return createActionError('UNKNOWN ERROR', 'noe gikk galt') + + const visibility = visibilityRes.data + const groups = groupsRes.data + const purpose = PurposeTextsConfig[visibility.purpose] + + if (!checkVisibility(await getUser(), visibility, 'ADMIN')) { + return createActionError('UNAUTHORIZED', 'You do not have permission to admin this collection') + } + if (visibility.type === 'SPECIAL') { + return { + success: true, + data: { + published: visibility.published, + purpose, + type: 'SPECIAL', + message: 'Denne syneligheten er spessiell', + regular: `Brukere med ${visibility.regular} har vanlig tilgang`, + admin: `Brukere med ${visibility.admin} har admin tilgang`, + } + } + } + const standardGroupingsRefular = ['CLASS', 'OMEGA_MEMBERSHIP_GROUP', 'STUDY_PROGRAMME'] satisfies GroupType[] + const standardGroupingsAdmin = ['COMMITTEE', 'OMEGA_MEMBERSHIP_GROUP'] satisfies GroupType[] + return { + success: true, + data: { + published: visibility.published, + purpose, + type: 'REGULAR', + regular: expandOneLevel(visibility.regular, groups, standardGroupingsRefular), + admin: expandOneLevel(visibility.admin, groups, standardGroupingsAdmin), + groups, + } + } +} + +function expandOneLevel( + matrix: GroupMatrix, + groups: GroupsStructured, + standardGroupings: GroupType[] +): VisibilityRequiermentForAdmin[] { + const res: VisibilityRequiermentForAdmin[] = [] + standardGroupings.forEach(groupType => { + if (!groups[groupType]) return + const standardRequriment: VisibilityRequiermentForAdmin = { + name: GroupTypesConfig[groupType].name, + groups: groups[groupType].groups.map(group => ({ + ...group, + selected: false + })) + } + //Find out if there is a row in the matrix with just the group type. + for (let i = 0; i < matrix.length; i++) { + if (matrix[i].every(groupId => groupTypeOfId(groupId, groups) === groupType)) { + standardRequriment.groups.forEach(group => { + group.selected = matrix[i].includes(group.id) + }) + //Remove the row from the matrix since it has been handled + matrix.splice(i, 1) + } + } + res.push(standardRequriment) + }) + + //Handle all non standard groupings + matrix.forEach(row => { + const groups_ = row.reduce((acc, id) => { + const g = findGroupOfId(id, groups) + if (g) acc.push(g) + return acc + }, [] as ExpandedGroup[]) + const nonStandardRequriment: VisibilityRequiermentForAdmin = { + name: 'ekstra', + groups: groups_.map(g => ({ + ...g, + selected: true + })) + } + res.push(nonStandardRequriment) + }) + + return res +} + +function findGroupOfId(id: number, groups: GroupsStructured): ExpandedGroup | null { + let found: ExpandedGroup | null = null + Object.values(groups).forEach(groupType => { + groupType.groups.forEach(group => { + if (group.id === id) { + found = group + } + }) + }) + return found +} + +function groupTypeOfId(id: number, groups: GroupsStructured): GroupType { + let type: GroupType | null = null + Object.values(groups).forEach((groupType) => { + groupType.groups.forEach(group => { + if (group.id === id) { + type = group.groupType + } + }) + }) + return type || 'MANUAL_GROUP' +} + +export async function updateVisibilityAction( + level: VisibilityLevelType, + formdata: FormData +): Promise> { + console.log(formdata) + return { success: true, data: undefined } +} From eb2f69ddc29fa23a4768976e54b5128c7aab59f4 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 22 Aug 2025 21:51:54 +0200 Subject: [PATCH 05/24] chore: handle new changes after rebase --- src/actions/news/update.ts | 3 +- src/services/actions.ts | 169 ++++++++++++++++++++ src/services/events/registration/methods.ts | 3 +- src/services/news/actions.ts | 17 +- src/services/notifications/actions.ts | 29 ++-- src/services/ombul/create.ts | 3 +- src/services/omegaquotes/create.ts | 2 +- src/services/visibility/actions.ts | 8 +- 8 files changed, 198 insertions(+), 36 deletions(-) create mode 100644 src/services/actions.ts diff --git a/src/actions/news/update.ts b/src/actions/news/update.ts index 584ec7d51..bc65530bd 100644 --- a/src/actions/news/update.ts +++ b/src/actions/news/update.ts @@ -27,7 +27,7 @@ export async function publishNewsAction( // eslint-disable-next-line @typescript-eslint/no-unused-vars shouldPublish: boolean ): Promise>> { - NotificationMethods.createSpecial.newClient().execute({ + NotificationMethods.createSpecial({ params: { special: 'NEW_NEWS_ARTICLE', }, @@ -35,7 +35,6 @@ export async function publishNewsAction( title: 'Ny nyhetsartikkel', // TODO: Add info about the article message: 'En ny nyhetsartikkel er publisert', }, - session: null, bypassAuth: true, }) diff --git a/src/services/actions.ts b/src/services/actions.ts new file mode 100644 index 000000000..78b2b1295 --- /dev/null +++ b/src/services/actions.ts @@ -0,0 +1,169 @@ +'use server' + +import type { AuthStatus } from '@/auth/getUser' +import { Session } from '@/auth/Session' +import { ParseError, Smorekopp, errorCodes } from '@/services/error' +import type { ErrorCode, ErrorMessage } from '@/services/error' +import type { ServiceMethodExecuteArgs, ServiceMethodType } from '@/services/ServiceMethod' +import '@pn-server-only' +import type { SafeParseError, z } from 'zod' + +export type ActionReturnError = { + success: false, + errorCode: ErrorCode, + httpCode: number, + error?: ErrorMessage[], +} + +export type ActionReturn = ( + ActionReturnError +) | { + success: true, +} & ( + DataGuarantee extends true ? { + data: ReturnType + } : { + data?: ReturnType + } +) + +export type Action = (formData: FormData) => ( + Promise> +) + +// This function is overloaded to allow for different combinations of parameters and data. + +export function action( + serviceMethod: ServiceMethodType +): () => Promise> + +export function action( + serviceMethod: ServiceMethodType +): (params: z.input) => Promise> + +export function action( + serviceMethod: ServiceMethodType +): (data: z.input> | FormData) => Promise> + +export function action( + serviceMethod: ServiceMethodType +): (params: z.input, data: z.input> | FormData) => Promise> + +/** + * Turn a service method into suitable function for an action. + * + * @param serviceMethod - The service method to create an action for. + * @returns - A function that takes in data (which may be FormData) and/or/nor parameters and calls the service method. + */ +export function action< + Return, + ParamsSchema extends z.ZodTypeAny | undefined = undefined, + DataSchema extends z.ZodTypeAny | undefined = undefined +>( + serviceMethod: ServiceMethodType +) { + // Letting the arguments to the actual function be unknown is safer as anything can be passed to it form the client. + // The action and service method will validate the parameter and data before it is used. + // + // For convenience this function is given a return type that is more specific. The return type is a function that + // has arguments witch match the underlying service method. This makes programming easier as Intellisense can + // help and errors are caught at compile time. + const actionUnsafe = async (params?: unknown, data?: unknown) => { + const session = await Session.fromNextAuth() + + // Treat empty form data as undefined. This is required because the form component will always send + // a FormData instance, even if no data is being sent. + if (data instanceof FormData && data.entries().next().done) { + data = undefined + } + + return safeServerCall(() => serviceMethod({ + session, + params, + data, + } as unknown as ServiceMethodExecuteArgs)) + } + + // If the service method has a params schema, we require the params to be passed to the action. + if (serviceMethod.paramsSchema) { + return actionUnsafe + } + + // Otherwise we return a function that takes no params, only data. + return actionUnsafe.bind(null, undefined) +}/** + * A simple utility function to bind parameters to an action. + * Under the hood this function simply calls "action.bind(null, params)", + * but it is more readable to use this function. + * + * @param action - An action that takes parameters. + * @param params - The parameters to bind to the action. + * @returns - The same action with the parameters bound to it. + */ +export function bindParams(action: (p: P, ...dataArgs: D) => R, params: P) { + return action.bind(null, params) +} + +/** + * A simple utility function to bind data to an action. + * Under the hood this function simply calls "action.bind(null, data)", + * but it is more readable to use this function. + * + * @param action - An action that takes data. + * @param bindData - The data to bind to the action. + * @returns - The same action with the data bound to it. + */ +export function bindData(action: (dataValue: D) => R, data: D) { + return action.bind(null, data) +} + +export function createActionError(errorCode: ErrorCode | AuthStatus, error?: string | ErrorMessage[]): ActionReturnError { + if (errorCode === 'AUTHORIZED' || errorCode === 'AUTHORIZED_NO_USER') { + return { + success: false, + errorCode: 'UNKNOWN ERROR', + httpCode: 500, + error: typeof error === 'string' ? [{ message: error }] : error, + } + } + return { + success: false, + errorCode, + httpCode: errorCodes.find(e => e.name === errorCode)?.httpCode ?? 500, + error: typeof error === 'string' ? [{ message: error }] : error, + } +} + +export function createZodActionError(parse: SafeParseError): ActionReturnError { + return { + success: false, + httpCode: 400, + errorCode: 'BAD PARAMETERS', + error: parse.error.issues, + } +} + +/** + * A function that calls a server function. If all goes well, it returns a ActionReturn with the data. + * If an error is thrown it returns ActionReturn of success false and the error. + * The function handles ServerErrors class, and treats all other errors as unknown. + * @param call - A async server function to call. + * @returns - A promise that resolves to an ActionReturn. + */ +export async function safeServerCall(call: () => Promise): Promise> { + try { + const data = await call() + return { + success: true, + data + } + } catch (error) { + if (error instanceof ParseError) { + return createZodActionError(error.parseError) + } + if (error instanceof Smorekopp) { + return createActionError(error.errorCode, error.errors) + } + return createActionError('UNKNOWN ERROR', 'unknown error') + } +} diff --git a/src/services/events/registration/methods.ts b/src/services/events/registration/methods.ts index 63c2afa7d..e87603f9e 100644 --- a/src/services/events/registration/methods.ts +++ b/src/services/events/registration/methods.ts @@ -372,7 +372,7 @@ export namespace EventRegistrationMethods { const message = `Gratulerer! Du har rykket opp fra venteliste på arrangementet ${registration.event.name}.` if (nextInLine.user) { - await NotificationMethods.createSpecial.newClient().execute({ + await NotificationMethods.createSpecial({ params: { special: 'EVENT_WAITINGLIST_PROMOTION', }, @@ -382,7 +382,6 @@ export namespace EventRegistrationMethods { userIdList: [nextInLine.user.id], }, bypassAuth: true, - session, }) } diff --git a/src/services/news/actions.ts b/src/services/news/actions.ts index bea3f9f8d..5f00068bf 100644 --- a/src/services/news/actions.ts +++ b/src/services/news/actions.ts @@ -11,7 +11,7 @@ import type { ExpandedNewsArticle, NewsCursor, SimpleNewsArticle } from '@/servi import { updateNews } from '@/services/news/update' import { createNewsArticleValidation, updateNewsArticleValidation } from '@/services/news/validation' import type { CreateNewsArticleTypes, UpdateNewsArticleTypes } from '@/services/news/validation' -import { dispatchSpecialNotification } from '@/services/notifications/create' +import { NotificationMethods } from '@/services/notifications/methods' export async function createNewsAction( rawdata: FormData | CreateNewsArticleTypes['Type'] @@ -68,11 +68,16 @@ export async function publishNewsAction( // eslint-disable-next-line @typescript-eslint/no-unused-vars shouldPublish: boolean ): Promise>> { - dispatchSpecialNotification( - 'NEW_NEWS_ARTICLE', - 'Nyhet🗞️: ', - 'Starten av artikkelen her kanskje?' - ) + NotificationMethods.createSpecial({ + params: { + special: 'NEW_NEWS_ARTICLE', + }, + data: { + title: 'Ny nyhetsartikkel', // TODO: Add info about the article + message: 'En ny nyhetsartikkel er publisert', + }, + bypassAuth: true, + }) return createActionError('UNKNOWN ERROR', 'Not implemented') } diff --git a/src/services/notifications/actions.ts b/src/services/notifications/actions.ts index 417eae41d..2764584fe 100644 --- a/src/services/notifications/actions.ts +++ b/src/services/notifications/actions.ts @@ -1,24 +1,15 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import { getUser } from '@/auth/getUser' -import { dispatchNotification } from '@/services/notifications/create' -import { createNotificaionValidation } from '@/services/notifications/validation' -import type { Notification } from '@prisma/client' +import { action } from '@/actions/action' +import { NotificationChannelMethods } from '@/services/notifications/channel/methods' +import { NotificationMethods } from '@/services/notifications/methods' +import { NotificationSubscriptionMethods } from '@/services/notifications/subscription/methods' -export async function dispatchNotificationAction(formdata: FormData): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['NOTIFICATION_CREATE']], - }) - if (!authorized) return createActionError(status) +export const createNotificationChannelAction = action(NotificationChannelMethods.create) +export const updateNotificationChannelAction = action(NotificationChannelMethods.update) +export const readNotificationChannelsAction = action(NotificationChannelMethods.readMany) - const parse = createNotificaionValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) +export const createNotificationAction = action(NotificationMethods.create) - return safeServerCall(() => dispatchNotification(parse.data)) -} +export const readNotificationSubscriptionsAction = action(NotificationSubscriptionMethods.read) +export const updateNotificationSubscriptionsAction = action(NotificationSubscriptionMethods.update) diff --git a/src/services/ombul/create.ts b/src/services/ombul/create.ts index 7ca0de738..cb8500f25 100644 --- a/src/services/ombul/create.ts +++ b/src/services/ombul/create.ts @@ -71,7 +71,7 @@ export async function createOmbul( } })) - NotificationMethods.createSpecial.newClient().execute({ + NotificationMethods.createSpecial({ params: { special: 'NEW_OMBUL', }, @@ -79,7 +79,6 @@ export async function createOmbul( title: 'Ny ombul', message: `Ny ombul er ute! ${ombul.name}`, }, - session: null, bypassAuth: true, }) diff --git a/src/services/omegaquotes/create.ts b/src/services/omegaquotes/create.ts index d26da895d..0596867b1 100644 --- a/src/services/omegaquotes/create.ts +++ b/src/services/omegaquotes/create.ts @@ -28,7 +28,7 @@ export async function createQuote( } })) - NotificationMethods.createSpecial.newClient().execute({ + NotificationMethods.createSpecial({ params: { special: 'NEW_OMEGAQUOTE', }, diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index f300655cb..b726da028 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -111,14 +111,14 @@ function expandOneLevel( //Handle all non standard groupings matrix.forEach(row => { const groups_ = row.reduce((acc, id) => { - const g = findGroupOfId(id, groups) - if (g) acc.push(g) + const group = findGroupOfId(id, groups) + if (group) acc.push(group) return acc }, [] as ExpandedGroup[]) const nonStandardRequriment: VisibilityRequiermentForAdmin = { name: 'ekstra', - groups: groups_.map(g => ({ - ...g, + groups: groups_.map(group => ({ + ...group, selected: true })) } From ab3e8d13f40cd9059a3cfd4b87eb2764b983e64a Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 22 Aug 2025 21:59:57 +0200 Subject: [PATCH 06/24] chore: remove "session: null" and fix linting erros --- src/app/lockers/[id]/page.tsx | 1 - src/auth/Session.ts | 3 - src/auth/VevenAdapter.ts | 2 - src/auth/authoptions.ts | 3 - src/auth/getUser.ts | 1 - .../seeder/src/development/seedDevEvents.ts | 2 - .../seeder/src/development/seedDevJobAds.ts | 1 - src/services/actions.ts | 169 ------------------ src/services/api-keys/methods.ts | 3 - src/services/auth/methods.ts | 1 - src/services/cabin/booking/methods.ts | 3 +- src/services/cms/articleCategories/actions.ts | 14 +- src/services/cms/articleSections/actions.ts | 4 +- src/services/cms/articles/actions.ts | 4 +- src/services/cms/images/actions.ts | 20 +-- src/services/cms/links/actions.ts | 2 +- src/services/cms/paragraphs/actions.ts | 18 +- src/services/education/schools/actions.ts | 8 +- src/services/groups/committees/actions.ts | 4 +- src/services/groups/committees/methods.ts | 1 - src/services/groups/committees/read.ts | 1 - src/services/groups/interestGroups/methods.ts | 1 - src/services/groups/memberships/actions.ts | 4 +- src/services/groups/memberships/create.ts | 3 - src/services/groups/memberships/destroy.ts | 2 - src/services/groups/memberships/update.ts | 1 - .../groups/studyProgrammes/actions.ts | 2 +- src/services/images/collections/actions.ts | 20 +-- src/services/images/collections/read.ts | 1 - src/services/lockers/reservations/methods.ts | 1 - src/services/mail/actions.ts | 40 ++--- src/services/mail/alias/actions.ts | 9 +- src/services/mail/list/actions.ts | 9 +- .../mail/mailAddressExternal/actions.ts | 9 +- src/services/news/actions.ts | 8 +- src/services/notifications/channel/actions.ts | 68 ------- .../notifications/subscription/actions.ts | 54 ------ src/services/ombul/actions.ts | 4 +- src/services/ombul/create.ts | 1 - src/services/omegaOrder/actions.ts | 2 +- src/services/omegaid/actions.ts | 2 +- src/services/omegaquotes/actions.ts | 6 +- src/services/omegaquotes/create.ts | 1 - src/services/screens/actions.ts | 4 +- src/services/screens/pages/actions.ts | 6 +- src/services/sendmail/actions.ts | 4 +- src/services/visibility/actions.ts | 4 +- tests/services/apiKeys.test.ts | 3 - tests/services/jobads.test.ts | 7 - 49 files changed, 112 insertions(+), 429 deletions(-) delete mode 100644 src/services/actions.ts delete mode 100644 src/services/notifications/channel/actions.ts delete mode 100644 src/services/notifications/subscription/actions.ts diff --git a/src/app/lockers/[id]/page.tsx b/src/app/lockers/[id]/page.tsx index 0e6c0fcfe..a11054a1a 100644 --- a/src/app/lockers/[id]/page.tsx +++ b/src/app/lockers/[id]/page.tsx @@ -34,7 +34,6 @@ export default async function Locker({ params }: PropTypes) { const groupName = (isReserved && reservation.group) ? inferGroupName(checkGroupValidity(reservation.group)) : '' const groups = await GroupMethods.readGroupsOfUser({ - session: null, bypassAuth: true, params: { userId: user.id, diff --git a/src/auth/Session.ts b/src/auth/Session.ts index 023ba5e09..ae1ed80af 100644 --- a/src/auth/Session.ts +++ b/src/auth/Session.ts @@ -72,7 +72,6 @@ export class Session { const { user = null, permissions = await PermissionMethods.readDefaultPermissions({ - session: null, bypassAuth: true, }), memberships = [], @@ -88,7 +87,6 @@ export class Session { */ public static async fromApiKey(keyAndIdEncoded: string | null): Promise> { const defaultPermissions = await PermissionMethods.readDefaultPermissions({ - session: null, bypassAuth: true, }) if (!keyAndIdEncoded) return new Session<'NO_USER'>({ user: null, permissions: defaultPermissions, memberships: [] }) @@ -100,7 +98,6 @@ export class Session { try { apiKeyFetch = await ApiKeyMethods.readWithHash({ - session: null, bypassAuth: true, params: { id } }) diff --git a/src/auth/VevenAdapter.ts b/src/auth/VevenAdapter.ts index 933380203..bf3fa49b8 100644 --- a/src/auth/VevenAdapter.ts +++ b/src/auth/VevenAdapter.ts @@ -107,7 +107,6 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { const user = await UserMethods.readOrNull({ params: { id: Number(id) }, - session: null, bypassAuth: true, }) @@ -119,7 +118,6 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { console.log(email) const user = await UserMethods.readOrNull({ params: { email }, - session: null, bypassAuth: true, }) diff --git a/src/auth/authoptions.ts b/src/auth/authoptions.ts index b8211d23e..44ee5af82 100644 --- a/src/auth/authoptions.ts +++ b/src/auth/authoptions.ts @@ -129,7 +129,6 @@ export const authOptions: AuthOptions = { case undefined: { const dbUser = await UserMethods.read({ params: { id: token.user.id }, - session: null, bypassAuth: true, }) @@ -167,12 +166,10 @@ export const authOptions: AuthOptions = { provider, user: await UserMethods.read({ params: { id: userId }, - session: null, bypassAuth: true, }), permissions: await PermissionMethods.readPermissionsOfUser({ bypassAuth: true, - session: null, params: { userId, } diff --git a/src/auth/getUser.ts b/src/auth/getUser.ts index 8c356269e..7ef780f30 100644 --- a/src/auth/getUser.ts +++ b/src/auth/getUser.ts @@ -93,7 +93,6 @@ export async function getUser({ const { user = null, permissions = await PermissionMethods.readDefaultPermissions({ - session: null, bypassAuth: true, }), memberships = [], diff --git a/src/prisma/seeder/src/development/seedDevEvents.ts b/src/prisma/seeder/src/development/seedDevEvents.ts index 795877636..077a609c1 100644 --- a/src/prisma/seeder/src/development/seedDevEvents.ts +++ b/src/prisma/seeder/src/development/seedDevEvents.ts @@ -19,7 +19,6 @@ export default async function seedDevEvents(prisma: PrismaClient) { const bedpres = await EventMethods.create({ prisma, - session: null, bypassAuth: true, data: { name: 'Bedpres med Kongsberg', @@ -40,7 +39,6 @@ export default async function seedDevEvents(prisma: PrismaClient) { await EventMethods.create({ prisma, - session: null, bypassAuth: true, data: { name: 'Stresset eksamenslesing', diff --git a/src/prisma/seeder/src/development/seedDevJobAds.ts b/src/prisma/seeder/src/development/seedDevJobAds.ts index 6b61e876e..d0e64236e 100644 --- a/src/prisma/seeder/src/development/seedDevJobAds.ts +++ b/src/prisma/seeder/src/development/seedDevJobAds.ts @@ -58,7 +58,6 @@ export default async function seedDevJobAds(prisma: PrismaClient) { companyId: 1, }, bypassAuth: true, - session: null, }) await prisma.article.update({ diff --git a/src/services/actions.ts b/src/services/actions.ts deleted file mode 100644 index 78b2b1295..000000000 --- a/src/services/actions.ts +++ /dev/null @@ -1,169 +0,0 @@ -'use server' - -import type { AuthStatus } from '@/auth/getUser' -import { Session } from '@/auth/Session' -import { ParseError, Smorekopp, errorCodes } from '@/services/error' -import type { ErrorCode, ErrorMessage } from '@/services/error' -import type { ServiceMethodExecuteArgs, ServiceMethodType } from '@/services/ServiceMethod' -import '@pn-server-only' -import type { SafeParseError, z } from 'zod' - -export type ActionReturnError = { - success: false, - errorCode: ErrorCode, - httpCode: number, - error?: ErrorMessage[], -} - -export type ActionReturn = ( - ActionReturnError -) | { - success: true, -} & ( - DataGuarantee extends true ? { - data: ReturnType - } : { - data?: ReturnType - } -) - -export type Action = (formData: FormData) => ( - Promise> -) - -// This function is overloaded to allow for different combinations of parameters and data. - -export function action( - serviceMethod: ServiceMethodType -): () => Promise> - -export function action( - serviceMethod: ServiceMethodType -): (params: z.input) => Promise> - -export function action( - serviceMethod: ServiceMethodType -): (data: z.input> | FormData) => Promise> - -export function action( - serviceMethod: ServiceMethodType -): (params: z.input, data: z.input> | FormData) => Promise> - -/** - * Turn a service method into suitable function for an action. - * - * @param serviceMethod - The service method to create an action for. - * @returns - A function that takes in data (which may be FormData) and/or/nor parameters and calls the service method. - */ -export function action< - Return, - ParamsSchema extends z.ZodTypeAny | undefined = undefined, - DataSchema extends z.ZodTypeAny | undefined = undefined ->( - serviceMethod: ServiceMethodType -) { - // Letting the arguments to the actual function be unknown is safer as anything can be passed to it form the client. - // The action and service method will validate the parameter and data before it is used. - // - // For convenience this function is given a return type that is more specific. The return type is a function that - // has arguments witch match the underlying service method. This makes programming easier as Intellisense can - // help and errors are caught at compile time. - const actionUnsafe = async (params?: unknown, data?: unknown) => { - const session = await Session.fromNextAuth() - - // Treat empty form data as undefined. This is required because the form component will always send - // a FormData instance, even if no data is being sent. - if (data instanceof FormData && data.entries().next().done) { - data = undefined - } - - return safeServerCall(() => serviceMethod({ - session, - params, - data, - } as unknown as ServiceMethodExecuteArgs)) - } - - // If the service method has a params schema, we require the params to be passed to the action. - if (serviceMethod.paramsSchema) { - return actionUnsafe - } - - // Otherwise we return a function that takes no params, only data. - return actionUnsafe.bind(null, undefined) -}/** - * A simple utility function to bind parameters to an action. - * Under the hood this function simply calls "action.bind(null, params)", - * but it is more readable to use this function. - * - * @param action - An action that takes parameters. - * @param params - The parameters to bind to the action. - * @returns - The same action with the parameters bound to it. - */ -export function bindParams(action: (p: P, ...dataArgs: D) => R, params: P) { - return action.bind(null, params) -} - -/** - * A simple utility function to bind data to an action. - * Under the hood this function simply calls "action.bind(null, data)", - * but it is more readable to use this function. - * - * @param action - An action that takes data. - * @param bindData - The data to bind to the action. - * @returns - The same action with the data bound to it. - */ -export function bindData(action: (dataValue: D) => R, data: D) { - return action.bind(null, data) -} - -export function createActionError(errorCode: ErrorCode | AuthStatus, error?: string | ErrorMessage[]): ActionReturnError { - if (errorCode === 'AUTHORIZED' || errorCode === 'AUTHORIZED_NO_USER') { - return { - success: false, - errorCode: 'UNKNOWN ERROR', - httpCode: 500, - error: typeof error === 'string' ? [{ message: error }] : error, - } - } - return { - success: false, - errorCode, - httpCode: errorCodes.find(e => e.name === errorCode)?.httpCode ?? 500, - error: typeof error === 'string' ? [{ message: error }] : error, - } -} - -export function createZodActionError(parse: SafeParseError): ActionReturnError { - return { - success: false, - httpCode: 400, - errorCode: 'BAD PARAMETERS', - error: parse.error.issues, - } -} - -/** - * A function that calls a server function. If all goes well, it returns a ActionReturn with the data. - * If an error is thrown it returns ActionReturn of success false and the error. - * The function handles ServerErrors class, and treats all other errors as unknown. - * @param call - A async server function to call. - * @returns - A promise that resolves to an ActionReturn. - */ -export async function safeServerCall(call: () => Promise): Promise> { - try { - const data = await call() - return { - success: true, - data - } - } catch (error) { - if (error instanceof ParseError) { - return createZodActionError(error.parseError) - } - if (error instanceof Smorekopp) { - return createActionError(error.errorCode, error.errors) - } - return createActionError('UNKNOWN ERROR', 'unknown error') - } -} diff --git a/src/services/api-keys/methods.ts b/src/services/api-keys/methods.ts index 177ca6b70..ab82861d0 100644 --- a/src/services/api-keys/methods.ts +++ b/src/services/api-keys/methods.ts @@ -79,7 +79,6 @@ export namespace ApiKeyMethods { ...apiKey, ...await updateIfExpired({ params: apiKey, - session: null, bypassAuth: true, }) } @@ -100,7 +99,6 @@ export namespace ApiKeyMethods { ...apiKey, ...await updateIfExpired({ params: apiKey, - session: null, bypassAuth: true, }) }))) @@ -127,7 +125,6 @@ export namespace ApiKeyMethods { ...apiKey, ...await updateIfExpired({ params: apiKey, - session: null, bypassAuth: true, }), } diff --git a/src/services/auth/methods.ts b/src/services/auth/methods.ts index dc317f2c2..f2cd308c9 100644 --- a/src/services/auth/methods.ts +++ b/src/services/auth/methods.ts @@ -33,7 +33,6 @@ export namespace AuthMethods { params: { id: userId, }, - session: null, bypassAuth: true, }) diff --git a/src/services/cabin/booking/methods.ts b/src/services/cabin/booking/methods.ts index 5f94378a0..cc2affd60 100644 --- a/src/services/cabin/booking/methods.ts +++ b/src/services/cabin/booking/methods.ts @@ -185,7 +185,7 @@ export namespace CabinBookingMethods { } }) - await NotificationMethods.createSpecial.client(prisma).execute({ + await NotificationMethods.createSpecial({ params: { special: 'CABIN_BOOKING_CONFIRMATION', }, @@ -193,7 +193,6 @@ export namespace CabinBookingMethods { ...mailData, userIdList: [params.userId], }, - session, bypassAuth: true, }) } diff --git a/src/services/cms/articleCategories/actions.ts b/src/services/cms/articleCategories/actions.ts index c5d6bf966..760487e42 100644 --- a/src/services/cms/articleCategories/actions.ts +++ b/src/services/cms/articleCategories/actions.ts @@ -2,14 +2,20 @@ import { createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { ArticleCategoryWithCover, - ExpandedArticleCategoryWithCover, ExpandedArticleCategory } from '@/cms/articleCategories/Types' import { createArticleCategory } from '@/services/cms/articleCategories/create' import { destroyArticleCategory } from '@/services/cms/articleCategories/destroy' import { readArticleCategories, readArticleCategory } from '@/services/cms/articleCategories/read' import { updateArticleCategory } from '@/services/cms/articleCategories/update' -import { createArticleCategoryValidation, updateArticleCategoryValidation } from '@/services/cms/articleCategories/validation' +import { + createArticleCategoryValidation, + updateArticleCategoryValidation, +} from '@/services/cms/articleCategories/validation' +import type { + ArticleCategoryWithCover, + ExpandedArticleCategoryWithCover, + ExpandedArticleCategory, +} from '@/cms/articleCategories/Types' +import type { ActionReturn } from '@/actions/Types' import type { CreateArticleCategoryTypes, UpdateArticleCategoryTypes } from '@/services/cms/articleCategories/validation' export async function createArticleCategoryAction( diff --git a/src/services/cms/articleSections/actions.ts b/src/services/cms/articleSections/actions.ts index e1ffc6671..d4e96f043 100644 --- a/src/services/cms/articleSections/actions.ts +++ b/src/services/cms/articleSections/actions.ts @@ -2,13 +2,13 @@ import { createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { ArticleSectionPart, ExpandedArticleSection } from '@/cms/articleSections/Types' import { createArticleSection } from '@/services/cms/articleSections/create' import { destroyArticleSection } from '@/services/cms/articleSections/destroy' import { readArticleSection } from '@/services/cms/articleSections/read' import { addArticleSectionPart, removeArticleSectionPart, updateArticleSection } from '@/services/cms/articleSections/update' import { createArticleSectionValidation } from '@/services/cms/articleSections/validation' +import type { ArticleSectionPart, ExpandedArticleSection } from '@/cms/articleSections/Types' +import type { ActionReturn } from '@/actions/Types' import type { CreateArticleSectionTypes } from '@/services/cms/articleSections/validation' import type { ArticleSection, Position } from '@prisma/client' diff --git a/src/services/cms/articles/actions.ts b/src/services/cms/articles/actions.ts index b5683b37b..9a3ce7239 100644 --- a/src/services/cms/articles/actions.ts +++ b/src/services/cms/articles/actions.ts @@ -2,13 +2,13 @@ import { createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedArticle } from '@/cms/articles/Types' import { createArticle } from '@/services/cms/articles/create' import { destroyArticle } from '@/services/cms/articles/destroy' import { readArticle } from '@/services/cms/articles/read' import { addSectionToArticle, moveSectionOrder, updateArticle } from '@/services/cms/articles/update' import { createArticleValidation, updateArticleValidation } from '@/services/cms/articles/validation' +import type { ExpandedArticle } from '@/cms/articles/Types' +import type { ActionReturn } from '@/actions/Types' import type { CreateArticleTypes, UpdateArticleTypes } from '@/services/cms/articles/validation' import type { ArticleSectionPart } from '@/services/cms/articleSections/Types' import type { Article, ArticleSection } from '@prisma/client' diff --git a/src/services/cms/images/actions.ts b/src/services/cms/images/actions.ts index 21d8865af..52c6ccfa9 100644 --- a/src/services/cms/images/actions.ts +++ b/src/services/cms/images/actions.ts @@ -2,17 +2,23 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedCmsImage } from '@/cms/images/Types' import { createCmsImage } from '@/services/cms/images/create' import { readCmsImage, readSpecialCmsImage } from '@/services/cms/images/read' -import type { ExpandedCmsImage } from '@/services/cms/images/Types' import { updateCmsImage, updateCmsImageConfig } from '@/services/cms/images/update' import { baseCmsImageValidation } from '@/services/cms/images/validation' -import type { ValidationTypes } from '@/services/Validation' import { SpecialCmsImage } from '@prisma/client' +import type { ValidationTypes } from '@/services/Validation' +import type { ExpandedCmsImage } from '@/services/cms/images/Types' +import type { ActionReturn } from '@/actions/Types' import type { CmsImage, Image, ImageSize } from '@prisma/client' +export const createCmsImageActionValidation = baseCmsImageValidation.createValidation({ + keys: ['name'], + transformer: data => data, +}) + +export type CreateCmsImageActionTypes = ValidationTypes + export async function createCmsImageAction( rawData: FormData | CreateCmsImageActionTypes['Type'], image?: Image, @@ -71,9 +77,3 @@ export async function updateCmsImageConfigAction( //TODO: Auth on visibility (or permission if special) return await safeServerCall(() => updateCmsImageConfig(cmsImageId, config)) } - -export const createCmsImageActionValidation = baseCmsImageValidation.createValidation({ - keys: ['name'], - transformer: data => data, -}) -export type CreateCmsImageActionTypes = ValidationTypes diff --git a/src/services/cms/links/actions.ts b/src/services/cms/links/actions.ts index 5bd70e40f..199f48cc8 100644 --- a/src/services/cms/links/actions.ts +++ b/src/services/cms/links/actions.ts @@ -3,11 +3,11 @@ import { action } from '@/actions/action' import { createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { createCmsLink } from '@/services/cms/links/create' import { readSpecialCmsLink } from '@/services/cms/links/read' import { updateCmsLink } from '@/services/cms/links/update' import { createCmsLinkValidation, updateCmsLinkValidation } from '@/services/cms/links/validation' +import type { ActionReturn } from '@/actions/Types' import type { CreateCmsLinkTypes, UpdateCmsLinkTypes } from '@/services/cms/links/validation' import type { CmsLink } from '@prisma/client' diff --git a/src/services/cms/paragraphs/actions.ts b/src/services/cms/paragraphs/actions.ts index 38c49144a..f7d2539f8 100644 --- a/src/services/cms/paragraphs/actions.ts +++ b/src/services/cms/paragraphs/actions.ts @@ -2,15 +2,22 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { readCmsParagraph, readSpecialCmsParagraph } from '@/services/cms/paragraphs/read' import { updateCmsParagraphContents } from '@/services/cms/paragraphs/update' import { baseCmsParagraphValidation } from '@/services/cms/paragraphs/validation' -import type { ValidationTypes } from '@/services/Validation' import { SpecialCmsParagraph } from '@prisma/client' +import type { ValidationTypes } from '@/services/Validation' +import type { ActionReturn } from '@/actions/Types' import type { CmsParagraph } from '@prisma/client' +export const createCmsParagraphActionValidation = baseCmsParagraphValidation.createValidation({ + keys: ['name'], + transformer: data => data +}) + +export type CreateCmsParagraphActionTypes = ValidationTypes + export async function createCmsParagraphAction( rawData: FormData | CreateCmsParagraphActionTypes['Type'] ): Promise> { @@ -52,10 +59,3 @@ export async function updateCmsParagraphAction(id: number, contentMd: string): P //TODO: Auth on visibility return await safeServerCall(() => updateCmsParagraphContents(id, contentMd)) } - -export const createCmsParagraphActionValidation = baseCmsParagraphValidation.createValidation({ - keys: ['name'], - transformer: data => data -}) - -export type CreateCmsParagraphActionTypes = ValidationTypes diff --git a/src/services/education/schools/actions.ts b/src/services/education/schools/actions.ts index 7389059f2..7bbef3ee2 100644 --- a/src/services/education/schools/actions.ts +++ b/src/services/education/schools/actions.ts @@ -2,16 +2,16 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' -import type { ExpandedSchool, SchoolCursor, SchoolFiltered } from '@/education/schools/Types' import { createSchoolValidation, updateSchoolValidation } from '@/education/schools/validation' -import type { CreateSchoolTypes, UpdateSchoolTypes } from '@/education/schools/validation' -import type { ReadPageInput } from '@/lib/paging/Types' import { createSchool } from '@/services/education/schools/create' import { destroySchool } from '@/services/education/schools/destroy' import { readSchool, readSchools, readSchoolsPage, readStandardSchools } from '@/services/education/schools/read' import { updateSchool } from '@/services/education/schools/update' +import type { ReadPageInput } from '@/lib/paging/Types' +import type { CreateSchoolTypes, UpdateSchoolTypes } from '@/education/schools/validation' +import type { ExpandedSchool, SchoolCursor, SchoolFiltered } from '@/education/schools/Types' +import type { ActionReturn } from '@/actions/Types' export async function createSchoolAction( rawdata: FormData | CreateSchoolTypes['Type'] diff --git a/src/services/groups/committees/actions.ts b/src/services/groups/committees/actions.ts index 87b1f1ba4..dd9f1a966 100644 --- a/src/services/groups/committees/actions.ts +++ b/src/services/groups/committees/actions.ts @@ -3,13 +3,13 @@ import { action } from '@/actions/action' import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { createCommittee } from '@/services/groups/committees/create' import { CommitteeMethods } from '@/services/groups/committees/methods' -import type { ExpandedCommittee } from '@/services/groups/committees/Types' import { updateCommittee } from '@/services/groups/committees/update' import { createCommitteeValidation, updateCommitteeValidation } from '@/services/groups/committees/validation' +import type { ExpandedCommittee } from '@/services/groups/committees/Types' +import type { ActionReturn } from '@/actions/Types' import type { CreateCommitteeTypes, UpdateCommitteeTypes } from '@/services/groups/committees/validation' export async function createCommitteeAction( diff --git a/src/services/groups/committees/methods.ts b/src/services/groups/committees/methods.ts index c28e3a4ab..a3edd78e9 100644 --- a/src/services/groups/committees/methods.ts +++ b/src/services/groups/committees/methods.ts @@ -24,7 +24,6 @@ export namespace CommitteeMethods { method: async ({ prisma, params }) => { const defaultImage = await ImageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, - session: null, bypassAuth: true }) diff --git a/src/services/groups/committees/read.ts b/src/services/groups/committees/read.ts index 833dd150d..17ad8fd08 100644 --- a/src/services/groups/committees/read.ts +++ b/src/services/groups/committees/read.ts @@ -92,7 +92,6 @@ export async function readCommitteeParagraph(shortName: string) : Promise group.groupId) diff --git a/src/services/groups/memberships/destroy.ts b/src/services/groups/memberships/destroy.ts index 5fe713d31..6f7dad362 100644 --- a/src/services/groups/memberships/destroy.ts +++ b/src/services/groups/memberships/destroy.ts @@ -21,7 +21,6 @@ export async function destoryMembershipOfUser({ } const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ bypassAuth: true, - session: null, params: { id: groupId } @@ -49,7 +48,6 @@ export async function destroyMembershipOfUsers( throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ - session: null, bypassAuth: true, params: { id: groupId, diff --git a/src/services/groups/memberships/update.ts b/src/services/groups/memberships/update.ts index d83782eae..888fba1e1 100644 --- a/src/services/groups/memberships/update.ts +++ b/src/services/groups/memberships/update.ts @@ -20,7 +20,6 @@ export async function updateMembership({ const order = (orderArg && typeof orderArg === 'number') ? orderArg : ( await GroupMethods.readCurrentGroupOrder({ bypassAuth: true, - session: null, params: { id: groupId } diff --git a/src/services/groups/studyProgrammes/actions.ts b/src/services/groups/studyProgrammes/actions.ts index 78eea4ed7..85f4f8895 100644 --- a/src/services/groups/studyProgrammes/actions.ts +++ b/src/services/groups/studyProgrammes/actions.ts @@ -2,12 +2,12 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { createStudyProgramme } from '@/services/groups/studyProgrammes/create' import { readStudyProgrammes } from '@/services/groups/studyProgrammes/read' import { updateStudyProgramme } from '@/services/groups/studyProgrammes/update' import { createStudyProgrammeValidation, updateStudyProgrammeValidation } from '@/services/groups/studyProgrammes/validation' +import type { ActionReturn } from '@/actions/Types' import type { StudyProgramme } from '@prisma/client' export async function createStudyProgrammeAction(rawdata: FormData): Promise> { diff --git a/src/services/images/collections/actions.ts b/src/services/images/collections/actions.ts index 0eb5601f4..d7a18e8ee 100644 --- a/src/services/images/collections/actions.ts +++ b/src/services/images/collections/actions.ts @@ -2,26 +2,26 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { checkVisibility } from '@/auth/checkVisibility' import { getUser } from '@/auth/getUser' import { getVisibilityFilter } from '@/auth/getVisibilityFilter' -import type { ReadPageInput } from '@/lib/paging/Types' import { createImageCollection } from '@/services/images/collections/create' import { destroyImageCollection } from '@/services/images/collections/destroy' -import { - readImageCollection, - readImageCollectionsPage, +import { + readImageCollection, + readImageCollectionsPage, readSpecialImageCollection } from '@/services/images/collections/read' -import type { ExpandedImageCollection, - ImageCollectionCursor, - ImageCollectionPageReturn } from '@/services/images/collections/Types' import { updateImageCollection } from '@/services/images/collections/update' import { createImageCollectionValidation, updateImageCollectionValidation } from '@/services/images/collections/validation' -import type { CreateImageCollectionTypes, UpdateImageCollectionTypes } from '@/services/images/collections/validation' import { includeVisibility } from '@/services/visibility/read' -import type { VisibilityCollapsed } from '@/services/visibility/Types' import { SpecialCollection } from '@prisma/client' +import type { CreateImageCollectionTypes, UpdateImageCollectionTypes } from '@/services/images/collections/validation' +import type { VisibilityCollapsed } from '@/services/visibility/Types' +import type { ExpandedImageCollection, + ImageCollectionCursor, + ImageCollectionPageReturn } from '@/services/images/collections/Types' +import type { ReadPageInput } from '@/lib/paging/Types' +import type { ActionReturn } from '@/actions/Types' import type { ImageCollection } from '@prisma/client' export async function createImageCollectionAction( diff --git a/src/services/images/collections/read.ts b/src/services/images/collections/read.ts index 10d77513e..35d0d2d2b 100644 --- a/src/services/images/collections/read.ts +++ b/src/services/images/collections/read.ts @@ -72,7 +72,6 @@ export async function readImageCollectionsPage( params: { special: 'DEFAULT_IMAGE_COLLECTION_COVER' }, - session: null //TODO: pass session }) const chooseCoverImage = (collection: { diff --git a/src/services/lockers/reservations/methods.ts b/src/services/lockers/reservations/methods.ts index 9072ea204..23631abeb 100644 --- a/src/services/lockers/reservations/methods.ts +++ b/src/services/lockers/reservations/methods.ts @@ -27,7 +27,6 @@ export namespace LockerReservationMethods { // Verify that user is in group if (data.groupId) { const groupUsers = await GroupMethods.readUsersOfGroups({ - session: null, bypassAuth: true, params: { groups: [{ groupId: data.groupId, admin: false }] diff --git a/src/services/mail/actions.ts b/src/services/mail/actions.ts index a6a105113..166ef1054 100644 --- a/src/services/mail/actions.ts +++ b/src/services/mail/actions.ts @@ -2,36 +2,36 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { readMailAliases } from '@/services/mail/alias/read' -import { - createAliasMailingListRelation, - createMailingListExternalRelation, - createMailingListGroupRelation, +import { + createAliasMailingListRelation, + createMailingListExternalRelation, + createMailingListGroupRelation, createMailingListUserRelation } from '@/services/mail/create' -import { - destroyAliasMailingListRelation, - destroyMailingListExternalRelation, - destroyMailingListGroupRelation, +import { + destroyAliasMailingListRelation, + destroyMailingListExternalRelation, + destroyMailingListGroupRelation, destroyMailingListUserRelation } from '@/services/mail/destroy' import { readMailingLists } from '@/services/mail/list/read' import { readMailAddressExternal } from '@/services/mail/mailAddressExternal/read' import { readMailTraversal } from '@/services/mail/read' -import type { MailListTypes } from '@/services/mail/Types' -import { - createAliasMailingListValidation, - createMailingListExternalValidation, - createMailingListGroupValidation, +import { + createAliasMailingListValidation, + createMailingListExternalValidation, + createMailingListGroupValidation, createMailingListUserValidation } from '@/services/mail/validation' -import type { CreateAliasMailingListType, - CreateMailingListExternalType, - CreateMailingListGroupType, +import type { MailListTypes } from '@/services/mail/Types' +import type { ActionReturn } from '@/actions/Types' +import type { CreateAliasMailingListType, + CreateMailingListExternalType, + CreateMailingListGroupType, CreateMailingListUserType } from '@/services/mail/validation' import type { UserFiltered } from '@/services/users/Types' -import type { MailAliasMailingList, - MailingListGroup, - MailingListMailAddressExternal, +import type { MailAliasMailingList, + MailingListGroup, + MailingListMailAddressExternal, MailingListUser, MailAddressExternal, MailAlias, MailingList } from '@prisma/client' export async function createAliasMailingListRelationAction(formdata: FormData): diff --git a/src/services/mail/alias/actions.ts b/src/services/mail/alias/actions.ts index 461b0e794..df5bb03e9 100644 --- a/src/services/mail/alias/actions.ts +++ b/src/services/mail/alias/actions.ts @@ -1,15 +1,18 @@ 'use server' -import type { ActionReturn } from '@/actions//Types' import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { createMailAlias } from '@/services/mail/alias/create' import { destroyMailAlias } from '@/services/mail/alias/destroy' import { readMailAliases } from '@/services/mail/alias/read' import { updateMailAlias } from '@/services/mail/alias/update' -import { createMailAliasValidation, destoryMailAliasValidation, updateMailAliasValidation } from '@/services/mail/alias/validation' +import { + createMailAliasValidation, + destoryMailAliasValidation, + updateMailAliasValidation, +} from '@/services/mail/alias/validation' +import type { ActionReturn } from '@/actions//Types' import type { MailAlias } from '@prisma/client' export async function createMailAliasAction(rawdata: FormData): diff --git a/src/services/mail/list/actions.ts b/src/services/mail/list/actions.ts index 6ab44f858..1b9040a0e 100644 --- a/src/services/mail/list/actions.ts +++ b/src/services/mail/list/actions.ts @@ -1,14 +1,17 @@ 'use server' -import type { ActionReturn } from '@/actions//Types' import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { createMailingList } from '@/services/mail/list/create' import { destroyMailingList } from '@/services/mail/list/destroy' import { updateMailingList } from '@/services/mail/list/update' -import { createMailingListValidation, readMailingListValidation, updateMailingListValidation } from '@/services/mail/list/validation' +import { + createMailingListValidation, + readMailingListValidation, + updateMailingListValidation +} from '@/services/mail/list/validation' +import type { ActionReturn } from '@/actions//Types' import type { MailingList } from '@prisma/client' export async function createMailingListAction(rawdata: FormData): diff --git a/src/services/mail/mailAddressExternal/actions.ts b/src/services/mail/mailAddressExternal/actions.ts index 094298cc1..4d2ca8b23 100644 --- a/src/services/mail/mailAddressExternal/actions.ts +++ b/src/services/mail/mailAddressExternal/actions.ts @@ -1,14 +1,17 @@ 'use server' -import type { ActionReturn } from '@/actions//Types' import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { createMailAddressExternal } from '@/services/mail/mailAddressExternal/create' import { destroyMailAddressExternal } from '@/services/mail/mailAddressExternal/destroy' import { updateMailAddressExternal } from '@/services/mail/mailAddressExternal/update' -import { createMailAddressExternalValidation, readMailAddressExternalValidation, updateMailAddressExternalValidation } from '@/services/mail/mailAddressExternal/validation' +import { + createMailAddressExternalValidation, + readMailAddressExternalValidation, + updateMailAddressExternalValidation, +} from '@/services/mail/mailAddressExternal/validation' +import type { ActionReturn } from '@/actions//Types' import type { MailAddressExternal } from '@prisma/client' export async function createMailAddressExternalAction(rawdata: FormData): diff --git a/src/services/news/actions.ts b/src/services/news/actions.ts index 5f00068bf..3a5afd3f2 100644 --- a/src/services/news/actions.ts +++ b/src/services/news/actions.ts @@ -2,16 +2,16 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { ReadPageInput } from '@/lib/paging/Types' import { createNews } from '@/services/news/create' import { destroyNews } from '@/services/news/destroy' import { readNews, readNewsCurrent, readOldNewsPage } from '@/services/news/read' -import type { ExpandedNewsArticle, NewsCursor, SimpleNewsArticle } from '@/services/news/Types' import { updateNews } from '@/services/news/update' import { createNewsArticleValidation, updateNewsArticleValidation } from '@/services/news/validation' -import type { CreateNewsArticleTypes, UpdateNewsArticleTypes } from '@/services/news/validation' import { NotificationMethods } from '@/services/notifications/methods' +import type { CreateNewsArticleTypes, UpdateNewsArticleTypes } from '@/services/news/validation' +import type { ExpandedNewsArticle, NewsCursor, SimpleNewsArticle } from '@/services/news/Types' +import type { ReadPageInput } from '@/lib/paging/Types' +import type { ActionReturn } from '@/actions/Types' export async function createNewsAction( rawdata: FormData | CreateNewsArticleTypes['Type'] diff --git a/src/services/notifications/channel/actions.ts b/src/services/notifications/channel/actions.ts deleted file mode 100644 index 5e9cbcfe1..000000000 --- a/src/services/notifications/channel/actions.ts +++ /dev/null @@ -1,68 +0,0 @@ -'use server' - -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import { getUser } from '@/auth/getUser' -import { createNotificationChannel } from '@/services/notifications/channel/create' -import { readNotificationChannels } from '@/services/notifications/channel/read' -import { updateNotificationChannel } from '@/services/notifications/channel/update' -import { createNotificaionChannelValidation, parseMethods, updateNotificaionChannelValidation } from '@/services/notifications/channel/validation' -import type { ExpandedNotificationChannel } from '@/services/notifications/Types' - -export async function createNotificationChannelAction(rawdata: FormData): -Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['NOTIFICATION_CHANNEL_CREATE']] - }) - - if (!authorized) return createActionError(status) - - const typeParsed = createNotificaionChannelValidation.typeValidate(rawdata) - if (!typeParsed.success) return createZodActionError(typeParsed) - - return safeServerCall(() => { - const availableParsed = parseMethods(rawdata, 'availableMethods') - const defaultParsed = parseMethods(rawdata, 'defaultMethods') - - return createNotificationChannel({ - ...typeParsed.data, - availableMethods: availableParsed, - defaultMethods: defaultParsed, - }) - }) -} - -export async function readNotificationChannelsAction(): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['NOTIFICATION_CHANNEL_READ']], - userRequired: false, - }) - - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readNotificationChannels()) -} - -export async function updateNotificationChannelAction(formdata: FormData): -Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['NOTIFICATION_CHANNEL_UPDATE']] - }) - if (!authorized) return createActionError(status) - - const parse = updateNotificaionChannelValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(async () => { - const availableMethods = parseMethods(formdata, 'availableMethods') - const defaultMethods = parseMethods(formdata, 'defaultMethods') - - return updateNotificationChannel({ - ...parse.data, - availableMethods, - defaultMethods, - }) - }) -} diff --git a/src/services/notifications/subscription/actions.ts b/src/services/notifications/subscription/actions.ts deleted file mode 100644 index cc080dd2c..000000000 --- a/src/services/notifications/subscription/actions.ts +++ /dev/null @@ -1,54 +0,0 @@ -'use server' - -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import { getUser } from '@/auth/getUser' -import { readUserSubscriptions } from '@/services/notifications/subscription/read' -import type { MinimizedSubscription, Subscription } from '@/services/notifications/subscription/Types' -import { updateSubscriptions } from '@/services/notifications/subscription/update' -import { parseSubscriptionMatrix, updateSubscriptionValidation } from '@/services/notifications/subscription/validation' - -export async function readSubscriptionsAction(userId?: number): -Promise> { - const { authorized, status, user, permissions } = await getUser({ - requiredPermissions: [ - ['NOTIFICATION_CHANNEL_READ'], - ['NOTIFICATION_SUBSCRIPTION_READ'], - ], - userRequired: true, - }) - - if (!authorized) return createActionError(status) - - if (!userId) { - userId = user.id - } - - if (userId !== user.id && !permissions.includes('NOTIFICATION_SUBSCRIPTION_READ_OTHER')) { - return createActionError('UNAUTHORIZED') - } - - return await safeServerCall(() => readUserSubscriptions(userId)) -} - -export async function updateSubscriptionsAction(userId: number, subscriptions: MinimizedSubscription[]): -Promise> { - const { authorized, status, user, permissions } = await getUser({ - requiredPermissions: [['NOTIFICATION_SUBSCRIPTION_UPDATE']], - userRequired: true, - }) - if (!authorized) return createActionError(status) - - if (userId !== user.id && !permissions.includes('NOTIFICATION_SUBSCRIPTION_UPDATE_OTHER')) { - return createActionError('UNAUTHORIZED') - } - - const parse = parseSubscriptionMatrix(subscriptions) - if (!parse.success) return createZodActionError(parse) - - const userParse = updateSubscriptionValidation.typeValidate({ userId }) - if (!userParse.success) return createZodActionError(userParse) - - return await safeServerCall(() => updateSubscriptions(userParse.data.userId, parse.data)) -} diff --git a/src/services/ombul/actions.ts b/src/services/ombul/actions.ts index a04a046d7..eaf6fc522 100644 --- a/src/services/ombul/actions.ts +++ b/src/services/ombul/actions.ts @@ -2,14 +2,14 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { createOmbul } from '@/services/ombul/create' import { destroyOmbul } from '@/services/ombul/destroy' import { readLatestOmbul, readOmbul, readOmbuls } from '@/services/ombul/read' -import type { ExpandedOmbul } from '@/services/ombul/Types' import { updateOmbul, updateOmbulFile } from '@/services/ombul/update' import { createOmbulValidation, updateOmbulFileValidation, updateOmbulValidation } from '@/services/ombul/validation' +import type { ExpandedOmbul } from '@/services/ombul/Types' +import type { ActionReturn } from '@/actions/Types' import type { CreateOmbulTypes, UpdateOmbulFileTypes, UpdateOmbulTypes } from '@/services/ombul/validation' import type { Ombul } from '@prisma/client' diff --git a/src/services/ombul/create.ts b/src/services/ombul/create.ts index cb8500f25..47a2d6669 100644 --- a/src/services/ombul/create.ts +++ b/src/services/ombul/create.ts @@ -52,7 +52,6 @@ export async function createOmbul( alt: `cover of ${config.name}`, file: cover, }, - session: null }) const cmsCoverImage = await createCmsImage({ name: fsLocation }, coverImage) diff --git a/src/services/omegaOrder/actions.ts b/src/services/omegaOrder/actions.ts index ffaf7e19e..aca1c03e7 100644 --- a/src/services/omegaOrder/actions.ts +++ b/src/services/omegaOrder/actions.ts @@ -2,10 +2,10 @@ import { createActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { createOmegaOrder } from '@/services/omegaOrder/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' +import type { ActionReturn } from '@/actions/Types' import type { OmegaOrder } from '@prisma/client' export async function createOmegaOrderAction(): Promise> { diff --git a/src/services/omegaid/actions.ts b/src/services/omegaid/actions.ts index 1e97786ec..809c6d4fb 100644 --- a/src/services/omegaid/actions.ts +++ b/src/services/omegaid/actions.ts @@ -1,10 +1,10 @@ 'use server' import { createActionError } from '@/actions/error' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { ServerError } from '@/services/error' import { generateOmegaId } from '@/services/omegaid/generate' +import type { ActionReturn } from '@/actions/Types' export async function generateOmegaIdAction(): Promise> { const { user, authorized, status } = await getUser({ diff --git a/src/services/omegaquotes/actions.ts b/src/services/omegaquotes/actions.ts index 8fe7ae274..7a6020c88 100644 --- a/src/services/omegaquotes/actions.ts +++ b/src/services/omegaquotes/actions.ts @@ -2,13 +2,13 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' -import type { ReadPageInput } from '@/lib/paging/Types' import { createQuote } from '@/services/omegaquotes/create' import { readQuotesPage } from '@/services/omegaquotes/read' -import type { OmegaquoteCursor, OmegaquoteFiltered } from '@/services/omegaquotes/Types' import { createOmegaquotesValidation } from '@/services/omegaquotes/validation' +import type { OmegaquoteCursor, OmegaquoteFiltered } from '@/services/omegaquotes/Types' +import type { ReadPageInput } from '@/lib/paging/Types' +import type { ActionReturn } from '@/actions/Types' import type { CreateOmegaguotesTypes } from '@/services/omegaquotes/validation' import type { OmegaQuote } from '@prisma/client' diff --git a/src/services/omegaquotes/create.ts b/src/services/omegaquotes/create.ts index 0596867b1..cc6e24838 100644 --- a/src/services/omegaquotes/create.ts +++ b/src/services/omegaquotes/create.ts @@ -36,7 +36,6 @@ export async function createQuote( title: 'Ny Omegaquote♪', message: `${results.quote}\n - ${results.author}`, }, - session: null, bypassAuth: true, }) diff --git a/src/services/screens/actions.ts b/src/services/screens/actions.ts index 064f75d85..eac0fe016 100644 --- a/src/services/screens/actions.ts +++ b/src/services/screens/actions.ts @@ -2,15 +2,15 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { RequirePermission } from '@/auth/auther/RequirePermission' import { Session } from '@/auth/Session' import { createScreen } from '@/services/screens/create' import { destroyScreen } from '@/services/screens/destroy' import { readScreen, readScreens } from '@/services/screens/read' -import type { ScreenPageMoveDirection } from '@/services/screens/Types' import { movePageInScreen, updateScreen } from '@/services/screens/update' import { createScreenValidation, updateScreenValidation } from '@/services/screens/validation' +import type { ScreenPageMoveDirection } from '@/services/screens/Types' +import type { ActionReturn } from '@/actions/Types' import type { CreateScreenTypes, UpdateScreenTypes } from '@/services/screens/validation' import type { Screen } from '@prisma/client' diff --git a/src/services/screens/pages/actions.ts b/src/services/screens/pages/actions.ts index 3ceab6eac..2e90d9f14 100644 --- a/src/services/screens/pages/actions.ts +++ b/src/services/screens/pages/actions.ts @@ -2,16 +2,16 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' import { createPage } from '@/services/screens/pages/create' import { destroyPage } from '@/services/screens/pages/destroy' import { readPage, readPages } from '@/services/screens/pages/read' -import type { ExpandedScreenPage } from '@/services/screens/pages/Types' import { updatePage } from '@/services/screens/pages/update' import { updatePageValidation } from '@/services/screens/pages/validation' -import type { UpdatePageTypes } from '@/services/screens/pages/validation' import { createScreenValidation } from '@/services/screens/validation' +import type { UpdatePageTypes } from '@/services/screens/pages/validation' +import type { ExpandedScreenPage } from '@/services/screens/pages/Types' +import type { ActionReturn } from '@/actions/Types' import type { CreateScreenTypes } from '@/services/screens/validation' import type { ScreenPage } from '@prisma/client' diff --git a/src/services/sendmail/actions.ts b/src/services/sendmail/actions.ts index 3c616bd2b..eb61df277 100644 --- a/src/services/sendmail/actions.ts +++ b/src/services/sendmail/actions.ts @@ -2,10 +2,10 @@ import { createActionError, createZodActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { getUser } from '@/auth/getUser' -import { sendMail as transportSendMail } from '@/services/notifications/email/send' +import { sendMail as transportSendMail } from '@/services/notifications/email/send' import { sendEmailValidation } from '@/services/notifications/email/validation' +import type { ActionReturn } from '@/actions/Types' export default async function sendMail(rawdata: FormData): Promise> { const { authorized, status } = await getUser({ diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index b726da028..6753a94a6 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -2,14 +2,14 @@ import { createActionError } from '@/actions/error' import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' import { checkVisibility } from '@/auth/checkVisibility' import { getUser } from '@/auth/getUser' import { GroupTypesConfig } from '@/services/groups/config' import { GroupMethods } from '@/services/groups/methods' -import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' import { PurposeTextsConfig } from '@/services/visibility/ConfigVars' import { readVisibilityCollapsed } from '@/services/visibility/read' +import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' +import type { ActionReturn } from '@/actions/Types' import type { GroupMatrix, VisibilityLevelType } from '@/services/visibility/Types' import type { GroupType } from '@prisma/client' diff --git a/tests/services/apiKeys.test.ts b/tests/services/apiKeys.test.ts index a830fc425..4a212084c 100644 --- a/tests/services/apiKeys.test.ts +++ b/tests/services/apiKeys.test.ts @@ -63,7 +63,6 @@ describe('api keys', () => { data: { name: 'Min api nøkkel', }, - session: null, }) expect(createdApiKeyPromise).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) expect(await prisma.apiKey.count()).toEqual(0) @@ -72,7 +71,6 @@ describe('api keys', () => { params: { id: 1, }, - session: null, }) expect(readApiKeyPromise).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) @@ -83,7 +81,6 @@ describe('api keys', () => { data: { permissions: ['APIKEY_ADMIN'], }, - session: null, }) expect(updateApiKeyPromise).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) }) diff --git a/tests/services/jobads.test.ts b/tests/services/jobads.test.ts index 7b1c369fe..76822b2a4 100644 --- a/tests/services/jobads.test.ts +++ b/tests/services/jobads.test.ts @@ -43,7 +43,6 @@ afterEach(async () => { params: { id: jobAd.id }, - session: null, bypassAuth: true, }) )) @@ -80,7 +79,6 @@ describe('job ads', () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, - session: null, bypassAuth: true }) @@ -92,7 +90,6 @@ describe('job ads', () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, - session: null, bypassAuth: true }) @@ -110,7 +107,6 @@ describe('job ads', () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, - session: null, bypassAuth: true }) @@ -130,7 +126,6 @@ describe('job ads', () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, - session: null, bypassAuth: true }) @@ -156,7 +151,6 @@ describe('job ads', () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, - session: null, bypassAuth: true }) @@ -171,7 +165,6 @@ describe('job ads', () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. const createRes = await JobadMethods.create({ data: CREATE_JOB_AD, - session: null, bypassAuth: true }) From e2c1d54ea05b9c634067960aa66063aa3f5fa33c Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 22 Aug 2025 22:18:46 +0200 Subject: [PATCH 07/24] refactor: remove old actions --- src/actions/Types.ts | 24 ---- src/actions/admission/create.ts | 5 - src/actions/api-keys/create.ts | 5 - src/actions/api-keys/destroy.ts | 5 - src/actions/api-keys/read.ts | 6 - src/actions/api-keys/update.ts | 5 - src/actions/applications/create.ts | 5 - src/actions/applications/destroy.ts | 5 - src/actions/applications/periods/create.ts | 5 - src/actions/applications/periods/destroy.ts | 6 - src/actions/applications/periods/read.ts | 7 - src/actions/applications/periods/update.ts | 5 - src/actions/applications/read.ts | 5 - src/actions/applications/update.ts | 5 - src/actions/auth/auth.ts | 8 -- src/actions/bind.ts | 25 ---- src/actions/cabin/index.ts | 31 ----- src/actions/career/companies/create.ts | 5 - src/actions/career/companies/destroy.ts | 5 - src/actions/career/companies/read.ts | 5 - src/actions/career/companies/update.ts | 5 - src/actions/career/jobAds/create.ts | 6 - src/actions/career/jobAds/destroy.ts | 5 - src/actions/career/jobAds/read.ts | 7 - src/actions/career/jobAds/update.ts | 5 - src/actions/cms/articleCategories/create.ts | 19 --- src/actions/cms/articleCategories/destroy.ts | 10 -- src/actions/cms/articleCategories/read.ts | 18 --- src/actions/cms/articleCategories/update.ts | 29 ---- src/actions/cms/articleSections/create.ts | 19 --- src/actions/cms/articleSections/destroy.ts | 10 -- src/actions/cms/articleSections/read.ts | 10 -- src/actions/cms/articleSections/update.ts | 31 ----- src/actions/cms/articles/create.ts | 21 --- src/actions/cms/articles/destroy.ts | 10 -- src/actions/cms/articles/read.ts | 13 -- src/actions/cms/articles/update.ts | 39 ------ src/actions/cms/images/create.ts | 21 --- src/actions/cms/images/read.ts | 42 ------ src/actions/cms/images/update.ts | 18 --- src/actions/cms/images/validation.ts | 8 -- src/actions/cms/links/create.ts | 19 --- src/actions/cms/links/read.ts | 6 - src/actions/cms/links/update.ts | 22 --- src/actions/cms/paragraphs/create.ts | 19 --- src/actions/cms/paragraphs/read.ts | 34 ----- src/actions/cms/paragraphs/update.ts | 10 -- src/actions/cms/paragraphs/validation.ts | 9 -- src/actions/dots/create.ts | 5 - src/actions/dots/read.ts | 7 - src/actions/education/courses/create.ts | 8 -- src/actions/education/schools/create.ts | 24 ---- src/actions/education/schools/destroy.ts | 15 -- src/actions/education/schools/read.ts | 50 ------- src/actions/education/schools/update.ts | 25 ---- src/actions/error.ts | 31 ----- src/actions/events/create.ts | 5 - src/actions/events/destroy.ts | 5 - src/actions/events/read.ts | 7 - src/actions/events/registration/index.ts | 12 -- src/actions/events/tags/create.ts | 5 - src/actions/events/tags/destroy.ts | 5 - src/actions/events/tags/read.ts | 7 - src/actions/events/tags/update.ts | 5 - src/actions/events/update.ts | 5 - src/actions/groups/committees/create.ts | 25 ---- src/actions/groups/committees/read.ts | 10 -- src/actions/groups/committees/update.ts | 24 ---- src/actions/groups/interestGroups/create.ts | 5 - src/actions/groups/interestGroups/destroy.ts | 6 - src/actions/groups/interestGroups/read.ts | 5 - src/actions/groups/interestGroups/update.ts | 5 - src/actions/groups/memberships/create.ts | 28 ---- src/actions/groups/memberships/destory.ts | 28 ---- src/actions/groups/memberships/update.ts | 27 ---- src/actions/groups/read.ts | 8 -- src/actions/groups/studyProgrammes/create.ts | 22 --- src/actions/groups/studyProgrammes/read.ts | 18 --- src/actions/groups/studyProgrammes/update.ts | 25 ---- src/actions/images/collections/create.ts | 23 ---- src/actions/images/collections/destroy.ts | 11 -- src/actions/images/collections/read.ts | 72 ---------- src/actions/images/collections/update.ts | 28 ---- src/actions/images/create.ts | 6 - src/actions/images/destroy.ts | 5 - src/actions/images/read.ts | 16 --- src/actions/images/update.ts | 5 - src/actions/licenses/create.ts | 5 - src/actions/licenses/destroy.ts | 5 - src/actions/licenses/read.ts | 5 - src/actions/licenses/update.ts | 5 - src/actions/lockers/locations.ts | 7 - src/actions/lockers/lockers.ts | 7 - src/actions/lockers/reservations.ts | 7 - src/actions/mail/alias/create.ts | 24 ---- src/actions/mail/alias/destory.ts | 20 --- src/actions/mail/alias/read.ts | 17 --- src/actions/mail/alias/update.ts | 21 --- src/actions/mail/create.ts | 76 ----------- src/actions/mail/destroy.ts | 83 ----------- src/actions/mail/list/create.ts | 24 ---- src/actions/mail/list/destory.ts | 20 --- src/actions/mail/list/update.ts | 23 ---- .../mail/mailAddressExternal/create.ts | 24 ---- .../mail/mailAddressExternal/destroy.ts | 20 --- .../mail/mailAddressExternal/update.ts | 23 ---- src/actions/mail/read.ts | 63 --------- src/actions/news/create.ts | 19 --- src/actions/news/destroy.ts | 10 -- src/actions/news/read.ts | 26 ---- src/actions/news/update.ts | 49 ------- src/actions/notifications/index.ts | 15 -- src/actions/ombul/create.ts | 28 ---- src/actions/ombul/destroy.ts | 17 --- src/actions/ombul/read.ts | 42 ------ src/actions/ombul/update.ts | 56 -------- src/actions/omegaOrder/create.ts | 15 -- src/actions/omegaOrder/read.ts | 16 --- src/actions/omegaid/generate.ts | 22 --- src/actions/omegaid/read.ts | 14 -- src/actions/omegaquotes/create.ts | 27 ---- src/actions/omegaquotes/read.ts | 20 --- src/actions/permissions/index.ts | 10 -- src/actions/safeServerCall.ts | 4 +- src/actions/screens/authers.ts | 4 - src/actions/screens/create.ts | 20 --- src/actions/screens/destroy.ts | 14 -- src/actions/screens/pages/create.ts | 22 --- src/actions/screens/pages/destroy.ts | 16 --- src/actions/screens/pages/read.ts | 26 ---- src/actions/screens/pages/update.ts | 22 --- src/actions/screens/read.ts | 22 --- src/actions/screens/update.ts | 32 ----- src/actions/sendmail/send.ts | 23 ---- src/actions/shop/product.ts | 14 -- src/actions/shop/shop.ts | 9 -- src/actions/users/create.ts | 10 -- src/actions/users/destroy.ts | 11 -- src/actions/users/read.ts | 25 ---- src/actions/users/update.ts | 8 -- src/actions/visibility/Types.ts | 25 ---- src/actions/visibility/read.ts | 129 ------------------ src/actions/visibility/update.ts | 11 -- 143 files changed, 2 insertions(+), 2570 deletions(-) delete mode 100644 src/actions/Types.ts delete mode 100644 src/actions/admission/create.ts delete mode 100644 src/actions/api-keys/create.ts delete mode 100644 src/actions/api-keys/destroy.ts delete mode 100644 src/actions/api-keys/read.ts delete mode 100644 src/actions/api-keys/update.ts delete mode 100644 src/actions/applications/create.ts delete mode 100644 src/actions/applications/destroy.ts delete mode 100644 src/actions/applications/periods/create.ts delete mode 100644 src/actions/applications/periods/destroy.ts delete mode 100644 src/actions/applications/periods/read.ts delete mode 100644 src/actions/applications/periods/update.ts delete mode 100644 src/actions/applications/read.ts delete mode 100644 src/actions/applications/update.ts delete mode 100644 src/actions/auth/auth.ts delete mode 100644 src/actions/bind.ts delete mode 100644 src/actions/cabin/index.ts delete mode 100644 src/actions/career/companies/create.ts delete mode 100644 src/actions/career/companies/destroy.ts delete mode 100644 src/actions/career/companies/read.ts delete mode 100644 src/actions/career/companies/update.ts delete mode 100644 src/actions/career/jobAds/create.ts delete mode 100644 src/actions/career/jobAds/destroy.ts delete mode 100644 src/actions/career/jobAds/read.ts delete mode 100644 src/actions/career/jobAds/update.ts delete mode 100644 src/actions/cms/articleCategories/create.ts delete mode 100644 src/actions/cms/articleCategories/destroy.ts delete mode 100644 src/actions/cms/articleCategories/read.ts delete mode 100644 src/actions/cms/articleCategories/update.ts delete mode 100644 src/actions/cms/articleSections/create.ts delete mode 100644 src/actions/cms/articleSections/destroy.ts delete mode 100644 src/actions/cms/articleSections/read.ts delete mode 100644 src/actions/cms/articleSections/update.ts delete mode 100644 src/actions/cms/articles/create.ts delete mode 100644 src/actions/cms/articles/destroy.ts delete mode 100644 src/actions/cms/articles/read.ts delete mode 100644 src/actions/cms/articles/update.ts delete mode 100644 src/actions/cms/images/create.ts delete mode 100644 src/actions/cms/images/read.ts delete mode 100644 src/actions/cms/images/update.ts delete mode 100644 src/actions/cms/images/validation.ts delete mode 100644 src/actions/cms/links/create.ts delete mode 100644 src/actions/cms/links/read.ts delete mode 100644 src/actions/cms/links/update.ts delete mode 100644 src/actions/cms/paragraphs/create.ts delete mode 100644 src/actions/cms/paragraphs/read.ts delete mode 100644 src/actions/cms/paragraphs/update.ts delete mode 100644 src/actions/cms/paragraphs/validation.ts delete mode 100644 src/actions/dots/create.ts delete mode 100644 src/actions/dots/read.ts delete mode 100644 src/actions/education/courses/create.ts delete mode 100644 src/actions/education/schools/create.ts delete mode 100644 src/actions/education/schools/destroy.ts delete mode 100644 src/actions/education/schools/read.ts delete mode 100644 src/actions/education/schools/update.ts delete mode 100644 src/actions/error.ts delete mode 100644 src/actions/events/create.ts delete mode 100644 src/actions/events/destroy.ts delete mode 100644 src/actions/events/read.ts delete mode 100644 src/actions/events/registration/index.ts delete mode 100644 src/actions/events/tags/create.ts delete mode 100644 src/actions/events/tags/destroy.ts delete mode 100644 src/actions/events/tags/read.ts delete mode 100644 src/actions/events/tags/update.ts delete mode 100644 src/actions/events/update.ts delete mode 100644 src/actions/groups/committees/create.ts delete mode 100644 src/actions/groups/committees/read.ts delete mode 100644 src/actions/groups/committees/update.ts delete mode 100644 src/actions/groups/interestGroups/create.ts delete mode 100644 src/actions/groups/interestGroups/destroy.ts delete mode 100644 src/actions/groups/interestGroups/read.ts delete mode 100644 src/actions/groups/interestGroups/update.ts delete mode 100644 src/actions/groups/memberships/create.ts delete mode 100644 src/actions/groups/memberships/destory.ts delete mode 100644 src/actions/groups/memberships/update.ts delete mode 100644 src/actions/groups/read.ts delete mode 100644 src/actions/groups/studyProgrammes/create.ts delete mode 100644 src/actions/groups/studyProgrammes/read.ts delete mode 100644 src/actions/groups/studyProgrammes/update.ts delete mode 100644 src/actions/images/collections/create.ts delete mode 100644 src/actions/images/collections/destroy.ts delete mode 100644 src/actions/images/collections/read.ts delete mode 100644 src/actions/images/collections/update.ts delete mode 100644 src/actions/images/create.ts delete mode 100644 src/actions/images/destroy.ts delete mode 100644 src/actions/images/read.ts delete mode 100644 src/actions/images/update.ts delete mode 100644 src/actions/licenses/create.ts delete mode 100644 src/actions/licenses/destroy.ts delete mode 100644 src/actions/licenses/read.ts delete mode 100644 src/actions/licenses/update.ts delete mode 100644 src/actions/lockers/locations.ts delete mode 100644 src/actions/lockers/lockers.ts delete mode 100644 src/actions/lockers/reservations.ts delete mode 100644 src/actions/mail/alias/create.ts delete mode 100644 src/actions/mail/alias/destory.ts delete mode 100644 src/actions/mail/alias/read.ts delete mode 100644 src/actions/mail/alias/update.ts delete mode 100644 src/actions/mail/create.ts delete mode 100644 src/actions/mail/destroy.ts delete mode 100644 src/actions/mail/list/create.ts delete mode 100644 src/actions/mail/list/destory.ts delete mode 100644 src/actions/mail/list/update.ts delete mode 100644 src/actions/mail/mailAddressExternal/create.ts delete mode 100644 src/actions/mail/mailAddressExternal/destroy.ts delete mode 100644 src/actions/mail/mailAddressExternal/update.ts delete mode 100644 src/actions/mail/read.ts delete mode 100644 src/actions/news/create.ts delete mode 100644 src/actions/news/destroy.ts delete mode 100644 src/actions/news/read.ts delete mode 100644 src/actions/news/update.ts delete mode 100644 src/actions/notifications/index.ts delete mode 100644 src/actions/ombul/create.ts delete mode 100644 src/actions/ombul/destroy.ts delete mode 100644 src/actions/ombul/read.ts delete mode 100644 src/actions/ombul/update.ts delete mode 100644 src/actions/omegaOrder/create.ts delete mode 100644 src/actions/omegaOrder/read.ts delete mode 100644 src/actions/omegaid/generate.ts delete mode 100644 src/actions/omegaid/read.ts delete mode 100644 src/actions/omegaquotes/create.ts delete mode 100644 src/actions/omegaquotes/read.ts delete mode 100644 src/actions/permissions/index.ts delete mode 100644 src/actions/screens/authers.ts delete mode 100644 src/actions/screens/create.ts delete mode 100644 src/actions/screens/destroy.ts delete mode 100644 src/actions/screens/pages/create.ts delete mode 100644 src/actions/screens/pages/destroy.ts delete mode 100644 src/actions/screens/pages/read.ts delete mode 100644 src/actions/screens/pages/update.ts delete mode 100644 src/actions/screens/read.ts delete mode 100644 src/actions/screens/update.ts delete mode 100644 src/actions/sendmail/send.ts delete mode 100644 src/actions/shop/product.ts delete mode 100644 src/actions/shop/shop.ts delete mode 100644 src/actions/users/create.ts delete mode 100644 src/actions/users/destroy.ts delete mode 100644 src/actions/users/read.ts delete mode 100644 src/actions/users/update.ts delete mode 100644 src/actions/visibility/Types.ts delete mode 100644 src/actions/visibility/read.ts delete mode 100644 src/actions/visibility/update.ts diff --git a/src/actions/Types.ts b/src/actions/Types.ts deleted file mode 100644 index dcdff4409..000000000 --- a/src/actions/Types.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { ErrorMessage, ErrorCode } from '@/services/error' - -export type ActionReturnError = { - success: false, - errorCode: ErrorCode, - httpCode: number, - error?: ErrorMessage[], -} - -export type ActionReturn = ( - ActionReturnError -) | { - success: true, -} & ( - DataGuarantee extends true ? { - data: ReturnType - } : { - data?: ReturnType - } -) - -export type Action = (formData: FormData) => ( - Promise> -) diff --git a/src/actions/admission/create.ts b/src/actions/admission/create.ts deleted file mode 100644 index 667035e50..000000000 --- a/src/actions/admission/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { AdmissionMethods } from '@/services/admission/methods' -import { action } from '@/actions/action' - -export const createAdmissionTrialAction = action(AdmissionMethods.createTrial) diff --git a/src/actions/api-keys/create.ts b/src/actions/api-keys/create.ts deleted file mode 100644 index 5a423e788..000000000 --- a/src/actions/api-keys/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { ApiKeyMethods } from '@/services/api-keys/methods' - -export const createApiKeyAction = action(ApiKeyMethods.create) diff --git a/src/actions/api-keys/destroy.ts b/src/actions/api-keys/destroy.ts deleted file mode 100644 index 9733a0653..000000000 --- a/src/actions/api-keys/destroy.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { ApiKeyMethods } from '@/services/api-keys/methods' - -export const destroyApiKeyAction = action(ApiKeyMethods.destroy) diff --git a/src/actions/api-keys/read.ts b/src/actions/api-keys/read.ts deleted file mode 100644 index 8ed3511a3..000000000 --- a/src/actions/api-keys/read.ts +++ /dev/null @@ -1,6 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { ApiKeyMethods } from '@/services/api-keys/methods' - -export const readApiKeysAction = action(ApiKeyMethods.readMany) -export const readApiKeyAction = action(ApiKeyMethods.read) diff --git a/src/actions/api-keys/update.ts b/src/actions/api-keys/update.ts deleted file mode 100644 index 82b1a6f8d..000000000 --- a/src/actions/api-keys/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { ApiKeyMethods } from '@/services/api-keys/methods' - -export const updateApiKeyAction = action(ApiKeyMethods.update) diff --git a/src/actions/applications/create.ts b/src/actions/applications/create.ts deleted file mode 100644 index 38e82751a..000000000 --- a/src/actions/applications/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { ApplicationMethods } from '@/services/applications/methods' -import { action } from '@/actions/action' - -export const createApplicationAction = action(ApplicationMethods.create) diff --git a/src/actions/applications/destroy.ts b/src/actions/applications/destroy.ts deleted file mode 100644 index 4c406f12a..000000000 --- a/src/actions/applications/destroy.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { ApplicationMethods } from '@/services/applications/methods' - -export const destroyApplicationAction = action(ApplicationMethods.destroy) diff --git a/src/actions/applications/periods/create.ts b/src/actions/applications/periods/create.ts deleted file mode 100644 index 7ea51d868..000000000 --- a/src/actions/applications/periods/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { ApplicationPeriodMethods } from '@/services/applications/periods/methods' - -export const createApplicationPeriodAction = action(ApplicationPeriodMethods.create) diff --git a/src/actions/applications/periods/destroy.ts b/src/actions/applications/periods/destroy.ts deleted file mode 100644 index 7af055abc..000000000 --- a/src/actions/applications/periods/destroy.ts +++ /dev/null @@ -1,6 +0,0 @@ -'use server' -import { ApplicationPeriodMethods } from '@/services/applications/periods/methods' -import { action } from '@/actions/action' - -export const destroyApplicationPeriodAction = action(ApplicationPeriodMethods.destroy) -export const removeAllApplicationTextsAction = action(ApplicationPeriodMethods.removeAllApplicationTexts) diff --git a/src/actions/applications/periods/read.ts b/src/actions/applications/periods/read.ts deleted file mode 100644 index 78d1e8521..000000000 --- a/src/actions/applications/periods/read.ts +++ /dev/null @@ -1,7 +0,0 @@ -'use server' -import { ApplicationPeriodMethods } from '@/services/applications/periods/methods' -import { action } from '@/actions/action' - -export const readApplicationPeriodsAction = action(ApplicationPeriodMethods.readAll) -export const readApplicationPeriodAction = action(ApplicationPeriodMethods.read) -export const readNumberOfApplicationsAction = action(ApplicationPeriodMethods.readNumberOfApplications) diff --git a/src/actions/applications/periods/update.ts b/src/actions/applications/periods/update.ts deleted file mode 100644 index 0ab295162..000000000 --- a/src/actions/applications/periods/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { ApplicationPeriodMethods } from '@/services/applications/periods/methods' -import { action } from '@/actions/action' - -export const updateApplicationPeriodAction = action(ApplicationPeriodMethods.update) diff --git a/src/actions/applications/read.ts b/src/actions/applications/read.ts deleted file mode 100644 index d87f4f4d2..000000000 --- a/src/actions/applications/read.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { ApplicationMethods } from '@/services/applications/methods' - -export const readApplicationsForUserAction = action(ApplicationMethods.readForUser) diff --git a/src/actions/applications/update.ts b/src/actions/applications/update.ts deleted file mode 100644 index 6b576cfc3..000000000 --- a/src/actions/applications/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { ApplicationMethods } from '@/services/applications/methods' -import { action } from '@/actions/action' - -export const updateApplicationAction = action(ApplicationMethods.update) diff --git a/src/actions/auth/auth.ts b/src/actions/auth/auth.ts deleted file mode 100644 index f391b6325..000000000 --- a/src/actions/auth/auth.ts +++ /dev/null @@ -1,8 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { AuthMethods } from '@/services/auth/methods' - -export const verifyResetPasswordTokenAction = action(AuthMethods.verifyResetPasswordToken) -export const resetPasswordAction = action(AuthMethods.resetPassword) -export const sendResetPasswordEmailAction = action(AuthMethods.sendResetPasswordEmail) -export const verifyEmailAction = action(AuthMethods.verifyEmail) diff --git a/src/actions/bind.ts b/src/actions/bind.ts deleted file mode 100644 index 322337999..000000000 --- a/src/actions/bind.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * A simple utility function to bind parameters to an action. - * Under the hood this function simply calls "action.bind(null, params)", - * but it is more readable to use this function. - * - * @param action - An action that takes parameters. - * @param params - The parameters to bind to the action. - * @returns - The same action with the parameters bound to it. - */ -export function bindParams(action: (p: P, ...dataArgs: D) => R, params: P) { - return action.bind(null, params) -} - -/** - * A simple utility function to bind data to an action. - * Under the hood this function simply calls "action.bind(null, data)", - * but it is more readable to use this function. - * - * @param action - An action that takes data. - * @param bindData - The data to bind to the action. - * @returns - The same action with the data bound to it. - */ -export function bindData(action: (dataValue: D) => R, data: D) { - return action.bind(null, data) -} diff --git a/src/actions/cabin/index.ts b/src/actions/cabin/index.ts deleted file mode 100644 index 360c65457..000000000 --- a/src/actions/cabin/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { CabinBookingMethods } from '@/services/cabin/booking/methods' -import { CabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' -import { CabinProductMethods } from '@/services/cabin/product/methods' -import { CabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' - -export const createReleasePeriodAction = action(CabinReleasePeriodMethods.create) -export const readReleasePeriodsAction = action(CabinReleasePeriodMethods.readMany) -export const updateReleasePeriodAction = action(CabinReleasePeriodMethods.update) -export const destroyReleasePeriodAction = action(CabinReleasePeriodMethods.destroy) - -export const createPricePeriodAction = action(CabinPricePeriodMethods.create) -export const destoryPricePeriodAction = action(CabinPricePeriodMethods.destroy) -export const readPricePeriodsAction = action(CabinPricePeriodMethods.readMany) -export const readPublicPricePeriodsAction = action(CabinPricePeriodMethods.readPublicPeriods) -export const readUnreleasedPricePeriodsAction = action(CabinPricePeriodMethods.readUnreleasedPeriods) - -export const createCabinBookingUserAttachedAction = action(CabinBookingMethods.createCabinBookingUserAttached) -export const createBedBookingUserAttachedAction = action(CabinBookingMethods.createBedBookingUserAttached) -export const createCabinBookingNoUserAction = action(CabinBookingMethods.createCabinBookingNoUser) -export const createBedBookingNoUserAction = action(CabinBookingMethods.createBedBookingNoUser) -export const readCabinAvailabilityAction = action(CabinBookingMethods.readAvailability) -export const readCabinBookingsAction = action(CabinBookingMethods.readMany) -export const readCabinBookingAction = action(CabinBookingMethods.read) - -export const readCabinProductsAction = action(CabinProductMethods.readMany) -export const readCabinProductsActiveAction = action(CabinProductMethods.readActive) -export const readCabinProductAction = action(CabinProductMethods.read) -export const createCabinProductAction = action(CabinProductMethods.create) -export const createCabinProductPriceAction = action(CabinProductMethods.createPrice) diff --git a/src/actions/career/companies/create.ts b/src/actions/career/companies/create.ts deleted file mode 100644 index a0da9c443..000000000 --- a/src/actions/career/companies/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { CompanyMethods } from '@/services/career/companies/methods' - -export const createCompanyAction = action(CompanyMethods.create) diff --git a/src/actions/career/companies/destroy.ts b/src/actions/career/companies/destroy.ts deleted file mode 100644 index b92d1f595..000000000 --- a/src/actions/career/companies/destroy.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { CompanyMethods } from '@/services/career/companies/methods' - -export const destroyCompanyAction = action(CompanyMethods.destroy) diff --git a/src/actions/career/companies/read.ts b/src/actions/career/companies/read.ts deleted file mode 100644 index 0716b6876..000000000 --- a/src/actions/career/companies/read.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { CompanyMethods } from '@/services/career/companies/methods' - -export const readCompanyPageAction = action(CompanyMethods.readPage) diff --git a/src/actions/career/companies/update.ts b/src/actions/career/companies/update.ts deleted file mode 100644 index fc1639e68..000000000 --- a/src/actions/career/companies/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { CompanyMethods } from '@/services/career/companies/methods' - -export const updateComanyAction = action(CompanyMethods.update) diff --git a/src/actions/career/jobAds/create.ts b/src/actions/career/jobAds/create.ts deleted file mode 100644 index 146939c51..000000000 --- a/src/actions/career/jobAds/create.ts +++ /dev/null @@ -1,6 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { JobadMethods } from '@/services/career/jobAds/methods' - -export const createJobAdAction = action(JobadMethods.create) - diff --git a/src/actions/career/jobAds/destroy.ts b/src/actions/career/jobAds/destroy.ts deleted file mode 100644 index 2f3583458..000000000 --- a/src/actions/career/jobAds/destroy.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { JobadMethods } from '@/services/career/jobAds/methods' - -export const destroyJobAdAction = action(JobadMethods.destroy) diff --git a/src/actions/career/jobAds/read.ts b/src/actions/career/jobAds/read.ts deleted file mode 100644 index 4cb4f75b6..000000000 --- a/src/actions/career/jobAds/read.ts +++ /dev/null @@ -1,7 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { JobadMethods } from '@/services/career/jobAds/methods' - -export const readJobAdAction = action(JobadMethods.read) -export const readActiveJobAdsAction = action(JobadMethods.readActive) -export const readInactiveJobAdsPageAction = action(JobadMethods.readInactivePage) diff --git a/src/actions/career/jobAds/update.ts b/src/actions/career/jobAds/update.ts deleted file mode 100644 index 666d1b5a8..000000000 --- a/src/actions/career/jobAds/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { JobadMethods } from '@/services/career/jobAds/methods' - -export const updateJobAdAction = action(JobadMethods.update) diff --git a/src/actions/cms/articleCategories/create.ts b/src/actions/cms/articleCategories/create.ts deleted file mode 100644 index db0ac7686..000000000 --- a/src/actions/cms/articleCategories/create.ts +++ /dev/null @@ -1,19 +0,0 @@ -'use server' -import { createZodActionError } from '@/actions/error' -import { createArticleCategory } from '@/services/cms/articleCategories/create' -import { safeServerCall } from '@/actions/safeServerCall' -import { createArticleCategoryValidation } from '@/services/cms/articleCategories/validation' -import type { CreateArticleCategoryTypes } from '@/services/cms/articleCategories/validation' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedArticleCategory } from '@/cms/articleCategories/Types' - -export async function createArticleCategoryAction( - rawData: FormData | CreateArticleCategoryTypes['Type'] -): Promise> { - //TODO: check permission - const parse = createArticleCategoryValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createArticleCategory(data)) -} diff --git a/src/actions/cms/articleCategories/destroy.ts b/src/actions/cms/articleCategories/destroy.ts deleted file mode 100644 index 0f1d2777a..000000000 --- a/src/actions/cms/articleCategories/destroy.ts +++ /dev/null @@ -1,10 +0,0 @@ -'use server' -import { destroyArticleCategory } from '@/services/cms/articleCategories/destroy' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ExpandedArticleCategory } from '@/cms/articleCategories/Types' -import type { ActionReturn } from '@/actions/Types' - -export async function destroyArticleCategoryAction(id: number): Promise> { - // TODO: Cheek for visibility type edit of user. - return await safeServerCall(() => destroyArticleCategory(id)) -} diff --git a/src/actions/cms/articleCategories/read.ts b/src/actions/cms/articleCategories/read.ts deleted file mode 100644 index 565d08268..000000000 --- a/src/actions/cms/articleCategories/read.ts +++ /dev/null @@ -1,18 +0,0 @@ -'use server' -import { readArticleCategories, readArticleCategory } from '@/services/cms/articleCategories/read' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { - ExpandedArticleCategoryWithCover, - ArticleCategoryWithCover, -} from '@/cms/articleCategories/Types' - -export async function readArticleCategoriesAction(): Promise> { - //TODO: only read categories that user has visibility - return await safeServerCall(() => readArticleCategories()) -} - -export async function readArticleCategoryAction(name: string): Promise> { - //TODO: only read if right visibility - return await safeServerCall(() => readArticleCategory(name)) -} diff --git a/src/actions/cms/articleCategories/update.ts b/src/actions/cms/articleCategories/update.ts deleted file mode 100644 index bb04c9d2d..000000000 --- a/src/actions/cms/articleCategories/update.ts +++ /dev/null @@ -1,29 +0,0 @@ -'use server' -import { createZodActionError } from '@/actions/error' -import { updateArticleCategory } from '@/services/cms/articleCategories/update' -import { safeServerCall } from '@/actions/safeServerCall' -import { updateArticleCategoryValidation } from '@/services/cms/articleCategories/validation' -import type { UpdateArticleCategoryTypes } from '@/services/cms/articleCategories/validation' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedArticleCategory } from '@/cms/articleCategories/Types' - -export async function updateArticleCategoryVisibilityAction( - // disable eslint rule temporarily until function is implemented - // eslint-disable-next-line @typescript-eslint/no-unused-vars - id: number, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - visibility: unknown -): Promise> { - throw new Error('Not implemented') -} - -export async function updateArticleCategoryAction( - id: number, - rawData: FormData | UpdateArticleCategoryTypes['Type'] -): Promise> { - const parse = updateArticleCategoryValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => updateArticleCategory(id, data)) -} diff --git a/src/actions/cms/articleSections/create.ts b/src/actions/cms/articleSections/create.ts deleted file mode 100644 index 43bb6fe0e..000000000 --- a/src/actions/cms/articleSections/create.ts +++ /dev/null @@ -1,19 +0,0 @@ -'use server' -import { createArticleSection } from '@/services/cms/articleSections/create' -import { safeServerCall } from '@/actions/safeServerCall' -import { createZodActionError } from '@/actions/error' -import { createArticleSectionValidation } from '@/services/cms/articleSections/validation' -import type { CreateArticleSectionTypes } from '@/services/cms/articleSections/validation' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedArticleSection } from '@/cms/articleSections/Types' - -export async function createArticleSectionAction( - rawData: FormData | CreateArticleSectionTypes['Type'], -): Promise> { - //TODO: Auth on general cms permission - const parse = createArticleSectionValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createArticleSection(data)) -} diff --git a/src/actions/cms/articleSections/destroy.ts b/src/actions/cms/articleSections/destroy.ts deleted file mode 100644 index 625c14f2a..000000000 --- a/src/actions/cms/articleSections/destroy.ts +++ /dev/null @@ -1,10 +0,0 @@ -'use server' -import { destroyArticleSection } from '@/services/cms/articleSections/destroy' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { ArticleSection } from '@prisma/client' - -export async function destroyArticleSectionAction(nameOrId: string): Promise> { - //Auth by visibility - return await safeServerCall(() => destroyArticleSection(nameOrId)) -} diff --git a/src/actions/cms/articleSections/read.ts b/src/actions/cms/articleSections/read.ts deleted file mode 100644 index 9b52c0ef1..000000000 --- a/src/actions/cms/articleSections/read.ts +++ /dev/null @@ -1,10 +0,0 @@ -'use server' -import { readArticleSection } from '@/services/cms/articleSections/read' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedArticleSection } from '@/cms/articleSections/Types' - -export async function readArticleSectionAction(name: string): Promise> { - //TODO: Auth by visibility - return await safeServerCall(() => readArticleSection(name)) -} diff --git a/src/actions/cms/articleSections/update.ts b/src/actions/cms/articleSections/update.ts deleted file mode 100644 index 08594e9df..000000000 --- a/src/actions/cms/articleSections/update.ts +++ /dev/null @@ -1,31 +0,0 @@ -'use server' -import { addArticleSectionPart, removeArticleSectionPart, updateArticleSection } from '@/services/cms/articleSections/update' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ArticleSection, Position } from '@prisma/client' -import type { ArticleSectionPart, ExpandedArticleSection } from '@/cms/articleSections/Types' -import type { ActionReturn } from '@/actions/Types' - - -export async function updateArticleSectionAction(name: string, changes: { - imageSize?: number, - imagePosition?: Position, -}): Promise> { - //Todo: Auth by visibilty - return await safeServerCall(() => updateArticleSection(name, changes)) -} - -export async function addArticleSectionPartAction( - name: string, - part: ArticleSectionPart -): Promise> { - //Todo: Auth by visibilty - return await safeServerCall(() => addArticleSectionPart(name, part)) -} - -export async function removeArticleSectionPartAction( - name: string, - part: ArticleSectionPart -): Promise> { - //TODO: Auth by visibility - return await safeServerCall(() => removeArticleSectionPart(name, part)) -} diff --git a/src/actions/cms/articles/create.ts b/src/actions/cms/articles/create.ts deleted file mode 100644 index 34de74837..000000000 --- a/src/actions/cms/articles/create.ts +++ /dev/null @@ -1,21 +0,0 @@ -'use server' -import { createArticle } from '@/services/cms/articles/create' -import { safeServerCall } from '@/actions/safeServerCall' -import { createZodActionError } from '@/actions/error' -import { createArticleValidation } from '@/services/cms/articles/validation' -import type { CreateArticleTypes } from '@/services/cms/articles/validation' -import type { ExpandedArticle } from '@/cms/articles/Types' -import type { ActionReturn } from '@/actions/Types' - -export async function createArticleAction( - rawData: FormData | CreateArticleTypes['Type'], - categoryId?: number, -): Promise> { - //TODO: auth on permission or visibility to categoryId - - const parse = createArticleValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createArticle(data, categoryId)) -} diff --git a/src/actions/cms/articles/destroy.ts b/src/actions/cms/articles/destroy.ts deleted file mode 100644 index 24c846f1d..000000000 --- a/src/actions/cms/articles/destroy.ts +++ /dev/null @@ -1,10 +0,0 @@ -'use server' -import { destroyArticle } from '@/services/cms/articles/destroy' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { Article } from '@prisma/client' - -export async function destroyArticleAction(id: number): Promise> { - //TODO: auth - return await safeServerCall(() => destroyArticle(id)) -} diff --git a/src/actions/cms/articles/read.ts b/src/actions/cms/articles/read.ts deleted file mode 100644 index 03db6231c..000000000 --- a/src/actions/cms/articles/read.ts +++ /dev/null @@ -1,13 +0,0 @@ -'use server' -import { readArticle } from '@/services/cms/articles/read' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ExpandedArticle } from '@/cms/articles/Types' -import type { ActionReturn } from '@/actions/Types' - -export async function readArticleAction(idOrName: number | { - name: string, - category: string -}): Promise> { - //TODO: auth - return await safeServerCall(() => readArticle(idOrName)) -} diff --git a/src/actions/cms/articles/update.ts b/src/actions/cms/articles/update.ts deleted file mode 100644 index f86905561..000000000 --- a/src/actions/cms/articles/update.ts +++ /dev/null @@ -1,39 +0,0 @@ -'use server' -import { createZodActionError } from '@/actions/error' -import { addSectionToArticle, moveSectionOrder, updateArticle } from '@/services/cms/articles/update' -import { safeServerCall } from '@/actions/safeServerCall' -import { updateArticleValidation } from '@/services/cms/articles/validation' -import type { UpdateArticleTypes } from '@/services/cms/articles/validation' -import type { ArticleSectionPart } from '@/services/cms/articleSections/Types' -import type { ActionReturn } from '@/actions/Types' -import type { ArticleSection } from '@prisma/client' -import type { ExpandedArticle } from '@/cms/articles/Types' - -export async function updateArticleAction( - id: number, - rawData: FormData | UpdateArticleTypes['Type'] -): Promise> { - //TODO: auth on visability - const parse = updateArticleValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => updateArticle(id, data)) -} - -export async function addSectionToArticleAction( - id: number, - include: Partial> -): Promise> { - //TODO: auth on visability - return await safeServerCall(() => addSectionToArticle(id, include)) -} - -export async function moveSectionOrderAction( - id: number, - sectionId: number, - direction: 'UP' | 'DOWN' -): Promise> { - //TODO: auth on visability - return await safeServerCall(() => moveSectionOrder(id, sectionId, direction)) -} diff --git a/src/actions/cms/images/create.ts b/src/actions/cms/images/create.ts deleted file mode 100644 index 46d7108b2..000000000 --- a/src/actions/cms/images/create.ts +++ /dev/null @@ -1,21 +0,0 @@ -'use server' -import { createCmsImageActionValidation } from './validation' -import { safeServerCall } from '@/actions/safeServerCall' -import { createCmsImage } from '@/services/cms/images/create' -import { createZodActionError } from '@/actions/error' -import type { CreateCmsImageActionTypes } from './validation' -import type { Image } from '@prisma/client' -import type { ExpandedCmsImage } from '@/services/cms/images/Types' -import type { ActionReturn } from '@/actions/Types' - -export async function createCmsImageAction( - rawData: FormData | CreateCmsImageActionTypes['Type'], - image?: Image, -): Promise> { - //TODO: Auth route (very few people should be able to create stand alone cmsImages...) - const parse = createCmsImageActionValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createCmsImage(data, image)) -} diff --git a/src/actions/cms/images/read.ts b/src/actions/cms/images/read.ts deleted file mode 100644 index b4f15f607..000000000 --- a/src/actions/cms/images/read.ts +++ /dev/null @@ -1,42 +0,0 @@ -'use server' -import { createActionError } from '@/actions/error' -import { readCmsImage, readSpecialCmsImage } from '@/services/cms/images/read' -import { createCmsImage } from '@/services/cms/images/create' -import { safeServerCall } from '@/actions/safeServerCall' -import { SpecialCmsImage } from '@prisma/client' -import type { ExpandedCmsImage } from '@/cms/images/Types' -import type { ActionReturn } from '@/actions/Types' - -/** - * A action to read a cms image including the image associated with it - * @param name - name of the cms image the image - * @returns - */ -export async function readCmsImageAction(name: string): Promise> { - //TODO: auth on visibilty - return await safeServerCall(() => readCmsImage(name)) -} - -/** - * Action to reads a special cmsImage, if it does not exist it creates it - * @param special SpecialCmsImage - * @returns ActionReturn - */ -export async function readSpecialCmsImageAction(special: SpecialCmsImage): Promise> { - if (!Object.values(SpecialCmsImage).includes(special)) { - return createActionError('BAD PARAMETERS', `${special} is not special`) - } - const specialRes = await safeServerCall(() => readSpecialCmsImage(special)) - if (!specialRes.success) { - if (specialRes.errorCode === 'NOT FOUND') { - return await safeServerCall(() => createCmsImage({ - name: special, - special, - })) - } - return specialRes - } - const cmsImage = specialRes.data - //TODO: Auth on visibilty - return { success: true, data: cmsImage } -} diff --git a/src/actions/cms/images/update.ts b/src/actions/cms/images/update.ts deleted file mode 100644 index f3175c2a1..000000000 --- a/src/actions/cms/images/update.ts +++ /dev/null @@ -1,18 +0,0 @@ -'use server' -import { updateCmsImage, updateCmsImageConfig } from '@/services/cms/images/update' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ActionReturn } from '@/actions/Types' -import type { CmsImage, ImageSize } from '@prisma/client' - -export async function updateCmsImageAction(cmsImageId: number, imageId: number): Promise> { - //TODO: Auth on visibility (or permission if special) - return await safeServerCall(() => updateCmsImage(cmsImageId, imageId)) -} - -export async function updateCmsImageConfigAction( - cmsImageId: number, - config: {imageSize: ImageSize} -): Promise> { - //TODO: Auth on visibility (or permission if special) - return await safeServerCall(() => updateCmsImageConfig(cmsImageId, config)) -} diff --git a/src/actions/cms/images/validation.ts b/src/actions/cms/images/validation.ts deleted file mode 100644 index d793e0682..000000000 --- a/src/actions/cms/images/validation.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { baseCmsImageValidation } from '@/services/cms/images/validation' -import type { ValidationTypes } from '@/services/Validation' - -export const createCmsImageActionValidation = baseCmsImageValidation.createValidation({ - keys: ['name'], - transformer: data => data, -}) -export type CreateCmsImageActionTypes = ValidationTypes diff --git a/src/actions/cms/links/create.ts b/src/actions/cms/links/create.ts deleted file mode 100644 index 28ea570d0..000000000 --- a/src/actions/cms/links/create.ts +++ /dev/null @@ -1,19 +0,0 @@ -'use server' -import { createCmsLink } from '@/services/cms/links/create' -import { safeServerCall } from '@/actions/safeServerCall' -import { createCmsLinkValidation } from '@/services/cms/links/validation' -import { createZodActionError } from '@/actions/error' -import type { CreateCmsLinkTypes } from '@/services/cms/links/validation' -import type { ActionReturn } from '@/actions/Types' -import type { CmsLink } from '@prisma/client' - -export async function createCmsLinkAction( - rawData: FormData | CreateCmsLinkTypes['Type'] -): Promise> { - //TODO: Auth on permission to create cms - const parse = createCmsLinkValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createCmsLink(data)) -} diff --git a/src/actions/cms/links/read.ts b/src/actions/cms/links/read.ts deleted file mode 100644 index 6b2d71b78..000000000 --- a/src/actions/cms/links/read.ts +++ /dev/null @@ -1,6 +0,0 @@ -'use server' - -import { action } from '@/actions/action' -import { readSpecialCmsLink } from '@/services/cms/links/read' - -export const readSpecialCmsLinkAction = action(readSpecialCmsLink) diff --git a/src/actions/cms/links/update.ts b/src/actions/cms/links/update.ts deleted file mode 100644 index ba5e728ec..000000000 --- a/src/actions/cms/links/update.ts +++ /dev/null @@ -1,22 +0,0 @@ -'use server' -import { createZodActionError } from '@/actions/error' -import { updateCmsLink } from '@/services/cms/links/update' -import { safeServerCall } from '@/actions/safeServerCall' -import { updateCmsLinkValidation } from '@/services/cms/links/validation' -import type { UpdateCmsLinkTypes } from '@/services/cms/links/validation' -import type { CmsLink } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' - -export async function updateCmsLinkAction( - id: number, - rawData: FormData | UpdateCmsLinkTypes['Type'] -): Promise> { - //TODO: auth on visibility - const parse = updateCmsLinkValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - if (data.url && data.url.includes('.') && !data.url.startsWith('http://') && !data.url.startsWith('https://')) { - data.url = `https://${data.url}` - } - return await safeServerCall(() => updateCmsLink(id, data)) -} diff --git a/src/actions/cms/paragraphs/create.ts b/src/actions/cms/paragraphs/create.ts deleted file mode 100644 index 5eff7631e..000000000 --- a/src/actions/cms/paragraphs/create.ts +++ /dev/null @@ -1,19 +0,0 @@ -'use server' -import { createCmsParagraphActionValidation } from './validation' -import { createCmsParagraph } from '@/services/cms/paragraphs/create' -import { safeServerCall } from '@/actions/safeServerCall' -import { createZodActionError } from '@/actions/error' -import type { CreateCmsParagraphActionTypes } from './validation' -import type { CmsParagraph } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' - -export async function createCmsParagraphAction( - rawData: FormData | CreateCmsParagraphActionTypes['Type'] -): Promise> { - //TDOD: Auth on cms permission (few should be able to create a paragraph standalone) - const parse = createCmsParagraphActionValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createCmsParagraph(data)) -} diff --git a/src/actions/cms/paragraphs/read.ts b/src/actions/cms/paragraphs/read.ts deleted file mode 100644 index f485398be..000000000 --- a/src/actions/cms/paragraphs/read.ts +++ /dev/null @@ -1,34 +0,0 @@ -'use server' -import { createCmsParagraph } from '@/services/cms/paragraphs/create' -import { createActionError } from '@/actions/error' -import { readCmsParagraph, readSpecialCmsParagraph } from '@/services/cms/paragraphs/read' -import { safeServerCall } from '@/actions/safeServerCall' -import { SpecialCmsParagraph } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' -import type { CmsParagraph } from '@prisma/client' - -export async function readCmsParagraphAction(name: string): Promise> { - //TODO: Auth on visibility (or permission if special) - return await safeServerCall(() => readCmsParagraph(name)) -} - -/** - * This action reads a special paragraph from the database, if it does not exist it will create it - * @param special - special paragraph to read - * @returns - the paragraph - */ -export async function readSpecialCmsParagraphAction(special: SpecialCmsParagraph): Promise> { - if (!Object.values(SpecialCmsParagraph).includes(special)) { - return createActionError('BAD PARAMETERS', `${special} is not special`) - } - - const specialRes = await safeServerCall(() => readSpecialCmsParagraph(special)) - if (specialRes.success) return specialRes - if (specialRes.errorCode === 'NOT FOUND') { - return await safeServerCall(() => createCmsParagraph({ - name: special, - special, - })) - } - return specialRes -} diff --git a/src/actions/cms/paragraphs/update.ts b/src/actions/cms/paragraphs/update.ts deleted file mode 100644 index cc0b4392f..000000000 --- a/src/actions/cms/paragraphs/update.ts +++ /dev/null @@ -1,10 +0,0 @@ -'use server' -import { updateCmsParagraphContents } from '@/services/cms/paragraphs/update' -import { safeServerCall } from '@/actions/safeServerCall' -import type { CmsParagraph } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' - -export async function updateCmsParagraphAction(id: number, contentMd: string): Promise> { - //TODO: Auth on visibility - return await safeServerCall(() => updateCmsParagraphContents(id, contentMd)) -} diff --git a/src/actions/cms/paragraphs/validation.ts b/src/actions/cms/paragraphs/validation.ts deleted file mode 100644 index c3ba2f115..000000000 --- a/src/actions/cms/paragraphs/validation.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { baseCmsParagraphValidation } from '@/services/cms/paragraphs/validation' -import type { ValidationTypes } from '@/services/Validation' - -export const createCmsParagraphActionValidation = baseCmsParagraphValidation.createValidation({ - keys: ['name'], - transformer: data => data -}) - -export type CreateCmsParagraphActionTypes = ValidationTypes diff --git a/src/actions/dots/create.ts b/src/actions/dots/create.ts deleted file mode 100644 index 460b05600..000000000 --- a/src/actions/dots/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { dotMethods } from '@/services/dots/methods' - -export const createDotAction = action(dotMethods.create) diff --git a/src/actions/dots/read.ts b/src/actions/dots/read.ts deleted file mode 100644 index 13ec99611..000000000 --- a/src/actions/dots/read.ts +++ /dev/null @@ -1,7 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { dotMethods } from '@/services/dots/methods' - -export const readDotPageAction = action(dotMethods.readPage) - -export const readDotWrappersForUserAction = action(dotMethods.readWrappersForUser) diff --git a/src/actions/education/courses/create.ts b/src/actions/education/courses/create.ts deleted file mode 100644 index 59a175d55..000000000 --- a/src/actions/education/courses/create.ts +++ /dev/null @@ -1,8 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import type { CreateCourseTypes } from '@/education/courses/validation' - -export async function createCourseAction(rawdata: FormData | CreateCourseTypes['Type']) { - console.log('createCourseAction', rawdata) - return safeServerCall(async () => ({ success: false })) -} diff --git a/src/actions/education/schools/create.ts b/src/actions/education/schools/create.ts deleted file mode 100644 index bc74cf281..000000000 --- a/src/actions/education/schools/create.ts +++ /dev/null @@ -1,24 +0,0 @@ -'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { getUser } from '@/auth/getUser' -import { createSchoolValidation } from '@/education/schools/validation' -import { safeServerCall } from '@/actions/safeServerCall' -import { createSchool } from '@/services/education/schools/create' -import type { SchoolFiltered } from '@/education/schools/Types' -import type { ActionReturn } from '@/actions/Types' -import type { CreateSchoolTypes } from '@/education/schools/validation' - -export async function createSchoolAction( - rawdata: FormData | CreateSchoolTypes['Type'] -): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCHOOLS_ADMIN']] - }) - if (!authorized) return createActionError(status) - - const parse = createSchoolValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createSchool(data)) -} diff --git a/src/actions/education/schools/destroy.ts b/src/actions/education/schools/destroy.ts deleted file mode 100644 index 5b61aa7d5..000000000 --- a/src/actions/education/schools/destroy.ts +++ /dev/null @@ -1,15 +0,0 @@ -'use server' -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { destroySchool } from '@/services/education/schools/destroy' -import type { ActionReturn } from '@/actions/Types' - -export async function destroySchoolAction(id: number): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCHOOLS_ADMIN']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => destroySchool(id)) -} diff --git a/src/actions/education/schools/read.ts b/src/actions/education/schools/read.ts deleted file mode 100644 index 72ae3ba3d..000000000 --- a/src/actions/education/schools/read.ts +++ /dev/null @@ -1,50 +0,0 @@ -'use server' -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { readSchool, readSchools, readSchoolsPage, readStandardSchools } from '@/services/education/schools/read' -import { getUser } from '@/auth/getUser' -import type { ReadPageInput } from '@/lib/paging/Types' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedSchool, SchoolCursor, SchoolFiltered } from '@/education/schools/Types' - -export async function readSchoolsPageAction( - pageReadInput: ReadPageInput -): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCHOOLS_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readSchoolsPage(pageReadInput)) -} - -export async function readStandardSchoolsAction(): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCHOOLS_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readStandardSchools()) -} - -export async function readSchoolsAction({ - onlyNonStandard -}: { - onlyNonStandard: boolean -}): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCHOOLS_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readSchools({ onlyNonStandard })) -} - -export async function readSchoolAction(shortname: string): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCHOOLS_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readSchool(shortname)) -} diff --git a/src/actions/education/schools/update.ts b/src/actions/education/schools/update.ts deleted file mode 100644 index 6cb7279eb..000000000 --- a/src/actions/education/schools/update.ts +++ /dev/null @@ -1,25 +0,0 @@ -'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { updateSchoolValidation } from '@/education/schools/validation' -import { updateSchool } from '@/services/education/schools/update' -import type { ActionReturn } from '@/actions/Types' -import type { UpdateSchoolTypes } from '@/education/schools/validation' -import type { SchoolFiltered } from '@/education/schools/Types' - -export async function updateSchoolAction( - id: number, - rawdata: FormData | UpdateSchoolTypes['Type'] -): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCHOOLS_ADMIN']] - }) - if (!authorized) return createActionError(status) - - const parse = updateSchoolValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => updateSchool(id, data)) -} diff --git a/src/actions/error.ts b/src/actions/error.ts deleted file mode 100644 index 2f26be65c..000000000 --- a/src/actions/error.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { errorCodes, type ErrorCode, type ErrorMessage } from '@/services/error' -import type { AuthStatus } from '@/auth/getUser' -import type { SafeParseError } from 'zod' -import type { ActionReturnError } from './Types' - -export function createActionError(errorCode: ErrorCode | AuthStatus, error?: string | ErrorMessage[]): ActionReturnError { - if (errorCode === 'AUTHORIZED' || errorCode === 'AUTHORIZED_NO_USER') { - return { - success: false, - errorCode: 'UNKNOWN ERROR', - httpCode: 500, - error: typeof error === 'string' ? [{ message: error }] : error, - } - } - return { - success: false, - errorCode, - httpCode: errorCodes.find(e => e.name === errorCode)?.httpCode ?? 500, - error: typeof error === 'string' ? [{ message: error }] : error, - } -} - -export function createZodActionError(parse: SafeParseError): ActionReturnError { - return { - success: false, - httpCode: 400, - errorCode: 'BAD PARAMETERS', - error: parse.error.issues, - } -} - diff --git a/src/actions/events/create.ts b/src/actions/events/create.ts deleted file mode 100644 index b25456029..000000000 --- a/src/actions/events/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { EventMethods } from '@/services/events/methods' - -export const createEventAction = action(EventMethods.create) diff --git a/src/actions/events/destroy.ts b/src/actions/events/destroy.ts deleted file mode 100644 index ea7b77fff..000000000 --- a/src/actions/events/destroy.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { EventMethods } from '@/services/events/methods' - -export const destroyEventAction = action(EventMethods.destroy) diff --git a/src/actions/events/read.ts b/src/actions/events/read.ts deleted file mode 100644 index 25fc3a037..000000000 --- a/src/actions/events/read.ts +++ /dev/null @@ -1,7 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { EventMethods } from '@/services/events/methods' - -export const readCurrentEventsAction = action(EventMethods.readManyCurrent) -export const readEventAction = action(EventMethods.read) -export const readArchivedEventsPageAction = action(EventMethods.readManyArchivedPage) diff --git a/src/actions/events/registration/index.ts b/src/actions/events/registration/index.ts deleted file mode 100644 index 0a22860c5..000000000 --- a/src/actions/events/registration/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -'use server' - -import { action } from '@/actions/action' -import { EventRegistrationMethods } from '@/services/events/registration/methods' - - -export const createEventRegistrationAction = action(EventRegistrationMethods.create) -export const createGuestEventRegistrationAction = action(EventRegistrationMethods.createGuest) -export const readManyEventRegistrationAction = action(EventRegistrationMethods.readMany) -export const eventRegistrationReadManyDetailedAction = action(EventRegistrationMethods.readManyDetailed) -export const eventRegistrationUpdateNotesAction = action(EventRegistrationMethods.updateNotes) -export const eventRegistrationDestroyAction = action(EventRegistrationMethods.destroy) diff --git a/src/actions/events/tags/create.ts b/src/actions/events/tags/create.ts deleted file mode 100644 index 0fadff21f..000000000 --- a/src/actions/events/tags/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { EventTagMethods } from '@/services/events/tags/methods' - -export const createEventTagAction = action(EventTagMethods.create) diff --git a/src/actions/events/tags/destroy.ts b/src/actions/events/tags/destroy.ts deleted file mode 100644 index f5c5390c0..000000000 --- a/src/actions/events/tags/destroy.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { EventTagMethods } from '@/services/events/tags/methods' - -export const destroyEventTagAction = action(EventTagMethods.destroy) diff --git a/src/actions/events/tags/read.ts b/src/actions/events/tags/read.ts deleted file mode 100644 index 8afec51fa..000000000 --- a/src/actions/events/tags/read.ts +++ /dev/null @@ -1,7 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { EventTagMethods } from '@/services/events/tags/methods' - -export const readEventTagsAction = action(EventTagMethods.readAll) -export const readSpecialEventTagAction = action(EventTagMethods.readSpecial) -export const readEventTagAction = action(EventTagMethods.read) diff --git a/src/actions/events/tags/update.ts b/src/actions/events/tags/update.ts deleted file mode 100644 index 8c237f4ef..000000000 --- a/src/actions/events/tags/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { EventTagMethods } from '@/services/events/tags/methods' - -export const updateEventTagAction = action(EventTagMethods.update) diff --git a/src/actions/events/update.ts b/src/actions/events/update.ts deleted file mode 100644 index e8f80a787..000000000 --- a/src/actions/events/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { EventMethods } from '@/services/events/methods' - -export const updateEventAction = action(EventMethods.update) diff --git a/src/actions/groups/committees/create.ts b/src/actions/groups/committees/create.ts deleted file mode 100644 index a402e5abd..000000000 --- a/src/actions/groups/committees/create.ts +++ /dev/null @@ -1,25 +0,0 @@ -'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { getUser } from '@/auth/getUser' -import { createCommittee } from '@/services/groups/committees/create' -import { safeServerCall } from '@/actions/safeServerCall' -import { createCommitteeValidation } from '@/services/groups/committees/validation' -import type { ExpandedCommittee } from '@/services/groups/committees/Types' -import type { ActionReturn } from '@/actions/Types' -import type { CreateCommitteeTypes } from '@/services/groups/committees/validation' - -export async function createCommitteeAction( - rawData: FormData | CreateCommitteeTypes['Type'] -): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['COMMITTEE_CREATE']], - shouldRedirect: false, - }) - - if (!authorized) return createActionError(status) - - const parse = createCommitteeValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - - return await safeServerCall(() => createCommittee(parse.data)) -} diff --git a/src/actions/groups/committees/read.ts b/src/actions/groups/committees/read.ts deleted file mode 100644 index ac6629449..000000000 --- a/src/actions/groups/committees/read.ts +++ /dev/null @@ -1,10 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { CommitteeMethods } from '@/services/groups/committees/methods' - -export const readCommitteesAction = action(CommitteeMethods.readCommittees) -export const readCommitteeAction = action(CommitteeMethods.readCommittee) -export const readCommitteeArticleAction = action(CommitteeMethods.readCommitteArticle) -export const readCommitteeParagraphAction = action(CommitteeMethods.readCommitteeParagraph) -export const readCommitteeMembersAction = action(CommitteeMethods.readCommitteeMembers) - diff --git a/src/actions/groups/committees/update.ts b/src/actions/groups/committees/update.ts deleted file mode 100644 index bcaedb055..000000000 --- a/src/actions/groups/committees/update.ts +++ /dev/null @@ -1,24 +0,0 @@ -'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { updateCommittee } from '@/services/groups/committees/update' -import { updateCommitteeValidation } from '@/services/groups/committees/validation' -import type { UpdateCommitteeTypes } from '@/services/groups/committees/validation' - - -export async function updateCommitteeAction( - id: number, - rawdata: FormData | UpdateCommitteeTypes['Type'] -) { - const { status, authorized } = await getUser({ - requiredPermissions: [['COMMITTEE_UPDATE']] - }) - if (!authorized) return createActionError(status) - - const parse = updateCommitteeValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => updateCommittee(id, data)) -} diff --git a/src/actions/groups/interestGroups/create.ts b/src/actions/groups/interestGroups/create.ts deleted file mode 100644 index a15258e5d..000000000 --- a/src/actions/groups/interestGroups/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { InterestGroupMethods } from '@/services/groups/interestGroups/methods' - -export const createInterestGroupAction = action(InterestGroupMethods.create) diff --git a/src/actions/groups/interestGroups/destroy.ts b/src/actions/groups/interestGroups/destroy.ts deleted file mode 100644 index d884b2427..000000000 --- a/src/actions/groups/interestGroups/destroy.ts +++ /dev/null @@ -1,6 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { InterestGroupMethods } from '@/services/groups/interestGroups/methods' - - -export const destroyInterestGroupAction = action(InterestGroupMethods.destroy) diff --git a/src/actions/groups/interestGroups/read.ts b/src/actions/groups/interestGroups/read.ts deleted file mode 100644 index 67ce4cff3..000000000 --- a/src/actions/groups/interestGroups/read.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { InterestGroupMethods } from '@/services/groups/interestGroups/methods' - -export const readInterestGroupsAction = action(InterestGroupMethods.readMany) diff --git a/src/actions/groups/interestGroups/update.ts b/src/actions/groups/interestGroups/update.ts deleted file mode 100644 index 72da82e01..000000000 --- a/src/actions/groups/interestGroups/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { InterestGroupMethods } from '@/services/groups/interestGroups/methods' - -export const updateInterestGroupAction = action(InterestGroupMethods.update) diff --git a/src/actions/groups/memberships/create.ts b/src/actions/groups/memberships/create.ts deleted file mode 100644 index 117dbb0f6..000000000 --- a/src/actions/groups/memberships/create.ts +++ /dev/null @@ -1,28 +0,0 @@ -'use server' - -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { createMembershipsForGroup } from '@/services/groups/memberships/create' -import type { ActionReturn } from '@/actions/Types' - -/** - * WARNING: This action will lead to error if used with group types not in CanEasalyManageMembership - */ -export async function createMembershipsForGroupAction({ - groupId, - users -}: { - groupId: number, - users: { - userId: number, - admin: boolean - }[] -}): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['GROUP_ADMIN']] - }) - if (!authorized) return createActionError(status) - - return safeServerCall(() => createMembershipsForGroup(groupId, users)) -} diff --git a/src/actions/groups/memberships/destory.ts b/src/actions/groups/memberships/destory.ts deleted file mode 100644 index a2c6c0266..000000000 --- a/src/actions/groups/memberships/destory.ts +++ /dev/null @@ -1,28 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { destoryMembershipOfUser } from '@/services/groups/memberships/destroy' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedMembership } from '@/services/groups/memberships/Types' - -/** - * WARNING: Do not use this action, usually you want updateMemebershipInactivate - * @param - * @returns - */ -export async function destroyMembership({ - groupId, - userId, - orderArg, -}: { - groupId: number, - userId: number, - orderArg: number -}): Promise> { - //TODO: make function to check that. user is admin of group - - return await safeServerCall(() => destoryMembershipOfUser({ - groupId, - userId, - orderArg - })) -} diff --git a/src/actions/groups/memberships/update.ts b/src/actions/groups/memberships/update.ts deleted file mode 100644 index fcce5eb25..000000000 --- a/src/actions/groups/memberships/update.ts +++ /dev/null @@ -1,27 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { updateMembership } from '@/services/groups/memberships/update' -import type { ExpandedMembership } from '@/services/groups/memberships/Types' -import type { ActionReturn } from '@/actions/Types' - -export async function updateMembershipAdminAcion(membership: { - groupId: number - userId: number -}, admin: boolean): Promise> { - //TODO: make function to check that user is admin of group - return await safeServerCall(() => updateMembership({ - ...membership, - orderArg: 'ACTIVE' - }, { admin })) -} - -export async function updateMembershipActiveAction(membership: { - groupId: number - userId: number -}, active: boolean): Promise> { - //TODO: make function to check that user is admin of group - return await safeServerCall(() => updateMembership({ - ...membership, - orderArg: 'ACTIVE' - }, { active })) -} diff --git a/src/actions/groups/read.ts b/src/actions/groups/read.ts deleted file mode 100644 index 97d8d0146..000000000 --- a/src/actions/groups/read.ts +++ /dev/null @@ -1,8 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { GroupMethods } from '@/services/groups/methods' - -export const readGroupsAction = action(GroupMethods.readGroups) -export const readGroupExpandedAction = action(GroupMethods.readGroupExpanded) -export const readGroupsExpandedAction = action(GroupMethods.readGroupsExpanded) -export const readGroupsStructuredAction = action(GroupMethods.readGroupsStructured) diff --git a/src/actions/groups/studyProgrammes/create.ts b/src/actions/groups/studyProgrammes/create.ts deleted file mode 100644 index 7d5fdaa55..000000000 --- a/src/actions/groups/studyProgrammes/create.ts +++ /dev/null @@ -1,22 +0,0 @@ -'use server' - -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { createStudyProgramme } from '@/services/groups/studyProgrammes/create' -import { createStudyProgrammeValidation } from '@/services/groups/studyProgrammes/validation' -import type { ActionReturn } from '@/actions/Types' -import type { StudyProgramme } from '@prisma/client' - - -export async function createStudyProgrammeAction(rawdata: FormData): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['STUDY_PROGRAMME_CREATE']], - }) - if (!authorized) return createActionError(status) - - const parse = createStudyProgrammeValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - - return await safeServerCall(() => createStudyProgramme(parse.data)) -} diff --git a/src/actions/groups/studyProgrammes/read.ts b/src/actions/groups/studyProgrammes/read.ts deleted file mode 100644 index 387de398c..000000000 --- a/src/actions/groups/studyProgrammes/read.ts +++ /dev/null @@ -1,18 +0,0 @@ -'use server' - -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { readStudyProgrammes } from '@/services/groups/studyProgrammes/read' -import type { ActionReturn } from '@/actions/Types' -import type { StudyProgramme } from '@prisma/client' - - -export async function readStudyProgrammesAction(): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['STUDY_PROGRAMME_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readStudyProgrammes()) -} diff --git a/src/actions/groups/studyProgrammes/update.ts b/src/actions/groups/studyProgrammes/update.ts deleted file mode 100644 index 3e32c05ac..000000000 --- a/src/actions/groups/studyProgrammes/update.ts +++ /dev/null @@ -1,25 +0,0 @@ -'use server' - -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { updateStudyProgramme } from '@/services/groups/studyProgrammes/update' -import { updateStudyProgrammeValidation } from '@/services/groups/studyProgrammes/validation' -import type { ActionReturn } from '@/actions/Types' -import type { StudyProgramme } from '@prisma/client' - - -export async function updateStudyProgrammeAction(id: number, rawdata: FormData): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['STUDY_PROGRAMME_UPDATE']], - }) - if (!authorized) return createActionError(status) - - const parse = updateStudyProgrammeValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - - return await safeServerCall(() => updateStudyProgramme({ - ...parse.data, - id, - })) -} diff --git a/src/actions/images/collections/create.ts b/src/actions/images/collections/create.ts deleted file mode 100644 index eb1791e30..000000000 --- a/src/actions/images/collections/create.ts +++ /dev/null @@ -1,23 +0,0 @@ -'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { createImageCollection } from '@/services/images/collections/create' -import { safeServerCall } from '@/actions/safeServerCall' -import { createImageCollectionValidation } from '@/services/images/collections/validation' -import { getUser } from '@/auth/getUser' -import type { ImageCollection } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' -import type { CreateImageCollectionTypes } from '@/services/images/collections/validation' - -export async function createImageCollectionAction( - rawdata: FormData | CreateImageCollectionTypes['Type'] -): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['IMAGE_COLLECTION_CREATE']] - }) - if (!authorized) return createActionError(status) - - const parse = createImageCollectionValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - return await safeServerCall(() => createImageCollection(data)) -} diff --git a/src/actions/images/collections/destroy.ts b/src/actions/images/collections/destroy.ts deleted file mode 100644 index 7ae1e63ac..000000000 --- a/src/actions/images/collections/destroy.ts +++ /dev/null @@ -1,11 +0,0 @@ -'use server' -import { destroyImageCollection } from '@/services/images/collections/destroy' -import { safeServerCall } from '@/actions/safeServerCall' -import type { ImageCollection } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' - -export async function destroyImageCollectionAction(collectionId: number): Promise> { - //TODO: Visibility check - - return await safeServerCall(() => destroyImageCollection(collectionId)) -} diff --git a/src/actions/images/collections/read.ts b/src/actions/images/collections/read.ts deleted file mode 100644 index a9404774c..000000000 --- a/src/actions/images/collections/read.ts +++ /dev/null @@ -1,72 +0,0 @@ -'use server' -import { createActionError } from '@/actions/error' -import { - readImageCollection, - readImageCollectionsPage, - readSpecialImageCollection -} from '@/services/images/collections/read' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { getVisibilityFilter } from '@/auth/getVisibilityFilter' -import { includeVisibility } from '@/services/visibility/read' -import { checkVisibility } from '@/auth/checkVisibility' -import { SpecialCollection } from '@prisma/client' -import type { VisibilityCollapsed } from '@/services/visibility/Types' -import type { ReadPageInput } from '@/lib/paging/Types' -import type { ImageCollection } from '@prisma/client' -import type { - ExpandedImageCollection, - ImageCollectionCursor, - ImageCollectionPageReturn -} from '@/services/images/collections/Types' -import type { ActionReturn } from '@/actions/Types' - -/** - * Action that reads an image collection by id or name - * @param idOrName - the id or name of the image collection - * @returns the image collection in actionrturn - */ -export async function readImageCollectionAction( - idOrName: number | string -): Promise> { - const collection = await safeServerCall(() => includeVisibility( - () => readImageCollection(idOrName), - data => data.visibilityId - )) - if (!collection.success) return collection - if (!checkVisibility(await getUser(), collection.data.visibility, 'REGULAR')) { - return createActionError('UNAUTHORIZED', 'You do not have permission to view this collection') - } - - return collection -} - -/** - * Action that returns a page of image collections, orders by createdAt (and then name) - * @param page - the page to read of the Page type - * @returns - A page of image collections - */ -export async function readImageCollectionsPageAction( - readPageInput: ReadPageInput -): Promise> { - const { memberships, permissions } = await getUser() - const visibilityFilter = getVisibilityFilter(memberships, permissions) - console.log(visibilityFilter) - return await safeServerCall(() => readImageCollectionsPage(readPageInput, visibilityFilter)) -} - -/** - * Reads a "special" collection read on this in the docs. If it does not exist it will create it. - * @param special - the special collection to read - * @returns the special collection - */ -export async function readSpecialImageCollectionAction(special: SpecialCollection): Promise> { - //Check that the collection actually is a special collection, as the paramter is only a compile time type check - if (!Object.values(SpecialCollection).includes(special)) { - return createActionError('BAD PARAMETERS', `${special} is not special`) - } - - //TODO: Auth special image collections on permission (not visibility) - //TODO: Check permission associated with the special collection - return await safeServerCall(() => readSpecialImageCollection(special)) -} diff --git a/src/actions/images/collections/update.ts b/src/actions/images/collections/update.ts deleted file mode 100644 index bfa141a3d..000000000 --- a/src/actions/images/collections/update.ts +++ /dev/null @@ -1,28 +0,0 @@ -'use server' -import { createZodActionError } from '@/actions/error' -import { updateImageCollection } from '@/services/images/collections/update' -import { safeServerCall } from '@/actions/safeServerCall' -import { updateImageCollectionValidation } from '@/services/images/collections/validation' -import type { ImageCollection } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' -import type { UpdateImageCollectionTypes } from '@/services/images/collections/validation' - -/** - * A action that updates an image collection - * @param collectionId - the id of the collection to update - * @param coverImageId - the id of the image to set as the cover image (optional) - * @param rawdata - the data to update the collection with - * @returns - the updated collection in ActionReturn - */ -export async function updateImageCollectionAction( - collectionId: number, - coverImageId: number | undefined, - rawdata: FormData | UpdateImageCollectionTypes['Type'] -): Promise> { - const parse = updateImageCollectionValidation.typeValidate(rawdata) - - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => updateImageCollection(collectionId, coverImageId, data)) -} diff --git a/src/actions/images/create.ts b/src/actions/images/create.ts deleted file mode 100644 index 34b11067d..000000000 --- a/src/actions/images/create.ts +++ /dev/null @@ -1,6 +0,0 @@ -'use server' -import { ImageMethods } from '@/services/images/methods' -import { action } from '@/actions/action' - -export const createImageAction = action(ImageMethods.create) -export const createImagesAction = action(ImageMethods.createMany) diff --git a/src/actions/images/destroy.ts b/src/actions/images/destroy.ts deleted file mode 100644 index 0b4814bdd..000000000 --- a/src/actions/images/destroy.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { ImageMethods } from '@/services/images/methods' - -export const destroyImageAction = action(ImageMethods.destroy) diff --git a/src/actions/images/read.ts b/src/actions/images/read.ts deleted file mode 100644 index c12881f6a..000000000 --- a/src/actions/images/read.ts +++ /dev/null @@ -1,16 +0,0 @@ -'use server' -import { ImageMethods } from '@/services/images/methods' -import { action } from '@/actions/action' - -/** - * Read one image. -*/ -export const readImageAction = action(ImageMethods.read) -/** - * Read one page of images. - */ -export const readImagesPageAction = action(ImageMethods.readPage) -/** - * Read one special image. - */ -export const readSpecialImageAction = action(ImageMethods.readSpecial) diff --git a/src/actions/images/update.ts b/src/actions/images/update.ts deleted file mode 100644 index 9f33da997..000000000 --- a/src/actions/images/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { ImageMethods } from '@/services/images/methods' -import { action } from '@/actions/action' - -export const updateImageAction = action(ImageMethods.update) diff --git a/src/actions/licenses/create.ts b/src/actions/licenses/create.ts deleted file mode 100644 index 69c3d44f7..000000000 --- a/src/actions/licenses/create.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { LicenseMethods } from '@/services/licenses/methods' - -export const createLicenseAction = action(LicenseMethods.create) diff --git a/src/actions/licenses/destroy.ts b/src/actions/licenses/destroy.ts deleted file mode 100644 index c7d3ba569..000000000 --- a/src/actions/licenses/destroy.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { LicenseMethods } from '@/services/licenses/methods' - -export const destroyLicenseAction = action(LicenseMethods.destroy) diff --git a/src/actions/licenses/read.ts b/src/actions/licenses/read.ts deleted file mode 100644 index 58c6b3d16..000000000 --- a/src/actions/licenses/read.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { LicenseMethods } from '@/services/licenses/methods' - -export const readAllLicensesAction = action(LicenseMethods.readAll) diff --git a/src/actions/licenses/update.ts b/src/actions/licenses/update.ts deleted file mode 100644 index 496480670..000000000 --- a/src/actions/licenses/update.ts +++ /dev/null @@ -1,5 +0,0 @@ -'use server' -import { LicenseMethods } from '@/services/licenses/methods' -import { action } from '@/actions/action' - -export const updateLicenseAction = action(LicenseMethods.update) diff --git a/src/actions/lockers/locations.ts b/src/actions/lockers/locations.ts deleted file mode 100644 index 358cc6785..000000000 --- a/src/actions/lockers/locations.ts +++ /dev/null @@ -1,7 +0,0 @@ -'use server' - -import { action } from '@/actions/action' -import { LockerLocationMethods } from '@/services/lockers/locations/methods' - -export const createLockerLocationAction = action(LockerLocationMethods.create) -export const readAllLockerLocationsAction = action(LockerLocationMethods.readAll) diff --git a/src/actions/lockers/lockers.ts b/src/actions/lockers/lockers.ts deleted file mode 100644 index e5c2f4c6e..000000000 --- a/src/actions/lockers/lockers.ts +++ /dev/null @@ -1,7 +0,0 @@ -'use server' -import { LockerMethods } from '@/services/lockers/methods' -import { action } from '@/actions/action' - -export const createLockerAction = action(LockerMethods.create) -export const readLockerAction = action(LockerMethods.read) -export const readLockerPageAction = action(LockerMethods.readPage) diff --git a/src/actions/lockers/reservations.ts b/src/actions/lockers/reservations.ts deleted file mode 100644 index 6453e9d0c..000000000 --- a/src/actions/lockers/reservations.ts +++ /dev/null @@ -1,7 +0,0 @@ -'use server' - -import { action } from '@/actions/action' -import { LockerReservationMethods } from '@/services/lockers/reservations/methods' - -export const updateLockerReservationAction = action(LockerReservationMethods.update) -export const createLockerReservationAction = action(LockerReservationMethods.create) diff --git a/src/actions/mail/alias/create.ts b/src/actions/mail/alias/create.ts deleted file mode 100644 index f8f47fc0a..000000000 --- a/src/actions/mail/alias/create.ts +++ /dev/null @@ -1,24 +0,0 @@ -'use server' - -import { createMailAliasValidation } from '@/services/mail/alias/validation' -import { createZodActionError, createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { createMailAlias } from '@/services/mail/alias/create' -import { getUser } from '@/auth/getUser' -import type { ActionReturn } from '@/actions//Types' -import type { MailAlias } from '@prisma/client' - - -export async function createMailAliasAction(rawdata: FormData): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILALIAS_CREATE']] - }) - if (!authorized) return createActionError(status) - - const parse = createMailAliasValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => createMailAlias(parse.data)) -} - diff --git a/src/actions/mail/alias/destory.ts b/src/actions/mail/alias/destory.ts deleted file mode 100644 index bc2871e82..000000000 --- a/src/actions/mail/alias/destory.ts +++ /dev/null @@ -1,20 +0,0 @@ -'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { destroyMailAlias } from '@/services/mail/alias/destroy' -import { destoryMailAliasValidation } from '@/services/mail/alias/validation' -import type { ActionReturn } from '@/actions/Types' -import type { MailAlias } from '@prisma/client' - -export async function destroyMailAliasAction(id: number): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILALIAS_DESTORY']], - }) - if (!authorized) return createActionError(status) - - const parse = destoryMailAliasValidation.typeValidate({ id }) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => destroyMailAlias(parse.data.id)) -} diff --git a/src/actions/mail/alias/read.ts b/src/actions/mail/alias/read.ts deleted file mode 100644 index 29def0ef4..000000000 --- a/src/actions/mail/alias/read.ts +++ /dev/null @@ -1,17 +0,0 @@ -'use server' - -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { readMailAliases } from '@/services/mail/alias/read' -import { getUser } from '@/auth/getUser' -import type { ActionReturn } from '@/actions/Types' -import type { MailAlias } from '@prisma/client' - -export async function readMailAliasesAction(): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILALIAS_READ']] - }) - if (!authorized) return createActionError(status) - - return safeServerCall(() => readMailAliases()) -} diff --git a/src/actions/mail/alias/update.ts b/src/actions/mail/alias/update.ts deleted file mode 100644 index 47e547600..000000000 --- a/src/actions/mail/alias/update.ts +++ /dev/null @@ -1,21 +0,0 @@ -'use server' - -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { createActionError, createZodActionError } from '@/actions/error' -import { updateMailAliasValidation } from '@/services/mail/alias/validation' -import { updateMailAlias } from '@/services/mail/alias/update' -import type { ActionReturn } from '@/actions/Types' -import type { MailAlias } from '@prisma/client' - -export async function updateMailAliasAction(rawdata: FormData): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILALIAS_UPDATE']], - }) - if (!authorized) return createActionError(status) - - const parsed = updateMailAliasValidation.typeValidate(rawdata) - if (!parsed.success) return createZodActionError(parsed) - - return await safeServerCall(() => updateMailAlias(parsed.data)) -} diff --git a/src/actions/mail/create.ts b/src/actions/mail/create.ts deleted file mode 100644 index 197fa748c..000000000 --- a/src/actions/mail/create.ts +++ /dev/null @@ -1,76 +0,0 @@ -'use server' - -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { - createAliasMailingListValidation, - createMailingListExternalValidation, - createMailingListGroupValidation, - createMailingListUserValidation -} from '@/services/mail/validation' -import { - createAliasMailingListRelation, - createMailingListExternalRelation, - createMailingListGroupRelation, - createMailingListUserRelation -} from '@/services/mail/create' -import type { ActionReturn } from '@/actions/Types' -import type { - MailAliasMailingList, - MailingListGroup, - MailingListMailAddressExternal, - MailingListUser -} from '@prisma/client' - -export async function createAliasMailingListRelationAction(formdata: FormData): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_ALIAS_CREATE']] - }) - if (!authorized) return createActionError(status) - - const parse = createAliasMailingListValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => createAliasMailingListRelation(parse.data)) -} - -export async function createMailingListExternalRelationAction(formdata: FormData): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_EXTERNAL_ADDRESS_CREATE']] - }) - if (!authorized) return createActionError(status) - - const parse = createMailingListExternalValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => createMailingListExternalRelation(parse.data)) -} - -export async function createMailingListUserRelationAction(formdata: FormData): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_USER_CREATE']] - }) - if (!authorized) return createActionError(status) - - const parse = createMailingListUserValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => createMailingListUserRelation(parse.data)) -} - -export async function createMailingListGroupRelationAction(formdata: FormData): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_GROUP_CREATE']] - }) - if (!authorized) return createActionError(status) - - const parse = createMailingListGroupValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => createMailingListGroupRelation(parse.data)) -} diff --git a/src/actions/mail/destroy.ts b/src/actions/mail/destroy.ts deleted file mode 100644 index 878f8cabf..000000000 --- a/src/actions/mail/destroy.ts +++ /dev/null @@ -1,83 +0,0 @@ -'use server' - -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { - createAliasMailingListValidation, - createMailingListExternalValidation, - createMailingListGroupValidation, - createMailingListUserValidation -} from '@/services/mail/validation' -import { - destroyAliasMailingListRelation, - destroyMailingListExternalRelation, - destroyMailingListGroupRelation, - destroyMailingListUserRelation -} from '@/services/mail/destroy' -import type { - CreateAliasMailingListType, - CreateMailingListExternalType, - CreateMailingListGroupType, - CreateMailingListUserType -} from '@/services/mail/validation' -import type { ActionReturn } from '@/actions/Types' -import type { - MailAliasMailingList, - MailingListGroup, - MailingListMailAddressExternal, - MailingListUser -} from '@prisma/client' - - -export async function destroyAliasMailingListRelationAction(formdata: FormData | CreateAliasMailingListType['Type']): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_ALIAS_DESTROY']] - }) - if (!authorized) return createActionError(status) - - const parse = createAliasMailingListValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => destroyAliasMailingListRelation(parse.data)) -} - -export async function destroyMailingListExternalRelationAction(formdata: FormData | CreateMailingListExternalType['Type']): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_EXTERNAL_ADDRESS_DESTROY']] - }) - if (!authorized) return createActionError(status) - - const parse = createMailingListExternalValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => destroyMailingListExternalRelation(parse.data)) -} - -export async function destroyMailingListUserRelationAction(formdata: FormData | CreateMailingListUserType['Type']): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_USER_DESTROY']], - }) - if (!authorized) return createActionError(status) - - const parse = createMailingListUserValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => destroyMailingListUserRelation(parse.data)) -} - -export async function destroyMailingListGroupRelationAction(formdata: FormData | CreateMailingListGroupType['Type']): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_GROUP_DESTROY']] - }) - if (!authorized) return createActionError(status) - - const parse = createMailingListGroupValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => destroyMailingListGroupRelation(parse.data)) -} diff --git a/src/actions/mail/list/create.ts b/src/actions/mail/list/create.ts deleted file mode 100644 index 065f19b76..000000000 --- a/src/actions/mail/list/create.ts +++ /dev/null @@ -1,24 +0,0 @@ -'use server' - -import { createMailingListValidation } from '@/services/mail/list/validation' -import { createZodActionError, createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { createMailingList } from '@/services/mail/list/create' -import { getUser } from '@/auth/getUser' -import type { ActionReturn } from '@/actions//Types' -import type { MailingList } from '@prisma/client' - - -export async function createMailingListAction(rawdata: FormData): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_CREATE']] - }) - if (!authorized) return createActionError(status) - - const parse = createMailingListValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => createMailingList(parse.data)) -} - diff --git a/src/actions/mail/list/destory.ts b/src/actions/mail/list/destory.ts deleted file mode 100644 index 8e805c492..000000000 --- a/src/actions/mail/list/destory.ts +++ /dev/null @@ -1,20 +0,0 @@ -'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { destroyMailingList } from '@/services/mail/list/destroy' -import { readMailingListValidation } from '@/services/mail/list/validation' -import type { ActionReturn } from '@/actions/Types' -import type { MailingList } from '@prisma/client' - -export async function destroyMailingListAction(id: number): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_DESTROY']], - }) - if (!authorized) return createActionError(status) - - const parse = readMailingListValidation.typeValidate({ id }) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => destroyMailingList(parse.data.id)) -} diff --git a/src/actions/mail/list/update.ts b/src/actions/mail/list/update.ts deleted file mode 100644 index 8e58e9d73..000000000 --- a/src/actions/mail/list/update.ts +++ /dev/null @@ -1,23 +0,0 @@ -'use server' - -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { updateMailingList } from '@/services/mail/list/update' -import { updateMailingListValidation } from '@/services/mail/list/validation' -import type { ActionReturn } from '@/actions/Types' -import type { MailingList } from '@prisma/client' - - -export async function updateMailingListAction(data: FormData): -Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILINGLIST_UPDATE']], - }) - if (!authorized) return createActionError(status) - - const parse = updateMailingListValidation.typeValidate(data) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => updateMailingList(parse.data)) -} diff --git a/src/actions/mail/mailAddressExternal/create.ts b/src/actions/mail/mailAddressExternal/create.ts deleted file mode 100644 index aa49e2907..000000000 --- a/src/actions/mail/mailAddressExternal/create.ts +++ /dev/null @@ -1,24 +0,0 @@ -'use server' - -import { createMailAddressExternalValidation } from '@/services/mail/mailAddressExternal/validation' -import { createZodActionError, createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { createMailAddressExternal } from '@/services/mail/mailAddressExternal/create' -import { getUser } from '@/auth/getUser' -import type { ActionReturn } from '@/actions//Types' -import type { MailAddressExternal } from '@prisma/client' - - -export async function createMailAddressExternalAction(rawdata: FormData): - Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILADDRESS_EXTERNAL_CREATE']] - }) - if (!authorized) return createActionError(status) - - const parse = createMailAddressExternalValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => createMailAddressExternal(parse.data)) -} - diff --git a/src/actions/mail/mailAddressExternal/destroy.ts b/src/actions/mail/mailAddressExternal/destroy.ts deleted file mode 100644 index fd62b1775..000000000 --- a/src/actions/mail/mailAddressExternal/destroy.ts +++ /dev/null @@ -1,20 +0,0 @@ -'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { readMailAddressExternalValidation } from '@/services/mail/mailAddressExternal/validation' -import { destroyMailAddressExternal } from '@/services/mail/mailAddressExternal/destroy' -import type { ActionReturn } from '@/actions/Types' -import type { MailAddressExternal } from '@prisma/client' - -export async function destroyMailAddressExternalAction(id: number): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILADDRESS_EXTERNAL_DESTROY']], - }) - if (!authorized) return createActionError(status) - - const parse = readMailAddressExternalValidation.typeValidate({ id }) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => destroyMailAddressExternal(parse.data.id)) -} diff --git a/src/actions/mail/mailAddressExternal/update.ts b/src/actions/mail/mailAddressExternal/update.ts deleted file mode 100644 index e9271b710..000000000 --- a/src/actions/mail/mailAddressExternal/update.ts +++ /dev/null @@ -1,23 +0,0 @@ -'use server' - -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { updateMailAddressExternal } from '@/services/mail/mailAddressExternal/update' -import { updateMailAddressExternalValidation } from '@/services/mail/mailAddressExternal/validation' -import type { ActionReturn } from '@/actions/Types' -import type { MailAddressExternal } from '@prisma/client' - - -export async function updateMailAddressExternalAction(data: FormData): -Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAILADDRESS_EXTERNAL_UPDATE']], - }) - if (!authorized) return createActionError(status) - - const parse = updateMailAddressExternalValidation.typeValidate(data) - if (!parse.success) return createZodActionError(parse) - - return safeServerCall(() => updateMailAddressExternal(parse.data)) -} diff --git a/src/actions/mail/read.ts b/src/actions/mail/read.ts deleted file mode 100644 index 0e9303951..000000000 --- a/src/actions/mail/read.ts +++ /dev/null @@ -1,63 +0,0 @@ -'use server' - -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError } from '@/actions/error' -import { readMailTraversal } from '@/services/mail/read' -import { readMailAliases } from '@/services/mail/alias/read' -import { readMailingLists } from '@/services/mail/list/read' -import { readMailAddressExternal } from '@/services/mail/mailAddressExternal/read' -import { getUser } from '@/auth/getUser' -import type { UserFiltered } from '@/services/users/Types' -import type { MailListTypes } from '@/services/mail/Types' -import type { MailingList, MailAlias, MailAddressExternal } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' - - -export async function readMailFlowAction(filter: MailListTypes, id: number) { - const { authorized, status } = await getUser({ - requiredPermissions: [ - ['MAILINGLIST_READ'], - ['MAILALIAS_READ'], - ['MAILADDRESS_EXTERNAL_READ'], - ['GROUP_READ'], - ], - }) - - if (!authorized) return createActionError(status) - - return safeServerCall(() => readMailTraversal({ - filter, - id, - })) -} - -export async function readMailOptions(): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [ - ['MAILINGLIST_READ'], - ['MAILALIAS_READ'], - ['MAILADDRESS_EXTERNAL_READ'], - ], - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(async () => { - const results = await Promise.all([ - readMailAliases(), - readMailingLists(), - readMailAddressExternal(), - ]) - - return { - alias: results[0], - mailingList: results[1], - mailaddressExternal: results[2], - users: [] - } - }) -} diff --git a/src/actions/news/create.ts b/src/actions/news/create.ts deleted file mode 100644 index 11f866d5e..000000000 --- a/src/actions/news/create.ts +++ /dev/null @@ -1,19 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { createZodActionError } from '@/actions/error' -import { createNews } from '@/services/news/create' -import { createNewsArticleValidation } from '@/services/news/validation' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedNewsArticle } from '@/services/news/Types' -import type { CreateNewsArticleTypes } from '@/services/news/validation' - -export async function createNewsAction( - rawdata: FormData | CreateNewsArticleTypes['Type'] -): Promise> { - //TODO: check for can create news permission - const parse = createNewsArticleValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createNews(data)) -} diff --git a/src/actions/news/destroy.ts b/src/actions/news/destroy.ts deleted file mode 100644 index 75865d72a..000000000 --- a/src/actions/news/destroy.ts +++ /dev/null @@ -1,10 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { destroyNews } from '@/services/news/destroy' -import type { ActionReturn } from '@/actions/Types' -import type { SimpleNewsArticle } from '@/services/news/Types' - -export async function destroyNewsAction(id: number): Promise>> { - //TODO: check auth - return await safeServerCall(() => destroyNews(id)) -} diff --git a/src/actions/news/read.ts b/src/actions/news/read.ts deleted file mode 100644 index 761b994a6..000000000 --- a/src/actions/news/read.ts +++ /dev/null @@ -1,26 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { readNews, readNewsCurrent, readOldNewsPage } from '@/services/news/read' -import type { ExpandedNewsArticle, NewsCursor, SimpleNewsArticle } from '@/services/news/Types' -import type { ActionReturn } from '@/actions/Types' -import type { ReadPageInput } from '@/lib/paging/Types' - -export async function readOldNewsPageAction( - readPageImput: ReadPageInput -): Promise> { - //TODO: only read news with right visibility - return await safeServerCall(() => readOldNewsPage(readPageImput)) -} - -export async function readNewsCurrentAction(): Promise> { - //TODO: only read news with right visibility - return await safeServerCall(() => readNewsCurrent()) -} - -export async function readNewsAction(idOrName: number | { - articleName: string - order: number -}): Promise> { - //TODO: only read news if right visibility - return await safeServerCall(() => readNews(idOrName)) -} diff --git a/src/actions/news/update.ts b/src/actions/news/update.ts deleted file mode 100644 index bc65530bd..000000000 --- a/src/actions/news/update.ts +++ /dev/null @@ -1,49 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { createZodActionError, createActionError } from '@/actions/error' -import { updateNews } from '@/services/news/update' -import { updateNewsArticleValidation } from '@/services/news/validation' -import { NotificationMethods } from '@/services/notifications/methods' -import type { SimpleNewsArticle } from '@/services/news/Types' -import type { ActionReturn } from '@/actions/Types' -import type { UpdateNewsArticleTypes } from '@/services/news/validation' - -export async function updateNewsAction( - id: number, - rawdata: FormData | UpdateNewsArticleTypes['Type'] -): Promise>> { - //TODO: auth - const parse = updateNewsArticleValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - return await safeServerCall(() => updateNews(id, data)) -} - -export async function publishNewsAction( - // disable eslint rule temporarily until todo is resolved - // eslint-disable-next-line @typescript-eslint/no-unused-vars - id: number, - // disable eslint rule temporarily until todo is resolved - // eslint-disable-next-line @typescript-eslint/no-unused-vars - shouldPublish: boolean -): Promise>> { - NotificationMethods.createSpecial({ - params: { - special: 'NEW_NEWS_ARTICLE', - }, - data: { - title: 'Ny nyhetsartikkel', // TODO: Add info about the article - message: 'En ny nyhetsartikkel er publisert', - }, - bypassAuth: true, - }) - - return createActionError('UNKNOWN ERROR', 'Not implemented') -} - -// disable eslint rule temporarily until todo is resolved -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export async function updateVisibilityAction(id: number, visible: unknown): Promise> { - //TODO: add visible field to news - return createActionError('UNKNOWN ERROR', 'Not implemented') -} diff --git a/src/actions/notifications/index.ts b/src/actions/notifications/index.ts deleted file mode 100644 index 2764584fe..000000000 --- a/src/actions/notifications/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -'use server' - -import { action } from '@/actions/action' -import { NotificationChannelMethods } from '@/services/notifications/channel/methods' -import { NotificationMethods } from '@/services/notifications/methods' -import { NotificationSubscriptionMethods } from '@/services/notifications/subscription/methods' - -export const createNotificationChannelAction = action(NotificationChannelMethods.create) -export const updateNotificationChannelAction = action(NotificationChannelMethods.update) -export const readNotificationChannelsAction = action(NotificationChannelMethods.readMany) - -export const createNotificationAction = action(NotificationMethods.create) - -export const readNotificationSubscriptionsAction = action(NotificationSubscriptionMethods.read) -export const updateNotificationSubscriptionsAction = action(NotificationSubscriptionMethods.update) diff --git a/src/actions/ombul/create.ts b/src/actions/ombul/create.ts deleted file mode 100644 index a63cf0c69..000000000 --- a/src/actions/ombul/create.ts +++ /dev/null @@ -1,28 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError, createZodActionError } from '@/actions/error' -import { getUser } from '@/auth/getUser' -import { createOmbul } from '@/services/ombul/create' -import { createOmbulValidation } from '@/services/ombul/validation' -import type { ActionReturn } from '@/actions/Types' -import type { Ombul } from '@prisma/client' -import type { CreateOmbulTypes } from '@/services/ombul/validation' - -/** - * Create a new Ombul. - * @param rawData includes a pdf file with the ombul issue optionaly year and issueNumber - * @param CoverImageId is the id of the Image that will be used as the cover of the ombul - */ -export async function createOmbulAction(rawdata: FormData | CreateOmbulTypes['Type']): Promise> { - //Auth route - const { status, authorized } = await getUser({ - requiredPermissions: [['OMBUL_CREATE']] - }) - if (!authorized) return createActionError(status) - - const parse = createOmbulValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createOmbul(data)) -} diff --git a/src/actions/ombul/destroy.ts b/src/actions/ombul/destroy.ts deleted file mode 100644 index de5a9cb2a..000000000 --- a/src/actions/ombul/destroy.ts +++ /dev/null @@ -1,17 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError } from '@/actions/error' -import { getUser } from '@/auth/getUser' -import { destroyOmbul } from '@/services/ombul/destroy' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedOmbul } from '@/services/ombul/Types' - -export async function destroyOmbulAction(id: number): Promise> { - const { status, authorized } = await getUser({ - requiredPermissions: [['OMBUL_DESTROY']] - }) - - if (!authorized) return createActionError(status) - - return await safeServerCall(() => destroyOmbul(id)) -} diff --git a/src/actions/ombul/read.ts b/src/actions/ombul/read.ts deleted file mode 100644 index 2f4accad8..000000000 --- a/src/actions/ombul/read.ts +++ /dev/null @@ -1,42 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError } from '@/actions/error' -import { getUser } from '@/auth/getUser' -import { readLatestOmbul, readOmbul, readOmbuls } from '@/services/ombul/read' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedOmbul } from '@/services/ombul/Types' -import type { Ombul } from '@prisma/client' - -export async function readLatestOmbulAction(): Promise> { - //Auth route - const { status, authorized } = await getUser({ - requiredPermissions: [['OMBUL_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readLatestOmbul()) -} - -export async function readOmbulAction(idOrNameAndYear: number | { - name: string, - year: number, -}): Promise> { - //Auth route - const { status, authorized } = await getUser({ - requiredPermissions: [['OMBUL_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readOmbul(idOrNameAndYear)) -} - -export async function readOmbulsAction(): Promise> { - //Auth route - const { status, authorized } = await getUser({ - requiredPermissions: [['OMBUL_READ']] - }) - if (!authorized) { - return createActionError(status) - } - return await safeServerCall(() => readOmbuls()) -} diff --git a/src/actions/ombul/update.ts b/src/actions/ombul/update.ts deleted file mode 100644 index 1e7420ce0..000000000 --- a/src/actions/ombul/update.ts +++ /dev/null @@ -1,56 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError, createZodActionError } from '@/actions/error' -import { getUser } from '@/auth/getUser' -import { updateOmbul, updateOmbulFile } from '@/services/ombul/update' -import { updateOmbulFileValidation, updateOmbulValidation } from '@/services/ombul/validation' -import type { UpdateOmbulFileTypes, UpdateOmbulTypes } from '@/services/ombul/validation' -import type { ExpandedOmbul } from '@/services/ombul/Types' -import type { ActionReturn } from '@/actions/Types' - -/** - * A action to update an ombul - * @param id - The id of the ombul to update - * @param rawdata - The new data for the ombul including: name, year, issueNumber, description, - * @returns The updated ombul - */ -export async function updateOmbulAction( - id: number, - rawdata: FormData | UpdateOmbulTypes['Type'] -): Promise> { - // Auth route - const { status, authorized } = await getUser({ - requiredPermissions: [['OMBUL_UPDATE']] - }) - if (!authorized) return createActionError(status) - - //Parse the data - const parse = updateOmbulValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => updateOmbul(id, data)) -} - -/** - * A action that updates the ombul file (i.e. the pdf file) of an ombul - * @param id - The id of the ombul to update - * @param rawData - The new data for the new ombul file with field name 'file' - * @returns The updated ombul - */ -export async function updateOmbulFileAction( - id: number, - rawData: FormData | UpdateOmbulFileTypes['Type'] -): Promise> { - // auth route - const { status, authorized } = await getUser({ - requiredPermissions: [['OMBUL_UPDATE']] - }) - if (!authorized) return createActionError(status) - - const parse = updateOmbulFileValidation.typeValidate(rawData) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => updateOmbulFile(id, data)) -} diff --git a/src/actions/omegaOrder/create.ts b/src/actions/omegaOrder/create.ts deleted file mode 100644 index 9a867af52..000000000 --- a/src/actions/omegaOrder/create.ts +++ /dev/null @@ -1,15 +0,0 @@ -'use server' -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { createOmegaOrder } from '@/services/omegaOrder/create' -import type { ActionReturn } from '@/actions/Types' - -export async function createOmegaOrderAction(): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['OMEGA_ORDER_CREATE']] - }) - if (!authorized) return createActionError(status) - - return safeServerCall(createOmegaOrder) -} diff --git a/src/actions/omegaOrder/read.ts b/src/actions/omegaOrder/read.ts deleted file mode 100644 index 6b0ac6e76..000000000 --- a/src/actions/omegaOrder/read.ts +++ /dev/null @@ -1,16 +0,0 @@ -'use server' -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' -import type { ActionReturn } from '@/actions/Types' -import type { OmegaOrder } from '@prisma/client' - -export async function readCurrentOmegaOrderAction(): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['OMEGA_ORDER_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readCurrentOmegaOrder()) -} diff --git a/src/actions/omegaid/generate.ts b/src/actions/omegaid/generate.ts deleted file mode 100644 index 1adb2ef61..000000000 --- a/src/actions/omegaid/generate.ts +++ /dev/null @@ -1,22 +0,0 @@ -'use server' - -import { createActionError } from '@/actions/error' -import { getUser } from '@/auth/getUser' -import { generateOmegaId } from '@/services/omegaid/generate' -import type { ActionReturn } from '@/actions/Types' - - -export async function generateOmegaIdAction(): Promise> { - const { user, authorized, status } = await getUser({ - userRequired: true, - }) - - if (!authorized) return createActionError(status) - - const token = generateOmegaId(user) - - return { - success: true, - data: token, - } -} diff --git a/src/actions/omegaid/read.ts b/src/actions/omegaid/read.ts deleted file mode 100644 index d34847475..000000000 --- a/src/actions/omegaid/read.ts +++ /dev/null @@ -1,14 +0,0 @@ -'use server' - -import { ServerError } from '@/services/error' - - -export async function readOmegaJWTPublicKey(): Promise { - const key = process.env.JWT_PUBLIC_KEY - - if (!key) { - throw new ServerError('INVALID CONFIGURATION', 'The JWT_PUBLIC_KEY must be set') - } - - return key -} diff --git a/src/actions/omegaquotes/create.ts b/src/actions/omegaquotes/create.ts deleted file mode 100644 index 90bce23d0..000000000 --- a/src/actions/omegaquotes/create.ts +++ /dev/null @@ -1,27 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError, createZodActionError } from '@/actions/error' -import { getUser } from '@/auth/getUser' -import { createQuote } from '@/services/omegaquotes/create' -import { createOmegaquotesValidation } from '@/services/omegaquotes/validation' -import type { CreateOmegaguotesTypes } from '@/services/omegaquotes/validation' -import type { ActionReturn } from '@/actions/Types' -import type { OmegaQuote } from '@prisma/client' - -export async function createQuoteAction( - rawdata: FormData | CreateOmegaguotesTypes['Type'] -): Promise> { - const { user, status, authorized } = await getUser({ - requiredPermissions: [['OMEGAQUOTES_WRITE']], - userRequired: true, - }) - if (!authorized) return createActionError(status) - - const parse = createOmegaquotesValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - const results = await safeServerCall(() => createQuote(user.id, data)) - - return results -} diff --git a/src/actions/omegaquotes/read.ts b/src/actions/omegaquotes/read.ts deleted file mode 100644 index 384fefb07..000000000 --- a/src/actions/omegaquotes/read.ts +++ /dev/null @@ -1,20 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError } from '@/actions/error' -import { getUser } from '@/auth/getUser' -import { readQuotesPage } from '@/services/omegaquotes/read' -import type { ActionReturn } from '@/actions/Types' -import type { ReadPageInput } from '@/lib/paging/Types' -import type { OmegaquoteCursor, OmegaquoteFiltered } from '@/services/omegaquotes/Types' - -export async function readQuotesPageAction( - readPageInput: ReadPageInput -): Promise> { - //TODO: REFACTOR when new permission system is working - const { status, authorized } = await getUser({ - requiredPermissions: [['OMEGAQUOTES_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readQuotesPage(readPageInput)) -} diff --git a/src/actions/permissions/index.ts b/src/actions/permissions/index.ts deleted file mode 100644 index 7028e1ba8..000000000 --- a/src/actions/permissions/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -'use server' - -import { action } from '@/actions/action' -import { PermissionMethods } from '@/services/permissions/methods' - -export const readPermissionOfGroupAction = action(PermissionMethods.readPermissionsOfGroup) -export const readPermissionMatrixAction = action(PermissionMethods.readPermissionMatrix) -export const readDefaultPermissionsAction = action(PermissionMethods.readDefaultPermissions) -export const updateDefaultPermissionsAction = action(PermissionMethods.updateDefaultPermissions) -export const updateGroupPermissionAction = action(PermissionMethods.updateGroupPermission) diff --git a/src/actions/safeServerCall.ts b/src/actions/safeServerCall.ts index abc48d409..32ddeb90f 100644 --- a/src/actions/safeServerCall.ts +++ b/src/actions/safeServerCall.ts @@ -1,6 +1,6 @@ -import { createActionError, createZodActionError } from './error' +import { createActionError, createZodActionError } from './actionError' import { ParseError, Smorekopp } from '@/services/error' -import type { ActionReturn } from './Types' +import type { ActionReturn } from './actionTypes' /** * A function that calls a server function. If all goes well, it returns a ActionReturn with the data. diff --git a/src/actions/screens/authers.ts b/src/actions/screens/authers.ts deleted file mode 100644 index 9113a0e7e..000000000 --- a/src/actions/screens/authers.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { RequirePermission } from '@/auth/auther/RequirePermission' - -export const adminScreenAuther = RequirePermission.staticFields({ permission: 'SCREEN_ADMIN' }) -export const readScreenAuther = RequirePermission.staticFields({ permission: 'SCREEN_READ' }) diff --git a/src/actions/screens/create.ts b/src/actions/screens/create.ts deleted file mode 100644 index 639adea54..000000000 --- a/src/actions/screens/create.ts +++ /dev/null @@ -1,20 +0,0 @@ -'use server' -import { adminScreenAuther } from './authers' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError, createZodActionError } from '@/actions/error' -import { createScreenValidation, type CreateScreenTypes } from '@/services/screens/validation' -import { createScreen } from '@/services/screens/create' -import { Session } from '@/auth/Session' -import type { Screen } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' - -export async function createScreenAction(formdata: CreateScreenTypes['Type']): Promise> { - const authRes = adminScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) - if (!authRes.authorized) return createActionError(authRes.status) - - const parse = createScreenValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createScreen(data)) -} diff --git a/src/actions/screens/destroy.ts b/src/actions/screens/destroy.ts deleted file mode 100644 index 14e6d75b6..000000000 --- a/src/actions/screens/destroy.ts +++ /dev/null @@ -1,14 +0,0 @@ -'use server' -import { adminScreenAuther } from './authers' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError } from '@/actions/error' -import { destroyScreen } from '@/services/screens/destroy' -import { Session } from '@/auth/Session' -import type { ActionReturn } from '@/actions/Types' - -export async function destroyScreenAction(id: number): Promise> { - const authRes = adminScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) - if (!authRes.authorized) return createActionError(authRes.status) - - return await safeServerCall(() => destroyScreen(id)) -} diff --git a/src/actions/screens/pages/create.ts b/src/actions/screens/pages/create.ts deleted file mode 100644 index af970e631..000000000 --- a/src/actions/screens/pages/create.ts +++ /dev/null @@ -1,22 +0,0 @@ -'use server' -import { createScreenValidation } from '@/services/screens/validation' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { createActionError, createZodActionError } from '@/actions/error' -import { createPage } from '@/services/screens/pages/create' -import type { ScreenPage } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' -import type { CreateScreenTypes } from '@/services/screens/validation' - -export async function createPageAction(formdata: CreateScreenTypes['Type']): Promise> { - const { status, authorized } = await getUser({ - requiredPermissions: [['SCREEN_ADMIN']] - }) - if (!authorized) return createActionError(status) - - const parse = createScreenValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => createPage(data)) -} diff --git a/src/actions/screens/pages/destroy.ts b/src/actions/screens/pages/destroy.ts deleted file mode 100644 index 3c21afdd1..000000000 --- a/src/actions/screens/pages/destroy.ts +++ /dev/null @@ -1,16 +0,0 @@ -'use server' -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { destroyPage } from '@/services/screens/pages/destroy' -import type { ActionReturn } from '@/actions/Types' - - -export async function destroyPageAction(id: number): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCREEN_ADMIN']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => destroyPage(id)) -} diff --git a/src/actions/screens/pages/read.ts b/src/actions/screens/pages/read.ts deleted file mode 100644 index 1a0cfbccb..000000000 --- a/src/actions/screens/pages/read.ts +++ /dev/null @@ -1,26 +0,0 @@ -'use server' -import { getUser } from '@/auth/getUser' -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { readPage, readPages } from '@/services/screens/pages/read' -import type { ScreenPage } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' -import type { ExpandedScreenPage } from '@/services/screens/pages/Types' - -export async function readPageAction(id: number): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCREEN_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readPage(id)) -} - -export async function readPagesAction(): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCREEN_READ']] - }) - if (!authorized) return createActionError(status) - - return await safeServerCall(() => readPages()) -} diff --git a/src/actions/screens/pages/update.ts b/src/actions/screens/pages/update.ts deleted file mode 100644 index f70ec9b38..000000000 --- a/src/actions/screens/pages/update.ts +++ /dev/null @@ -1,22 +0,0 @@ -'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' -import { getUser } from '@/auth/getUser' -import { updatePage } from '@/services/screens/pages/update' -import { updatePageValidation } from '@/services/screens/pages/validation' -import type { UpdatePageTypes } from '@/services/screens/pages/validation' -import type { ActionReturn } from '@/actions/Types' -import type { ScreenPage } from '@prisma/client' - -export async function updatePageAction(id: number, formdata: UpdatePageTypes['Type']): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['SCREEN_ADMIN']] - }) - if (!authorized) return createActionError(status) - - const parse = updatePageValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => updatePage(id, data)) -} diff --git a/src/actions/screens/read.ts b/src/actions/screens/read.ts deleted file mode 100644 index d1f900bc8..000000000 --- a/src/actions/screens/read.ts +++ /dev/null @@ -1,22 +0,0 @@ -'use server' -import { readScreenAuther } from './authers' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError } from '@/actions/error' -import { readScreen, readScreens } from '@/services/screens/read' -import { Session } from '@/auth/Session' -import type { Screen } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' - -export async function readScreenAction(id: number): Promise> { - const authRes = readScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) - if (!authRes.authorized) return createActionError(authRes.status) - - return await safeServerCall(() => readScreen(id)) -} - -export async function readScreensAction(): Promise> { - const authRes = readScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) - if (!authRes.authorized) return createActionError(authRes.status) - - return await safeServerCall(() => readScreens()) -} diff --git a/src/actions/screens/update.ts b/src/actions/screens/update.ts deleted file mode 100644 index 541707f4c..000000000 --- a/src/actions/screens/update.ts +++ /dev/null @@ -1,32 +0,0 @@ -'use server' -import { adminScreenAuther } from './authers' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError, createZodActionError } from '@/actions/error' -import { updateScreenValidation, type UpdateScreenTypes } from '@/services/screens/validation' -import { movePageInScreen, updateScreen } from '@/services/screens/update' -import { Session } from '@/auth/Session' -import type { Screen } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' -import type { ScreenPageMoveDirection } from '@/services/screens/Types' - -export async function updateScreenAction(id: number, formdata: UpdateScreenTypes['Type']): Promise> { - const authRes = adminScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) - if (!authRes.authorized) return createActionError(authRes.status) - - const parse = updateScreenValidation.typeValidate(formdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => updateScreen(id, data)) -} - -export async function movePageInScreenAction( - id: {screen: number, page: number}, - direction: ScreenPageMoveDirection -): Promise> { - const authRes = adminScreenAuther.dynamicFields({}).auth(await Session.fromNextAuth()) - if (!authRes.authorized) return createActionError(authRes.status) - - return await safeServerCall(() => movePageInScreen(id, direction)) -} - diff --git a/src/actions/sendmail/send.ts b/src/actions/sendmail/send.ts deleted file mode 100644 index 60a6e6282..000000000 --- a/src/actions/sendmail/send.ts +++ /dev/null @@ -1,23 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { sendMail as transportSendMail } from '@/services/notifications/email/send' -import { getUser } from '@/auth/getUser' -import { createActionError, createZodActionError } from '@/actions/error' -import { sendEmailValidation } from '@/services/notifications/email/validation' -import type { ActionReturn } from '@/actions/Types' - -export default async function sendMail(rawdata: FormData): Promise> { - const { authorized, status } = await getUser({ - requiredPermissions: [['MAIL_SEND']], - }) - - if (!authorized) { - return createActionError(status) - } - - const parse = sendEmailValidation.typeValidate(rawdata) - if (!parse.success) return createZodActionError(parse) - const data = parse.data - - return await safeServerCall(() => transportSendMail(data)) -} diff --git a/src/actions/shop/product.ts b/src/actions/shop/product.ts deleted file mode 100644 index 05fa7ec74..000000000 --- a/src/actions/shop/product.ts +++ /dev/null @@ -1,14 +0,0 @@ -'use server' - -import { action } from '@/actions/action' -import { ProductMethods } from '@/services/shop/product/methods' - -export const readProductsAction = action(ProductMethods.readMany) -export const readProductAction = action(ProductMethods.read) -export const createProductAction = action(ProductMethods.create) -export const updateProductAction = action(ProductMethods.update) - -export const createProductForShopAction = action(ProductMethods.createForShop) -export const updateProductForShopAction = action(ProductMethods.updateForShop) - -export const createShopProductConnectionAction = action(ProductMethods.createShopConnection) diff --git a/src/actions/shop/shop.ts b/src/actions/shop/shop.ts deleted file mode 100644 index 551af7665..000000000 --- a/src/actions/shop/shop.ts +++ /dev/null @@ -1,9 +0,0 @@ -'use server' - -import { action } from '@/actions/action' -import { ShopMethods } from '@/services/shop/shop/methods' - -export const readShopsAction = action(ShopMethods.readMany) -export const readShopAction = action(ShopMethods.read) -export const createShopAction = action(ShopMethods.create) - diff --git a/src/actions/users/create.ts b/src/actions/users/create.ts deleted file mode 100644 index 683d195ca..000000000 --- a/src/actions/users/create.ts +++ /dev/null @@ -1,10 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { UserMethods } from '@/services/users/methods' - -/** - * A action that creates a user by the given data. It will also hash the password - * @param rawdata - The user to create - * @returns - The created user - */ -export const createUserAction = action(UserMethods.create) diff --git a/src/actions/users/destroy.ts b/src/actions/users/destroy.ts deleted file mode 100644 index bf1a24a4e..000000000 --- a/src/actions/users/destroy.ts +++ /dev/null @@ -1,11 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { UserMethods } from '@/services/users/methods' - -/** - * Action to destroy a user by the given id - * @param id - The id of the user to destroy - * @returns - */ -export const destroyUserAction = action(UserMethods.destroy) - diff --git a/src/actions/users/read.ts b/src/actions/users/read.ts deleted file mode 100644 index b33bd5b5f..000000000 --- a/src/actions/users/read.ts +++ /dev/null @@ -1,25 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { UserMethods } from '@/services/users/methods' -import { GroupMethods } from '@/services/groups/methods' - -/** - * A action to read a page of users with the given details (filtering) - * @param readPageInput - This is a) the page to read and b) the details to filter by like - * name and groups - * @returns - */ -export const readUserPageAction = action(UserMethods.readPage) - -/** - * Action meant to read the profile of a user. - * A profile is a user with more information about them attached. - * @param username - The username of the user to read - * @returns - The profile of the user - */ -export const readUserProfileAction = action(UserMethods.readProfile) - -export const readUserAction = action(UserMethods.read) - -export const readGroupsForPageFilteringAction = action(GroupMethods.readGroupsExpanded) - diff --git a/src/actions/users/update.ts b/src/actions/users/update.ts deleted file mode 100644 index 6be51862e..000000000 --- a/src/actions/users/update.ts +++ /dev/null @@ -1,8 +0,0 @@ -'use server' -import { action } from '@/actions/action' -import { UserMethods } from '@/services/users/methods' - -export const updateUserAction = action(UserMethods.update) -export const registerNewEmailAction = action(UserMethods.registerNewEmail) -export const registerUser = action(UserMethods.register) -export const registerStudentCardInQueueAction = action(UserMethods.registerStudentCardInQueue) diff --git a/src/actions/visibility/Types.ts b/src/actions/visibility/Types.ts deleted file mode 100644 index 66d6e0cc2..000000000 --- a/src/actions/visibility/Types.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' - -export type VisibilityRequiermentForAdmin = { - name: string - groups: (ExpandedGroup & { - selected: boolean - })[] -} - -export type VisibilityStructuredForAdmin = { - published: boolean - purpose: string -} & ( - { - type: 'REGULAR' - groups: GroupsStructured - regular: VisibilityRequiermentForAdmin[] - admin: VisibilityRequiermentForAdmin[] - } | { - type: 'SPECIAL' - message: string - regular: string - admin: string - } -) diff --git a/src/actions/visibility/read.ts b/src/actions/visibility/read.ts deleted file mode 100644 index 3533188c2..000000000 --- a/src/actions/visibility/read.ts +++ /dev/null @@ -1,129 +0,0 @@ -'use server' -import { safeServerCall } from '@/actions/safeServerCall' -import { createActionError } from '@/actions/error' -import { readVisibilityCollapsed } from '@/services/visibility/read' -import { checkVisibility } from '@/auth/checkVisibility' -import { getUser } from '@/auth/getUser' -import { PurposeTextsConfig } from '@/services/visibility/ConfigVars' -import { GroupTypesConfig } from '@/services/groups/config' -import { GroupMethods } from '@/services/groups/methods' -import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' -import type { GroupMatrix } from '@/services/visibility/Types' -import type { ActionReturn } from '@/actions/Types' -import type { GroupType } from '@prisma/client' -import type { VisibilityRequiermentForAdmin, VisibilityStructuredForAdmin } from './Types' - -export async function readVisibilityForAdminAction(id: number): Promise> { - const [visibilityRes, groupsRes] = await Promise.all([ - safeServerCall(() => readVisibilityCollapsed(id)), - // TODO: Fix Authing here. The bypass should be false - safeServerCall(() => GroupMethods.readGroupsStructured({ session: null, bypassAuth: true })) - ]) - if (!visibilityRes.success || !groupsRes.success) return createActionError('UNKNOWN ERROR', 'noe gikk galt') - - const visibility = visibilityRes.data - const groups = groupsRes.data - const purpose = PurposeTextsConfig[visibility.purpose] - - if (!checkVisibility(await getUser(), visibility, 'ADMIN')) { - return createActionError('UNAUTHORIZED', 'You do not have permission to admin this collection') - } - if (visibility.type === 'SPECIAL') { - return { - success: true, - data: { - published: visibility.published, - purpose, - type: 'SPECIAL', - message: 'Denne syneligheten er spessiell', - regular: `Brukere med ${visibility.regular} har vanlig tilgang`, - admin: `Brukere med ${visibility.admin} har admin tilgang`, - } - } - } - const standardGroupingsRefular = ['CLASS', 'OMEGA_MEMBERSHIP_GROUP', 'STUDY_PROGRAMME'] satisfies GroupType[] - const standardGroupingsAdmin = ['COMMITTEE', 'OMEGA_MEMBERSHIP_GROUP'] satisfies GroupType[] - return { - success: true, - data: { - published: visibility.published, - purpose, - type: 'REGULAR', - regular: expandOneLevel(visibility.regular, groups, standardGroupingsRefular), - admin: expandOneLevel(visibility.admin, groups, standardGroupingsAdmin), - groups, - } - } -} - -function expandOneLevel( - matrix: GroupMatrix, - groups: GroupsStructured, - standardGroupings: GroupType[] -): VisibilityRequiermentForAdmin[] { - const res: VisibilityRequiermentForAdmin[] = [] - standardGroupings.forEach(groupType => { - if (!groups[groupType]) return - const standardRequriment: VisibilityRequiermentForAdmin = { - name: GroupTypesConfig[groupType].name, - groups: groups[groupType].groups.map(group => ({ - ...group, - selected: false - })) - } - //Find out if there is a row in the matrix with just the group type. - for (let i = 0; i < matrix.length; i++) { - if (matrix[i].every(groupId => groupTypeOfId(groupId, groups) === groupType)) { - standardRequriment.groups.forEach(group => { - group.selected = matrix[i].includes(group.id) - }) - //Remove the row from the matrix since it has been handled - matrix.splice(i, 1) - } - } - res.push(standardRequriment) - }) - - //Handle all non standard groupings - matrix.forEach(row => { - const groups_ = row.reduce((acc, id) => { - const group = findGroupOfId(id, groups) - if (group) acc.push(group) - return acc - }, [] as ExpandedGroup[]) - const nonStandardRequriment: VisibilityRequiermentForAdmin = { - name: 'ekstra', - groups: groups_.map(group => ({ - ...group, - selected: true - })) - } - res.push(nonStandardRequriment) - }) - - return res -} - -function findGroupOfId(id: number, groups: GroupsStructured): ExpandedGroup | null { - let found: ExpandedGroup | null = null - Object.values(groups).forEach(groupType => { - groupType.groups.forEach(group => { - if (group.id === id) { - found = group - } - }) - }) - return found -} - -function groupTypeOfId(id: number, groups: GroupsStructured): GroupType { - let type: GroupType | null = null - Object.values(groups).forEach((groupType) => { - groupType.groups.forEach(group => { - if (group.id === id) { - type = group.groupType - } - }) - }) - return type || 'MANUAL_GROUP' -} diff --git a/src/actions/visibility/update.ts b/src/actions/visibility/update.ts deleted file mode 100644 index 5cb0ae162..000000000 --- a/src/actions/visibility/update.ts +++ /dev/null @@ -1,11 +0,0 @@ -'use server' -import type { VisibilityLevelType } from '@/services/visibility/Types' -import type { ActionReturn } from '@/actions/Types' - -export async function updateVisibilityAction( - level: VisibilityLevelType, - formdata: FormData -): Promise> { - console.log(formdata) - return { success: true, data: undefined } -} From 3df5c0d58c7847f1c651b5759abea2a2d9cd0984 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 22 Aug 2025 22:22:18 +0200 Subject: [PATCH 08/24] refactor: rename action utils --- src/actions/safeServerCall.ts | 28 -------- src/app/_components/Company/Company.tsx | 2 +- src/app/_components/Event/EventTagsAdmin.tsx | 2 +- src/app/_components/Form/Form.tsx | 2 +- src/app/_components/Image/ImageUploader.tsx | 2 +- .../admission/[admission]/registration.tsx | 2 +- src/app/admin/mail/[filter]/[id]/MailFlow.tsx | 2 +- src/app/admin/mail/[filter]/[id]/mailList.tsx | 4 +- .../admin/mail/[filter]/[id]/mailListItem.tsx | 2 +- .../[currentId]/channelSettings.tsx | 2 +- .../addNotificationChannel.tsx | 2 +- .../jobads/[...orderAndName]/EditJobAd.tsx | 2 +- src/app/events/CreateOrUpdateEventForm.tsx | 2 +- .../[order]/[name]/ManualRegistrationForm.tsx | 4 +- .../events/[order]/[name]/RegistrationUI.tsx | 2 +- .../[order]/[name]/RegistrationsList.tsx | 2 +- src/app/events/[order]/[name]/page.tsx | 2 +- .../[id]/CollectionAdminUpload.tsx | 2 +- .../[id]/CreateLockerReservationForm.tsx | 2 +- .../[id]/UpdateLockerReservationForm.tsx | 2 +- src/app/redirectToErrorPage.ts | 2 +- src/contexts/paging/PagingGenerator.tsx | 2 +- src/hooks/useActionCall.ts | 4 +- src/lib/jwt/parseJWTClient.ts | 4 +- src/{actions => services}/action.ts | 4 +- src/services/actionBind.ts | 25 +++++++ src/services/actionError.ts | 65 +++++++++++++++++++ src/services/actionTypes.ts | 24 +++++++ src/services/admission/actions.ts | 2 +- src/services/api-keys/actions.ts | 2 +- src/services/applications/actions.ts | 2 +- src/services/applications/periods/actions.ts | 2 +- src/services/auth/actions.ts | 2 +- src/services/cabin/actions.ts | 2 +- src/services/career/companies/actions.ts | 2 +- src/services/career/jobAds/actions.ts | 2 +- src/services/cms/articleCategories/actions.ts | 6 +- src/services/cms/articleSections/actions.ts | 6 +- src/services/cms/articles/actions.ts | 6 +- src/services/cms/images/actions.ts | 6 +- src/services/cms/links/actions.ts | 8 +-- src/services/cms/paragraphs/actions.ts | 6 +- src/services/dots/actions.ts | 2 +- src/services/education/courses/actions.ts | 2 +- src/services/education/schools/actions.ts | 6 +- src/services/events/actions.ts | 2 +- src/services/events/registration/actions.ts | 2 +- src/services/events/tags/actions.ts | 2 +- src/services/groups/actions.ts | 2 +- src/services/groups/committees/actions.ts | 8 +-- src/services/groups/interestGroups/actions.ts | 2 +- src/services/groups/memberships/actions.ts | 6 +- .../groups/studyProgrammes/actions.ts | 6 +- src/services/images/actions.ts | 2 +- src/services/images/collections/actions.ts | 6 +- src/services/licenses/actions.ts | 2 +- src/services/lockers/actions.ts | 2 +- src/services/mail/actions.ts | 6 +- src/services/mail/alias/actions.ts | 6 +- src/services/mail/list/actions.ts | 6 +- .../mail/mailAddressExternal/actions.ts | 6 +- src/services/news/actions.ts | 6 +- src/services/notifications/actions.ts | 2 +- src/services/ombul/actions.ts | 6 +- src/services/omegaOrder/actions.ts | 6 +- src/services/omegaid/actions.ts | 4 +- src/services/omegaid/compress.ts | 2 +- src/services/omegaquotes/actions.ts | 6 +- src/services/permissions/actions.ts | 2 +- src/services/screens/actions.ts | 6 +- src/services/screens/pages/actions.ts | 6 +- src/services/sendmail/actions.ts | 6 +- src/services/shop/actions.ts | 2 +- src/services/users/actions.ts | 2 +- src/services/visibility/actions.ts | 6 +- 75 files changed, 239 insertions(+), 153 deletions(-) delete mode 100644 src/actions/safeServerCall.ts rename src/{actions => services}/action.ts (96%) create mode 100644 src/services/actionBind.ts create mode 100644 src/services/actionError.ts create mode 100644 src/services/actionTypes.ts diff --git a/src/actions/safeServerCall.ts b/src/actions/safeServerCall.ts deleted file mode 100644 index 32ddeb90f..000000000 --- a/src/actions/safeServerCall.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { createActionError, createZodActionError } from './actionError' -import { ParseError, Smorekopp } from '@/services/error' -import type { ActionReturn } from './actionTypes' - -/** - * A function that calls a server function. If all goes well, it returns a ActionReturn with the data. - * If an error is thrown it returns ActionReturn of success false and the error. - * The function handles ServerErrors class, and treats all other errors as unknown. - * @param call - A async server function to call. - * @returns - A promise that resolves to an ActionReturn. - */ -export async function safeServerCall(call: () => Promise): Promise> { - try { - const data = await call() - return { - success: true, - data - } - } catch (error) { - if (error instanceof ParseError) { - return createZodActionError(error.parseError) - } - if (error instanceof Smorekopp) { - return createActionError(error.errorCode, error.errors) - } - return createActionError('UNKNOWN ERROR', 'unknown error') - } -} diff --git a/src/app/_components/Company/Company.tsx b/src/app/_components/Company/Company.tsx index 16605b1e3..93e5afaef 100644 --- a/src/app/_components/Company/Company.tsx +++ b/src/app/_components/Company/Company.tsx @@ -7,7 +7,7 @@ import CmsImageClient from '@/cms/CmsImage/CmsImageClient' import Form from '@/components/Form/Form' import { updateComanyAction } from '@/actions/career/companies/update' import { destroyCompanyAction } from '@/actions/career/companies/destroy' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { CompanyAuthers } from '@/services/career/companies/authers' import type { CompanyExpanded } from '@/services/career/companies/Types' import type { SessionMaybeUser } from '@/auth/Session' diff --git a/src/app/_components/Event/EventTagsAdmin.tsx b/src/app/_components/Event/EventTagsAdmin.tsx index 78e7b3328..19639afcf 100644 --- a/src/app/_components/Event/EventTagsAdmin.tsx +++ b/src/app/_components/Event/EventTagsAdmin.tsx @@ -9,7 +9,7 @@ import ColorInput from '@/UI/ColorInput' import { updateEventTagAction } from '@/actions/events/tags/update' import { QueryParams } from '@/lib/query-params/queryParams' import { destroyEventTagAction } from '@/actions/events/tags/destroy' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import Link from 'next/link' import type { EventTag as EventTagT } from '@prisma/client' diff --git a/src/app/_components/Form/Form.tsx b/src/app/_components/Form/Form.tsx index 0e6605d33..124ab7f24 100644 --- a/src/app/_components/Form/Form.tsx +++ b/src/app/_components/Form/Form.tsx @@ -9,7 +9,7 @@ import { useRouter } from 'next/navigation' import type { PopUpKeyType } from '@/contexts/PopUp' import type { Colors, Confirmation } from '@/components/UI/SubmitButton' import type { FormHTMLAttributes, ReactNode, DetailedHTMLProps } from 'react' -import type { Action } from '@/actions/Types' +import type { Action } from '@/services/actionTypes' import type { ErrorMessage } from '@/services/error' type FormType = DetailedHTMLProps, HTMLFormElement> diff --git a/src/app/_components/Image/ImageUploader.tsx b/src/app/_components/Image/ImageUploader.tsx index ef0f3decc..b883553c4 100644 --- a/src/app/_components/Image/ImageUploader.tsx +++ b/src/app/_components/Image/ImageUploader.tsx @@ -3,7 +3,7 @@ import { createImageAction } from '@/actions/images/create' import TextInput from '@/components/UI/TextInput' import FileInput from '@/components/UI/FileInput' import LicenseChooser from '@/components/LicenseChooser/LicenseChooser' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import type { PropTypes as FormPropTypes } from '@/components/Form/Form' type ResponseType = Awaited>; diff --git a/src/app/admin/admission/[admission]/registration.tsx b/src/app/admin/admission/[admission]/registration.tsx index a16b0b76f..5e4bddd2a 100644 --- a/src/app/admin/admission/[admission]/registration.tsx +++ b/src/app/admin/admission/[admission]/registration.tsx @@ -1,7 +1,7 @@ 'use client' import styles from './registration.module.scss' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { createAdmissionTrialAction } from '@/actions/admission/create' import Form from '@/components/Form/Form' import OmegaIdReader from '@/components/OmegaId/reader/OmegaIdReader' diff --git a/src/app/admin/mail/[filter]/[id]/MailFlow.tsx b/src/app/admin/mail/[filter]/[id]/MailFlow.tsx index c2ea0f0e3..5533b1638 100644 --- a/src/app/admin/mail/[filter]/[id]/MailFlow.tsx +++ b/src/app/admin/mail/[filter]/[id]/MailFlow.tsx @@ -9,7 +9,7 @@ import { destroyMailingListUserRelationAction } from '@/actions/mail/destroy' import { useUser } from '@/auth/useUser' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { MailFlowObject, MailListTypes } from '@/services/mail/Types' type DestroyFunction = null | ((id: number) => Promise>) diff --git a/src/app/admin/mail/[filter]/[id]/mailList.tsx b/src/app/admin/mail/[filter]/[id]/mailList.tsx index bf3b48b35..b37c6f8b0 100644 --- a/src/app/admin/mail/[filter]/[id]/mailList.tsx +++ b/src/app/admin/mail/[filter]/[id]/mailList.tsx @@ -2,10 +2,10 @@ import MailListItem from './mailListItem' import styles from './mailList.module.scss' -import { createActionError } from '@/actions/error' +import { createActionError } from '@/services/actionError' import { v4 as uuid } from 'uuid' import { useState } from 'react' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { MailListTypes, ViaArrayType } from '@/services/mail/Types' import type { Group, MailAddressExternal, MailAlias, MailingList } from '@prisma/client' import type { UserFiltered } from '@/services/users/Types' diff --git a/src/app/admin/mail/[filter]/[id]/mailListItem.tsx b/src/app/admin/mail/[filter]/[id]/mailListItem.tsx index 5b128b49f..90fce6926 100644 --- a/src/app/admin/mail/[filter]/[id]/mailListItem.tsx +++ b/src/app/admin/mail/[filter]/[id]/mailListItem.tsx @@ -6,7 +6,7 @@ import { notFound } from 'next/navigation' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faTrashCan } from '@fortawesome/free-solid-svg-icons' import { v4 as uuid } from 'uuid' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { MailListTypes, ViaArrayType } from '@/services/mail/Types' export default function MailListItem({ diff --git a/src/app/admin/notification-channels/[currentId]/channelSettings.tsx b/src/app/admin/notification-channels/[currentId]/channelSettings.tsx index e6293c818..d2cf006d8 100644 --- a/src/app/admin/notification-channels/[currentId]/channelSettings.tsx +++ b/src/app/admin/notification-channels/[currentId]/channelSettings.tsx @@ -7,7 +7,7 @@ import { SelectNumber } from '@/components/UI/Select' import Form from '@/components/Form/Form' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { updateNotificationChannelAction } from '@/actions/notifications' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { NotificationChannelSchemas } from '@/services/notifications/channel/schemas' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' import { useState } from 'react' diff --git a/src/app/admin/notification-channels/addNotificationChannel.tsx b/src/app/admin/notification-channels/addNotificationChannel.tsx index 5cf8915c8..bed188fbd 100644 --- a/src/app/admin/notification-channels/addNotificationChannel.tsx +++ b/src/app/admin/notification-channels/addNotificationChannel.tsx @@ -5,7 +5,7 @@ import { SelectNumber } from '@/components/UI/Select' import NotificationMethodSelector from '@/components/NotificaionMethodSelector/NotificaionMethodSelector' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' import { createNotificationChannelAction } from '@/actions/notifications' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { NotificationConfig } from '@/services/notifications/config' import { useState } from 'react' import { useRouter } from 'next/navigation' diff --git a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx index 43f50bdfb..c96244b5e 100644 --- a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx +++ b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx @@ -12,7 +12,7 @@ import DateInput from '@/components/UI/DateInput' import Slider from '@/app/_components/UI/Slider' import { CompanyPagingContext } from '@/contexts/paging/CompanyPaging' import CompanyChooser from '@/app/career/jobads/CompanyChooser' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { JobAdConfig } from '@/services/career/jobAds/config' import { v4 as uuid } from 'uuid' import { useContext, type ReactNode } from 'react' diff --git a/src/app/events/CreateOrUpdateEventForm.tsx b/src/app/events/CreateOrUpdateEventForm.tsx index 3f62a74f5..c226fdcf0 100644 --- a/src/app/events/CreateOrUpdateEventForm.tsx +++ b/src/app/events/CreateOrUpdateEventForm.tsx @@ -11,7 +11,7 @@ import { EventConfig } from '@/services/events/config' import { updateEventAction } from '@/actions/events/update' import { createEventAction } from '@/actions/events/create' import EventTag from '@/components/Event/EventTag' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { FIELD_IS_PRESENT_VALUE } from '@/lib/fields/config' import { useState } from 'react' import type { Event, EventTag as EventTagT } from '@prisma/client' diff --git a/src/app/events/[order]/[name]/ManualRegistrationForm.tsx b/src/app/events/[order]/[name]/ManualRegistrationForm.tsx index 763dc537d..00e167ab3 100644 --- a/src/app/events/[order]/[name]/ManualRegistrationForm.tsx +++ b/src/app/events/[order]/[name]/ManualRegistrationForm.tsx @@ -6,10 +6,10 @@ import UserList from '@/components/User/UserList/UserList' import UserPagingProvider from '@/contexts/paging/UserPaging' import UserSelectionProvider, { UserSelectionContext } from '@/contexts/UserSelection' import TextInput from '@/components/UI/TextInput' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { useContext } from 'react' import type { EventRegistration } from '@prisma/client' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' function ManualRegistrationFormInner({ eventId, diff --git a/src/app/events/[order]/[name]/RegistrationUI.tsx b/src/app/events/[order]/[name]/RegistrationUI.tsx index d9cae653e..033bcda3d 100644 --- a/src/app/events/[order]/[name]/RegistrationUI.tsx +++ b/src/app/events/[order]/[name]/RegistrationUI.tsx @@ -7,7 +7,7 @@ import { } from '@/actions/events/registration' import CountDown from '@/components/countDown/CountDown' import Form from '@/components/Form/Form' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import TextInput from '@/components/UI/TextInput' import SubmitButton from '@/components/UI/SubmitButton' import { useEffect, useState } from 'react' diff --git a/src/app/events/[order]/[name]/RegistrationsList.tsx b/src/app/events/[order]/[name]/RegistrationsList.tsx index 696b36df2..c24e4019f 100644 --- a/src/app/events/[order]/[name]/RegistrationsList.tsx +++ b/src/app/events/[order]/[name]/RegistrationsList.tsx @@ -9,7 +9,7 @@ import EventRegistrationDetailedPagingProvider, { import UserDisplayName from '@/components/User/UserDisplayName' import Slider from '@/components/UI/Slider' import Form from '@/components/Form/Form' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { eventRegistrationDestroyAction } from '@/actions/events/registration' import { EventRegistrationConfig } from '@/services/events/registration/config' import ContactCard from '@/components/User/ContactCard' diff --git a/src/app/events/[order]/[name]/page.tsx b/src/app/events/[order]/[name]/page.tsx index 4bf56e409..0c5311e3f 100644 --- a/src/app/events/[order]/[name]/page.tsx +++ b/src/app/events/[order]/[name]/page.tsx @@ -14,7 +14,7 @@ import { destroyEventAction } from '@/actions/events/destroy' import { SettingsHeaderItemPopUp, UsersHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import { readEventTagsAction } from '@/actions/events/tags/read' import { QueryParams } from '@/lib/query-params/queryParams' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import Link from 'next/link' import { faCalendar, faExclamation, faLocationDot, faUsers } from '@fortawesome/free-solid-svg-icons' diff --git a/src/app/images/collections/[id]/CollectionAdminUpload.tsx b/src/app/images/collections/[id]/CollectionAdminUpload.tsx index b8967011f..df60e7e7e 100644 --- a/src/app/images/collections/[id]/CollectionAdminUpload.tsx +++ b/src/app/images/collections/[id]/CollectionAdminUpload.tsx @@ -10,7 +10,7 @@ import LicenseChooser from '@/app/_components/LicenseChooser/LicenseChooser' import { ImageConfig } from '@/services/images/config' import { useCallback, useState } from 'react' import type { FileWithStatus } from '@/components/UI/Dropzone' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' type PropTypes = { collectionId: number diff --git a/src/app/lockers/[id]/CreateLockerReservationForm.tsx b/src/app/lockers/[id]/CreateLockerReservationForm.tsx index ba42c7561..65600e6a3 100644 --- a/src/app/lockers/[id]/CreateLockerReservationForm.tsx +++ b/src/app/lockers/[id]/CreateLockerReservationForm.tsx @@ -4,7 +4,7 @@ import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' import DateInput from '@/components/UI/DateInput' import Checkbox from '@/components/UI/Checkbox' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import React, { useState } from 'react' import { useRouter } from 'next/navigation' diff --git a/src/app/lockers/[id]/UpdateLockerReservationForm.tsx b/src/app/lockers/[id]/UpdateLockerReservationForm.tsx index c525eeeef..7b151ad71 100644 --- a/src/app/lockers/[id]/UpdateLockerReservationForm.tsx +++ b/src/app/lockers/[id]/UpdateLockerReservationForm.tsx @@ -4,7 +4,7 @@ import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' import DateInput from '@/components/UI/DateInput' import Checkbox from '@/components/UI/Checkbox' -import { bindParams } from '@/actions/bind' +import { bindParams } from '@/services/actionBind' import { useState } from 'react' import { useRouter } from 'next/navigation' diff --git a/src/app/redirectToErrorPage.ts b/src/app/redirectToErrorPage.ts index e587b8d90..e6ee067af 100644 --- a/src/app/redirectToErrorPage.ts +++ b/src/app/redirectToErrorPage.ts @@ -1,5 +1,5 @@ import { errorCodes } from '@/services/error' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { ErrorCode } from '@/services/error' /** diff --git a/src/contexts/paging/PagingGenerator.tsx b/src/contexts/paging/PagingGenerator.tsx index e356910c4..68c094e1d 100644 --- a/src/contexts/paging/PagingGenerator.tsx +++ b/src/contexts/paging/PagingGenerator.tsx @@ -1,7 +1,7 @@ 'use client' import React, { createContext, useState, useRef, useEffect } from 'react' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { ReadPageInput, Page } from '@/lib/paging/Types' import type { Context as ReactContextType } from 'react' diff --git a/src/hooks/useActionCall.ts b/src/hooks/useActionCall.ts index ddc724aaf..090974758 100644 --- a/src/hooks/useActionCall.ts +++ b/src/hooks/useActionCall.ts @@ -1,7 +1,7 @@ 'use client' -import { createActionError } from '@/actions/error' +import { createActionError } from '@/services/actionError' import { useState, useEffect } from 'react' -import type { ActionReturn, ActionReturnError } from '@/actions/Types' +import type { ActionReturn, ActionReturnError } from '@/services/actionTypes' /** * You sometimes want to call a server action that reads from the client. This hook helps with that. diff --git a/src/lib/jwt/parseJWTClient.ts b/src/lib/jwt/parseJWTClient.ts index 9a4405354..2cd64d5b4 100644 --- a/src/lib/jwt/parseJWTClient.ts +++ b/src/lib/jwt/parseJWTClient.ts @@ -1,10 +1,10 @@ 'use client' import { readJWTPayload } from './jwtReadUnsecure' -import { createActionError } from '@/actions/error' +import { createActionError } from '@/services/actionError' import { JWT_ISSUER } from '@/jwt/ConfigVars' import type { OmegaJWTAudience } from '@/jwt/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' /** * Parses a JSON Web Token (JWT) and verifies its signature using the provided public key. diff --git a/src/actions/action.ts b/src/services/action.ts similarity index 96% rename from src/actions/action.ts rename to src/services/action.ts index b8dc127a8..b10e3b1c9 100644 --- a/src/actions/action.ts +++ b/src/services/action.ts @@ -1,7 +1,7 @@ import '@pn-server-only' -import { safeServerCall } from './safeServerCall' +import { safeServerCall } from './actionError' import { Session } from '@/auth/Session' -import type { ActionReturn } from './Types' +import type { ActionReturn } from './actionTypes' import type { ServiceMethodExecuteArgs, ServiceMethodType } from '@/services/ServiceMethod' import type { z } from 'zod' diff --git a/src/services/actionBind.ts b/src/services/actionBind.ts new file mode 100644 index 000000000..322337999 --- /dev/null +++ b/src/services/actionBind.ts @@ -0,0 +1,25 @@ +/** + * A simple utility function to bind parameters to an action. + * Under the hood this function simply calls "action.bind(null, params)", + * but it is more readable to use this function. + * + * @param action - An action that takes parameters. + * @param params - The parameters to bind to the action. + * @returns - The same action with the parameters bound to it. + */ +export function bindParams(action: (p: P, ...dataArgs: D) => R, params: P) { + return action.bind(null, params) +} + +/** + * A simple utility function to bind data to an action. + * Under the hood this function simply calls "action.bind(null, data)", + * but it is more readable to use this function. + * + * @param action - An action that takes data. + * @param bindData - The data to bind to the action. + * @returns - The same action with the data bound to it. + */ +export function bindData(action: (dataValue: D) => R, data: D) { + return action.bind(null, data) +} diff --git a/src/services/actionError.ts b/src/services/actionError.ts new file mode 100644 index 000000000..0ae9e3e3e --- /dev/null +++ b/src/services/actionError.ts @@ -0,0 +1,65 @@ +import { errorCodes, type ErrorCode, type ErrorMessage } from '@/services/error' +import { ParseError, Smorekopp } from '@/services/error' +import type { AuthStatus } from '@/auth/getUser' +import type { SafeParseError } from 'zod' +import type { ActionReturnError } from './actionTypes' +import type { ActionReturn } from './actionTypes' + +/** + * @deprecated With the "new" service method system this should not be called directly. + * The action creation utility should handle this internally. + */ +export function createActionError(errorCode: ErrorCode | AuthStatus, error?: string | ErrorMessage[]): ActionReturnError { + if (errorCode === 'AUTHORIZED' || errorCode === 'AUTHORIZED_NO_USER') { + return { + success: false, + errorCode: 'UNKNOWN ERROR', + httpCode: 500, + error: typeof error === 'string' ? [{ message: error }] : error, + } + } + return { + success: false, + errorCode, + httpCode: errorCodes.find(e => e.name === errorCode)?.httpCode ?? 500, + error: typeof error === 'string' ? [{ message: error }] : error, + } +} + +/** + * @deprecated With the "new" service method system this should not be called directly. + * The action creation utility should handle this internally. + */ +export function createZodActionError(parse: SafeParseError): ActionReturnError { + return { + success: false, + httpCode: 400, + errorCode: 'BAD PARAMETERS', + error: parse.error.issues, + } +} + +/** + * A function that calls a server function. If all goes well, it returns a ActionReturn with the data. + * If an error is thrown it returns ActionReturn of success false and the error. + * The function handles ServerErrors class, and treats all other errors as unknown. + * @param call - A async server function to call. + * @returns - A promise that resolves to an ActionReturn. + */ +export async function safeServerCall(call: () => Promise): Promise> { + try { + const data = await call() + return { + success: true, + data + } + } catch (error) { + if (error instanceof ParseError) { + return createZodActionError(error.parseError) + } + if (error instanceof Smorekopp) { + return createActionError(error.errorCode, error.errors) + } + return createActionError('UNKNOWN ERROR', 'unknown error') + } +} diff --git a/src/services/actionTypes.ts b/src/services/actionTypes.ts new file mode 100644 index 000000000..dcdff4409 --- /dev/null +++ b/src/services/actionTypes.ts @@ -0,0 +1,24 @@ +import type { ErrorMessage, ErrorCode } from '@/services/error' + +export type ActionReturnError = { + success: false, + errorCode: ErrorCode, + httpCode: number, + error?: ErrorMessage[], +} + +export type ActionReturn = ( + ActionReturnError +) | { + success: true, +} & ( + DataGuarantee extends true ? { + data: ReturnType + } : { + data?: ReturnType + } +) + +export type Action = (formData: FormData) => ( + Promise> +) diff --git a/src/services/admission/actions.ts b/src/services/admission/actions.ts index a428c561f..49ab11c0f 100644 --- a/src/services/admission/actions.ts +++ b/src/services/admission/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { AdmissionMethods } from '@/services/admission/methods' export const createAdmissionTrialAction = action(AdmissionMethods.createTrial) diff --git a/src/services/api-keys/actions.ts b/src/services/api-keys/actions.ts index 8a2274ffd..4cd3defe9 100644 --- a/src/services/api-keys/actions.ts +++ b/src/services/api-keys/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { ApiKeyMethods } from '@/services/api-keys/methods' export const createApiKeyAction = action(ApiKeyMethods.create) diff --git a/src/services/applications/actions.ts b/src/services/applications/actions.ts index 7b39df1a6..0c63bc9ff 100644 --- a/src/services/applications/actions.ts +++ b/src/services/applications/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { ApplicationMethods } from '@/services/applications/methods' export const createApplicationAction = action(ApplicationMethods.create) diff --git a/src/services/applications/periods/actions.ts b/src/services/applications/periods/actions.ts index a941d7a1b..bf2df977a 100644 --- a/src/services/applications/periods/actions.ts +++ b/src/services/applications/periods/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { ApplicationPeriodMethods } from '@/services/applications/periods/methods' export const createApplicationPeriodAction = action(ApplicationPeriodMethods.create) diff --git a/src/services/auth/actions.ts b/src/services/auth/actions.ts index b25fd7781..6f624c393 100644 --- a/src/services/auth/actions.ts +++ b/src/services/auth/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { AuthMethods } from '@/services/auth/methods' export const verifyResetPasswordTokenAction = action(AuthMethods.verifyResetPasswordToken) diff --git a/src/services/cabin/actions.ts b/src/services/cabin/actions.ts index 8f8fdfbd6..e9ad95e0b 100644 --- a/src/services/cabin/actions.ts +++ b/src/services/cabin/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { CabinBookingMethods } from '@/services/cabin/booking/methods' import { CabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' import { CabinProductMethods } from '@/services/cabin/product/methods' diff --git a/src/services/career/companies/actions.ts b/src/services/career/companies/actions.ts index c9b88dab6..12bdbde6d 100644 --- a/src/services/career/companies/actions.ts +++ b/src/services/career/companies/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { CompanyMethods } from '@/services/career/companies/methods' export const createCompanyAction = action(CompanyMethods.create) diff --git a/src/services/career/jobAds/actions.ts b/src/services/career/jobAds/actions.ts index bfa11fca5..f5c5d0a51 100644 --- a/src/services/career/jobAds/actions.ts +++ b/src/services/career/jobAds/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { JobadMethods } from '@/services/career/jobAds/methods' export const createJobAdAction = action(JobadMethods.create) diff --git a/src/services/cms/articleCategories/actions.ts b/src/services/cms/articleCategories/actions.ts index 760487e42..4f0f7d48f 100644 --- a/src/services/cms/articleCategories/actions.ts +++ b/src/services/cms/articleCategories/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { createArticleCategory } from '@/services/cms/articleCategories/create' import { destroyArticleCategory } from '@/services/cms/articleCategories/destroy' import { readArticleCategories, readArticleCategory } from '@/services/cms/articleCategories/read' @@ -15,7 +15,7 @@ import type { ExpandedArticleCategoryWithCover, ExpandedArticleCategory, } from '@/cms/articleCategories/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateArticleCategoryTypes, UpdateArticleCategoryTypes } from '@/services/cms/articleCategories/validation' export async function createArticleCategoryAction( diff --git a/src/services/cms/articleSections/actions.ts b/src/services/cms/articleSections/actions.ts index d4e96f043..8dbb8afb2 100644 --- a/src/services/cms/articleSections/actions.ts +++ b/src/services/cms/articleSections/actions.ts @@ -1,14 +1,14 @@ 'use server' -import { createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { createArticleSection } from '@/services/cms/articleSections/create' import { destroyArticleSection } from '@/services/cms/articleSections/destroy' import { readArticleSection } from '@/services/cms/articleSections/read' import { addArticleSectionPart, removeArticleSectionPart, updateArticleSection } from '@/services/cms/articleSections/update' import { createArticleSectionValidation } from '@/services/cms/articleSections/validation' import type { ArticleSectionPart, ExpandedArticleSection } from '@/cms/articleSections/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateArticleSectionTypes } from '@/services/cms/articleSections/validation' import type { ArticleSection, Position } from '@prisma/client' diff --git a/src/services/cms/articles/actions.ts b/src/services/cms/articles/actions.ts index 9a3ce7239..eb8ae9e4a 100644 --- a/src/services/cms/articles/actions.ts +++ b/src/services/cms/articles/actions.ts @@ -1,14 +1,14 @@ 'use server' -import { createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { createArticle } from '@/services/cms/articles/create' import { destroyArticle } from '@/services/cms/articles/destroy' import { readArticle } from '@/services/cms/articles/read' import { addSectionToArticle, moveSectionOrder, updateArticle } from '@/services/cms/articles/update' import { createArticleValidation, updateArticleValidation } from '@/services/cms/articles/validation' import type { ExpandedArticle } from '@/cms/articles/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateArticleTypes, UpdateArticleTypes } from '@/services/cms/articles/validation' import type { ArticleSectionPart } from '@/services/cms/articleSections/Types' import type { Article, ArticleSection } from '@prisma/client' diff --git a/src/services/cms/images/actions.ts b/src/services/cms/images/actions.ts index 52c6ccfa9..358558f1e 100644 --- a/src/services/cms/images/actions.ts +++ b/src/services/cms/images/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { createCmsImage } from '@/services/cms/images/create' import { readCmsImage, readSpecialCmsImage } from '@/services/cms/images/read' import { updateCmsImage, updateCmsImageConfig } from '@/services/cms/images/update' @@ -9,7 +9,7 @@ import { baseCmsImageValidation } from '@/services/cms/images/validation' import { SpecialCmsImage } from '@prisma/client' import type { ValidationTypes } from '@/services/Validation' import type { ExpandedCmsImage } from '@/services/cms/images/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CmsImage, Image, ImageSize } from '@prisma/client' export const createCmsImageActionValidation = baseCmsImageValidation.createValidation({ diff --git a/src/services/cms/links/actions.ts b/src/services/cms/links/actions.ts index 199f48cc8..332091d8a 100644 --- a/src/services/cms/links/actions.ts +++ b/src/services/cms/links/actions.ts @@ -1,13 +1,13 @@ 'use server' -import { action } from '@/actions/action' -import { createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { action } from '@/services/action' +import { createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { createCmsLink } from '@/services/cms/links/create' import { readSpecialCmsLink } from '@/services/cms/links/read' import { updateCmsLink } from '@/services/cms/links/update' import { createCmsLinkValidation, updateCmsLinkValidation } from '@/services/cms/links/validation' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateCmsLinkTypes, UpdateCmsLinkTypes } from '@/services/cms/links/validation' import type { CmsLink } from '@prisma/client' diff --git a/src/services/cms/paragraphs/actions.ts b/src/services/cms/paragraphs/actions.ts index f7d2539f8..437050af8 100644 --- a/src/services/cms/paragraphs/actions.ts +++ b/src/services/cms/paragraphs/actions.ts @@ -1,14 +1,14 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { readCmsParagraph, readSpecialCmsParagraph } from '@/services/cms/paragraphs/read' import { updateCmsParagraphContents } from '@/services/cms/paragraphs/update' import { baseCmsParagraphValidation } from '@/services/cms/paragraphs/validation' import { SpecialCmsParagraph } from '@prisma/client' import type { ValidationTypes } from '@/services/Validation' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CmsParagraph } from '@prisma/client' export const createCmsParagraphActionValidation = baseCmsParagraphValidation.createValidation({ diff --git a/src/services/dots/actions.ts b/src/services/dots/actions.ts index c755cd645..1cc90e8bd 100644 --- a/src/services/dots/actions.ts +++ b/src/services/dots/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { dotMethods } from '@/services/dots/methods' export const createDotAction = action(dotMethods.create) diff --git a/src/services/education/courses/actions.ts b/src/services/education/courses/actions.ts index bc4dd5e77..dd53c6904 100644 --- a/src/services/education/courses/actions.ts +++ b/src/services/education/courses/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { safeServerCall } from '@/actions/safeServerCall' +import { safeServerCall } from '@/services/actionError' import type { CreateCourseTypes } from '@/education/courses/validation' export async function createCourseAction(rawdata: FormData | CreateCourseTypes['Type']) { diff --git a/src/services/education/schools/actions.ts b/src/services/education/schools/actions.ts index 7bbef3ee2..6ed2158c7 100644 --- a/src/services/education/schools/actions.ts +++ b/src/services/education/schools/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createSchoolValidation, updateSchoolValidation } from '@/education/schools/validation' import { createSchool } from '@/services/education/schools/create' @@ -11,7 +11,7 @@ import { updateSchool } from '@/services/education/schools/update' import type { ReadPageInput } from '@/lib/paging/Types' import type { CreateSchoolTypes, UpdateSchoolTypes } from '@/education/schools/validation' import type { ExpandedSchool, SchoolCursor, SchoolFiltered } from '@/education/schools/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' export async function createSchoolAction( rawdata: FormData | CreateSchoolTypes['Type'] diff --git a/src/services/events/actions.ts b/src/services/events/actions.ts index 0f780f0cb..d5fe93627 100644 --- a/src/services/events/actions.ts +++ b/src/services/events/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { EventMethods } from '@/services/events/methods' export const createEventAction = action(EventMethods.create) diff --git a/src/services/events/registration/actions.ts b/src/services/events/registration/actions.ts index 2d760678b..f05322b16 100644 --- a/src/services/events/registration/actions.ts +++ b/src/services/events/registration/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { EventRegistrationMethods } from '@/services/events/registration/methods' export const createEventRegistrationAction = action(EventRegistrationMethods.create) diff --git a/src/services/events/tags/actions.ts b/src/services/events/tags/actions.ts index fbeb08743..479d1863e 100644 --- a/src/services/events/tags/actions.ts +++ b/src/services/events/tags/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { EventTagMethods } from '@/services/events/tags/methods' export const createEventTagAction = action(EventTagMethods.create) diff --git a/src/services/groups/actions.ts b/src/services/groups/actions.ts index ce4f39d41..1ba6e20c3 100644 --- a/src/services/groups/actions.ts +++ b/src/services/groups/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { GroupMethods } from '@/services/groups/methods' export const readGroupsAction = action(GroupMethods.readGroups) diff --git a/src/services/groups/committees/actions.ts b/src/services/groups/committees/actions.ts index dd9f1a966..bb87aa87f 100644 --- a/src/services/groups/committees/actions.ts +++ b/src/services/groups/committees/actions.ts @@ -1,15 +1,15 @@ 'use server' -import { action } from '@/actions/action' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { action } from '@/services/action' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createCommittee } from '@/services/groups/committees/create' import { CommitteeMethods } from '@/services/groups/committees/methods' import { updateCommittee } from '@/services/groups/committees/update' import { createCommitteeValidation, updateCommitteeValidation } from '@/services/groups/committees/validation' import type { ExpandedCommittee } from '@/services/groups/committees/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateCommitteeTypes, UpdateCommitteeTypes } from '@/services/groups/committees/validation' export async function createCommitteeAction( diff --git a/src/services/groups/interestGroups/actions.ts b/src/services/groups/interestGroups/actions.ts index 75d59dfe8..4c8faa53d 100644 --- a/src/services/groups/interestGroups/actions.ts +++ b/src/services/groups/interestGroups/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { InterestGroupMethods } from '@/services/groups/interestGroups/methods' export const createInterestGroupAction = action(InterestGroupMethods.create) diff --git a/src/services/groups/memberships/actions.ts b/src/services/groups/memberships/actions.ts index 754dcdb3a..bf0b8d337 100644 --- a/src/services/groups/memberships/actions.ts +++ b/src/services/groups/memberships/actions.ts @@ -1,13 +1,13 @@ 'use server' -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createMembershipsForGroup } from '@/services/groups/memberships/create' import { destoryMembershipOfUser } from '@/services/groups/memberships/destroy' import { updateMembership } from '@/services/groups/memberships/update' import type { ExpandedMembership } from '@/services/groups/memberships/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' /** * WARNING: This action will lead to error if used with group types not in CanEasalyManageMembership diff --git a/src/services/groups/studyProgrammes/actions.ts b/src/services/groups/studyProgrammes/actions.ts index 85f4f8895..490e82576 100644 --- a/src/services/groups/studyProgrammes/actions.ts +++ b/src/services/groups/studyProgrammes/actions.ts @@ -1,13 +1,13 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createStudyProgramme } from '@/services/groups/studyProgrammes/create' import { readStudyProgrammes } from '@/services/groups/studyProgrammes/read' import { updateStudyProgramme } from '@/services/groups/studyProgrammes/update' import { createStudyProgrammeValidation, updateStudyProgrammeValidation } from '@/services/groups/studyProgrammes/validation' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { StudyProgramme } from '@prisma/client' export async function createStudyProgrammeAction(rawdata: FormData): Promise> { diff --git a/src/services/images/actions.ts b/src/services/images/actions.ts index 100e44681..4ffe7d95b 100644 --- a/src/services/images/actions.ts +++ b/src/services/images/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { ImageMethods } from '@/services/images/methods' export const createImageAction = action(ImageMethods.create) diff --git a/src/services/images/collections/actions.ts b/src/services/images/collections/actions.ts index d7a18e8ee..1e8fc969d 100644 --- a/src/services/images/collections/actions.ts +++ b/src/services/images/collections/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { checkVisibility } from '@/auth/checkVisibility' import { getUser } from '@/auth/getUser' import { getVisibilityFilter } from '@/auth/getVisibilityFilter' @@ -21,7 +21,7 @@ import type { ExpandedImageCollection, ImageCollectionCursor, ImageCollectionPageReturn } from '@/services/images/collections/Types' import type { ReadPageInput } from '@/lib/paging/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { ImageCollection } from '@prisma/client' export async function createImageCollectionAction( diff --git a/src/services/licenses/actions.ts b/src/services/licenses/actions.ts index 1de4702bb..f6043b3d2 100644 --- a/src/services/licenses/actions.ts +++ b/src/services/licenses/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { LicenseMethods } from '@/services/licenses/methods' export const createLicenseAction = action(LicenseMethods.create) diff --git a/src/services/lockers/actions.ts b/src/services/lockers/actions.ts index 670617f02..2cdf11090 100644 --- a/src/services/lockers/actions.ts +++ b/src/services/lockers/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { LockerLocationMethods } from '@/services/lockers/locations/methods' import { LockerMethods } from '@/services/lockers/methods' import { LockerReservationMethods } from '@/services/lockers/reservations/methods' diff --git a/src/services/mail/actions.ts b/src/services/mail/actions.ts index 166ef1054..51888825c 100644 --- a/src/services/mail/actions.ts +++ b/src/services/mail/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { readMailAliases } from '@/services/mail/alias/read' import { @@ -23,7 +23,7 @@ import { createMailingListGroupValidation, createMailingListUserValidation } from '@/services/mail/validation' import type { MailListTypes } from '@/services/mail/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateAliasMailingListType, CreateMailingListExternalType, CreateMailingListGroupType, diff --git a/src/services/mail/alias/actions.ts b/src/services/mail/alias/actions.ts index df5bb03e9..2999ad0a9 100644 --- a/src/services/mail/alias/actions.ts +++ b/src/services/mail/alias/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createMailAlias } from '@/services/mail/alias/create' import { destroyMailAlias } from '@/services/mail/alias/destroy' @@ -12,7 +12,7 @@ import { destoryMailAliasValidation, updateMailAliasValidation, } from '@/services/mail/alias/validation' -import type { ActionReturn } from '@/actions//Types' +import type { ActionReturn } from '@/services/actionTypes' import type { MailAlias } from '@prisma/client' export async function createMailAliasAction(rawdata: FormData): diff --git a/src/services/mail/list/actions.ts b/src/services/mail/list/actions.ts index 1b9040a0e..c8fa86eaf 100644 --- a/src/services/mail/list/actions.ts +++ b/src/services/mail/list/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createMailingList } from '@/services/mail/list/create' import { destroyMailingList } from '@/services/mail/list/destroy' @@ -11,7 +11,7 @@ import { readMailingListValidation, updateMailingListValidation } from '@/services/mail/list/validation' -import type { ActionReturn } from '@/actions//Types' +import type { ActionReturn } from '@/services/actionTypes' import type { MailingList } from '@prisma/client' export async function createMailingListAction(rawdata: FormData): diff --git a/src/services/mail/mailAddressExternal/actions.ts b/src/services/mail/mailAddressExternal/actions.ts index 4d2ca8b23..fd29163fd 100644 --- a/src/services/mail/mailAddressExternal/actions.ts +++ b/src/services/mail/mailAddressExternal/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createMailAddressExternal } from '@/services/mail/mailAddressExternal/create' import { destroyMailAddressExternal } from '@/services/mail/mailAddressExternal/destroy' @@ -11,7 +11,7 @@ import { readMailAddressExternalValidation, updateMailAddressExternalValidation, } from '@/services/mail/mailAddressExternal/validation' -import type { ActionReturn } from '@/actions//Types' +import type { ActionReturn } from '@/services/actionTypes' import type { MailAddressExternal } from '@prisma/client' export async function createMailAddressExternalAction(rawdata: FormData): diff --git a/src/services/news/actions.ts b/src/services/news/actions.ts index 3a5afd3f2..e9b9e37da 100644 --- a/src/services/news/actions.ts +++ b/src/services/news/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { createNews } from '@/services/news/create' import { destroyNews } from '@/services/news/destroy' import { readNews, readNewsCurrent, readOldNewsPage } from '@/services/news/read' @@ -11,7 +11,7 @@ import { NotificationMethods } from '@/services/notifications/methods' import type { CreateNewsArticleTypes, UpdateNewsArticleTypes } from '@/services/news/validation' import type { ExpandedNewsArticle, NewsCursor, SimpleNewsArticle } from '@/services/news/Types' import type { ReadPageInput } from '@/lib/paging/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' export async function createNewsAction( rawdata: FormData | CreateNewsArticleTypes['Type'] diff --git a/src/services/notifications/actions.ts b/src/services/notifications/actions.ts index 2764584fe..4020e9a03 100644 --- a/src/services/notifications/actions.ts +++ b/src/services/notifications/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { NotificationChannelMethods } from '@/services/notifications/channel/methods' import { NotificationMethods } from '@/services/notifications/methods' import { NotificationSubscriptionMethods } from '@/services/notifications/subscription/methods' diff --git a/src/services/ombul/actions.ts b/src/services/ombul/actions.ts index eaf6fc522..871a866b4 100644 --- a/src/services/ombul/actions.ts +++ b/src/services/ombul/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createOmbul } from '@/services/ombul/create' import { destroyOmbul } from '@/services/ombul/destroy' @@ -9,7 +9,7 @@ import { readLatestOmbul, readOmbul, readOmbuls } from '@/services/ombul/read' import { updateOmbul, updateOmbulFile } from '@/services/ombul/update' import { createOmbulValidation, updateOmbulFileValidation, updateOmbulValidation } from '@/services/ombul/validation' import type { ExpandedOmbul } from '@/services/ombul/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateOmbulTypes, UpdateOmbulFileTypes, UpdateOmbulTypes } from '@/services/ombul/validation' import type { Ombul } from '@prisma/client' diff --git a/src/services/omegaOrder/actions.ts b/src/services/omegaOrder/actions.ts index aca1c03e7..21a824f60 100644 --- a/src/services/omegaOrder/actions.ts +++ b/src/services/omegaOrder/actions.ts @@ -1,11 +1,11 @@ 'use server' -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createOmegaOrder } from '@/services/omegaOrder/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { OmegaOrder } from '@prisma/client' export async function createOmegaOrderAction(): Promise> { diff --git a/src/services/omegaid/actions.ts b/src/services/omegaid/actions.ts index 809c6d4fb..7ecabb75a 100644 --- a/src/services/omegaid/actions.ts +++ b/src/services/omegaid/actions.ts @@ -1,10 +1,10 @@ 'use server' -import { createActionError } from '@/actions/error' +import { createActionError } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { ServerError } from '@/services/error' import { generateOmegaId } from '@/services/omegaid/generate' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' export async function generateOmegaIdAction(): Promise> { const { user, authorized, status } = await getUser({ diff --git a/src/services/omegaid/compress.ts b/src/services/omegaid/compress.ts index 4e1df7f40..ac45b1394 100644 --- a/src/services/omegaid/compress.ts +++ b/src/services/omegaid/compress.ts @@ -1,5 +1,5 @@ import { JWT_ISSUER } from '@/lib/jwt/ConfigVars' -import type { ActionReturn, ActionReturnError } from '@/actions/Types' +import type { ActionReturn, ActionReturnError } from '@/services/actionTypes' import type { OmegaIdJWT } from '@/services/omegaid/Types' /** diff --git a/src/services/omegaquotes/actions.ts b/src/services/omegaquotes/actions.ts index 7a6020c88..df7eb8169 100644 --- a/src/services/omegaquotes/actions.ts +++ b/src/services/omegaquotes/actions.ts @@ -1,14 +1,14 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createQuote } from '@/services/omegaquotes/create' import { readQuotesPage } from '@/services/omegaquotes/read' import { createOmegaquotesValidation } from '@/services/omegaquotes/validation' import type { OmegaquoteCursor, OmegaquoteFiltered } from '@/services/omegaquotes/Types' import type { ReadPageInput } from '@/lib/paging/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateOmegaguotesTypes } from '@/services/omegaquotes/validation' import type { OmegaQuote } from '@prisma/client' diff --git a/src/services/permissions/actions.ts b/src/services/permissions/actions.ts index 7028e1ba8..65e9cd60d 100644 --- a/src/services/permissions/actions.ts +++ b/src/services/permissions/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { PermissionMethods } from '@/services/permissions/methods' export const readPermissionOfGroupAction = action(PermissionMethods.readPermissionsOfGroup) diff --git a/src/services/screens/actions.ts b/src/services/screens/actions.ts index eac0fe016..bfe0a4df6 100644 --- a/src/services/screens/actions.ts +++ b/src/services/screens/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { RequirePermission } from '@/auth/auther/RequirePermission' import { Session } from '@/auth/Session' import { createScreen } from '@/services/screens/create' @@ -10,7 +10,7 @@ import { readScreen, readScreens } from '@/services/screens/read' import { movePageInScreen, updateScreen } from '@/services/screens/update' import { createScreenValidation, updateScreenValidation } from '@/services/screens/validation' import type { ScreenPageMoveDirection } from '@/services/screens/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateScreenTypes, UpdateScreenTypes } from '@/services/screens/validation' import type { Screen } from '@prisma/client' diff --git a/src/services/screens/pages/actions.ts b/src/services/screens/pages/actions.ts index 2e90d9f14..602d39133 100644 --- a/src/services/screens/pages/actions.ts +++ b/src/services/screens/pages/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createPage } from '@/services/screens/pages/create' import { destroyPage } from '@/services/screens/pages/destroy' @@ -11,7 +11,7 @@ import { updatePageValidation } from '@/services/screens/pages/validation' import { createScreenValidation } from '@/services/screens/validation' import type { UpdatePageTypes } from '@/services/screens/pages/validation' import type { ExpandedScreenPage } from '@/services/screens/pages/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { CreateScreenTypes } from '@/services/screens/validation' import type { ScreenPage } from '@prisma/client' diff --git a/src/services/sendmail/actions.ts b/src/services/sendmail/actions.ts index eb61df277..1135dcd4e 100644 --- a/src/services/sendmail/actions.ts +++ b/src/services/sendmail/actions.ts @@ -1,11 +1,11 @@ 'use server' -import { createActionError, createZodActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError, createZodActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { sendMail as transportSendMail } from '@/services/notifications/email/send' import { sendEmailValidation } from '@/services/notifications/email/validation' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' export default async function sendMail(rawdata: FormData): Promise> { const { authorized, status } = await getUser({ diff --git a/src/services/shop/actions.ts b/src/services/shop/actions.ts index 5f415cce1..08db0529d 100644 --- a/src/services/shop/actions.ts +++ b/src/services/shop/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { ProductMethods } from '@/services/shop/product/methods' import { ShopMethods } from '@/services/shop/shop/methods' diff --git a/src/services/users/actions.ts b/src/services/users/actions.ts index d2d08285d..1cc88547a 100644 --- a/src/services/users/actions.ts +++ b/src/services/users/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/actions/action' +import { action } from '@/services/action' import { GroupMethods } from '@/services/groups/methods' import { UserMethods } from '@/services/users/methods' diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index 6753a94a6..292b782bb 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -1,7 +1,7 @@ 'use server' -import { createActionError } from '@/actions/error' -import { safeServerCall } from '@/actions/safeServerCall' +import { createActionError } from '@/services/actionError' +import { safeServerCall } from '@/services/actionError' import { checkVisibility } from '@/auth/checkVisibility' import { getUser } from '@/auth/getUser' import { GroupTypesConfig } from '@/services/groups/config' @@ -9,7 +9,7 @@ import { GroupMethods } from '@/services/groups/methods' import { PurposeTextsConfig } from '@/services/visibility/ConfigVars' import { readVisibilityCollapsed } from '@/services/visibility/read' import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' -import type { ActionReturn } from '@/actions/Types' +import type { ActionReturn } from '@/services/actionTypes' import type { GroupMatrix, VisibilityLevelType } from '@/services/visibility/Types' import type { GroupType } from '@prisma/client' From f5c296ad2d8777242499c8b0fab331977f63008b Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 22 Aug 2025 22:23:53 +0200 Subject: [PATCH 09/24] style: linting --- src/app/(auth)/verify-email/page.tsx | 2 +- src/app/_components/Cms/Article/SectionMover.tsx | 2 +- src/app/_components/Cms/CmsImage/ChangeImage.tsx | 2 +- src/app/_components/Cms/CmsImage/CmsImage.tsx | 2 +- .../_components/Cms/CmsImage/CmsImageClient.tsx | 2 +- .../Cms/CmsParagraph/CmsParagraphEditor.tsx | 2 +- src/app/_components/Company/Company.tsx | 4 ++-- src/app/_components/Event/EventTagsAdmin.tsx | 6 +++--- .../_components/Image/ImageList/ImageDisplay.tsx | 6 +++--- src/app/_components/Image/ImageUploader.tsx | 2 +- src/app/_components/User/UserList/UserList.tsx | 2 +- .../admin/admission/[admission]/registration.tsx | 2 +- src/app/admin/groups/page.tsx | 2 +- src/app/admin/mail/[filter]/[id]/MailFlow.tsx | 6 +++--- .../[currentId]/channelSettings.tsx | 2 +- .../notification-channels/[currentId]/page.tsx | 2 +- .../addNotificationChannel.tsx | 2 +- src/app/admin/stateOfOmega/page.tsx | 2 +- .../updateStudyProgrammeForm.tsx | 4 ++-- .../[periodName]/countdown/CommitteeLogoRoll.tsx | 2 +- .../[periodName]/countdown/FinalCountdown.tsx | 2 +- src/app/applications/[periodName]/page.tsx | 16 ++++++++-------- .../jobads/[...orderAndName]/EditJobAd.tsx | 4 ++-- src/app/career/jobads/[...orderAndName]/page.tsx | 2 +- src/app/career/page.tsx | 6 +++--- src/app/events/CreateOrUpdateEventForm.tsx | 4 ++-- .../[order]/[name]/ManualRegistrationForm.tsx | 2 +- src/app/events/[order]/[name]/RegistrationUI.tsx | 10 +++++----- .../events/[order]/[name]/RegistrationsList.tsx | 2 +- .../events/[order]/[name]/ShowAndEditName.tsx | 2 +- src/app/events/[order]/[name]/page.tsx | 6 +++--- .../collections/[id]/CollectionAdminUpload.tsx | 2 +- src/app/images/collections/[id]/page.tsx | 4 ++-- src/app/images/page.tsx | 2 +- src/app/interest-groups/page.tsx | 2 +- src/app/layout.tsx | 2 +- .../lockers/[id]/CreateLockerReservationForm.tsx | 2 +- .../lockers/[id]/UpdateLockerReservationForm.tsx | 2 +- src/app/news/[...orderAndName]/EditNews.tsx | 4 ++-- .../(user-admin)/notifications/page.tsx | 2 +- src/app/users/[username]/page.tsx | 4 ++-- src/services/actionError.ts | 3 +-- src/services/cms/articleCategories/actions.ts | 3 +-- src/services/cms/articleSections/actions.ts | 3 +-- src/services/cms/articles/actions.ts | 3 +-- src/services/cms/images/actions.ts | 3 +-- src/services/cms/links/actions.ts | 3 +-- src/services/cms/paragraphs/actions.ts | 3 +-- src/services/education/schools/actions.ts | 3 +-- src/services/groups/committees/actions.ts | 3 +-- src/services/groups/memberships/actions.ts | 3 +-- src/services/groups/studyProgrammes/actions.ts | 3 +-- src/services/images/collections/actions.ts | 3 +-- src/services/mail/actions.ts | 3 +-- src/services/mail/alias/actions.ts | 3 +-- src/services/mail/list/actions.ts | 3 +-- src/services/mail/mailAddressExternal/actions.ts | 3 +-- src/services/news/actions.ts | 3 +-- src/services/ombul/actions.ts | 3 +-- src/services/omegaOrder/actions.ts | 3 +-- src/services/omegaquotes/actions.ts | 3 +-- src/services/screens/actions.ts | 3 +-- src/services/screens/pages/actions.ts | 3 +-- src/services/sendmail/actions.ts | 3 +-- src/services/visibility/actions.ts | 3 +-- 65 files changed, 93 insertions(+), 117 deletions(-) diff --git a/src/app/(auth)/verify-email/page.tsx b/src/app/(auth)/verify-email/page.tsx index e306dd4c1..1f195d576 100644 --- a/src/app/(auth)/verify-email/page.tsx +++ b/src/app/(auth)/verify-email/page.tsx @@ -1,11 +1,11 @@ import { EmailVerifiedWrapper } from './EmailVerifiedWrapper' import { getUser } from '@/auth/getUser' -import { verifyEmailAction } from '@/actions/auth/auth' import { QueryParams } from '@/lib/query-params/queryParams' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { notFound, redirect } from 'next/navigation' import Link from 'next/link' import type { SearchParamsServerSide } from '@/lib/query-params/Types' +import { verifyEmailAction } from '@/actions/auth/auth' type PropTypes = SearchParamsServerSide diff --git a/src/app/_components/Cms/Article/SectionMover.tsx b/src/app/_components/Cms/Article/SectionMover.tsx index 35a65911d..e87a11dc8 100644 --- a/src/app/_components/Cms/Article/SectionMover.tsx +++ b/src/app/_components/Cms/Article/SectionMover.tsx @@ -1,11 +1,11 @@ 'use client' import styles from './SectionMover.module.scss' -import { moveSectionOrderAction } from '@/actions/cms/articles/update' import useEditing from '@/hooks/useEditing' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faArrowDown, faArrowUp } from '@fortawesome/free-solid-svg-icons' import { useCallback } from 'react' import { useRouter } from 'next/navigation' +import { moveSectionOrderAction } from '@/actions/cms/articles/update' type PropTypes = { articleId: number diff --git a/src/app/_components/Cms/CmsImage/ChangeImage.tsx b/src/app/_components/Cms/CmsImage/ChangeImage.tsx index 92ccd5b14..a2e15ae80 100644 --- a/src/app/_components/Cms/CmsImage/ChangeImage.tsx +++ b/src/app/_components/Cms/CmsImage/ChangeImage.tsx @@ -4,11 +4,11 @@ import ChangeImageForm from './ChangeImageForm' import Image from '@/components/Image/Image' import { ImageSelectionContext } from '@/contexts/ImageSelection' import Form from '@/components/Form/Form' -import { updateCmsImageConfigAction } from '@/actions/cms/images/update' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faTurnUp } from '@fortawesome/free-solid-svg-icons' import React, { useContext, useEffect, useState } from 'react' import type { ImageSize, Image as ImageT } from '@prisma/client' +import { updateCmsImageConfigAction } from '@/actions/cms/images/update' type PropTypes = { currentImage: ImageT, diff --git a/src/app/_components/Cms/CmsImage/CmsImage.tsx b/src/app/_components/Cms/CmsImage/CmsImage.tsx index 260025981..2a5009816 100644 --- a/src/app/_components/Cms/CmsImage/CmsImage.tsx +++ b/src/app/_components/Cms/CmsImage/CmsImage.tsx @@ -1,10 +1,10 @@ import CmsImageEditor from './CmsImageEditor' import styles from './CmsImage.module.scss' import Image, { SrcImage } from '@/components/Image/Image' -import { readSpecialImageAction } from '@/actions/images/read' import React from 'react' import type { ExpandedCmsImage } from '@/cms/images/Types' import type { PropTypes as ImagePropTypes } from '@/components/Image/Image' +import { readSpecialImageAction } from '@/actions/images/read' export type PropTypes = Omit< ImagePropTypes, 'className' | 'imageSize' | 'smallSize' | 'largeSize' | 'image' | 'children' diff --git a/src/app/_components/Cms/CmsImage/CmsImageClient.tsx b/src/app/_components/Cms/CmsImage/CmsImageClient.tsx index 87ce31534..7341e52e9 100644 --- a/src/app/_components/Cms/CmsImage/CmsImageClient.tsx +++ b/src/app/_components/Cms/CmsImage/CmsImageClient.tsx @@ -3,10 +3,10 @@ import CmsImageEditor from './CmsImageEditor' import styles from './CmsImage.module.scss' import { fallbackImage } from './CmsImage' import Image, { SrcImage } from '@/components/Image/Image' -import { readSpecialImageAction } from '@/actions/images/read' import { useState, useEffect } from 'react' import type { PropTypes } from './CmsImage' import type { Image as ImageT } from '@prisma/client' +import { readSpecialImageAction } from '@/actions/images/read' /** * WARNING: This component is only meant for the client diff --git a/src/app/_components/Cms/CmsParagraph/CmsParagraphEditor.tsx b/src/app/_components/Cms/CmsParagraph/CmsParagraphEditor.tsx index c5afb0969..ccfaea7e8 100644 --- a/src/app/_components/Cms/CmsParagraph/CmsParagraphEditor.tsx +++ b/src/app/_components/Cms/CmsParagraph/CmsParagraphEditor.tsx @@ -2,7 +2,6 @@ import styles from './CmsParagraphEditor.module.scss' import EditOverlay from '@/components/Cms/EditOverlay' import Form from '@/components/Form/Form' -import { updateCmsParagraphAction } from '@/actions/cms/paragraphs/update' import PopUp from '@/components/PopUp/PopUp' import useEditing from '@/hooks/useEditing' import { useState } from 'react' @@ -11,6 +10,7 @@ import 'easymde/dist/easymde.min.css' import './CustomEditorClasses.scss' import dynamic from 'next/dynamic' import type { CmsParagraph } from '@prisma/client' +import { updateCmsParagraphAction } from '@/actions/cms/paragraphs/update' //needed because SimpleMDE is not SSR compatible as it access navigator object const DynamicSimpleMDEditor = dynamic( diff --git a/src/app/_components/Company/Company.tsx b/src/app/_components/Company/Company.tsx index 93e5afaef..e4c4eb9a5 100644 --- a/src/app/_components/Company/Company.tsx +++ b/src/app/_components/Company/Company.tsx @@ -5,12 +5,12 @@ import TextInput from '@/UI/TextInput' import CmsImage from '@/cms/CmsImage/CmsImage' import CmsImageClient from '@/cms/CmsImage/CmsImageClient' import Form from '@/components/Form/Form' -import { updateComanyAction } from '@/actions/career/companies/update' -import { destroyCompanyAction } from '@/actions/career/companies/destroy' import { bindParams } from '@/services/actionBind' import { CompanyAuthers } from '@/services/career/companies/authers' import type { CompanyExpanded } from '@/services/career/companies/Types' import type { SessionMaybeUser } from '@/auth/Session' +import { destroyCompanyAction } from '@/actions/career/companies/destroy' +import { updateComanyAction } from '@/actions/career/companies/update' type PropTypes = { company: CompanyExpanded, diff --git a/src/app/_components/Event/EventTagsAdmin.tsx b/src/app/_components/Event/EventTagsAdmin.tsx index 19639afcf..17b6f3c24 100644 --- a/src/app/_components/Event/EventTagsAdmin.tsx +++ b/src/app/_components/Event/EventTagsAdmin.tsx @@ -2,16 +2,16 @@ import EventTag from './EventTag' import styles from './EventTagsAdmin.module.scss' import Form from '@/components/Form/Form' import { SettingsHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' -import { createEventTagAction } from '@/actions/events/tags/create' import TextInput from '@/UI/TextInput' import Textarea from '@/UI/Textarea' import ColorInput from '@/UI/ColorInput' -import { updateEventTagAction } from '@/actions/events/tags/update' import { QueryParams } from '@/lib/query-params/queryParams' -import { destroyEventTagAction } from '@/actions/events/tags/destroy' import { bindParams } from '@/services/actionBind' import Link from 'next/link' import type { EventTag as EventTagT } from '@prisma/client' +import { destroyEventTagAction } from '@/actions/events/tags/destroy' +import { updateEventTagAction } from '@/actions/events/tags/update' +import { createEventTagAction } from '@/actions/events/tags/create' type PropTypes = { eventTags: EventTagT[] diff --git a/src/app/_components/Image/ImageList/ImageDisplay.tsx b/src/app/_components/Image/ImageList/ImageDisplay.tsx index 4bdfd5aa0..78e11bfe1 100644 --- a/src/app/_components/Image/ImageList/ImageDisplay.tsx +++ b/src/app/_components/Image/ImageList/ImageDisplay.tsx @@ -6,11 +6,8 @@ import Image from '@/components/Image/Image' import useKeyPress from '@/hooks/useKeyPress' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' -import { updateImageAction } from '@/actions/images/update' -import { destroyImageAction } from '@/actions/images/destroy' import { ImagePagingContext } from '@/contexts/paging/ImagePaging' import { ImageDisplayContext } from '@/contexts/ImageDisplayProvider' -import { updateImageCollectionAction } from '@/actions/images/collections/update' import LicenseChooser from '@/components/LicenseChooser/LicenseChooser' import { useRouter } from 'next/navigation' import { faChevronRight, faChevronLeft, faX, faCog } from '@fortawesome/free-solid-svg-icons' @@ -19,6 +16,9 @@ import { useContext } from 'react' import Link from 'next/link' import type { ImageSizeOptions } from '@/components/Image/Image' import type { Image as ImageT } from '@prisma/client' +import { updateImageCollectionAction } from '@/actions/images/collections/update' +import { destroyImageAction } from '@/actions/images/destroy' +import { updateImageAction } from '@/actions/images/update' const mimeTypes: { [key: string]: string } = { jpg: 'image/jpeg', diff --git a/src/app/_components/Image/ImageUploader.tsx b/src/app/_components/Image/ImageUploader.tsx index b883553c4..c33cb2da6 100644 --- a/src/app/_components/Image/ImageUploader.tsx +++ b/src/app/_components/Image/ImageUploader.tsx @@ -1,10 +1,10 @@ import Form from '@/components/Form/Form' -import { createImageAction } from '@/actions/images/create' import TextInput from '@/components/UI/TextInput' import FileInput from '@/components/UI/FileInput' import LicenseChooser from '@/components/LicenseChooser/LicenseChooser' import { bindParams } from '@/services/actionBind' import type { PropTypes as FormPropTypes } from '@/components/Form/Form' +import { createImageAction } from '@/actions/images/create' type ResponseType = Awaited>; type T = Pick['data'] diff --git a/src/app/_components/User/UserList/UserList.tsx b/src/app/_components/User/UserList/UserList.tsx index 62f6dba8d..60b2df190 100644 --- a/src/app/_components/User/UserList/UserList.tsx +++ b/src/app/_components/User/UserList/UserList.tsx @@ -5,7 +5,6 @@ import { UserPagingContext } from '@/contexts/paging/UserPaging' import EndlessScroll from '@/components/PagingWrappers/EndlessScroll' import UserRow from '@/components/User/UserList/UserRow' import useActionCall from '@/hooks/useActionCall' -import { readGroupsForPageFilteringAction } from '@/actions/users/read' import { UsersSelectionContext } from '@/contexts/UsersSelection' import { UserSelectionContext } from '@/contexts/UserSelection' import { useContext, useEffect, useState } from 'react' @@ -15,6 +14,7 @@ import type { UserPagingReturn } from '@/services/users/Types' import type { ChangeEvent, ReactNode } from 'react' import type { GroupType } from '@prisma/client' import type { ExpandedGroup } from '@/services/groups/Types' +import { readGroupsForPageFilteringAction } from '@/actions/users/read' type GroupSelectionType = Exclude diff --git a/src/app/admin/admission/[admission]/registration.tsx b/src/app/admin/admission/[admission]/registration.tsx index 5e4bddd2a..21bb02825 100644 --- a/src/app/admin/admission/[admission]/registration.tsx +++ b/src/app/admin/admission/[admission]/registration.tsx @@ -2,11 +2,11 @@ import styles from './registration.module.scss' import { bindParams } from '@/services/actionBind' -import { createAdmissionTrialAction } from '@/actions/admission/create' import Form from '@/components/Form/Form' import OmegaIdReader from '@/components/OmegaId/reader/OmegaIdReader' import TextInput from '@/components/UI/TextInput' import type { Admission } from '@prisma/client' +import { createAdmissionTrialAction } from '@/actions/admission/create' export default function RegisterAdmissiontrial({ diff --git a/src/app/admin/groups/page.tsx b/src/app/admin/groups/page.tsx index fe678fc54..36b534b7d 100644 --- a/src/app/admin/groups/page.tsx +++ b/src/app/admin/groups/page.tsx @@ -1,8 +1,8 @@ import styles from './page.module.scss' import GroupSelector from './GroupSelector' -import { readGroupsStructuredAction } from '@/actions/groups/read' import { GroupTypeOrdering } from '@/services/groups/config' import { notFound } from 'next/navigation' +import { readGroupsStructuredAction } from '@/actions/groups/read' /** * A page that displays memberships in all groups for admins diff --git a/src/app/admin/mail/[filter]/[id]/MailFlow.tsx b/src/app/admin/mail/[filter]/[id]/MailFlow.tsx index 5533b1638..c6d59f1a4 100644 --- a/src/app/admin/mail/[filter]/[id]/MailFlow.tsx +++ b/src/app/admin/mail/[filter]/[id]/MailFlow.tsx @@ -2,15 +2,15 @@ import MailList from './mailList' import styles from './MailFlow.module.scss' +import { useUser } from '@/auth/useUser' +import type { ActionReturn } from '@/services/actionTypes' +import type { MailFlowObject, MailListTypes } from '@/services/mail/Types' import { destroyAliasMailingListRelationAction, destroyMailingListExternalRelationAction, destroyMailingListGroupRelationAction, destroyMailingListUserRelationAction } from '@/actions/mail/destroy' -import { useUser } from '@/auth/useUser' -import type { ActionReturn } from '@/services/actionTypes' -import type { MailFlowObject, MailListTypes } from '@/services/mail/Types' type DestroyFunction = null | ((id: number) => Promise>) diff --git a/src/app/admin/notification-channels/[currentId]/channelSettings.tsx b/src/app/admin/notification-channels/[currentId]/channelSettings.tsx index d2cf006d8..7ce665a11 100644 --- a/src/app/admin/notification-channels/[currentId]/channelSettings.tsx +++ b/src/app/admin/notification-channels/[currentId]/channelSettings.tsx @@ -6,13 +6,13 @@ import TextInput from '@/components/UI/TextInput' import { SelectNumber } from '@/components/UI/Select' import Form from '@/components/Form/Form' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { updateNotificationChannelAction } from '@/actions/notifications' import { bindParams } from '@/services/actionBind' import { NotificationChannelSchemas } from '@/services/notifications/channel/schemas' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' import { useState } from 'react' import type { ExpandedNotificationChannel } from '@/services/notifications/Types' import type { MailAlias } from '@prisma/client' +import { updateNotificationChannelAction } from '@/actions/notifications' export default function ChannelSettings({ currentChannel, diff --git a/src/app/admin/notification-channels/[currentId]/page.tsx b/src/app/admin/notification-channels/[currentId]/page.tsx index 83ef4e8d8..c81c07d0a 100644 --- a/src/app/admin/notification-channels/[currentId]/page.tsx +++ b/src/app/admin/notification-channels/[currentId]/page.tsx @@ -1,8 +1,8 @@ import ChannelSettings from './channelSettings' +import { notFound } from 'next/navigation' import { readNotificationChannelsAction } from '@/actions/notifications' import { readMailAliasesAction } from '@/actions/mail/alias/read' -import { notFound } from 'next/navigation' type PropTypes = { params: Promise<{ diff --git a/src/app/admin/notification-channels/addNotificationChannel.tsx b/src/app/admin/notification-channels/addNotificationChannel.tsx index bed188fbd..416d46dfe 100644 --- a/src/app/admin/notification-channels/addNotificationChannel.tsx +++ b/src/app/admin/notification-channels/addNotificationChannel.tsx @@ -4,12 +4,12 @@ import TextInput from '@/components/UI/TextInput' import { SelectNumber } from '@/components/UI/Select' import NotificationMethodSelector from '@/components/NotificaionMethodSelector/NotificaionMethodSelector' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' -import { createNotificationChannelAction } from '@/actions/notifications' import { bindParams } from '@/services/actionBind' import { NotificationConfig } from '@/services/notifications/config' import { useState } from 'react' import { useRouter } from 'next/navigation' import type { ExpandedNotificationChannel, NotificationMethodGeneral } from '@/services/notifications/Types' +import { createNotificationChannelAction } from '@/actions/notifications' export default function AddNotificationChannel({ diff --git a/src/app/admin/stateOfOmega/page.tsx b/src/app/admin/stateOfOmega/page.tsx index 9bc336920..16cc497ea 100644 --- a/src/app/admin/stateOfOmega/page.tsx +++ b/src/app/admin/stateOfOmega/page.tsx @@ -1,8 +1,8 @@ import styles from './page.module.scss' import CreateOrder from './CreateOrder' import { getUser } from '@/auth/getUser' -import { readCurrentOmegaOrderAction } from '@/actions/omegaOrder/read' import { notFound } from 'next/navigation' +import { readCurrentOmegaOrderAction } from '@/actions/omegaOrder/read' export default async function stateOfOmega() { const { authorized } = await getUser({ diff --git a/src/app/admin/study-programmes/updateStudyProgrammeForm.tsx b/src/app/admin/study-programmes/updateStudyProgrammeForm.tsx index cfe8f83c1..6b7c7d94a 100644 --- a/src/app/admin/study-programmes/updateStudyProgrammeForm.tsx +++ b/src/app/admin/study-programmes/updateStudyProgrammeForm.tsx @@ -1,12 +1,12 @@ 'use client' -import { createStudyProgrammeAction } from '@/actions/groups/studyProgrammes/create' -import { updateStudyProgrammeAction } from '@/actions/groups/studyProgrammes/update' import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' import TextInput from '@/components/UI/TextInput' import { useRouter } from 'next/navigation' import type { StudyProgramme } from '@prisma/client' +import { updateStudyProgrammeAction } from '@/actions/groups/studyProgrammes/update' +import { createStudyProgrammeAction } from '@/actions/groups/studyProgrammes/create' export default function UpdateStudyProgrammeForm({ diff --git a/src/app/applications/[periodName]/countdown/CommitteeLogoRoll.tsx b/src/app/applications/[periodName]/countdown/CommitteeLogoRoll.tsx index 207b000f9..10c40d6d6 100644 --- a/src/app/applications/[periodName]/countdown/CommitteeLogoRoll.tsx +++ b/src/app/applications/[periodName]/countdown/CommitteeLogoRoll.tsx @@ -2,9 +2,9 @@ import styles from './CommitteeLogoRoll.module.scss' import Image from '@/app/_components/Image/Image' import useInterval from '@/hooks/useInterval' -import { readNumberOfApplicationsAction } from '@/actions/applications/periods/read' import { useRef, useState } from 'react' import type { Image as ImageT } from '@prisma/client' +import { readNumberOfApplicationsAction } from '@/actions/applications/periods/read' type PropTypes = { committees: { diff --git a/src/app/applications/[periodName]/countdown/FinalCountdown.tsx b/src/app/applications/[periodName]/countdown/FinalCountdown.tsx index 954e0d291..f69bb1982 100644 --- a/src/app/applications/[periodName]/countdown/FinalCountdown.tsx +++ b/src/app/applications/[periodName]/countdown/FinalCountdown.tsx @@ -1,7 +1,7 @@ import styles from './FinalCountdown.module.scss' -import { readNumberOfApplicationsAction } from '@/actions/applications/periods/read' import useInterval from '@/hooks/useInterval' import { useEffect, useRef, useState } from 'react' +import { readNumberOfApplicationsAction } from '@/actions/applications/periods/read' type PropTypes = { periodName: string diff --git a/src/app/applications/[periodName]/page.tsx b/src/app/applications/[periodName]/page.tsx index 322dfc423..819c3976d 100644 --- a/src/app/applications/[periodName]/page.tsx +++ b/src/app/applications/[periodName]/page.tsx @@ -1,28 +1,28 @@ import styles from './page.module.scss' import Reprioritize from './Reprioritize' -import { readApplicationPeriodAction } from '@/actions/applications/periods/read' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { default as DateComponent } from '@/components/Date/Date' import PageWrapper from '@/components/PageWrapper/PageWrapper' import CountDown from '@/components/countDown/CountDown' -import { readSpecialImageAction } from '@/images/read' import BackdropImage from '@/components/BackdropImage/BackdropImage' import CmsParagraph from '@/components/Cms/CmsParagraph/CmsParagraph' import PopUp from '@/components/PopUp/PopUp' -import { readApplicationsForUserAction } from '@/actions/applications/read' import { Session } from '@/auth/Session' import Textarea from '@/components/UI/Textarea' import Form from '@/components/Form/Form' -import { createApplicationAction } from '@/actions/applications/create' -import { updateApplicationAction } from '@/actions/applications/update' import { SettingsHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import CreateUpdateApplicationPeriodForm from '@/app/applications/CreateUpdateApplicationPeriodForm' -import { readCommitteesAction } from '@/actions/groups/committees/read' -import { destroyApplicationAction } from '@/actions/applications/destroy' -import { destroyApplicationPeriodAction, removeAllApplicationTextsAction } from '@/actions/applications/periods/destroy' import Link from 'next/link' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faVideo } from '@fortawesome/free-solid-svg-icons' +import { createApplicationAction } from '@/actions/applications/create' +import { updateApplicationAction } from '@/actions/applications/update' +import { readCommitteesAction } from '@/actions/groups/committees/read' +import { destroyApplicationAction } from '@/actions/applications/destroy' +import { destroyApplicationPeriodAction, removeAllApplicationTextsAction } from '@/actions/applications/periods/destroy' +import { readApplicationsForUserAction } from '@/actions/applications/read' +import { readSpecialImageAction } from '@/images/read' +import { readApplicationPeriodAction } from '@/actions/applications/periods/read' export type PropTypes = { params: Promise<{ diff --git a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx index c96244b5e..f3273baec 100644 --- a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx +++ b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx @@ -2,8 +2,6 @@ import styles from './EditJobAd.module.scss' import SelectedCompany from '@/career/jobads/SelectedCompany' import Form from '@/components/Form/Form' -import { updateJobAdAction } from '@/career/jobAds/update' -import { destroyJobAdAction } from '@/career/jobAds/destroy' import TextInput from '@/components/UI/TextInput' import Textarea from '@/components/UI/Textarea' import useEditing from '@/hooks/useEditing' @@ -17,6 +15,8 @@ import { JobAdConfig } from '@/services/career/jobAds/config' import { v4 as uuid } from 'uuid' import { useContext, type ReactNode } from 'react' import type { ExpandedJobAd } from '@/career/jobAds/Types' +import { destroyJobAdAction } from '@/career/jobAds/destroy' +import { updateJobAdAction } from '@/career/jobAds/update' type PropTypes = { jobAd: ExpandedJobAd diff --git a/src/app/career/jobads/[...orderAndName]/page.tsx b/src/app/career/jobads/[...orderAndName]/page.tsx index a2ad6b097..f5606e578 100644 --- a/src/app/career/jobads/[...orderAndName]/page.tsx +++ b/src/app/career/jobads/[...orderAndName]/page.tsx @@ -1,7 +1,6 @@ import styles from './page.module.scss' import EditJobAd from './EditJobAd' -import { readJobAdAction } from '@/actions/career/jobAds/read' import Article from '@/components/Cms/Article/Article' import CompanySelectionProvider from '@/contexts/CompanySelection' import CompanyPagingProvider from '@/contexts/paging/CompanyPaging' @@ -19,6 +18,7 @@ import { faSuitcase, faXmarkCircle } from '@fortawesome/free-solid-svg-icons' +import { readJobAdAction } from '@/actions/career/jobAds/read' type PropTypes = { params: Promise<{ diff --git a/src/app/career/page.tsx b/src/app/career/page.tsx index 00e3fb900..cad815fdb 100644 --- a/src/app/career/page.tsx +++ b/src/app/career/page.tsx @@ -3,12 +3,12 @@ import SpecialCmsParagraph from '@/components/Cms/CmsParagraph/SpecialCmsParagra import PageWrapper from '@/components/PageWrapper/PageWrapper' import { Session } from '@/auth/Session' import Image from '@/components/Image/Image' -import { readSpecialImageAction } from '@/actions/images/read' -import { readSpecialCmsLinkAction } from '@/actions/cms/links/read' import CmsLink from '@/components/Cms/CmsLink/CmsLink' -import { readSpecialEventTagAction } from '@/actions/events/tags/read' import { QueryParams } from '@/lib/query-params/queryParams' import Link from 'next/link' +import { readSpecialImageAction } from '@/actions/images/read' +import { readSpecialCmsLinkAction } from '@/actions/cms/links/read' +import { readSpecialEventTagAction } from '@/actions/events/tags/read' export default async function CareerLandingPage() { const session = await Session.fromNextAuth() diff --git a/src/app/events/CreateOrUpdateEventForm.tsx b/src/app/events/CreateOrUpdateEventForm.tsx index c226fdcf0..06062a6c5 100644 --- a/src/app/events/CreateOrUpdateEventForm.tsx +++ b/src/app/events/CreateOrUpdateEventForm.tsx @@ -8,14 +8,14 @@ import NumberInput from '@/components/UI/NumberInput' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import { EventConfig } from '@/services/events/config' -import { updateEventAction } from '@/actions/events/update' -import { createEventAction } from '@/actions/events/create' import EventTag from '@/components/Event/EventTag' import { bindParams } from '@/services/actionBind' import { FIELD_IS_PRESENT_VALUE } from '@/lib/fields/config' import { useState } from 'react' import type { Event, EventTag as EventTagT } from '@prisma/client' import type { ChangeEvent } from 'react' +import { createEventAction } from '@/actions/events/create' +import { updateEventAction } from '@/actions/events/update' type PropTypes = { event?: Event & { tags: EventTagT[] } diff --git a/src/app/events/[order]/[name]/ManualRegistrationForm.tsx b/src/app/events/[order]/[name]/ManualRegistrationForm.tsx index 00e167ab3..9576fd5ad 100644 --- a/src/app/events/[order]/[name]/ManualRegistrationForm.tsx +++ b/src/app/events/[order]/[name]/ManualRegistrationForm.tsx @@ -1,6 +1,5 @@ 'use client' import styles from './ManualRegistrationForm.module.scss' -import { createEventRegistrationAction, createGuestEventRegistrationAction } from '@/actions/events/registration' import Form from '@/components/Form/Form' import UserList from '@/components/User/UserList/UserList' import UserPagingProvider from '@/contexts/paging/UserPaging' @@ -10,6 +9,7 @@ import { bindParams } from '@/services/actionBind' import { useContext } from 'react' import type { EventRegistration } from '@prisma/client' import type { ActionReturn } from '@/services/actionTypes' +import { createEventRegistrationAction, createGuestEventRegistrationAction } from '@/actions/events/registration' function ManualRegistrationFormInner({ eventId, diff --git a/src/app/events/[order]/[name]/RegistrationUI.tsx b/src/app/events/[order]/[name]/RegistrationUI.tsx index 033bcda3d..96096049e 100644 --- a/src/app/events/[order]/[name]/RegistrationUI.tsx +++ b/src/app/events/[order]/[name]/RegistrationUI.tsx @@ -1,10 +1,5 @@ 'use client' import styles from './RegistrationUI.module.scss' -import { - createEventRegistrationAction, - eventRegistrationDestroyAction, - eventRegistrationUpdateNotesAction -} from '@/actions/events/registration' import CountDown from '@/components/countDown/CountDown' import Form from '@/components/Form/Form' import { bindParams } from '@/services/actionBind' @@ -14,6 +9,11 @@ import { useEffect, useState } from 'react' import { useSession } from 'next-auth/react' import type { EventExpanded } from '@/services/events/Types' import type { EventRegistration } from '@prisma/client' +import { + createEventRegistrationAction, + eventRegistrationDestroyAction, + eventRegistrationUpdateNotesAction +} from '@/actions/events/registration' enum RegistrationButtonState { NOT_REGISTERED = 'NOT_REGISTERED', diff --git a/src/app/events/[order]/[name]/RegistrationsList.tsx b/src/app/events/[order]/[name]/RegistrationsList.tsx index c24e4019f..53b94204d 100644 --- a/src/app/events/[order]/[name]/RegistrationsList.tsx +++ b/src/app/events/[order]/[name]/RegistrationsList.tsx @@ -10,12 +10,12 @@ import UserDisplayName from '@/components/User/UserDisplayName' import Slider from '@/components/UI/Slider' import Form from '@/components/Form/Form' import { bindParams } from '@/services/actionBind' -import { eventRegistrationDestroyAction } from '@/actions/events/registration' import { EventRegistrationConfig } from '@/services/events/registration/config' import ContactCard from '@/components/User/ContactCard' import Link from 'next/link' import { useState } from 'react' import type { EventFiltered } from '@/services/events/Types' +import { eventRegistrationDestroyAction } from '@/actions/events/registration' function DetailedTable({ event, diff --git a/src/app/events/[order]/[name]/ShowAndEditName.tsx b/src/app/events/[order]/[name]/ShowAndEditName.tsx index b592dc190..c91dde3ab 100644 --- a/src/app/events/[order]/[name]/ShowAndEditName.tsx +++ b/src/app/events/[order]/[name]/ShowAndEditName.tsx @@ -1,8 +1,8 @@ 'use client' import styles from './ShowAndEditName.module.scss' import EditableTextField from '@/components/EditableTextField/EditableTextField' -import { updateEventAction } from '@/actions/events/update' import type { Event } from '@prisma/client' +import { updateEventAction } from '@/actions/events/update' type PropTypes = { event: Event diff --git a/src/app/events/[order]/[name]/page.tsx b/src/app/events/[order]/[name]/page.tsx index 0c5311e3f..aeec70c64 100644 --- a/src/app/events/[order]/[name]/page.tsx +++ b/src/app/events/[order]/[name]/page.tsx @@ -5,20 +5,20 @@ import RegistrationsList from './RegistrationsList' import ManualRegistrationForm from './ManualRegistrationForm' import Date from '@/components/Date/Date' import CreateOrUpdateEventForm from '@/app/events/CreateOrUpdateEventForm' -import { readEventAction } from '@/actions/events/read' import CmsImage from '@/components/Cms/CmsImage/CmsImage' import CmsParagraph from '@/components/Cms/CmsParagraph/CmsParagraph' import Form from '@/components/Form/Form' import EventTag from '@/components/Event/EventTag' -import { destroyEventAction } from '@/actions/events/destroy' import { SettingsHeaderItemPopUp, UsersHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' -import { readEventTagsAction } from '@/actions/events/tags/read' import { QueryParams } from '@/lib/query-params/queryParams' import { bindParams } from '@/services/actionBind' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import Link from 'next/link' import { faCalendar, faExclamation, faLocationDot, faUsers } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { readEventTagsAction } from '@/actions/events/tags/read' +import { destroyEventAction } from '@/actions/events/destroy' +import { readEventAction } from '@/actions/events/read' type PropTypes = { params: Promise<{ diff --git a/src/app/images/collections/[id]/CollectionAdminUpload.tsx b/src/app/images/collections/[id]/CollectionAdminUpload.tsx index df60e7e7e..aabdca268 100644 --- a/src/app/images/collections/[id]/CollectionAdminUpload.tsx +++ b/src/app/images/collections/[id]/CollectionAdminUpload.tsx @@ -1,7 +1,6 @@ 'use client' import styles from './CollectionAdminUpload.module.scss' import Dropzone from '@/components/UI/Dropzone' -import { createImagesAction } from '@/actions/images/create' import Form from '@/components/Form/Form' import Slider from '@/components/UI/Slider' import ProgressBar from '@/components/ProgressBar/ProgressBar' @@ -11,6 +10,7 @@ import { ImageConfig } from '@/services/images/config' import { useCallback, useState } from 'react' import type { FileWithStatus } from '@/components/UI/Dropzone' import type { ActionReturn } from '@/services/actionTypes' +import { createImagesAction } from '@/actions/images/create' type PropTypes = { collectionId: number diff --git a/src/app/images/collections/[id]/page.tsx b/src/app/images/collections/[id]/page.tsx index dfcf60a1b..73e845d3c 100644 --- a/src/app/images/collections/[id]/page.tsx +++ b/src/app/images/collections/[id]/page.tsx @@ -1,13 +1,13 @@ import styles from './page.module.scss' import CollectionAdmin from './CollectionAdmin' -import { readImagesPageAction } from '@/actions/images/read' -import { readImageCollectionAction } from '@/actions/images/collections/read' import ImageList from '@/components/Image/ImageList/ImageList' import ImagePagingProvider from '@/contexts/paging/ImagePaging' import ImageListImage from '@/components/Image/ImageList/ImageListImage' import ImageDisplayProvider from '@/contexts/ImageDisplayProvider' import { notFound } from 'next/navigation' import type { PageSizeImage } from '@/contexts/paging/ImagePaging' +import { readImageCollectionAction } from '@/actions/images/collections/read' +import { readImagesPageAction } from '@/actions/images/read' type PropTypes = { params: Promise<{ diff --git a/src/app/images/page.tsx b/src/app/images/page.tsx index fd8507e46..2ab4f8797 100644 --- a/src/app/images/page.tsx +++ b/src/app/images/page.tsx @@ -1,11 +1,11 @@ import styles from './page.module.scss' import MakeNewCollection from './MakeNewCollection' import ImageCollectionList from '@/components/Image/Collection/ImageCollectionList' -import { readImageCollectionsPageAction } from '@/actions/images/collections/read' import ImageCollectionPagingProvider from '@/contexts/paging/ImageCollectionPaging' import CollectionCard from '@/components/Image/Collection/CollectionCard' import { getUser } from '@/auth/getUser' import type { PageSizeImageCollection } from '@/contexts/paging/ImageCollectionPaging' +import { readImageCollectionsPageAction } from '@/actions/images/collections/read' export default async function Images() { const { user } = await getUser() diff --git a/src/app/interest-groups/page.tsx b/src/app/interest-groups/page.tsx index fe50ffa3d..fcd9c9a90 100644 --- a/src/app/interest-groups/page.tsx +++ b/src/app/interest-groups/page.tsx @@ -1,11 +1,11 @@ import CreateInterestGroupForm from './CreateInterestGroupForm' import InterestGroup from './InterestGroup' -import { readInterestGroupsAction } from '@/actions/groups/interestGroups/read' import SpecialCmsParagraph from '@/cms/CmsParagraph/SpecialCmsParagraph' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import { Session } from '@/auth/Session' import { InterestGroupAuthers } from '@/services/groups/interestGroups/authers' +import { readInterestGroupsAction } from '@/actions/groups/interestGroups/read' export default async function InterestGroups() { const session = await Session.fromNextAuth() diff --git a/src/app/layout.tsx b/src/app/layout.tsx index efeb77edd..e40a07573 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -7,8 +7,8 @@ import { authOptions } from '@/auth/authoptions' import EditModeProvider from '@/contexts/EditMode' import PopUpProvider from '@/contexts/PopUp' import DefaultPermissionsProvider from '@/contexts/DefaultPermissions' -import { readDefaultPermissionsAction } from '@/actions/permissions/index' import { Inter } from 'next/font/google' +import { readDefaultPermissionsAction } from '@/actions/permissions/index' import '@/styles/globals.scss' import { config } from '@fortawesome/fontawesome-svg-core' import '@fortawesome/fontawesome-svg-core/styles.css' diff --git a/src/app/lockers/[id]/CreateLockerReservationForm.tsx b/src/app/lockers/[id]/CreateLockerReservationForm.tsx index 65600e6a3..1372f5cf1 100644 --- a/src/app/lockers/[id]/CreateLockerReservationForm.tsx +++ b/src/app/lockers/[id]/CreateLockerReservationForm.tsx @@ -1,5 +1,4 @@ 'use client' -import { createLockerReservationAction } from '@/actions/lockers/reservations' import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' import DateInput from '@/components/UI/DateInput' @@ -7,6 +6,7 @@ import Checkbox from '@/components/UI/Checkbox' import { bindParams } from '@/services/actionBind' import React, { useState } from 'react' import { useRouter } from 'next/navigation' +import { createLockerReservationAction } from '@/actions/lockers/reservations' type PropTypes = { lockerId: number diff --git a/src/app/lockers/[id]/UpdateLockerReservationForm.tsx b/src/app/lockers/[id]/UpdateLockerReservationForm.tsx index 7b151ad71..5e99c8611 100644 --- a/src/app/lockers/[id]/UpdateLockerReservationForm.tsx +++ b/src/app/lockers/[id]/UpdateLockerReservationForm.tsx @@ -1,5 +1,4 @@ 'use client' -import { updateLockerReservationAction } from '@/actions/lockers/reservations' import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' import DateInput from '@/components/UI/DateInput' @@ -7,6 +6,7 @@ import Checkbox from '@/components/UI/Checkbox' import { bindParams } from '@/services/actionBind' import { useState } from 'react' import { useRouter } from 'next/navigation' +import { updateLockerReservationAction } from '@/actions/lockers/reservations' type PropTypes = { reservationId: number, diff --git a/src/app/news/[...orderAndName]/EditNews.tsx b/src/app/news/[...orderAndName]/EditNews.tsx index fa81f6b28..2576ddfcc 100644 --- a/src/app/news/[...orderAndName]/EditNews.tsx +++ b/src/app/news/[...orderAndName]/EditNews.tsx @@ -1,8 +1,6 @@ 'use client' import styles from './EditNews.module.scss' import Form from '@/components/Form/Form' -import { updateNewsAction } from '@/actions/news/update' -import { destroyNewsAction } from '@/actions/news/destroy' import TextInput from '@/components/UI/TextInput' import Textarea from '@/components/UI/Textarea' import DateInput from '@/components/UI/DateInput' @@ -10,6 +8,8 @@ import useEditing from '@/hooks/useEditing' import { useRouter } from 'next/navigation' import type { ExpandedNewsArticle } from '@/services/news/Types' import type { ReactNode } from 'react' +import { destroyNewsAction } from '@/actions/news/destroy' +import { updateNewsAction } from '@/actions/news/update' type PropTypes = { news: ExpandedNewsArticle diff --git a/src/app/users/[username]/(user-admin)/notifications/page.tsx b/src/app/users/[username]/(user-admin)/notifications/page.tsx index a227ea543..ec451acfa 100644 --- a/src/app/users/[username]/(user-admin)/notifications/page.tsx +++ b/src/app/users/[username]/(user-admin)/notifications/page.tsx @@ -1,8 +1,8 @@ 'use server' import NotificationSettings from './notificationSettings' -import { readNotificationChannelsAction, readNotificationSubscriptionsAction } from '@/actions/notifications' import { getProfileForAdmin } from '@/app/users/[username]/(user-admin)/getProfileForAdmin' import type { PropTypes } from '@/app/users/[username]/page' +import { readNotificationChannelsAction, readNotificationSubscriptionsAction } from '@/actions/notifications' export default async function Notififcations({ params }: PropTypes) { const { profile } = await getProfileForAdmin(await params, 'notifications') diff --git a/src/app/users/[username]/page.tsx b/src/app/users/[username]/page.tsx index 1a8c0ffa0..634128426 100644 --- a/src/app/users/[username]/page.tsx +++ b/src/app/users/[username]/page.tsx @@ -1,8 +1,6 @@ import styles from './page.module.scss' -import { readSpecialImageAction } from '@/actions/images/read' import BorderButton from '@/components/UI/BorderButton' import { readCommitteesFromGroupIds } from '@/services/groups/committees/read' -import { readUserProfileAction } from '@/actions/users/read' import OmegaId from '@/components/OmegaId/identification/OmegaId' import PopUp from '@/components/PopUp/PopUp' import { Session } from '@/auth/Session' @@ -15,6 +13,8 @@ import { notFound, redirect } from 'next/navigation' import { v4 as uuid } from 'uuid' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faQrcode } from '@fortawesome/free-solid-svg-icons' +import { readUserProfileAction } from '@/actions/users/read' +import { readSpecialImageAction } from '@/actions/images/read' export type PropTypes = { params: Promise<{ diff --git a/src/services/actionError.ts b/src/services/actionError.ts index 0ae9e3e3e..f30e91070 100644 --- a/src/services/actionError.ts +++ b/src/services/actionError.ts @@ -2,8 +2,7 @@ import { errorCodes, type ErrorCode, type ErrorMessage } from '@/services/error' import { ParseError, Smorekopp } from '@/services/error' import type { AuthStatus } from '@/auth/getUser' import type { SafeParseError } from 'zod' -import type { ActionReturnError } from './actionTypes' -import type { ActionReturn } from './actionTypes' +import type { ActionReturnError, ActionReturn } from './actionTypes' /** * @deprecated With the "new" service method system this should not be called directly. diff --git a/src/services/cms/articleCategories/actions.ts b/src/services/cms/articleCategories/actions.ts index 4f0f7d48f..f760fc862 100644 --- a/src/services/cms/articleCategories/actions.ts +++ b/src/services/cms/articleCategories/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createZodActionError, safeServerCall } from '@/services/actionError' import { createArticleCategory } from '@/services/cms/articleCategories/create' import { destroyArticleCategory } from '@/services/cms/articleCategories/destroy' import { readArticleCategories, readArticleCategory } from '@/services/cms/articleCategories/read' diff --git a/src/services/cms/articleSections/actions.ts b/src/services/cms/articleSections/actions.ts index 8dbb8afb2..2e4ef865c 100644 --- a/src/services/cms/articleSections/actions.ts +++ b/src/services/cms/articleSections/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createZodActionError, safeServerCall } from '@/services/actionError' import { createArticleSection } from '@/services/cms/articleSections/create' import { destroyArticleSection } from '@/services/cms/articleSections/destroy' import { readArticleSection } from '@/services/cms/articleSections/read' diff --git a/src/services/cms/articles/actions.ts b/src/services/cms/articles/actions.ts index eb8ae9e4a..7c797e441 100644 --- a/src/services/cms/articles/actions.ts +++ b/src/services/cms/articles/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createZodActionError, safeServerCall } from '@/services/actionError' import { createArticle } from '@/services/cms/articles/create' import { destroyArticle } from '@/services/cms/articles/destroy' import { readArticle } from '@/services/cms/articles/read' diff --git a/src/services/cms/images/actions.ts b/src/services/cms/images/actions.ts index 358558f1e..91a7ef8a5 100644 --- a/src/services/cms/images/actions.ts +++ b/src/services/cms/images/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { createCmsImage } from '@/services/cms/images/create' import { readCmsImage, readSpecialCmsImage } from '@/services/cms/images/read' import { updateCmsImage, updateCmsImageConfig } from '@/services/cms/images/update' diff --git a/src/services/cms/links/actions.ts b/src/services/cms/links/actions.ts index 332091d8a..4dcf21866 100644 --- a/src/services/cms/links/actions.ts +++ b/src/services/cms/links/actions.ts @@ -1,8 +1,7 @@ 'use server' import { action } from '@/services/action' -import { createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createZodActionError, safeServerCall } from '@/services/actionError' import { createCmsLink } from '@/services/cms/links/create' import { readSpecialCmsLink } from '@/services/cms/links/read' import { updateCmsLink } from '@/services/cms/links/update' diff --git a/src/services/cms/paragraphs/actions.ts b/src/services/cms/paragraphs/actions.ts index 437050af8..5cfdfa1ec 100644 --- a/src/services/cms/paragraphs/actions.ts +++ b/src/services/cms/paragraphs/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { readCmsParagraph, readSpecialCmsParagraph } from '@/services/cms/paragraphs/read' import { updateCmsParagraphContents } from '@/services/cms/paragraphs/update' diff --git a/src/services/education/schools/actions.ts b/src/services/education/schools/actions.ts index 6ed2158c7..a664d5d2d 100644 --- a/src/services/education/schools/actions.ts +++ b/src/services/education/schools/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createSchoolValidation, updateSchoolValidation } from '@/education/schools/validation' import { createSchool } from '@/services/education/schools/create' diff --git a/src/services/groups/committees/actions.ts b/src/services/groups/committees/actions.ts index bb87aa87f..f841dffa6 100644 --- a/src/services/groups/committees/actions.ts +++ b/src/services/groups/committees/actions.ts @@ -1,8 +1,7 @@ 'use server' import { action } from '@/services/action' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createCommittee } from '@/services/groups/committees/create' import { CommitteeMethods } from '@/services/groups/committees/methods' diff --git a/src/services/groups/memberships/actions.ts b/src/services/groups/memberships/actions.ts index bf0b8d337..402ab7257 100644 --- a/src/services/groups/memberships/actions.ts +++ b/src/services/groups/memberships/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createMembershipsForGroup } from '@/services/groups/memberships/create' import { destoryMembershipOfUser } from '@/services/groups/memberships/destroy' diff --git a/src/services/groups/studyProgrammes/actions.ts b/src/services/groups/studyProgrammes/actions.ts index 490e82576..3c7200e6e 100644 --- a/src/services/groups/studyProgrammes/actions.ts +++ b/src/services/groups/studyProgrammes/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createStudyProgramme } from '@/services/groups/studyProgrammes/create' import { readStudyProgrammes } from '@/services/groups/studyProgrammes/read' diff --git a/src/services/images/collections/actions.ts b/src/services/images/collections/actions.ts index 1e8fc969d..675bdf4d6 100644 --- a/src/services/images/collections/actions.ts +++ b/src/services/images/collections/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { checkVisibility } from '@/auth/checkVisibility' import { getUser } from '@/auth/getUser' import { getVisibilityFilter } from '@/auth/getVisibilityFilter' diff --git a/src/services/mail/actions.ts b/src/services/mail/actions.ts index 51888825c..e0fe0cfc6 100644 --- a/src/services/mail/actions.ts +++ b/src/services/mail/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { readMailAliases } from '@/services/mail/alias/read' import { diff --git a/src/services/mail/alias/actions.ts b/src/services/mail/alias/actions.ts index 2999ad0a9..7748c5cde 100644 --- a/src/services/mail/alias/actions.ts +++ b/src/services/mail/alias/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createMailAlias } from '@/services/mail/alias/create' import { destroyMailAlias } from '@/services/mail/alias/destroy' diff --git a/src/services/mail/list/actions.ts b/src/services/mail/list/actions.ts index c8fa86eaf..31c93a489 100644 --- a/src/services/mail/list/actions.ts +++ b/src/services/mail/list/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createMailingList } from '@/services/mail/list/create' import { destroyMailingList } from '@/services/mail/list/destroy' diff --git a/src/services/mail/mailAddressExternal/actions.ts b/src/services/mail/mailAddressExternal/actions.ts index fd29163fd..4723a0e90 100644 --- a/src/services/mail/mailAddressExternal/actions.ts +++ b/src/services/mail/mailAddressExternal/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createMailAddressExternal } from '@/services/mail/mailAddressExternal/create' import { destroyMailAddressExternal } from '@/services/mail/mailAddressExternal/destroy' diff --git a/src/services/news/actions.ts b/src/services/news/actions.ts index e9b9e37da..be62da560 100644 --- a/src/services/news/actions.ts +++ b/src/services/news/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { createNews } from '@/services/news/create' import { destroyNews } from '@/services/news/destroy' import { readNews, readNewsCurrent, readOldNewsPage } from '@/services/news/read' diff --git a/src/services/ombul/actions.ts b/src/services/ombul/actions.ts index 871a866b4..3474e9028 100644 --- a/src/services/ombul/actions.ts +++ b/src/services/ombul/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createOmbul } from '@/services/ombul/create' import { destroyOmbul } from '@/services/ombul/destroy' diff --git a/src/services/omegaOrder/actions.ts b/src/services/omegaOrder/actions.ts index 21a824f60..e32756c53 100644 --- a/src/services/omegaOrder/actions.ts +++ b/src/services/omegaOrder/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createOmegaOrder } from '@/services/omegaOrder/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' diff --git a/src/services/omegaquotes/actions.ts b/src/services/omegaquotes/actions.ts index df7eb8169..a4bbffbd0 100644 --- a/src/services/omegaquotes/actions.ts +++ b/src/services/omegaquotes/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createQuote } from '@/services/omegaquotes/create' import { readQuotesPage } from '@/services/omegaquotes/read' diff --git a/src/services/screens/actions.ts b/src/services/screens/actions.ts index bfe0a4df6..81fa5fef3 100644 --- a/src/services/screens/actions.ts +++ b/src/services/screens/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { RequirePermission } from '@/auth/auther/RequirePermission' import { Session } from '@/auth/Session' import { createScreen } from '@/services/screens/create' diff --git a/src/services/screens/pages/actions.ts b/src/services/screens/pages/actions.ts index 602d39133..37cfdeae4 100644 --- a/src/services/screens/pages/actions.ts +++ b/src/services/screens/pages/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createPage } from '@/services/screens/pages/create' import { destroyPage } from '@/services/screens/pages/destroy' diff --git a/src/services/sendmail/actions.ts b/src/services/sendmail/actions.ts index 1135dcd4e..492b79307 100644 --- a/src/services/sendmail/actions.ts +++ b/src/services/sendmail/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError, createZodActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { sendMail as transportSendMail } from '@/services/notifications/email/send' import { sendEmailValidation } from '@/services/notifications/email/validation' diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index 292b782bb..ea4433301 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -1,7 +1,6 @@ 'use server' -import { createActionError } from '@/services/actionError' -import { safeServerCall } from '@/services/actionError' +import { createActionError, safeServerCall } from '@/services/actionError' import { checkVisibility } from '@/auth/checkVisibility' import { getUser } from '@/auth/getUser' import { GroupTypesConfig } from '@/services/groups/config' From d7528b708dc569dc3c5d055a9a979b7f572e51be Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 22 Aug 2025 22:54:42 +0200 Subject: [PATCH 10/24] refactor: update imports to use new locatin --- .../register-email/EmailregistrationForm.tsx | 2 +- src/app/(auth)/register-email/page.tsx | 2 +- src/app/(auth)/register/RegistrationForm.tsx | 2 +- src/app/(auth)/register/page.tsx | 2 +- src/app/(auth)/reset-password-form/page.tsx | 2 +- .../reset-password-form/resetpasswordForm.tsx | 2 +- .../(auth)/send-reset-password-email/page.tsx | 2 +- src/app/(auth)/verify-email/page.tsx | 2 +- src/app/(home)/LoggedIn.tsx | 6 ++-- .../_components/Cms/Article/AddSection.tsx | 2 +- .../_components/Cms/Article/ChangeName.tsx | 2 +- .../_components/Cms/Article/SectionMover.tsx | 2 +- .../AddPartToArticleSection.tsx | 2 +- .../Cms/ArticleSection/ImageControls.tsx | 2 +- .../Cms/ArticleSection/RemovePart.tsx | 2 +- .../_components/Cms/CmsImage/ChangeImage.tsx | 2 +- .../Cms/CmsImage/ChangeImageForm.tsx | 2 +- src/app/_components/Cms/CmsImage/CmsImage.tsx | 2 +- .../Cms/CmsImage/CmsImageClient.tsx | 2 +- .../Cms/CmsImage/SpecialCmsImage.tsx | 2 +- .../Cms/CmsImage/SpecialCmsImageClient.tsx | 2 +- .../_components/Cms/CmsLink/CmsLinkEditor.tsx | 2 +- .../Cms/CmsParagraph/CmsParagraphEditor.tsx | 2 +- .../Cms/CmsParagraph/SpecialCmsParagraph.tsx | 2 +- src/app/_components/Company/Company.tsx | 3 +- src/app/_components/Event/EventTagsAdmin.tsx | 4 +-- .../Image/ImageList/ImageDisplay.tsx | 5 ++- src/app/_components/Image/ImageUploader.tsx | 2 +- .../LicenseChooser/LicenseChooser.tsx | 2 +- .../OmegaId/identification/OmegaId.tsx | 2 +- .../OmegaId/identification/OmegaIdElement.tsx | 2 +- src/app/_components/User/CreateUserForm.tsx | 2 +- .../_components/User/UserList/UserList.tsx | 2 +- .../VisiblityAdmin/VisibilityAdmin.tsx | 2 +- .../VisiblityAdmin/VisibilityLevelAdmin.tsx | 5 ++- .../default-permissions/page.tsx | 2 +- .../group-permissions/PermissionCheckbox.tsx | 2 +- .../(permissions)/group-permissions/page.tsx | 2 +- src/app/admin/admission/[admission]/page.tsx | 2 +- .../admission/[admission]/registration.tsx | 2 +- src/app/admin/api-keys/CreateApiKeyForm.tsx | 2 +- .../api-keys/[name]/UpdateApiKeyForm.tsx | 2 +- src/app/admin/api-keys/[name]/page.tsx | 3 +- src/app/admin/api-keys/page.tsx | 2 +- .../admin/cabin-booking/[booking]/page.tsx | 2 +- src/app/admin/cabin-booking/page.tsx | 2 +- .../admin/cabin-periods/PageStateWrapper.tsx | 2 +- .../admin/cabin-periods/PricePeriodForm.tsx | 2 +- .../admin/cabin-periods/ReleasePeriodForm.tsx | 2 +- src/app/admin/cabin-periods/page.tsx | 2 +- .../cabin-product/UpdateCabinProductForm.tsx | 2 +- .../[product]/UpdateCabinProductPriceForm.tsx | 2 +- .../admin/cabin-product/[product]/page.tsx | 2 +- src/app/admin/cabin-product/page.tsx | 2 +- .../admin/committees/CreateCommitteeForm.tsx | 2 +- src/app/admin/committees/page.tsx | 4 +-- src/app/admin/dots/CreateDotForm.tsx | 2 +- src/app/admin/groups/[id]/AddUsersToGroup.tsx | 2 +- .../groups/[id]/MembershipAdminForUser.tsx | 2 +- src/app/admin/groups/[id]/page.tsx | 2 +- src/app/admin/groups/page.tsx | 2 +- src/app/admin/licenses/page.tsx | 10 +++--- .../location/CreateLockerLocationForm.tsx | 2 +- .../admin/lockers/locker/CreateLockerForm.tsx | 2 +- src/app/admin/lockers/locker/page.tsx | 2 +- .../[filter]/[id]/(editComponents)/group.tsx | 2 +- .../(editComponents)/mailAddressExternal.tsx | 8 +++-- .../[id]/(editComponents)/mailAlias.tsx | 5 ++- .../[id]/(editComponents)/mailingList.tsx | 5 ++- .../[filter]/[id]/(editComponents)/user.tsx | 2 +- src/app/admin/mail/[filter]/[id]/MailFlow.tsx | 6 ++-- src/app/admin/mail/[filter]/[id]/page.tsx | 2 +- src/app/admin/mail/createMailAliasForm.tsx | 2 +- .../mail/createMailaddressExternalForm.tsx | 2 +- src/app/admin/mail/createMailingListForm.tsx | 2 +- .../[currentId]/channelSettings.tsx | 2 +- .../[currentId]/page.tsx | 4 +-- .../addNotificationChannel.tsx | 2 +- src/app/admin/notification-channels/page.tsx | 2 +- src/app/admin/omegaid/page.tsx | 2 +- src/app/admin/product/[productId]/page.tsx | 2 +- src/app/admin/product/page.tsx | 2 +- src/app/admin/product/productForm.tsx | 2 +- .../schools/[shortname]/UpdateSchool.tsx | 2 +- src/app/admin/schools/[shortname]/page.tsx | 3 +- src/app/admin/schools/page.tsx | 3 +- src/app/admin/send-mail/mailForm.tsx | 2 +- .../send-notification/notificationForm.tsx | 2 +- src/app/admin/send-notification/page.tsx | 2 +- .../shop/[shop]/EditProductForShopForm.tsx | 2 +- src/app/admin/shop/[shop]/FindProductForm.tsx | 2 +- src/app/admin/shop/[shop]/page.tsx | 3 +- src/app/admin/shop/page.tsx | 2 +- src/app/admin/shop/shopForm.tsx | 2 +- src/app/admin/stateOfOmega/CreateOrder.tsx | 2 +- src/app/admin/stateOfOmega/page.tsx | 2 +- src/app/admin/study-programmes/page.tsx | 2 +- .../updateStudyProgrammeForm.tsx | 3 +- .../CreateUpdateApplicationPeriodForm.tsx | 3 +- .../[periodName]/Reprioritize.tsx | 2 +- .../countdown/CommitteeLogoRoll.tsx | 2 +- .../[periodName]/countdown/FinalCountdown.tsx | 2 +- .../[periodName]/countdown/page.tsx | 4 +-- src/app/applications/[periodName]/page.tsx | 25 +++++++++------ src/app/applications/page.tsx | 4 +-- src/app/articles/AddCategory.tsx | 2 +- src/app/articles/[category]/EditCategory.tsx | 5 ++- src/app/articles/[category]/SideBar.tsx | 2 +- src/app/articles/[category]/[name]/page.tsx | 2 +- src/app/articles/[category]/layout.tsx | 2 +- src/app/articles/page.tsx | 2 +- src/app/cabin/book/page.tsx | 2 +- src/app/cabin/book/stateWrapper.tsx | 2 +- src/app/career/companies/page.tsx | 3 +- src/app/career/jobads/CreateJobAdForm.tsx | 2 +- src/app/career/jobads/CurrentJobAds.tsx | 2 +- .../jobads/[...orderAndName]/EditJobAd.tsx | 3 +- .../career/jobads/[...orderAndName]/page.tsx | 2 +- src/app/career/page.tsx | 6 ++-- src/app/committees/[shortName]/about/page.tsx | 2 +- .../committees/[shortName]/getCommittee.ts | 2 +- src/app/committees/[shortName]/layout.tsx | 2 +- .../committees/[shortName]/members/page.tsx | 2 +- src/app/committees/[shortName]/page.tsx | 2 +- src/app/committees/page.tsx | 4 +-- src/app/education/courses/page.tsx | 2 +- src/app/education/page.tsx | 2 +- src/app/education/schools/page.tsx | 2 +- src/app/events/CreateOrUpdateEventForm.tsx | 3 +- .../[order]/[name]/ManualRegistrationForm.tsx | 2 +- .../events/[order]/[name]/RegistrationUI.tsx | 10 +++--- .../[order]/[name]/RegistrationsList.tsx | 2 +- .../events/[order]/[name]/ShowAndEditName.tsx | 2 +- src/app/events/[order]/[name]/page.tsx | 5 ++- src/app/events/archive/page.tsx | 2 +- src/app/events/page.tsx | 4 +-- src/app/images/MakeNewCollection.tsx | 2 +- .../collections/[id]/CollectionAdmin.tsx | 3 +- .../[id]/CollectionAdminUpload.tsx | 2 +- src/app/images/collections/[id]/page.tsx | 4 +-- src/app/images/page.tsx | 2 +- .../CreateInterestGroupForm.tsx | 2 +- src/app/interest-groups/InterestGroup.tsx | 3 +- src/app/interest-groups/page.tsx | 2 +- src/app/layout.tsx | 4 +-- .../[id]/CreateLockerReservationForm.tsx | 2 +- .../[id]/UpdateLockerReservationForm.tsx | 2 +- src/app/lockers/[id]/page.tsx | 2 +- src/app/news/AddNews.tsx | 2 +- src/app/news/CurrentNews.tsx | 2 +- src/app/news/[...orderAndName]/EditNews.tsx | 3 +- src/app/news/[...orderAndName]/page.tsx | 2 +- src/app/news/archive/page.tsx | 2 +- src/app/ombul/CreateOmbul.tsx | 2 +- src/app/ombul/[...yearAndName]/ChangeName.tsx | 2 +- src/app/ombul/[...yearAndName]/OmbulAdmin.tsx | 3 +- src/app/ombul/[...yearAndName]/page.tsx | 3 +- src/app/ombul/page.tsx | 2 +- src/app/omegaquotes/CreateOmegaquoteForm.tsx | 2 +- src/app/omegaquotes/page.tsx | 2 +- .../[username]/(user-admin)/dots/page.tsx | 2 +- .../(user-admin)/getProfileForAdmin.ts | 2 +- .../users/[username]/(user-admin)/layout.tsx | 2 +- .../notifications/notificationSettings.tsx | 2 +- .../(user-admin)/notifications/page.tsx | 2 +- .../settings/RegisterStudentCardButton.tsx | 2 +- src/app/users/[username]/page.tsx | 4 +-- src/contexts/paging/CompanyPaging.tsx | 2 +- src/contexts/paging/DotPaging.tsx | 2 +- src/contexts/paging/EventArchivePaging.tsx | 2 +- .../EventRegistrationDetailedPaging.tsx | 2 +- .../paging/EventRegistrationPaging.tsx | 2 +- src/contexts/paging/ImageCollectionPaging.tsx | 2 +- src/contexts/paging/ImagePaging.tsx | 2 +- src/contexts/paging/JobAdInactivePaging.tsx | 2 +- src/contexts/paging/LockerPaging.tsx | 2 +- src/contexts/paging/OldNewsPaging.tsx | 2 +- src/contexts/paging/OmegaquotesPaging.tsx | 2 +- src/contexts/paging/SchoolPaging.tsx | 2 +- src/contexts/paging/UserPaging.tsx | 2 +- src/services/cms/images/actions.ts | 11 ++----- src/services/cms/images/validation.ts | 7 +++++ src/services/cms/paragraphs/actions.ts | 11 ++----- src/services/cms/paragraphs/validation.ts | 7 +++++ src/services/visibility/Types.ts | 25 +++++++++++++++ src/services/visibility/actions.ts | 31 ++++--------------- tsconfig.json | 8 ++--- 187 files changed, 280 insertions(+), 290 deletions(-) diff --git a/src/app/(auth)/register-email/EmailregistrationForm.tsx b/src/app/(auth)/register-email/EmailregistrationForm.tsx index d250fc39c..dc40b449a 100644 --- a/src/app/(auth)/register-email/EmailregistrationForm.tsx +++ b/src/app/(auth)/register-email/EmailregistrationForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { registerNewEmailAction } from '@/actions/users/update' +import { registerNewEmailAction } from '@/services/users/actions' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import { useSearchParams, useRouter } from 'next/navigation' diff --git a/src/app/(auth)/register-email/page.tsx b/src/app/(auth)/register-email/page.tsx index c6102fc22..9ec1224d9 100644 --- a/src/app/(auth)/register-email/page.tsx +++ b/src/app/(auth)/register-email/page.tsx @@ -1,6 +1,6 @@ import EmailRegistrationForm from './EmailregistrationForm' import { getUser } from '@/auth/getUser' -import { readUserAction } from '@/actions/users/read' +import { readUserAction } from '@/services/users/actions' import { notFound, redirect } from 'next/navigation' export default async function Registeremail() { diff --git a/src/app/(auth)/register/RegistrationForm.tsx b/src/app/(auth)/register/RegistrationForm.tsx index 8b75b0fcf..cbe1c00a7 100644 --- a/src/app/(auth)/register/RegistrationForm.tsx +++ b/src/app/(auth)/register/RegistrationForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { registerUser } from '@/actions/users/update' +import { registerUser } from '@/services/users/actions' import Form from '@/components/Form/Form' import Checkbox from '@/components/UI/Checkbox' import { SelectString } from '@/components/UI/Select' diff --git a/src/app/(auth)/register/page.tsx b/src/app/(auth)/register/page.tsx index 19a55df3d..3fb3aa197 100644 --- a/src/app/(auth)/register/page.tsx +++ b/src/app/(auth)/register/page.tsx @@ -2,7 +2,7 @@ import RegistrationForm from './RegistrationForm' import { getUser } from '@/auth/getUser' import { QueryParams } from '@/lib/query-params/queryParams' import { unwrapActionReturn } from '@/app/redirectToErrorPage' -import { readUserAction } from '@/actions/users/read' +import { readUserAction } from '@/services/users/actions' import { notFound, redirect } from 'next/navigation' import type { SearchParamsServerSide } from '@/lib/query-params/Types' diff --git a/src/app/(auth)/reset-password-form/page.tsx b/src/app/(auth)/reset-password-form/page.tsx index d34097c16..d63adf3d4 100644 --- a/src/app/(auth)/reset-password-form/page.tsx +++ b/src/app/(auth)/reset-password-form/page.tsx @@ -1,5 +1,5 @@ import ResetPasswordForm from './resetpasswordForm' -import { verifyResetPasswordTokenAction } from '@/actions/auth/auth' +import { verifyResetPasswordTokenAction } from '@/services/auth/actions' import { QueryParams } from '@/lib/query-params/queryParams' import type { SearchParamsServerSide } from '@/lib/query-params/Types' diff --git a/src/app/(auth)/reset-password-form/resetpasswordForm.tsx b/src/app/(auth)/reset-password-form/resetpasswordForm.tsx index 724a87af0..1886c3f9e 100644 --- a/src/app/(auth)/reset-password-form/resetpasswordForm.tsx +++ b/src/app/(auth)/reset-password-form/resetpasswordForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { resetPasswordAction } from '@/actions/auth/auth' +import { resetPasswordAction } from '@/services/auth/actions' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' diff --git a/src/app/(auth)/send-reset-password-email/page.tsx b/src/app/(auth)/send-reset-password-email/page.tsx index 4d7931739..b5b5498b8 100644 --- a/src/app/(auth)/send-reset-password-email/page.tsx +++ b/src/app/(auth)/send-reset-password-email/page.tsx @@ -1,5 +1,5 @@ 'use client' -import { sendResetPasswordEmailAction } from '@/actions/auth/auth' +import { sendResetPasswordEmailAction } from '@/services/auth/actions' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import { useState } from 'react' diff --git a/src/app/(auth)/verify-email/page.tsx b/src/app/(auth)/verify-email/page.tsx index 1f195d576..9ede27b8d 100644 --- a/src/app/(auth)/verify-email/page.tsx +++ b/src/app/(auth)/verify-email/page.tsx @@ -2,10 +2,10 @@ import { EmailVerifiedWrapper } from './EmailVerifiedWrapper' import { getUser } from '@/auth/getUser' import { QueryParams } from '@/lib/query-params/queryParams' import { unwrapActionReturn } from '@/app/redirectToErrorPage' +import { verifyEmailAction } from '@/services/auth/actions' import { notFound, redirect } from 'next/navigation' import Link from 'next/link' import type { SearchParamsServerSide } from '@/lib/query-params/Types' -import { verifyEmailAction } from '@/actions/auth/auth' type PropTypes = SearchParamsServerSide diff --git a/src/app/(home)/LoggedIn.tsx b/src/app/(home)/LoggedIn.tsx index b060e7cd6..e32ab51f5 100644 --- a/src/app/(home)/LoggedIn.tsx +++ b/src/app/(home)/LoggedIn.tsx @@ -7,9 +7,9 @@ import NewsCard from '@/app/news/NewsCard' import SocialIcons from '@/components/SocialIcons/SocialIcons' import SpecialCmsImage from '@/components/Cms/CmsImage/SpecialCmsImage' import { unwrapActionReturn } from '@/app/redirectToErrorPage' -import { readNewsCurrentAction } from '@/actions/news/read' -import { readActiveJobAdsAction } from '@/actions/career/jobAds/read' -import { readCurrentEventsAction } from '@/actions/events/read' +import { readNewsCurrentAction } from '@/services/news/actions' +import { readActiveJobAdsAction } from '@/services/career/jobAds/actions' +import { readCurrentEventsAction } from '@/services/events/actions' import { faAngleDown } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import Link from 'next/link' diff --git a/src/app/_components/Cms/Article/AddSection.tsx b/src/app/_components/Cms/Article/AddSection.tsx index 94817c325..bfe816249 100644 --- a/src/app/_components/Cms/Article/AddSection.tsx +++ b/src/app/_components/Cms/Article/AddSection.tsx @@ -2,7 +2,7 @@ import styles from './AddSection.module.scss' import AddParts from '@/cms/AddParts' -import { addSectionToArticleAction } from '@/cms/articles/update' +import { addSectionToArticleAction } from '@/cms/articles/actions' import { maxSections } from '@/cms/articles/ConfigVars' import useEditing from '@/hooks/useEditing' import { useRouter } from 'next/navigation' diff --git a/src/app/_components/Cms/Article/ChangeName.tsx b/src/app/_components/Cms/Article/ChangeName.tsx index ca962c0bb..f7c05ce34 100644 --- a/src/app/_components/Cms/Article/ChangeName.tsx +++ b/src/app/_components/Cms/Article/ChangeName.tsx @@ -1,7 +1,7 @@ 'use client' import styles from './ChangeName.module.scss' import EditableTextField from '@/components/EditableTextField/EditableTextField' -import { updateArticleAction } from '@/actions/cms/articles/update' +import { updateArticleAction } from '@/services/cms/articles/actions' import React, { useState } from 'react' import { usePathname } from 'next/navigation' import type { ExpandedArticle } from '@/cms/articles/Types' diff --git a/src/app/_components/Cms/Article/SectionMover.tsx b/src/app/_components/Cms/Article/SectionMover.tsx index e87a11dc8..2424301d9 100644 --- a/src/app/_components/Cms/Article/SectionMover.tsx +++ b/src/app/_components/Cms/Article/SectionMover.tsx @@ -1,11 +1,11 @@ 'use client' import styles from './SectionMover.module.scss' import useEditing from '@/hooks/useEditing' +import { moveSectionOrderAction } from '@/services/cms/articles/actions' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faArrowDown, faArrowUp } from '@fortawesome/free-solid-svg-icons' import { useCallback } from 'react' import { useRouter } from 'next/navigation' -import { moveSectionOrderAction } from '@/actions/cms/articles/update' type PropTypes = { articleId: number diff --git a/src/app/_components/Cms/ArticleSection/AddPartToArticleSection.tsx b/src/app/_components/Cms/ArticleSection/AddPartToArticleSection.tsx index f801f665a..722d7674f 100644 --- a/src/app/_components/Cms/ArticleSection/AddPartToArticleSection.tsx +++ b/src/app/_components/Cms/ArticleSection/AddPartToArticleSection.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './AddPartToArticleSection.module.scss' -import { addArticleSectionPartAction } from '@/cms/articleSections/update' +import { addArticleSectionPartAction } from '@/cms/articleSections/actions' import AddParts from '@/cms/AddParts' import useEditing from '@/hooks/useEditing' import { useCallback } from 'react' diff --git a/src/app/_components/Cms/ArticleSection/ImageControls.tsx b/src/app/_components/Cms/ArticleSection/ImageControls.tsx index 7834fced7..21805c64f 100644 --- a/src/app/_components/Cms/ArticleSection/ImageControls.tsx +++ b/src/app/_components/Cms/ArticleSection/ImageControls.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './ImageControls.module.scss' -import { updateArticleSectionAction } from '@/cms/articleSections/update' +import { updateArticleSectionAction } from '@/cms/articleSections/actions' import { imageSizeIncrement, maxImageSize, minImageSize } from '@/cms/articleSections/ConfigVars' import useEditing from '@/hooks/useEditing' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' diff --git a/src/app/_components/Cms/ArticleSection/RemovePart.tsx b/src/app/_components/Cms/ArticleSection/RemovePart.tsx index 7b0c085c7..402d1d52e 100644 --- a/src/app/_components/Cms/ArticleSection/RemovePart.tsx +++ b/src/app/_components/Cms/ArticleSection/RemovePart.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './RemovePart.module.scss' -import { removeArticleSectionPartAction } from '@/cms/articleSections/update' +import { removeArticleSectionPartAction } from '@/cms/articleSections/actions' import Form from '@/components/Form/Form' import useClickOutsideRef from '@/hooks/useClickOutsideRef' import useEditing from '@/hooks/useEditing' diff --git a/src/app/_components/Cms/CmsImage/ChangeImage.tsx b/src/app/_components/Cms/CmsImage/ChangeImage.tsx index a2e15ae80..b154db70d 100644 --- a/src/app/_components/Cms/CmsImage/ChangeImage.tsx +++ b/src/app/_components/Cms/CmsImage/ChangeImage.tsx @@ -4,11 +4,11 @@ import ChangeImageForm from './ChangeImageForm' import Image from '@/components/Image/Image' import { ImageSelectionContext } from '@/contexts/ImageSelection' import Form from '@/components/Form/Form' +import { updateCmsImageConfigAction } from '@/services/cms/images/actions' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faTurnUp } from '@fortawesome/free-solid-svg-icons' import React, { useContext, useEffect, useState } from 'react' import type { ImageSize, Image as ImageT } from '@prisma/client' -import { updateCmsImageConfigAction } from '@/actions/cms/images/update' type PropTypes = { currentImage: ImageT, diff --git a/src/app/_components/Cms/CmsImage/ChangeImageForm.tsx b/src/app/_components/Cms/CmsImage/ChangeImageForm.tsx index f1734a248..86f300124 100644 --- a/src/app/_components/Cms/CmsImage/ChangeImageForm.tsx +++ b/src/app/_components/Cms/CmsImage/ChangeImageForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { updateCmsImageAction } from '@/actions/cms/images/update' +import { updateCmsImageAction } from '@/services/cms/images/actions' import Form from '@/components/Form/Form' import { ImageSelectionContext } from '@/contexts/ImageSelection' import { useContext } from 'react' diff --git a/src/app/_components/Cms/CmsImage/CmsImage.tsx b/src/app/_components/Cms/CmsImage/CmsImage.tsx index 2a5009816..8dac43d5a 100644 --- a/src/app/_components/Cms/CmsImage/CmsImage.tsx +++ b/src/app/_components/Cms/CmsImage/CmsImage.tsx @@ -1,10 +1,10 @@ import CmsImageEditor from './CmsImageEditor' import styles from './CmsImage.module.scss' import Image, { SrcImage } from '@/components/Image/Image' +import { readSpecialImageAction } from '@/services/images/actions' import React from 'react' import type { ExpandedCmsImage } from '@/cms/images/Types' import type { PropTypes as ImagePropTypes } from '@/components/Image/Image' -import { readSpecialImageAction } from '@/actions/images/read' export type PropTypes = Omit< ImagePropTypes, 'className' | 'imageSize' | 'smallSize' | 'largeSize' | 'image' | 'children' diff --git a/src/app/_components/Cms/CmsImage/CmsImageClient.tsx b/src/app/_components/Cms/CmsImage/CmsImageClient.tsx index 7341e52e9..19b8a873e 100644 --- a/src/app/_components/Cms/CmsImage/CmsImageClient.tsx +++ b/src/app/_components/Cms/CmsImage/CmsImageClient.tsx @@ -3,10 +3,10 @@ import CmsImageEditor from './CmsImageEditor' import styles from './CmsImage.module.scss' import { fallbackImage } from './CmsImage' import Image, { SrcImage } from '@/components/Image/Image' +import { readSpecialImageAction } from '@/services/images/actions' import { useState, useEffect } from 'react' import type { PropTypes } from './CmsImage' import type { Image as ImageT } from '@prisma/client' -import { readSpecialImageAction } from '@/actions/images/read' /** * WARNING: This component is only meant for the client diff --git a/src/app/_components/Cms/CmsImage/SpecialCmsImage.tsx b/src/app/_components/Cms/CmsImage/SpecialCmsImage.tsx index 672435efb..0def3826d 100644 --- a/src/app/_components/Cms/CmsImage/SpecialCmsImage.tsx +++ b/src/app/_components/Cms/CmsImage/SpecialCmsImage.tsx @@ -1,5 +1,5 @@ import CmsImage from './CmsImage' -import { readSpecialCmsImageAction } from '@/actions/cms/images/read' +import { readSpecialCmsImageAction } from '@/services/cms/images/actions' import type { SpecialCmsImage as SpecialCmsImageT } from '@prisma/client' import type { PropTypes as CmsImageProps } from './CmsImage' diff --git a/src/app/_components/Cms/CmsImage/SpecialCmsImageClient.tsx b/src/app/_components/Cms/CmsImage/SpecialCmsImageClient.tsx index e0a20b7fd..f3ae1377d 100644 --- a/src/app/_components/Cms/CmsImage/SpecialCmsImageClient.tsx +++ b/src/app/_components/Cms/CmsImage/SpecialCmsImageClient.tsx @@ -1,6 +1,6 @@ 'use client' import CmsImageClient from './CmsImageClient' -import { readSpecialCmsImageAction } from '@/actions/cms/images/read' +import { readSpecialCmsImageAction } from '@/services/cms/images/actions' import useActionCall from '@/hooks/useActionCall' import { useCallback } from 'react' import type { PropTypes } from './SpecialCmsImage' diff --git a/src/app/_components/Cms/CmsLink/CmsLinkEditor.tsx b/src/app/_components/Cms/CmsLink/CmsLinkEditor.tsx index d8ceb9a0a..a683fea17 100644 --- a/src/app/_components/Cms/CmsLink/CmsLinkEditor.tsx +++ b/src/app/_components/Cms/CmsLink/CmsLinkEditor.tsx @@ -3,7 +3,7 @@ import styles from './CmsLinkEditor.module.scss' import TextInput from '@/components/UI/TextInput' import EditOverlay from '@/cms/EditOverlay' import Form from '@/components/Form/Form' -import { updateCmsLinkAction } from '@/cms/links/update' +import { updateCmsLinkAction } from '@/cms/links/actions' import PopUp from '@/components/PopUp/PopUp' import useEditing from '@/hooks/useEditing' import { useRouter } from 'next/navigation' diff --git a/src/app/_components/Cms/CmsParagraph/CmsParagraphEditor.tsx b/src/app/_components/Cms/CmsParagraph/CmsParagraphEditor.tsx index ccfaea7e8..373f1e248 100644 --- a/src/app/_components/Cms/CmsParagraph/CmsParagraphEditor.tsx +++ b/src/app/_components/Cms/CmsParagraph/CmsParagraphEditor.tsx @@ -4,13 +4,13 @@ import EditOverlay from '@/components/Cms/EditOverlay' import Form from '@/components/Form/Form' import PopUp from '@/components/PopUp/PopUp' import useEditing from '@/hooks/useEditing' +import { updateCmsParagraphAction } from '@/services/cms/paragraphs/actions' import { useState } from 'react' import { useRouter } from 'next/navigation' import 'easymde/dist/easymde.min.css' import './CustomEditorClasses.scss' import dynamic from 'next/dynamic' import type { CmsParagraph } from '@prisma/client' -import { updateCmsParagraphAction } from '@/actions/cms/paragraphs/update' //needed because SimpleMDE is not SSR compatible as it access navigator object const DynamicSimpleMDEditor = dynamic( diff --git a/src/app/_components/Cms/CmsParagraph/SpecialCmsParagraph.tsx b/src/app/_components/Cms/CmsParagraph/SpecialCmsParagraph.tsx index ff32037d2..84bf5482b 100644 --- a/src/app/_components/Cms/CmsParagraph/SpecialCmsParagraph.tsx +++ b/src/app/_components/Cms/CmsParagraph/SpecialCmsParagraph.tsx @@ -1,5 +1,5 @@ import CmsParagraph from './CmsParagraph' -import { readSpecialCmsParagraphAction } from '@/actions/cms/paragraphs/read' +import { readSpecialCmsParagraphAction } from '@/services/cms/paragraphs/actions' import React from 'react' import type { PropTypes as PropTypesCmsParapraph } from './CmsParagraph' import type { SpecialCmsParagraph as SpecialCmsParagraphT } from '@prisma/client' diff --git a/src/app/_components/Company/Company.tsx b/src/app/_components/Company/Company.tsx index e4c4eb9a5..9b3d5bf62 100644 --- a/src/app/_components/Company/Company.tsx +++ b/src/app/_components/Company/Company.tsx @@ -7,10 +7,9 @@ import CmsImageClient from '@/cms/CmsImage/CmsImageClient' import Form from '@/components/Form/Form' import { bindParams } from '@/services/actionBind' import { CompanyAuthers } from '@/services/career/companies/authers' +import { destroyCompanyAction, updateComanyAction } from '@/services/career/companies/actions' import type { CompanyExpanded } from '@/services/career/companies/Types' import type { SessionMaybeUser } from '@/auth/Session' -import { destroyCompanyAction } from '@/actions/career/companies/destroy' -import { updateComanyAction } from '@/actions/career/companies/update' type PropTypes = { company: CompanyExpanded, diff --git a/src/app/_components/Event/EventTagsAdmin.tsx b/src/app/_components/Event/EventTagsAdmin.tsx index 17b6f3c24..d7e13d76a 100644 --- a/src/app/_components/Event/EventTagsAdmin.tsx +++ b/src/app/_components/Event/EventTagsAdmin.tsx @@ -7,11 +7,9 @@ import Textarea from '@/UI/Textarea' import ColorInput from '@/UI/ColorInput' import { QueryParams } from '@/lib/query-params/queryParams' import { bindParams } from '@/services/actionBind' +import { destroyEventTagAction, updateEventTagAction, createEventTagAction } from '@/services/events/tags/actions' import Link from 'next/link' import type { EventTag as EventTagT } from '@prisma/client' -import { destroyEventTagAction } from '@/actions/events/tags/destroy' -import { updateEventTagAction } from '@/actions/events/tags/update' -import { createEventTagAction } from '@/actions/events/tags/create' type PropTypes = { eventTags: EventTagT[] diff --git a/src/app/_components/Image/ImageList/ImageDisplay.tsx b/src/app/_components/Image/ImageList/ImageDisplay.tsx index 78e11bfe1..7dec70291 100644 --- a/src/app/_components/Image/ImageList/ImageDisplay.tsx +++ b/src/app/_components/Image/ImageList/ImageDisplay.tsx @@ -9,6 +9,8 @@ import TextInput from '@/components/UI/TextInput' import { ImagePagingContext } from '@/contexts/paging/ImagePaging' import { ImageDisplayContext } from '@/contexts/ImageDisplayProvider' import LicenseChooser from '@/components/LicenseChooser/LicenseChooser' +import { updateImageCollectionAction } from '@/services/images/collections/actions' +import { destroyImageAction, updateImageAction } from '@/services/images/actions' import { useRouter } from 'next/navigation' import { faChevronRight, faChevronLeft, faX, faCog } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' @@ -16,9 +18,6 @@ import { useContext } from 'react' import Link from 'next/link' import type { ImageSizeOptions } from '@/components/Image/Image' import type { Image as ImageT } from '@prisma/client' -import { updateImageCollectionAction } from '@/actions/images/collections/update' -import { destroyImageAction } from '@/actions/images/destroy' -import { updateImageAction } from '@/actions/images/update' const mimeTypes: { [key: string]: string } = { jpg: 'image/jpeg', diff --git a/src/app/_components/Image/ImageUploader.tsx b/src/app/_components/Image/ImageUploader.tsx index c33cb2da6..435eabc73 100644 --- a/src/app/_components/Image/ImageUploader.tsx +++ b/src/app/_components/Image/ImageUploader.tsx @@ -3,8 +3,8 @@ import TextInput from '@/components/UI/TextInput' import FileInput from '@/components/UI/FileInput' import LicenseChooser from '@/components/LicenseChooser/LicenseChooser' import { bindParams } from '@/services/actionBind' +import { createImageAction } from '@/services/images/actions' import type { PropTypes as FormPropTypes } from '@/components/Form/Form' -import { createImageAction } from '@/actions/images/create' type ResponseType = Awaited>; type T = Pick['data'] diff --git a/src/app/_components/LicenseChooser/LicenseChooser.tsx b/src/app/_components/LicenseChooser/LicenseChooser.tsx index 97930217a..17089067f 100644 --- a/src/app/_components/LicenseChooser/LicenseChooser.tsx +++ b/src/app/_components/LicenseChooser/LicenseChooser.tsx @@ -1,7 +1,7 @@ 'use client' import styles from './LicenseChooser.module.scss' import { SelectNumberPossibleNULL } from '@/UI/Select' -import { readAllLicensesAction } from '@/actions/licenses/read' +import { readAllLicensesAction } from '@/services/licenses/actions' import useActionCall from '@/hooks/useActionCall' import { useCallback, useEffect, useState } from 'react' diff --git a/src/app/_components/OmegaId/identification/OmegaId.tsx b/src/app/_components/OmegaId/identification/OmegaId.tsx index c08ac0a7d..17bb5c9fb 100644 --- a/src/app/_components/OmegaId/identification/OmegaId.tsx +++ b/src/app/_components/OmegaId/identification/OmegaId.tsx @@ -1,7 +1,7 @@ 'use server' import OmegaIdElement from './OmegaIdElement' -import { generateOmegaIdAction } from '@/actions/omegaid/generate' +import { generateOmegaIdAction } from '@/services/omegaid/actions' export default async function OmegaId() { diff --git a/src/app/_components/OmegaId/identification/OmegaIdElement.tsx b/src/app/_components/OmegaId/identification/OmegaIdElement.tsx index 3e9b3d919..c052eb76d 100644 --- a/src/app/_components/OmegaId/identification/OmegaIdElement.tsx +++ b/src/app/_components/OmegaId/identification/OmegaIdElement.tsx @@ -1,7 +1,7 @@ 'use client' import styles from './OmegaIdElement.module.scss' import { useUser } from '@/auth/useUser' -import { generateOmegaIdAction } from '@/actions/omegaid/generate' +import { generateOmegaIdAction } from '@/services/omegaid/actions' import { readJWTPayload } from '@/jwt/jwtReadUnsecure' import { compressOmegaId } from '@/services/omegaid/compress' import { useQRCode } from 'next-qrcode' diff --git a/src/app/_components/User/CreateUserForm.tsx b/src/app/_components/User/CreateUserForm.tsx index ca01be9f5..05b9bf370 100644 --- a/src/app/_components/User/CreateUserForm.tsx +++ b/src/app/_components/User/CreateUserForm.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './CreateUserForm.module.scss' -import { createUserAction } from '@/actions/users/create' +import { createUserAction } from '@/services/users/actions' import TextInput from '@/components/UI/TextInput' import Form from '@/components/Form/Form' import React from 'react' diff --git a/src/app/_components/User/UserList/UserList.tsx b/src/app/_components/User/UserList/UserList.tsx index 60b2df190..779802aa0 100644 --- a/src/app/_components/User/UserList/UserList.tsx +++ b/src/app/_components/User/UserList/UserList.tsx @@ -7,6 +7,7 @@ import UserRow from '@/components/User/UserList/UserRow' import useActionCall from '@/hooks/useActionCall' import { UsersSelectionContext } from '@/contexts/UsersSelection' import { UserSelectionContext } from '@/contexts/UserSelection' +import { readGroupsForPageFilteringAction } from '@/services/users/actions' import { useContext, useEffect, useState } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faCheck } from '@fortawesome/free-solid-svg-icons' @@ -14,7 +15,6 @@ import type { UserPagingReturn } from '@/services/users/Types' import type { ChangeEvent, ReactNode } from 'react' import type { GroupType } from '@prisma/client' import type { ExpandedGroup } from '@/services/groups/Types' -import { readGroupsForPageFilteringAction } from '@/actions/users/read' type GroupSelectionType = Exclude diff --git a/src/app/_components/VisiblityAdmin/VisibilityAdmin.tsx b/src/app/_components/VisiblityAdmin/VisibilityAdmin.tsx index b5645cfa5..bd940e11f 100644 --- a/src/app/_components/VisiblityAdmin/VisibilityAdmin.tsx +++ b/src/app/_components/VisiblityAdmin/VisibilityAdmin.tsx @@ -2,7 +2,7 @@ import styles from './VisibilityAdmin.module.scss' import VisibilityLevelAdmin from './VisibilityLevelAdmin' import useActionCall from '@/hooks/useActionCall' -import { readVisibilityForAdminAction } from '@/actions/visibility/read' +import { readVisibilityForAdminAction } from '@/services/visibility/actions' import { useCallback } from 'react' type PropTypes = { diff --git a/src/app/_components/VisiblityAdmin/VisibilityLevelAdmin.tsx b/src/app/_components/VisiblityAdmin/VisibilityLevelAdmin.tsx index 4f16a6ed4..acc1c2d3b 100644 --- a/src/app/_components/VisiblityAdmin/VisibilityLevelAdmin.tsx +++ b/src/app/_components/VisiblityAdmin/VisibilityLevelAdmin.tsx @@ -1,8 +1,7 @@ import styles from './VisibilityLevelAdmin.module.scss' import Form from '@/components/Form/Form' -import { updateVisibilityAction } from '@/actions/visibility/update' -import type { VisibilityLevelType } from '@/services/visibility/Types' -import type { VisibilityRequiermentForAdmin } from '@/actions/visibility/Types' +import { updateVisibilityAction } from '@/services/visibility/actions' +import type { VisibilityLevelType, VisibilityRequiermentForAdmin } from '@/services/visibility/Types' type PropTypes = { data: VisibilityRequiermentForAdmin[] diff --git a/src/app/admin/(permissions)/default-permissions/page.tsx b/src/app/admin/(permissions)/default-permissions/page.tsx index e657ebb67..da8d052b6 100644 --- a/src/app/admin/(permissions)/default-permissions/page.tsx +++ b/src/app/admin/(permissions)/default-permissions/page.tsx @@ -1,4 +1,4 @@ -import { updateDefaultPermissionsAction, readDefaultPermissionsAction } from '@/actions/permissions/index' +import { updateDefaultPermissionsAction, readDefaultPermissionsAction } from '@/services/permissions/actions' import Form from '@/components/Form/Form' import DisplayAllPermissions from '@/components/Permission/DisplayAllPermissions' import React from 'react' diff --git a/src/app/admin/(permissions)/group-permissions/PermissionCheckbox.tsx b/src/app/admin/(permissions)/group-permissions/PermissionCheckbox.tsx index 3984084f4..d61f8a99e 100644 --- a/src/app/admin/(permissions)/group-permissions/PermissionCheckbox.tsx +++ b/src/app/admin/(permissions)/group-permissions/PermissionCheckbox.tsx @@ -2,7 +2,7 @@ import Checkbox from '@/components/UI/Checkbox' import { unwrapActionReturn } from '@/app/redirectToErrorPage' -import { updateGroupPermissionAction } from '@/actions/permissions' +import { updateGroupPermissionAction } from '@/services/permissions/actions' import { useState } from 'react' import type { Permission } from '@prisma/client' diff --git a/src/app/admin/(permissions)/group-permissions/page.tsx b/src/app/admin/(permissions)/group-permissions/page.tsx index 6b74b3bb8..56ccb625f 100644 --- a/src/app/admin/(permissions)/group-permissions/page.tsx +++ b/src/app/admin/(permissions)/group-permissions/page.tsx @@ -1,6 +1,6 @@ import styles from './page.module.scss' import PermissionCheckbox from './PermissionCheckbox' -import { readPermissionMatrixAction } from '@/actions/permissions' +import { readPermissionMatrixAction } from '@/services/permissions/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { PermissionConfig } from '@/services/permissions/config' import type { Permission } from '@prisma/client' diff --git a/src/app/admin/admission/[admission]/page.tsx b/src/app/admin/admission/[admission]/page.tsx index 327d7a921..83481671d 100644 --- a/src/app/admin/admission/[admission]/page.tsx +++ b/src/app/admin/admission/[admission]/page.tsx @@ -1,6 +1,6 @@ import RegisterAdmissiontrial from './registration' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { readOmegaJWTPublicKey } from '@/actions/omegaid/read' +import { readOmegaJWTPublicKey } from '@/services/omegaid/actions' import { AdmissionConfig } from '@/services/admission/config' import { type Admission as AdmissionType } from '@prisma/client' import { notFound } from 'next/navigation' diff --git a/src/app/admin/admission/[admission]/registration.tsx b/src/app/admin/admission/[admission]/registration.tsx index 21bb02825..8f5010308 100644 --- a/src/app/admin/admission/[admission]/registration.tsx +++ b/src/app/admin/admission/[admission]/registration.tsx @@ -5,8 +5,8 @@ import { bindParams } from '@/services/actionBind' import Form from '@/components/Form/Form' import OmegaIdReader from '@/components/OmegaId/reader/OmegaIdReader' import TextInput from '@/components/UI/TextInput' +import { createAdmissionTrialAction } from '@/services/admission/actions' import type { Admission } from '@prisma/client' -import { createAdmissionTrialAction } from '@/actions/admission/create' export default function RegisterAdmissiontrial({ diff --git a/src/app/admin/api-keys/CreateApiKeyForm.tsx b/src/app/admin/api-keys/CreateApiKeyForm.tsx index 23cdbb0bb..efbda9ff9 100644 --- a/src/app/admin/api-keys/CreateApiKeyForm.tsx +++ b/src/app/admin/api-keys/CreateApiKeyForm.tsx @@ -1,7 +1,7 @@ 'use client' import styles from './CreateApiKeyForm.module.scss' import Form from '@/components/Form/Form' -import { createApiKeyAction } from '@/actions/api-keys/create' +import { createApiKeyAction } from '@/services/api-keys/actions' import TextInput from '@/components/UI/TextInput' import { PopUpContext } from '@/contexts/PopUp' import { useContext, useState } from 'react' diff --git a/src/app/admin/api-keys/[name]/UpdateApiKeyForm.tsx b/src/app/admin/api-keys/[name]/UpdateApiKeyForm.tsx index 8d85a10f5..405636a76 100644 --- a/src/app/admin/api-keys/[name]/UpdateApiKeyForm.tsx +++ b/src/app/admin/api-keys/[name]/UpdateApiKeyForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { updateApiKeyAction } from '@/actions/api-keys/update' +import { updateApiKeyAction } from '@/services/api-keys/actions' import Form from '@/app/_components/Form/Form' import type { ReactNode } from 'react' diff --git a/src/app/admin/api-keys/[name]/page.tsx b/src/app/admin/api-keys/[name]/page.tsx index ddf2aba8b..45d8ce06e 100644 --- a/src/app/admin/api-keys/[name]/page.tsx +++ b/src/app/admin/api-keys/[name]/page.tsx @@ -1,13 +1,12 @@ import styles from './page.module.scss' import UpdateApiKeyForm from './UpdateApiKeyForm' -import { readApiKeyAction } from '@/actions/api-keys/read' +import { readApiKeyAction, destroyApiKeyAction } from '@/services/api-keys/actions' import PageWrapper from '@/components/PageWrapper/PageWrapper' import Form from '@/components/Form/Form' import DateInput from '@/components/UI/DateInput' import TextInput from '@/components/UI/TextInput' import DisplayAllPermissions from '@/components/Permission/DisplayAllPermissions' import Slider from '@/components/UI/Slider' -import { destroyApiKeyAction } from '@/actions/api-keys/destroy' import Date from '@/app/_components/Date/Date' import Checkbox from '@/app/_components/UI/Checkbox' diff --git a/src/app/admin/api-keys/page.tsx b/src/app/admin/api-keys/page.tsx index 27f7d30bb..a3b0b3dc4 100644 --- a/src/app/admin/api-keys/page.tsx +++ b/src/app/admin/api-keys/page.tsx @@ -2,7 +2,7 @@ import styles from './page.module.scss' import CreateApiKeyForm from './CreateApiKeyForm' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' -import { readApiKeysAction } from '@/actions/api-keys/read' +import { readApiKeysAction } from '@/services/api-keys/actions' import Date from '@/components/Date/Date' import { v4 as uuid } from 'uuid' import Link from 'next/link' diff --git a/src/app/admin/cabin-booking/[booking]/page.tsx b/src/app/admin/cabin-booking/[booking]/page.tsx index 3a8eef919..07107623e 100644 --- a/src/app/admin/cabin-booking/[booking]/page.tsx +++ b/src/app/admin/cabin-booking/[booking]/page.tsx @@ -1,4 +1,4 @@ -import { readCabinBookingAction } from '@/actions/cabin' +import { readCabinBookingAction } from '@/services/cabin/actions' import PageWrapper from '@/app/_components/PageWrapper/PageWrapper' import SimpleTable from '@/app/_components/Table/SimpleTable' import { unwrapActionReturn } from '@/app/redirectToErrorPage' diff --git a/src/app/admin/cabin-booking/page.tsx b/src/app/admin/cabin-booking/page.tsx index ccc991923..1001a8951 100644 --- a/src/app/admin/cabin-booking/page.tsx +++ b/src/app/admin/cabin-booking/page.tsx @@ -1,4 +1,4 @@ -import { readCabinBookingsAction } from '@/actions/cabin' +import { readCabinBookingsAction } from '@/services/cabin/actions' import PageWrapper from '@/app/_components/PageWrapper/PageWrapper' import SimpleTable from '@/app/_components/Table/SimpleTable' import { unwrapActionReturn } from '@/app/redirectToErrorPage' diff --git a/src/app/admin/cabin-periods/PageStateWrapper.tsx b/src/app/admin/cabin-periods/PageStateWrapper.tsx index b2f509eba..71c29945c 100644 --- a/src/app/admin/cabin-periods/PageStateWrapper.tsx +++ b/src/app/admin/cabin-periods/PageStateWrapper.tsx @@ -6,7 +6,7 @@ import PopUp from '@/app/_components/PopUp/PopUp' import { displayDate } from '@/lib/dates/displayDate' import SimpleTable from '@/app/_components/Table/SimpleTable' import Form from '@/app/_components/Form/Form' -import { destoryPricePeriodAction, destroyReleasePeriodAction } from '@/actions/cabin' +import { destoryPricePeriodAction, destroyReleasePeriodAction } from '@/services/cabin/actions' import { v4 as uuid } from 'uuid' import type { PricePeriod, ReleasePeriod } from '@prisma/client' diff --git a/src/app/admin/cabin-periods/PricePeriodForm.tsx b/src/app/admin/cabin-periods/PricePeriodForm.tsx index 0979f39c9..7b2fc1b3d 100644 --- a/src/app/admin/cabin-periods/PricePeriodForm.tsx +++ b/src/app/admin/cabin-periods/PricePeriodForm.tsx @@ -1,6 +1,6 @@ 'use client' -import { createPricePeriodAction } from '@/actions/cabin' +import { createPricePeriodAction } from '@/services/cabin/actions' import Form from '@/app/_components/Form/Form' import Checkbox from '@/app/_components/UI/Checkbox' import DateInput from '@/app/_components/UI/DateInput' diff --git a/src/app/admin/cabin-periods/ReleasePeriodForm.tsx b/src/app/admin/cabin-periods/ReleasePeriodForm.tsx index 2f1dc29dc..76ed1f232 100644 --- a/src/app/admin/cabin-periods/ReleasePeriodForm.tsx +++ b/src/app/admin/cabin-periods/ReleasePeriodForm.tsx @@ -1,6 +1,6 @@ 'use client' -import { createReleasePeriodAction } from '@/actions/cabin' +import { createReleasePeriodAction } from '@/services/cabin/actions' import Form from '@/app/_components/Form/Form' import DateInput from '@/app/_components/UI/DateInput' diff --git a/src/app/admin/cabin-periods/page.tsx b/src/app/admin/cabin-periods/page.tsx index 0c3f1937d..ff7ed5d89 100644 --- a/src/app/admin/cabin-periods/page.tsx +++ b/src/app/admin/cabin-periods/page.tsx @@ -1,7 +1,7 @@ 'use server' import PageStateWrapper from './PageStateWrapper' import PageWrapper from '@/app/_components/PageWrapper/PageWrapper' -import { readPricePeriodsAction, readReleasePeriodsAction } from '@/actions/cabin' +import { readPricePeriodsAction, readReleasePeriodsAction } from '@/services/cabin/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' diff --git a/src/app/admin/cabin-product/UpdateCabinProductForm.tsx b/src/app/admin/cabin-product/UpdateCabinProductForm.tsx index 9bc1a0577..303945cd1 100644 --- a/src/app/admin/cabin-product/UpdateCabinProductForm.tsx +++ b/src/app/admin/cabin-product/UpdateCabinProductForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { createCabinProductAction } from '@/actions/cabin' +import { createCabinProductAction } from '@/services/cabin/actions' import Form from '@/app/_components/Form/Form' import NumberInput from '@/app/_components/UI/NumberInput' import TextInput from '@/app/_components/UI/TextInput' diff --git a/src/app/admin/cabin-product/[product]/UpdateCabinProductPriceForm.tsx b/src/app/admin/cabin-product/[product]/UpdateCabinProductPriceForm.tsx index 3187b0d3c..675c58271 100644 --- a/src/app/admin/cabin-product/[product]/UpdateCabinProductPriceForm.tsx +++ b/src/app/admin/cabin-product/[product]/UpdateCabinProductPriceForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { createCabinProductPriceAction } from '@/actions/cabin' +import { createCabinProductPriceAction } from '@/services/cabin/actions' import Form from '@/app/_components/Form/Form' import NumberInput from '@/app/_components/UI/NumberInput' import { SelectNumber } from '@/app/_components/UI/Select' diff --git a/src/app/admin/cabin-product/[product]/page.tsx b/src/app/admin/cabin-product/[product]/page.tsx index e2cc02e2a..94c6fda2f 100644 --- a/src/app/admin/cabin-product/[product]/page.tsx +++ b/src/app/admin/cabin-product/[product]/page.tsx @@ -1,7 +1,7 @@ import styles from './page.module.scss' import { UpdateCabinProductPriceForm } from './UpdateCabinProductPriceForm' import { AddHeaderItemPopUp } from '@/app/_components/HeaderItems/HeaderItemPopUp' -import { readCabinProductAction, readUnreleasedPricePeriodsAction } from '@/actions/cabin' +import { readCabinProductAction, readUnreleasedPricePeriodsAction } from '@/services/cabin/actions' import PageWrapper from '@/app/_components/PageWrapper/PageWrapper' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { displayDate } from '@/lib/dates/displayDate' diff --git a/src/app/admin/cabin-product/page.tsx b/src/app/admin/cabin-product/page.tsx index 4141c8562..23b9d9aa2 100644 --- a/src/app/admin/cabin-product/page.tsx +++ b/src/app/admin/cabin-product/page.tsx @@ -1,6 +1,6 @@ import { UpdateCabinProductForm } from './UpdateCabinProductForm' import { AddHeaderItemPopUp } from '@/app/_components/HeaderItems/HeaderItemPopUp' -import { readCabinProductsAction } from '@/actions/cabin' +import { readCabinProductsAction } from '@/services/cabin/actions' import PageWrapper from '@/app/_components/PageWrapper/PageWrapper' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import SimpleTable from '@/app/_components/Table/SimpleTable' diff --git a/src/app/admin/committees/CreateCommitteeForm.tsx b/src/app/admin/committees/CreateCommitteeForm.tsx index 1163433ea..339653ecc 100644 --- a/src/app/admin/committees/CreateCommitteeForm.tsx +++ b/src/app/admin/committees/CreateCommitteeForm.tsx @@ -2,7 +2,7 @@ import styles from './CreateCommitteeForm.module.scss' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' -import { createCommitteeAction } from '@/actions/groups/committees/create' +import { createCommitteeAction } from '@/services/groups/committees/actions' import { ImageSelectionContext } from '@/contexts/ImageSelection' import { useContext } from 'react' diff --git a/src/app/admin/committees/page.tsx b/src/app/admin/committees/page.tsx index 761980ad5..6b01e91d0 100644 --- a/src/app/admin/committees/page.tsx +++ b/src/app/admin/committees/page.tsx @@ -3,9 +3,9 @@ import CreateCommitteeForm from './CreateCommitteeForm' import ImageSelectionProvider from '@/contexts/ImageSelection' import ImageList from '@/components/Image/ImageList/ImageList' import ImagePagingProvider from '@/contexts/paging/ImagePaging' -import { readSpecialImageCollectionAction } from '@/actions/images/collections/read' +import { readSpecialImageCollectionAction } from '@/services/images/collections/actions' import PopUpProvider from '@/contexts/PopUp' -import { readSpecialImageAction } from '@/actions/images/read' +import { readSpecialImageAction } from '@/services/images/actions' import type { PageSizeImage } from '@/contexts/paging/ImagePaging' export default async function adminCommittee() { diff --git a/src/app/admin/dots/CreateDotForm.tsx b/src/app/admin/dots/CreateDotForm.tsx index 759241bcb..086b3ef9b 100644 --- a/src/app/admin/dots/CreateDotForm.tsx +++ b/src/app/admin/dots/CreateDotForm.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './CreateDotForm.module.scss' -import { createDotAction } from '@/actions/dots/create' +import { createDotAction } from '@/services/dots/actions' import Form from '@/components/Form/Form' import PopUp from '@/components/PopUp/PopUp' import NumberInput from '@/components/UI/NumberInput' diff --git a/src/app/admin/groups/[id]/AddUsersToGroup.tsx b/src/app/admin/groups/[id]/AddUsersToGroup.tsx index 2a42e6ace..3743275db 100644 --- a/src/app/admin/groups/[id]/AddUsersToGroup.tsx +++ b/src/app/admin/groups/[id]/AddUsersToGroup.tsx @@ -2,7 +2,7 @@ import styles from './AddUsersToGroup.module.scss' import UserList from '@/components/User/UserList/UserList' import Form from '@/components/Form/Form' -import { createMembershipsForGroupAction } from '@/actions/groups/memberships/create' +import { createMembershipsForGroupAction } from '@/services/groups/memberships/actions' import { UsersSelectionContext } from '@/contexts/UsersSelection' import { useContext } from 'react' import { useRouter } from 'next/navigation' diff --git a/src/app/admin/groups/[id]/MembershipAdminForUser.tsx b/src/app/admin/groups/[id]/MembershipAdminForUser.tsx index f74165084..fe9848821 100644 --- a/src/app/admin/groups/[id]/MembershipAdminForUser.tsx +++ b/src/app/admin/groups/[id]/MembershipAdminForUser.tsx @@ -1,7 +1,7 @@ 'use client' import styles from './MembershipAdminForUser.module.scss' import Form from '@/components/Form/Form' -import { updateMembershipActiveAction, updateMembershipAdminAcion } from '@/actions/groups/memberships/update' +import { updateMembershipActiveAction, updateMembershipAdminAcion } from '@/services/groups/memberships/actions' import { useRouter } from 'next/navigation' import type { UserPagingReturn } from '@/services/users/Types' import type { ExpandedGroup } from '@/services/groups/Types' diff --git a/src/app/admin/groups/[id]/page.tsx b/src/app/admin/groups/[id]/page.tsx index 0d3bb76e9..26bbb5ada 100644 --- a/src/app/admin/groups/[id]/page.tsx +++ b/src/app/admin/groups/[id]/page.tsx @@ -5,7 +5,7 @@ import UserPagingProvider from '@/contexts/paging/UserPaging' import { CanEasilyManageMembership } from '@/services/groups/memberships/ConfigVars' import PopUp from '@/components/PopUp/PopUp' import UsersSelectionProvider from '@/contexts/UsersSelection' -import { readGroupExpandedAction } from '@/actions/groups/read' +import { readGroupExpandedAction } from '@/services/groups/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import Link from 'next/link' diff --git a/src/app/admin/groups/page.tsx b/src/app/admin/groups/page.tsx index 36b534b7d..08817a796 100644 --- a/src/app/admin/groups/page.tsx +++ b/src/app/admin/groups/page.tsx @@ -1,8 +1,8 @@ import styles from './page.module.scss' import GroupSelector from './GroupSelector' import { GroupTypeOrdering } from '@/services/groups/config' +import { readGroupsStructuredAction } from '@/services/groups/actions' import { notFound } from 'next/navigation' -import { readGroupsStructuredAction } from '@/actions/groups/read' /** * A page that displays memberships in all groups for admins diff --git a/src/app/admin/licenses/page.tsx b/src/app/admin/licenses/page.tsx index 123e7bb15..128ea9102 100644 --- a/src/app/admin/licenses/page.tsx +++ b/src/app/admin/licenses/page.tsx @@ -2,11 +2,13 @@ import styles from './page.module.scss' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { SettingsHeaderItemPopUp } from '@/app/_components/HeaderItems/HeaderItemPopUp' import Form from '@/app/_components/Form/Form' -import { destroyLicenseAction } from '@/actions/licenses/destroy' -import { createLicenseAction } from '@/actions/licenses/create' +import { + destroyLicenseAction, + createLicenseAction, + updateLicenseAction, + readAllLicensesAction +} from '@/services/licenses/actions' import TextInput from '@/UI/TextInput' -import { updateLicenseAction } from '@/actions/licenses/update' -import { readAllLicensesAction } from '@/actions/licenses/read' import Link from 'next/link' export default async function Licenses() { diff --git a/src/app/admin/lockers/location/CreateLockerLocationForm.tsx b/src/app/admin/lockers/location/CreateLockerLocationForm.tsx index 7b0897f07..7a15626a9 100644 --- a/src/app/admin/lockers/location/CreateLockerLocationForm.tsx +++ b/src/app/admin/lockers/location/CreateLockerLocationForm.tsx @@ -1,6 +1,6 @@ 'use client' import Form from '@/components/Form/Form' -import { createLockerLocationAction } from '@/actions/lockers/locations' +import { createLockerLocationAction } from '@/services/lockers/actions' import TextInput from '@/components/UI/TextInput' import NumberInput from '@/components/UI/NumberInput' diff --git a/src/app/admin/lockers/locker/CreateLockerForm.tsx b/src/app/admin/lockers/locker/CreateLockerForm.tsx index 91538d1ea..708766e57 100644 --- a/src/app/admin/lockers/locker/CreateLockerForm.tsx +++ b/src/app/admin/lockers/locker/CreateLockerForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { createLockerAction } from '@/actions/lockers/lockers' +import { createLockerAction } from '@/services/lockers/actions' import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' import NumberInput from '@/components/UI/NumberInput' diff --git a/src/app/admin/lockers/locker/page.tsx b/src/app/admin/lockers/locker/page.tsx index 70b725fb4..b9b5094a6 100644 --- a/src/app/admin/lockers/locker/page.tsx +++ b/src/app/admin/lockers/locker/page.tsx @@ -1,6 +1,6 @@ import styles from './page.module.scss' import CreateLockerForm from './CreateLockerForm' -import { readAllLockerLocationsAction as readAllLockerLocationsAction } from '@/actions/lockers/locations' +import { readAllLockerLocationsAction as readAllLockerLocationsAction } from '@/services/lockers/actions' export default async function Locker() { diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/group.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/group.tsx index ae0e84bd9..e660e6b82 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/group.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/group.tsx @@ -1,7 +1,7 @@ 'use client' import Form from '@/components/Form/Form' import { SelectNumber } from '@/components/UI/Select' -import { createMailingListGroupRelationAction } from '@/actions/mail/create' +import { createMailingListGroupRelationAction } from '@/services/mail/actions' import { useUser } from '@/auth/useUser' import type { MailFlowObject } from '@/services/mail/Types' import type { MailingList } from '@prisma/client' diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAddressExternal.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAddressExternal.tsx index 3000347dc..ced0f30af 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAddressExternal.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAddressExternal.tsx @@ -3,10 +3,12 @@ import TextInput from '@/components/UI/TextInput' import Form from '@/components/Form/Form' import { SelectNumber } from '@/components/UI/Select' -import { createMailingListExternalRelationAction } from '@/actions/mail/create' +import { createMailingListExternalRelationAction } from '@/services/mail/actions' import { useUser } from '@/auth/useUser' -import { updateMailAddressExternalAction } from '@/actions/mail/mailAddressExternal/update' -import { destroyMailAddressExternalAction } from '@/actions/mail/mailAddressExternal/destroy' +import { + updateMailAddressExternalAction, + destroyMailAddressExternalAction +} from '@/services/mail/mailAddressExternal/actions' import { useRouter } from 'next/navigation' import type { MailingList } from '@prisma/client' import type { MailFlowObject } from '@/services/mail/Types' diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAlias.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAlias.tsx index 531ccd171..b347b1d32 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAlias.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAlias.tsx @@ -3,10 +3,9 @@ import TextInput from '@/components/UI/TextInput' import Form from '@/components/Form/Form' import { SelectNumber } from '@/components/UI/Select' -import { createAliasMailingListRelationAction } from '@/actions/mail/create' +import { createAliasMailingListRelationAction } from '@/services/mail/actions' import { useUser } from '@/auth/useUser' -import { updateMailAliasAction } from '@/actions/mail/alias/update' -import { destroyMailAliasAction } from '@/actions/mail/alias/destory' +import { updateMailAliasAction, destroyMailAliasAction } from '@/services/mail/alias/actions' import { useRouter } from 'next/navigation' import type { MailFlowObject } from '@/services/mail/Types' import type { MailingList } from '@prisma/client' diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailingList.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailingList.tsx index 6dcffb325..f04ceebfa 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailingList.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailingList.tsx @@ -8,10 +8,9 @@ import { createMailingListExternalRelationAction, createMailingListGroupRelationAction, createMailingListUserRelationAction -} from '@/actions/mail/create' +} from '@/services/mail/actions' import { useUser } from '@/auth/useUser' -import { updateMailingListAction } from '@/actions/mail/list/update' -import { destroyMailingListAction } from '@/actions/mail/list/destory' +import { updateMailingListAction, destroyMailingListAction } from '@/services/mail/list/actions' import { useRouter } from 'next/navigation' import type { MailAddressExternal, MailAlias } from '@prisma/client' import type { MailFlowObject } from '@/services/mail/Types' diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/user.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/user.tsx index a1e6c8d4a..f2458a9c5 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/user.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/user.tsx @@ -2,7 +2,7 @@ import Form from '@/components/Form/Form' import { SelectNumber } from '@/components/UI/Select' -import { createMailingListUserRelationAction } from '@/actions/mail/create' +import { createMailingListUserRelationAction } from '@/services/mail/actions' import { useUser } from '@/auth/useUser' import type { MailFlowObject } from '@/services/mail/Types' import type { MailingList } from '@prisma/client' diff --git a/src/app/admin/mail/[filter]/[id]/MailFlow.tsx b/src/app/admin/mail/[filter]/[id]/MailFlow.tsx index c6d59f1a4..f79b680c1 100644 --- a/src/app/admin/mail/[filter]/[id]/MailFlow.tsx +++ b/src/app/admin/mail/[filter]/[id]/MailFlow.tsx @@ -3,14 +3,14 @@ import MailList from './mailList' import styles from './MailFlow.module.scss' import { useUser } from '@/auth/useUser' -import type { ActionReturn } from '@/services/actionTypes' -import type { MailFlowObject, MailListTypes } from '@/services/mail/Types' import { destroyAliasMailingListRelationAction, destroyMailingListExternalRelationAction, destroyMailingListGroupRelationAction, destroyMailingListUserRelationAction -} from '@/actions/mail/destroy' +} from '@/services/mail/actions' +import type { ActionReturn } from '@/services/actionTypes' +import type { MailFlowObject, MailListTypes } from '@/services/mail/Types' type DestroyFunction = null | ((id: number) => Promise>) diff --git a/src/app/admin/mail/[filter]/[id]/page.tsx b/src/app/admin/mail/[filter]/[id]/page.tsx index a71472b85..9593348f4 100644 --- a/src/app/admin/mail/[filter]/[id]/page.tsx +++ b/src/app/admin/mail/[filter]/[id]/page.tsx @@ -7,7 +7,7 @@ import EditMailingList from './(editComponents)/mailingList' import EditMailAddressExternal from './(editComponents)/mailAddressExternal' import EditUser from './(editComponents)/user' import EditGroup from './(editComponents)/group' -import { readMailOptions, readMailFlowAction } from '@/actions/mail/read' +import { readMailOptions, readMailFlowAction } from '@/services/mail/actions' import { MailListTypeArray } from '@/services/mail/Types' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { notFound } from 'next/navigation' diff --git a/src/app/admin/mail/createMailAliasForm.tsx b/src/app/admin/mail/createMailAliasForm.tsx index e948435c7..48b16efa9 100644 --- a/src/app/admin/mail/createMailAliasForm.tsx +++ b/src/app/admin/mail/createMailAliasForm.tsx @@ -1,6 +1,6 @@ 'use client' -import { createMailAliasAction } from '@/actions/mail/alias/create' +import { createMailAliasAction } from '@/services/mail/alias/actions' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import { useRouter } from 'next/navigation' diff --git a/src/app/admin/mail/createMailaddressExternalForm.tsx b/src/app/admin/mail/createMailaddressExternalForm.tsx index 4cfd67d70..d4daebcdb 100644 --- a/src/app/admin/mail/createMailaddressExternalForm.tsx +++ b/src/app/admin/mail/createMailaddressExternalForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { createMailAddressExternalAction } from '@/actions/mail/mailAddressExternal/create' +import { createMailAddressExternalAction } from '@/services/mail/mailAddressExternal/actions' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import { useRouter } from 'next/navigation' diff --git a/src/app/admin/mail/createMailingListForm.tsx b/src/app/admin/mail/createMailingListForm.tsx index 9f6ddb543..bce0b7d6f 100644 --- a/src/app/admin/mail/createMailingListForm.tsx +++ b/src/app/admin/mail/createMailingListForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { createMailingListAction } from '@/actions/mail/list/create' +import { createMailingListAction } from '@/services/mail/list/actions' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import { useRouter } from 'next/navigation' diff --git a/src/app/admin/notification-channels/[currentId]/channelSettings.tsx b/src/app/admin/notification-channels/[currentId]/channelSettings.tsx index 7ce665a11..ea42a3b77 100644 --- a/src/app/admin/notification-channels/[currentId]/channelSettings.tsx +++ b/src/app/admin/notification-channels/[currentId]/channelSettings.tsx @@ -9,10 +9,10 @@ import PageWrapper from '@/components/PageWrapper/PageWrapper' import { bindParams } from '@/services/actionBind' import { NotificationChannelSchemas } from '@/services/notifications/channel/schemas' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' +import { updateNotificationChannelAction } from '@/services/notifications/actions' import { useState } from 'react' import type { ExpandedNotificationChannel } from '@/services/notifications/Types' import type { MailAlias } from '@prisma/client' -import { updateNotificationChannelAction } from '@/actions/notifications' export default function ChannelSettings({ currentChannel, diff --git a/src/app/admin/notification-channels/[currentId]/page.tsx b/src/app/admin/notification-channels/[currentId]/page.tsx index c81c07d0a..8bc61dc57 100644 --- a/src/app/admin/notification-channels/[currentId]/page.tsx +++ b/src/app/admin/notification-channels/[currentId]/page.tsx @@ -1,8 +1,8 @@ import ChannelSettings from './channelSettings' +import { readNotificationChannelsAction } from '@/services/notifications/actions' +import { readMailAliasesAction } from '@/services/mail/alias/actions' import { notFound } from 'next/navigation' -import { readNotificationChannelsAction } from '@/actions/notifications' -import { readMailAliasesAction } from '@/actions/mail/alias/read' type PropTypes = { params: Promise<{ diff --git a/src/app/admin/notification-channels/addNotificationChannel.tsx b/src/app/admin/notification-channels/addNotificationChannel.tsx index 416d46dfe..3ac74a792 100644 --- a/src/app/admin/notification-channels/addNotificationChannel.tsx +++ b/src/app/admin/notification-channels/addNotificationChannel.tsx @@ -6,10 +6,10 @@ import NotificationMethodSelector from '@/components/NotificaionMethodSelector/N import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' import { bindParams } from '@/services/actionBind' import { NotificationConfig } from '@/services/notifications/config' +import { createNotificationChannelAction } from '@/services/notifications/actions' import { useState } from 'react' import { useRouter } from 'next/navigation' import type { ExpandedNotificationChannel, NotificationMethodGeneral } from '@/services/notifications/Types' -import { createNotificationChannelAction } from '@/actions/notifications' export default function AddNotificationChannel({ diff --git a/src/app/admin/notification-channels/page.tsx b/src/app/admin/notification-channels/page.tsx index 19d9ac8b0..80f745502 100644 --- a/src/app/admin/notification-channels/page.tsx +++ b/src/app/admin/notification-channels/page.tsx @@ -3,7 +3,7 @@ import AddNotificationChannel from './addNotificationChannel' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { readNotificationChannelsAction } from '@/actions/notifications' +import { readNotificationChannelsAction } from '@/services/notifications/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import Link from 'next/link' import { v4 as uuid } from 'uuid' diff --git a/src/app/admin/omegaid/page.tsx b/src/app/admin/omegaid/page.tsx index d59d78362..12cd84676 100644 --- a/src/app/admin/omegaid/page.tsx +++ b/src/app/admin/omegaid/page.tsx @@ -1,7 +1,7 @@ 'use server' import OmegaIdContainer from './container' -import { readOmegaJWTPublicKey } from '@/actions/omegaid/read' +import { readOmegaJWTPublicKey } from '@/services/omegaid/actions' export default async function OmegaId() { diff --git a/src/app/admin/product/[productId]/page.tsx b/src/app/admin/product/[productId]/page.tsx index 451e5b02e..8b9bdbafc 100644 --- a/src/app/admin/product/[productId]/page.tsx +++ b/src/app/admin/product/[productId]/page.tsx @@ -3,7 +3,7 @@ import ProductForm from '@/app/admin/product/productForm' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import PageWrapper from '@/app/_components/PageWrapper/PageWrapper' import { displayPrice } from '@/lib/money/convert' -import { readProductAction } from '@/actions/shop/product' +import { readProductAction } from '@/services/shop/actions' import { v4 as uuid } from 'uuid' import Link from 'next/link' diff --git a/src/app/admin/product/page.tsx b/src/app/admin/product/page.tsx index fdb0cf345..9b76fef30 100644 --- a/src/app/admin/product/page.tsx +++ b/src/app/admin/product/page.tsx @@ -6,7 +6,7 @@ import { AddHeaderItemPopUp } from '@/app/_components/HeaderItems/HeaderItemPopU import PageWrapper from '@/app/_components/PageWrapper/PageWrapper' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { sortObjectsByName } from '@/lib/sortObjects' -import { readProductsAction } from '@/actions/shop/product' +import { readProductsAction } from '@/services/shop/actions' import { v4 as uuid } from 'uuid' import Link from 'next/link' diff --git a/src/app/admin/product/productForm.tsx b/src/app/admin/product/productForm.tsx index ea235542d..d50c457bf 100644 --- a/src/app/admin/product/productForm.tsx +++ b/src/app/admin/product/productForm.tsx @@ -1,4 +1,4 @@ -import { createProductAction, updateProductAction } from '@/actions/shop/product' +import { createProductAction, updateProductAction } from '@/services/shop/actions' import Form from '@/app/_components/Form/Form' import TextInput from '@/app/_components/UI/TextInput' import type { Product } from '@prisma/client' diff --git a/src/app/admin/schools/[shortname]/UpdateSchool.tsx b/src/app/admin/schools/[shortname]/UpdateSchool.tsx index 01a91e55d..40d7ff0d7 100644 --- a/src/app/admin/schools/[shortname]/UpdateSchool.tsx +++ b/src/app/admin/schools/[shortname]/UpdateSchool.tsx @@ -1,6 +1,6 @@ 'use client' import Form from '@/components/Form/Form' -import { updateSchoolAction } from '@/education/schools/update' +import { updateSchoolAction } from '@/education/schools/actions' import TextInput from '@/components/UI/TextInput' import type { SchoolFiltered } from '@/education/schools/Types' diff --git a/src/app/admin/schools/[shortname]/page.tsx b/src/app/admin/schools/[shortname]/page.tsx index ee58be7b8..411e11e33 100644 --- a/src/app/admin/schools/[shortname]/page.tsx +++ b/src/app/admin/schools/[shortname]/page.tsx @@ -1,7 +1,6 @@ import styles from './page.module.scss' import UpdateSchool from './UpdateSchool' -import { destroySchoolAction } from '@/education/schools/destroy' -import { readSchoolAction } from '@/education/schools/read' +import { destroySchoolAction, readSchoolAction } from '@/education/schools/actions' import Form from '@/components/Form/Form' import PageWrapper from '@/components/PageWrapper/PageWrapper' import School from '@/components/School/School' diff --git a/src/app/admin/schools/page.tsx b/src/app/admin/schools/page.tsx index 7a0fef341..e57c16746 100644 --- a/src/app/admin/schools/page.tsx +++ b/src/app/admin/schools/page.tsx @@ -3,9 +3,8 @@ import { SchoolAdminList } from './SchoolAdminList' import Form from '@/components/Form/Form' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { createSchoolAction } from '@/education/schools/create' +import { createSchoolAction, readSchoolsAction, readStandardSchoolsAction } from '@/education/schools/actions' import TextInput from '@/components/UI/TextInput' -import { readSchoolsAction, readStandardSchoolsAction } from '@/education/schools/read' export default async function SchoolsAdmin() { const standardSchoolsRes = await readStandardSchoolsAction() diff --git a/src/app/admin/send-mail/mailForm.tsx b/src/app/admin/send-mail/mailForm.tsx index 21b90b41a..39fb94e99 100644 --- a/src/app/admin/send-mail/mailForm.tsx +++ b/src/app/admin/send-mail/mailForm.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './mailForm.module.scss' -import sendMail from '@/actions/sendmail/send' +import sendMail from '@/services/sendmail/actions' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import Textarea from '@/components/UI/Textarea' diff --git a/src/app/admin/send-notification/notificationForm.tsx b/src/app/admin/send-notification/notificationForm.tsx index 6a646ac53..56a117280 100644 --- a/src/app/admin/send-notification/notificationForm.tsx +++ b/src/app/admin/send-notification/notificationForm.tsx @@ -4,7 +4,7 @@ import { SelectNumber } from '@/components/UI/Select' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import Textarea from '@/components/UI/Textarea' -import { createNotificationAction } from '@/actions/notifications' +import { createNotificationAction } from '@/services/notifications/actions' import { useState } from 'react' import type { ExpandedNotificationChannel } from '@/services/notifications/Types' diff --git a/src/app/admin/send-notification/page.tsx b/src/app/admin/send-notification/page.tsx index 0d0e32295..f7b8821b7 100644 --- a/src/app/admin/send-notification/page.tsx +++ b/src/app/admin/send-notification/page.tsx @@ -1,7 +1,7 @@ 'use server' import NotificaionForm from './notificationForm' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { readNotificationChannelsAction } from '@/actions/notifications' +import { readNotificationChannelsAction } from '@/services/notifications/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' diff --git a/src/app/admin/shop/[shop]/EditProductForShopForm.tsx b/src/app/admin/shop/[shop]/EditProductForShopForm.tsx index 39c10af23..1726da9bf 100644 --- a/src/app/admin/shop/[shop]/EditProductForShopForm.tsx +++ b/src/app/admin/shop/[shop]/EditProductForShopForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { createProductForShopAction, updateProductForShopAction } from '@/actions/shop/product' +import { createProductForShopAction, updateProductForShopAction } from '@/services/shop/actions' import Form from '@/app/_components/Form/Form' import Checkbox from '@/app/_components/UI/Checkbox' import NumberInput from '@/app/_components/UI/NumberInput' diff --git a/src/app/admin/shop/[shop]/FindProductForm.tsx b/src/app/admin/shop/[shop]/FindProductForm.tsx index afb785c84..3957adc51 100644 --- a/src/app/admin/shop/[shop]/FindProductForm.tsx +++ b/src/app/admin/shop/[shop]/FindProductForm.tsx @@ -1,5 +1,5 @@ 'use client' -import { createShopProductConnectionAction } from '@/actions/shop/product' +import { createShopProductConnectionAction } from '@/services/shop/actions' import Form from '@/app/_components/Form/Form' import NumberInput from '@/app/_components/UI/NumberInput' import { SelectNumber } from '@/app/_components/UI/Select' diff --git a/src/app/admin/shop/[shop]/page.tsx b/src/app/admin/shop/[shop]/page.tsx index 8be8a690a..e835e0d2a 100644 --- a/src/app/admin/shop/[shop]/page.tsx +++ b/src/app/admin/shop/[shop]/page.tsx @@ -6,8 +6,7 @@ import PopUp from '@/app/_components/PopUp/PopUp' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { displayPrice } from '@/lib/money/convert' import { sortObjectsByName } from '@/lib/sortObjects' -import { readShopAction } from '@/actions/shop/shop' -import { readProductsAction } from '@/actions/shop/product' +import { readShopAction, readProductsAction } from '@/services/shop/actions' import { faPencil } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { notFound } from 'next/navigation' diff --git a/src/app/admin/shop/page.tsx b/src/app/admin/shop/page.tsx index 08ce27283..f1cfa0e40 100644 --- a/src/app/admin/shop/page.tsx +++ b/src/app/admin/shop/page.tsx @@ -5,7 +5,7 @@ import { AddHeaderItemPopUp } from '@/app/_components/HeaderItems/HeaderItemPopU import PageWrapper from '@/app/_components/PageWrapper/PageWrapper' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { sortObjectsByName } from '@/lib/sortObjects' -import { readShopsAction } from '@/actions/shop/shop' +import { readShopsAction } from '@/services/shop/actions' import Link from 'next/link' import { v4 as uuid } from 'uuid' diff --git a/src/app/admin/shop/shopForm.tsx b/src/app/admin/shop/shopForm.tsx index dcb6488e6..752532cd5 100644 --- a/src/app/admin/shop/shopForm.tsx +++ b/src/app/admin/shop/shopForm.tsx @@ -1,4 +1,4 @@ -import { createShopAction } from '@/actions/shop/shop' +import { createShopAction } from '@/services/shop/actions' import Form from '@/app/_components/Form/Form' import TextInput from '@/app/_components/UI/TextInput' diff --git a/src/app/admin/stateOfOmega/CreateOrder.tsx b/src/app/admin/stateOfOmega/CreateOrder.tsx index 63236ef10..a97a3e41a 100644 --- a/src/app/admin/stateOfOmega/CreateOrder.tsx +++ b/src/app/admin/stateOfOmega/CreateOrder.tsx @@ -1,5 +1,5 @@ 'use client' -import { createOmegaOrderAction } from '@/actions/omegaOrder/create' +import { createOmegaOrderAction } from '@/services/omegaOrder/actions' import Form from '@/components/Form/Form' import { useRouter } from 'next/navigation' import React from 'react' diff --git a/src/app/admin/stateOfOmega/page.tsx b/src/app/admin/stateOfOmega/page.tsx index 16cc497ea..9076b7e4f 100644 --- a/src/app/admin/stateOfOmega/page.tsx +++ b/src/app/admin/stateOfOmega/page.tsx @@ -1,8 +1,8 @@ import styles from './page.module.scss' import CreateOrder from './CreateOrder' import { getUser } from '@/auth/getUser' +import { readCurrentOmegaOrderAction } from '@/services/omegaOrder/actions' import { notFound } from 'next/navigation' -import { readCurrentOmegaOrderAction } from '@/actions/omegaOrder/read' export default async function stateOfOmega() { const { authorized } = await getUser({ diff --git a/src/app/admin/study-programmes/page.tsx b/src/app/admin/study-programmes/page.tsx index 2ff77a5b3..9f8aa416b 100644 --- a/src/app/admin/study-programmes/page.tsx +++ b/src/app/admin/study-programmes/page.tsx @@ -3,7 +3,7 @@ import UpdateStudyProgrammeForm from './updateStudyProgrammeForm' import StudyProgrammeTableBody from './studyProgrammeTable' import styles from './page.module.scss' -import { readStudyProgrammesAction } from '@/actions/groups/studyProgrammes/read' +import { readStudyProgrammesAction } from '@/services/groups/studyProgrammes/actions' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { getUser } from '@/auth/getUser' diff --git a/src/app/admin/study-programmes/updateStudyProgrammeForm.tsx b/src/app/admin/study-programmes/updateStudyProgrammeForm.tsx index 6b7c7d94a..1b8d0d6be 100644 --- a/src/app/admin/study-programmes/updateStudyProgrammeForm.tsx +++ b/src/app/admin/study-programmes/updateStudyProgrammeForm.tsx @@ -3,10 +3,9 @@ import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' import TextInput from '@/components/UI/TextInput' +import { updateStudyProgrammeAction, createStudyProgrammeAction } from '@/services/groups/studyProgrammes/actions' import { useRouter } from 'next/navigation' import type { StudyProgramme } from '@prisma/client' -import { updateStudyProgrammeAction } from '@/actions/groups/studyProgrammes/update' -import { createStudyProgrammeAction } from '@/actions/groups/studyProgrammes/create' export default function UpdateStudyProgrammeForm({ diff --git a/src/app/applications/CreateUpdateApplicationPeriodForm.tsx b/src/app/applications/CreateUpdateApplicationPeriodForm.tsx index c655e351c..5779d350e 100644 --- a/src/app/applications/CreateUpdateApplicationPeriodForm.tsx +++ b/src/app/applications/CreateUpdateApplicationPeriodForm.tsx @@ -1,7 +1,6 @@ 'use client' import styles from './CreateUpdateApplicationPeriodForm.module.scss' -import { createApplicationPeriodAction } from '@/actions/applications/periods/create' -import { updateApplicationPeriodAction } from '@/actions/applications/periods/update' +import { createApplicationPeriodAction, updateApplicationPeriodAction } from '@/services/applications/periods/actions' import Form from '@/components/Form/Form' import Checkbox from '@/components/UI/Checkbox' import DateInput from '@/components/UI/DateInput' diff --git a/src/app/applications/[periodName]/Reprioritize.tsx b/src/app/applications/[periodName]/Reprioritize.tsx index b8279defe..d29bda9e5 100644 --- a/src/app/applications/[periodName]/Reprioritize.tsx +++ b/src/app/applications/[periodName]/Reprioritize.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './Reprioritize.module.scss' -import { updateApplicationAction } from '@/actions/applications/update' +import { updateApplicationAction } from '@/services/applications/actions' import { faArrowDown, faArrowUp } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { useCallback, useState } from 'react' diff --git a/src/app/applications/[periodName]/countdown/CommitteeLogoRoll.tsx b/src/app/applications/[periodName]/countdown/CommitteeLogoRoll.tsx index 10c40d6d6..36ec0523d 100644 --- a/src/app/applications/[periodName]/countdown/CommitteeLogoRoll.tsx +++ b/src/app/applications/[periodName]/countdown/CommitteeLogoRoll.tsx @@ -2,9 +2,9 @@ import styles from './CommitteeLogoRoll.module.scss' import Image from '@/app/_components/Image/Image' import useInterval from '@/hooks/useInterval' +import { readNumberOfApplicationsAction } from '@/services/applications/periods/actions' import { useRef, useState } from 'react' import type { Image as ImageT } from '@prisma/client' -import { readNumberOfApplicationsAction } from '@/actions/applications/periods/read' type PropTypes = { committees: { diff --git a/src/app/applications/[periodName]/countdown/FinalCountdown.tsx b/src/app/applications/[periodName]/countdown/FinalCountdown.tsx index f69bb1982..d356fee8a 100644 --- a/src/app/applications/[periodName]/countdown/FinalCountdown.tsx +++ b/src/app/applications/[periodName]/countdown/FinalCountdown.tsx @@ -1,7 +1,7 @@ import styles from './FinalCountdown.module.scss' import useInterval from '@/hooks/useInterval' +import { readNumberOfApplicationsAction } from '@/services/applications/periods/actions' import { useEffect, useRef, useState } from 'react' -import { readNumberOfApplicationsAction } from '@/actions/applications/periods/read' type PropTypes = { periodName: string diff --git a/src/app/applications/[periodName]/countdown/page.tsx b/src/app/applications/[periodName]/countdown/page.tsx index 84e1ae657..da6fe20d7 100644 --- a/src/app/applications/[periodName]/countdown/page.tsx +++ b/src/app/applications/[periodName]/countdown/page.tsx @@ -1,8 +1,8 @@ import styles from './page.module.scss' import Countdown from './Countdown' -import { readApplicationPeriodAction } from '@/actions/applications/periods/read' +import { readApplicationPeriodAction } from '@/services/applications/periods/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' -import { readSpecialImageAction } from '@/images/read' +import { readSpecialImageAction } from '@/services/images/actions' import type { PropTypes } from '@/app/applications/[periodName]/page' export default async function ApplicationPeriodCountdown({ params }: PropTypes) { diff --git a/src/app/applications/[periodName]/page.tsx b/src/app/applications/[periodName]/page.tsx index 819c3976d..7385de545 100644 --- a/src/app/applications/[periodName]/page.tsx +++ b/src/app/applications/[periodName]/page.tsx @@ -12,17 +12,22 @@ import Textarea from '@/components/UI/Textarea' import Form from '@/components/Form/Form' import { SettingsHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import CreateUpdateApplicationPeriodForm from '@/app/applications/CreateUpdateApplicationPeriodForm' -import Link from 'next/link' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { + createApplicationAction, + updateApplicationAction, + destroyApplicationAction, + readApplicationsForUserAction +} from '@/services/applications/actions' +import { readCommitteesAction } from '@/services/groups/committees/actions' +import { + destroyApplicationPeriodAction, + removeAllApplicationTextsAction, + readApplicationPeriodAction +} from '@/services/applications/periods/actions' +import { readSpecialImageAction } from '@/services/images/actions' import { faVideo } from '@fortawesome/free-solid-svg-icons' -import { createApplicationAction } from '@/actions/applications/create' -import { updateApplicationAction } from '@/actions/applications/update' -import { readCommitteesAction } from '@/actions/groups/committees/read' -import { destroyApplicationAction } from '@/actions/applications/destroy' -import { destroyApplicationPeriodAction, removeAllApplicationTextsAction } from '@/actions/applications/periods/destroy' -import { readApplicationsForUserAction } from '@/actions/applications/read' -import { readSpecialImageAction } from '@/images/read' -import { readApplicationPeriodAction } from '@/actions/applications/periods/read' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import Link from 'next/link' export type PropTypes = { params: Promise<{ diff --git a/src/app/applications/page.tsx b/src/app/applications/page.tsx index 277b00c95..03080cc82 100644 --- a/src/app/applications/page.tsx +++ b/src/app/applications/page.tsx @@ -1,11 +1,11 @@ import styles from './page.module.scss' import CreateUpdateApplicationPeriodForm from './CreateUpdateApplicationPeriodForm' import { unwrapActionReturn } from '@/app/redirectToErrorPage' -import { readApplicationPeriodsAction } from '@/actions/applications/periods/read' +import { readApplicationPeriodsAction } from '@/services/applications/periods/actions' import PageWrapper from '@/components/PageWrapper/PageWrapper' import Date from '@/components/Date/Date' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' -import { readCommitteesAction } from '@/actions/groups/committees/read' +import { readCommitteesAction } from '@/services/groups/committees/actions' export default async function Apllications() { const periods = unwrapActionReturn(await readApplicationPeriodsAction()) diff --git a/src/app/articles/AddCategory.tsx b/src/app/articles/AddCategory.tsx index 95908c907..0ca7d431f 100644 --- a/src/app/articles/AddCategory.tsx +++ b/src/app/articles/AddCategory.tsx @@ -3,7 +3,7 @@ import styles from './AddCategory.module.scss' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import Textarea from '@/components/UI/Textarea' -import { createArticleCategoryAction } from '@/actions/cms/articleCategories/create' +import { createArticleCategoryAction } from '@/services/cms/articleCategories/actions' import { useRouter } from 'next/navigation' export default function AddCategory() { diff --git a/src/app/articles/[category]/EditCategory.tsx b/src/app/articles/[category]/EditCategory.tsx index 683403547..0618164fb 100644 --- a/src/app/articles/[category]/EditCategory.tsx +++ b/src/app/articles/[category]/EditCategory.tsx @@ -3,9 +3,8 @@ import Form from '@/components/Form/Form' import PopUp from '@/components/PopUp/PopUp' import Textarea from '@/components/UI/Textarea' import TextInput from '@/components/UI/TextInput' -import { updateArticleCategoryAction } from '@/actions/cms/articleCategories/update' -import { createArticleAction } from '@/actions/cms/articles/create' -import { destroyArticleCategoryAction } from '@/actions/cms/articleCategories/destroy' +import { updateArticleCategoryAction, destroyArticleCategoryAction } from '@/services/cms/articleCategories/actions' +import { createArticleAction } from '@/services/cms/articles/actions' import { useRouter } from 'next/navigation' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faCog } from '@fortawesome/free-solid-svg-icons' diff --git a/src/app/articles/[category]/SideBar.tsx b/src/app/articles/[category]/SideBar.tsx index 65902c1f3..f8701b392 100644 --- a/src/app/articles/[category]/SideBar.tsx +++ b/src/app/articles/[category]/SideBar.tsx @@ -4,7 +4,7 @@ import EditCategory from './EditCategory' import useScroll from '@/hooks/useScroll' import useOnNavigation from '@/hooks/useOnNavigation' import useViewPort from '@/hooks/useViewPort' -import { destroyArticleAction } from '@/actions/cms/articles/destroy' +import { destroyArticleAction } from '@/services/cms/articles/actions' import React, { useRef, useState } from 'react' import Link from 'next/link' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' diff --git a/src/app/articles/[category]/[name]/page.tsx b/src/app/articles/[category]/[name]/page.tsx index b4b8a4e70..a0104c511 100644 --- a/src/app/articles/[category]/[name]/page.tsx +++ b/src/app/articles/[category]/[name]/page.tsx @@ -1,6 +1,6 @@ import styles from './page.module.scss' import Article from '@/cms/Article/Article' -import { readArticleAction } from '@/cms/articles/read' +import { readArticleAction } from '@/cms/articles/actions' import { notFound } from 'next/navigation' type PropTypes = { diff --git a/src/app/articles/[category]/layout.tsx b/src/app/articles/[category]/layout.tsx index 3337753c5..c3539e44c 100644 --- a/src/app/articles/[category]/layout.tsx +++ b/src/app/articles/[category]/layout.tsx @@ -1,6 +1,6 @@ import styles from './layout.module.scss' import SideBar from './SideBar' -import { readArticleCategoryAction } from '@/cms/articleCategories/read' +import { readArticleCategoryAction } from '@/cms/articleCategories/actions' import { notFound } from 'next/navigation' import type { ReactNode } from 'react' diff --git a/src/app/articles/page.tsx b/src/app/articles/page.tsx index 00031dbb9..6e9cc1812 100644 --- a/src/app/articles/page.tsx +++ b/src/app/articles/page.tsx @@ -2,7 +2,7 @@ import styles from './page.module.scss' import AddCategory from './AddCategory' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import ImageCard from '@/components/ImageCard/ImageCard' -import { readArticleCategoriesAction } from '@/cms/articleCategories/read' +import { readArticleCategoriesAction } from '@/cms/articleCategories/actions' import PageWrapper from '@/components/PageWrapper/PageWrapper' export default async function ArticleCategoryList() { diff --git a/src/app/cabin/book/page.tsx b/src/app/cabin/book/page.tsx index 72c916c81..1e73c009b 100644 --- a/src/app/cabin/book/page.tsx +++ b/src/app/cabin/book/page.tsx @@ -7,7 +7,7 @@ import { readCabinProductsActiveAction, readPublicPricePeriodsAction, readReleasePeriodsAction -} from '@/actions/cabin' +} from '@/services/cabin/actions' import { displayDate } from '@/lib/dates/displayDate' import { Session } from '@/auth/Session' import { CabinBookingAuthers } from '@/services/cabin/booking/authers' diff --git a/src/app/cabin/book/stateWrapper.tsx b/src/app/cabin/book/stateWrapper.tsx index bd629464c..e2c23f51c 100644 --- a/src/app/cabin/book/stateWrapper.tsx +++ b/src/app/cabin/book/stateWrapper.tsx @@ -14,7 +14,7 @@ import { createBedBookingUserAttachedAction, createCabinBookingNoUserAction, createCabinBookingUserAttachedAction -} from '@/actions/cabin' +} from '@/services/cabin/actions' import { getZodDateString } from '@/lib/dates/formatting' import { useMemo, useState } from 'react' import type { CabinProductConfig } from '@/services/cabin/product/config' diff --git a/src/app/career/companies/page.tsx b/src/app/career/companies/page.tsx index 91e4d3024..c6b073eaf 100644 --- a/src/app/career/companies/page.tsx +++ b/src/app/career/companies/page.tsx @@ -1,10 +1,9 @@ -import { createCompanyAction } from '@/actions/career/companies/create' +import { createCompanyAction, readCompanyPageAction } from '@/services/career/companies/actions' import Form from '@/components/Form/Form' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import TextInput from '@/components/UI/TextInput' import PageWrapper from '@/components/PageWrapper/PageWrapper' import CompanyPagingProvider from '@/contexts/paging/CompanyPaging' -import { readCompanyPageAction } from '@/actions/career/companies/read' import CompanyList from '@/components/Company/CompanyList' import { companyListRenderer } from '@/components/Company/CompanyListRenderer' import { QueryParams } from '@/lib/query-params/queryParams' diff --git a/src/app/career/jobads/CreateJobAdForm.tsx b/src/app/career/jobads/CreateJobAdForm.tsx index 15cc5e8ad..c364d5ee9 100644 --- a/src/app/career/jobads/CreateJobAdForm.tsx +++ b/src/app/career/jobads/CreateJobAdForm.tsx @@ -2,7 +2,7 @@ import styles from './CreateJobAdForm.module.scss' import CompanyChooser from './CompanyChooser' import SelectedCompany from './SelectedCompany' -import { createJobAdAction } from '@/actions/career/jobAds/create' +import { createJobAdAction } from '@/services/career/jobAds/actions' import TextInput from '@/components/UI/TextInput' import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' diff --git a/src/app/career/jobads/CurrentJobAds.tsx b/src/app/career/jobads/CurrentJobAds.tsx index 3df157894..b5efdc009 100644 --- a/src/app/career/jobads/CurrentJobAds.tsx +++ b/src/app/career/jobads/CurrentJobAds.tsx @@ -1,5 +1,5 @@ import JobAd from './JobAd' -import { readActiveJobAdsAction } from '@/actions/career/jobAds/read' +import { readActiveJobAdsAction } from '@/services/career/jobAds/actions' type PropTypes = { not?: number diff --git a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx index f3273baec..53bcb0f2c 100644 --- a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx +++ b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx @@ -12,11 +12,10 @@ import { CompanyPagingContext } from '@/contexts/paging/CompanyPaging' import CompanyChooser from '@/app/career/jobads/CompanyChooser' import { bindParams } from '@/services/actionBind' import { JobAdConfig } from '@/services/career/jobAds/config' +import { destroyJobAdAction, updateJobAdAction } from '@/career/jobAds/actions' import { v4 as uuid } from 'uuid' import { useContext, type ReactNode } from 'react' import type { ExpandedJobAd } from '@/career/jobAds/Types' -import { destroyJobAdAction } from '@/career/jobAds/destroy' -import { updateJobAdAction } from '@/career/jobAds/update' type PropTypes = { jobAd: ExpandedJobAd diff --git a/src/app/career/jobads/[...orderAndName]/page.tsx b/src/app/career/jobads/[...orderAndName]/page.tsx index f5606e578..75d906c8f 100644 --- a/src/app/career/jobads/[...orderAndName]/page.tsx +++ b/src/app/career/jobads/[...orderAndName]/page.tsx @@ -8,6 +8,7 @@ import Company from '@/components/Company/Company' import Date from '@/components/Date/Date' import { Session } from '@/auth/Session' import { JobAdConfig } from '@/services/career/jobAds/config' +import { readJobAdAction } from '@/services/career/jobAds/actions' import { notFound } from 'next/navigation' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { @@ -18,7 +19,6 @@ import { faSuitcase, faXmarkCircle } from '@fortawesome/free-solid-svg-icons' -import { readJobAdAction } from '@/actions/career/jobAds/read' type PropTypes = { params: Promise<{ diff --git a/src/app/career/page.tsx b/src/app/career/page.tsx index cad815fdb..d01cee89f 100644 --- a/src/app/career/page.tsx +++ b/src/app/career/page.tsx @@ -5,10 +5,10 @@ import { Session } from '@/auth/Session' import Image from '@/components/Image/Image' import CmsLink from '@/components/Cms/CmsLink/CmsLink' import { QueryParams } from '@/lib/query-params/queryParams' +import { readSpecialImageAction } from '@/services/images/actions' +import { readSpecialCmsLinkAction } from '@/services/cms/links/actions' +import { readSpecialEventTagAction } from '@/services/events/tags/actions' import Link from 'next/link' -import { readSpecialImageAction } from '@/actions/images/read' -import { readSpecialCmsLinkAction } from '@/actions/cms/links/read' -import { readSpecialEventTagAction } from '@/actions/events/tags/read' export default async function CareerLandingPage() { const session = await Session.fromNextAuth() diff --git a/src/app/committees/[shortName]/about/page.tsx b/src/app/committees/[shortName]/about/page.tsx index 8f0db30f3..3d36c5793 100644 --- a/src/app/committees/[shortName]/about/page.tsx +++ b/src/app/committees/[shortName]/about/page.tsx @@ -1,5 +1,5 @@ import styles from './page.module.scss' -import { readCommitteeArticleAction } from '@/actions/groups/committees/read' +import { readCommitteeArticleAction } from '@/services/groups/committees/actions' import Article from '@/components/Cms/Article/Article' export type PropTypes = { diff --git a/src/app/committees/[shortName]/getCommittee.ts b/src/app/committees/[shortName]/getCommittee.ts index d38c24ba7..7c68f6b9f 100644 --- a/src/app/committees/[shortName]/getCommittee.ts +++ b/src/app/committees/[shortName]/getCommittee.ts @@ -1,4 +1,4 @@ -import { readCommitteeAction } from '@/actions/groups/committees/read' +import { readCommitteeAction } from '@/services/groups/committees/actions' import { notFound } from 'next/navigation' import type { PropTypes } from './page' diff --git a/src/app/committees/[shortName]/layout.tsx b/src/app/committees/[shortName]/layout.tsx index cb6e49bc8..48b7a348a 100644 --- a/src/app/committees/[shortName]/layout.tsx +++ b/src/app/committees/[shortName]/layout.tsx @@ -1,7 +1,7 @@ import getCommitee from './getCommittee' import Nav from './Nav' import styles from './layout.module.scss' -import { readSpecialImageAction } from '@/actions/images/read' +import { readSpecialImageAction } from '@/services/images/actions' import BackdropImage from '@/components/BackdropImage/BackdropImage' import PageWrapper from '@/components/PageWrapper/PageWrapper' import CommitteeImage from '@/components/CommitteeImage/CommitteeImage' diff --git a/src/app/committees/[shortName]/members/page.tsx b/src/app/committees/[shortName]/members/page.tsx index 1cd9d090a..a7dfe05f2 100644 --- a/src/app/committees/[shortName]/members/page.tsx +++ b/src/app/committees/[shortName]/members/page.tsx @@ -1,6 +1,6 @@ import styles from './page.module.scss' import { unwrapActionReturn } from '@/app/redirectToErrorPage' -import { readCommitteeMembersAction } from '@/actions/groups/committees/read' +import { readCommitteeMembersAction } from '@/services/groups/committees/actions' import UserCard from '@/components/User/UserCard' import type { PropTypes } from '@/app/committees/[shortName]/page' diff --git a/src/app/committees/[shortName]/page.tsx b/src/app/committees/[shortName]/page.tsx index 8358d6b98..a85c87d5b 100644 --- a/src/app/committees/[shortName]/page.tsx +++ b/src/app/committees/[shortName]/page.tsx @@ -1,5 +1,5 @@ import styles from './page.module.scss' -import { readCommitteeMembersAction, readCommitteeParagraphAction } from '@/actions/groups/committees/read' +import { readCommitteeMembersAction, readCommitteeParagraphAction } from '@/services/groups/committees/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import CmsParagraph from '@/components/Cms/CmsParagraph/CmsParagraph' import UserCard from '@/components/User/UserCard' diff --git a/src/app/committees/page.tsx b/src/app/committees/page.tsx index b79b5ee1c..ca8cdce1e 100644 --- a/src/app/committees/page.tsx +++ b/src/app/committees/page.tsx @@ -1,7 +1,7 @@ import styles from './page.module.scss' import CommitteeCard from '@/components/CommitteeCard/CommitteeCard' -import { readCommitteesAction } from '@/actions/groups/committees/read' -import { readSpecialImageAction } from '@/actions/images/read' +import { readCommitteesAction } from '@/services/groups/committees/actions' +import { readSpecialImageAction } from '@/services/images/actions' export default async function Committees() { const res = await readCommitteesAction() diff --git a/src/app/education/courses/page.tsx b/src/app/education/courses/page.tsx index dd41c093c..466dbcd90 100644 --- a/src/app/education/courses/page.tsx +++ b/src/app/education/courses/page.tsx @@ -2,7 +2,7 @@ import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import PageWrapper from '@/components/PageWrapper/PageWrapper' import TextInput from '@/components/UI/TextInput' import Form from '@/components/Form/Form' -import { createCourseAction } from '@/education/courses/create' +import { createCourseAction } from '@/education/courses/actions' export default function Courses() { return ( diff --git a/src/app/education/page.tsx b/src/app/education/page.tsx index 8e0b2070b..510414092 100644 --- a/src/app/education/page.tsx +++ b/src/app/education/page.tsx @@ -1,5 +1,5 @@ import styles from './page.module.scss' -import { readSpecialImageAction } from '@/actions/images/read' +import { readSpecialImageAction } from '@/services/images/actions' import PageWrapper from '@/components/PageWrapper/PageWrapper' import ImageCard from '@/components/ImageCard/ImageCard' diff --git a/src/app/education/schools/page.tsx b/src/app/education/schools/page.tsx index dd6ac0d92..a9551388f 100644 --- a/src/app/education/schools/page.tsx +++ b/src/app/education/schools/page.tsx @@ -1,5 +1,5 @@ import styles from './page.module.scss' -import { readSchoolsPageAction } from '@/actions/education/schools/read' +import { readSchoolsPageAction } from '@/services/education/schools/actions' import { getUser } from '@/auth/getUser' import PageWrapper from '@/components/PageWrapper/PageWrapper' import SchoolPagingProvider from '@/contexts/paging/SchoolPaging' diff --git a/src/app/events/CreateOrUpdateEventForm.tsx b/src/app/events/CreateOrUpdateEventForm.tsx index 06062a6c5..f8dde6f3b 100644 --- a/src/app/events/CreateOrUpdateEventForm.tsx +++ b/src/app/events/CreateOrUpdateEventForm.tsx @@ -11,11 +11,10 @@ import { EventConfig } from '@/services/events/config' import EventTag from '@/components/Event/EventTag' import { bindParams } from '@/services/actionBind' import { FIELD_IS_PRESENT_VALUE } from '@/lib/fields/config' +import { createEventAction, updateEventAction } from '@/services/events/actions' import { useState } from 'react' import type { Event, EventTag as EventTagT } from '@prisma/client' import type { ChangeEvent } from 'react' -import { createEventAction } from '@/actions/events/create' -import { updateEventAction } from '@/actions/events/update' type PropTypes = { event?: Event & { tags: EventTagT[] } diff --git a/src/app/events/[order]/[name]/ManualRegistrationForm.tsx b/src/app/events/[order]/[name]/ManualRegistrationForm.tsx index 9576fd5ad..fd275756d 100644 --- a/src/app/events/[order]/[name]/ManualRegistrationForm.tsx +++ b/src/app/events/[order]/[name]/ManualRegistrationForm.tsx @@ -6,10 +6,10 @@ import UserPagingProvider from '@/contexts/paging/UserPaging' import UserSelectionProvider, { UserSelectionContext } from '@/contexts/UserSelection' import TextInput from '@/components/UI/TextInput' import { bindParams } from '@/services/actionBind' +import { createEventRegistrationAction, createGuestEventRegistrationAction } from '@/services/events/registration/actions' import { useContext } from 'react' import type { EventRegistration } from '@prisma/client' import type { ActionReturn } from '@/services/actionTypes' -import { createEventRegistrationAction, createGuestEventRegistrationAction } from '@/actions/events/registration' function ManualRegistrationFormInner({ eventId, diff --git a/src/app/events/[order]/[name]/RegistrationUI.tsx b/src/app/events/[order]/[name]/RegistrationUI.tsx index 96096049e..716cefb0a 100644 --- a/src/app/events/[order]/[name]/RegistrationUI.tsx +++ b/src/app/events/[order]/[name]/RegistrationUI.tsx @@ -5,15 +5,15 @@ import Form from '@/components/Form/Form' import { bindParams } from '@/services/actionBind' import TextInput from '@/components/UI/TextInput' import SubmitButton from '@/components/UI/SubmitButton' -import { useEffect, useState } from 'react' -import { useSession } from 'next-auth/react' -import type { EventExpanded } from '@/services/events/Types' -import type { EventRegistration } from '@prisma/client' import { createEventRegistrationAction, eventRegistrationDestroyAction, eventRegistrationUpdateNotesAction -} from '@/actions/events/registration' +} from '@/services/events/registration/actions' +import { useEffect, useState } from 'react' +import { useSession } from 'next-auth/react' +import type { EventExpanded } from '@/services/events/Types' +import type { EventRegistration } from '@prisma/client' enum RegistrationButtonState { NOT_REGISTERED = 'NOT_REGISTERED', diff --git a/src/app/events/[order]/[name]/RegistrationsList.tsx b/src/app/events/[order]/[name]/RegistrationsList.tsx index 53b94204d..4f2d2a21c 100644 --- a/src/app/events/[order]/[name]/RegistrationsList.tsx +++ b/src/app/events/[order]/[name]/RegistrationsList.tsx @@ -12,10 +12,10 @@ import Form from '@/components/Form/Form' import { bindParams } from '@/services/actionBind' import { EventRegistrationConfig } from '@/services/events/registration/config' import ContactCard from '@/components/User/ContactCard' +import { eventRegistrationDestroyAction } from '@/services/events/registration/actions' import Link from 'next/link' import { useState } from 'react' import type { EventFiltered } from '@/services/events/Types' -import { eventRegistrationDestroyAction } from '@/actions/events/registration' function DetailedTable({ event, diff --git a/src/app/events/[order]/[name]/ShowAndEditName.tsx b/src/app/events/[order]/[name]/ShowAndEditName.tsx index c91dde3ab..a4f8599cd 100644 --- a/src/app/events/[order]/[name]/ShowAndEditName.tsx +++ b/src/app/events/[order]/[name]/ShowAndEditName.tsx @@ -1,8 +1,8 @@ 'use client' import styles from './ShowAndEditName.module.scss' import EditableTextField from '@/components/EditableTextField/EditableTextField' +import { updateEventAction } from '@/services/events/actions' import type { Event } from '@prisma/client' -import { updateEventAction } from '@/actions/events/update' type PropTypes = { event: Event diff --git a/src/app/events/[order]/[name]/page.tsx b/src/app/events/[order]/[name]/page.tsx index aeec70c64..24c5abd2c 100644 --- a/src/app/events/[order]/[name]/page.tsx +++ b/src/app/events/[order]/[name]/page.tsx @@ -13,12 +13,11 @@ import { SettingsHeaderItemPopUp, UsersHeaderItemPopUp } from '@/components/Head import { QueryParams } from '@/lib/query-params/queryParams' import { bindParams } from '@/services/actionBind' import { unwrapActionReturn } from '@/app/redirectToErrorPage' +import { readEventTagsAction } from '@/services/events/tags/actions' +import { destroyEventAction, readEventAction } from '@/services/events/actions' import Link from 'next/link' import { faCalendar, faExclamation, faLocationDot, faUsers } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { readEventTagsAction } from '@/actions/events/tags/read' -import { destroyEventAction } from '@/actions/events/destroy' -import { readEventAction } from '@/actions/events/read' type PropTypes = { params: Promise<{ diff --git a/src/app/events/archive/page.tsx b/src/app/events/archive/page.tsx index f7d7efc61..02d07db36 100644 --- a/src/app/events/archive/page.tsx +++ b/src/app/events/archive/page.tsx @@ -1,6 +1,6 @@ import EventArchiveList from './EventArchiveList' import TagHeaderItem from '@/app/events/TagHeaderItem' -import { readEventTagsAction } from '@/actions/events/tags/read' +import { readEventTagsAction } from '@/services/events/tags/actions' import EventsLandingLayout from '@/app/events/EventsLandingLayout' import EventArchivePagingProvider from '@/contexts/paging/EventArchivePaging' import { QueryParams } from '@/lib/query-params/queryParams' diff --git a/src/app/events/page.tsx b/src/app/events/page.tsx index 6ca662308..19e44e6c1 100644 --- a/src/app/events/page.tsx +++ b/src/app/events/page.tsx @@ -3,9 +3,9 @@ import CreateOrUpdateEventForm from './CreateOrUpdateEventForm' import EventsLandingLayout from './EventsLandingLayout' import TagHeaderItem from './TagHeaderItem' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' -import { readCurrentEventsAction } from '@/actions/events/read' +import { readCurrentEventsAction } from '@/services/events/actions' import EventCard from '@/components/Event/EventCard' -import { readEventTagsAction } from '@/actions/events/tags/read' +import { readEventTagsAction } from '@/services/events/tags/actions' import { EventTagAuthers } from '@/services/events/tags/authers' import { QueryParams } from '@/lib/query-params/queryParams' import { Session } from '@/auth/Session' diff --git a/src/app/images/MakeNewCollection.tsx b/src/app/images/MakeNewCollection.tsx index c5df6660e..14b4fb8e5 100644 --- a/src/app/images/MakeNewCollection.tsx +++ b/src/app/images/MakeNewCollection.tsx @@ -3,7 +3,7 @@ import styles from './MakeNewCollection.module.scss' import Form from '@/components/Form/Form' import PopUp from '@/components/PopUp/PopUp' import TextInput from '@/components/UI/TextInput' -import { createImageCollectionAction } from '@/actions/images/collections/create' +import { createImageCollectionAction } from '@/services/images/collections/actions' import { faPlus } from '@fortawesome/free-solid-svg-icons' import { useRouter } from 'next/navigation' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' diff --git a/src/app/images/collections/[id]/CollectionAdmin.tsx b/src/app/images/collections/[id]/CollectionAdmin.tsx index 3ac798af9..13634371a 100644 --- a/src/app/images/collections/[id]/CollectionAdmin.tsx +++ b/src/app/images/collections/[id]/CollectionAdmin.tsx @@ -1,10 +1,9 @@ 'use client' import styles from './CollectionAdmin.module.scss' import CollectionAdminUpload from './CollectionAdminUpload' -import { updateImageCollectionAction } from '@/actions/images/collections/update' +import { updateImageCollectionAction, destroyImageCollectionAction } from '@/services/images/collections/actions' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' -import { destroyImageCollectionAction } from '@/actions/images/collections/destroy' import { ImagePagingContext } from '@/contexts/paging/ImagePaging' import ImageUploader from '@/components/Image/ImageUploader' import useEditing from '@/hooks/useEditing' diff --git a/src/app/images/collections/[id]/CollectionAdminUpload.tsx b/src/app/images/collections/[id]/CollectionAdminUpload.tsx index aabdca268..0ab90f9f9 100644 --- a/src/app/images/collections/[id]/CollectionAdminUpload.tsx +++ b/src/app/images/collections/[id]/CollectionAdminUpload.tsx @@ -7,10 +7,10 @@ import ProgressBar from '@/components/ProgressBar/ProgressBar' import TextInput from '@/app/_components/UI/TextInput' import LicenseChooser from '@/app/_components/LicenseChooser/LicenseChooser' import { ImageConfig } from '@/services/images/config' +import { createImagesAction } from '@/services/images/actions' import { useCallback, useState } from 'react' import type { FileWithStatus } from '@/components/UI/Dropzone' import type { ActionReturn } from '@/services/actionTypes' -import { createImagesAction } from '@/actions/images/create' type PropTypes = { collectionId: number diff --git a/src/app/images/collections/[id]/page.tsx b/src/app/images/collections/[id]/page.tsx index 73e845d3c..8e528610e 100644 --- a/src/app/images/collections/[id]/page.tsx +++ b/src/app/images/collections/[id]/page.tsx @@ -4,10 +4,10 @@ import ImageList from '@/components/Image/ImageList/ImageList' import ImagePagingProvider from '@/contexts/paging/ImagePaging' import ImageListImage from '@/components/Image/ImageList/ImageListImage' import ImageDisplayProvider from '@/contexts/ImageDisplayProvider' +import { readImageCollectionAction } from '@/services/images/collections/actions' +import { readImagesPageAction } from '@/services/images/actions' import { notFound } from 'next/navigation' import type { PageSizeImage } from '@/contexts/paging/ImagePaging' -import { readImageCollectionAction } from '@/actions/images/collections/read' -import { readImagesPageAction } from '@/actions/images/read' type PropTypes = { params: Promise<{ diff --git a/src/app/images/page.tsx b/src/app/images/page.tsx index 2ab4f8797..8a217443c 100644 --- a/src/app/images/page.tsx +++ b/src/app/images/page.tsx @@ -4,8 +4,8 @@ import ImageCollectionList from '@/components/Image/Collection/ImageCollectionLi import ImageCollectionPagingProvider from '@/contexts/paging/ImageCollectionPaging' import CollectionCard from '@/components/Image/Collection/CollectionCard' import { getUser } from '@/auth/getUser' +import { readImageCollectionsPageAction } from '@/services/images/collections/actions' import type { PageSizeImageCollection } from '@/contexts/paging/ImageCollectionPaging' -import { readImageCollectionsPageAction } from '@/actions/images/collections/read' export default async function Images() { const { user } = await getUser() diff --git a/src/app/interest-groups/CreateInterestGroupForm.tsx b/src/app/interest-groups/CreateInterestGroupForm.tsx index 356738d80..4b936d2fb 100644 --- a/src/app/interest-groups/CreateInterestGroupForm.tsx +++ b/src/app/interest-groups/CreateInterestGroupForm.tsx @@ -1,6 +1,6 @@ import styles from './CreateInterestGroupForm.module.scss' import Form from '@/components/Form/Form' -import { createInterestGroupAction } from '@/actions/groups/interestGroups/create' +import { createInterestGroupAction } from '@/services/groups/interestGroups/actions' import TextInput from '@/components/UI/TextInput' export default function CreateInterestGroupForm() { diff --git a/src/app/interest-groups/InterestGroup.tsx b/src/app/interest-groups/InterestGroup.tsx index f834133d7..ae6c6a2bf 100644 --- a/src/app/interest-groups/InterestGroup.tsx +++ b/src/app/interest-groups/InterestGroup.tsx @@ -3,8 +3,7 @@ import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import ArticleSection from '@/components/Cms/ArticleSection/ArticleSection' import { SettingsHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' -import { updateInterestGroupAction } from '@/actions/groups/interestGroups/update' -import { destroyInterestGroupAction } from '@/actions/groups/interestGroups/destroy' +import { updateInterestGroupAction, destroyInterestGroupAction } from '@/services/groups/interestGroups/actions' import { InterestGroupAuthers } from '@/services/groups/interestGroups/authers' import type { SessionMaybeUser } from '@/auth/Session' import type { ExpandedInterestGroup } from '@/services/groups/interestGroups/Types' diff --git a/src/app/interest-groups/page.tsx b/src/app/interest-groups/page.tsx index fcd9c9a90..115e9e458 100644 --- a/src/app/interest-groups/page.tsx +++ b/src/app/interest-groups/page.tsx @@ -5,7 +5,7 @@ import PageWrapper from '@/components/PageWrapper/PageWrapper' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import { Session } from '@/auth/Session' import { InterestGroupAuthers } from '@/services/groups/interestGroups/authers' -import { readInterestGroupsAction } from '@/actions/groups/interestGroups/read' +import { readInterestGroupsAction } from '@/services/groups/interestGroups/actions' export default async function InterestGroups() { const session = await Session.fromNextAuth() diff --git a/src/app/layout.tsx b/src/app/layout.tsx index e40a07573..61bff1f51 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -7,14 +7,14 @@ import { authOptions } from '@/auth/authoptions' import EditModeProvider from '@/contexts/EditMode' import PopUpProvider from '@/contexts/PopUp' import DefaultPermissionsProvider from '@/contexts/DefaultPermissions' +import { readDefaultPermissionsAction } from '@/services/permissions/actions' import { Inter } from 'next/font/google' -import { readDefaultPermissionsAction } from '@/actions/permissions/index' import '@/styles/globals.scss' import { config } from '@fortawesome/fontawesome-svg-core' import '@fortawesome/fontawesome-svg-core/styles.css' import { getServerSession } from 'next-auth' import type { ReactNode } from 'react' -import { readUserProfileAction } from '@/actions/users/read' +import { readUserProfileAction } from '@/services/users/actions' import { unwrapActionReturn } from './redirectToErrorPage' config.autoAddCss = false diff --git a/src/app/lockers/[id]/CreateLockerReservationForm.tsx b/src/app/lockers/[id]/CreateLockerReservationForm.tsx index 1372f5cf1..4f8b51c5c 100644 --- a/src/app/lockers/[id]/CreateLockerReservationForm.tsx +++ b/src/app/lockers/[id]/CreateLockerReservationForm.tsx @@ -4,9 +4,9 @@ import { SelectString } from '@/components/UI/Select' import DateInput from '@/components/UI/DateInput' import Checkbox from '@/components/UI/Checkbox' import { bindParams } from '@/services/actionBind' +import { createLockerReservationAction } from '@/services/lockers/actions' import React, { useState } from 'react' import { useRouter } from 'next/navigation' -import { createLockerReservationAction } from '@/actions/lockers/reservations' type PropTypes = { lockerId: number diff --git a/src/app/lockers/[id]/UpdateLockerReservationForm.tsx b/src/app/lockers/[id]/UpdateLockerReservationForm.tsx index 5e99c8611..35710d862 100644 --- a/src/app/lockers/[id]/UpdateLockerReservationForm.tsx +++ b/src/app/lockers/[id]/UpdateLockerReservationForm.tsx @@ -4,9 +4,9 @@ import { SelectString } from '@/components/UI/Select' import DateInput from '@/components/UI/DateInput' import Checkbox from '@/components/UI/Checkbox' import { bindParams } from '@/services/actionBind' +import { updateLockerReservationAction } from '@/services/lockers/actions' import { useState } from 'react' import { useRouter } from 'next/navigation' -import { updateLockerReservationAction } from '@/actions/lockers/reservations' type PropTypes = { reservationId: number, diff --git a/src/app/lockers/[id]/page.tsx b/src/app/lockers/[id]/page.tsx index a11054a1a..9997928de 100644 --- a/src/app/lockers/[id]/page.tsx +++ b/src/app/lockers/[id]/page.tsx @@ -3,7 +3,7 @@ import LockerNotFound from './LockerNotFound' import CreateLockerReservationForm from './CreateLockerReservationForm' import UpdateLockerReservationForm from './UpdateLockerReservationForm' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { readLockerAction } from '@/actions/lockers/lockers' +import { readLockerAction } from '@/services/lockers/actions' import { getUser } from '@/auth/getUser' import { checkGroupValidity, GroupMethods, inferGroupName } from '@/services/groups/methods' diff --git a/src/app/news/AddNews.tsx b/src/app/news/AddNews.tsx index 054b286bc..d2ef6d27f 100644 --- a/src/app/news/AddNews.tsx +++ b/src/app/news/AddNews.tsx @@ -1,7 +1,7 @@ 'use client' import styles from './AddNews.module.scss' import Textarea from '@/components/UI/Textarea' -import { createNewsAction } from '@/actions/news/create' +import { createNewsAction } from '@/services/news/actions' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import { EditModeContext } from '@/contexts/EditMode' diff --git a/src/app/news/CurrentNews.tsx b/src/app/news/CurrentNews.tsx index 601cbfd33..cba9ac01c 100644 --- a/src/app/news/CurrentNews.tsx +++ b/src/app/news/CurrentNews.tsx @@ -1,5 +1,5 @@ import NewsCard from './NewsCard' -import { readNewsCurrentAction } from '@/actions/news/read' +import { readNewsCurrentAction } from '@/services/news/actions' import React from 'react' type PropTypes = { diff --git a/src/app/news/[...orderAndName]/EditNews.tsx b/src/app/news/[...orderAndName]/EditNews.tsx index 2576ddfcc..71186681c 100644 --- a/src/app/news/[...orderAndName]/EditNews.tsx +++ b/src/app/news/[...orderAndName]/EditNews.tsx @@ -5,11 +5,10 @@ import TextInput from '@/components/UI/TextInput' import Textarea from '@/components/UI/Textarea' import DateInput from '@/components/UI/DateInput' import useEditing from '@/hooks/useEditing' +import { destroyNewsAction, updateNewsAction } from '@/services/news/actions' import { useRouter } from 'next/navigation' import type { ExpandedNewsArticle } from '@/services/news/Types' import type { ReactNode } from 'react' -import { destroyNewsAction } from '@/actions/news/destroy' -import { updateNewsAction } from '@/actions/news/update' type PropTypes = { news: ExpandedNewsArticle diff --git a/src/app/news/[...orderAndName]/page.tsx b/src/app/news/[...orderAndName]/page.tsx index e2f43358b..146747db1 100644 --- a/src/app/news/[...orderAndName]/page.tsx +++ b/src/app/news/[...orderAndName]/page.tsx @@ -2,7 +2,7 @@ import styles from './page.module.scss' import EditNews from './EditNews' import CurrentNews from '@/app/news/CurrentNews' import Article from '@/cms/Article/Article' -import { readNewsAction } from '@/actions/news/read' +import { readNewsAction } from '@/services/news/actions' import SlideInOnView from '@/components/SlideInOnView/SlideInOnView' import { notFound } from 'next/navigation' diff --git a/src/app/news/archive/page.tsx b/src/app/news/archive/page.tsx index 50bd36ac0..c0dafbdc6 100644 --- a/src/app/news/archive/page.tsx +++ b/src/app/news/archive/page.tsx @@ -1,7 +1,7 @@ import OldNewsList from './OldNewsList' import NewsCard from '@/app/news/NewsCard' import OldNewsPagingProvider from '@/contexts/paging/OldNewsPaging' -import { readOldNewsPageAction } from '@/actions/news/read' +import { readOldNewsPageAction } from '@/services/news/actions' import PageWrapper from '@/components/PageWrapper/PageWrapper' import type { PageSizeOldNews } from '@/contexts/paging/OldNewsPaging' diff --git a/src/app/ombul/CreateOmbul.tsx b/src/app/ombul/CreateOmbul.tsx index 284b3ae5a..d6c165aba 100644 --- a/src/app/ombul/CreateOmbul.tsx +++ b/src/app/ombul/CreateOmbul.tsx @@ -5,7 +5,7 @@ import TextInput from '@/components/UI/TextInput' import NumberInput from '@/components/UI/NumberInput' import FileInput from '@/components/UI/FileInput' import Textarea from '@/components/UI/Textarea' -import { createOmbulAction } from '@/actions/ombul/create' +import { createOmbulAction } from '@/services/ombul/actions' import Form from '@/components/Form/Form' import { useState } from 'react' import { useRouter } from 'next/navigation' diff --git a/src/app/ombul/[...yearAndName]/ChangeName.tsx b/src/app/ombul/[...yearAndName]/ChangeName.tsx index 49a9f38ab..92f85fce8 100644 --- a/src/app/ombul/[...yearAndName]/ChangeName.tsx +++ b/src/app/ombul/[...yearAndName]/ChangeName.tsx @@ -2,7 +2,7 @@ import styles from './ChangeName.module.scss' import EditableTextField from '@/components/EditableTextField/EditableTextField' -import { updateOmbulAction } from '@/actions/ombul/update' +import { updateOmbulAction } from '@/services/ombul/actions' import type { ReactNode } from 'react' import type { ExpandedOmbul } from '@/services/ombul/Types' diff --git a/src/app/ombul/[...yearAndName]/OmbulAdmin.tsx b/src/app/ombul/[...yearAndName]/OmbulAdmin.tsx index ca7a77ec0..7425d93a7 100644 --- a/src/app/ombul/[...yearAndName]/OmbulAdmin.tsx +++ b/src/app/ombul/[...yearAndName]/OmbulAdmin.tsx @@ -2,10 +2,9 @@ import styles from './OmbulAdmin.module.scss' import Form from '@/components/Form/Form' -import { updateOmbulAction, updateOmbulFileAction } from '@/actions/ombul/update' +import { updateOmbulAction, updateOmbulFileAction, destroyOmbulAction } from '@/services/ombul/actions' import NumberInput from '@/components/UI/NumberInput' import FileInput from '@/components/UI/FileInput' -import { destroyOmbulAction } from '@/actions/ombul/destroy' import useEditing from '@/hooks/useEditing' import { useRouter } from 'next/navigation' import type { ReactNode } from 'react' diff --git a/src/app/ombul/[...yearAndName]/page.tsx b/src/app/ombul/[...yearAndName]/page.tsx index 85658fb26..04001baf4 100644 --- a/src/app/ombul/[...yearAndName]/page.tsx +++ b/src/app/ombul/[...yearAndName]/page.tsx @@ -1,11 +1,10 @@ import styles from './page.module.scss' import ChangeName from './ChangeName' import OmbulAdmin from './OmbulAdmin' -import { readOmbulAction } from '@/actions/ombul/read' +import { readOmbulAction, updateOmbulAction } from '@/services/ombul/actions' import PdfDocument from '@/components/PdfDocument/PdfDocument' import SlideInOnView from '@/components/SlideInOnView/SlideInOnView' import EditableTextField from '@/components/EditableTextField/EditableTextField' -import { updateOmbulAction } from '@/actions/ombul/update' import { getUser } from '@/auth/getUser' import CmsImage from '@/components/Cms/CmsImage/CmsImage' import Link from 'next/link' diff --git a/src/app/ombul/page.tsx b/src/app/ombul/page.tsx index 91f95a19a..375812ebd 100644 --- a/src/app/ombul/page.tsx +++ b/src/app/ombul/page.tsx @@ -3,7 +3,7 @@ import CreateOmbul from './CreateOmbul' import OmbulCover from './OmbulCover' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' -import { readLatestOmbulAction, readOmbulsAction } from '@/actions/ombul/read' +import { readLatestOmbulAction, readOmbulsAction } from '@/services/ombul/actions' import { getUser } from '@/auth/getUser' import type { ExpandedOmbul } from '@/services/ombul/Types' diff --git a/src/app/omegaquotes/CreateOmegaquoteForm.tsx b/src/app/omegaquotes/CreateOmegaquoteForm.tsx index 17bf1e98a..21c8e6715 100644 --- a/src/app/omegaquotes/CreateOmegaquoteForm.tsx +++ b/src/app/omegaquotes/CreateOmegaquoteForm.tsx @@ -3,7 +3,7 @@ import styles from './CreateOmegaquoteFrom.module.scss' import PopUp from '@/components/PopUp/PopUp' import Form from '@/components/Form/Form' -import { createQuoteAction } from '@/actions/omegaquotes/create' +import { createQuoteAction } from '@/services/omegaquotes/actions' import TextInput from '@/components/UI/TextInput' import Textarea from '@/components/UI/Textarea' import { useRouter } from 'next/navigation' diff --git a/src/app/omegaquotes/page.tsx b/src/app/omegaquotes/page.tsx index ab32a663c..5a84c859a 100644 --- a/src/app/omegaquotes/page.tsx +++ b/src/app/omegaquotes/page.tsx @@ -3,7 +3,7 @@ import OmegaquoteQuote from './OmegaquotesQuote' import CreateOmegaquoteForm from './CreateOmegaquoteForm' import OmegaquotePagingProvider from '@/contexts/paging/OmegaquotesPaging' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { readQuotesPageAction } from '@/actions/omegaquotes/read' +import { readQuotesPageAction } from '@/services/omegaquotes/actions' import { getUser } from '@/auth/getUser' import { notFound } from 'next/navigation' import { v4 as uuid } from 'uuid' diff --git a/src/app/users/[username]/(user-admin)/dots/page.tsx b/src/app/users/[username]/(user-admin)/dots/page.tsx index 2267e6b22..a672a0790 100644 --- a/src/app/users/[username]/(user-admin)/dots/page.tsx +++ b/src/app/users/[username]/(user-admin)/dots/page.tsx @@ -1,6 +1,6 @@ import styles from './page.module.scss' -import { readDotWrappersForUserAction } from '@/actions/dots/read' +import { readDotWrappersForUserAction } from '@/services/dots/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { getProfileForAdmin } from '@/app/users/[username]/(user-admin)/getProfileForAdmin' import Date from '@/components/Date/Date' diff --git a/src/app/users/[username]/(user-admin)/getProfileForAdmin.ts b/src/app/users/[username]/(user-admin)/getProfileForAdmin.ts index 5ff7c9269..ac1b62f64 100644 --- a/src/app/users/[username]/(user-admin)/getProfileForAdmin.ts +++ b/src/app/users/[username]/(user-admin)/getProfileForAdmin.ts @@ -1,4 +1,4 @@ -import { readUserProfileAction } from '@/actions/users/read' +import { readUserProfileAction } from '@/services/users/actions' import { Session } from '@/auth/Session' import { UserAuthers } from '@/services/users/authers' import { notFound, redirect } from 'next/navigation' diff --git a/src/app/users/[username]/(user-admin)/layout.tsx b/src/app/users/[username]/(user-admin)/layout.tsx index 4161a321b..1c4aec771 100644 --- a/src/app/users/[username]/(user-admin)/layout.tsx +++ b/src/app/users/[username]/(user-admin)/layout.tsx @@ -1,7 +1,7 @@ import styles from './layout.module.scss' import Nav from './Nav' import { Session } from '@/auth/Session' -import { readUserProfileAction } from '@/actions/users/read' +import { readUserProfileAction } from '@/services/users/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { notFound } from 'next/navigation' diff --git a/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx b/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx index 90ef95ad3..405aa92ad 100644 --- a/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx +++ b/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx @@ -5,7 +5,7 @@ import styles from './notificationSettings.module.scss' import { booleanOperationOnMethods, newAllMethodsOff } from '@/services/notifications/notificationMethodOperations' import SubmitButton from '@/components/UI/SubmitButton' import { SUCCESS_FEEDBACK_TIME } from '@/components/Form/ConfigVars' -import { updateNotificationSubscriptionsAction } from '@/actions/notifications' +import { updateNotificationSubscriptionsAction } from '@/services/notifications/actions' import { NotificationConfig } from '@/services/notifications/config' import { v4 as uuid } from 'uuid' import { useState } from 'react' diff --git a/src/app/users/[username]/(user-admin)/notifications/page.tsx b/src/app/users/[username]/(user-admin)/notifications/page.tsx index ec451acfa..b3b27cd2d 100644 --- a/src/app/users/[username]/(user-admin)/notifications/page.tsx +++ b/src/app/users/[username]/(user-admin)/notifications/page.tsx @@ -1,8 +1,8 @@ 'use server' import NotificationSettings from './notificationSettings' import { getProfileForAdmin } from '@/app/users/[username]/(user-admin)/getProfileForAdmin' +import { readNotificationChannelsAction, readNotificationSubscriptionsAction } from '@/services/notifications/actions' import type { PropTypes } from '@/app/users/[username]/page' -import { readNotificationChannelsAction, readNotificationSubscriptionsAction } from '@/actions/notifications' export default async function Notififcations({ params }: PropTypes) { const { profile } = await getProfileForAdmin(await params, 'notifications') diff --git a/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx b/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx index 96cdb4d80..a7856bcdc 100644 --- a/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx +++ b/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx @@ -1,5 +1,5 @@ 'use client' -import { registerStudentCardInQueueAction } from '@/actions/users/update' +import { registerStudentCardInQueueAction } from '@/services/users/actions' import Form from '@/app/_components/Form/Form' import { UserConfig } from '@/services/users/config' diff --git a/src/app/users/[username]/page.tsx b/src/app/users/[username]/page.tsx index 634128426..87b710005 100644 --- a/src/app/users/[username]/page.tsx +++ b/src/app/users/[username]/page.tsx @@ -8,13 +8,13 @@ import { UserAuthers } from '@/services/users/authers' import ProfilePicture from '@/components/User/ProfilePicture' import { UserConfig } from '@/services/users/config' import UserDisplayName from '@/components/User/UserDisplayName' +import { readUserProfileAction } from '@/services/users/actions' +import { readSpecialImageAction } from '@/services/images/actions' import Link from 'next/link' import { notFound, redirect } from 'next/navigation' import { v4 as uuid } from 'uuid' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faQrcode } from '@fortawesome/free-solid-svg-icons' -import { readUserProfileAction } from '@/actions/users/read' -import { readSpecialImageAction } from '@/actions/images/read' export type PropTypes = { params: Promise<{ diff --git a/src/contexts/paging/CompanyPaging.tsx b/src/contexts/paging/CompanyPaging.tsx index 371fc6b24..caf8bcc77 100644 --- a/src/contexts/paging/CompanyPaging.tsx +++ b/src/contexts/paging/CompanyPaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readCompanyPageAction } from '@/actions/career/companies/read' +import { readCompanyPageAction } from '@/services/career/companies/actions' import type { CompanyCursor, CompanyDetails, CompanyExpanded } from '@/services/career/companies/Types' import type { ReadPageInput } from '@/lib/paging/Types' diff --git a/src/contexts/paging/DotPaging.tsx b/src/contexts/paging/DotPaging.tsx index d9cd88a99..63fb92353 100644 --- a/src/contexts/paging/DotPaging.tsx +++ b/src/contexts/paging/DotPaging.tsx @@ -1,7 +1,7 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readDotPageAction } from '@/actions/dots/read' +import { readDotPageAction } from '@/services/dots/actions' import type { ReadPageInput } from '@/lib/paging/Types' import type { DotDetails, DotCursor, DotWrapperWithDots } from '@/services/dots/Types' diff --git a/src/contexts/paging/EventArchivePaging.tsx b/src/contexts/paging/EventArchivePaging.tsx index 7b4e5246b..3fe4c7199 100644 --- a/src/contexts/paging/EventArchivePaging.tsx +++ b/src/contexts/paging/EventArchivePaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readArchivedEventsPageAction } from '@/actions/events/read' +import { readArchivedEventsPageAction } from '@/services/events/actions' import type { EventArchiveCursor, EventArchiveDetails, EventExpanded } from '@/services/events/Types' import type { ReadPageInput } from '@/lib/paging/Types' diff --git a/src/contexts/paging/EventRegistrationDetailedPaging.tsx b/src/contexts/paging/EventRegistrationDetailedPaging.tsx index d078b55be..12b39c0ca 100644 --- a/src/contexts/paging/EventRegistrationDetailedPaging.tsx +++ b/src/contexts/paging/EventRegistrationDetailedPaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { eventRegistrationReadManyDetailedAction } from '@/actions/events/registration' +import { eventRegistrationReadManyDetailedAction } from '@/services/events/registration/actions' import type { EventRegistrationDetailedExpanded, EventRegistrationFetcherDetails diff --git a/src/contexts/paging/EventRegistrationPaging.tsx b/src/contexts/paging/EventRegistrationPaging.tsx index e19fc4a4d..65f09f70e 100644 --- a/src/contexts/paging/EventRegistrationPaging.tsx +++ b/src/contexts/paging/EventRegistrationPaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readManyEventRegistrationAction } from '@/actions/events/registration' +import { readManyEventRegistrationAction } from '@/services/events/registration/actions' import type { EventRegistrationExpanded, EventRegistrationFetcherDetails } from '@/services/events/registration/Types' import type { PageSizeUsers } from './UserPaging' import type { ReadPageInput } from '@/lib/paging/Types' diff --git a/src/contexts/paging/ImageCollectionPaging.tsx b/src/contexts/paging/ImageCollectionPaging.tsx index 10fbd2432..717ab57da 100644 --- a/src/contexts/paging/ImageCollectionPaging.tsx +++ b/src/contexts/paging/ImageCollectionPaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readImageCollectionsPageAction } from '@/actions/images/collections/read' +import { readImageCollectionsPageAction } from '@/services/images/collections/actions' import type { ReadPageInput } from '@/lib/paging/Types' import type { ImageCollectionCursor, ImageCollectionPageReturn } from '@/services/images/collections/Types' diff --git a/src/contexts/paging/ImagePaging.tsx b/src/contexts/paging/ImagePaging.tsx index 90a30d73e..c66d7c20f 100644 --- a/src/contexts/paging/ImagePaging.tsx +++ b/src/contexts/paging/ImagePaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readImagesPageAction } from '@/actions/images/read' +import { readImagesPageAction } from '@/services/images/actions' import type { ReadPageInput } from '@/lib/paging/Types' import type { Image } from '@prisma/client' import type { ImageCursor, ImageDetails } from '@/services/images/Types' diff --git a/src/contexts/paging/JobAdInactivePaging.tsx b/src/contexts/paging/JobAdInactivePaging.tsx index 8f99d9879..4fbce7438 100644 --- a/src/contexts/paging/JobAdInactivePaging.tsx +++ b/src/contexts/paging/JobAdInactivePaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readInactiveJobAdsPageAction } from '@/actions/career/jobAds/read' +import { readInactiveJobAdsPageAction } from '@/services/career/jobAds/actions' import type { ReadPageInput } from '@/lib/paging/Types' import type { JobAdInactiveCursor, JobAdInactiveDetails, SimpleJobAd } from '@/services/career/jobAds/Types' diff --git a/src/contexts/paging/LockerPaging.tsx b/src/contexts/paging/LockerPaging.tsx index be4fb549e..1d628f77e 100644 --- a/src/contexts/paging/LockerPaging.tsx +++ b/src/contexts/paging/LockerPaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from '@/contexts/paging/PagingGenerator' -import { readLockerPageAction } from '@/actions/lockers/lockers' +import { readLockerPageAction } from '@/services/lockers/actions' import type { ReadPageInput } from '@/lib/paging/Types' import type { LockerCursor, LockerWithReservation } from '@/services/lockers/Types' diff --git a/src/contexts/paging/OldNewsPaging.tsx b/src/contexts/paging/OldNewsPaging.tsx index 668cf3fa6..55d740a79 100644 --- a/src/contexts/paging/OldNewsPaging.tsx +++ b/src/contexts/paging/OldNewsPaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readOldNewsPageAction } from '@/actions/news/read' +import { readOldNewsPageAction } from '@/services/news/actions' import type { ReadPageInput } from '@/lib/paging/Types' import type { NewsCursor, SimpleNewsArticle } from '@/services/news/Types' diff --git a/src/contexts/paging/OmegaquotesPaging.tsx b/src/contexts/paging/OmegaquotesPaging.tsx index 78b665618..ee2c64a25 100644 --- a/src/contexts/paging/OmegaquotesPaging.tsx +++ b/src/contexts/paging/OmegaquotesPaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from '@/contexts/paging/PagingGenerator' -import { readQuotesPageAction } from '@/actions/omegaquotes/read' +import { readQuotesPageAction } from '@/services/omegaquotes/actions' import type { ReadPageInput } from '@/lib/paging/Types' import type { OmegaquoteCursor, OmegaquoteFiltered } from '@/services/omegaquotes/Types' diff --git a/src/contexts/paging/SchoolPaging.tsx b/src/contexts/paging/SchoolPaging.tsx index 083e62ce4..5c6b40897 100644 --- a/src/contexts/paging/SchoolPaging.tsx +++ b/src/contexts/paging/SchoolPaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readSchoolsPageAction } from '@/education/schools/read' +import { readSchoolsPageAction } from '@/education/schools/actions' import type { ReadPageInput } from '@/lib/paging/Types' import type { ExpandedSchool, SchoolCursor } from '@/education/schools/Types' diff --git a/src/contexts/paging/UserPaging.tsx b/src/contexts/paging/UserPaging.tsx index 38e322e66..23abc4a8f 100644 --- a/src/contexts/paging/UserPaging.tsx +++ b/src/contexts/paging/UserPaging.tsx @@ -1,6 +1,6 @@ 'use client' import generatePagingProvider, { generatePagingContext } from './PagingGenerator' -import { readUserPageAction } from '@/actions/users/read' +import { readUserPageAction } from '@/services/users/actions' import type { ReadPageInput } from '@/lib/paging/Types' import type { UserDetails, UserPagingReturn, UserCursor } from '@/services/users/Types' diff --git a/src/services/cms/images/actions.ts b/src/services/cms/images/actions.ts index 91a7ef8a5..08f701534 100644 --- a/src/services/cms/images/actions.ts +++ b/src/services/cms/images/actions.ts @@ -4,20 +4,13 @@ import { createActionError, createZodActionError, safeServerCall } from '@/servi import { createCmsImage } from '@/services/cms/images/create' import { readCmsImage, readSpecialCmsImage } from '@/services/cms/images/read' import { updateCmsImage, updateCmsImageConfig } from '@/services/cms/images/update' -import { baseCmsImageValidation } from '@/services/cms/images/validation' +import { createCmsImageActionValidation } from '@/services/cms/images/validation' import { SpecialCmsImage } from '@prisma/client' -import type { ValidationTypes } from '@/services/Validation' +import type { CreateCmsImageActionTypes } from '@/services/cms/images/validation' import type { ExpandedCmsImage } from '@/services/cms/images/Types' import type { ActionReturn } from '@/services/actionTypes' import type { CmsImage, Image, ImageSize } from '@prisma/client' -export const createCmsImageActionValidation = baseCmsImageValidation.createValidation({ - keys: ['name'], - transformer: data => data, -}) - -export type CreateCmsImageActionTypes = ValidationTypes - export async function createCmsImageAction( rawData: FormData | CreateCmsImageActionTypes['Type'], image?: Image, diff --git a/src/services/cms/images/validation.ts b/src/services/cms/images/validation.ts index 30f4fc6e9..eb2ac266a 100644 --- a/src/services/cms/images/validation.ts +++ b/src/services/cms/images/validation.ts @@ -20,3 +20,10 @@ export const createCmsImageValidation = baseCmsImageValidation.createValidation( }) export type CreateCmsImageTypes = ValidationTypes + +export const createCmsImageActionValidation = baseCmsImageValidation.createValidation({ + keys: ['name'], + transformer: data => data, +}) + +export type CreateCmsImageActionTypes = ValidationTypes diff --git a/src/services/cms/paragraphs/actions.ts b/src/services/cms/paragraphs/actions.ts index 5cfdfa1ec..ab6ba0dad 100644 --- a/src/services/cms/paragraphs/actions.ts +++ b/src/services/cms/paragraphs/actions.ts @@ -4,19 +4,12 @@ import { createActionError, createZodActionError, safeServerCall } from '@/servi import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { readCmsParagraph, readSpecialCmsParagraph } from '@/services/cms/paragraphs/read' import { updateCmsParagraphContents } from '@/services/cms/paragraphs/update' -import { baseCmsParagraphValidation } from '@/services/cms/paragraphs/validation' +import { createCmsParagraphActionValidation } from '@/services/cms/paragraphs/validation' import { SpecialCmsParagraph } from '@prisma/client' -import type { ValidationTypes } from '@/services/Validation' +import type { CreateCmsParagraphActionTypes } from '@/services/cms/paragraphs/validation' import type { ActionReturn } from '@/services/actionTypes' import type { CmsParagraph } from '@prisma/client' -export const createCmsParagraphActionValidation = baseCmsParagraphValidation.createValidation({ - keys: ['name'], - transformer: data => data -}) - -export type CreateCmsParagraphActionTypes = ValidationTypes - export async function createCmsParagraphAction( rawData: FormData | CreateCmsParagraphActionTypes['Type'] ): Promise> { diff --git a/src/services/cms/paragraphs/validation.ts b/src/services/cms/paragraphs/validation.ts index 82406a9f8..e1bcc8c27 100644 --- a/src/services/cms/paragraphs/validation.ts +++ b/src/services/cms/paragraphs/validation.ts @@ -20,3 +20,10 @@ export const createCmsParagraphValidation = baseCmsParagraphValidation.createVal }) export type CreateCmsParagraphTypes = ValidationTypes + +export const createCmsParagraphActionValidation = baseCmsParagraphValidation.createValidation({ + keys: ['name'], + transformer: data => data +}) + +export type CreateCmsParagraphActionTypes = ValidationTypes diff --git a/src/services/visibility/Types.ts b/src/services/visibility/Types.ts index 04aac260a..61ddce2b7 100644 --- a/src/services/visibility/Types.ts +++ b/src/services/visibility/Types.ts @@ -1,3 +1,4 @@ +import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' import type { Matrix } from '@/utils/checkMatrix' import type { Permission, VisibilityPurpose } from '@prisma/client' @@ -28,3 +29,27 @@ export type VisibilityCollapsed = { regular: Permission | null, admin: Permission | null }) + +export type VisibilityRequiermentForAdmin = { + name: string + groups: (ExpandedGroup & { + selected: boolean + })[] +} + +export type VisibilityStructuredForAdmin = { + published: boolean + purpose: string +} & ( + { + type: 'REGULAR' + groups: GroupsStructured + regular: VisibilityRequiermentForAdmin[] + admin: VisibilityRequiermentForAdmin[] + } | { + type: 'SPECIAL' + message: string + regular: string + admin: string + } +) diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index ea4433301..d3ba99af7 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -9,33 +9,14 @@ import { PurposeTextsConfig } from '@/services/visibility/ConfigVars' import { readVisibilityCollapsed } from '@/services/visibility/read' import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' import type { ActionReturn } from '@/services/actionTypes' -import type { GroupMatrix, VisibilityLevelType } from '@/services/visibility/Types' +import type { + GroupMatrix, + VisibilityLevelType, + VisibilityRequiermentForAdmin, + VisibilityStructuredForAdmin +} from '@/services/visibility/Types' import type { GroupType } from '@prisma/client' -export type VisibilityRequiermentForAdmin = { - name: string - groups: (ExpandedGroup & { - selected: boolean - })[] -} - -export type VisibilityStructuredForAdmin = { - published: boolean - purpose: string -} & ( - { - type: 'REGULAR' - groups: GroupsStructured - regular: VisibilityRequiermentForAdmin[] - admin: VisibilityRequiermentForAdmin[] - } | { - type: 'SPECIAL' - message: string - regular: string - admin: string - } -) - export async function readVisibilityForAdminAction(id: number): Promise> { const [visibilityRes, groupsRes] = await Promise.all([ safeServerCall(() => readVisibilityCollapsed(id)), diff --git a/tsconfig.json b/tsconfig.json index 6995df053..94ef950b7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,18 +25,16 @@ "@/components/*": ["src/app/_components/*"], "@/UI/*": ["src/app/_components/UI/*"], "@/styles/*": ["src/styles/*"], - "@/images/*": ["src/actions/images/*"], - "@/actions/*": ["src/actions/*"], "@/prisma/*": ["src/prisma/*"], "@/contexts/*": ["src/contexts/*"], "@/hooks/*": ["src/hooks/*"], - "@/cms/*": ["src/app/_components/Cms/*", "src/actions/cms/*", "src/services/cms/*"], + "@/cms/*": ["src/app/_components/Cms/*", "src/services/cms/*"], "@/services/*": ["src/services/*"], "@/utils/*": ["src/utils/*"], "@/jwt/*": ["src/lib/jwt/*"], "@/api/*": ["src/app/api/*"], - "@/education/*": ["src/actions/education/*", "src/services/education/*", "src/app/education/*"], - "@/career/*": ["src/actions/career/*", "src/services/career/*", "src/app/career/*"], + "@/education/*": ["src/services/education/*", "src/app/education/*"], + "@/career/*": ["src/services/career/*", "src/app/career/*"], "@/prisma-dobbel-omega/*": ["node_modules/.prisma-dobbel-omega/*"], "@/seeder/*": ["src/prisma/seeder/*"], "@/*": ["./src/*"] From dfb05e63fae448b23127fb52dad3047098381b15 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 29 Aug 2025 22:03:42 +0200 Subject: [PATCH 11/24] refactor: service method simplification --- src/services/ServiceMethod.ts | 306 ++++++++++---------------- tests/services/service-method.test.ts | 94 ++++++++ 2 files changed, 215 insertions(+), 185 deletions(-) create mode 100644 tests/services/service-method.test.ts diff --git a/src/services/ServiceMethod.ts b/src/services/ServiceMethod.ts index 0000881f1..e4e89d3cf 100644 --- a/src/services/ServiceMethod.ts +++ b/src/services/ServiceMethod.ts @@ -1,11 +1,10 @@ import '@pn-server-only' +import { z } from 'zod' import { ParseError, Smorekopp } from './error' import { prismaErrorWrapper } from './prismaCall' import { default as globalPrisma } from '@/prisma' import { Session } from '@/auth/Session' -import { zfd } from 'zod-form-data' import { AsyncLocalStorage } from 'async_hooks' -import type { z } from 'zod' import type { Prisma, PrismaClient } from '@prisma/client' import type { SessionMaybeUser } from '@/auth/Session' import type { AutherStaticFieldsBound } from '@/auth/auther/Auther' @@ -22,66 +21,37 @@ export type PrismaPossibleTransaction< > = OpensTransaction extends true ? PrismaClient : Prisma.TransactionClient /** - * Type for an object that contains params and data fields as long as thery are not undefined. - * For example, if Params is undefined and Data is not, the type will be { data: Data }. - * Conversely, if Data is undefined and Params is not, the type will be { params: Params }. - * If both are undefined, the type will be object. - * This is used to make the type of the arguments of a service method align with whether - * or not the underlying method expects params/data or not. + * The type used internally by Zod to represent a tuple of schemas. */ -export type ServiceMethodParamsData< - ParamsSchema extends z.ZodTypeAny | undefined, - DataSchema extends z.ZodTypeAny | undefined, - SchemaType extends 'INFERRED' | 'INPUT' -> = ( - ParamsSchema extends undefined ? object : { - params: SchemaType extends 'INFERRED' ? z.infer> : z.input> - } -) & ( - DataSchema extends undefined ? object : { - data: SchemaType extends 'INFERRED' ? z.infer> : z.input> - } -) +export type SchemaTuple = [z.ZodTypeAny, ...z.ZodTypeAny[]] | [] -// TODO: Refactor into maybe one type? Or maybe something more concise? -export type ServiceMethodParamsDataUnsafe = { - params?: unknown, - data?: unknown, -} +/** + * Helper type to infer the input types of a tuple of schemas. + */ +export type InputSchemaTuple = z.input> /** - * This is the type for the arguments that are passed to the method implementation of a service method. + * Helper type to infer the output types of a tuple of schemas. */ -export type ServiceMethodArguments< - OpensTransaction extends boolean, - ParamsSchema extends z.ZodTypeAny | undefined, - DataSchema extends z.ZodTypeAny | undefined, -> = { - prisma: PrismaPossibleTransaction, - session: SessionMaybeUser, -} & ServiceMethodParamsData +export type OutputSchemaTuple = z.infer> /** - * This is the type for the argument that are passed to the execute method of a service method. + * The input arguments for a service method function. + * These are the arguments passed by the caller of the service method. */ -export type ServiceMethodExecuteArgs< - ParamsSchema extends z.ZodTypeAny | undefined, - DataSchema extends z.ZodTypeAny | undefined, +export type ServiceMethodInputArgs< OpensTransaction extends boolean, -> = { - session?: SessionMaybeUser | null, - prisma?: PrismaPossibleTransaction, - bypassAuth?: boolean, -} & ServiceMethodParamsData + Schemas extends SchemaTuple, +> = [...InputSchemaTuple, Partial>?] /** - * This is the type for the argument that are passed to the execute method of a service method. + * The output arguments for a service method function. + * These are the arguments passed to the author and the method internally. */ -export type ServiceMethodExecuteArgsUnsafe = { - session?: SessionMaybeUser | null, - prisma?: PrismaPossibleTransaction, - bypassAuth?: boolean, -} & ServiceMethodParamsDataUnsafe +export type ServiceMethodOutputArgs< + OpensTransaction extends boolean, + Schemas extends SchemaTuple, +> = [...OutputSchemaTuple, ServiceMethodContext] /** * This is the type for the configuration of a service method. @@ -91,163 +61,133 @@ export type ServiceMethodConfig< DynamicFields extends object, OpensTransaction extends boolean, Return, - ParamsSchema extends z.ZodTypeAny | undefined, - DataSchema extends z.ZodTypeAny | undefined, + Schemas extends SchemaTuple, > = { - paramsSchema?: ParamsSchema, - dataSchema?: DataSchema, + schemas?: Schemas, opensTransaction?: OpensTransaction, - auther: ( - paramsData: ServiceMethodParamsData + auther?: ( + ...args: ServiceMethodOutputArgs ) => // Todo: Make prettier type for returntype of dynamic fields | ReturnType['dynamicFields']> | Promise['dynamicFields']>>, method: ( - args: ServiceMethodArguments + ...args: ServiceMethodOutputArgs ) => Return | Promise, } /** - * This is the return type of the ServiceMethod function. It contains a client function that can be used - * to pass a specific prisma client to the service method, and a newClient function that can be used to - * pass the global prisma client to the service method. - * - * TypeScript is smart enough to infer the behaviour of the return functons without the need to excplitly - * type the return type of the ServiceMethod function, but it is done so for the sake of clarity. + * The return type of the ServiceMethod function. + * It is a function that takes the data arguments and an optional context argument. */ export type ServiceMethodType< OpensTransaction extends boolean, Return, - ParamsSchema extends z.ZodTypeAny | undefined, - DataSchema extends z.ZodTypeAny | undefined, + Schemas extends SchemaTuple, > = { - (args: ServiceMethodExecuteArgs): Promise, - /** - * Pass a specific prisma client to the service method. Usefull when using the service method inside a transaction. - * @note - * @param client - */ - client: (client: PrismaPossibleTransaction) => { - execute: (args: ServiceMethodExecuteArgs) => Promise, - executeUnsafe: (args: ServiceMethodExecuteArgsUnsafe) => Promise, - }, - /** - * Use the global prisma client for the service method. - */ - newClient: () => ( - ReturnType< - ServiceMethodType['client'] - > - ), - paramsSchema?: ParamsSchema, - dataSchema?: DataSchema, + (...args: ServiceMethodInputArgs): Promise, + schemas?: Schemas, } -export type Context = { prisma: PrismaClient | Prisma.TransactionClient, session: SessionMaybeUser | null } +/** + * In addition to custom data arguments, every service method receives a context object. + */ +export type ServiceMethodContext = { + prisma: PrismaPossibleTransaction, + session: SessionMaybeUser, + bypassAuth: boolean, +} -const asyncLocalStorage = new AsyncLocalStorage() +/** + * Async local storage is used to store the context of the current service method call. + * All service methods called within the context of another service method will + * inherit the context of the parent service method, unless explicitly overridden. + * + * Read more about async local storage here: https://nodejs.org/api/async_context.html + */ +const asyncLocalStorage = new AsyncLocalStorage() -function withContext(defaultContext: Partial, callback: (context: Context) => T): T { - const context = asyncLocalStorage.getStore() ?? { - prisma: defaultContext.prisma ?? globalPrisma, - session: defaultContext.session ?? null - } +/** + * Runs a callback with a specific service method context. + * + * @param contextOverride Partial context to override the current context with. + * @param callback The callback to run with the context. + * @returns The return value of the callback. + */ +function withContext(contextOverride: Partial, callback: (context: ServiceMethodContext) => T): T { + const localContext = asyncLocalStorage.getStore(); + + const context: ServiceMethodContext = { + prisma: contextOverride.prisma ?? localContext?.prisma ?? globalPrisma, + session: contextOverride.session ?? localContext?.session ?? Session.empty(), + bypassAuth: contextOverride.bypassAuth ?? localContext?.bypassAuth ?? false, + }; + return asyncLocalStorage.run(context, () => callback(context)) } /** * Wrapper for creating service methods. It handles validation, authorization, and errors for you. * - * Whether or not a service method expects params and/or data is inferred from the configuration. - * If paramsSchema is defined, the service method expects params. - * If dataValidation is defined, the service method expects data. - * * @param config - The configuration for the service method. - * @param config.auther - The auther that will be used to authorize the user. - * @param config.dynamicAuthFields - A function that returns the dynamic auth fields that will be used to authorize the user. + * @param config.auther - A function which returns the auther that will be used to authorize the user. * @param config.method - The method that will be called when the service method is executed. - * @param config.paramsSchema - The zod schema that will be used to validate the params that is passed to the service method. - * @param config.dataSchema - The zod schema that will be used to validate the data that is passed to the service method. - * @param [config.opensTransaction=false] - Whether or not the service method opens a transaction. (Just for correct typing) + * @param config.schemas - An array of zod schemas that will be used to validate the arguments that are passed to the service method. + * @param [config.opensTransaction=false] - Whether or not the service method opens a transaction. Determines the type of prisma client that is passed to the service method. */ export function ServiceMethod< DynamicFields extends object, OpensTransaction extends boolean, Return, - ParamsSchema extends z.ZodTypeAny | undefined = undefined, - DataSchema extends z.ZodTypeAny | undefined = undefined, + Schemas extends SchemaTuple = [], >( - config: ServiceMethodConfig, -): ServiceMethodType { - // Simple utility function to check if the expected arguments are present. - // I.e. if the params/data are present when they should be and vice versa. - // This is needed to help typescript infer the correct types for the arguments. - const expectedArgsArePresent = ( - args: ServiceMethodExecuteArgsUnsafe - ): args is ServiceMethodExecuteArgs => { - const paramsMatch = Boolean(args.params) === Boolean(config.paramsSchema) - const dataMatches = Boolean(args.data) === Boolean(config.dataSchema) - return paramsMatch && dataMatches - } + config: ServiceMethodConfig, +): ServiceMethodType { + // Create a tuple schema from the array of schemas. + // This allows us to parse all the data arguments at once. + const schema = z.tuple(config.schemas ?? [] as Schemas) + const expectedDataArgCount = config.schemas?.length ?? 0 + + // Parses the data arguments using the provided schemas. + const parseData = (data: unknown[]) => { + // We expect as many data arguments as there are schemas. + if (data.length !== expectedDataArgCount) { + throw new Smorekopp( + 'BAD DATA', + `Service method expected ${expectedDataArgCount} data arguments, but got ${data.length}.`, + ) + } + // Do the actual parsing. + const parsedData = schema.safeParse(data) + if (!parsedData.success) { + throw new ParseError(parsedData) + } + return parsedData.data + } + // Guard to check if the prisma client can be used for this service method. const isAppropriateClient = ( prisma: PrismaClient | Prisma.TransactionClient ): prisma is PrismaPossibleTransaction => !config.opensTransaction || '$transaction' in prisma - async function executeUnsafe(args: ServiceMethodExecuteArgsUnsafe) { - // First, validate parameters (if any). - if (args.params) { - if (!config.paramsSchema) { - throw new Smorekopp( - 'BAD PARAMETERS', - 'Service method recieved params, but has no params schema.', - ) - } - - // TODO: Decide if this should be a validation or a schema. - // For now it's just a schema because it's simpler. - const paramsParse = config.paramsSchema.safeParse(args.params) - - if (!paramsParse.success) { - // TODO: This needs to be returned to give good error message. - throw new Smorekopp( - 'BAD PARAMETERS', - 'Invalid params passed to service method.', - ) - } - - args.params = paramsParse.data - } - - // Then, validate data (if any). - if (args.data) { - if (!config.dataSchema) { - throw new Smorekopp( - 'BAD DATA', - 'Service method recieved data, but has no dataValidation or dataSchema.', - ) - } - const parse = zfd.formData(config.dataSchema).safeParse(args.data) - if (!parse.success) { - throw new ParseError(parse) - } - args.data = parse.data - } - - // Then, determine if the correct properties are present. - // This gives the correct type for "args" if the check succeeds. - if (!expectedArgsArePresent(args)) { - throw new Smorekopp( - 'SERVER ERROR', - 'Service method recieved invalid arguments.', - ) - } - - return withContext({ prisma: args.prisma, session: args.session }, async ({ prisma, session }) => { - session ??= Session.empty() - + // Wraps the execution of the method with parsing, authorization, and context handling. + async function execute(...args: ServiceMethodInputArgs) { + // First, split the arguments into data and context. + // There should always be at as many arguments as there are schemas. + const dataArgs = args.slice(0, expectedDataArgCount) + // There may also be one additional argument for overriding the context. + // NOTE: TypeScript thinks this is "{}" for some reason, but this works so it's fine I guess? + const contextArg = args[expectedDataArgCount] ?? {} + + // Second, parse the data arguments. + // This function will throw if the data is invalid. + const parsedData = parseData(dataArgs) + + // Third, get the context (which includes the prisma client, the session and the bypassAuth flag). + // If a context override is provided, use it. Otherwise, use the context from the async local storage. + // If there is no context in the async local storage, use global defaults. + return withContext(contextArg, async context => { if (!isAppropriateClient(prisma)) { throw new Smorekopp( 'SERVER ERROR', @@ -257,8 +197,16 @@ export function ServiceMethod< // Then, authorize user. // This has to be done after the validation because the auther might use the data to authorize the user. - if (!args.bypassAuth) { - const authRes = (await config.auther(args)).auth(session) + if (!context.bypassAuth) { + if (!config.auther) { + throw new Smorekopp( + 'UNAUTHENTICATED', + 'This service method is not externally by users.' + ) + } + + const auther = await config.auther(...parsedData, context) + const authRes = auther.auth(context.session) if (!authRes.authorized) { throw new Smorekopp(authRes.status, authRes.getErrorMessage) @@ -266,24 +214,12 @@ export function ServiceMethod< } // Finally, call the method. - return prismaErrorWrapper(() => config.method({ - ...args, - prisma, - session, - })) + return prismaErrorWrapper(() => config.method(...parsedData, context)) }) } - // Add the old api interface for backwards compatibility. - executeUnsafe.client = (prisma: PrismaPossibleTransaction) => ({ - executeUnsafe: (args: ServiceMethodExecuteArgsUnsafe) => - executeUnsafe({ prisma, ...args }), - execute: (args: ServiceMethodExecuteArgs) => - executeUnsafe({ prisma, ...args }), - }) - executeUnsafe.newClient = () => executeUnsafe.client(globalPrisma) - executeUnsafe.dataSchema = config.dataSchema - executeUnsafe.paramsSchema = config.paramsSchema + // Attach the schemas to the execute function for introspection purposes + execute.schemas = config.schemas - return executeUnsafe + return execute } diff --git a/tests/services/service-method.test.ts b/tests/services/service-method.test.ts new file mode 100644 index 000000000..0416ae528 --- /dev/null +++ b/tests/services/service-method.test.ts @@ -0,0 +1,94 @@ +import { RequireNothing } from "@/auth/auther/RequireNothing"; +import { RequireServerOnly } from "@/auth/auther/ServerOnly"; +import { Session } from "@/auth/Session"; +import { ServiceMethod, ServiceMethodContext } from "@/services/ServiceMethod"; +import { describe } from "@jest/globals"; +import { z } from "zod"; +import { default as globalPrisma } from "@/prisma"; + +describe('service method', () => { + describe('simple', () => { + const addPositiveOnly = ServiceMethod({ + auther: (a, b) => { + if (a < 0 || b < 0) { + return RequireServerOnly.staticFields({}).dynamicFields({}) + } + + return RequireNothing.staticFields({}).dynamicFields({}) + }, + schemas: [z.number(), z.number()], + method: (a, b) => a + b, + }) + + test('method result', async () => { + const res = await addPositiveOnly(1, 2) + + expect(res).toBe(3) + }) + + test('auth fail', async () => { + await expect(addPositiveOnly(-1, 2)).rejects.toThrow() + }) + + test('bypass auth', async () => { + const res = await addPositiveOnly(-1, 2, { bypassAuth: true }) + + expect(res).toBe(1) + }) + }) + + describe('nested', () => { + // Simple service method that just returns its own context + const inner = ServiceMethod({ + auther: () => RequireNothing.staticFields({}).dynamicFields({}), + method: async (context) => context, + }) + + // Outer service method that calls the inner one and returns its context + const outer = ServiceMethod({ + auther: () => RequireNothing.staticFields({}).dynamicFields({}), + method: async () => await inner(), + }) + + test('nested context global defaults', async () => { + const res = await outer() + + expect(res.bypassAuth).toBe(false) + expect(res.session).toBeInstanceOf(Session) + expect(res.prisma).toBe(globalPrisma) + }) + + test('nested context override bypassAuth', async () => { + const res = await outer({ bypassAuth: true }) + + expect(res.bypassAuth).toBe(true) + expect(res.session).toBeInstanceOf(Session) + expect(res.prisma).toBe(globalPrisma) + }) + + test('nested context override session', async () => { + const customSession = Session.fromJsObject({ + apiKeyId: 1919, + memberships: [], + permissions: [], + user: null, + }) + + const res = await outer({ session: customSession }) + + expect(res.bypassAuth).toBe(false) + expect(res.session).toBe(customSession) + expect(res.prisma).toBe(globalPrisma) + }) + + test('nested context override prisma', async () => { + await globalPrisma.$transaction(async (tx) => { + const res = await outer({ prisma: tx }) + + expect(res.bypassAuth).toBe(false) + expect(res.session).toBeInstanceOf(Session) + expect(res.prisma).toBe(tx) + }) + }) + }) +}) \ No newline at end of file From 8c2f440789d7a2db32e524e8d991818659945801 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sun, 21 Sep 2025 15:55:14 +0200 Subject: [PATCH 12/24] refactor: revert back to data and params --- src/services/ServiceMethod.ts | 246 ++++++++++++++++++++-------------- 1 file changed, 144 insertions(+), 102 deletions(-) diff --git a/src/services/ServiceMethod.ts b/src/services/ServiceMethod.ts index e4e89d3cf..52c27c621 100644 --- a/src/services/ServiceMethod.ts +++ b/src/services/ServiceMethod.ts @@ -1,10 +1,11 @@ import '@pn-server-only' -import { z } from 'zod' import { ParseError, Smorekopp } from './error' import { prismaErrorWrapper } from './prismaCall' import { default as globalPrisma } from '@/prisma' import { Session } from '@/auth/Session' +import { zfd } from 'zod-form-data' import { AsyncLocalStorage } from 'async_hooks' +import type { z } from 'zod' import type { Prisma, PrismaClient } from '@prisma/client' import type { SessionMaybeUser } from '@/auth/Session' import type { AutherStaticFieldsBound } from '@/auth/auther/Auther' @@ -16,82 +17,104 @@ import type { AutherStaticFieldsBound } from '@/auth/auther/Auther' * The caveat is that a Prisma.TransactionClient can't be used to open a new transaction * so if the service method opens a transaction, the prisma client can only be a PrismaClient. */ -export type PrismaPossibleTransaction< +type PrismaPossibleTransaction< OpensTransaction extends boolean > = OpensTransaction extends true ? PrismaClient : Prisma.TransactionClient /** - * The type used internally by Zod to represent a tuple of schemas. + * Utility type that remove all properties of type `never`. */ -export type SchemaTuple = [z.ZodTypeAny, ...z.ZodTypeAny[]] | [] - -/** - * Helper type to infer the input types of a tuple of schemas. - */ -export type InputSchemaTuple = z.input> +type HideNever = { + [K in keyof T as T[K] extends never ? never : K]: T[K] +} /** - * Helper type to infer the output types of a tuple of schemas. + * The input type which should will be passed to the service method. + * This is what the zod schemas will parse. */ -export type OutputSchemaTuple = z.infer> +export type ServiceMethodInputUnparsed< + ParamsSchema extends z.ZodTypeAny | undefined, + DataSchema extends z.ZodTypeAny | undefined, +> = HideNever<{ + params: z.input>, + data: z.input>, +}> /** - * The input arguments for a service method function. - * These are the arguments passed by the caller of the service method. + * The input that is provided to the a service method implementation. + * This is the the input after is has been parsed with zod. */ -export type ServiceMethodInputArgs< - OpensTransaction extends boolean, - Schemas extends SchemaTuple, -> = [...InputSchemaTuple, Partial>?] +export type ServiceMethodInputParsed< + ParamsSchema extends z.ZodTypeAny | undefined, + DataSchema extends z.ZodTypeAny | undefined, +> = HideNever<{ + params: z.infer>, + data: z.infer>, +}> /** - * The output arguments for a service method function. - * These are the arguments passed to the author and the method internally. + * This is the actual input type for the service method function used under the hood + * since the input can be from the client we can't guarantee type safety. */ -export type ServiceMethodOutputArgs< - OpensTransaction extends boolean, - Schemas extends SchemaTuple, -> = [...OutputSchemaTuple, ServiceMethodContext] +export type ServiceMethodInputUnchecked = { + params?: unknown, + data?: unknown, +} /** * This is the type for the configuration of a service method. * I.e. what is passed to the ServiceMethod function when creating a service method. */ -export type ServiceMethodConfig< +type ServiceMethodConfig< DynamicFields extends object, OpensTransaction extends boolean, Return, - Schemas extends SchemaTuple, + ParamsSchema extends z.ZodTypeAny | undefined, + DataSchema extends z.ZodTypeAny | undefined, > = { - schemas?: Schemas, + paramsSchema?: ParamsSchema, + dataSchema?: DataSchema, opensTransaction?: OpensTransaction, - auther?: ( - ...args: ServiceMethodOutputArgs - ) => // Todo: Make prettier type for returntype of dynamic fields + authorizer?: (args: ServiceMethodInputParsed & ServiceMethodContext) => + // Todo: Make prettier type for return type of dynamic fields | ReturnType['dynamicFields']> | Promise['dynamicFields']>>, - method: ( - ...args: ServiceMethodOutputArgs - ) => Return | Promise, + method: (args: ServiceMethodInputParsed & ServiceMethodContext) => + Return | Promise, } /** - * The return type of the ServiceMethod function. - * It is a function that takes the data arguments and an optional context argument. + * The function signature for a service method. + * + * The generic `Checked` determines whether to use compile time type checking or not for the argument. + * + * The default is `CHECKED` which means that the arguments will have to match what the + * zod schemas expect to parse. + * + * Alternatively, `UNCHECKED` can be selected to forgo the TypeScript type checking. + * Importantly, this will not skip the runtime validation with zod. + * `UNCHECKED` is used when handling untyped input, e.g. from an HTTP request. */ -export type ServiceMethodType< +export type ServiceMethod< OpensTransaction extends boolean, Return, - Schemas extends SchemaTuple, + ParamsSchema extends z.ZodTypeAny | undefined, + DataSchema extends z.ZodTypeAny | undefined, > = { - (...args: ServiceMethodInputArgs): Promise, - schemas?: Schemas, + ( + args: ( + Checked extends 'CHECKED' + ? ServiceMethodInputUnparsed + : ServiceMethodInputUnchecked + ) & Partial> + ): Promise + paramsSchema?: ParamsSchema, + dataSchema?: DataSchema, } - /** * In addition to custom data arguments, every service method receives a context object. */ -export type ServiceMethodContext = { +type ServiceMethodContext = { prisma: PrismaPossibleTransaction, session: SessionMaybeUser, bypassAuth: boolean, @@ -99,29 +122,29 @@ export type ServiceMethodContext = { /** * Async local storage is used to store the context of the current service method call. - * All service methods called within the context of another service method will + * All service methods called within the context of another service method will * inherit the context of the parent service method, unless explicitly overridden. - * + * * Read more about async local storage here: https://nodejs.org/api/async_context.html */ const asyncLocalStorage = new AsyncLocalStorage() /** * Runs a callback with a specific service method context. - * + * * @param contextOverride Partial context to override the current context with. * @param callback The callback to run with the context. * @returns The return value of the callback. */ function withContext(contextOverride: Partial, callback: (context: ServiceMethodContext) => T): T { - const localContext = asyncLocalStorage.getStore(); + const localContext = asyncLocalStorage.getStore() const context: ServiceMethodContext = { - prisma: contextOverride.prisma ?? localContext?.prisma ?? globalPrisma, - session: contextOverride.session ?? localContext?.session ?? Session.empty(), + prisma: contextOverride.prisma ?? localContext?.prisma ?? globalPrisma, + session: contextOverride.session ?? localContext?.session ?? Session.empty(), bypassAuth: contextOverride.bypassAuth ?? localContext?.bypassAuth ?? false, - }; - + } + return asyncLocalStorage.run(context, () => callback(context)) } @@ -129,42 +152,30 @@ function withContext(contextOverride: Partial, callback * Wrapper for creating service methods. It handles validation, authorization, and errors for you. * * @param config - The configuration for the service method. - * @param config.auther - A function which returns the auther that will be used to authorize the user. + * @param config.authorizer - A function which returns the authorizer that will be used to authorize the user. + * @param config.paramsSchema - The zod schemas that will be used to validate the parameters which are passed. + * @param config.dataSchema - The zod schemas that will be used to validate the data which is passed. * @param config.method - The method that will be called when the service method is executed. - * @param config.schemas - An array of zod schemas that will be used to validate the arguments that are passed to the service method. - * @param [config.opensTransaction=false] - Whether or not the service method opens a transaction. Determines the type of prisma client that is passed to the service method. + * @param [config.opensTransaction=false] - Determines the type of prisma client that is passed to the service method. */ -export function ServiceMethod< +export function serviceMethod< DynamicFields extends object, OpensTransaction extends boolean, Return, - Schemas extends SchemaTuple = [], + ParamsSchema extends z.ZodTypeAny | undefined = undefined, + DataSchema extends z.ZodTypeAny | undefined = undefined, >( - config: ServiceMethodConfig, -): ServiceMethodType { - // Create a tuple schema from the array of schemas. - // This allows us to parse all the data arguments at once. - const schema = z.tuple(config.schemas ?? [] as Schemas) - const expectedDataArgCount = config.schemas?.length ?? 0 - - // Parses the data arguments using the provided schemas. - const parseData = (data: unknown[]) => { - // We expect as many data arguments as there are schemas. - if (data.length !== expectedDataArgCount) { - throw new Smorekopp( - 'BAD DATA', - `Service method expected ${expectedDataArgCount} data arguments, but got ${data.length}.`, - ) - } - - // Do the actual parsing. - const parsedData = schema.safeParse(data) - if (!parsedData.success) { - throw new ParseError(parsedData) - } - return parsedData.data + config: ServiceMethodConfig, +): ServiceMethod { + // Guard to check if params and data are only present if there are corresponding schemas. + const expectedInputsIsPresent = ( + input: ServiceMethodInputUnchecked + ): input is ServiceMethodInputParsed => { + const paramsMatch = (input.params !== undefined) === (config.paramsSchema !== undefined) + const dataMatches = (input.data !== undefined) === (config.dataSchema !== undefined) + return paramsMatch && dataMatches } - + // Guard to check if the prisma client can be used for this service method. const isAppropriateClient = ( prisma: PrismaClient | Prisma.TransactionClient @@ -172,22 +183,53 @@ export function ServiceMethod< !config.opensTransaction || '$transaction' in prisma // Wraps the execution of the method with parsing, authorization, and context handling. - async function execute(...args: ServiceMethodInputArgs) { - // First, split the arguments into data and context. - // There should always be at as many arguments as there are schemas. - const dataArgs = args.slice(0, expectedDataArgCount) - // There may also be one additional argument for overriding the context. - // NOTE: TypeScript thinks this is "{}" for some reason, but this works so it's fine I guess? - const contextArg = args[expectedDataArgCount] ?? {} - - // Second, parse the data arguments. - // This function will throw if the data is invalid. - const parsedData = parseData(dataArgs) - - // Third, get the context (which includes the prisma client, the session and the bypassAuth flag). + const execute = async ( + { params, data, ...context }: ServiceMethodInputUnchecked & Partial> + ) => { + const input = { params, data } + + // First, parse the provided params and data. + if (input.params) { + if (!config.paramsSchema) { + throw new Smorekopp( + 'BAD PARAMETERS', + 'Service method received params, but has no params schema.', + ) + } + const paramsParse = config.paramsSchema.safeParse(input.params) + if (!paramsParse.success) { + throw new Smorekopp( + 'BAD PARAMETERS', + 'Invalid params passed to service method.', + ) + } + input.params = paramsParse.data + } + + // Then, validate data (if any). + if (input.data) { + if (!config.dataSchema) { + throw new Smorekopp( + 'BAD DATA', + 'Service method received data, but has no dataValidation or dataSchema.', + ) + } + const parse = zfd.formData(config.dataSchema).safeParse(input.data) + if (!parse.success) { + console.log(parse.error) + throw new ParseError(parse) + } + input.data = parse.data + } + + if (!expectedInputsIsPresent(input)) { + throw new Smorekopp('SERVER ERROR', 'Service method received invalid input.') + } + + // Then, get the context (which includes the prisma client, the session and the bypassAuth flag). // If a context override is provided, use it. Otherwise, use the context from the async local storage. // If there is no context in the async local storage, use global defaults. - return withContext(contextArg, async context => { + return withContext(context, async ({ prisma, bypassAuth, session }) => { if (!isAppropriateClient(prisma)) { throw new Smorekopp( 'SERVER ERROR', @@ -196,30 +238,30 @@ export function ServiceMethod< } // Then, authorize user. - // This has to be done after the validation because the auther might use the data to authorize the user. - if (!context.bypassAuth) { - if (!config.auther) { + // This has to be done after the validation because the authorizer might use the data to authorize the user. + if (!bypassAuth) { + if (!config.authorizer) { throw new Smorekopp( 'UNAUTHENTICATED', - 'This service method is not externally by users.' + 'This service method is not externally callable.' ) } - const auther = await config.auther(...parsedData, context) - const authRes = auther.auth(context.session) + const authorizer = await config.authorizer({ ...input, prisma, bypassAuth, session }) + const authResult = authorizer.auth(session) - if (!authRes.authorized) { - throw new Smorekopp(authRes.status, authRes.getErrorMessage) + if (!authResult.authorized) { + throw new Smorekopp(authResult.status, authResult.getErrorMessage) } } // Finally, call the method. - return prismaErrorWrapper(() => config.method(...parsedData, context)) + return prismaErrorWrapper(() => config.method({ ...input, prisma, bypassAuth, session })) }) } - // Attach the schemas to the execute function for introspection purposes - execute.schemas = config.schemas + execute.paramsSchema = config.paramsSchema + execute.dataSchema = config.dataSchema return execute } From d5cf6668f6d432e547298fb50d7e85d1663e2ea8 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sun, 21 Sep 2025 15:56:00 +0200 Subject: [PATCH 13/24] refactor: rename ServiceMethod.ts to serviceMethods.ts --- src/services/{ServiceMethod.ts => serviceMethod.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/services/{ServiceMethod.ts => serviceMethod.ts} (100%) diff --git a/src/services/ServiceMethod.ts b/src/services/serviceMethod.ts similarity index 100% rename from src/services/ServiceMethod.ts rename to src/services/serviceMethod.ts From e691c54083a1846f581325797dcd8ed23a37ee37 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sun, 21 Sep 2025 15:56:41 +0200 Subject: [PATCH 14/24] refactor: apply service method name change to rest of project --- src/app/api/apiHandler.ts | 14 ++-- src/services/action.ts | 33 ++++---- src/services/admission/methods.ts | 10 +-- src/services/api-keys/methods.ts | 30 +++---- src/services/applications/methods.ts | 18 ++--- src/services/applications/periods/methods.ts | 30 +++---- src/services/auth/methods.ts | 18 ++--- src/services/cabin/booking/methods.ts | 46 +++++------ src/services/cabin/pricePeriod/methods.ts | 26 +++--- src/services/cabin/product/methods.ts | 22 +++--- src/services/cabin/releasePeriod/methods.ts | 22 +++--- src/services/career/companies/methods.ts | 18 ++--- src/services/career/jobAds/methods.ts | 26 +++--- src/services/cms/links/read.ts | 6 +- src/services/dots/methods.ts | 18 ++--- src/services/events/methods.ts | 29 ++++--- src/services/events/registration/methods.ts | 26 +++--- src/services/events/tags/methods.ts | 26 +++--- src/services/groups/committees/create.ts | 2 +- src/services/groups/committees/methods.ts | 26 +++--- src/services/groups/committees/update.ts | 2 +- src/services/groups/interestGroups/methods.ts | 22 +++--- src/services/groups/methods.ts | 38 ++++----- src/services/images/methods.ts | 34 ++++---- src/services/licenses/methods.ts | 18 ++--- src/services/lockers/locations/methods.ts | 10 +-- src/services/lockers/methods.ts | 14 ++-- src/services/lockers/reservations/methods.ts | 14 ++-- src/services/notifications/channel/methods.ts | 27 +++---- src/services/notifications/methods.ts | 12 +-- .../notifications/subscription/methods.ts | 20 ++--- src/services/permissions/methods.ts | 26 +++--- src/services/shop/product/methods.ts | 34 ++++---- src/services/shop/purchase/methods.ts | 6 +- src/services/shop/shop/methods.ts | 14 ++-- src/services/users/methods.ts | 59 +++++++------- src/services/visibility/actions.ts | 2 +- tests/services/service-method.test.ts | 79 ++++++++++++------- 38 files changed, 444 insertions(+), 433 deletions(-) diff --git a/src/app/api/apiHandler.ts b/src/app/api/apiHandler.ts index 134302858..8b8f9e3fb 100644 --- a/src/app/api/apiHandler.ts +++ b/src/app/api/apiHandler.ts @@ -2,21 +2,21 @@ import '@pn-server-only' import { Session } from '@/auth/Session' import { getHttpErrorCode, ServerError, Smorekopp } from '@/services/error' import type { ErrorCode, ErrorMessage } from '@/services/error' -import type { ServiceMethodExecuteArgs, ServiceMethodType } from '@/services/ServiceMethod' +import type { ServiceMethod } from '@/services/serviceMethod' import type { SessionNoUser } from '@/auth/Session' import type { z } from 'zod' type APIHandler< RawParams, Return, - ParamsSchema extends z.ZodTypeAny | undefined, - DataSchema extends z.ZodTypeAny | undefined, + ParamsSchema extends z.ZodTypeAny | undefined = undefined, + DataSchema extends z.ZodTypeAny | undefined = undefined, > = { - serviceMethod: ServiceMethodType, + serviceMethod: ServiceMethod, } & (ParamsSchema extends undefined ? { params?: undefined, } : { - params: (rawparams: RawParams) => z.input>, + params: (rawParams: RawParams) => z.input>, }) async function apiHandlerGeneric(req: Request, handle: (session: SessionNoUser) => Promise) { @@ -58,11 +58,11 @@ export function apiHandler< } } - return serviceMethod({ + return serviceMethod<'UNCHECKED'>({ params: params ? params(await rawParams) : undefined, data, session, - } as unknown as ServiceMethodExecuteArgs) + }) }) } diff --git a/src/services/action.ts b/src/services/action.ts index b10e3b1c9..9f9670281 100644 --- a/src/services/action.ts +++ b/src/services/action.ts @@ -1,27 +1,25 @@ import '@pn-server-only' import { safeServerCall } from './actionError' -import { Session } from '@/auth/Session' import type { ActionReturn } from './actionTypes' -import type { ServiceMethodExecuteArgs, ServiceMethodType } from '@/services/ServiceMethod' +import type { ServiceMethod } from '@/services/serviceMethod' import type { z } from 'zod' -// This function is overloaded to allow for different combinations of parameters and data. - export function action( - serviceMethod: ServiceMethodType + serviceMethod: ServiceMethod ): () => Promise> export function action( - serviceMethod: ServiceMethodType + serviceMethod: ServiceMethod ): (params: z.input) => Promise> -export function action( - serviceMethod: ServiceMethodType -): (data: z.input> | FormData) => Promise> +export function action( + serviceMethod: ServiceMethod +): (data: z.input | FormData) => Promise> -export function action( - serviceMethod: ServiceMethodType -): (params: z.input, data: z.input> | FormData) => Promise> +// This function is overloaded to allow for different combinations of parameters and data. +export function action( + serviceMethod: ServiceMethod +): (params: z.input, data: z.input | FormData) => Promise> /** * Turn a service method into suitable function for an action. @@ -32,9 +30,9 @@ export function action( - serviceMethod: ServiceMethodType + serviceMethod: ServiceMethod ) { // Letting the arguments to the actual function be unknown is safer as anything can be passed to it form the client. // The action and service method will validate the parameter and data before it is used. @@ -43,19 +41,16 @@ export function action< // has arguments witch match the underlying service method. This makes programming easier as Intellisense can // help and errors are caught at compile time. const actionUnsafe = async (params?: unknown, data?: unknown) => { - const session = await Session.fromNextAuth() - // Treat empty form data as undefined. This is required because the form component will always send // a FormData instance, even if no data is being sent. if (data instanceof FormData && data.entries().next().done) { data = undefined } - return safeServerCall(() => serviceMethod({ - session, + return safeServerCall(() => serviceMethod<'UNCHECKED'>({ params, data, - } as unknown as ServiceMethodExecuteArgs)) + })) } // If the service method has a params schema, we require the params to be passed to the action. diff --git a/src/services/admission/methods.ts b/src/services/admission/methods.ts index 05b0d1eb6..9643bb5f9 100644 --- a/src/services/admission/methods.ts +++ b/src/services/admission/methods.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { AdmissionSchemas } from './schemas' import { AdmissionAuthers } from './authers' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { updateUserOmegaMembershipGroup } from '@/services/groups/omegaMembershipGroups/update' import { UserConfig } from '@/services/users/config' import { Admission } from '@prisma/client' @@ -9,8 +9,8 @@ import { z } from 'zod' import type { ExpandedAdmissionTrail } from './Types' export namespace AdmissionMethods { - export const readTrial = ServiceMethod({ - auther: () => AdmissionAuthers.readTrial.dynamicFields({}), + export const readTrial = serviceMethod({ + authorizer: () => AdmissionAuthers.readTrial.dynamicFields({}), paramsSchema: z.object({ userId: z.number(), }), @@ -20,8 +20,8 @@ export namespace AdmissionMethods { } }) }) - export const createTrial = ServiceMethod({ - auther: () => AdmissionAuthers.createTrial.dynamicFields({}), + export const createTrial = serviceMethod({ + authorizer: () => AdmissionAuthers.createTrial.dynamicFields({}), paramsSchema: z.object({ admission: z.nativeEnum(Admission), }), diff --git a/src/services/api-keys/methods.ts b/src/services/api-keys/methods.ts index ab82861d0..05c1f0c8f 100644 --- a/src/services/api-keys/methods.ts +++ b/src/services/api-keys/methods.ts @@ -5,7 +5,7 @@ import { ApiKeySchemas } from './schemas' import { apiKeyHashAndEncrypt } from './hashEncryptKey' import { encodeApiKey } from './apiKeyEncoder' import { ServerError } from '@/services/error' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import logger from '@/lib/logger' import { z } from 'zod' import crypto from 'crypto' @@ -16,8 +16,8 @@ export namespace ApiKeyMethods { * Updates the active status of an api key if it has expired, i.e. if the expiresAt date is in the past. * This method is used when reading api keys to ensure that the active status is correct. */ - const updateIfExpired = ServiceMethod({ - auther: () => ApiKeyAuthers.updateIfExpired.dynamicFields({}), + const updateIfExpired = serviceMethod({ + authorizer: () => ApiKeyAuthers.updateIfExpired.dynamicFields({}), paramsSchema: z.object({ id: z.number(), expiresAt: z.date().nullable(), @@ -41,8 +41,8 @@ export namespace ApiKeyMethods { } } }) - export const create = ServiceMethod({ - auther: () => ApiKeyAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => ApiKeyAuthers.create.dynamicFields({}), dataSchema: ApiKeySchemas.create, method: async ({ prisma, data }): Promise => { const NODE_ENV = process.env.NODE_ENV @@ -62,8 +62,8 @@ export namespace ApiKeyMethods { return { ...apiKey, key: encodeApiKey({ key, id: apiKey.id }) } } }) - export const read = ServiceMethod({ - auther: () => ApiKeyAuthers.read.dynamicFields({}), + export const read = serviceMethod({ + authorizer: () => ApiKeyAuthers.read.dynamicFields({}), paramsSchema: z.union([z.object({ id: z.number() }), z.object({ name: z.string() })]), method: async ({ prisma, params }): Promise => { const apiKey = await prisma.apiKey.findUnique({ @@ -84,8 +84,8 @@ export namespace ApiKeyMethods { } } }) - export const readMany = ServiceMethod({ - auther: () => ApiKeyAuthers.readMany.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => ApiKeyAuthers.readMany.dynamicFields({}), method: async ({ prisma }): Promise => { const apiKeys = await prisma.apiKey.findMany({ select: ApiKeyConfig.filterSelection, @@ -104,8 +104,8 @@ export namespace ApiKeyMethods { }))) } }) - export const readWithHash = ServiceMethod({ - auther: () => ApiKeyAuthers.readWithHash.dynamicFields({}), + export const readWithHash = serviceMethod({ + authorizer: () => ApiKeyAuthers.readWithHash.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -130,8 +130,8 @@ export namespace ApiKeyMethods { } } }) - export const update = ServiceMethod({ - auther: () => ApiKeyAuthers.update.dynamicFields({}), + export const update = serviceMethod({ + authorizer: () => ApiKeyAuthers.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -148,8 +148,8 @@ export namespace ApiKeyMethods { return { name } }, }) - export const destroy = ServiceMethod({ - auther: () => ApiKeyAuthers.destroy.dynamicFields({}), + export const destroy = serviceMethod({ + authorizer: () => ApiKeyAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/applications/methods.ts b/src/services/applications/methods.ts index 32cb9f594..2100b4ce4 100644 --- a/src/services/applications/methods.ts +++ b/src/services/applications/methods.ts @@ -2,16 +2,16 @@ import '@pn-server-only' import { ApplicationAuthers } from './authers' import { ApplicationSchemas } from './schemas' import { ServerError } from '@/services/error' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { z } from 'zod' export namespace ApplicationMethods { - export const readForUser = ServiceMethod({ + export const readForUser = serviceMethod({ paramsSchema: z.object({ userId: z.number(), periodId: z.number() }), - auther: ({ params }) => ApplicationAuthers.readForUser.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => ApplicationAuthers.readForUser.dynamicFields({ userId: params.userId }), method: async ({ prisma, params }) => prisma.application.findMany({ where: { userId: params.userId, @@ -20,13 +20,13 @@ export namespace ApplicationMethods { }) }) - export const create = ServiceMethod({ + export const create = serviceMethod({ dataSchema: ApplicationSchemas.create, paramsSchema: z.object({ userId: z.number(), commiteeParticipationId: z.number() }), - auther: ({ params }) => ApplicationAuthers.create.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => ApplicationAuthers.create.dynamicFields({ userId: params.userId }), method: async ({ prisma, data, params }) => { const commiteeParticipation = await prisma.committeeParticipationInApplicationPeriod.findUniqueOrThrow({ where: { @@ -78,14 +78,14 @@ export namespace ApplicationMethods { }, }) - export const update = ServiceMethod({ + export const update = serviceMethod({ dataSchema: ApplicationSchemas.update, paramsSchema: z.object({ userId: z.number(), commiteeParticipationId: z.number() }), opensTransaction: true, - auther: ({ params }) => ApplicationAuthers.update.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => ApplicationAuthers.update.dynamicFields({ userId: params.userId }), method: async ({ prisma, data, params }) => { const application = await prisma.application.findUniqueOrThrow({ where: { @@ -194,12 +194,12 @@ export namespace ApplicationMethods { }, }) - export const destroy = ServiceMethod({ + export const destroy = serviceMethod({ paramsSchema: z.object({ userId: z.number(), commiteeParticipationId: z.number() }), - auther: ({ params }) => ApplicationAuthers.destroy.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => ApplicationAuthers.destroy.dynamicFields({ userId: params.userId }), opensTransaction: true, method: async ({ prisma, params }) => { prisma.$transaction(async (tx) => { diff --git a/src/services/applications/periods/methods.ts b/src/services/applications/periods/methods.ts index ead3e74e9..5385fa112 100644 --- a/src/services/applications/periods/methods.ts +++ b/src/services/applications/periods/methods.ts @@ -2,19 +2,19 @@ import '@pn-server-only' import { ApplicationPeriodAuthers } from './authers' import { ApplicationPeriodSchemas } from './schemas' import { ApplicationPeriodConfig } from './config' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { ApplicationMethods } from '@/services/applications/methods' import { ServerError } from '@/services/error' import { z } from 'zod' export namespace ApplicationPeriodMethods { - export const readAll = ServiceMethod({ - auther: () => ApplicationPeriodAuthers.readAll.dynamicFields({}), + export const readAll = serviceMethod({ + authorizer: () => ApplicationPeriodAuthers.readAll.dynamicFields({}), method: async ({ prisma }) => prisma.applicationPeriod.findMany() }) - export const read = ServiceMethod({ - auther: () => ApplicationPeriodAuthers.read.dynamicFields({}), + export const read = serviceMethod({ + authorizer: () => ApplicationPeriodAuthers.read.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), @@ -24,8 +24,8 @@ export namespace ApplicationPeriodMethods { }) }) - export const create = ServiceMethod({ - auther: () => ApplicationPeriodAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => ApplicationPeriodAuthers.create.dynamicFields({}), dataSchema: ApplicationPeriodSchemas.create, method: async ({ prisma, data }) => { await prisma.applicationPeriod.create({ @@ -43,8 +43,8 @@ export namespace ApplicationPeriodMethods { } }) - export const update = ServiceMethod({ - auther: () => ApplicationPeriodAuthers.update.dynamicFields({}), + export const update = serviceMethod({ + authorizer: () => ApplicationPeriodAuthers.update.dynamicFields({}), dataSchema: ApplicationPeriodSchemas.update, paramsSchema: z.object({ name: z.string() @@ -122,11 +122,11 @@ export namespace ApplicationPeriodMethods { } }) - export const removeAllApplicationTexts = ServiceMethod({ + export const removeAllApplicationTexts = serviceMethod({ paramsSchema: z.object({ name: z.string() }), - auther: () => ApplicationPeriodAuthers.removeAllApplicationTexts.dynamicFields({}), + authorizer: () => ApplicationPeriodAuthers.removeAllApplicationTexts.dynamicFields({}), method: async ({ prisma, params, session }) => { const period = await read({ params: { name: params.name }, @@ -148,8 +148,8 @@ export namespace ApplicationPeriodMethods { } }) - export const destroy = ServiceMethod({ - auther: () => ApplicationPeriodAuthers.destroy.dynamicFields({}), + export const destroy = serviceMethod({ + authorizer: () => ApplicationPeriodAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), @@ -160,8 +160,8 @@ export namespace ApplicationPeriodMethods { } }) - export const readNumberOfApplications = ServiceMethod({ - auther: () => ApplicationPeriodAuthers.readNumberOfApplications.dynamicFields({}), + export const readNumberOfApplications = serviceMethod({ + authorizer: () => ApplicationPeriodAuthers.readNumberOfApplications.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), diff --git a/src/services/auth/methods.ts b/src/services/auth/methods.ts index f2cd308c9..4bd705a1c 100644 --- a/src/services/auth/methods.ts +++ b/src/services/auth/methods.ts @@ -1,7 +1,7 @@ import { AuthAuthers } from './authers' import { AuthSchemas } from './schemas' import { sendResetPasswordMail } from '@/services/notifications/email/systemMail/resetPassword' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { ServerError } from '@/services/error' import { UserMethods } from '@/services/users/methods' import { UserConfig } from '@/services/users/config' @@ -11,11 +11,11 @@ import { z } from 'zod' export namespace AuthMethods { - export const verifyEmail = ServiceMethod({ + export const verifyEmail = serviceMethod({ paramsSchema: z.object({ token: z.string(), }), - auther: ({ params }) => AuthAuthers.verifyEmail.dynamicFields(params), + authorizer: ({ params }) => AuthAuthers.verifyEmail.dynamicFields(params), method: async ({ prisma, params }) => { // INFO: Safe to parse unsafe since the auther has verified the token. const payload = readJWTPayload(params.token) @@ -53,11 +53,11 @@ export namespace AuthMethods { } }) - export const verifyResetPasswordToken = ServiceMethod({ + export const verifyResetPasswordToken = serviceMethod({ paramsSchema: z.object({ token: z.string() }), - auther: ({ params }) => AuthAuthers.resetPassword.dynamicFields(params), + authorizer: ({ params }) => AuthAuthers.resetPassword.dynamicFields(params), method: async ({ prisma, params }) => { // INFO: Safe to parse unsafe since the auther has verified the token. const payload = readJWTPayload(params.token) @@ -85,12 +85,12 @@ export namespace AuthMethods { } }) - export const resetPassword = ServiceMethod({ + export const resetPassword = serviceMethod({ paramsSchema: z.object({ token: z.string() }), dataSchema: UserSchemas.updatePassword, - auther: ({ params }) => AuthAuthers.resetPassword.dynamicFields(params), + authorizer: ({ params }) => AuthAuthers.resetPassword.dynamicFields(params), method: async ({ params, data }) => { const userId = await verifyResetPasswordToken({ params }) @@ -104,9 +104,9 @@ export namespace AuthMethods { } }) - export const sendResetPasswordEmail = ServiceMethod({ + export const sendResetPasswordEmail = serviceMethod({ dataSchema: AuthSchemas.sendResetPasswordEmail, - auther: () => AuthAuthers.sendResetPasswordEmail.dynamicFields({}), + authorizer: () => AuthAuthers.sendResetPasswordEmail.dynamicFields({}), method: async ({ data }) => { console.log(data) try { diff --git a/src/services/cabin/booking/methods.ts b/src/services/cabin/booking/methods.ts index cc2affd60..b2b983d8c 100644 --- a/src/services/cabin/booking/methods.ts +++ b/src/services/cabin/booking/methods.ts @@ -4,7 +4,7 @@ import { CabinBookingSchemas } from './schemas' import { calculateCabinBookingPrice, calculateTotalCabinBookingPrice } from './cabinPriceCalculator' import { CabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' import { CabinProductConfig } from '@/services/cabin/product/config' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import 'server-only' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { ServerError } from '@/services/error' @@ -22,12 +22,12 @@ Dette skal være en bookingbekreftelse, så det bør nok komme noe nyttig info h export namespace CabinBookingMethods { - const cabinAvailable = ServiceMethod({ + const cabinAvailable = serviceMethod({ paramsSchema: z.object({ start: z.date(), end: z.date() }), - auther: ServerOnlyAuther, + authorizer: ServerOnlyAuther, method: async ({ prisma, params }) => { const results = await prisma.booking.findMany({ where: { @@ -49,12 +49,12 @@ export namespace CabinBookingMethods { })) - const create = ServiceMethod({ + const create = serviceMethod({ paramsSchema: z.object({ bookingType: z.nativeEnum(BookingType), bookingProducts: bookingProductParams, }), - auther: ServerOnlyAuther, + authorizer: ServerOnlyAuther, dataSchema: CabinBookingSchemas.createBookingUserAttached, method: async ({ prisma, params, data }) => { // TODO: Prevent Race conditions @@ -157,13 +157,13 @@ export namespace CabinBookingMethods { } }) - const createBookingWithUser = ServiceMethod({ + const createBookingWithUser = serviceMethod({ paramsSchema: z.object({ userId: z.number(), bookingType: z.nativeEnum(BookingType), bookingProducts: bookingProductParams, }), - auther: ServerOnlyAuther, + authorizer: ServerOnlyAuther, dataSchema: CabinBookingSchemas.createBookingUserAttached, method: async ({ prisma, params, data }) => { const result = await create({ @@ -198,12 +198,12 @@ export namespace CabinBookingMethods { } }) - export const createCabinBookingUserAttached = ServiceMethod({ + export const createCabinBookingUserAttached = serviceMethod({ paramsSchema: z.object({ userId: z.number(), bookingProducts: bookingProductParams, }), - auther: ({ params }) => CabinBookingAuthers.createCabinBookingUserAttached.dynamicFields({ + authorizer: ({ params }) => CabinBookingAuthers.createCabinBookingUserAttached.dynamicFields({ userId: params.userId, }), dataSchema: CabinBookingSchemas.createBookingUserAttached, @@ -219,12 +219,12 @@ export namespace CabinBookingMethods { }) }) - export const createBedBookingUserAttached = ServiceMethod({ + export const createBedBookingUserAttached = serviceMethod({ paramsSchema: z.object({ userId: z.number(), bookingProducts: bookingProductParams, }), - auther: ({ params }) => CabinBookingAuthers.createBedBookingUserAttached.dynamicFields({ + authorizer: ({ params }) => CabinBookingAuthers.createBedBookingUserAttached.dynamicFields({ userId: params.userId, }), dataSchema: CabinBookingSchemas.createBookingUserAttached, @@ -240,12 +240,12 @@ export namespace CabinBookingMethods { }) }) - const createBookingNoUser = ServiceMethod({ + const createBookingNoUser = serviceMethod({ paramsSchema: z.object({ bookingType: z.nativeEnum(BookingType), bookingProducts: bookingProductParams, }), - auther: ServerOnlyAuther, + authorizer: ServerOnlyAuther, dataSchema: CabinBookingSchemas.createBookingNoUser, method: async ({ prisma, params, data }) => { const result = await create({ @@ -282,11 +282,11 @@ export namespace CabinBookingMethods { } }) - export const createCabinBookingNoUser = ServiceMethod({ + export const createCabinBookingNoUser = serviceMethod({ paramsSchema: z.object({ bookingProducts: bookingProductParams, }), - auther: () => CabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}), + authorizer: () => CabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}), dataSchema: CabinBookingSchemas.createBookingNoUser, method: async ({ params, data }) => createBookingNoUser({ params: { @@ -298,11 +298,11 @@ export namespace CabinBookingMethods { }) }) - export const createBedBookingNoUser = ServiceMethod({ + export const createBedBookingNoUser = serviceMethod({ paramsSchema: z.object({ bookingProducts: bookingProductParams, }), - auther: () => CabinBookingAuthers.createBedBookingNoUser.dynamicFields({}), + authorizer: () => CabinBookingAuthers.createBedBookingNoUser.dynamicFields({}), dataSchema: CabinBookingSchemas.createBookingNoUser, method: async ({ params, data }) => createBookingNoUser({ params: { @@ -314,8 +314,8 @@ export namespace CabinBookingMethods { }) }) - export const readAvailability = ServiceMethod({ - auther: () => CabinBookingAuthers.readAvailability.dynamicFields({}), + export const readAvailability = serviceMethod({ + authorizer: () => CabinBookingAuthers.readAvailability.dynamicFields({}), method: async ({ prisma }) => { const results = await prisma.booking.findMany({ select: CabinBookingConfig.bookingFilerSelection, @@ -342,8 +342,8 @@ export namespace CabinBookingMethods { } }) - export const readMany = ServiceMethod({ - auther: () => CabinBookingAuthers.readMany.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => CabinBookingAuthers.readMany.dynamicFields({}), method: ({ prisma }) => prisma.booking.findMany({ orderBy: { start: 'asc', @@ -352,8 +352,8 @@ export namespace CabinBookingMethods { }), // TODO: Pager }) - export const read = ServiceMethod({ - auther: () => CabinBookingAuthers.read.dynamicFields({}), + export const read = serviceMethod({ + authorizer: () => CabinBookingAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/cabin/pricePeriod/methods.ts b/src/services/cabin/pricePeriod/methods.ts index 51994fc41..6629062dd 100644 --- a/src/services/cabin/pricePeriod/methods.ts +++ b/src/services/cabin/pricePeriod/methods.ts @@ -1,6 +1,6 @@ import { CabinPricePeriodAuthers } from './authers' import { CabinPricePeriodSchemas } from './schemas' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import 'server-only' import { CabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' import { ServerError } from '@/services/error' @@ -8,8 +8,8 @@ import { z } from 'zod' export namespace CabinPricePeriodMethods { - export const create = ServiceMethod({ - auther: () => CabinPricePeriodAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => CabinPricePeriodAuthers.create.dynamicFields({}), dataSchema: CabinPricePeriodSchemas.createPricePeriod, method: async ({ prisma, data }) => { const currentReleaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) @@ -59,8 +59,8 @@ export namespace CabinPricePeriodMethods { } }) - export const destroy = ServiceMethod({ - auther: () => CabinPricePeriodAuthers.destroy.dynamicFields({}), + export const destroy = serviceMethod({ + authorizer: () => CabinPricePeriodAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -81,13 +81,13 @@ export namespace CabinPricePeriodMethods { } }) - export const readMany = ServiceMethod({ - auther: () => CabinPricePeriodAuthers.read.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => CabinPricePeriodAuthers.read.dynamicFields({}), method: async ({ prisma }) => prisma.pricePeriod.findMany() }) - export const readPublicPeriods = ServiceMethod({ - auther: () => CabinPricePeriodAuthers.readPublicPeriods.dynamicFields({}), + export const readPublicPeriods = serviceMethod({ + authorizer: () => CabinPricePeriodAuthers.readPublicPeriods.dynamicFields({}), method: async ({ prisma }) => { const releaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) @@ -119,8 +119,8 @@ export namespace CabinPricePeriodMethods { } }) - export const readUnreleasedPeriods = ServiceMethod({ - auther: () => CabinPricePeriodAuthers.read.dynamicFields({}), + export const readUnreleasedPeriods = serviceMethod({ + authorizer: () => CabinPricePeriodAuthers.read.dynamicFields({}), method: async ({ prisma }) => { const releaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) return prisma.pricePeriod.findMany({ @@ -133,8 +133,8 @@ export namespace CabinPricePeriodMethods { } }) - export const update = ServiceMethod({ - auther: () => CabinPricePeriodAuthers.update.dynamicFields({}), + export const update = serviceMethod({ + authorizer: () => CabinPricePeriodAuthers.update.dynamicFields({}), dataSchema: CabinPricePeriodSchemas.updatePricePeriod, paramsSchema: z.object({ pricePeriodId: z.number(), diff --git a/src/services/cabin/product/methods.ts b/src/services/cabin/product/methods.ts index f276ebe73..aeee102af 100644 --- a/src/services/cabin/product/methods.ts +++ b/src/services/cabin/product/methods.ts @@ -1,7 +1,7 @@ import { CabinProductAuthers } from './authers' import { CabinProductSchemas } from './schemas' import { CabinProductConfig } from './config' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import 'server-only' import { ServerError } from '@/services/error' import { CabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' @@ -10,16 +10,16 @@ import { z } from 'zod' export namespace CabinProductMethods { - export const create = ServiceMethod({ - auther: () => CabinProductAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => CabinProductAuthers.create.dynamicFields({}), dataSchema: CabinProductSchemas.createProduct, method: ({ prisma, data }) => prisma.cabinProduct.create({ data, }) }) - export const createPrice = ServiceMethod({ - auther: () => CabinProductAuthers.createPrice.dynamicFields({}), + export const createPrice = serviceMethod({ + authorizer: () => CabinProductAuthers.createPrice.dynamicFields({}), paramsSchema: z.object({ cabinProductId: z.number(), }), @@ -52,15 +52,15 @@ export namespace CabinProductMethods { } }) - export const readMany = ServiceMethod({ - auther: () => CabinProductAuthers.read.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => CabinProductAuthers.read.dynamicFields({}), method: ({ prisma }) => prisma.cabinProduct.findMany({ include: CabinProductConfig.includer, }), }) - export const readActive = ServiceMethod({ - auther: () => CabinProductAuthers.read.dynamicFields({}), + export const readActive = serviceMethod({ + authorizer: () => CabinProductAuthers.read.dynamicFields({}), method: async ({ prisma }) => { const pricePeriods = await CabinPricePeriodMethods.readPublicPeriods({ bypassAuth: true }) @@ -79,8 +79,8 @@ export namespace CabinProductMethods { }, }) - export const read = ServiceMethod({ - auther: () => CabinProductAuthers.read.dynamicFields({}), + export const read = serviceMethod({ + authorizer: () => CabinProductAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/cabin/releasePeriod/methods.ts b/src/services/cabin/releasePeriod/methods.ts index 2e8999197..aea523c63 100644 --- a/src/services/cabin/releasePeriod/methods.ts +++ b/src/services/cabin/releasePeriod/methods.ts @@ -1,14 +1,14 @@ import { CabinReleasePeriodAuthers } from './authers' import { CabinReleasePeriodSchemas } from './schemas' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import 'server-only' import { ServerError } from '@/services/error' import { z } from 'zod' export namespace CabinReleasePeriodMethods { - export const create = ServiceMethod({ - auther: () => CabinReleasePeriodAuthers.createReleasePeriodAuther.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => CabinReleasePeriodAuthers.createReleasePeriodAuther.dynamicFields({}), dataSchema: CabinReleasePeriodSchemas.createReleasePeriod, method: async ({ prisma, data }) => { const latestReleasePeriod = await prisma.releasePeriod.findFirst({ @@ -31,8 +31,8 @@ export namespace CabinReleasePeriodMethods { } }) - export const destroy = ServiceMethod({ - auther: () => CabinReleasePeriodAuthers.deleteReleasePeriodAuther.dynamicFields({}), + export const destroy = serviceMethod({ + authorizer: () => CabinReleasePeriodAuthers.deleteReleasePeriodAuther.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -51,8 +51,8 @@ export namespace CabinReleasePeriodMethods { } }) - export const readMany = ServiceMethod({ - auther: () => CabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => CabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), method: async ({ prisma }) => prisma.releasePeriod.findMany({ orderBy: { releaseUntil: 'desc', @@ -60,8 +60,8 @@ export namespace CabinReleasePeriodMethods { }) }) - export const getCurrentReleasePeriod = ServiceMethod({ - auther: () => CabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), + export const getCurrentReleasePeriod = serviceMethod({ + authorizer: () => CabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), method: async ({ prisma }) => prisma.releasePeriod.findFirst({ where: { releaseTime: { @@ -75,8 +75,8 @@ export namespace CabinReleasePeriodMethods { }) }) - export const update = ServiceMethod({ - auther: () => CabinReleasePeriodAuthers.updateReleasePeriodAuther.dynamicFields({}), + export const update = serviceMethod({ + authorizer: () => CabinReleasePeriodAuthers.updateReleasePeriodAuther.dynamicFields({}), dataSchema: CabinReleasePeriodSchemas.updateReleasePeriod, method: async ({ prisma, data }) => prisma.releasePeriod.update({ where: { diff --git a/src/services/career/companies/methods.ts b/src/services/career/companies/methods.ts index 60c0e1759..674863b67 100644 --- a/src/services/career/companies/methods.ts +++ b/src/services/career/companies/methods.ts @@ -3,16 +3,16 @@ import { CompanySchemas } from './schemas' import { CompanyAuthers } from './authers' import { CompanyConfig } from './config' import { createCmsImage } from '@/services/cms/images/create' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { v4 as uuid } from 'uuid' import { z } from 'zod' export namespace CompanyMethods { - export const create = ServiceMethod({ + export const create = serviceMethod({ dataSchema: CompanySchemas.create, - auther: () => CompanyAuthers.create.dynamicFields({}), + authorizer: () => CompanyAuthers.create.dynamicFields({}), method: async ({ prisma, data }) => { //TODO: tranaction when createCmsImage is service method. const logo = await createCmsImage({ name: uuid() }) @@ -24,7 +24,7 @@ export namespace CompanyMethods { }) } }) - export const readPage = ServiceMethod({ + export const readPage = serviceMethod({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -34,7 +34,7 @@ export namespace CompanyMethods { name: z.string().optional(), }), ), - auther: () => CompanyAuthers.readPage.dynamicFields({}), + authorizer: () => CompanyAuthers.readPage.dynamicFields({}), method: async ({ prisma, params }) => await prisma.company.findMany({ ...cursorPageingSelection(params.paging.page), where: { @@ -46,12 +46,12 @@ export namespace CompanyMethods { include: CompanyConfig.relationIncluder }) }) - export const update = ServiceMethod({ + export const update = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), dataSchema: CompanySchemas.update, - auther: () => CompanyAuthers.update.dynamicFields({}), + authorizer: () => CompanyAuthers.update.dynamicFields({}), method: async ({ prisma, params: { id }, data }) => { await prisma.company.update({ where: { id }, @@ -59,11 +59,11 @@ export namespace CompanyMethods { }) }, }) - export const destroy = ServiceMethod({ + export const destroy = serviceMethod({ paramsSchema: z.object({ id: z.number() }), - auther: () => CompanyAuthers.destroy.dynamicFields({}), + authorizer: () => CompanyAuthers.destroy.dynamicFields({}), method: async ({ prisma, params: { id } }) => { await prisma.company.delete({ where: { diff --git a/src/services/career/jobAds/methods.ts b/src/services/career/jobAds/methods.ts index 9351e0205..831b82e20 100644 --- a/src/services/career/jobAds/methods.ts +++ b/src/services/career/jobAds/methods.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { JobAdSchemas } from './schemas' import { JobAdAuthers } from './authers' import { JobAdConfig } from './config' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createArticle } from '@/services/cms/articles/create' import { CompanyConfig } from '@/career/companies/config' @@ -15,9 +15,9 @@ import { JobType } from '@prisma/client' import type { ExpandedJobAd, SimpleJobAd } from './Types' export namespace JobadMethods { - export const create = ServiceMethod({ + export const create = serviceMethod({ dataSchema: JobAdSchemas.create, - auther: () => JobAdAuthers.create.dynamicFields({}), + authorizer: () => JobAdAuthers.create.dynamicFields({}), method: async ({ prisma, data: { articleName, companyId, ...data } }) => { const article = await createArticle({ name: articleName }) @@ -48,7 +48,7 @@ export namespace JobadMethods { * @param idOrName - id or articleName and order of jobAd to read (id or {articleName: string, order: number}) * @returns ExpandedJobAd - the jobAd and its article */ - export const read = ServiceMethod({ + export const read = serviceMethod({ paramsSchema: z.object({ idOrName: z.union([ z.number(), @@ -58,7 +58,7 @@ export namespace JobadMethods { }), ]), }), - auther: () => JobAdAuthers.read.dynamicFields({}), + authorizer: () => JobAdAuthers.read.dynamicFields({}), method: async ({ prisma, params: { idOrName } }): Promise => { const jobAd = await prisma.jobAd.findUnique({ where: typeof idOrName === 'number' ? { @@ -84,8 +84,8 @@ export namespace JobadMethods { * This handler reads all active jobAds * @returns SimpleJobAd[] - all jobAds with coverImage */ - export const readActive = ServiceMethod({ - auther: () => JobAdAuthers.readActive.dynamicFields({}), + export const readActive = serviceMethod({ + authorizer: () => JobAdAuthers.readActive.dynamicFields({}), method: async ({ prisma }): Promise => { const jobAds = await prisma.jobAd.findMany({ orderBy: { @@ -109,7 +109,7 @@ export namespace JobadMethods { * This handler reads a page of inactive jobAds * @param paging - the page to read, includes details to filter by name (articleName) and the type. */ - export const readInactivePage = ServiceMethod({ + export const readInactivePage = serviceMethod({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -120,7 +120,7 @@ export namespace JobadMethods { type: z.nativeEnum(JobType).nullable(), }), ), - auther: () => JobAdAuthers.readInactivePage.dynamicFields({}), + authorizer: () => JobAdAuthers.readInactivePage.dynamicFields({}), method: async ({ prisma, params }): Promise => { const jobAds = await prisma.jobAd.findMany({ ...cursorPageingSelection(params.paging.page), @@ -149,22 +149,22 @@ export namespace JobadMethods { * @param id - id of news article to destroy * @returns */ - export const update = ServiceMethod({ + export const update = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), dataSchema: JobAdSchemas.update, - auther: () => JobAdAuthers.update.dynamicFields({}), + authorizer: () => JobAdAuthers.update.dynamicFields({}), method: async ({ prisma, params: { id }, data }) => await prisma.jobAd.update({ where: { id }, data, }) }) - export const destroy = ServiceMethod({ + export const destroy = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - auther: () => JobAdAuthers.destroy.dynamicFields({}), + authorizer: () => JobAdAuthers.destroy.dynamicFields({}), method: async ({ prisma, params: { id } }) => { const jobAd = await prisma.jobAd.delete({ where: { id }, diff --git a/src/services/cms/links/read.ts b/src/services/cms/links/read.ts index e1fb13de8..66b14dd47 100644 --- a/src/services/cms/links/read.ts +++ b/src/services/cms/links/read.ts @@ -1,15 +1,15 @@ import '@pn-server-only' import { readSpecialCmsLinkAuther } from './authers' import logger from '@/lib/logger' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { SpecialCmsLink } from '@prisma/client' import { z } from 'zod' -export const readSpecialCmsLink = ServiceMethod({ +export const readSpecialCmsLink = serviceMethod({ paramsSchema: z.object({ special: z.nativeEnum(SpecialCmsLink), }), - auther: () => readSpecialCmsLinkAuther.dynamicFields({}), + authorizer: () => readSpecialCmsLinkAuther.dynamicFields({}), method: async ({ prisma, params: { special } }) => { const cmsLink = await prisma.cmsLink.findUnique({ where: { special } diff --git a/src/services/dots/methods.ts b/src/services/dots/methods.ts index 057e260ae..27ddf2515 100644 --- a/src/services/dots/methods.ts +++ b/src/services/dots/methods.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { DotConfig } from './config' import { DotAuthers } from './authers' import { DotSchemas } from './schemas' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { z } from 'zod' @@ -12,8 +12,8 @@ import { z } from 'zod' * @param userId - The user id to read dots for * @returns All dots for the user in ascending order of expiration. i.e the dot that expires first will be first in the list */ -const readForUser = ServiceMethod({ - auther: ({ params }) => DotAuthers.readForUser.dynamicFields({ userId: params.userId }), +const readForUser = serviceMethod({ + authorizer: ({ params }) => DotAuthers.readForUser.dynamicFields({ userId: params.userId }), paramsSchema: z.object({ userId: z.number(), onlyActive: z.boolean(), @@ -33,9 +33,9 @@ const readForUser = ServiceMethod({ }) }) -const create = ServiceMethod({ +const create = serviceMethod({ dataSchema: DotSchemas.create, - auther: ({ data }) => DotAuthers.create.dynamicFields({ userId: data.userId }), + authorizer: ({ data }) => DotAuthers.create.dynamicFields({ userId: data.userId }), paramsSchema: z.object({ accuserId: z.number(), }), @@ -70,8 +70,8 @@ const create = ServiceMethod({ } }) -const readWrappersForUser = ServiceMethod({ - auther: ({ params }) => DotAuthers.readWrapperForUser.dynamicFields({ userId: params.userId }), +const readWrappersForUser = serviceMethod({ + authorizer: ({ params }) => DotAuthers.readWrapperForUser.dynamicFields({ userId: params.userId }), paramsSchema: z.object({ userId: z.number(), }), @@ -94,8 +94,8 @@ const readWrappersForUser = ServiceMethod({ } }) -const readPage = ServiceMethod({ - auther: () => DotAuthers.readPage.dynamicFields({}), +const readPage = serviceMethod({ + authorizer: () => DotAuthers.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), z.object({ diff --git a/src/services/events/methods.ts b/src/services/events/methods.ts index fa24b6fdf..3ae2b5c5a 100644 --- a/src/services/events/methods.ts +++ b/src/services/events/methods.ts @@ -7,7 +7,7 @@ import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createCmsImage } from '@/services/cms/images/create' import { getOsloTime } from '@/lib/dates/getOsloTime' import { ServerError } from '@/services/error' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { NotificationMethods } from '@/services/notifications/methods' @@ -17,9 +17,9 @@ import { z } from 'zod' import type { EventExpanded } from './Types' export namespace EventMethods { - export const create = ServiceMethod({ + export const create = serviceMethod({ dataSchema: EventSchemas.create, - auther: () => EventAuthers.create.dynamicFields({}), + authorizer: () => EventAuthers.create.dynamicFields({}), method: async ({ prisma, data, session }) => { const cmsParagraph = await createCmsParagraph({ name: uuid() }) const cmsImage = await createCmsImage({ name: uuid() }) @@ -79,7 +79,7 @@ export namespace EventMethods { })) }) - await NotificationMethods.createSpecial.client(prisma).execute({ + await NotificationMethods.createSpecial({ params: { special: 'NEW_EVENT', }, @@ -87,18 +87,17 @@ export namespace EventMethods { title: `Hva der hender: ${event.name}`, message: `${event.name}, 🕓 ${displayDate(event.eventStart, false)},📍 ${event.location}`, }, - session, bypassAuth: true, }) return event } }) - export const read = ServiceMethod({ + export const read = serviceMethod({ paramsSchema: z.object({ order: z.number(), name: z.string(), }), - auther: () => EventAuthers.read.dynamicFields({}), + authorizer: () => EventAuthers.read.dynamicFields({}), method: async ({ prisma, params, session }) => { const event = await prisma.event.findUniqueOrThrow({ where: { @@ -156,11 +155,11 @@ export namespace EventMethods { } } }) - export const readManyCurrent = ServiceMethod({ + export const readManyCurrent = serviceMethod({ paramsSchema: z.object({ tags: z.array(z.string()).nullable(), }), - auther: () => EventAuthers.readManyCurrent.dynamicFields({}), + authorizer: () => EventAuthers.readManyCurrent.dynamicFields({}), method: async ({ prisma, params }): Promise => { const events = await prisma.event.findMany({ select: { @@ -191,7 +190,7 @@ export namespace EventMethods { })) } }) - export const readManyArchivedPage = ServiceMethod({ + export const readManyArchivedPage = serviceMethod({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -202,7 +201,7 @@ export namespace EventMethods { tags: z.array(z.string()).nullable(), }), ), // Converted from ReadPageInput - auther: () => EventAuthers.readManyArchivedPage.dynamicFields({}), + authorizer: () => EventAuthers.readManyArchivedPage.dynamicFields({}), method: async ({ prisma, params }): Promise => { const events = await prisma.event.findMany({ ...cursorPageingSelection(params.paging.page), @@ -238,12 +237,12 @@ export namespace EventMethods { })) } }) - export const update = ServiceMethod({ + export const update = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), dataSchema: EventSchemas.update, - auther: () => EventAuthers.update.dynamicFields({}), + authorizer: () => EventAuthers.update.dynamicFields({}), method: async ({ prisma, params, data: { tagIds, ...data } }) => { const event = await prisma.event.findUniqueOrThrow({ where: { id: params.id } @@ -289,11 +288,11 @@ export namespace EventMethods { return eventUpdate } }) - export const destroy = ServiceMethod({ + export const destroy = serviceMethod({ paramsSchema: z.object({ id: z.number() }), - auther: () => EventAuthers.destroy.dynamicFields({}), + authorizer: () => EventAuthers.destroy.dynamicFields({}), method: async ({ prisma, params }) => { await prisma.event.delete({ where: { diff --git a/src/services/events/registration/methods.ts b/src/services/events/registration/methods.ts index e87603f9e..37cb72d78 100644 --- a/src/services/events/registration/methods.ts +++ b/src/services/events/registration/methods.ts @@ -1,7 +1,7 @@ import { EventRegistrationAuthers } from './authers' import { EventRegistrationConfig } from './config' import { EventRegistrationSchemas } from './schemas' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import '@pn-server-only' import { Smorekopp } from '@/services/error' import { ImageMethods } from '@/services/images/methods' @@ -125,12 +125,12 @@ async function calculateTakeSkip(prisma: Prisma.TransactionClient, params: { export namespace EventRegistrationMethods { - export const create = ServiceMethod({ + export const create = serviceMethod({ paramsSchema: z.object({ userId: z.number().min(0), eventId: z.number().min(0), }), - auther: ({ params }) => EventRegistrationAuthers.create.dynamicFields({ + authorizer: ({ params }) => EventRegistrationAuthers.create.dynamicFields({ userId: params.userId, }), opensTransaction: true, @@ -162,8 +162,8 @@ export namespace EventRegistrationMethods { }, }) - export const createGuest = ServiceMethod({ - auther: () => EventRegistrationAuthers.createGuest.dynamicFields({}), + export const createGuest = serviceMethod({ + authorizer: () => EventRegistrationAuthers.createGuest.dynamicFields({}), paramsSchema: z.object({ eventId: z.number(), }), @@ -196,8 +196,8 @@ export namespace EventRegistrationMethods { }, }) - export const readMany = ServiceMethod({ - auther: () => EventRegistrationAuthers.readMany.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => EventRegistrationAuthers.readMany.dynamicFields({}), paramsSchema: z.object({ eventId: z.number().min(0), skip: z.number().optional(), @@ -230,8 +230,8 @@ export namespace EventRegistrationMethods { }, }) - export const readManyDetailed = ServiceMethod({ - auther: () => EventRegistrationAuthers.readManyDetailed.dynamicFields({}), + export const readManyDetailed = serviceMethod({ + authorizer: () => EventRegistrationAuthers.readManyDetailed.dynamicFields({}), paramsSchema: z.object({ eventId: z.number().min(0), skip: z.number().optional(), @@ -255,8 +255,8 @@ export namespace EventRegistrationMethods { } }) - export const updateNotes = ServiceMethod({ - auther: () => EventRegistrationAuthers.updateRegistrationNotes.dynamicFields({}), + export const updateNotes = serviceMethod({ + authorizer: () => EventRegistrationAuthers.updateRegistrationNotes.dynamicFields({}), paramsSchema: z.object({ registrationId: z.number().min(0), }), @@ -291,8 +291,8 @@ export namespace EventRegistrationMethods { } }) - export const destroy = ServiceMethod({ - auther: () => EventRegistrationAuthers.destroy.dynamicFields({}), + export const destroy = serviceMethod({ + authorizer: () => EventRegistrationAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ registrationId: z.number().min(0), }), diff --git a/src/services/events/tags/methods.ts b/src/services/events/tags/methods.ts index 64aa846c3..388d653ac 100644 --- a/src/services/events/tags/methods.ts +++ b/src/services/events/tags/methods.ts @@ -4,28 +4,28 @@ import { EvantTagConfig } from './config' import { EventTagSchemas } from './schemas' import { EventAuthers } from '@/services/events/authers' import logger from '@/lib/logger' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { ServerError } from '@/services/error' import { SpecialEventTags } from '@prisma/client' import { z } from 'zod' export namespace EventTagMethods { - export const read = ServiceMethod({ + export const read = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - auther: () => EventTagAuthers.read.dynamicFields({}), + authorizer: () => EventTagAuthers.read.dynamicFields({}), method: async ({ prisma, params: { id } }) => await prisma.eventTag.findUniqueOrThrow({ where: { id } }) }) - export const readSpecial = ServiceMethod({ + export const readSpecial = serviceMethod({ paramsSchema: z.object({ special: z.nativeEnum(SpecialEventTags), }), - auther: () => EventTagAuthers.readSpecial.dynamicFields({}), + authorizer: () => EventTagAuthers.readSpecial.dynamicFields({}), method: async ({ prisma, params: { special } }) => { const tag = await prisma.eventTag.findUnique({ where: { @@ -44,13 +44,13 @@ export namespace EventTagMethods { return tag } }) - export const readAll = ServiceMethod({ - auther: () => EventTagAuthers.readAll.dynamicFields({}), + export const readAll = serviceMethod({ + authorizer: () => EventTagAuthers.readAll.dynamicFields({}), method: async ({ prisma }) => await prisma.eventTag.findMany() }) - export const create = ServiceMethod({ + export const create = serviceMethod({ dataSchema: EventTagSchemas.create, - auther: () => EventTagAuthers.create.dynamicFields({}), + authorizer: () => EventTagAuthers.create.dynamicFields({}), method: async ({ prisma, data: { color, ...data } }) => { const colorR = parseInt(color.slice(1, 3), 16) const colorG = parseInt(color.slice(3, 5), 16) @@ -65,12 +65,12 @@ export namespace EventTagMethods { }) } }) - export const update = ServiceMethod({ + export const update = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), dataSchema: EventTagSchemas.update, - auther: () => EventAuthers.update.dynamicFields({}), + authorizer: () => EventAuthers.update.dynamicFields({}), method: async ({ prisma, params: { id }, data: { color, ...data } }) => { const colorR = color ? parseInt(color.slice(1, 3), 16) : undefined const colorG = color ? parseInt(color.slice(3, 5), 16) : undefined @@ -88,11 +88,11 @@ export namespace EventTagMethods { }) } }) - export const destroy = ServiceMethod({ + export const destroy = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - auther: () => EventAuthers.destroy.dynamicFields({}), + authorizer: () => EventAuthers.destroy.dynamicFields({}), method: async ({ prisma, params }) => { const tag = await prisma.eventTag.findUniqueOrThrow({ where: { id: params.id } diff --git a/src/services/groups/committees/create.ts b/src/services/groups/committees/create.ts index fb8786bc7..2f8443154 100644 --- a/src/services/groups/committees/create.ts +++ b/src/services/groups/committees/create.ts @@ -14,7 +14,7 @@ export async function createCommittee(rawdata: CreateCommitteeTypes['Detailed']) let defaultLogoImageId: number if (!logoImageId) { defaultLogoImageId = await ImageMethods.readSpecial({ - params: { special: 'DAFAULT_COMMITTEE_LOGO' }, session: null //TODO: pass session + params: { special: 'DAFAULT_COMMITTEE_LOGO' }, //TODO: pass session }).then(res => res.id) } const article = await createArticle({}) diff --git a/src/services/groups/committees/methods.ts b/src/services/groups/committees/methods.ts index a3edd78e9..e3b63030d 100644 --- a/src/services/groups/committees/methods.ts +++ b/src/services/groups/committees/methods.ts @@ -2,21 +2,21 @@ import { CommitteeAuthers } from './authers' import { CommitteeConfig } from './config' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { ImageMethods } from '@/services/images/methods' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { articleRealtionsIncluder } from '@/cms/articles/ConfigVars' import { z } from 'zod' export namespace CommitteeMethods { - export const readCommittees = ServiceMethod({ - auther: () => CommitteeAuthers.read.dynamicFields({}), + export const readCommittees = serviceMethod({ + authorizer: () => CommitteeAuthers.read.dynamicFields({}), method: async ({ prisma }) => prisma.committee.findMany({ include: CommitteeConfig.committeeLogoIncluder, }) }) - export const readCommittee = ServiceMethod({ - auther: () => CommitteeAuthers.read.dynamicFields({}), + export const readCommittee = serviceMethod({ + authorizer: () => CommitteeAuthers.read.dynamicFields({}), paramsSchema: z.union([ z.object({ id: z.number() }), z.object({ shortName: z.string() }) @@ -49,8 +49,8 @@ export namespace CommitteeMethods { } }) - export const readCommitteArticle = ServiceMethod({ - auther: () => CommitteeAuthers.read.dynamicFields({}), + export const readCommitteArticle = serviceMethod({ + authorizer: () => CommitteeAuthers.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), }), @@ -64,8 +64,8 @@ export namespace CommitteeMethods { })).committeeArticle }) - export const readCommitteesFromGroupIds = ServiceMethod({ - auther: ServerOnlyAuther, + export const readCommitteesFromGroupIds = serviceMethod({ + authorizer: ServerOnlyAuther, paramsSchema: z.object({ ids: z.number().int().array() }), @@ -79,8 +79,8 @@ export namespace CommitteeMethods { }) }) - export const readCommitteeParagraph = ServiceMethod({ - auther: () => CommitteeAuthers.read.dynamicFields({}), + export const readCommitteeParagraph = serviceMethod({ + authorizer: () => CommitteeAuthers.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), }), @@ -92,8 +92,8 @@ export namespace CommitteeMethods { })).paragraph }) - export const readCommitteeMembers = ServiceMethod({ - auther: () => CommitteeAuthers.read.dynamicFields({}), + export const readCommitteeMembers = serviceMethod({ + authorizer: () => CommitteeAuthers.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), active: z.boolean().optional(), diff --git a/src/services/groups/committees/update.ts b/src/services/groups/committees/update.ts index 149ad341e..53c479aab 100644 --- a/src/services/groups/committees/update.ts +++ b/src/services/groups/committees/update.ts @@ -14,7 +14,7 @@ export async function updateCommittee( let defaultLogoImageId: number if (!logoImageId) { defaultLogoImageId = await ImageMethods.readSpecial({ - params: { special: 'DAFAULT_COMMITTEE_LOGO' }, session: null //TODO: pass session + params: { special: 'DAFAULT_COMMITTEE_LOGO' }, //TODO: pass session }).then(res => res.id) } diff --git a/src/services/groups/interestGroups/methods.ts b/src/services/groups/interestGroups/methods.ts index f15a06d33..b081f5e20 100644 --- a/src/services/groups/interestGroups/methods.ts +++ b/src/services/groups/interestGroups/methods.ts @@ -2,15 +2,15 @@ import '@pn-server-only' import { InterestGroupAuthers } from './authers' import { InterestGroupSchemas } from './schemas' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { articleSectionsRealtionsIncluder } from '@/services/cms/articleSections/ConfigVars' import { z } from 'zod' import type { ExpandedInterestGroup } from './Types' export namespace InterestGroupMethods { - export const create = ServiceMethod({ + export const create = serviceMethod({ dataSchema: InterestGroupSchemas.create, - auther: () => InterestGroupAuthers.create.dynamicFields({}), + authorizer: () => InterestGroupAuthers.create.dynamicFields({}), method: async ({ prisma, data }) => { const { order } = await readCurrentOmegaOrder() @@ -35,8 +35,8 @@ export namespace InterestGroupMethods { } }) - export const readMany = ServiceMethod({ - auther: () => InterestGroupAuthers.readMany.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => InterestGroupAuthers.readMany.dynamicFields({}), method: async ({ prisma }): Promise => prisma.interestGroup.findMany({ include: { articleSection: { @@ -50,12 +50,12 @@ export namespace InterestGroupMethods { }) }) - export const read = ServiceMethod({ + export const read = serviceMethod({ paramsSchema: z.object({ id: z.number().optional(), shortName: z.string().optional(), }), - auther: () => InterestGroupAuthers.read.dynamicFields({}), + authorizer: () => InterestGroupAuthers.read.dynamicFields({}), method: async ({ prisma, params: { id, shortName } }) => await prisma.interestGroup.findUniqueOrThrow({ where: { id, @@ -69,12 +69,12 @@ export namespace InterestGroupMethods { }) }) - export const update = ServiceMethod({ + export const update = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), dataSchema: InterestGroupSchemas.update, - auther: async ({ params }) => InterestGroupAuthers.update.dynamicFields({ + authorizer: async ({ params }) => InterestGroupAuthers.update.dynamicFields({ groupId: ( await read({ params: { id: params.id }, @@ -88,11 +88,11 @@ export namespace InterestGroupMethods { }), }) - export const destroy = ServiceMethod({ + export const destroy = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - auther: () => InterestGroupAuthers.destroy.dynamicFields({}), + authorizer: () => InterestGroupAuthers.destroy.dynamicFields({}), opensTransaction: true, method: async ({ prisma, params: { id } }) => { await prisma.$transaction(async tx => { diff --git a/src/services/groups/methods.ts b/src/services/groups/methods.ts index 93fd11650..e18a36dbc 100644 --- a/src/services/groups/methods.ts +++ b/src/services/groups/methods.ts @@ -3,7 +3,7 @@ import { groupsExpandedIncluder, GroupTypesConfig, OmegaMembershipLevelConfig, r import { GroupAuthers } from './authers' import { UserConfig } from '@/services/users/config' import { ServerError } from '@/services/error' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { getMembershipFilter } from '@/auth/getMembershipFilter' import logger from '@/lib/logger' @@ -189,13 +189,13 @@ export function checkGroupValidity< export namespace GroupMethods { - export const readGroups = ServiceMethod({ - auther: () => GroupAuthers.read.dynamicFields({}), + export const readGroups = serviceMethod({ + authorizer: () => GroupAuthers.read.dynamicFields({}), method: async ({ prisma }) => prisma.group.findMany() }) - export const readCurrentGroupOrder = ServiceMethod({ - auther: ServerOnlyAuther, + export const readCurrentGroupOrder = serviceMethod({ + authorizer: ServerOnlyAuther, paramsSchema: z.object({ id: z.number(), }), @@ -209,8 +209,8 @@ export namespace GroupMethods { })).order }) - export const readCurrentGroupOrders = ServiceMethod({ - auther: ServerOnlyAuther, + export const readCurrentGroupOrders = serviceMethod({ + authorizer: ServerOnlyAuther, paramsSchema: z.object({ ids: z.number().array(), }), @@ -227,8 +227,8 @@ export namespace GroupMethods { }) }) - export const readGroup = ServiceMethod({ - auther: ServerOnlyAuther, + export const readGroup = serviceMethod({ + authorizer: ServerOnlyAuther, paramsSchema: z.object({ id: z.number(), }), @@ -239,8 +239,8 @@ export namespace GroupMethods { }) }) - export const readGroupExpanded = ServiceMethod({ - auther: () => GroupAuthers.read.dynamicFields({}), + export const readGroupExpanded = serviceMethod({ + authorizer: () => GroupAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -255,8 +255,8 @@ export namespace GroupMethods { } }) - export const readGroupsExpanded = ServiceMethod({ - auther: () => GroupAuthers.read.dynamicFields({}), + export const readGroupsExpanded = serviceMethod({ + authorizer: () => GroupAuthers.read.dynamicFields({}), method: async ({ prisma }) => { const groups = (await prisma.group.findMany({ include: groupsExpandedIncluder, @@ -266,8 +266,8 @@ export namespace GroupMethods { } }) - export const readGroupsStructured = ServiceMethod({ - auther: () => GroupAuthers.read.dynamicFields({}), + export const readGroupsStructured = serviceMethod({ + authorizer: () => GroupAuthers.read.dynamicFields({}), method: async () => { const groupsStructured: GroupsStructured = { CLASS: { @@ -306,8 +306,8 @@ export namespace GroupMethods { } }) - export const readUsersOfGroups = ServiceMethod({ - auther: ServerOnlyAuther, + export const readUsersOfGroups = serviceMethod({ + authorizer: ServerOnlyAuther, paramsSchema: z.object({ groups: z.array(z.object({ groupId: z.number(), @@ -333,8 +333,8 @@ export namespace GroupMethods { } }) - export const readGroupsOfUser = ServiceMethod({ - auther: ServerOnlyAuther, + export const readGroupsOfUser = serviceMethod({ + authorizer: ServerOnlyAuther, paramsSchema: z.object({ userId: z.number(), }), diff --git a/src/services/images/methods.ts b/src/services/images/methods.ts index 78292c940..ec8222a7b 100644 --- a/src/services/images/methods.ts +++ b/src/services/images/methods.ts @@ -6,7 +6,7 @@ import { ImageSchemas } from './schemas' import { ServerError } from '@/services/error' import { createFile } from '@/services/store/createFile' import logger from '@/lib/logger' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import sharp from 'sharp' @@ -21,8 +21,8 @@ export namespace ImageMethods { * All images are saved as avif (except the original). * @param collectionId - The id of the collection to add the image to */ - export const create = ServiceMethod({ - auther: () => ImageAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => ImageAuthers.create.dynamicFields({}), paramsSchema: z.object({ collectionId: z.number(), }), @@ -70,8 +70,8 @@ export namespace ImageMethods { * Creates many images from files. * The method will resize the images to the correct sizes and save them to the store. */ - export const createMany = ServiceMethod({ - auther: () => ImageAuthers.createMany.dynamicFields({}), + export const createMany = serviceMethod({ + authorizer: () => ImageAuthers.createMany.dynamicFields({}), paramsSchema: z.object({ useFileName: z.boolean(), collectionId: z.number(), @@ -101,8 +101,8 @@ export namespace ImageMethods { * @param name - the name of the image * @param config - the config for the image (special) */ - const createSourceless = ServiceMethod({ - auther: () => ImageAuthers.createSourcelessImage.dynamicFields({}), + const createSourceless = serviceMethod({ + authorizer: () => ImageAuthers.createSourcelessImage.dynamicFields({}), paramsSchema: z.object({ name: z.string(), special: z.nativeEnum(SpecialImage), @@ -136,8 +136,8 @@ export namespace ImageMethods { /** * Reads an image by id. */ - export const read = ServiceMethod({ - auther: () => ImageAuthers.read.dynamicFields({}), + export const read = serviceMethod({ + authorizer: () => ImageAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -156,8 +156,8 @@ export namespace ImageMethods { /** * Reads a page of images in a collection by collectionId. */ - export const readPage = ServiceMethod({ - auther: () => ImageAuthers.readPage.dynamicFields({}), + export const readPage = serviceMethod({ + authorizer: () => ImageAuthers.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -182,8 +182,8 @@ export namespace ImageMethods { * Reads a special image by name (special atr.). * In the case that the special image does not exist (bad state) a "bad" image will be created. */ - export const readSpecial = ServiceMethod({ - auther: () => ImageAuthers.readSpecial.dynamicFields({}), + export const readSpecial = serviceMethod({ + authorizer: () => ImageAuthers.readSpecial.dynamicFields({}), paramsSchema: z.object({ special: z.nativeEnum(SpecialImage) }), @@ -206,8 +206,8 @@ export namespace ImageMethods { /** * Update a image by id and data. Also can give the image a new license by data.licenseId. */ - export const update = ServiceMethod({ - auther: () => ImageAuthers.update.dynamicFields({}), + export const update = serviceMethod({ + authorizer: () => ImageAuthers.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -228,8 +228,8 @@ export namespace ImageMethods { } }) - export const destroy = ServiceMethod({ - auther: () => ImageAuthers.destroy.dynamicFields({}), + export const destroy = serviceMethod({ + authorizer: () => ImageAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/licenses/methods.ts b/src/services/licenses/methods.ts index 2eb48af82..bfbaefb33 100644 --- a/src/services/licenses/methods.ts +++ b/src/services/licenses/methods.ts @@ -2,26 +2,26 @@ import '@pn-server-only' import { LicenseSchemas } from './schemas' import { LicenseAuthers } from './authers' import { ServerError } from '@/services/error' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { z } from 'zod' export namespace LicenseMethods { - export const create = ServiceMethod({ - auther: () => LicenseAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => LicenseAuthers.create.dynamicFields({}), dataSchema: LicenseSchemas.create, method: async ({ prisma, data }) => await prisma.license.create({ data, }), }) - export const readAll = ServiceMethod({ - auther: () => LicenseAuthers.destroy.dynamicFields({}), + export const readAll = serviceMethod({ + authorizer: () => LicenseAuthers.destroy.dynamicFields({}), method: async ({ prisma }) => await prisma.license.findMany() }) - export const destroy = ServiceMethod({ + export const destroy = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - auther: () => LicenseAuthers.destroy.dynamicFields({}), + authorizer: () => LicenseAuthers.destroy.dynamicFields({}), method: async ({ prisma, params }) => { const { name: licenseName } = await prisma.license.findUniqueOrThrow({ where: { id: params.id }, @@ -44,12 +44,12 @@ export namespace LicenseMethods { await prisma.license.delete({ where: { id: params.id } }) } }) - export const update = ServiceMethod({ + export const update = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), dataSchema: LicenseSchemas.update, - auther: () => LicenseAuthers.update.dynamicFields({}), + authorizer: () => LicenseAuthers.update.dynamicFields({}), method: async ({ prisma, params, data }) => { await prisma.license.update({ where: { diff --git a/src/services/lockers/locations/methods.ts b/src/services/lockers/locations/methods.ts index 8932fbac8..145d05d3c 100644 --- a/src/services/lockers/locations/methods.ts +++ b/src/services/lockers/locations/methods.ts @@ -1,6 +1,6 @@ import { LockerLocationAuthers } from './authers' import { LockersSchemas } from '@/services/lockers/schemas' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' export namespace LockerLocationMethods { /** @@ -10,8 +10,8 @@ export namespace LockerLocationMethods { * * @returns The newly created locker location object. */ - export const create = ServiceMethod({ - auther: () => LockerLocationAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => LockerLocationAuthers.create.dynamicFields({}), dataSchema: LockersSchemas.createLocation, method: async ({ prisma, data }) => prisma.lockerLocation.create({ data: { @@ -26,8 +26,8 @@ export namespace LockerLocationMethods { * * @returns All locker location objects. */ - export const readAll = ServiceMethod({ - auther: () => LockerLocationAuthers.readAll.dynamicFields({}), + export const readAll = serviceMethod({ + authorizer: () => LockerLocationAuthers.readAll.dynamicFields({}), method: async ({ prisma }) => prisma.lockerLocation.findMany() }) } diff --git a/src/services/lockers/methods.ts b/src/services/lockers/methods.ts index 01bf5dd37..47f19b79c 100644 --- a/src/services/lockers/methods.ts +++ b/src/services/lockers/methods.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { lockerReservationIncluder } from './reservations/config' import { LockerAuthers } from './authers' import { LockersSchemas } from './schemas' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { ServerError } from '@/services/error' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' @@ -40,8 +40,8 @@ export namespace LockerMethods { * * @returns The newly created locker object. */ - export const create = ServiceMethod({ - auther: () => LockerAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => LockerAuthers.create.dynamicFields({}), dataSchema: LockersSchemas.create, method: async ({ prisma, data }) => { console.log(data) @@ -59,8 +59,8 @@ export namespace LockerMethods { * * @returns The locker object. */ - export const read = ServiceMethod({ - auther: () => LockerAuthers.read.dynamicFields({}), + export const read = serviceMethod({ + authorizer: () => LockerAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -85,8 +85,8 @@ export namespace LockerMethods { * * @returns A list of locker objects. */ - export const readPage = ServiceMethod({ - auther: () => LockerAuthers.readPage.dynamicFields({}), + export const readPage = serviceMethod({ + authorizer: () => LockerAuthers.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), z.object({ diff --git a/src/services/lockers/reservations/methods.ts b/src/services/lockers/reservations/methods.ts index 23631abeb..a40f3ff00 100644 --- a/src/services/lockers/reservations/methods.ts +++ b/src/services/lockers/reservations/methods.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { LockerReservationAuthers } from './authers' import { LockerReservationSchemas } from './schemas' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { Smorekopp } from '@/services/error' import { GroupMethods } from '@/services/groups/methods' import { z } from 'zod' @@ -16,8 +16,8 @@ export namespace LockerReservationMethods { * * @returns The newly created reservation object. */ - export const create = ServiceMethod({ - auther: () => LockerReservationAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => LockerReservationAuthers.create.dynamicFields({}), paramsSchema: z.object({ lockerId: z.number(), }), @@ -63,8 +63,8 @@ export namespace LockerReservationMethods { * * @returns The updated reservation object. */ - export const read = ServiceMethod({ - auther: () => LockerReservationAuthers.read.dynamicFields({}), + export const read = serviceMethod({ + authorizer: () => LockerReservationAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -83,8 +83,8 @@ export namespace LockerReservationMethods { * * @returns The updated reservation object. */ - export const update = ServiceMethod({ - auther: () => LockerReservationAuthers.update.dynamicFields({}), + export const update = serviceMethod({ + authorizer: () => LockerReservationAuthers.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/notifications/channel/methods.ts b/src/services/notifications/channel/methods.ts index 04fef2d48..dfea0ef3a 100644 --- a/src/services/notifications/channel/methods.ts +++ b/src/services/notifications/channel/methods.ts @@ -3,7 +3,7 @@ import { NotificationChannelAuthers } from './authers' import { NotificationChannelSchemas } from './schemas' import { NotificationChannelConfig } from './config' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { DEFAULT_NOTIFICATION_ALIAS } from '@/services/notifications/email/config' import { NotificationConfig } from '@/services/notifications/config' import { ServerError } from '@/services/error' @@ -13,8 +13,8 @@ import type { ExpandedNotificationChannel, NotificationMethodGeneral } from '@/s export namespace NotificationChannelMethods { - export const create = ServiceMethod({ - auther: () => NotificationChannelAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => NotificationChannelAuthers.create.dynamicFields({}), dataSchema: NotificationChannelSchemas.create, opensTransaction: true, paramsSchema: z.object({ @@ -101,15 +101,15 @@ export namespace NotificationChannelMethods { } }) - export const readMany = ServiceMethod({ - auther: () => NotificationChannelAuthers.read.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => NotificationChannelAuthers.read.dynamicFields({}), method: async ({ prisma }) => await prisma.notificationChannel.findMany({ include: NotificationChannelConfig.includer, }) }) - export const readDefault = ServiceMethod({ - auther: () => NotificationChannelAuthers.read.dynamicFields({}), + export const readDefault = serviceMethod({ + authorizer: () => NotificationChannelAuthers.read.dynamicFields({}), method: async ({ prisma }) => await prisma.notificationChannel.findMany({ where: { defaultMethods: { @@ -122,8 +122,8 @@ export namespace NotificationChannelMethods { }) }) - export const update = ServiceMethod({ - auther: () => NotificationChannelAuthers.update.dynamicFields({}), + export const update = serviceMethod({ + authorizer: () => NotificationChannelAuthers.update.dynamicFields({}), dataSchema: NotificationChannelSchemas.update, paramsSchema: z.object({ id: z.number(), @@ -131,7 +131,7 @@ export namespace NotificationChannelMethods { defaultMethods: NotificationSchemas.notificationMethodFields, }), opensTransaction: true, - method: async ({ prisma, data, params, session }) => { + method: async ({ prisma, data, params }) => { if (!NotificationChannelSchemas.validateMethods(params.availableMethods, params.defaultMethods)) { throw new ServerError('BAD PARAMETERS', 'Default methods cannot exceed available methods.') } @@ -153,8 +153,7 @@ export namespace NotificationChannelMethods { // Not allowed to change the parent of ROOT if (channel.special !== 'ROOT') { - const allChannels = await readMany.client(prisma).execute({ - session, + const allChannels = await readMany({ bypassAuth: true, }) @@ -216,8 +215,8 @@ export namespace NotificationChannelMethods { }) // It doesn't seem that this function is used yet. -Theodor - export const destroy = ServiceMethod({ - auther: () => NotificationChannelAuthers.destroy.dynamicFields({}), + export const destroy = serviceMethod({ + authorizer: () => NotificationChannelAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/notifications/methods.ts b/src/services/notifications/methods.ts index b905a8bfe..983aa839d 100644 --- a/src/services/notifications/methods.ts +++ b/src/services/notifications/methods.ts @@ -4,7 +4,7 @@ import { NotificationConfig } from './config' import { NotificationChannelConfig } from './channel/config' import { dispatchEmailNotifications } from './email/dispatch' import { NotificationAuthers } from './authers' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { ServerOnly } from '@/auth/auther/ServerOnly' import { UserConfig } from '@/services/users/config' import { z } from 'zod' @@ -36,8 +36,8 @@ export namespace NotificationMethods { * @param data - The detailed data for dispatching the notification. * @returns A promise that resolves with an object containing the dispatched notification and the number of recipients. */ - export const create = ServiceMethod({ - auther: () => NotificationAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => NotificationAuthers.create.dynamicFields({}), dataSchema: NotificationSchemas.create, method: async ({ prisma, data }) => { // This prevent notifications from beeing sent during seeding @@ -119,8 +119,8 @@ export namespace NotificationMethods { * @param message - The message content of the notification. * @returns A promise that resolves with an object containing the dispatched notification and the number of recipients. */ - export const createSpecial = ServiceMethod({ - auther: ServerOnly, + export const createSpecial = serviceMethod({ + authorizer: ServerOnly, paramsSchema: z.object({ special: z.nativeEnum(SpecialNotificationChannel), }), @@ -132,7 +132,7 @@ export namespace NotificationMethods { } }) - return await create.client(prisma).execute({ + return await create({ session, bypassAuth: true, data: { diff --git a/src/services/notifications/subscription/methods.ts b/src/services/notifications/subscription/methods.ts index b723c70e8..c51553eb2 100644 --- a/src/services/notifications/subscription/methods.ts +++ b/src/services/notifications/subscription/methods.ts @@ -5,22 +5,22 @@ import { NotificationChannelConfig } from '@/services/notifications/channel/conf import { NotificationConfig } from '@/services/notifications/config' import { NotificationChannelSchemas } from '@/services/notifications/channel/schemas' import { NotificationChannelMethods } from '@/services/notifications/channel/methods' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { ServerOnly } from '@/auth/auther/ServerOnly' import { ServerError } from '@/services/error' import { z } from 'zod' -import type { PrismaPossibleTransaction } from '@/services/ServiceMethod' +import type { Prisma } from '@prisma/client' import type { Subscription } from './Types' import type { NotificationMethodGeneral } from '@/services/notifications/Types' export namespace NotificationSubscriptionMethods { - export const read = ServiceMethod({ + export const read = serviceMethod({ paramsSchema: z.object({ userId: z.number(), }), - auther: ({ params }) => NotificationSubscriptionAuthers.read.dynamicFields(params), + authorizer: ({ params }) => NotificationSubscriptionAuthers.read.dynamicFields(params), method: async ({ prisma, params }) => await prisma.notificationSubscription.findMany({ where: { userId: params.userId, @@ -29,14 +29,14 @@ export namespace NotificationSubscriptionMethods { }), }) - export const createDefault = ServiceMethod({ - auther: ServerOnly, + export const createDefault = serviceMethod({ + authorizer: ServerOnly, paramsSchema: z.object({ userId: z.number(), }), opensTransaction: true, method: async ({ prisma, params, session }) => { - const channels = await NotificationChannelMethods.readDefault.client(prisma).execute({ + const channels = await NotificationChannelMethods.readDefault({ session, bypassAuth: true, }) @@ -66,7 +66,7 @@ export namespace NotificationSubscriptionMethods { // eslint-disable-next-line async function createTransactionPart( - prisma: PrismaPossibleTransaction, + prisma: Prisma.TransactionClient, userId: number, channelId: number, methods: NotificationMethodGeneral @@ -159,8 +159,8 @@ export namespace NotificationSubscriptionMethods { }) } - export const update = ServiceMethod({ - auther: ({ params }) => NotificationSubscriptionAuthers.update.dynamicFields(params), + export const update = serviceMethod({ + authorizer: ({ params }) => NotificationSubscriptionAuthers.update.dynamicFields(params), paramsSchema: z.object({ userId: z.number(), }), diff --git a/src/services/permissions/methods.ts b/src/services/permissions/methods.ts index 4044de137..df3ef4ab6 100644 --- a/src/services/permissions/methods.ts +++ b/src/services/permissions/methods.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { PermissionAuthers } from './auther' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { invalidateAllUserSessionData, invalidateManyUserSessionData } from '@/services/auth/invalidateSession' import { groupsWithRelationsIncluder } from '@/services/groups/config' @@ -11,14 +11,14 @@ import { z } from 'zod' export namespace PermissionMethods { - export const readDefaultPermissions = ServiceMethod({ - auther: () => PermissionAuthers.readDefaultPermissions.dynamicFields({}), + export const readDefaultPermissions = serviceMethod({ + authorizer: () => PermissionAuthers.readDefaultPermissions.dynamicFields({}), method: async ({ prisma }) => (await prisma.defaultPermission.findMany()).map(perm => perm.permission) }) - export const readPermissionsOfUser = ServiceMethod({ - auther: ServerOnlyAuther, + export const readPermissionsOfUser = serviceMethod({ + authorizer: ServerOnlyAuther, paramsSchema: z.object({ userId: z.number(), }), @@ -50,8 +50,8 @@ export namespace PermissionMethods { } }) - export const readPermissionsOfGroup = ServiceMethod({ - auther: () => PermissionAuthers.readGroupPermissions.dynamicFields({}), + export const readPermissionsOfGroup = serviceMethod({ + authorizer: () => PermissionAuthers.readGroupPermissions.dynamicFields({}), paramsSchema: z.object({ groupId: z.number() }), @@ -62,8 +62,8 @@ export namespace PermissionMethods { })).map(permission => permission.permission) }) - export const readPermissionMatrix = ServiceMethod({ - auther: () => PermissionAuthers.readPermissionMatrix.dynamicFields({}), + export const readPermissionMatrix = serviceMethod({ + authorizer: () => PermissionAuthers.readPermissionMatrix.dynamicFields({}), method: async ({ prisma }) => { const groupsPermission = await prisma.group.findMany({ include: { @@ -80,8 +80,8 @@ export namespace PermissionMethods { } }) - export const updateDefaultPermissions = ServiceMethod({ - auther: () => PermissionAuthers.updateDefaultPermissions.dynamicFields({}), + export const updateDefaultPermissions = serviceMethod({ + authorizer: () => PermissionAuthers.updateDefaultPermissions.dynamicFields({}), dataSchema: z.object({ permissions: z.nativeEnum(Permission).array(), }), @@ -108,8 +108,8 @@ export namespace PermissionMethods { } }) - export const updateGroupPermission = ServiceMethod({ - auther: () => PermissionAuthers.updateGroupPermission.dynamicFields({}), + export const updateGroupPermission = serviceMethod({ + authorizer: () => PermissionAuthers.updateGroupPermission.dynamicFields({}), paramsSchema: z.object({ groupId: z.number(), permission: z.nativeEnum(Permission), diff --git a/src/services/shop/product/methods.ts b/src/services/shop/product/methods.ts index 4da287b6f..11c0ba5f8 100644 --- a/src/services/shop/product/methods.ts +++ b/src/services/shop/product/methods.ts @@ -1,14 +1,14 @@ import { ProductAuthers } from './authers' import { ProductSchemas } from './schemas' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import '@pn-server-only' import { ServerError } from '@/services/error' import { z } from 'zod' import type { ExtendedProduct } from './Types' export namespace ProductMethods { - export const create = ServiceMethod({ - auther: () => ProductAuthers.create.dynamicFields({}), + export const create = serviceMethod({ + authorizer: () => ProductAuthers.create.dynamicFields({}), dataSchema: ProductSchemas.create, method: async ({ prisma, data }) => prisma.product.create({ data: { @@ -19,8 +19,8 @@ export namespace ProductMethods { }) }) - export const createForShop = ServiceMethod({ - auther: () => ProductAuthers.create.dynamicFields({}), + export const createForShop = serviceMethod({ + authorizer: () => ProductAuthers.create.dynamicFields({}), paramsSchema: z.object({ shopId: z.number(), }), @@ -44,8 +44,8 @@ export namespace ProductMethods { }) }) - export const createShopConnection = ServiceMethod({ - auther: () => ProductAuthers.createShopConnection.dynamicFields({}), + export const createShopConnection = serviceMethod({ + authorizer: () => ProductAuthers.createShopConnection.dynamicFields({}), dataSchema: ProductSchemas.createShopConnection, method: async ({ prisma, data }) => prisma.shopProduct.create({ data: { @@ -64,13 +64,13 @@ export namespace ProductMethods { }) }) - export const readMany = ServiceMethod({ - auther: () => ProductAuthers.read.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => ProductAuthers.read.dynamicFields({}), method: async ({ prisma }) => await prisma.product.findMany() }) - export const read = ServiceMethod({ - auther: () => ProductAuthers.read.dynamicFields({}), + export const read = serviceMethod({ + authorizer: () => ProductAuthers.read.dynamicFields({}), paramsSchema: z.object({ productId: z.number(), }), @@ -88,8 +88,8 @@ export namespace ProductMethods { }) }) - export const readByBarCode = ServiceMethod({ - auther: () => ProductAuthers.read.dynamicFields({}), + export const readByBarCode = serviceMethod({ + authorizer: () => ProductAuthers.read.dynamicFields({}), dataSchema: ProductSchemas.readByBarCode, method: async ({ prisma, data }): Promise => { if (!data.barcode) { @@ -130,8 +130,8 @@ export namespace ProductMethods { } }) - export const update = ServiceMethod({ - auther: () => ProductAuthers.update.dynamicFields({}), + export const update = serviceMethod({ + authorizer: () => ProductAuthers.update.dynamicFields({}), dataSchema: ProductSchemas.update, method: async ({ prisma, data }) => prisma.product.update({ where: { @@ -145,8 +145,8 @@ export namespace ProductMethods { }) }) - export const updateForShop = ServiceMethod({ - auther: () => ProductAuthers.update.dynamicFields({}), + export const updateForShop = serviceMethod({ + authorizer: () => ProductAuthers.update.dynamicFields({}), dataSchema: ProductSchemas.updateForShop, paramsSchema: z.object({ shopId: z.number(), diff --git a/src/services/shop/purchase/methods.ts b/src/services/shop/purchase/methods.ts index bcd826167..874914fcf 100644 --- a/src/services/shop/purchase/methods.ts +++ b/src/services/shop/purchase/methods.ts @@ -2,15 +2,15 @@ import '@pn-server-only' import { PurchaseAuthers } from './authers' import { PurchaseSchemas } from './schemas' import { ServerError } from '@/services/error' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { UserMethods } from '@/services/users/methods' import { UserConfig } from '@/services/users/config' import { PermissionMethods } from '@/services/permissions/methods' import { PurchaseMethod } from '@prisma/client' export namespace PurchaseMethods { - export const createByStudentCard = ServiceMethod({ - auther: async ({ data }) => { + export const createByStudentCard = serviceMethod({ + authorizer: async ({ data }) => { let user try { user = await UserMethods.read({ diff --git a/src/services/shop/shop/methods.ts b/src/services/shop/shop/methods.ts index 59d86b79b..29b42fb19 100644 --- a/src/services/shop/shop/methods.ts +++ b/src/services/shop/shop/methods.ts @@ -1,26 +1,26 @@ import { ShopAuthers } from './authers' import { ShopSchemas } from './schema' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import '@pn-server-only' import { z } from 'zod' import type { ExtendedShop } from './Types' export namespace ShopMethods { - export const create = ServiceMethod({ + export const create = serviceMethod({ dataSchema: ShopSchemas.create, - auther: () => ShopAuthers.create.dynamicFields({}), + authorizer: () => ShopAuthers.create.dynamicFields({}), method: async ({ prisma, data }) => prisma.shop.create({ data }) }) - export const readMany = ServiceMethod({ - auther: () => ShopAuthers.read.dynamicFields({}), + export const readMany = serviceMethod({ + authorizer: () => ShopAuthers.read.dynamicFields({}), method: ({ prisma }) => prisma.shop.findMany(), }) - export const read = ServiceMethod({ - auther: () => ShopAuthers.read.dynamicFields({}), + export const read = serviceMethod({ + authorizer: () => ShopAuthers.read.dynamicFields({}), paramsSchema: z.object({ shopId: z.number(), }), diff --git a/src/services/users/methods.ts b/src/services/users/methods.ts index 5e74e236a..038fde9cc 100644 --- a/src/services/users/methods.ts +++ b/src/services/users/methods.ts @@ -9,7 +9,7 @@ import { updateUserOmegaMembershipGroup } from '@/services/groups/omegaMembershi import { sendUserInvitationEmail } from '@/services/notifications/email/systemMail/userInvitivation' import { readOmegaMembershipGroup } from '@/services/groups/omegaMembershipGroups/read' import { UserSchemas } from '@/services/users/schemas' -import { ServiceMethod } from '@/services/ServiceMethod' +import { serviceMethod } from '@/services/serviceMethod' import { ImageMethods } from '@/services/images/methods' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { ServerError } from '@/services/error' @@ -26,9 +26,9 @@ export namespace UserMethods { * This Method creates an user by invitation, and sends the invitation email. * WARNING: This should not be used to create users registered by Feide. */ - export const create = ServiceMethod({ + export const create = serviceMethod({ dataSchema: UserSchemas.create, - auther: () => UserAuthers.create.dynamicFields({}), + authorizer: () => UserAuthers.create.dynamicFields({}), method: async ({ prisma, data }) => { const omegaMembership = await readOmegaMembershipGroup('EXTERNAL') const omegaOrder = await readCurrentOmegaOrder() @@ -56,14 +56,14 @@ export namespace UserMethods { } }) - export const read = ServiceMethod({ + export const read = serviceMethod({ paramsSchema: z.object({ username: z.string().optional(), id: z.coerce.number().optional(), email: z.string().optional(), studentCard: z.string().optional(), }), - auther: ({ params }) => UserAuthers.read.dynamicFields(params), + authorizer: ({ params }) => UserAuthers.read.dynamicFields(params), method: async ({ prisma, params }) => await prisma.user.findUniqueOrThrow({ where: { id: params.id, @@ -73,14 +73,14 @@ export namespace UserMethods { }) }) - export const readOrNull = ServiceMethod({ + export const readOrNull = serviceMethod({ paramsSchema: z.object({ username: z.string().optional(), id: z.coerce.number().optional(), email: z.string().optional(), studentCard: z.string().optional(), }), - auther: ({ params }) => UserAuthers.read.dynamicFields(params), + authorizer: ({ params }) => UserAuthers.read.dynamicFields(params), method: async ({ prisma, params }) => await prisma.user.findUnique({ where: { id: params.id, // This is a bit wierd, but now ts is satisfied. @@ -90,11 +90,11 @@ export namespace UserMethods { }) }) - export const readProfile = ServiceMethod({ + export const readProfile = serviceMethod({ paramsSchema: z.object({ username: z.string(), }), - auther: ({ params }) => UserAuthers.readProfile.dynamicFields({ username: params.username }), + authorizer: ({ params }) => UserAuthers.readProfile.dynamicFields({ username: params.username }), method: async ({ prisma, params }) => { const defaultProfileImage = await ImageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, @@ -123,7 +123,7 @@ export namespace UserMethods { } }) - export const readPage = ServiceMethod({ + export const readPage = serviceMethod({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -141,7 +141,7 @@ export namespace UserMethods { }).nullable().optional() }) ), - auther: () => UserAuthers.readPage.dynamicFields({}), + authorizer: () => UserAuthers.readPage.dynamicFields({}), method: async ({ prisma, params }): Promise => { const { page, details } = params.paging const words = details.partOfName.split(' ') @@ -250,8 +250,8 @@ export namespace UserMethods { } }) - export const connectStudentCard = ServiceMethod({ - auther: () => UserAuthers.connectStudentCard.dynamicFields({}), + export const connectStudentCard = serviceMethod({ + authorizer: () => UserAuthers.connectStudentCard.dynamicFields({}), dataSchema: UserSchemas.connectStudentCard, opensTransaction: true, method: async ({ prisma, data }) => { @@ -296,11 +296,11 @@ export namespace UserMethods { } }) - export const registerStudentCardInQueue = ServiceMethod({ + export const registerStudentCardInQueue = serviceMethod({ paramsSchema: z.object({ userId: z.number(), }), - auther: ({ params }) => UserAuthers.registerStudentCardInQueue.dynamicFields(params), + authorizer: ({ params }) => UserAuthers.registerStudentCardInQueue.dynamicFields(params), method: async (args) => { const expiry = (new Date()).getTime() + UserConfig.studentCardRegistrationExpiry * 60 * 1000 await args.prisma.registerStudentCardQueue.upsert({ @@ -322,10 +322,10 @@ export namespace UserMethods { } }) - export const update = ServiceMethod({ + export const update = serviceMethod({ paramsSchema: z.union([z.object({ id: z.number() }), z.object({ username: z.string() })]), dataSchema: UserSchemas.update, - auther: () => UserAuthers.update.dynamicFields({}), + authorizer: () => UserAuthers.update.dynamicFields({}), method: async ({ prisma: prisma_, params, data }) => prisma_.user.update({ where: params, data @@ -333,12 +333,12 @@ export namespace UserMethods { }) - export const updatePassword = ServiceMethod({ + export const updatePassword = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), dataSchema: UserSchemas.updatePassword, - auther: ({ params }) => UserAuthers.updatePassword.dynamicFields({ userId: params.id }), + authorizer: ({ params }) => UserAuthers.updatePassword.dynamicFields({ userId: params.id }), method: async ({ prisma, data, params }) => { const passwordHash = await hashAndEncryptPassword(data.password) @@ -355,11 +355,11 @@ export namespace UserMethods { } }) - export const registerNewEmail = ServiceMethod({ + export const registerNewEmail = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - auther: ({ params }) => UserAuthers.registerNewEmail.dynamicFields({ userId: params.id }), + authorizer: ({ params }) => UserAuthers.registerNewEmail.dynamicFields({ userId: params.id }), dataSchema: UserSchemas.registerNewEmail, method: async ({ prisma, params, data }) => { const storedUser = await prisma.user.findUniqueOrThrow({ @@ -419,14 +419,14 @@ export namespace UserMethods { * @param rawdata - Registration data. * @returns null */ - export const register = ServiceMethod({ + export const register = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), dataSchema: UserSchemas.register, - auther: ({ params }) => UserAuthers.register.dynamicFields({ userId: params.id }), + authorizer: ({ params }) => UserAuthers.register.dynamicFields({ userId: params.id }), opensTransaction: true, - method: async ({ prisma, data, params, session }) => { + method: async ({ prisma, data, params }) => { const { sex, password, mobile, allergies } = data if (!password) throw new ServerError('BAD PARAMETERS', 'Passord er obligatorisk.') @@ -498,11 +498,10 @@ export namespace UserMethods { ]) try { - await NotificationSubscriptionMethods.createDefault.client(prisma).execute({ + await NotificationSubscriptionMethods.createDefault({ params: { userId: params.id, }, - session, bypassAuth: true, }) } catch (error) { @@ -525,8 +524,8 @@ export namespace UserMethods { return results[0] } }) - export const readUserWithBalance = ServiceMethod({ - auther: ({ params }) => UserAuthers.read.dynamicFields({ + export const readUserWithBalance = serviceMethod({ + authorizer: ({ params }) => UserAuthers.read.dynamicFields({ username: params.username || '', }), paramsSchema: z.object({ @@ -554,11 +553,11 @@ export namespace UserMethods { /** * This function deletes a user from the database. */ - export const destroy = ServiceMethod({ + export const destroy = serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - auther: () => UserAuthers.destroy.dynamicFields({}), + authorizer: () => UserAuthers.destroy.dynamicFields({}), method: async ({ prisma, params }) => { await prisma.user.delete({ where: { diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index d3ba99af7..12535e7a7 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -21,7 +21,7 @@ export async function readVisibilityForAdminAction(id: number): Promise readVisibilityCollapsed(id)), // TODO: Fix Authing here. The bypass should be false - safeServerCall(() => GroupMethods.readGroupsStructured({ session: null, bypassAuth: true })) + safeServerCall(() => GroupMethods.readGroupsStructured({ bypassAuth: true })) ]) if (!visibilityRes.success || !groupsRes.success) return createActionError('UNKNOWN ERROR', 'noe gikk galt') diff --git a/tests/services/service-method.test.ts b/tests/services/service-method.test.ts index 0416ae528..c61cdd9a5 100644 --- a/tests/services/service-method.test.ts +++ b/tests/services/service-method.test.ts @@ -1,58 +1,77 @@ -import { RequireNothing } from "@/auth/auther/RequireNothing"; -import { RequireServerOnly } from "@/auth/auther/ServerOnly"; -import { Session } from "@/auth/Session"; -import { ServiceMethod, ServiceMethodContext } from "@/services/ServiceMethod"; -import { describe } from "@jest/globals"; -import { z } from "zod"; -import { default as globalPrisma } from "@/prisma"; +import { RequireNothing } from '@/auth/auther/RequireNothing' +import { RequireServerOnly } from '@/auth/auther/ServerOnly' +import { Session } from '@/auth/Session' +import { serviceMethod } from '@/services/serviceMethod' +import { default as globalPrisma } from '@/prisma' +import { describe, expect, test } from '@jest/globals' +import { z } from 'zod' describe('service method', () => { describe('simple', () => { - const addPositiveOnly = ServiceMethod({ - auther: (a, b) => { + const addPositiveOnly = serviceMethod({ + authorizer: ({ data: { a, b } }) => { if (a < 0 || b < 0) { return RequireServerOnly.staticFields({}).dynamicFields({}) } return RequireNothing.staticFields({}).dynamicFields({}) }, - schemas: [z.number(), z.number()], - method: (a, b) => a + b, + dataSchema: z.object({ + a: z.number(), + b: z.number(), + }), + method: ({ data: { a, b } }) => a + b, }) test('method result', async () => { - const res = await addPositiveOnly(1, 2) - + const res = await addPositiveOnly({ + data: { + a: 1, + b: 2, + }, + }) + expect(res).toBe(3) }) - + test('auth fail', async () => { - await expect(addPositiveOnly(-1, 2)).rejects.toThrow() + await expect(addPositiveOnly({ + data: { + a: -1, + b: 2, + }, + })).rejects.toThrow() }) - + test('bypass auth', async () => { - const res = await addPositiveOnly(-1, 2, { bypassAuth: true }) - + const res = await addPositiveOnly({ + data: { + a: -1, + b: 2, + }, + bypassAuth: true, + }) + expect(res).toBe(1) }) }) describe('nested', () => { // Simple service method that just returns its own context - const inner = ServiceMethod({ - auther: () => RequireNothing.staticFields({}).dynamicFields({}), + const inner = serviceMethod({ + authorizer: () => RequireNothing.staticFields({}).dynamicFields({}), method: async (context) => context, }) - + // Outer service method that calls the inner one and returns its context - const outer = ServiceMethod({ - auther: () => RequireNothing.staticFields({}).dynamicFields({}), - method: async () => await inner(), + const outer = serviceMethod({ + authorizer: () => RequireNothing.staticFields({}).dynamicFields({}), + method: async () => await inner({}), }) test('nested context global defaults', async () => { - const res = await outer() - + const res = await outer({}) + expect(res.bypassAuth).toBe(false) expect(res.session).toBeInstanceOf(Session) expect(res.prisma).toBe(globalPrisma) @@ -60,7 +79,7 @@ describe('service method', () => { test('nested context override bypassAuth', async () => { const res = await outer({ bypassAuth: true }) - + expect(res.bypassAuth).toBe(true) expect(res.session).toBeInstanceOf(Session) expect(res.prisma).toBe(globalPrisma) @@ -75,7 +94,7 @@ describe('service method', () => { }) const res = await outer({ session: customSession }) - + expect(res.bypassAuth).toBe(false) expect(res.session).toBe(customSession) expect(res.prisma).toBe(globalPrisma) @@ -84,11 +103,11 @@ describe('service method', () => { test('nested context override prisma', async () => { await globalPrisma.$transaction(async (tx) => { const res = await outer({ prisma: tx }) - + expect(res.bypassAuth).toBe(false) expect(res.session).toBeInstanceOf(Session) expect(res.prisma).toBe(tx) }) }) }) -}) \ No newline at end of file +}) From edb1e8e84e3497377bcdbbab1c4e90ffd93e0fc7 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sun, 21 Sep 2025 16:10:51 +0200 Subject: [PATCH 15/24] refactor: make prisma client use named export --- src/auth/authoptions.ts | 2 +- src/lib/feide/userRoutines.ts | 2 +- src/prisma/client.ts | 12 ++++++++++++ src/prisma/index.ts | 7 ------- src/prisma/seeder/seed.ts | 2 +- src/services/auth/feideAccounts/create.ts | 2 +- src/services/auth/feideAccounts/read.ts | 2 +- src/services/auth/feideAccounts/update.ts | 2 +- src/services/auth/invalidateSession.ts | 2 +- src/services/cms/articleCategories/create.ts | 2 +- src/services/cms/articleCategories/destroy.ts | 2 +- src/services/cms/articleCategories/read.ts | 2 +- src/services/cms/articleCategories/update.ts | 2 +- src/services/cms/articleSections/create.ts | 2 +- src/services/cms/articleSections/destroy.ts | 2 +- src/services/cms/articleSections/read.ts | 2 +- src/services/cms/articleSections/update.ts | 2 +- src/services/cms/articles/create.ts | 2 +- src/services/cms/articles/destroy.ts | 2 +- src/services/cms/articles/read.ts | 2 +- src/services/cms/articles/update.ts | 2 +- src/services/cms/images/create.ts | 2 +- src/services/cms/images/destoy.ts | 2 +- src/services/cms/images/read.ts | 2 +- src/services/cms/images/update.ts | 2 +- src/services/cms/links/create.ts | 2 +- src/services/cms/links/destroy.ts | 2 +- src/services/cms/links/update.ts | 2 +- src/services/cms/paragraphs/create.ts | 2 +- src/services/cms/paragraphs/destroy.ts | 2 +- src/services/cms/paragraphs/read.ts | 2 +- src/services/cms/paragraphs/update.ts | 2 +- src/services/education/schools/create.ts | 2 +- src/services/education/schools/destroy.ts | 2 +- src/services/education/schools/read.ts | 2 +- src/services/education/schools/update.ts | 2 +- src/services/groups/classes/read.ts | 2 +- src/services/groups/committees/create.ts | 2 +- src/services/groups/committees/destroy.ts | 2 +- src/services/groups/committees/read.ts | 2 +- src/services/groups/committees/update.ts | 2 +- src/services/groups/manualGroups/create.ts | 2 +- src/services/groups/manualGroups/destroy.ts | 2 +- src/services/groups/manualGroups/read.ts | 2 +- src/services/groups/manualGroups/update.ts | 2 +- .../groups/memberships/canEasilyManageMembership.ts | 2 +- src/services/groups/memberships/create.ts | 2 +- src/services/groups/memberships/destroy.ts | 2 +- src/services/groups/memberships/read.ts | 2 +- src/services/groups/memberships/update.ts | 2 +- src/services/groups/omegaMembershipGroups/read.ts | 2 +- src/services/groups/omegaMembershipGroups/update.ts | 2 +- src/services/groups/studyProgrammes/create.ts | 2 +- src/services/groups/studyProgrammes/destroy.ts | 2 +- src/services/groups/studyProgrammes/read.ts | 2 +- src/services/groups/studyProgrammes/update.ts | 2 +- src/services/images/collections/create.ts | 2 +- src/services/images/collections/destroy.ts | 2 +- src/services/images/collections/read.ts | 2 +- src/services/images/collections/update.ts | 2 +- src/services/mail/alias/create.ts | 2 +- src/services/mail/alias/destroy.ts | 2 +- src/services/mail/alias/read.ts | 2 +- src/services/mail/alias/update.ts | 2 +- src/services/mail/create.ts | 2 +- src/services/mail/destroy.ts | 2 +- src/services/mail/list/create.ts | 2 +- src/services/mail/list/destroy.ts | 2 +- src/services/mail/list/read.ts | 2 +- src/services/mail/list/update.ts | 2 +- src/services/mail/mailAddressExternal/create.ts | 2 +- src/services/mail/mailAddressExternal/destroy.ts | 2 +- src/services/mail/mailAddressExternal/read.ts | 2 +- src/services/mail/mailAddressExternal/update.ts | 2 +- src/services/mail/read.ts | 2 +- src/services/news/create.ts | 2 +- src/services/news/destroy.ts | 2 +- src/services/news/read.ts | 2 +- src/services/news/update.ts | 2 +- src/services/notifications/email/dispatch.tsx | 2 +- src/services/ombul/create.ts | 2 +- src/services/ombul/destroy.ts | 2 +- src/services/ombul/read.ts | 2 +- src/services/ombul/update.ts | 2 +- src/services/omegaOrder/create.ts | 2 +- src/services/omegaOrder/read.ts | 2 +- src/services/omegaquotes/create.ts | 2 +- src/services/omegaquotes/read.ts | 2 +- src/services/screens/create.ts | 2 +- src/services/screens/destroy.ts | 2 +- src/services/screens/pages/create.ts | 2 +- src/services/screens/pages/destroy.ts | 2 +- src/services/screens/pages/read.ts | 2 +- src/services/screens/pages/update.ts | 2 +- src/services/screens/read.ts | 2 +- src/services/screens/update.ts | 2 +- src/services/serviceMethod.ts | 2 +- src/services/visibility/create.ts | 2 +- src/services/visibility/destroy.ts | 2 +- src/services/visibility/read.ts | 2 +- src/services/visibility/update.ts | 2 +- src/typings/global.d.ts | 4 ---- tests/services/apiKeys.test.ts | 2 +- tests/services/jobads.test.ts | 2 +- tests/services/service-method.test.ts | 2 +- 105 files changed, 114 insertions(+), 113 deletions(-) create mode 100644 src/prisma/client.ts delete mode 100644 src/prisma/index.ts diff --git a/src/auth/authoptions.ts b/src/auth/authoptions.ts index 44ee5af82..534370b91 100644 --- a/src/auth/authoptions.ts +++ b/src/auth/authoptions.ts @@ -3,7 +3,7 @@ import VevenAdapter from './VevenAdapter' import { decryptAndComparePassword } from './password' import FeideProvider from '@/lib/feide/FeideProvider' import { updateUserStudyProgrammes } from '@/lib/feide/userRoutines' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { readMembershipsOfUser } from '@/services/groups/memberships/read' import { updateEmailForFeideAccount } from '@/services/auth/feideAccounts/update' import { UserMethods } from '@/services/users/methods' diff --git a/src/lib/feide/userRoutines.ts b/src/lib/feide/userRoutines.ts index ce76fa1dc..a60ffecfe 100644 --- a/src/lib/feide/userRoutines.ts +++ b/src/lib/feide/userRoutines.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { fetchStudyProgrammesFromFeide } from './api' import { upsertStudyProgrammes } from '@/services/groups/studyProgrammes/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' export async function updateUserStudyProgrammes(userId: number, accessToken: string) { const feideStudyProgrammes = await fetchStudyProgrammesFromFeide(accessToken) diff --git a/src/prisma/client.ts b/src/prisma/client.ts new file mode 100644 index 000000000..3bc814850 --- /dev/null +++ b/src/prisma/client.ts @@ -0,0 +1,12 @@ +import { PrismaClient } from '@prisma/client' + +// To prevent hot reloading from creating new instances of PrismaClient it is stored in the global object. +// Read more about it in the section "Prevent hot reloading from creating new instances of PrismaClient" here: +// https://www.prisma.io/docs/orm/prisma-client/setup-and-configuration/databases-connections + +// This is how the Prisma docs recommend doing it +const globalForPrisma = global as unknown as { prisma: PrismaClient } + +export const prisma = globalForPrisma.prisma || new PrismaClient() + +if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma diff --git a/src/prisma/index.ts b/src/prisma/index.ts deleted file mode 100644 index dda84f8cb..000000000 --- a/src/prisma/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { PrismaClient } from '@prisma/client' - -const prisma = global.prisma || new PrismaClient() - -if (process.env.NODE_ENV !== 'production') global.prisma = prisma - -export default prisma diff --git a/src/prisma/seeder/seed.ts b/src/prisma/seeder/seed.ts index a18e6b89a..e755cbd1a 100644 --- a/src/prisma/seeder/seed.ts +++ b/src/prisma/seeder/seed.ts @@ -1,5 +1,5 @@ import seed from './src/seeder' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { exit } from 'process' seed( diff --git a/src/services/auth/feideAccounts/create.ts b/src/services/auth/feideAccounts/create.ts index a3fdf6f6c..97aabd6ae 100644 --- a/src/services/auth/feideAccounts/create.ts +++ b/src/services/auth/feideAccounts/create.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { FeideAccount } from '@prisma/client' export async function createFeideAccount({ diff --git a/src/services/auth/feideAccounts/read.ts b/src/services/auth/feideAccounts/read.ts index c250609c1..cd05cdc12 100644 --- a/src/services/auth/feideAccounts/read.ts +++ b/src/services/auth/feideAccounts/read.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { User } from '@prisma/client' /** diff --git a/src/services/auth/feideAccounts/update.ts b/src/services/auth/feideAccounts/update.ts index 963b2a0b9..1877de04e 100644 --- a/src/services/auth/feideAccounts/update.ts +++ b/src/services/auth/feideAccounts/update.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { readJWTPayload } from '@/jwt/jwtReadUnsecure' import { ServerError } from '@/services/error' diff --git a/src/services/auth/invalidateSession.ts b/src/services/auth/invalidateSession.ts index f37e8da52..3afbf26be 100644 --- a/src/services/auth/invalidateSession.ts +++ b/src/services/auth/invalidateSession.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' /** * Invalidate a given user. diff --git a/src/services/cms/articleCategories/create.ts b/src/services/cms/articleCategories/create.ts index 80c3f09b6..181e94426 100644 --- a/src/services/cms/articleCategories/create.ts +++ b/src/services/cms/articleCategories/create.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { createArticleCategoryValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CreateArticleCategoryTypes } from './validation' import type { ExpandedArticleCategory } from './Types' diff --git a/src/services/cms/articleCategories/destroy.ts b/src/services/cms/articleCategories/destroy.ts index 1cb9fd635..079b98458 100644 --- a/src/services/cms/articleCategories/destroy.ts +++ b/src/services/cms/articleCategories/destroy.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { ExpandedArticleCategory } from '@/cms/articleCategories/Types' diff --git a/src/services/cms/articleCategories/read.ts b/src/services/cms/articleCategories/read.ts index 9e6d46bfb..f8a01feea 100644 --- a/src/services/cms/articleCategories/read.ts +++ b/src/services/cms/articleCategories/read.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import type { Image } from '@prisma/client' diff --git a/src/services/cms/articleCategories/update.ts b/src/services/cms/articleCategories/update.ts index 4605d7aa8..d6f1961c7 100644 --- a/src/services/cms/articleCategories/update.ts +++ b/src/services/cms/articleCategories/update.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { updateArticleCategoryValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { UpdateArticleCategoryTypes } from './validation' import type { ExpandedArticleCategory } from '@/cms/articleCategories/Types' diff --git a/src/services/cms/articleSections/create.ts b/src/services/cms/articleSections/create.ts index 4cad9cbef..6fe1c7306 100644 --- a/src/services/cms/articleSections/create.ts +++ b/src/services/cms/articleSections/create.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { articleSectionsRealtionsIncluder } from './ConfigVars' import { createArticleSectionValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CreateArticleSectionTypes } from './validation' import type { ExpandedArticleSection } from './Types' diff --git a/src/services/cms/articleSections/destroy.ts b/src/services/cms/articleSections/destroy.ts index 2d09859e3..1ffbce482 100644 --- a/src/services/cms/articleSections/destroy.ts +++ b/src/services/cms/articleSections/destroy.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { ArticleSection } from '@prisma/client' diff --git a/src/services/cms/articleSections/read.ts b/src/services/cms/articleSections/read.ts index 458d7ceef..bc874ccd8 100644 --- a/src/services/cms/articleSections/read.ts +++ b/src/services/cms/articleSections/read.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { articleSectionsRealtionsIncluder } from '@/cms/articleSections/ConfigVars' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' import type { ExpandedArticleSection } from '@/cms/articleSections/Types' diff --git a/src/services/cms/articleSections/update.ts b/src/services/cms/articleSections/update.ts index f71fd9f44..00b172abe 100644 --- a/src/services/cms/articleSections/update.ts +++ b/src/services/cms/articleSections/update.ts @@ -4,7 +4,7 @@ import { destroyCmsImage } from '@/services/cms/images/destoy' import { destroyCmsLink } from '@/services/cms/links/destroy' import { destroyCmsParagraph } from '@/services/cms/paragraphs/destroy' import { maxImageSize, minImageSize, articleSectionsRealtionsIncluder } from '@/cms/articleSections/ConfigVars' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { createCmsImage } from '@/services/cms/images/create' import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { createCmsLink } from '@/services/cms/links/create' diff --git a/src/services/cms/articles/create.ts b/src/services/cms/articles/create.ts index a8bfdeb66..972ecbbc1 100644 --- a/src/services/cms/articles/create.ts +++ b/src/services/cms/articles/create.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { articleRealtionsIncluder } from './ConfigVars' import { createArticleValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CreateArticleTypes } from './validation' import type { ExpandedArticle } from './Types' diff --git a/src/services/cms/articles/destroy.ts b/src/services/cms/articles/destroy.ts index c27acb3e2..22fa99d6c 100644 --- a/src/services/cms/articles/destroy.ts +++ b/src/services/cms/articles/destroy.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { destroyCmsImage } from '@/cms/images/destoy' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { Article } from '@prisma/client' diff --git a/src/services/cms/articles/read.ts b/src/services/cms/articles/read.ts index 6d6fd17d2..fb93f23ce 100644 --- a/src/services/cms/articles/read.ts +++ b/src/services/cms/articles/read.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { articleRealtionsIncluder } from './ConfigVars' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' import type { ExpandedArticle } from './Types' diff --git a/src/services/cms/articles/update.ts b/src/services/cms/articles/update.ts index 1d585d05b..0d6717271 100644 --- a/src/services/cms/articles/update.ts +++ b/src/services/cms/articles/update.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { updateArticleValidation } from './validation' import { articleRealtionsIncluder, maxSections } from '@/cms/articles/ConfigVars' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { addArticleSectionPart } from '@/services/cms/articleSections/update' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' diff --git a/src/services/cms/images/create.ts b/src/services/cms/images/create.ts index be854cfbe..160dd7ae7 100644 --- a/src/services/cms/images/create.ts +++ b/src/services/cms/images/create.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { createCmsImageValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CreateCmsImageTypes } from './validation' import type { Image } from '@prisma/client' diff --git a/src/services/cms/images/destoy.ts b/src/services/cms/images/destoy.ts index 1a3eee322..c2fca396a 100644 --- a/src/services/cms/images/destoy.ts +++ b/src/services/cms/images/destoy.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CmsImage } from '@prisma/client' diff --git a/src/services/cms/images/read.ts b/src/services/cms/images/read.ts index 05256d228..38b3d57f0 100644 --- a/src/services/cms/images/read.ts +++ b/src/services/cms/images/read.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' import type { SpecialCmsImage } from '@prisma/client' diff --git a/src/services/cms/images/update.ts b/src/services/cms/images/update.ts index 36706e4e8..15eba1158 100644 --- a/src/services/cms/images/update.ts +++ b/src/services/cms/images/update.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CmsImage, ImageSize } from '@prisma/client' diff --git a/src/services/cms/links/create.ts b/src/services/cms/links/create.ts index 4e1fc4c17..3ebd7c3b0 100644 --- a/src/services/cms/links/create.ts +++ b/src/services/cms/links/create.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { createCmsLinkValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CreateCmsLinkTypes } from './validation' import type { CmsLink } from '@prisma/client' diff --git a/src/services/cms/links/destroy.ts b/src/services/cms/links/destroy.ts index 222a52328..48946aa6d 100644 --- a/src/services/cms/links/destroy.ts +++ b/src/services/cms/links/destroy.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CmsLink } from '@prisma/client' diff --git a/src/services/cms/links/update.ts b/src/services/cms/links/update.ts index 420199789..f49e86916 100644 --- a/src/services/cms/links/update.ts +++ b/src/services/cms/links/update.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { updateCmsLinkValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { UpdateCmsLinkTypes } from './validation' import type { CmsLink } from '@prisma/client' diff --git a/src/services/cms/paragraphs/create.ts b/src/services/cms/paragraphs/create.ts index bb8d8ae8c..1e73944f5 100644 --- a/src/services/cms/paragraphs/create.ts +++ b/src/services/cms/paragraphs/create.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { createCmsParagraphValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CreateCmsParagraphTypes } from './validation' import type { CmsParagraph } from '@prisma/client' diff --git a/src/services/cms/paragraphs/destroy.ts b/src/services/cms/paragraphs/destroy.ts index 224d2e29a..a5092b497 100644 --- a/src/services/cms/paragraphs/destroy.ts +++ b/src/services/cms/paragraphs/destroy.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { CmsParagraph } from '@prisma/client' diff --git a/src/services/cms/paragraphs/read.ts b/src/services/cms/paragraphs/read.ts index b745c9967..07091ad91 100644 --- a/src/services/cms/paragraphs/read.ts +++ b/src/services/cms/paragraphs/read.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' import type { SpecialCmsParagraph, CmsParagraph } from '@prisma/client' diff --git a/src/services/cms/paragraphs/update.ts b/src/services/cms/paragraphs/update.ts index 6a0a50651..770288467 100644 --- a/src/services/cms/paragraphs/update.ts +++ b/src/services/cms/paragraphs/update.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { unified } from 'unified' diff --git a/src/services/education/schools/create.ts b/src/services/education/schools/create.ts index 8465069fc..69359eff9 100644 --- a/src/services/education/schools/create.ts +++ b/src/services/education/schools/create.ts @@ -5,7 +5,7 @@ import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { createCmsImage } from '@/services/cms/images/create' import { createCmsParagraph } from '@/services/cms/paragraphs/create' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { createCmsLink } from '@/services/cms/links/create' import { v4 as uuid } from 'uuid' import { StandardSchool } from '@prisma/client' diff --git a/src/services/education/schools/destroy.ts b/src/services/education/schools/destroy.ts index 5ca8d68d9..bcf6a6df9 100644 --- a/src/services/education/schools/destroy.ts +++ b/src/services/education/schools/destroy.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' export async function destroySchool(id: number): Promise { const school = await prismaCall(() => prisma.school.findUniqueOrThrow({ diff --git a/src/services/education/schools/read.ts b/src/services/education/schools/read.ts index 99b6f92eb..3604e50ce 100644 --- a/src/services/education/schools/read.ts +++ b/src/services/education/schools/read.ts @@ -3,7 +3,7 @@ import { createStandardSchool } from './create' import { SchoolFilteredSelection, SchoolRelationIncluder } from './ConfigVars' import { prismaCall } from '@/services/prismaCall' import logger from '@/lib/logger' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { StandardSchool } from '@prisma/client' import type { ExpandedSchool, SchoolCursor, SchoolFiltered } from './Types' diff --git a/src/services/education/schools/update.ts b/src/services/education/schools/update.ts index faab8af3b..e52b971aa 100644 --- a/src/services/education/schools/update.ts +++ b/src/services/education/schools/update.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { SchoolFilteredSelection } from './ConfigVars' import { updateSchoolValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { SchoolFiltered } from './Types' import type { UpdateSchoolTypes } from './validation' diff --git a/src/services/groups/classes/read.ts b/src/services/groups/classes/read.ts index ba701c798..67f8911a4 100644 --- a/src/services/groups/classes/read.ts +++ b/src/services/groups/classes/read.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ExpandedClass } from './Types' export async function readClasses(): Promise { diff --git a/src/services/groups/committees/create.ts b/src/services/groups/committees/create.ts index 2f8443154..ca082c87f 100644 --- a/src/services/groups/committees/create.ts +++ b/src/services/groups/committees/create.ts @@ -1,5 +1,5 @@ import { createCommitteeValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { createArticle } from '@/services/cms/articles/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' diff --git a/src/services/groups/committees/destroy.ts b/src/services/groups/committees/destroy.ts index caa514d6a..e27cbf008 100644 --- a/src/services/groups/committees/destroy.ts +++ b/src/services/groups/committees/destroy.ts @@ -1,4 +1,4 @@ -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { ExpandedCommittee } from './Types' diff --git a/src/services/groups/committees/read.ts b/src/services/groups/committees/read.ts index 17ad8fd08..1e5fb474b 100644 --- a/src/services/groups/committees/read.ts +++ b/src/services/groups/committees/read.ts @@ -1,4 +1,4 @@ -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { articleRealtionsIncluder } from '@/services/cms/articles/ConfigVars' diff --git a/src/services/groups/committees/update.ts b/src/services/groups/committees/update.ts index 53c479aab..d78f01929 100644 --- a/src/services/groups/committees/update.ts +++ b/src/services/groups/committees/update.ts @@ -1,5 +1,5 @@ import { updateCommitteeValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { ImageMethods } from '@/services/images/methods' import type { ExpandedCommittee } from './Types' diff --git a/src/services/groups/manualGroups/create.ts b/src/services/groups/manualGroups/create.ts index 520afc58c..a6edb0af4 100644 --- a/src/services/groups/manualGroups/create.ts +++ b/src/services/groups/manualGroups/create.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import type { ExpandedManualGroup } from './Types' diff --git a/src/services/groups/manualGroups/destroy.ts b/src/services/groups/manualGroups/destroy.ts index 34ae07737..16fe10c85 100644 --- a/src/services/groups/manualGroups/destroy.ts +++ b/src/services/groups/manualGroups/destroy.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ExpandedManualGroup } from './Types' export async function destroyManualGroup(id: number): Promise { diff --git a/src/services/groups/manualGroups/read.ts b/src/services/groups/manualGroups/read.ts index f75f4e4b0..3cc6a416e 100644 --- a/src/services/groups/manualGroups/read.ts +++ b/src/services/groups/manualGroups/read.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ExpandedManualGroup } from './Types' export async function readManualGroups(): Promise { diff --git a/src/services/groups/manualGroups/update.ts b/src/services/groups/manualGroups/update.ts index b2bc43d86..04bc5cf9e 100644 --- a/src/services/groups/manualGroups/update.ts +++ b/src/services/groups/manualGroups/update.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' type UpdateManualGroupArgs = { name?: string, diff --git a/src/services/groups/memberships/canEasilyManageMembership.ts b/src/services/groups/memberships/canEasilyManageMembership.ts index 3876dda84..d628c1125 100644 --- a/src/services/groups/memberships/canEasilyManageMembership.ts +++ b/src/services/groups/memberships/canEasilyManageMembership.ts @@ -1,6 +1,6 @@ import { CanEasilyManageMembership } from './ConfigVars' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' export async function canEasilyManageMembershipOfGroup(groupId: number): Promise { const group = await prismaCall(() => prisma.group.findUniqueOrThrow({ diff --git a/src/services/groups/memberships/create.ts b/src/services/groups/memberships/create.ts index c04f0ecfe..f91913d72 100644 --- a/src/services/groups/memberships/create.ts +++ b/src/services/groups/memberships/create.ts @@ -3,7 +3,7 @@ import { canEasilyManageMembershipOfGroup, canEasilyManageMembershipOfGroups } f import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { invalidateManyUserSessionData, invalidateOneUserSessionData } from '@/services/auth/invalidateSession' import { GroupMethods } from '@/services/groups/methods' import type { ExpandedMembership } from './Types' diff --git a/src/services/groups/memberships/destroy.ts b/src/services/groups/memberships/destroy.ts index 6f7dad362..c07813bc9 100644 --- a/src/services/groups/memberships/destroy.ts +++ b/src/services/groups/memberships/destroy.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { canEasilyManageMembershipOfGroup } from './canEasilyManageMembership' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { invalidateManyUserSessionData, invalidateOneUserSessionData } from '@/services/auth/invalidateSession' import { GroupMethods } from '@/services/groups/methods' import type { ExpandedMembership } from './Types' diff --git a/src/services/groups/memberships/read.ts b/src/services/groups/memberships/read.ts index 537d181d6..1afcd2951 100644 --- a/src/services/groups/memberships/read.ts +++ b/src/services/groups/memberships/read.ts @@ -3,7 +3,7 @@ import { membershipFilterSelection } from './ConfigVars' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { getMembershipFilter } from '@/auth/getMembershipFilter' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ExpandedMembership, MembershipFiltered, MembershipSelectorType } from './Types' export async function readMembershipsOfGroup(id: number): Promise { diff --git a/src/services/groups/memberships/update.ts b/src/services/groups/memberships/update.ts index 888fba1e1..d3f842453 100644 --- a/src/services/groups/memberships/update.ts +++ b/src/services/groups/memberships/update.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { invalidateOneUserSessionData } from '@/services/auth/invalidateSession' import { GroupMethods } from '@/services/groups/methods' import type { ExpandedMembership } from './Types' diff --git a/src/services/groups/omegaMembershipGroups/read.ts b/src/services/groups/omegaMembershipGroups/read.ts index f90dd934f..fbc825c8d 100644 --- a/src/services/groups/omegaMembershipGroups/read.ts +++ b/src/services/groups/omegaMembershipGroups/read.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { ServerError } from '@/services/error' import type { OmegaMembershipLevel } from '@prisma/client' import type { ExpandedOmegaMembershipGroup } from './Types' diff --git a/src/services/groups/omegaMembershipGroups/update.ts b/src/services/groups/omegaMembershipGroups/update.ts index e3d6d4f78..728564eda 100644 --- a/src/services/groups/omegaMembershipGroups/update.ts +++ b/src/services/groups/omegaMembershipGroups/update.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { readOmegaMembershipGroup, readUserOmegaMembershipLevel } from './read' import { OMEGA_MEMBERSHIP_LEVEL_RANKING } from '@/services/groups/config' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { ServerError } from '@/services/error' diff --git a/src/services/groups/studyProgrammes/create.ts b/src/services/groups/studyProgrammes/create.ts index ab8f92102..139461587 100644 --- a/src/services/groups/studyProgrammes/create.ts +++ b/src/services/groups/studyProgrammes/create.ts @@ -1,6 +1,6 @@ import { createStudyProgrammeValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import type { CreateStudyProgrammeTypes } from './validation' import type { ExpandedStudyProgramme } from './Types' diff --git a/src/services/groups/studyProgrammes/destroy.ts b/src/services/groups/studyProgrammes/destroy.ts index 3ef66e961..28965bf73 100644 --- a/src/services/groups/studyProgrammes/destroy.ts +++ b/src/services/groups/studyProgrammes/destroy.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ExpandedStudyProgramme } from './Types' export async function destroyStudyProgramme(id: number): Promise { diff --git a/src/services/groups/studyProgrammes/read.ts b/src/services/groups/studyProgrammes/read.ts index f53e2b09c..d41933c9f 100644 --- a/src/services/groups/studyProgrammes/read.ts +++ b/src/services/groups/studyProgrammes/read.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ExpandedStudyProgramme } from './Types' export async function readStudyProgrammes(): Promise { diff --git a/src/services/groups/studyProgrammes/update.ts b/src/services/groups/studyProgrammes/update.ts index 84b965135..94bd6eacc 100644 --- a/src/services/groups/studyProgrammes/update.ts +++ b/src/services/groups/studyProgrammes/update.ts @@ -1,6 +1,6 @@ import { updateStudyProgrammeValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { UpdateStudyProgrammeTypes } from './validation' import type { ExpandedStudyProgramme } from './Types' diff --git a/src/services/images/collections/create.ts b/src/services/images/collections/create.ts index 337c5e38e..66eaa424a 100644 --- a/src/services/images/collections/create.ts +++ b/src/services/images/collections/create.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { createImageCollectionValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { createVisibility } from '@/services/visibility/create' import type { CreateImageCollectionTypes } from './validation' diff --git a/src/services/images/collections/destroy.ts b/src/services/images/collections/destroy.ts index 3a4fc3bfa..07e1b7a53 100644 --- a/src/services/images/collections/destroy.ts +++ b/src/services/images/collections/destroy.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' import { destroyVisibility } from '@/services/visibility/destroy' diff --git a/src/services/images/collections/read.ts b/src/services/images/collections/read.ts index 35d0d2d2b..c92a618e5 100644 --- a/src/services/images/collections/read.ts +++ b/src/services/images/collections/read.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { specialCollectionsSpecialVisibilityMap } from './ConfigVars' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import logger from '@/lib/logger' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' diff --git a/src/services/images/collections/update.ts b/src/services/images/collections/update.ts index 74e371fb7..427e61234 100644 --- a/src/services/images/collections/update.ts +++ b/src/services/images/collections/update.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { updateImageCollectionValidation } from './validation' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import type { ImageCollection } from '@prisma/client' import type { UpdateImageCollectionTypes } from './validation' diff --git a/src/services/mail/alias/create.ts b/src/services/mail/alias/create.ts index a18b752f4..b957b7fc1 100644 --- a/src/services/mail/alias/create.ts +++ b/src/services/mail/alias/create.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { createMailAliasValidation, type CreateMailAliasTypes } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailAlias } from '@prisma/client' export async function createMailAlias(rawdata: CreateMailAliasTypes['Detailed']): diff --git a/src/services/mail/alias/destroy.ts b/src/services/mail/alias/destroy.ts index c54088692..8e5f6b2b2 100644 --- a/src/services/mail/alias/destroy.ts +++ b/src/services/mail/alias/destroy.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { destoryMailAliasValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { ServerError } from '@/services/error' import type { MailAlias } from '@prisma/client' diff --git a/src/services/mail/alias/read.ts b/src/services/mail/alias/read.ts index 2b3d89f5a..8ce0b35b1 100644 --- a/src/services/mail/alias/read.ts +++ b/src/services/mail/alias/read.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailAlias } from '@prisma/client' diff --git a/src/services/mail/alias/update.ts b/src/services/mail/alias/update.ts index eb7df0a5f..7da3566c9 100644 --- a/src/services/mail/alias/update.ts +++ b/src/services/mail/alias/update.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { updateMailAliasValidation, type UpdateMailAliasTypes } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailAlias } from '@prisma/client' export async function updateMailAlias(rawdata: UpdateMailAliasTypes['Detailed']): Promise { diff --git a/src/services/mail/create.ts b/src/services/mail/create.ts index 08fdcb224..f768e9549 100644 --- a/src/services/mail/create.ts +++ b/src/services/mail/create.ts @@ -6,7 +6,7 @@ import { createMailingListUserValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailAliasMailingList, MailingListGroup, diff --git a/src/services/mail/destroy.ts b/src/services/mail/destroy.ts index 02ae53465..3e64bfb7b 100644 --- a/src/services/mail/destroy.ts +++ b/src/services/mail/destroy.ts @@ -6,7 +6,7 @@ import { createMailingListUserValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailAliasMailingList, MailingListGroup, diff --git a/src/services/mail/list/create.ts b/src/services/mail/list/create.ts index dd913aa03..d13b8e8e7 100644 --- a/src/services/mail/list/create.ts +++ b/src/services/mail/list/create.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { createMailingListValidation, type CreateMailingListTypes } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailingList } from '@prisma/client' export async function createMailingList(rawdata: CreateMailingListTypes['Detailed']): diff --git a/src/services/mail/list/destroy.ts b/src/services/mail/list/destroy.ts index 2f2a60a86..fd3ae6685 100644 --- a/src/services/mail/list/destroy.ts +++ b/src/services/mail/list/destroy.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { readMailingListValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailingList } from '@prisma/client' diff --git a/src/services/mail/list/read.ts b/src/services/mail/list/read.ts index 3174cc890..0f3033dd6 100644 --- a/src/services/mail/list/read.ts +++ b/src/services/mail/list/read.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailingList } from '@prisma/client' export async function readMailingLists(): Promise { diff --git a/src/services/mail/list/update.ts b/src/services/mail/list/update.ts index 475292767..0316a39ff 100644 --- a/src/services/mail/list/update.ts +++ b/src/services/mail/list/update.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { updateMailingListValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { UpdateMailingListTypes } from './validation' import type { MailingList } from '@prisma/client' diff --git a/src/services/mail/mailAddressExternal/create.ts b/src/services/mail/mailAddressExternal/create.ts index 1f334f823..3540c4c1f 100644 --- a/src/services/mail/mailAddressExternal/create.ts +++ b/src/services/mail/mailAddressExternal/create.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { createMailAddressExternalValidation, type CreateMailAddressExternalTypes } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailAddressExternal } from '@prisma/client' export async function createMailAddressExternal(rawdata: CreateMailAddressExternalTypes['Detailed']): diff --git a/src/services/mail/mailAddressExternal/destroy.ts b/src/services/mail/mailAddressExternal/destroy.ts index bad655b42..99df8f13f 100644 --- a/src/services/mail/mailAddressExternal/destroy.ts +++ b/src/services/mail/mailAddressExternal/destroy.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { readMailAddressExternalValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailAddressExternal } from '@prisma/client' diff --git a/src/services/mail/mailAddressExternal/read.ts b/src/services/mail/mailAddressExternal/read.ts index 3f3e046b4..4f1cacaa0 100644 --- a/src/services/mail/mailAddressExternal/read.ts +++ b/src/services/mail/mailAddressExternal/read.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailAddressExternal } from '@prisma/client' diff --git a/src/services/mail/mailAddressExternal/update.ts b/src/services/mail/mailAddressExternal/update.ts index 919b7f808..c6f3152a6 100644 --- a/src/services/mail/mailAddressExternal/update.ts +++ b/src/services/mail/mailAddressExternal/update.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { updateMailAddressExternalValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { MailAddressExternal } from '@prisma/client' import type { UpdatemailAddressExternalTypes } from './validation' diff --git a/src/services/mail/read.ts b/src/services/mail/read.ts index 07a949aa5..8cbc0d622 100644 --- a/src/services/mail/read.ts +++ b/src/services/mail/read.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { UserConfig } from '@/services/users/config' import type { MailFlowObject, MailListTypes, ViaArrayType, ViaType } from './Types' diff --git a/src/services/news/create.ts b/src/services/news/create.ts index a9d430ef1..aa52f7825 100644 --- a/src/services/news/create.ts +++ b/src/services/news/create.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { defaultNewsArticleOldCutoff, newsArticleRealtionsIncluder } from './ConfigVars' import { createNewsArticleValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createArticle } from '@/services/cms/articles/create' import type { CreateNewsArticleTypes } from './validation' diff --git a/src/services/news/destroy.ts b/src/services/news/destroy.ts index 0270f2898..d487ccfb3 100644 --- a/src/services/news/destroy.ts +++ b/src/services/news/destroy.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' import { destroyArticle } from '@/services/cms/articles/destroy' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { SimpleNewsArticle } from '@/services/news/Types' /** diff --git a/src/services/news/read.ts b/src/services/news/read.ts index b9d123e9c..221bf986a 100644 --- a/src/services/news/read.ts +++ b/src/services/news/read.ts @@ -3,7 +3,7 @@ import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { newsArticleRealtionsIncluder, simpleNewsArticleRealtionsIncluder } from '@/services/news/ConfigVars' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ExpandedNewsArticle, NewsCursor, SimpleNewsArticle } from '@/services/news/Types' import type { ReadPageInput } from '@/lib/paging/Types' diff --git a/src/services/news/update.ts b/src/services/news/update.ts index f2c2bad27..0519dfbb0 100644 --- a/src/services/news/update.ts +++ b/src/services/news/update.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { updateNewsArticleValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { UpdateNewsArticleTypes } from './validation' import type { SimpleNewsArticle } from '@/services/news/Types' diff --git a/src/services/notifications/email/dispatch.tsx b/src/services/notifications/email/dispatch.tsx index f478aef98..78a5c43f5 100644 --- a/src/services/notifications/email/dispatch.tsx +++ b/src/services/notifications/email/dispatch.tsx @@ -4,7 +4,7 @@ import { sendEmailValidation } from './validation' import { DefaultEmailTemplate } from './templates/default' import { NotificationMethods } from '@/services/notifications/methods' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { render } from '@react-email/render' import type { ExpandedNotificationChannel } from '@/services/notifications/Types' import type { Notification } from '@prisma/client' diff --git a/src/services/ombul/create.ts b/src/services/ombul/create.ts index 47a2d6669..1cad872cd 100644 --- a/src/services/ombul/create.ts +++ b/src/services/ombul/create.ts @@ -3,7 +3,7 @@ import { createOmbulValidation } from './validation' import { prismaCall } from '@/services/prismaCall' import { readSpecialImageCollection } from '@/services/images/collections/read' import { createCmsImage } from '@/services/cms/images/create' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { createFile } from '@/services/store/createFile' import { ImageMethods } from '@/services/images/methods' import { NotificationMethods } from '@/services/notifications/methods' diff --git a/src/services/ombul/destroy.ts b/src/services/ombul/destroy.ts index 604bacd8f..17718362d 100644 --- a/src/services/ombul/destroy.ts +++ b/src/services/ombul/destroy.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { destroyFile } from '@/services/store/destroyFile' import type { ExpandedOmbul } from '@/services/ombul/Types' diff --git a/src/services/ombul/read.ts b/src/services/ombul/read.ts index 474c8bb27..7d861519d 100644 --- a/src/services/ombul/read.ts +++ b/src/services/ombul/read.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { Ombul } from '@prisma/client' import type { ExpandedOmbul } from './Types' diff --git a/src/services/ombul/update.ts b/src/services/ombul/update.ts index 29cb1623f..fb80b2998 100644 --- a/src/services/ombul/update.ts +++ b/src/services/ombul/update.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { updateOmbulFileValidation, updateOmbulValidation } from './validation' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { createFile } from '@/services/store/createFile' import { destroyFile } from '@/services/store/destroyFile' import type { UpdateOmbulFileTypes, UpdateOmbulTypes } from './validation' diff --git a/src/services/omegaOrder/create.ts b/src/services/omegaOrder/create.ts index d2c2ddaed..14ad8f697 100644 --- a/src/services/omegaOrder/create.ts +++ b/src/services/omegaOrder/create.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { readCurrentOmegaOrder } from './read' import { AutomaticallyIncreaseOrder } from './ConfigVars' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { GroupType } from '@prisma/client' import type { PrismaPromise } from '@prisma/client' diff --git a/src/services/omegaOrder/read.ts b/src/services/omegaOrder/read.ts index 8ea8dfae4..38c509554 100644 --- a/src/services/omegaOrder/read.ts +++ b/src/services/omegaOrder/read.ts @@ -1,7 +1,7 @@ 'use server' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { OmegaOrder } from '@prisma/client' /** diff --git a/src/services/omegaquotes/create.ts b/src/services/omegaquotes/create.ts index cc6e24838..2928ea6d7 100644 --- a/src/services/omegaquotes/create.ts +++ b/src/services/omegaquotes/create.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { createOmegaquotesValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { NotificationMethods } from '@/services/notifications/methods' import type { CreateOmegaguotesTypes } from './validation' import type { OmegaQuote } from '@prisma/client' diff --git a/src/services/omegaquotes/read.ts b/src/services/omegaquotes/read.ts index 4b5b729f6..cb071a971 100644 --- a/src/services/omegaquotes/read.ts +++ b/src/services/omegaquotes/read.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { omegaQuoteFilterSelection } from './CofigVars' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ReadPageInput } from '@/lib/paging/Types' import type { OmegaquoteCursor, OmegaquoteFiltered } from '@/services/omegaquotes/Types' diff --git a/src/services/screens/create.ts b/src/services/screens/create.ts index 0f8c08c6e..0689abfd6 100644 --- a/src/services/screens/create.ts +++ b/src/services/screens/create.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { createScreenValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { CreateScreenTypes } from './validation' import type { Screen } from '@prisma/client' diff --git a/src/services/screens/destroy.ts b/src/services/screens/destroy.ts index 8da83205b..fe8a336e7 100644 --- a/src/services/screens/destroy.ts +++ b/src/services/screens/destroy.ts @@ -1,5 +1,5 @@ import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' export async function destroyScreen(id: number): Promise { await prismaCall(() => prisma.screen.delete({ diff --git a/src/services/screens/pages/create.ts b/src/services/screens/pages/create.ts index bc0874047..53f31a6a6 100644 --- a/src/services/screens/pages/create.ts +++ b/src/services/screens/pages/create.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { type CreatePageTypes, createPageValidation } from './validation' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { createCmsImage } from '@/services/cms/images/create' import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { v4 } from 'uuid' diff --git a/src/services/screens/pages/destroy.ts b/src/services/screens/pages/destroy.ts index 6ba419784..43df11054 100644 --- a/src/services/screens/pages/destroy.ts +++ b/src/services/screens/pages/destroy.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' export async function destroyPage(id: number): Promise { diff --git a/src/services/screens/pages/read.ts b/src/services/screens/pages/read.ts index cbe8140c5..cd1b87f67 100644 --- a/src/services/screens/pages/read.ts +++ b/src/services/screens/pages/read.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { screenPageIncluder } from './ConfigVars' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ScreenPage } from '@prisma/client' import type { ExpandedScreenPage } from './Types' diff --git a/src/services/screens/pages/update.ts b/src/services/screens/pages/update.ts index 6ea09f115..8cee2b348 100644 --- a/src/services/screens/pages/update.ts +++ b/src/services/screens/pages/update.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { updatePageValidation } from '@/services/screens/pages/validation' import type { UpdatePageTypes } from '@/services/screens/pages/validation' diff --git a/src/services/screens/read.ts b/src/services/screens/read.ts index eec8d8c02..73a628ed2 100644 --- a/src/services/screens/read.ts +++ b/src/services/screens/read.ts @@ -1,6 +1,6 @@ import { screenPageIncluder } from './pages/ConfigVars' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ExpandedScreen } from './Types' import type { Screen } from '@prisma/client' diff --git a/src/services/screens/update.ts b/src/services/screens/update.ts index f3fdc5fd4..a8ee27cd1 100644 --- a/src/services/screens/update.ts +++ b/src/services/screens/update.ts @@ -2,7 +2,7 @@ import { updateScreenValidation } from './validation' import { readScreen } from './read' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { ScreenPageMoveDirection } from './Types' import type { UpdateScreenTypes } from './validation' import type { Screen } from '@prisma/client' diff --git a/src/services/serviceMethod.ts b/src/services/serviceMethod.ts index 52c27c621..a5895aaa6 100644 --- a/src/services/serviceMethod.ts +++ b/src/services/serviceMethod.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { ParseError, Smorekopp } from './error' import { prismaErrorWrapper } from './prismaCall' -import { default as globalPrisma } from '@/prisma' +import { prisma as globalPrisma } from '@/prisma/client' import { Session } from '@/auth/Session' import { zfd } from 'zod-form-data' import { AsyncLocalStorage } from 'async_hooks' diff --git a/src/services/visibility/create.ts b/src/services/visibility/create.ts index 63365375e..5a9633b66 100644 --- a/src/services/visibility/create.ts +++ b/src/services/visibility/create.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { updateVisibility } from './update' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { Visibility, VisibilityPurpose } from '@prisma/client' import type { VisibilityLevelMatrices } from './Types' diff --git a/src/services/visibility/destroy.ts b/src/services/visibility/destroy.ts index 4a63e3df2..bdfa7d279 100644 --- a/src/services/visibility/destroy.ts +++ b/src/services/visibility/destroy.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { ServerError } from '@/services/error' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' /** * Destroy a visibility. This will also destroy the visibility levels associated with the visibility, diff --git a/src/services/visibility/read.ts b/src/services/visibility/read.ts index 34170d7f9..7536df68a 100644 --- a/src/services/visibility/read.ts +++ b/src/services/visibility/read.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { SpecialVisibilityConfig } from './ConfigVars' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { SpecialVisibilityPurpose, VisibilityRequirmenetGroup } from '@prisma/client' import type { VisibilityCollapsed } from './Types' diff --git a/src/services/visibility/update.ts b/src/services/visibility/update.ts index a8af6f1f9..8d1e4a8b8 100644 --- a/src/services/visibility/update.ts +++ b/src/services/visibility/update.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import type { VisibilityLevelMatrices } from './Types' export async function updateVisibility(id: number, data: VisibilityLevelMatrices): Promise { diff --git a/src/typings/global.d.ts b/src/typings/global.d.ts index 75fecbda8..23c3b36f9 100644 --- a/src/typings/global.d.ts +++ b/src/typings/global.d.ts @@ -1,10 +1,6 @@ import type { mailHandlerSingleton } from '@/services/notifications/email/mailHandler' -import type { Prisma, PrismaClient } from '@prisma/client' -import type { DefaultArgs } from '@prisma/client/runtime/library' declare global { - // eslint-disable-next-line no-var - var prisma: PrismaClient // eslint-disable-next-line no-var var mailHandler: ReturnType } diff --git a/tests/services/apiKeys.test.ts b/tests/services/apiKeys.test.ts index 4a212084c..09dea2699 100644 --- a/tests/services/apiKeys.test.ts +++ b/tests/services/apiKeys.test.ts @@ -1,6 +1,6 @@ import { Session } from '@/auth/Session' import { Smorekopp } from '@/services/error' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { ApiKeyMethods } from '@/services/api-keys/methods' import { afterEach, describe, expect, test } from '@jest/globals' diff --git a/tests/services/jobads.test.ts b/tests/services/jobads.test.ts index 76822b2a4..8f4a67eae 100644 --- a/tests/services/jobads.test.ts +++ b/tests/services/jobads.test.ts @@ -1,6 +1,6 @@ import { Session } from '@/auth/Session' import { Smorekopp } from '@/services/error' -import prisma from '@/prisma' +import { prisma } from '@/prisma/client' import { JobadMethods } from '@/services/career/jobAds/methods' import { afterEach, beforeAll, describe, expect, test } from '@jest/globals' diff --git a/tests/services/service-method.test.ts b/tests/services/service-method.test.ts index c61cdd9a5..96e0b7c2f 100644 --- a/tests/services/service-method.test.ts +++ b/tests/services/service-method.test.ts @@ -2,7 +2,7 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequireServerOnly } from '@/auth/auther/ServerOnly' import { Session } from '@/auth/Session' import { serviceMethod } from '@/services/serviceMethod' -import { default as globalPrisma } from '@/prisma' +import { prisma as globalPrisma } from '@/prisma/client' import { describe, expect, test } from '@jest/globals' import { z } from 'zod' From a9579201ba0360332d1c49fac4980cfca9e05249 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sun, 21 Sep 2025 22:09:56 +0200 Subject: [PATCH 16/24] fix: pass session to service method from action --- src/services/action.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/services/action.ts b/src/services/action.ts index 9f9670281..bbcf10c6e 100644 --- a/src/services/action.ts +++ b/src/services/action.ts @@ -3,6 +3,7 @@ import { safeServerCall } from './actionError' import type { ActionReturn } from './actionTypes' import type { ServiceMethod } from '@/services/serviceMethod' import type { z } from 'zod' +import { Session } from '@/auth/Session' export function action( serviceMethod: ServiceMethod @@ -41,6 +42,8 @@ export function action< // has arguments witch match the underlying service method. This makes programming easier as Intellisense can // help and errors are caught at compile time. const actionUnsafe = async (params?: unknown, data?: unknown) => { + const session = await Session.fromNextAuth() + // Treat empty form data as undefined. This is required because the form component will always send // a FormData instance, even if no data is being sent. if (data instanceof FormData && data.entries().next().done) { @@ -50,6 +53,7 @@ export function action< return safeServerCall(() => serviceMethod<'UNCHECKED'>({ params, data, + session, })) } From 2e5e6ba0ba499c298815251f78517ec04a2be67b Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 10 Oct 2025 18:27:53 +0200 Subject: [PATCH 17/24] refactor: namespace is kill --- src/app/(auth)/register/RegistrationForm.tsx | 4 +- src/app/_components/Company/Company.tsx | 6 +- .../NotificationMethodCheckboxes.tsx | 4 +- .../_components/OmegaId/reader/ConfigVars.ts | 2 +- .../OmegaId/reader/OmegaIdReader.tsx | 4 +- src/app/_components/Permission/Permission.tsx | 4 +- .../Permission/PermissionCategory.tsx | 4 +- .../(permissions)/group-permissions/page.tsx | 8 +- src/app/admin/admission/[admission]/page.tsx | 7 +- src/app/admin/admission/page.tsx | 6 +- .../[currentId]/channelSettings.tsx | 4 +- .../addNotificationChannel.tsx | 10 +- src/app/api/shop/getAll/route.ts | 4 +- src/app/api/shop/product/barcode/route.ts | 4 +- .../purchase/createByStudentCard/route.ts | 4 +- src/app/api/users/connectStudentCard/route.ts | 4 +- src/app/api/users/get/[username]/route.ts | 6 +- .../getWithBalance/[studentCard]/route.ts | 4 +- src/app/api/users/route.ts | 4 +- src/app/cabin/book/CabinPriceCalculator.tsx | 4 +- src/app/cabin/book/SelectBedProduct.tsx | 4 +- src/app/cabin/book/page.tsx | 6 +- src/app/cabin/book/stateWrapper.tsx | 22 +- src/app/career/jobads/CreateJobAdForm.tsx | 4 +- src/app/career/jobads/JobAd.tsx | 4 +- .../jobads/[...orderAndName]/EditJobAd.tsx | 4 +- .../career/jobads/[...orderAndName]/page.tsx | 4 +- src/app/events/CreateOrUpdateEventForm.tsx | 4 +- .../[order]/[name]/RegistrationsList.tsx | 14 +- src/app/events/archive/page.tsx | 8 +- src/app/events/page.tsx | 8 +- .../[id]/CollectionAdminUpload.tsx | 4 +- src/app/interest-groups/InterestGroup.tsx | 6 +- src/app/interest-groups/page.tsx | 4 +- src/app/lockers/[id]/page.tsx | 4 +- .../(user-admin)/getProfileForAdmin.ts | 4 +- .../notifications/notificationSettings.tsx | 6 +- .../notifications/subscriptionItem.tsx | 4 +- .../settings/RegisterStudentCardButton.tsx | 4 +- src/app/users/[username]/page.tsx | 8 +- src/auth/Session.ts | 10 +- src/auth/VevenAdapter.ts | 14 +- src/auth/auther/Auther.ts | 14 +- src/auth/authoptions.ts | 10 +- src/auth/getUser.ts | 4 +- .../seeder/src/development/seedDevEvents.ts | 6 +- .../seeder/src/development/seedDevJobAds.ts | 4 +- .../seeder/src/seedNotificationsChannels.ts | 34 +- src/services/action.ts | 2 +- src/services/admission/actions.ts | 4 +- src/services/admission/authers.ts | 8 +- src/services/admission/config.ts | 13 +- src/services/admission/methods.ts | 26 +- src/services/admission/schemas.ts | 11 +- src/services/api-keys/Types.ts | 4 +- src/services/api-keys/actions.ts | 12 +- src/services/api-keys/authers.ts | 18 +- src/services/api-keys/config.ts | 25 +- src/services/api-keys/methods.ts | 111 ++--- src/services/api-keys/schemas.ts | 23 +- src/services/applications/actions.ts | 10 +- src/services/applications/authers.ts | 10 +- src/services/applications/methods.ts | 34 +- src/services/applications/periods/Types.ts | 4 +- src/services/applications/periods/actions.ts | 16 +- src/services/applications/periods/authers.ts | 16 +- src/services/applications/periods/config.ts | 28 +- src/services/applications/periods/methods.ts | 66 +-- src/services/applications/periods/schemas.ts | 40 +- src/services/applications/schemas.ts | 26 +- src/services/auth/actions.ts | 10 +- src/services/auth/authers.ts | 8 +- src/services/auth/methods.ts | 50 +- src/services/auth/schemas.ts | 7 +- src/services/cabin/actions.ts | 50 +- src/services/cabin/booking/Types.ts | 4 +- src/services/cabin/booking/authers.ts | 30 +- .../cabin/booking/cabinPriceCalculator.ts | 8 +- src/services/cabin/booking/config.ts | 32 +- src/services/cabin/booking/methods.ts | 454 +++++++++--------- src/services/cabin/booking/schemas.ts | 49 +- src/services/cabin/pricePeriod/authers.ts | 15 +- src/services/cabin/pricePeriod/methods.ts | 59 ++- src/services/cabin/pricePeriod/schemas.ts | 22 +- src/services/cabin/product/authers.ts | 14 +- src/services/cabin/product/config.ts | 28 +- src/services/cabin/product/methods.ts | 59 +-- src/services/cabin/product/schemas.ts | 34 +- src/services/cabin/releasePeriod/authers.ts | 12 +- src/services/cabin/releasePeriod/methods.ts | 42 +- src/services/cabin/releasePeriod/schemas.ts | 30 +- src/services/career/companies/actions.ts | 10 +- src/services/career/companies/authers.ts | 10 +- src/services/career/companies/config.ts | 14 +- src/services/career/companies/methods.ts | 38 +- src/services/career/companies/schemas.ts | 31 +- src/services/career/jobAds/actions.ts | 14 +- src/services/career/jobAds/authers.ts | 14 +- src/services/career/jobAds/config.ts | 65 +-- src/services/career/jobAds/methods.ts | 58 +-- src/services/career/jobAds/schemas.ts | 33 +- src/services/dots/authers.ts | 14 +- src/services/dots/config.ts | 48 +- src/services/dots/methods.ts | 22 +- src/services/dots/schemas.ts | 28 +- src/services/events/Types.ts | 4 +- src/services/events/actions.ts | 14 +- src/services/events/authers.ts | 14 +- src/services/events/config.ts | 61 ++- src/services/events/methods.ts | 56 +-- src/services/events/registration/Types.ts | 8 +- src/services/events/registration/actions.ts | 14 +- src/services/events/registration/authers.ts | 14 +- src/services/events/registration/config.ts | 43 +- src/services/events/registration/methods.ts | 72 +-- src/services/events/registration/schemas.ts | 16 +- src/services/events/schemas.ts | 59 +-- src/services/events/tags/actions.ts | 14 +- src/services/events/tags/authers.ts | 14 +- src/services/events/tags/config.ts | 32 +- src/services/events/tags/methods.ts | 52 +- src/services/events/tags/schemas.ts | 25 +- src/services/groups/actions.ts | 10 +- src/services/groups/authers.ts | 4 +- src/services/groups/committees/actions.ts | 12 +- src/services/groups/committees/authers.ts | 4 +- src/services/groups/committees/config.ts | 66 ++- src/services/groups/committees/create.ts | 4 +- src/services/groups/committees/methods.ts | 54 +-- src/services/groups/committees/read.ts | 8 +- src/services/groups/committees/update.ts | 4 +- src/services/groups/config.ts | 2 +- src/services/groups/interestGroups/actions.ts | 10 +- src/services/groups/interestGroups/authers.ts | 12 +- src/services/groups/interestGroups/methods.ts | 56 +-- src/services/groups/interestGroups/schemas.ts | 32 +- src/services/groups/memberships/create.ts | 8 +- src/services/groups/memberships/destroy.ts | 6 +- src/services/groups/memberships/update.ts | 4 +- src/services/groups/methods.ts | 69 ++- src/services/images/actions.ts | 16 +- src/services/images/authers.ts | 18 +- src/services/images/collections/read.ts | 4 +- src/services/images/config.ts | 30 +- src/services/images/methods.ts | 178 +++---- src/services/images/schemas.ts | 84 ++-- src/services/licenses/actions.ts | 10 +- src/services/licenses/authers.ts | 10 +- src/services/licenses/methods.ts | 34 +- src/services/licenses/schemas.ts | 31 +- src/services/lockers/actions.ts | 20 +- src/services/lockers/authers.ts | 8 +- src/services/lockers/locations/authers.ts | 6 +- src/services/lockers/locations/methods.ts | 20 +- src/services/lockers/methods.ts | 27 +- src/services/lockers/reservations/authers.ts | 8 +- src/services/lockers/reservations/methods.ts | 34 +- src/services/lockers/reservations/schemas.ts | 29 +- src/services/lockers/schemas.ts | 21 +- src/services/mail/read.ts | 12 +- src/services/news/actions.ts | 4 +- src/services/notifications/Types.ts | 17 +- src/services/notifications/actions.ts | 18 +- src/services/notifications/authers.ts | 6 +- src/services/notifications/channel/authers.ts | 10 +- src/services/notifications/channel/config.ts | 23 +- src/services/notifications/channel/methods.ts | 92 ++-- src/services/notifications/channel/schemas.ts | 150 +++--- src/services/notifications/config.ts | 30 +- src/services/notifications/email/dispatch.tsx | 6 +- .../email/systemMail/resetPassword.tsx | 4 +- .../email/systemMail/verifyEmail.tsx | 4 +- src/services/notifications/methods.ts | 70 ++- .../notificationMethodOperations.ts | 8 +- src/services/notifications/schemas.ts | 46 +- .../notifications/subscription/Types.ts | 4 +- .../notifications/subscription/authers.ts | 6 +- .../notifications/subscription/config.ts | 15 +- .../notifications/subscription/methods.ts | 226 +++++---- .../notifications/subscription/schemas.ts | 22 +- src/services/ombul/create.ts | 8 +- src/services/ombul/validation.ts | 6 +- src/services/omegaquotes/create.ts | 4 +- src/services/permissions/actions.ts | 12 +- src/services/permissions/auther.ts | 12 +- src/services/permissions/config.ts | 2 +- src/services/permissions/methods.ts | 43 +- src/services/serviceMethod.ts | 10 +- src/services/shop/actions.ts | 24 +- src/services/shop/product/authers.ts | 10 +- src/services/shop/product/methods.ts | 66 +-- src/services/shop/product/schemas.ts | 47 +- src/services/shop/purchase/authers.ts | 4 +- src/services/shop/purchase/methods.ts | 25 +- src/services/shop/purchase/schemas.ts | 25 +- src/services/shop/shop/authers.ts | 6 +- src/services/shop/shop/methods.ts | 26 +- src/services/shop/shop/schema.ts | 13 +- src/services/users/Types.ts | 4 +- src/services/users/actions.ts | 24 +- src/services/users/authers.ts | 29 +- src/services/users/config.ts | 106 ++-- src/services/users/methods.ts | 136 +++--- src/services/users/schemas.ts | 78 +-- src/services/visibility/ConfigVars.ts | 4 +- src/services/visibility/actions.ts | 12 +- src/services/visibility/read.ts | 6 +- tests/services/jobads.test.ts | 32 +- 208 files changed, 2606 insertions(+), 2648 deletions(-) diff --git a/src/app/(auth)/register/RegistrationForm.tsx b/src/app/(auth)/register/RegistrationForm.tsx index cbe1c00a7..7206cbefc 100644 --- a/src/app/(auth)/register/RegistrationForm.tsx +++ b/src/app/(auth)/register/RegistrationForm.tsx @@ -4,7 +4,7 @@ import Form from '@/components/Form/Form' import Checkbox from '@/components/UI/Checkbox' import { SelectString } from '@/components/UI/Select' import TextInput from '@/components/UI/TextInput' -import { UserConfig } from '@/services/users/config' +import { sexConfig } from '@/services/users/config' import { SEX, type User } from '@prisma/client' import { signIn } from 'next-auth/react' import { useSearchParams } from 'next/navigation' @@ -23,7 +23,7 @@ export default function RegistrationForm({ const sexOptions = Object.values(SEX).map(sex => ({ value: sex, - label: UserConfig.sexConfig[sex].label + label: sexConfig[sex].label })) return
{asClient ? diff --git a/src/app/_components/NotificaionMethodSelector/NotificationMethodCheckboxes.tsx b/src/app/_components/NotificaionMethodSelector/NotificationMethodCheckboxes.tsx index 313335acf..f7fb16a0c 100644 --- a/src/app/_components/NotificaionMethodSelector/NotificationMethodCheckboxes.tsx +++ b/src/app/_components/NotificaionMethodSelector/NotificationMethodCheckboxes.tsx @@ -1,6 +1,6 @@ 'use client' import Checkbox from '@/components/UI/Checkbox' -import { NotificationConfig } from '@/services/notifications/config' +import { notificationMethodsDisplayMap } from '@/services/notifications/config' import { v4 as uuid } from 'uuid' import React, { useState } from 'react' import type { NotificationMethodGeneral, NotificationMethodTypes } from '@/services/notifications/Types' @@ -36,7 +36,7 @@ export default function NotificationMethodCheckboxes({ key={uuid()} name={formPrefix ? `${formPrefix}_${key}` : key} {...(onChange ? { checked: canEdit && value } : { defaultChecked: value })} - {...(label ? { label: NotificationConfig.methodsDisplayMap[key] } : {})} + {...(label ? { label: notificationMethodsDisplayMap[key] } : {})} disabled={!canEdit} onChange={handleChange.bind(key)} /> diff --git a/src/app/_components/OmegaId/reader/ConfigVars.ts b/src/app/_components/OmegaId/reader/ConfigVars.ts index a2be938f8..6aeb07e68 100644 --- a/src/app/_components/OmegaId/reader/ConfigVars.ts +++ b/src/app/_components/OmegaId/reader/ConfigVars.ts @@ -1,6 +1,6 @@ import type { Html5QrcodeScannerConfig } from 'html5-qrcode/esm/html5-qrcode-scanner' -export const QRCodeReaderConfig: Html5QrcodeScannerConfig = { +export const qrCodeReaderConfig: Html5QrcodeScannerConfig = { fps: 4, disableFlip: true, qrbox: { diff --git a/src/app/_components/OmegaId/reader/OmegaIdReader.tsx b/src/app/_components/OmegaId/reader/OmegaIdReader.tsx index 5ba805b44..5afb01464 100644 --- a/src/app/_components/OmegaId/reader/OmegaIdReader.tsx +++ b/src/app/_components/OmegaId/reader/OmegaIdReader.tsx @@ -1,5 +1,5 @@ 'use client' -import { QRCodeReaderConfig } from './ConfigVars' +import { qrCodeReaderConfig } from './ConfigVars' import styles from './OmegaIdReader.module.scss' import { parseJWT } from '@/jwt/parseJWTClient' import { decompressOmegaId } from '@/services/omegaid/compress' @@ -46,7 +46,7 @@ export default function OmegaIdReader({ const qrcodeRegionId = uuid() useEffect(() => { - const html5QrcodeScanner = new Html5QrcodeScanner(qrcodeRegionId, QRCodeReaderConfig, false) + const html5QrcodeScanner = new Html5QrcodeScanner(qrcodeRegionId, qrCodeReaderConfig, false) let lastReadTime = 0 let lastReadUserId = -1 diff --git a/src/app/_components/Permission/Permission.tsx b/src/app/_components/Permission/Permission.tsx index c854c9fe0..56ea31df4 100644 --- a/src/app/_components/Permission/Permission.tsx +++ b/src/app/_components/Permission/Permission.tsx @@ -1,5 +1,5 @@ import styles from './Permission.module.scss' -import { PermissionConfig } from '@/services/permissions/config' +import { permissionConfig } from '@/services/permissions/config' import type { ReactNode } from 'react' import type { Permission as PermissionT } from '@prisma/client' @@ -18,7 +18,7 @@ type PropTypes = { * @returns */ export default function Permission({ permission, children, displayCategory = true, className }: PropTypes) { - const permissionInfo = PermissionConfig[permission] + const permissionInfo = permissionConfig[permission] return (
diff --git a/src/app/_components/Permission/PermissionCategory.tsx b/src/app/_components/Permission/PermissionCategory.tsx index 37b7c06ef..b1f8eac07 100644 --- a/src/app/_components/Permission/PermissionCategory.tsx +++ b/src/app/_components/Permission/PermissionCategory.tsx @@ -1,6 +1,6 @@ import Permission from './Permission' import styles from './PermissionCategory.module.scss' -import { PermissionConfig } from '@/services/permissions/config' +import { permissionConfig } from '@/services/permissions/config' import { Permission as PermissionEnum } from '@prisma/client' import type { PermissionCategory } from '@/services/permissions/Types' import type { ReactNode } from 'react' @@ -17,7 +17,7 @@ export type PropTypes = { */ export default function PermissionCategory({ category, renderBesidePermission }: PropTypes) { const permissionsInCategory = Object.values(PermissionEnum).filter(permission => - PermissionConfig[permission].category === category + permissionConfig[permission].category === category ) return ( diff --git a/src/app/admin/(permissions)/group-permissions/page.tsx b/src/app/admin/(permissions)/group-permissions/page.tsx index 56ccb625f..7e09a0829 100644 --- a/src/app/admin/(permissions)/group-permissions/page.tsx +++ b/src/app/admin/(permissions)/group-permissions/page.tsx @@ -2,13 +2,13 @@ import styles from './page.module.scss' import PermissionCheckbox from './PermissionCheckbox' import { readPermissionMatrixAction } from '@/services/permissions/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' -import { PermissionConfig } from '@/services/permissions/config' +import { permissionConfig } from '@/services/permissions/config' import type { Permission } from '@prisma/client' export default async function PermissionGroups() { const permissionMatrix = unwrapActionReturn(await readPermissionMatrixAction()) - const permissionList = Object.keys(PermissionConfig) + const permissionList = Object.keys(permissionConfig) return
@@ -19,9 +19,9 @@ export default async function PermissionGroups() { )} diff --git a/src/app/admin/admission/[admission]/page.tsx b/src/app/admin/admission/[admission]/page.tsx index 83481671d..191c83ea0 100644 --- a/src/app/admin/admission/[admission]/page.tsx +++ b/src/app/admin/admission/[admission]/page.tsx @@ -1,7 +1,7 @@ import RegisterAdmissiontrial from './registration' +import { admissionDisplayNames, allAdmissions } from '@/services/admission/config' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { readOmegaJWTPublicKey } from '@/services/omegaid/actions' -import { AdmissionConfig } from '@/services/admission/config' import { type Admission as AdmissionType } from '@prisma/client' import { notFound } from 'next/navigation' @@ -12,15 +12,16 @@ type PropTypes = { } export default async function AdmissionTrials({ params }: PropTypes) { - if (!AdmissionConfig.array.includes((await params).admission)) { + if (!allAdmissions.includes((await params).admission)) { notFound() } + const admission = (await params).admission const publicKey = await readOmegaJWTPublicKey() return
    - {AdmissionConfig.array.map(trial => + {allAdmissions.map(trial =>
  • - {AdmissionConfig.displayNames[trial]} + {admissionDisplayNames[trial]}
  • )}
diff --git a/src/app/admin/notification-channels/[currentId]/channelSettings.tsx b/src/app/admin/notification-channels/[currentId]/channelSettings.tsx index ea42a3b77..5817f3611 100644 --- a/src/app/admin/notification-channels/[currentId]/channelSettings.tsx +++ b/src/app/admin/notification-channels/[currentId]/channelSettings.tsx @@ -7,9 +7,9 @@ import { SelectNumber } from '@/components/UI/Select' import Form from '@/components/Form/Form' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { bindParams } from '@/services/actionBind' -import { NotificationChannelSchemas } from '@/services/notifications/channel/schemas' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' import { updateNotificationChannelAction } from '@/services/notifications/actions' +import { findValidParents } from '@/services/notifications/channel/schemas' import { useState } from 'react' import type { ExpandedNotificationChannel } from '@/services/notifications/Types' import type { MailAlias } from '@prisma/client' @@ -25,7 +25,7 @@ export default function ChannelSettings({ }) { const [currentChannelState, setCurrentChannel] = useState(currentChannel) - const selectOptions = NotificationChannelSchemas.findValidParents(currentChannel.id, channels) + const selectOptions = findValidParents(currentChannel.id, channels) return (NotificationConfig.allMethodsOn) - const [defaultMethods, setDefaultMethods] = useState(NotificationConfig.allMethodsOff) + const [availableMethods, setAvailableMethods] = useState(allNotificationMethodsOn) + const [defaultMethods, setDefaultMethods] = useState(allNotificationMethodsOn) const [selectedParentId, setSelectedParentId] = useState(channels.find(channel => channel.special === 'ROOT')?.id) const [editableMethods, setEditableMethods] = useState( - channels.find(channel => channel.id === selectedParentId)?.availableMethods ?? NotificationConfig.allMethodsOn + channels.find(channel => channel.id === selectedParentId)?.availableMethods ?? allNotificationMethodsOn ) function handleNewParent(id: number) { setSelectedParentId(id) - setEditableMethods(channels.find(channel => channel.id === id)?.availableMethods ?? NotificationConfig.allMethodsOn) + setEditableMethods(channels.find(channel => channel.id === id)?.availableMethods ?? allNotificationMethodsOff) } return ({ username: rawparams.username }) }) export const PATCH = apiHandler({ - serviceMethod: UserMethods.update, + serviceMethod: userMethods.update, params: (rawparams: { username: string }) => ({ username: rawparams.username }) }) diff --git a/src/app/api/users/getWithBalance/[studentCard]/route.ts b/src/app/api/users/getWithBalance/[studentCard]/route.ts index 492ee5eb8..57e5a66cc 100644 --- a/src/app/api/users/getWithBalance/[studentCard]/route.ts +++ b/src/app/api/users/getWithBalance/[studentCard]/route.ts @@ -1,9 +1,9 @@ import { apiHandler } from '@/api/apiHandler' -import { UserMethods } from '@/services/users/methods' +import { userMethods } from '@/services/users/methods' export const GET = apiHandler({ params: (rawparams: { studentCard: string }) => ({ studentCard: rawparams.studentCard, }), - serviceMethod: UserMethods.readUserWithBalance, + serviceMethod: userMethods.readUserWithBalance, }) diff --git a/src/app/api/users/route.ts b/src/app/api/users/route.ts index 45e20a6e7..65b213005 100644 --- a/src/app/api/users/route.ts +++ b/src/app/api/users/route.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { apiHandler } from '@/api/apiHandler' -import { UserMethods } from '@/services/users/methods' +import { userMethods } from '@/services/users/methods' export const POST = apiHandler({ - serviceMethod: UserMethods.create + serviceMethod: userMethods.create }) diff --git a/src/app/cabin/book/CabinPriceCalculator.tsx b/src/app/cabin/book/CabinPriceCalculator.tsx index 89c4d0236..391cd1cbe 100644 --- a/src/app/cabin/book/CabinPriceCalculator.tsx +++ b/src/app/cabin/book/CabinPriceCalculator.tsx @@ -1,9 +1,9 @@ import SimpleTable from '@/app/_components/Table/SimpleTable' import { displayPrice } from '@/lib/money/convert' import { calculateCabinBookingPrice, calculateTotalCabinBookingPrice } from '@/services/cabin/booking/cabinPriceCalculator' +import type { CabinProductExtended } from '@/services/cabin/product/config' import type { CabinPriceCalculatorReturnType } from '@/services/cabin/booking/cabinPriceCalculator' import type { PricePeriod } from '@prisma/client' -import type { CabinProductConfig } from '@/services/cabin/product/config' export default function CabinPriceCalculator({ @@ -16,7 +16,7 @@ export default function CabinPriceCalculator({ numberOfNonMembers, }: { pricePeriods: PricePeriod[], - products: CabinProductConfig.CabinProductExtended[], + products: CabinProductExtended[], productAmounts: number[], startDate?: Date, endDate?: Date, diff --git a/src/app/cabin/book/SelectBedProduct.tsx b/src/app/cabin/book/SelectBedProduct.tsx index a2aaf5fdf..4b0694b7c 100644 --- a/src/app/cabin/book/SelectBedProduct.tsx +++ b/src/app/cabin/book/SelectBedProduct.tsx @@ -1,5 +1,5 @@ import NumberInput from '@/app/_components/UI/NumberInput' -import type { CabinProductConfig } from '@/services/cabin/product/config' +import type { CabinProductExtended } from '@/services/cabin/product/config' export default function SelectBedProducts({ @@ -7,7 +7,7 @@ export default function SelectBedProducts({ onChange, amounts, }: { - bedProducts: CabinProductConfig.CabinProductExtended[], + bedProducts: CabinProductExtended[], onChange: (product: number[]) => void amounts: number[], }) { diff --git a/src/app/cabin/book/page.tsx b/src/app/cabin/book/page.tsx index 1e73c009b..972b7912d 100644 --- a/src/app/cabin/book/page.tsx +++ b/src/app/cabin/book/page.tsx @@ -10,7 +10,7 @@ import { } from '@/services/cabin/actions' import { displayDate } from '@/lib/dates/displayDate' import { Session } from '@/auth/Session' -import { CabinBookingAuthers } from '@/services/cabin/booking/authers' +import { cabinBookingAuthers } from '@/services/cabin/booking/authers' import type { ReleasePeriod } from '@prisma/client' function findCurrentReleasePeriod(releasePeriods: ReleasePeriod[]) { @@ -41,8 +41,8 @@ export default async function CabinBooking() { const pricePeriods = unwrapActionReturn(await readPublicPricePeriodsAction()) const cabinProducts = unwrapActionReturn(await readCabinProductsActiveAction()) const session = await Session.fromNextAuth() - const canBookCabin = CabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}).auth(session) - const canBookBed = CabinBookingAuthers.createBedBookingNoUser.dynamicFields({}).auth(session) + const canBookCabin = cabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}).auth(session) + const canBookBed = cabinBookingAuthers.createBedBookingNoUser.dynamicFields({}).auth(session) return (canBookCabin ? 'CABIN' : 'BED') const [dateRange, setDateRange] = useState({}) - const [selectedProducts, setSelectedProducts] = useState( + const [selectedProducts, setSelectedProducts] = useState( canBookCabin ? [cabinProduct] : bedProducts ) const [bedAmounts, setBedAmounts] = useState(Array(bedProducts.length).fill(0)) @@ -208,29 +208,29 @@ export default function StateWrapper({ name="firstname" label="Fornavn" defaultValue={user.user?.firstname ?? ''} - disabled={!!user.user} - readOnly={!!user.user} + disabled={Boolean(user.user)} + readOnly={Boolean(user.user)} /> diff --git a/src/app/career/jobads/CreateJobAdForm.tsx b/src/app/career/jobads/CreateJobAdForm.tsx index c364d5ee9..379c4fdc4 100644 --- a/src/app/career/jobads/CreateJobAdForm.tsx +++ b/src/app/career/jobads/CreateJobAdForm.tsx @@ -6,7 +6,7 @@ import { createJobAdAction } from '@/services/career/jobAds/actions' import TextInput from '@/components/UI/TextInput' import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' -import { JobAdConfig } from '@/services/career/jobAds/config' +import { jobAdOptions } from '@/services/career/jobAds/config' import DateInput from '@/components/UI/DateInput' import { v4 as uuid } from 'uuid' @@ -23,7 +23,7 @@ export default function CreateJobAdForm() { - + diff --git a/src/app/career/jobads/JobAd.tsx b/src/app/career/jobads/JobAd.tsx index 9705c8cf0..3ce7faeb5 100644 --- a/src/app/career/jobads/JobAd.tsx +++ b/src/app/career/jobads/JobAd.tsx @@ -1,6 +1,6 @@ import styles from './JobAd.module.scss' import ImageCard from '@/components/ImageCard/ImageCard' -import { JobAdConfig } from '@/services/career/jobAds/config' +import { jobAdType } from '@/services/career/jobAds/config' import type { SimpleJobAd } from '@/services/career/jobAds/Types' type PropTypes = { @@ -16,7 +16,7 @@ export default function JobAd({ jobAd }: PropTypes) { key={jobAd.id} > {!jobAd.active ?

Inaktiv

: <>} -

{jobAd.companyName} - {JobAdConfig.type[jobAd.type].label}

+

{jobAd.companyName} - {jobAdType[jobAd.type].label}

{jobAd.description} ) diff --git a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx index 53bcb0f2c..b8b4a38f2 100644 --- a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx +++ b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx @@ -11,8 +11,8 @@ import Slider from '@/app/_components/UI/Slider' import { CompanyPagingContext } from '@/contexts/paging/CompanyPaging' import CompanyChooser from '@/app/career/jobads/CompanyChooser' import { bindParams } from '@/services/actionBind' -import { JobAdConfig } from '@/services/career/jobAds/config' import { destroyJobAdAction, updateJobAdAction } from '@/career/jobAds/actions' +import { jobAdOptions } from '@/services/career/jobAds/config' import { v4 as uuid } from 'uuid' import { useContext, type ReactNode } from 'react' import type { ExpandedJobAd } from '@/career/jobAds/Types' @@ -60,7 +60,7 @@ export default function EditJobAd({ jobAd, children }: PropTypes) { />

Stillingstype

-

{JobAdConfig.type[jobAd.type].label}

+

{jobAdType[jobAd.type].label}

  • diff --git a/src/app/events/CreateOrUpdateEventForm.tsx b/src/app/events/CreateOrUpdateEventForm.tsx index f8dde6f3b..5a21836d8 100644 --- a/src/app/events/CreateOrUpdateEventForm.tsx +++ b/src/app/events/CreateOrUpdateEventForm.tsx @@ -7,11 +7,11 @@ import Slider from '@/components/UI/Slider' import NumberInput from '@/components/UI/NumberInput' import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' -import { EventConfig } from '@/services/events/config' import EventTag from '@/components/Event/EventTag' import { bindParams } from '@/services/actionBind' import { FIELD_IS_PRESENT_VALUE } from '@/lib/fields/config' import { createEventAction, updateEventAction } from '@/services/events/actions' +import { eventCanBeViewdByOptions } from '@/services/events/config' import { useState } from 'react' import type { Event, EventTag as EventTagT } from '@prisma/client' import type { ChangeEvent } from 'react' @@ -54,7 +54,7 @@ export default function CreateOrUpdateEventForm({ event, eventTags }: PropTypes) className={styles.canBeViewdBy} label="Hvem kan se" name="canBeViewdBy" - options={EventConfig.canBeViewdByOptions} + options={eventCanBeViewdByOptions} defaultValue={event?.canBeViewdBy} /> diff --git a/src/app/events/[order]/[name]/RegistrationsList.tsx b/src/app/events/[order]/[name]/RegistrationsList.tsx index 4f2d2a21c..680154061 100644 --- a/src/app/events/[order]/[name]/RegistrationsList.tsx +++ b/src/app/events/[order]/[name]/RegistrationsList.tsx @@ -10,9 +10,9 @@ import UserDisplayName from '@/components/User/UserDisplayName' import Slider from '@/components/UI/Slider' import Form from '@/components/Form/Form' import { bindParams } from '@/services/actionBind' -import { EventRegistrationConfig } from '@/services/events/registration/config' import ContactCard from '@/components/User/ContactCard' import { eventRegistrationDestroyAction } from '@/services/events/registration/actions' +import { REGISTRATION_READER_TYPE } from '@/services/events/registration/config' import Link from 'next/link' import { useState } from 'react' import type { EventFiltered } from '@/services/events/Types' @@ -22,7 +22,7 @@ function DetailedTable({ type, }: { event: EventFiltered, - type: EventRegistrationConfig.REGISTRATION_READER_TYPE + type: REGISTRATION_READER_TYPE, }) { return } {detailedView ? : } {event.waitingList && <>

    Venteliste

    {detailedView ? : } } diff --git a/src/app/events/archive/page.tsx b/src/app/events/archive/page.tsx index 02d07db36..af38427a8 100644 --- a/src/app/events/archive/page.tsx +++ b/src/app/events/archive/page.tsx @@ -4,7 +4,7 @@ import { readEventTagsAction } from '@/services/events/tags/actions' import EventsLandingLayout from '@/app/events/EventsLandingLayout' import EventArchivePagingProvider from '@/contexts/paging/EventArchivePaging' import { QueryParams } from '@/lib/query-params/queryParams' -import { EventTagAuthers } from '@/services/events/tags/authers' +import { eventTagAuthers } from '@/services/events/tags/authers' import { Session } from '@/auth/Session' import { faArrowLeft } from '@fortawesome/free-solid-svg-icons' import type { SearchParamsServerSide } from '@/lib/query-params/Types' @@ -24,9 +24,9 @@ export default async function EventArchive({ const session = await Session.fromNextAuth() - const canUpdate = EventTagAuthers.update.dynamicFields({}).auth(session) - const canCreate = EventTagAuthers.create.dynamicFields({}).auth(session) - const canDestroy = EventTagAuthers.destroy.dynamicFields({}).auth(session) + const canUpdate = eventTagAuthers.update.dynamicFields({}).auth(session) + const canCreate = eventTagAuthers.create.dynamicFields({}).auth(session) + const canDestroy = eventTagAuthers.destroy.dynamicFields({}).auth(session) return ( { // split files into batches of maxNumberOfImagesInOneBatch const batches = files.reduce((acc, file, index) => { - if (index % ImageConfig.maxNumberInOneBatch === 0) { + if (index % maxImageCountInOneBatch === 0) { acc.push([]) } acc[acc.length - 1].push(file) diff --git a/src/app/interest-groups/InterestGroup.tsx b/src/app/interest-groups/InterestGroup.tsx index ae6c6a2bf..e35f4aa04 100644 --- a/src/app/interest-groups/InterestGroup.tsx +++ b/src/app/interest-groups/InterestGroup.tsx @@ -4,7 +4,7 @@ import TextInput from '@/components/UI/TextInput' import ArticleSection from '@/components/Cms/ArticleSection/ArticleSection' import { SettingsHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import { updateInterestGroupAction, destroyInterestGroupAction } from '@/services/groups/interestGroups/actions' -import { InterestGroupAuthers } from '@/services/groups/interestGroups/authers' +import { interestGroupAuthers } from '@/services/groups/interestGroups/authers' import type { SessionMaybeUser } from '@/auth/Session' import type { ExpandedInterestGroup } from '@/services/groups/interestGroups/Types' @@ -14,8 +14,8 @@ type PropTypes = { } export default function InterestGroup({ interestGroup, session }: PropTypes) { - const canUpdate = InterestGroupAuthers.update.dynamicFields({ groupId: interestGroup.groupId }).auth(session) - const canDestroy = InterestGroupAuthers.destroy.dynamicFields({}).auth(session) + const canUpdate = interestGroupAuthers.update.dynamicFields({ groupId: interestGroup.groupId }).auth(session) + const canDestroy = interestGroupAuthers.destroy.dynamicFields({}).auth(session) const PopUpKey = `Update interest group ${interestGroup.name}` diff --git a/src/app/interest-groups/page.tsx b/src/app/interest-groups/page.tsx index 115e9e458..841e30c92 100644 --- a/src/app/interest-groups/page.tsx +++ b/src/app/interest-groups/page.tsx @@ -4,7 +4,7 @@ import SpecialCmsParagraph from '@/cms/CmsParagraph/SpecialCmsParagraph' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import { Session } from '@/auth/Session' -import { InterestGroupAuthers } from '@/services/groups/interestGroups/authers' +import { interestGroupAuthers } from '@/services/groups/interestGroups/authers' import { readInterestGroupsAction } from '@/services/groups/interestGroups/actions' export default async function InterestGroups() { @@ -13,7 +13,7 @@ export default async function InterestGroups() { if (!interestGroupsRes.success) return
    Failed to load interest groups
    //TODO: Change to unwrap const interestGroups = interestGroupsRes.data - const canCreate = InterestGroupAuthers.create.dynamicFields({}).auth(session) + const canCreate = interestGroupAuthers.create.dynamicFields({}).auth(session) return (
  • - {NotificationConfig.methods.map(method => + {notificationMethodsArray.map(method => )} diff --git a/src/app/users/[username]/(user-admin)/notifications/subscriptionItem.tsx b/src/app/users/[username]/(user-admin)/notifications/subscriptionItem.tsx index 68534ae30..b300308c5 100644 --- a/src/app/users/[username]/(user-admin)/notifications/subscriptionItem.tsx +++ b/src/app/users/[username]/(user-admin)/notifications/subscriptionItem.tsx @@ -2,7 +2,7 @@ import styles from './subscriptionItem.module.scss' import NotificationMethodCheckboxes from '@/components/NotificaionMethodSelector/NotificationMethodCheckboxes' -import { NotificationConfig } from '@/services/notifications/config' +import { allNotificationMethodsOn } from '@/services/notifications/config' import { v4 as uuid } from 'uuid' import React from 'react' import type { NotificationMethodGeneral } from '@/services/notifications/Types' @@ -19,7 +19,7 @@ export default function SubscriptionItem({ onChange?: (branchId: number, method: NotificationMethodGeneral) => void }) { const checkboxes = NotificationMethodCheckboxes({ - methods: branch.subscription?.methods ?? NotificationConfig.allMethodsOff, + methods: branch.subscription?.methods ?? allNotificationMethodsOn, editable: branch.availableMethods, onChange: (method: NotificationMethodGeneral) => { if (!onChange) { diff --git a/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx b/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx index a7856bcdc..d6878c5a7 100644 --- a/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx +++ b/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx @@ -1,7 +1,7 @@ 'use client' import { registerStudentCardInQueueAction } from '@/services/users/actions' import Form from '@/app/_components/Form/Form' -import { UserConfig } from '@/services/users/config' +import { studentCardRegistrationExpiry } from '@/services/users/config' export default function RegisterStudentCardButton({ @@ -16,7 +16,7 @@ export default function RegisterStudentCardButton({

    For å registrere studentkortet til brukeren din trykk på knappen under. Deretter skan kortet ditt på skanneren til Koigeskabet på Lophtet, uten at du har lagt inn noen varer enda. - Fra du trykker på knappen har du { UserConfig.studentCardRegistrationExpiry } + Fra du trykker på knappen har du { studentCardRegistrationExpiry } minutter på deg til å skanne kortet ditt.

    diff --git a/src/app/users/[username]/page.tsx b/src/app/users/[username]/page.tsx index 87b710005..41d030987 100644 --- a/src/app/users/[username]/page.tsx +++ b/src/app/users/[username]/page.tsx @@ -4,12 +4,12 @@ import { readCommitteesFromGroupIds } from '@/services/groups/committees/read' import OmegaId from '@/components/OmegaId/identification/OmegaId' import PopUp from '@/components/PopUp/PopUp' import { Session } from '@/auth/Session' -import { UserAuthers } from '@/services/users/authers' +import { userAuthers } from '@/services/users/authers' import ProfilePicture from '@/components/User/ProfilePicture' -import { UserConfig } from '@/services/users/config' import UserDisplayName from '@/components/User/UserDisplayName' import { readUserProfileAction } from '@/services/users/actions' import { readSpecialImageAction } from '@/services/images/actions' +import { sexConfig } from '@/services/users/config' import Link from 'next/link' import { notFound, redirect } from 'next/navigation' import { v4 as uuid } from 'uuid' @@ -49,7 +49,7 @@ export default async function User({ params }: PropTypes) { return res.data }) - const { authorized: canAdministrate } = UserAuthers.updateProfile.dynamicFields( + const { authorized: canAdministrate } = userAuthers.updateProfile.dynamicFields( { username: profile.user.username } ).auth(session) @@ -96,7 +96,7 @@ export default async function User({ params }: PropTypes) {

    - {UserConfig.sexConfig[profile.user.sex ?? 'OTHER'].title} + {sexConfig[profile.user.sex ?? 'OTHER'].title} uudaf {order}´dis orden i Sanctus Omega Broderskab

    diff --git a/src/auth/Session.ts b/src/auth/Session.ts index ae1ed80af..acfe3aa58 100644 --- a/src/auth/Session.ts +++ b/src/auth/Session.ts @@ -1,9 +1,9 @@ import { authOptions } from './authoptions' -import { ApiKeyMethods } from '@/services/api-keys/methods' +import { apiKeyMethods } from '@/services/api-keys/methods' import { apiKeyDecryptAndCompare } from '@/services/api-keys/hashEncryptKey' import { decodeApiKey } from '@/services/api-keys/apiKeyEncoder' import { ServerError } from '@/services/error' -import { PermissionMethods } from '@/services/permissions/methods' +import { permissionMethods } from '@/services/permissions/methods' import { getServerSession as getSessionNextAuth } from 'next-auth' import type { Permission } from '@prisma/client' import type { UserFiltered } from '@/services/users/Types' @@ -71,7 +71,7 @@ export class Session { public static async fromNextAuth(): Promise | Session<'HAS_USER'>> { const { user = null, - permissions = await PermissionMethods.readDefaultPermissions({ + permissions = await permissionMethods.readDefaultPermissions({ bypassAuth: true, }), memberships = [], @@ -86,7 +86,7 @@ export class Session { * If the key is null, the session will be cratedwith only default permissios */ public static async fromApiKey(keyAndIdEncoded: string | null): Promise> { - const defaultPermissions = await PermissionMethods.readDefaultPermissions({ + const defaultPermissions = await permissionMethods.readDefaultPermissions({ bypassAuth: true, }) if (!keyAndIdEncoded) return new Session<'NO_USER'>({ user: null, permissions: defaultPermissions, memberships: [] }) @@ -97,7 +97,7 @@ export class Session { let apiKeyFetch try { - apiKeyFetch = await ApiKeyMethods.readWithHash({ + apiKeyFetch = await apiKeyMethods.readWithHash({ bypassAuth: true, params: { id } }) diff --git a/src/auth/VevenAdapter.ts b/src/auth/VevenAdapter.ts index bf3fa49b8..4621233a5 100644 --- a/src/auth/VevenAdapter.ts +++ b/src/auth/VevenAdapter.ts @@ -2,8 +2,8 @@ import '@pn-server-only' import { readJWTPayload } from '@/jwt/jwtReadUnsecure' import { createFeideAccount } from '@/services/auth/feideAccounts/create' import { readUserOrNullOfFeideAccount } from '@/services/auth/feideAccounts/read' -import { UserMethods } from '@/services/users/methods' -import { UserConfig } from '@/services/users/config' +import { userMethods } from '@/services/users/methods' +import { userFilterSelection } from '@/services/users/config' import type { UserFiltered } from '@/services/users/Types' import type { PrismaClient } from '@prisma/client' import type { Adapter, AdapterUser, AdapterAccount } from 'next-auth/adapters' @@ -96,7 +96,7 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { username, emailVerified: null, }, - select: UserConfig.filterSelection, + select: userFilterSelection, }) return convertToAdapterUser(createdUser) @@ -105,7 +105,7 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { async getUser(id) { console.log('get id') - const user = await UserMethods.readOrNull({ + const user = await userMethods.readOrNull({ params: { id: Number(id) }, bypassAuth: true, }) @@ -116,7 +116,7 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { async getUserByEmail(email) { console.log('get email') console.log(email) - const user = await UserMethods.readOrNull({ + const user = await userMethods.readOrNull({ params: { email }, bypassAuth: true, }) @@ -131,7 +131,7 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { }, include: { user: { - select: UserConfig.filterSelection, + select: userFilterSelection, }, }, }) @@ -163,7 +163,7 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { firstname: user.firstname, lastname: user.lastname, }, - select: UserConfig.filterSelection, + select: userFilterSelection, }) return convertToAdapterUser(updatedUser) diff --git a/src/auth/auther/Auther.ts b/src/auth/auther/Auther.ts index 9d6946813..c8da07a60 100644 --- a/src/auth/auther/Auther.ts +++ b/src/auth/auther/Auther.ts @@ -3,15 +3,19 @@ import type { SessionMaybeUser, SessionUser } from '@/auth/Session' export type UserRequieredOutOpt = 'USER_NOT_REQUIERED_FOR_AUTHORIZED' | 'USER_REQUIERED_FOR_AUTHORIZED' +export type AutherResult< + UserRequieredOut extends UserRequieredOutOpt = 'USER_NOT_REQUIERED_FOR_AUTHORIZED' | 'USER_REQUIERED_FOR_AUTHORIZED', +> = { + auth: (session: SessionMaybeUser) => UserRequieredOut extends 'USER_REQUIERED_FOR_AUTHORIZED' + ? (AuthResult<'HAS_USER', true> | AuthResult<'HAS_USER' | 'NO_USER', false>) + : (AuthResult<'HAS_USER' | 'NO_USER', true> | AuthResult<'HAS_USER' | 'NO_USER', false>) +} + export type AutherStaticFieldsBound< DynamicFields extends object, UserRequieredOut extends UserRequieredOutOpt = 'USER_NOT_REQUIERED_FOR_AUTHORIZED' | 'USER_REQUIERED_FOR_AUTHORIZED', > = { - dynamicFields: (dynamicFields: DynamicFields) => { - auth: (session: SessionMaybeUser) => UserRequieredOut extends 'USER_REQUIERED_FOR_AUTHORIZED' - ? (AuthResult<'HAS_USER', true> | AuthResult<'HAS_USER' | 'NO_USER', false>) - : (AuthResult<'HAS_USER' | 'NO_USER', true> | AuthResult<'HAS_USER' | 'NO_USER', false>) - } + dynamicFields: (dynamicFields: DynamicFields) => AutherResult, } export type Auther< diff --git a/src/auth/authoptions.ts b/src/auth/authoptions.ts index 534370b91..eaf45e4a6 100644 --- a/src/auth/authoptions.ts +++ b/src/auth/authoptions.ts @@ -6,8 +6,8 @@ import { updateUserStudyProgrammes } from '@/lib/feide/userRoutines' import { prisma } from '@/prisma/client' import { readMembershipsOfUser } from '@/services/groups/memberships/read' import { updateEmailForFeideAccount } from '@/services/auth/feideAccounts/update' -import { UserMethods } from '@/services/users/methods' -import { PermissionMethods } from '@/services/permissions/methods' +import { userMethods } from '@/services/users/methods' +import { permissionMethods } from '@/services/permissions/methods' import CredentialsProvider from 'next-auth/providers/credentials' import { decode } from 'next-auth/jwt' import type { AuthOptions } from 'next-auth' @@ -127,7 +127,7 @@ export const authOptions: AuthOptions = { } // Trigger is undefined for subsequent calls case undefined: { - const dbUser = await UserMethods.read({ + const dbUser = await userMethods.read({ params: { id: token.user.id }, bypassAuth: true, }) @@ -164,11 +164,11 @@ export const authOptions: AuthOptions = { return { provider, - user: await UserMethods.read({ + user: await userMethods.read({ params: { id: userId }, bypassAuth: true, }), - permissions: await PermissionMethods.readPermissionsOfUser({ + permissions: await permissionMethods.readPermissionsOfUser({ bypassAuth: true, params: { userId, diff --git a/src/auth/getUser.ts b/src/auth/getUser.ts index 7ef780f30..e11af0c2a 100644 --- a/src/auth/getUser.ts +++ b/src/auth/getUser.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { authOptions } from './authoptions' import checkMatrix from '@/utils/checkMatrix' -import { PermissionMethods } from '@/services/permissions/methods' +import { permissionMethods } from '@/services/permissions/methods' import { getServerSession } from 'next-auth' import { notFound, redirect } from 'next/navigation' import type { Matrix } from '@/utils/checkMatrix' @@ -92,7 +92,7 @@ export async function getUser({ }: GetUserArgsType = {}): Promise> { const { user = null, - permissions = await PermissionMethods.readDefaultPermissions({ + permissions = await permissionMethods.readDefaultPermissions({ bypassAuth: true, }), memberships = [], diff --git a/src/prisma/seeder/src/development/seedDevEvents.ts b/src/prisma/seeder/src/development/seedDevEvents.ts index 077a609c1..3d29e6230 100644 --- a/src/prisma/seeder/src/development/seedDevEvents.ts +++ b/src/prisma/seeder/src/development/seedDevEvents.ts @@ -1,4 +1,4 @@ -import { EventMethods } from '@/services/events/methods' +import { eventMethods } from '@/services/events/methods' import type { PrismaClient } from '@prisma/client' export default async function seedDevEvents(prisma: PrismaClient) { @@ -17,7 +17,7 @@ export default async function seedDevEvents(prisma: PrismaClient) { } }) - const bedpres = await EventMethods.create({ + const bedpres = await eventMethods.create({ prisma, bypassAuth: true, data: { @@ -37,7 +37,7 @@ export default async function seedDevEvents(prisma: PrismaClient) { } }) - await EventMethods.create({ + await eventMethods.create({ prisma, bypassAuth: true, data: { diff --git a/src/prisma/seeder/src/development/seedDevJobAds.ts b/src/prisma/seeder/src/development/seedDevJobAds.ts index d0e64236e..4a279c6bf 100644 --- a/src/prisma/seeder/src/development/seedDevJobAds.ts +++ b/src/prisma/seeder/src/development/seedDevJobAds.ts @@ -1,4 +1,4 @@ -import { JobadMethods } from '@/services/career/jobAds/methods' +import { jobAdMethods } from '@/services/career/jobAds/methods' import type { JobType, PrismaClient } from '@prisma/client' @@ -51,7 +51,7 @@ export default async function seedDevJobAds(prisma: PrismaClient) { ] for (const jobAd of jobAdData) { - const restult = await JobadMethods.create({ + const restult = await jobAdMethods.create({ prisma, data: { ...jobAd, diff --git a/src/prisma/seeder/src/seedNotificationsChannels.ts b/src/prisma/seeder/src/seedNotificationsChannels.ts index a6255e2f1..344606379 100644 --- a/src/prisma/seeder/src/seedNotificationsChannels.ts +++ b/src/prisma/seeder/src/seedNotificationsChannels.ts @@ -1,4 +1,4 @@ -import { NotificationConfig } from '@/services/notifications/config' +import { allNotificationMethodsOn } from '@/services/notifications/config' import { SpecialNotificationChannel } from '@prisma/client' import type { NotificationMethod, PrismaClient } from '@prisma/client' @@ -19,8 +19,8 @@ export default async function seedNotificationChannels(prisma: PrismaClient) { special: 'ROOT', name: 'Alle varslinger', description: 'Denne kanalen styrer alle varslinger', - defaultMethods: NotificationConfig.allMethodsOn, - availableMethods: NotificationConfig.allMethodsOn, + defaultMethods: allNotificationMethodsOn, + availableMethods: allNotificationMethodsOn, }, { special: 'NEW_EVENT', @@ -30,35 +30,35 @@ export default async function seedNotificationChannels(prisma: PrismaClient) { email: false, emailWeekly: true, }, - availableMethods: NotificationConfig.allMethodsOn, + availableMethods: allNotificationMethodsOn, }, { special: 'NEW_OMBUL', name: 'Ny ombul', description: 'Varsling når det kommer ny ombul', - defaultMethods: NotificationConfig.allMethodsOff, - availableMethods: NotificationConfig.allMethodsOn, + defaultMethods: allNotificationMethodsOn, + availableMethods: allNotificationMethodsOn, }, { special: 'NEW_NEWS_ARTICLE', name: 'Ny nyhetsartikkel', description: 'Varslinger om nye artikler', - defaultMethods: NotificationConfig.allMethodsOff, - availableMethods: NotificationConfig.allMethodsOn, + defaultMethods: allNotificationMethodsOn, + availableMethods: allNotificationMethodsOn, }, { special: 'NEW_JOBAD', name: 'Ny jobbannonse', description: 'Varslinger at en ny jobbanonse er ute', - defaultMethods: NotificationConfig.allMethodsOff, - availableMethods: NotificationConfig.allMethodsOn, + defaultMethods: allNotificationMethodsOn, + availableMethods: allNotificationMethodsOn, }, { special: 'NEW_OMEGAQUOTE', name: 'Ny omegaquote', description: 'Varslinger om en ny omega quote', - defaultMethods: NotificationConfig.allMethodsOff, - availableMethods: NotificationConfig.allMethodsOn, + defaultMethods: allNotificationMethodsOn, + availableMethods: allNotificationMethodsOn, }, { special: 'EVENT_WAITINGLIST_PROMOTION', @@ -94,7 +94,7 @@ export default async function seedNotificationChannels(prisma: PrismaClient) { email: true, emailWeekly: false, }, - availableMethods: NotificationConfig.allMethodsOn, + availableMethods: allNotificationMethodsOn, alias: 'hs', }, { @@ -104,7 +104,7 @@ export default async function seedNotificationChannels(prisma: PrismaClient) { email: true, emailWeekly: false, }, - availableMethods: NotificationConfig.allMethodsOn, + availableMethods: allNotificationMethodsOn, alias: 'bleast', }, { @@ -114,7 +114,7 @@ export default async function seedNotificationChannels(prisma: PrismaClient) { email: true, emailWeekly: false, }, - availableMethods: NotificationConfig.allMethodsOn, + availableMethods: allNotificationMethodsOn, alias: 'vevcom', }, { @@ -124,7 +124,7 @@ export default async function seedNotificationChannels(prisma: PrismaClient) { email: true, emailWeekly: false, }, - availableMethods: NotificationConfig.allMethodsOn, + availableMethods: allNotificationMethodsOn, alias: 'contactor', }, { @@ -147,7 +147,7 @@ export default async function seedNotificationChannels(prisma: PrismaClient) { email: true, emailWeekly: false, }, - availableMethods: NotificationConfig.allMethodsOn, + availableMethods: allNotificationMethodsOn, }, ] diff --git a/src/services/action.ts b/src/services/action.ts index bbcf10c6e..92f08f0f5 100644 --- a/src/services/action.ts +++ b/src/services/action.ts @@ -1,9 +1,9 @@ import '@pn-server-only' import { safeServerCall } from './actionError' +import { Session } from '@/auth/Session' import type { ActionReturn } from './actionTypes' import type { ServiceMethod } from '@/services/serviceMethod' import type { z } from 'zod' -import { Session } from '@/auth/Session' export function action( serviceMethod: ServiceMethod diff --git a/src/services/admission/actions.ts b/src/services/admission/actions.ts index 49ab11c0f..1599061ed 100644 --- a/src/services/admission/actions.ts +++ b/src/services/admission/actions.ts @@ -1,6 +1,6 @@ 'use server' import { action } from '@/services/action' -import { AdmissionMethods } from '@/services/admission/methods' +import { admissionMethods } from '@/services/admission/methods' -export const createAdmissionTrialAction = action(AdmissionMethods.createTrial) +export const createAdmissionTrialAction = action(admissionMethods.createTrial) diff --git a/src/services/admission/authers.ts b/src/services/admission/authers.ts index 9bcf6e00d..25ebce0a2 100644 --- a/src/services/admission/authers.ts +++ b/src/services/admission/authers.ts @@ -1,9 +1,9 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequirePermissionAndUser } from '@/auth/auther/RequirePermissionAndUser' -export namespace AdmissionAuthers { - export const createTrial = RequirePermissionAndUser.staticFields({ +export const admissionAuthers = { + createTrial: RequirePermissionAndUser.staticFields({ permission: 'ADMISSION_TRIAL_CREATE', - }) - export const readTrial = RequireNothing.staticFields({}) + }), + readTrial: RequireNothing.staticFields({}), } diff --git a/src/services/admission/config.ts b/src/services/admission/config.ts index 364ca97e8..b91f12313 100644 --- a/src/services/admission/config.ts +++ b/src/services/admission/config.ts @@ -1,9 +1,8 @@ import { Admission } from '@prisma/client' -export namespace AdmissionConfig { - export const displayNames = { - PLIKTTIAENESTE: 'Plikttiaeneste', - PROEVELSEN: 'Proevelsen', - } as const satisfies Record - export const array = Object.values(Admission) -} +export const admissionDisplayNames = { + PLIKTTIAENESTE: 'Plikttiaeneste', + PROEVELSEN: 'Proevelsen', +} as const satisfies Record + +export const allAdmissions = Object.values(Admission) diff --git a/src/services/admission/methods.ts b/src/services/admission/methods.ts index 9643bb5f9..5e6712b82 100644 --- a/src/services/admission/methods.ts +++ b/src/services/admission/methods.ts @@ -1,16 +1,16 @@ import '@pn-server-only' -import { AdmissionSchemas } from './schemas' -import { AdmissionAuthers } from './authers' +import { admissionSchemas } from './schemas' +import { admissionAuthers } from './authers' +import { userFilterSelection } from '@/services/users/config' import { serviceMethod } from '@/services/serviceMethod' import { updateUserOmegaMembershipGroup } from '@/services/groups/omegaMembershipGroups/update' -import { UserConfig } from '@/services/users/config' import { Admission } from '@prisma/client' import { z } from 'zod' import type { ExpandedAdmissionTrail } from './Types' -export namespace AdmissionMethods { - export const readTrial = serviceMethod({ - authorizer: () => AdmissionAuthers.readTrial.dynamicFields({}), +export const admissionMethods = { + readTrial: serviceMethod({ + authorizer: () => admissionAuthers.readTrial.dynamicFields({}), paramsSchema: z.object({ userId: z.number(), }), @@ -19,13 +19,13 @@ export namespace AdmissionMethods { userId, } }) - }) - export const createTrial = serviceMethod({ - authorizer: () => AdmissionAuthers.createTrial.dynamicFields({}), + }), + createTrial: serviceMethod({ + authorizer: () => admissionAuthers.createTrial.dynamicFields({}), paramsSchema: z.object({ admission: z.nativeEnum(Admission), }), - dataSchema: AdmissionSchemas.createTrial, + dataSchema: admissionSchemas.createTrial, method: async ({ prisma, session, params, data }): Promise => { const results = await prisma.admissionTrial.create({ data: { @@ -43,13 +43,13 @@ export namespace AdmissionMethods { }, include: { user: { - select: UserConfig.filterSelection + select: userFilterSelection, } } }) // check if user has taken all admissions - const userTrials = await readTrial({ + const userTrials = await admissionMethods.readTrial({ params: { userId: data.userId }, @@ -61,5 +61,5 @@ export namespace AdmissionMethods { return results } - }) + }), } diff --git a/src/services/admission/schemas.ts b/src/services/admission/schemas.ts index 3ace62c7b..630b7b210 100644 --- a/src/services/admission/schemas.ts +++ b/src/services/admission/schemas.ts @@ -1,10 +1,11 @@ import { z } from 'zod' -export namespace AdmissionSchemas { - const fields = z.object({ - userId: z.coerce.number(), - }) - export const createTrial = fields.pick({ +const baseSchema = z.object({ + userId: z.coerce.number(), +}) + +export const admissionSchemas = { + createTrial: baseSchema.pick({ userId: true, }) } diff --git a/src/services/api-keys/Types.ts b/src/services/api-keys/Types.ts index 3bd68ad70..07c39330c 100644 --- a/src/services/api-keys/Types.ts +++ b/src/services/api-keys/Types.ts @@ -1,7 +1,7 @@ -import type { ApiKeyConfig } from './config' +import type { apiKeyFieldsToExpose } from './config' import type { ApiKey } from '@prisma/client' -export type ApiKeyFiltered = Pick +export type ApiKeyFiltered = Pick export type ApiKeyFilteredWithKey = ApiKeyFiltered & { key: string diff --git a/src/services/api-keys/actions.ts b/src/services/api-keys/actions.ts index 4cd3defe9..dc3a2364d 100644 --- a/src/services/api-keys/actions.ts +++ b/src/services/api-keys/actions.ts @@ -1,13 +1,13 @@ 'use server' import { action } from '@/services/action' -import { ApiKeyMethods } from '@/services/api-keys/methods' +import { apiKeyMethods } from '@/services/api-keys/methods' -export const createApiKeyAction = action(ApiKeyMethods.create) +export const createApiKeyAction = action(apiKeyMethods.create) -export const destroyApiKeyAction = action(ApiKeyMethods.destroy) +export const destroyApiKeyAction = action(apiKeyMethods.destroy) -export const readApiKeysAction = action(ApiKeyMethods.readMany) -export const readApiKeyAction = action(ApiKeyMethods.read) +export const readApiKeysAction = action(apiKeyMethods.readMany) +export const readApiKeyAction = action(apiKeyMethods.read) -export const updateApiKeyAction = action(ApiKeyMethods.update) +export const updateApiKeyAction = action(apiKeyMethods.update) diff --git a/src/services/api-keys/authers.ts b/src/services/api-keys/authers.ts index 7c92c6325..d9231cd2d 100644 --- a/src/services/api-keys/authers.ts +++ b/src/services/api-keys/authers.ts @@ -1,11 +1,13 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace ApiKeyAuthers { - export const create = RequirePermission.staticFields({ permission: 'APIKEY_ADMIN' }) - export const read = RequirePermission.staticFields({ permission: 'APIKEY_ADMIN' }) - export const readMany = RequirePermission.staticFields({ permission: 'APIKEY_ADMIN' }) - export const readWithHash = RequirePermission.staticFields({ permission: 'APIKEY_ADMIN' }) - export const update = RequirePermission.staticFields({ permission: 'APIKEY_ADMIN' }) - export const updateIfExpired = RequirePermission.staticFields({ permission: 'APIKEY_ADMIN' }) - export const destroy = RequirePermission.staticFields({ permission: 'APIKEY_ADMIN' }) +const baseAuther = RequirePermission.staticFields({ permission: 'APIKEY_ADMIN' }) + +export const apiKeyAuthers = { + create: baseAuther, + read: baseAuther, + readMany: baseAuther, + readWithHash: baseAuther, + update: baseAuther, + updateIfExpired: baseAuther, + destroy: baseAuther, } diff --git a/src/services/api-keys/config.ts b/src/services/api-keys/config.ts index 7376d7402..5c08a5cf2 100644 --- a/src/services/api-keys/config.ts +++ b/src/services/api-keys/config.ts @@ -1,18 +1,15 @@ import { createSelection } from '@/services/createSelection' import type { ApiKey } from '@prisma/client' +export const apiKeyFieldsToExpose = [ + 'id', + 'active', + 'createdAt', + 'updatedAt', + 'name', + 'permissions', + 'expiresAt' +] as const satisfies (keyof ApiKey)[] -export namespace ApiKeyConfig { - export const fieldsToExpose = [ - 'id', - 'active', - 'createdAt', - 'updatedAt', - 'name', - 'permissions', - 'expiresAt' - ] as const satisfies (keyof ApiKey)[] - - export const filterSelection = createSelection([...fieldsToExpose]) - export const keyLength = 32 as const -} +export const apiFilterSelection = createSelection([...apiKeyFieldsToExpose]) +export const apiKeyLength = 32 as const diff --git a/src/services/api-keys/methods.ts b/src/services/api-keys/methods.ts index 05c1f0c8f..5eb7c43fb 100644 --- a/src/services/api-keys/methods.ts +++ b/src/services/api-keys/methods.ts @@ -1,9 +1,9 @@ import '@pn-server-only' -import { ApiKeyAuthers } from './authers' -import { ApiKeyConfig } from './config' -import { ApiKeySchemas } from './schemas' +import { apiKeyAuthers } from './authers' +import { apiKeySchemas } from './schemas' import { apiKeyHashAndEncrypt } from './hashEncryptKey' import { encodeApiKey } from './apiKeyEncoder' +import { apiFilterSelection, apiKeyLength } from './config' import { ServerError } from '@/services/error' import { serviceMethod } from '@/services/serviceMethod' import logger from '@/lib/logger' @@ -11,44 +11,47 @@ import { z } from 'zod' import crypto from 'crypto' import type { ApiKeyFiltered, ApiKeyFilteredWithKey } from './Types' -export namespace ApiKeyMethods { - /** - * Updates the active status of an api key if it has expired, i.e. if the expiresAt date is in the past. - * This method is used when reading api keys to ensure that the active status is correct. - */ - const updateIfExpired = serviceMethod({ - authorizer: () => ApiKeyAuthers.updateIfExpired.dynamicFields({}), - paramsSchema: z.object({ - id: z.number(), - expiresAt: z.date().nullable(), - active: z.boolean(), - }), - method: async ({ prisma, params: apiKey }) => { - if (!apiKey) { - throw new ServerError('NOT FOUND', 'Nøkkelen finnes ikke') - } +/** + * Updates the active status of an api key if it has expired, i.e. if the expiresAt date is in the past. + * This method is used when reading api keys to ensure that the active status is correct. + * + * Note: This operaiton is only used internally. + */ +const updateIfExpired = serviceMethod({ + authorizer: () => apiKeyAuthers.updateIfExpired.dynamicFields({}), + paramsSchema: z.object({ + id: z.number(), + expiresAt: z.date().nullable(), + active: z.boolean(), + }), + method: async ({ prisma, params: apiKey }) => { + if (!apiKey) { + throw new ServerError('NOT FOUND', 'Nøkkelen finnes ikke') + } - if (!apiKey.expiresAt || apiKey.expiresAt > new Date()) return { active: apiKey.active } - logger.info('Deactivating expired api key', { id: apiKey.id }) + if (!apiKey.expiresAt || apiKey.expiresAt > new Date()) return { active: apiKey.active } + logger.info('Deactivating expired api key', { id: apiKey.id }) - const updated = await prisma.apiKey.update({ - where: { id: apiKey.id }, - data: { active: false }, - select: { active: true }, - }) - return { - active: updated.active, - } + const updated = await prisma.apiKey.update({ + where: { id: apiKey.id }, + data: { active: false }, + select: { active: true }, + }) + return { + active: updated.active, } - }) - export const create = serviceMethod({ - authorizer: () => ApiKeyAuthers.create.dynamicFields({}), - dataSchema: ApiKeySchemas.create, + } +}) + +export const apiKeyMethods = { + create: serviceMethod({ + authorizer: () => apiKeyAuthers.create.dynamicFields({}), + dataSchema: apiKeySchemas.create, method: async ({ prisma, data }): Promise => { const NODE_ENV = process.env.NODE_ENV const prepend = NODE_ENV === 'production' ? 'prod' : 'dev' - const key = prepend + crypto.randomBytes(ApiKeyConfig.keyLength - prepend.length).toString('hex') + const key = prepend + crypto.randomBytes(apiKeyLength - prepend.length).toString('hex') const keyHashEncrypted = await apiKeyHashAndEncrypt(key) const apiKey = await prisma.apiKey.create({ @@ -57,13 +60,13 @@ export namespace ApiKeyMethods { name: data.name, active: true, }, - select: ApiKeyConfig.filterSelection + select: apiFilterSelection, }) return { ...apiKey, key: encodeApiKey({ key, id: apiKey.id }) } } - }) - export const read = serviceMethod({ - authorizer: () => ApiKeyAuthers.read.dynamicFields({}), + }), + read: serviceMethod({ + authorizer: () => apiKeyAuthers.read.dynamicFields({}), paramsSchema: z.union([z.object({ id: z.number() }), z.object({ name: z.string() })]), method: async ({ prisma, params }): Promise => { const apiKey = await prisma.apiKey.findUnique({ @@ -71,7 +74,7 @@ export namespace ApiKeyMethods { id: 'id' in params ? params.id : undefined, name: 'name' in params ? params.name : undefined, }, - select: ApiKeyConfig.filterSelection + select: apiFilterSelection, }) if (!apiKey) throw new ServerError('BAD PARAMETERS', 'Api key does not exist') @@ -83,12 +86,12 @@ export namespace ApiKeyMethods { }) } } - }) - export const readMany = serviceMethod({ - authorizer: () => ApiKeyAuthers.readMany.dynamicFields({}), + }), + readMany: serviceMethod({ + authorizer: () => apiKeyAuthers.readMany.dynamicFields({}), method: async ({ prisma }): Promise => { const apiKeys = await prisma.apiKey.findMany({ - select: ApiKeyConfig.filterSelection, + select: apiFilterSelection, orderBy: [ { active: 'desc' }, { name: 'asc' } @@ -103,9 +106,9 @@ export namespace ApiKeyMethods { }) }))) } - }) - export const readWithHash = serviceMethod({ - authorizer: () => ApiKeyAuthers.readWithHash.dynamicFields({}), + }), + readWithHash: serviceMethod({ + authorizer: () => apiKeyAuthers.readWithHash.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -129,13 +132,13 @@ export namespace ApiKeyMethods { }), } } - }) - export const update = serviceMethod({ - authorizer: () => ApiKeyAuthers.update.dynamicFields({}), + }), + update: serviceMethod({ + authorizer: () => apiKeyAuthers.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - dataSchema: ApiKeySchemas.update, + dataSchema: apiKeySchemas.update, method: async ({ prisma, params, data }) => { if (data.active && data.expiresAt && data.expiresAt < new Date()) { throw new ServerError('BAD PARAMETERS', 'Hvis du vil aktivere en nøkkel, kan den ikke ha utløpt') @@ -147,9 +150,9 @@ export namespace ApiKeyMethods { }) return { name } }, - }) - export const destroy = serviceMethod({ - authorizer: () => ApiKeyAuthers.destroy.dynamicFields({}), + }), + destroy: serviceMethod({ + authorizer: () => apiKeyAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -170,5 +173,5 @@ export namespace ApiKeyMethods { }) }) } - }) + }), } diff --git a/src/services/api-keys/schemas.ts b/src/services/api-keys/schemas.ts index 4cc875129..81310fe7c 100644 --- a/src/services/api-keys/schemas.ts +++ b/src/services/api-keys/schemas.ts @@ -2,20 +2,21 @@ import { zpn } from '@/lib/fields/zpn' import { z } from 'zod' import { Permission } from '@prisma/client' -export namespace ApiKeySchemas { - const fields = z.object({ - name: z.string().min(10, 'minimum lengde 10').max(100, 'maksimum lengde 100'), - expiresAt: z.coerce.date().optional(), - active: zpn.checkboxOrBoolean({ label: 'Aktiv' }), - permissions: zpn.enumListCheckboxFriendly({ label: 'Tillatelser', enum: Permission }) - }) - export const create = fields.pick({ +const baseSchema = z.object({ + name: z.string().min(10, 'minimum lengde 10').max(100, 'maksimum lengde 100'), + expiresAt: z.coerce.date().optional(), + active: zpn.checkboxOrBoolean({ label: 'Aktiv' }), + permissions: zpn.enumListCheckboxFriendly({ label: 'Tillatelser', enum: Permission }) +}) + +export const apiKeySchemas = { + create: baseSchema.pick({ name: true, - }) - export const update = fields.partial().pick({ + }), + update: baseSchema.partial().pick({ name: true, expiresAt: true, active: true, permissions: true - }) + }), } diff --git a/src/services/applications/actions.ts b/src/services/applications/actions.ts index 0c63bc9ff..29922f1db 100644 --- a/src/services/applications/actions.ts +++ b/src/services/applications/actions.ts @@ -1,12 +1,12 @@ 'use server' +import { applicationMethods } from './methods' import { action } from '@/services/action' -import { ApplicationMethods } from '@/services/applications/methods' -export const createApplicationAction = action(ApplicationMethods.create) +export const createApplicationAction = action(applicationMethods.create) -export const destroyApplicationAction = action(ApplicationMethods.destroy) +export const destroyApplicationAction = action(applicationMethods.destroy) -export const readApplicationsForUserAction = action(ApplicationMethods.readForUser) +export const readApplicationsForUserAction = action(applicationMethods.readForUser) -export const updateApplicationAction = action(ApplicationMethods.update) +export const updateApplicationAction = action(applicationMethods.update) diff --git a/src/services/applications/authers.ts b/src/services/applications/authers.ts index e545e43e9..235bb4956 100644 --- a/src/services/applications/authers.ts +++ b/src/services/applications/authers.ts @@ -1,8 +1,8 @@ import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' -export namespace ApplicationAuthers { - export const readForUser = RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }) - export const create = RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }) - export const update = RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }) - export const destroy = RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }) +export const applicationAuthers = { + readForUser: RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }), + create: RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }), + update: RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }), + destroy: RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }), } diff --git a/src/services/applications/methods.ts b/src/services/applications/methods.ts index 2100b4ce4..8b82ddb0c 100644 --- a/src/services/applications/methods.ts +++ b/src/services/applications/methods.ts @@ -1,32 +1,32 @@ import '@pn-server-only' -import { ApplicationAuthers } from './authers' -import { ApplicationSchemas } from './schemas' +import { applicationAuthers } from './authers' +import { applicationSchemas } from './schemas' import { ServerError } from '@/services/error' import { serviceMethod } from '@/services/serviceMethod' import { z } from 'zod' -export namespace ApplicationMethods { - export const readForUser = serviceMethod({ +export const applicationMethods = { + readForUser: serviceMethod({ paramsSchema: z.object({ userId: z.number(), periodId: z.number() }), - authorizer: ({ params }) => ApplicationAuthers.readForUser.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => applicationAuthers.readForUser.dynamicFields({ userId: params.userId }), method: async ({ prisma, params }) => prisma.application.findMany({ where: { userId: params.userId, applicationPeriodId: params.periodId } }) - }) + }), - export const create = serviceMethod({ - dataSchema: ApplicationSchemas.create, + create: serviceMethod({ + dataSchema: applicationSchemas.create, paramsSchema: z.object({ userId: z.number(), commiteeParticipationId: z.number() }), - authorizer: ({ params }) => ApplicationAuthers.create.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => applicationAuthers.create.dynamicFields({ userId: params.userId }), method: async ({ prisma, data, params }) => { const commiteeParticipation = await prisma.committeeParticipationInApplicationPeriod.findUniqueOrThrow({ where: { @@ -76,16 +76,16 @@ export namespace ApplicationMethods { } }) }, - }) + }), - export const update = serviceMethod({ - dataSchema: ApplicationSchemas.update, + update: serviceMethod({ + dataSchema: applicationSchemas.update, paramsSchema: z.object({ userId: z.number(), commiteeParticipationId: z.number() }), opensTransaction: true, - authorizer: ({ params }) => ApplicationAuthers.update.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => applicationAuthers.update.dynamicFields({ userId: params.userId }), method: async ({ prisma, data, params }) => { const application = await prisma.application.findUniqueOrThrow({ where: { @@ -192,14 +192,14 @@ export namespace ApplicationMethods { }) }) }, - }) + }), - export const destroy = serviceMethod({ + destroy: serviceMethod({ paramsSchema: z.object({ userId: z.number(), commiteeParticipationId: z.number() }), - authorizer: ({ params }) => ApplicationAuthers.destroy.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => applicationAuthers.destroy.dynamicFields({ userId: params.userId }), opensTransaction: true, method: async ({ prisma, params }) => { prisma.$transaction(async (tx) => { @@ -245,5 +245,5 @@ export namespace ApplicationMethods { }) }) } - }) + }), } diff --git a/src/services/applications/periods/Types.ts b/src/services/applications/periods/Types.ts index 737af9dbf..f03f0c86c 100644 --- a/src/services/applications/periods/Types.ts +++ b/src/services/applications/periods/Types.ts @@ -1,4 +1,4 @@ -import type { ApplicationPeriodConfig } from './config' +import type { committeesParticipatingincluder } from './config' import type { Image, Prisma } from '@prisma/client' export type CountdownInfo = { @@ -10,5 +10,5 @@ export type CountdownInfo = { } export type ExpandedApplicationPeriod = Prisma.ApplicationPeriodGetPayload<{ - include: typeof ApplicationPeriodConfig.includer + include: typeof committeesParticipatingincluder }> diff --git a/src/services/applications/periods/actions.ts b/src/services/applications/periods/actions.ts index bf2df977a..dec1af610 100644 --- a/src/services/applications/periods/actions.ts +++ b/src/services/applications/periods/actions.ts @@ -1,15 +1,15 @@ 'use server' import { action } from '@/services/action' -import { ApplicationPeriodMethods } from '@/services/applications/periods/methods' +import { applicationPeriodMethods } from '@/services/applications/periods/methods' -export const createApplicationPeriodAction = action(ApplicationPeriodMethods.create) +export const createApplicationPeriodAction = action(applicationPeriodMethods.create) -export const destroyApplicationPeriodAction = action(ApplicationPeriodMethods.destroy) -export const removeAllApplicationTextsAction = action(ApplicationPeriodMethods.removeAllApplicationTexts) +export const destroyApplicationPeriodAction = action(applicationPeriodMethods.destroy) +export const removeAllApplicationTextsAction = action(applicationPeriodMethods.removeAllApplicationTexts) -export const readApplicationPeriodsAction = action(ApplicationPeriodMethods.readAll) -export const readApplicationPeriodAction = action(ApplicationPeriodMethods.read) -export const readNumberOfApplicationsAction = action(ApplicationPeriodMethods.readNumberOfApplications) +export const readApplicationPeriodsAction = action(applicationPeriodMethods.readAll) +export const readApplicationPeriodAction = action(applicationPeriodMethods.read) +export const readNumberOfApplicationsAction = action(applicationPeriodMethods.readNumberOfApplications) -export const updateApplicationPeriodAction = action(ApplicationPeriodMethods.update) +export const updateApplicationPeriodAction = action(applicationPeriodMethods.update) diff --git a/src/services/applications/periods/authers.ts b/src/services/applications/periods/authers.ts index da2046b1f..6f8483f02 100644 --- a/src/services/applications/periods/authers.ts +++ b/src/services/applications/periods/authers.ts @@ -1,11 +1,11 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace ApplicationPeriodAuthers { - export const readAll = RequirePermission.staticFields({ permission: 'APPLICATION_WRITE' }) - export const read = RequirePermission.staticFields({ permission: 'APPLICATION_WRITE' }) - export const readNumberOfApplications = RequirePermission.staticFields({ permission: 'APPLICATION_WRITE' }) - export const create = RequirePermission.staticFields({ permission: 'APPLICATION_ADMIN' }) - export const update = RequirePermission.staticFields({ permission: 'APPLICATION_ADMIN' }) - export const removeAllApplicationTexts = RequirePermission.staticFields({ permission: 'APPLICATION_ADMIN' }) - export const destroy = RequirePermission.staticFields({ permission: 'APPLICATION_ADMIN' }) +export const applicationPeriodAuthers = { + readAll: RequirePermission.staticFields({ permission: 'APPLICATION_WRITE' }), + read: RequirePermission.staticFields({ permission: 'APPLICATION_WRITE' }), + readNumberOfApplications: RequirePermission.staticFields({ permission: 'APPLICATION_WRITE' }), + create: RequirePermission.staticFields({ permission: 'APPLICATION_ADMIN' }), + update: RequirePermission.staticFields({ permission: 'APPLICATION_ADMIN' }), + removeAllApplicationTexts: RequirePermission.staticFields({ permission: 'APPLICATION_ADMIN' }), + destroy: RequirePermission.staticFields({ permission: 'APPLICATION_ADMIN' }), } diff --git a/src/services/applications/periods/config.ts b/src/services/applications/periods/config.ts index 44249731a..f213b5360 100644 --- a/src/services/applications/periods/config.ts +++ b/src/services/applications/periods/config.ts @@ -1,20 +1,18 @@ import type { Prisma } from '@prisma/client' -export namespace ApplicationPeriodConfig { - export const includer = { - committeesParticipating: { - include: { - committee: { - include: { - logoImage: { - include: { - image: true - } - }, - paragraph: true - } +export const committeesParticipatingincluder = { + committeesParticipating: { + include: { + committee: { + include: { + logoImage: { + include: { + image: true + } + }, + paragraph: true } } } - } as const satisfies Prisma.ApplicationPeriodInclude -} + } +} as const satisfies Prisma.ApplicationPeriodInclude diff --git a/src/services/applications/periods/methods.ts b/src/services/applications/periods/methods.ts index 5385fa112..4ad811ab8 100644 --- a/src/services/applications/periods/methods.ts +++ b/src/services/applications/periods/methods.ts @@ -1,32 +1,32 @@ import '@pn-server-only' -import { ApplicationPeriodAuthers } from './authers' -import { ApplicationPeriodSchemas } from './schemas' -import { ApplicationPeriodConfig } from './config' -import { serviceMethod } from '@/services/serviceMethod' -import { ApplicationMethods } from '@/services/applications/methods' +import { applicationPeriodAuthers } from './authers' +import { applicationPeriodSchemas } from './schemas' +import { committeesParticipatingincluder } from './config' +import { applicationMethods } from '@/services/applications/methods' import { ServerError } from '@/services/error' +import { serviceMethod } from '@/services/serviceMethod' import { z } from 'zod' -export namespace ApplicationPeriodMethods { - export const readAll = serviceMethod({ - authorizer: () => ApplicationPeriodAuthers.readAll.dynamicFields({}), +export const applicationPeriodMethods = { + readAll: serviceMethod({ + authorizer: () => applicationPeriodAuthers.readAll.dynamicFields({}), method: async ({ prisma }) => prisma.applicationPeriod.findMany() - }) + }), - export const read = serviceMethod({ - authorizer: () => ApplicationPeriodAuthers.read.dynamicFields({}), + read: serviceMethod({ + authorizer: () => applicationPeriodAuthers.read.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), method: async ({ prisma, params }) => prisma.applicationPeriod.findUniqueOrThrow({ where: { name: params.name }, - include: ApplicationPeriodConfig.includer + include: committeesParticipatingincluder, }) - }) + }), - export const create = serviceMethod({ - authorizer: () => ApplicationPeriodAuthers.create.dynamicFields({}), - dataSchema: ApplicationPeriodSchemas.create, + create: serviceMethod({ + authorizer: () => applicationPeriodAuthers.create.dynamicFields({}), + dataSchema: applicationPeriodSchemas.create, method: async ({ prisma, data }) => { await prisma.applicationPeriod.create({ data: { @@ -41,11 +41,11 @@ export namespace ApplicationPeriodMethods { }) return { name: data.name } } - }) + }), - export const update = serviceMethod({ - authorizer: () => ApplicationPeriodAuthers.update.dynamicFields({}), - dataSchema: ApplicationPeriodSchemas.update, + update: serviceMethod({ + authorizer: () => applicationPeriodAuthers.update.dynamicFields({}), + dataSchema: applicationPeriodSchemas.update, paramsSchema: z.object({ name: z.string() }), @@ -69,7 +69,7 @@ export namespace ApplicationPeriodMethods { if (data.participatingCommitteeIds) { // Remove applications to committees that are no longer participating - // This must be done through the ApplicationMethods.destroy method to ensure + // This must be done through the applicationMethods.destroy method to ensure // that reordering priorities is handled correctly. await Promise.all( period.committeesParticipating @@ -90,7 +90,7 @@ export namespace ApplicationPeriodMethods { }) await Promise.all( removeApplications.map(async application => - await ApplicationMethods.destroy({ + await applicationMethods.destroy({ params: { userId: application.userId, commiteeParticipationId: application.applicationPeriodCommiteeId @@ -120,15 +120,15 @@ export namespace ApplicationPeriodMethods { return { name: period.name } } - }) + }), - export const removeAllApplicationTexts = serviceMethod({ + removeAllApplicationTexts: serviceMethod({ paramsSchema: z.object({ name: z.string() }), - authorizer: () => ApplicationPeriodAuthers.removeAllApplicationTexts.dynamicFields({}), + authorizer: () => applicationPeriodAuthers.removeAllApplicationTexts.dynamicFields({}), method: async ({ prisma, params, session }) => { - const period = await read({ + const period = await applicationPeriodMethods.read({ params: { name: params.name }, session }) @@ -146,10 +146,10 @@ export namespace ApplicationPeriodMethods { } }) } - }) + }), - export const destroy = serviceMethod({ - authorizer: () => ApplicationPeriodAuthers.destroy.dynamicFields({}), + destroy: serviceMethod({ + authorizer: () => applicationPeriodAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), @@ -158,10 +158,10 @@ export namespace ApplicationPeriodMethods { where: { name: params.name } }) } - }) + }), - export const readNumberOfApplications = serviceMethod({ - authorizer: () => ApplicationPeriodAuthers.readNumberOfApplications.dynamicFields({}), + readNumberOfApplications: serviceMethod({ + authorizer: () => applicationPeriodAuthers.readNumberOfApplications.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), @@ -178,5 +178,5 @@ export namespace ApplicationPeriodMethods { }, }) } - }) + }), } diff --git a/src/services/applications/periods/schemas.ts b/src/services/applications/periods/schemas.ts index 2c645b70d..b98505628 100644 --- a/src/services/applications/periods/schemas.ts +++ b/src/services/applications/periods/schemas.ts @@ -1,37 +1,37 @@ import { zpn } from '@/lib/fields/zpn' import { z } from 'zod' -export namespace ApplicationPeriodSchemas { - const fields = z.object({ - name: z.string().trim().min(2, { message: 'Navnet må være minst 2 tegn.' }), - startDate: zpn.date({ label: 'Start' }), - endDate: zpn.date({ label: 'Siste frist for søknader' }), - endPriorityDate: zpn.date({ label: 'Siste frist for prioritering' }), - participatingCommitteeIds: zpn.numberListCheckboxFriendly({ label: 'Deltakende komiteer' }) - }) +const fields = z.object({ + name: z.string().trim().min(2, { message: 'Navnet må være minst 2 tegn.' }), + startDate: zpn.date({ label: 'Start' }), + endDate: zpn.date({ label: 'Siste frist for søknader' }), + endPriorityDate: zpn.date({ label: 'Siste frist for prioritering' }), + participatingCommitteeIds: zpn.numberListCheckboxFriendly({ label: 'Deltakende komiteer' }) +}) - const refineDates = { - fcn: (data: { startDate?: Date, endDate?: Date, endPriorityDate?: Date }) => { - if (!data.startDate && !data.endDate && !data.endPriorityDate) return true - if (!data.startDate || !data.endDate || !data.endPriorityDate) return false - return data.startDate < data.endDate && data.endDate <= data.endPriorityDate - }, - message: 'Starttidspunktet må være før sluttidspunktet.' - } +const refineDates = { + fcn: (data: { startDate?: Date, endDate?: Date, endPriorityDate?: Date }) => { + if (!data.startDate && !data.endDate && !data.endPriorityDate) return true + if (!data.startDate || !data.endDate || !data.endPriorityDate) return false + return data.startDate < data.endDate && data.endDate <= data.endPriorityDate + }, + message: 'Starttidspunktet må være før sluttidspunktet.' +} - export const create = fields.pick({ +export const applicationPeriodSchemas = { + create: fields.pick({ name: true, startDate: true, endDate: true, endPriorityDate: true, participatingCommitteeIds: true - }).refine(refineDates.fcn, refineDates.message) + }).refine(refineDates.fcn, refineDates.message), - export const update = fields.pick({ + update: fields.pick({ name: true, startDate: true, endDate: true, endPriorityDate: true, participatingCommitteeIds: true - }).partial().refine(refineDates.fcn, refineDates.message) + }).partial().refine(refineDates.fcn, refineDates.message), } diff --git a/src/services/applications/schemas.ts b/src/services/applications/schemas.ts index 01d4ca622..3ee37772e 100644 --- a/src/services/applications/schemas.ts +++ b/src/services/applications/schemas.ts @@ -1,21 +1,21 @@ import { z } from 'zod' -export namespace ApplicationSchemas { - const fields = z.object({ - text: z.string().trim().min( - 1, { message: 'Søknadsteksten kan ikke være tom.' } - ).max( - 1000, { message: 'Søknadsteksten kan ikke være lengre enn 1000 tegn.' } - ), - priority: z.literal('UP').or(z.literal('DOWN')) - }) +const baseSchema = z.object({ + text: z.string().trim().min( + 1, { message: 'Søknadsteksten kan ikke være tom.' } + ).max( + 1000, { message: 'Søknadsteksten kan ikke være lengre enn 1000 tegn.' } + ), + priority: z.literal('UP').or(z.literal('DOWN')) +}) - export const create = fields.pick({ +export const applicationSchemas = { + create: baseSchema.pick({ text: true, - }) + }), - export const update = fields.pick({ + update: baseSchema.pick({ text: true, priority: true - }).partial() + }).partial(), } diff --git a/src/services/auth/actions.ts b/src/services/auth/actions.ts index 6f624c393..3f000c5da 100644 --- a/src/services/auth/actions.ts +++ b/src/services/auth/actions.ts @@ -1,9 +1,9 @@ 'use server' import { action } from '@/services/action' -import { AuthMethods } from '@/services/auth/methods' +import { authMethods } from '@/services/auth/methods' -export const verifyResetPasswordTokenAction = action(AuthMethods.verifyResetPasswordToken) -export const resetPasswordAction = action(AuthMethods.resetPassword) -export const sendResetPasswordEmailAction = action(AuthMethods.sendResetPasswordEmail) -export const verifyEmailAction = action(AuthMethods.verifyEmail) +export const verifyResetPasswordTokenAction = action(authMethods.verifyResetPasswordToken) +export const resetPasswordAction = action(authMethods.resetPassword) +export const sendResetPasswordEmailAction = action(authMethods.sendResetPasswordEmail) +export const verifyEmailAction = action(authMethods.verifyEmail) diff --git a/src/services/auth/authers.ts b/src/services/auth/authers.ts index 3b9e0a99b..b91bbaff0 100644 --- a/src/services/auth/authers.ts +++ b/src/services/auth/authers.ts @@ -1,8 +1,8 @@ import { RequireJWT } from '@/auth/auther/RequireJWT' import { RequireNothing } from '@/auth/auther/RequireNothing' -export namespace AuthAuthers { - export const verifyEmail = RequireJWT.staticFields({ audience: 'verifyemail' }) - export const resetPassword = RequireJWT.staticFields({ audience: 'resetpassword' }) - export const sendResetPasswordEmail = RequireNothing.staticFields({}) +export const authAuthers = { + verifyEmail: RequireJWT.staticFields({ audience: 'verifyemail' }), + resetPassword: RequireJWT.staticFields({ audience: 'resetpassword' }), + sendResetPasswordEmail: RequireNothing.staticFields({}), } diff --git a/src/services/auth/methods.ts b/src/services/auth/methods.ts index 4bd705a1c..6ed3c2329 100644 --- a/src/services/auth/methods.ts +++ b/src/services/auth/methods.ts @@ -1,21 +1,21 @@ -import { AuthAuthers } from './authers' -import { AuthSchemas } from './schemas' +import { authAuthers } from './authers' +import { authSchemas } from './schemas' +import { userFilterSelection } from '@/services/users/config' +import { userSchemas } from '@/services/users/schemas' import { sendResetPasswordMail } from '@/services/notifications/email/systemMail/resetPassword' import { serviceMethod } from '@/services/serviceMethod' import { ServerError } from '@/services/error' -import { UserMethods } from '@/services/users/methods' -import { UserConfig } from '@/services/users/config' +import { userMethods } from '@/services/users/methods' import { readJWTPayload } from '@/lib/jwt/jwtReadUnsecure' -import { UserSchemas } from '@/services/users/schemas' import { z } from 'zod' -export namespace AuthMethods { +export const authMethods = { - export const verifyEmail = serviceMethod({ + verifyEmail: serviceMethod({ paramsSchema: z.object({ token: z.string(), }), - authorizer: ({ params }) => AuthAuthers.verifyEmail.dynamicFields(params), + authorizer: ({ params }) => authAuthers.verifyEmail.dynamicFields(params), method: async ({ prisma, params }) => { // INFO: Safe to parse unsafe since the auther has verified the token. const payload = readJWTPayload(params.token) @@ -29,7 +29,7 @@ export namespace AuthMethods { const iat = new Date(payload.iat * 1000) - const user = await UserMethods.read({ + const user = await userMethods.read({ params: { id: userId, }, @@ -48,16 +48,16 @@ export namespace AuthMethods { emailVerified: new Date(), email, }, - select: UserConfig.filterSelection + select: userFilterSelection, }) } - }) + }), - export const verifyResetPasswordToken = serviceMethod({ + verifyResetPasswordToken: serviceMethod({ paramsSchema: z.object({ token: z.string() }), - authorizer: ({ params }) => AuthAuthers.resetPassword.dynamicFields(params), + authorizer: ({ params }) => authAuthers.resetPassword.dynamicFields(params), method: async ({ prisma, params }) => { // INFO: Safe to parse unsafe since the auther has verified the token. const payload = readJWTPayload(params.token) @@ -83,18 +83,18 @@ export namespace AuthMethods { return userId } - }) + }), - export const resetPassword = serviceMethod({ + resetPassword: serviceMethod({ paramsSchema: z.object({ token: z.string() }), - dataSchema: UserSchemas.updatePassword, - authorizer: ({ params }) => AuthAuthers.resetPassword.dynamicFields(params), + dataSchema: userSchemas.updatePassword, + authorizer: ({ params }) => authAuthers.resetPassword.dynamicFields(params), method: async ({ params, data }) => { - const userId = await verifyResetPasswordToken({ params }) + const userId = await authMethods.verifyResetPasswordToken({ params }) - UserMethods.updatePassword({ + userMethods.updatePassword({ params: { id: userId, }, @@ -102,15 +102,15 @@ export namespace AuthMethods { bypassAuth: true, }) } - }) + }), - export const sendResetPasswordEmail = serviceMethod({ - dataSchema: AuthSchemas.sendResetPasswordEmail, - authorizer: () => AuthAuthers.sendResetPasswordEmail.dynamicFields({}), + sendResetPasswordEmail: serviceMethod({ + dataSchema: authSchemas.sendResetPasswordEmail, + authorizer: () => authAuthers.sendResetPasswordEmail.dynamicFields({}), method: async ({ data }) => { console.log(data) try { - const user = await UserMethods.read({ + const user = await userMethods.read({ params: { email: data.email, }, @@ -125,5 +125,5 @@ export namespace AuthMethods { return data.email } - }) + }), } diff --git a/src/services/auth/schemas.ts b/src/services/auth/schemas.ts index 8e6117e90..d08a9449b 100644 --- a/src/services/auth/schemas.ts +++ b/src/services/auth/schemas.ts @@ -1,8 +1,7 @@ -import { UserSchemas } from '@/services/users/schemas' +import { userSchema } from '@/services/users/schemas' -export namespace AuthSchemas { - - export const sendResetPasswordEmail = UserSchemas.fields.pick({ +export const authSchemas = { + sendResetPasswordEmail: userSchema.pick({ email: true, }) } diff --git a/src/services/cabin/actions.ts b/src/services/cabin/actions.ts index e9ad95e0b..9e9829923 100644 --- a/src/services/cabin/actions.ts +++ b/src/services/cabin/actions.ts @@ -1,32 +1,32 @@ 'use server' +import { cabinReleasePeriodMethods } from './releasePeriod/methods' +import { cabinPricePeriodMethods } from './pricePeriod/methods' +import { cabinBookingMethods } from './booking/methods' +import { cabinProductMethods } from './product/methods' import { action } from '@/services/action' -import { CabinBookingMethods } from '@/services/cabin/booking/methods' -import { CabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' -import { CabinProductMethods } from '@/services/cabin/product/methods' -import { CabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' -export const createReleasePeriodAction = action(CabinReleasePeriodMethods.create) -export const readReleasePeriodsAction = action(CabinReleasePeriodMethods.readMany) -export const updateReleasePeriodAction = action(CabinReleasePeriodMethods.update) -export const destroyReleasePeriodAction = action(CabinReleasePeriodMethods.destroy) +export const createReleasePeriodAction = action(cabinReleasePeriodMethods.create) +export const readReleasePeriodsAction = action(cabinReleasePeriodMethods.readMany) +export const updateReleasePeriodAction = action(cabinReleasePeriodMethods.update) +export const destroyReleasePeriodAction = action(cabinReleasePeriodMethods.destroy) -export const createPricePeriodAction = action(CabinPricePeriodMethods.create) -export const destoryPricePeriodAction = action(CabinPricePeriodMethods.destroy) -export const readPricePeriodsAction = action(CabinPricePeriodMethods.readMany) -export const readPublicPricePeriodsAction = action(CabinPricePeriodMethods.readPublicPeriods) -export const readUnreleasedPricePeriodsAction = action(CabinPricePeriodMethods.readUnreleasedPeriods) +export const createPricePeriodAction = action(cabinPricePeriodMethods.create) +export const destoryPricePeriodAction = action(cabinPricePeriodMethods.destroy) +export const readPricePeriodsAction = action(cabinPricePeriodMethods.readMany) +export const readPublicPricePeriodsAction = action(cabinPricePeriodMethods.readPublicPeriods) +export const readUnreleasedPricePeriodsAction = action(cabinPricePeriodMethods.readUnreleasedPeriods) -export const createCabinBookingUserAttachedAction = action(CabinBookingMethods.createCabinBookingUserAttached) -export const createBedBookingUserAttachedAction = action(CabinBookingMethods.createBedBookingUserAttached) -export const createCabinBookingNoUserAction = action(CabinBookingMethods.createCabinBookingNoUser) -export const createBedBookingNoUserAction = action(CabinBookingMethods.createBedBookingNoUser) -export const readCabinAvailabilityAction = action(CabinBookingMethods.readAvailability) -export const readCabinBookingsAction = action(CabinBookingMethods.readMany) -export const readCabinBookingAction = action(CabinBookingMethods.read) +export const createCabinBookingUserAttachedAction = action(cabinBookingMethods.createCabinBookingUserAttached) +export const createBedBookingUserAttachedAction = action(cabinBookingMethods.createBedBookingUserAttached) +export const createCabinBookingNoUserAction = action(cabinBookingMethods.createCabinBookingNoUser) +export const createBedBookingNoUserAction = action(cabinBookingMethods.createBedBookingNoUser) +export const readCabinAvailabilityAction = action(cabinBookingMethods.readAvailability) +export const readCabinBookingsAction = action(cabinBookingMethods.readMany) +export const readCabinBookingAction = action(cabinBookingMethods.read) -export const readCabinProductsAction = action(CabinProductMethods.readMany) -export const readCabinProductsActiveAction = action(CabinProductMethods.readActive) -export const readCabinProductAction = action(CabinProductMethods.read) -export const createCabinProductAction = action(CabinProductMethods.create) -export const createCabinProductPriceAction = action(CabinProductMethods.createPrice) +export const readCabinProductsAction = action(cabinProductMethods.readMany) +export const readCabinProductsActiveAction = action(cabinProductMethods.readActive) +export const readCabinProductAction = action(cabinProductMethods.read) +export const createCabinProductAction = action(cabinProductMethods.create) +export const createCabinProductPriceAction = action(cabinProductMethods.createPrice) diff --git a/src/services/cabin/booking/Types.ts b/src/services/cabin/booking/Types.ts index e7233fd0f..f391c3604 100644 --- a/src/services/cabin/booking/Types.ts +++ b/src/services/cabin/booking/Types.ts @@ -1,4 +1,4 @@ -import type { CabinBookingConfig } from './config' +import type { cabinBookingFieldsToExpose } from './config' import type { Booking } from '@prisma/client' -export type BookingFiltered = Pick +export type BookingFiltered = Pick diff --git a/src/services/cabin/booking/authers.ts b/src/services/cabin/booking/authers.ts index f1ee0a218..7d6184366 100644 --- a/src/services/cabin/booking/authers.ts +++ b/src/services/cabin/booking/authers.ts @@ -1,33 +1,33 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import { RequirePermissionAndUserId } from '@/auth/auther/RequirePermissionAndUserId' -export namespace CabinBookingAuthers { - export const createCabinBookingUserAttached = RequirePermissionAndUserId.staticFields({ +export const cabinBookingAuthers = { + createCabinBookingUserAttached: RequirePermissionAndUserId.staticFields({ permission: 'CABIN_BOOKING_CABIN_CREATE' - }) + }), - export const createCabinBookingNoUser = RequirePermission.staticFields({ + createCabinBookingNoUser: RequirePermission.staticFields({ permission: 'CABIN_BOOKING_CABIN_CREATE' - }) + }), - export const createBedBookingUserAttached = RequirePermissionAndUserId.staticFields({ + createBedBookingUserAttached: RequirePermissionAndUserId.staticFields({ permission: 'CABIN_BOOKING_BED_CREATE' - }) + }), - export const createBedBookingNoUser = RequirePermission.staticFields({ + createBedBookingNoUser: RequirePermission.staticFields({ permission: 'CABIN_BOOKING_BED_CREATE' - }) + }), - export const readAvailability = RequirePermission.staticFields({ + readAvailability: RequirePermission.staticFields({ permission: 'CABIN_CALENDAR_READ' - }) + }), - export const readMany = RequirePermission.staticFields({ + readMany: RequirePermission.staticFields({ permission: 'CABIN_BOOKING_ADMIN' - }) + }), - export const read = RequirePermission.staticFields({ + read: RequirePermission.staticFields({ permission: 'CABIN_BOOKING_ADMIN' - }) + }), } diff --git a/src/services/cabin/booking/cabinPriceCalculator.ts b/src/services/cabin/booking/cabinPriceCalculator.ts index 02abda2f2..8928cea3e 100644 --- a/src/services/cabin/booking/cabinPriceCalculator.ts +++ b/src/services/cabin/booking/cabinPriceCalculator.ts @@ -1,5 +1,5 @@ import { dateMatchCron } from '@/lib/dates/cron' -import type { CabinProductConfig } from '@/services/cabin/product/config' +import type { CabinProductExtended, CabinProductPriceExtended } from '@/services/cabin/product/config' import type { CabinProduct, CabinProductPrice, PricePeriod } from '@prisma/client' function getDateArray(start: Date, end: Date) { @@ -25,7 +25,7 @@ function matchPriceForDay({ day: Date, memberShare: number, pricePeriods: PricePeriod[], - prices: CabinProductConfig.CabinProductPriceExtended[] + prices: CabinProductPriceExtended[] }) { const currentPricePeriod = pricePeriods.findLast(period => period.validFrom <= day) if (!currentPricePeriod) { @@ -76,7 +76,7 @@ function findPricesForProduct({ numberOfMembers: number, numberOfNonMembers: number, pricePeriods: PricePeriod[], - product: CabinProductConfig.CabinProductExtended + product: CabinProductExtended }): CabinPriceCalculatorReturnType[] { const dateArray = getDateArray(startDate, endDate) let memberShare = Math.ceil(numberOfMembers / (numberOfMembers + numberOfNonMembers) * 100) @@ -117,7 +117,7 @@ export function calculateCabinBookingPrice({ numberOfNonMembers, }: { pricePeriods: PricePeriod[], - products: CabinProductConfig.CabinProductExtended[], + products: CabinProductExtended[], productAmounts: number[], startDate: Date, endDate: Date, diff --git a/src/services/cabin/booking/config.ts b/src/services/cabin/booking/config.ts index 61c255f5a..d492f4b1e 100644 --- a/src/services/cabin/booking/config.ts +++ b/src/services/cabin/booking/config.ts @@ -1,25 +1,21 @@ import { createSelection } from '@/services/createSelection' -import { UserConfig } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/config' import type { Booking } from '@prisma/client' -export namespace CabinBookingConfig { +export const cabinBookingFieldsToExpose = ['start', 'end', 'type'] as const satisfies (keyof Booking)[] - export const bookingFieldsToExpose = ['start', 'end', 'type'] as const satisfies (keyof Booking)[] - - export const bookingFilerSelection = createSelection(bookingFieldsToExpose) - - export const bookingIncluder = { - user: { - select: UserConfig.filterSelection, - }, - BookingProduct: { - include: { - product: true, - } - }, - event: true, - guestUser: true, - } +export const cabinBookingFilerSelection = createSelection(cabinBookingFieldsToExpose) +export const cabinBookingIncluder = { + user: { + select: userFilterSelection, + }, + BookingProduct: { + include: { + product: true, + } + }, + event: true, + guestUser: true, } diff --git a/src/services/cabin/booking/methods.ts b/src/services/cabin/booking/methods.ts index b2b983d8c..244870f4b 100644 --- a/src/services/cabin/booking/methods.ts +++ b/src/services/cabin/booking/methods.ts @@ -1,18 +1,19 @@ -import { CabinBookingAuthers } from './authers' -import { CabinBookingConfig } from './config' -import { CabinBookingSchemas } from './schemas' +import 'server-only' import { calculateCabinBookingPrice, calculateTotalCabinBookingPrice } from './cabinPriceCalculator' -import { CabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' -import { CabinProductConfig } from '@/services/cabin/product/config' +import { cabinBookingSchemas } from './schemas' +import { cabinBookingAuthers } from './authers' +import { cabinBookingFilerSelection, cabinBookingIncluder } from './config' +import { cabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' +import { cabinProductPriceIncluder } from '@/services/cabin/product/config' import { serviceMethod } from '@/services/serviceMethod' -import 'server-only' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { ServerError } from '@/services/error' -import { CabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' +import { cabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' import { sendSystemMail } from '@/services/notifications/email/send' -import { NotificationMethods } from '@/services/notifications/methods' +import { notificationMethods } from '@/services/notifications/methods' import { z } from 'zod' import { BookingType } from '@prisma/client' +import type { CabinProductExtended } from '@/services/cabin/product/config' const mailData = { title: 'Bekreftelse på hyttebooking', @@ -20,193 +21,234 @@ const mailData = { Dette skal være en bookingbekreftelse, så det bør nok komme noe nyttig info her snart.`, } -export namespace CabinBookingMethods { +const cabinAvailable = serviceMethod({ + paramsSchema: z.object({ + start: z.date(), + end: z.date() + }), + authorizer: ServerOnlyAuther, + method: async ({ prisma, params }) => { + const results = await prisma.booking.findMany({ + where: { + start: { + lt: params.end, + }, + end: { + gt: params.start, + }, + } + }) + return results.length === 0 + } +}) + +const bookingProductParams = z.array(z.object({ + cabinProductId: z.number(), + quantity: z.number().int().min(1), +})) + + +const create = serviceMethod({ + paramsSchema: z.object({ + bookingType: z.nativeEnum(BookingType), + bookingProducts: bookingProductParams, + }), + authorizer: ServerOnlyAuther, + dataSchema: cabinBookingSchemas.createBookingUserAttached, + method: async ({ prisma, params, data }) => { + // TODO: Prevent Race conditions + + const latestReleaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ + bypassAuth: true, + }) - const cabinAvailable = serviceMethod({ - paramsSchema: z.object({ - start: z.date(), - end: z.date() - }), - authorizer: ServerOnlyAuther, - method: async ({ prisma, params }) => { - const results = await prisma.booking.findMany({ - where: { - start: { - lt: params.end, - }, - end: { - gt: params.start, - }, - } - }) - return results.length === 0 + if (latestReleaseDate === null) { + throw new ServerError('SERVER ERROR', 'Hyttebooking siden er ikke tilgjengelig.') } - }) - - const bookingProductParams = z.array(z.object({ - cabinProductId: z.number(), - quantity: z.number().int().min(1), - })) + if (data.end > latestReleaseDate.releaseUntil) { + throw new ServerError('BAD PARAMETERS', 'Hytta kan ikke bookes etter siste slippdato.') + } - const create = serviceMethod({ - paramsSchema: z.object({ - bookingType: z.nativeEnum(BookingType), - bookingProducts: bookingProductParams, - }), - authorizer: ServerOnlyAuther, - dataSchema: CabinBookingSchemas.createBookingUserAttached, - method: async ({ prisma, params, data }) => { - // TODO: Prevent Race conditions + if (!await cabinAvailable({ + params: data, + bypassAuth: true, + })) { + throw new ServerError('BAD PARAMETERS', 'Hytta er ikke tilgjengelig i den perioden.') + } - const latestReleaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ - bypassAuth: true, - }) + const products = await prisma.cabinProduct.findMany({ + where: { + id: { + in: params.bookingProducts.map(product => product.cabinProductId), + } + }, + include: cabinProductPriceIncluder, + }) + if (products.length !== params.bookingProducts.length) { + throw new ServerError('BAD PARAMETERS', 'Kunne ikke finne alle hytta produktene. Duplikater er ikke tillat.') + } - if (latestReleaseDate === null) { - throw new ServerError('SERVER ERROR', 'Hyttebooking siden er ikke tilgjengelig.') - } + const productsInOrder: CabinProductExtended[] = [] - if (data.end > latestReleaseDate.releaseUntil) { - throw new ServerError('BAD PARAMETERS', 'Hytta kan ikke bookes etter siste slippdato.') + for (const paramProduct of params.bookingProducts) { + const product = products.find(prodItem => prodItem.id === paramProduct.cabinProductId) + if (!product) { + throw new ServerError('UNKNOWN ERROR', 'Kunne ikke finne mengden av produktet.') } + productsInOrder.push(product) - if (!await cabinAvailable({ - params: data, - bypassAuth: true, - })) { - throw new ServerError('BAD PARAMETERS', 'Hytta er ikke tilgjengelig i den perioden.') + if (product.type !== params.bookingType) { + throw new ServerError('BAD PARAMETERS', 'Alle produktene må ha samme type som bookingen.') } - const products = await prisma.cabinProduct.findMany({ - where: { - id: { - in: params.bookingProducts.map(product => product.cabinProductId), - } - }, - include: CabinProductConfig.includer - }) - if (products.length !== params.bookingProducts.length) { - throw new ServerError('BAD PARAMETERS', 'Kunne ikke finne alle hytta produktene. Duplikater er ikke tillat.') + if (product.amount < paramProduct.quantity) { + throw new ServerError('BAD PARAMETERS', 'Det er ikke nok av produktet til å oppfylle bookingen.') } + } - const productsInOrder: CabinProductConfig.CabinProductExtended[] = [] - - for (const paramProduct of params.bookingProducts) { - const product = products.find(prodItem => prodItem.id === paramProduct.cabinProductId) - if (!product) { - throw new ServerError('UNKNOWN ERROR', 'Kunne ikke finne mengden av produktet.') - } - productsInOrder.push(product) - - if (product.type !== params.bookingType) { - throw new ServerError('BAD PARAMETERS', 'Alle produktene må ha samme type som bookingen.') - } + if (params.bookingType === 'EVENT' && params.bookingProducts.length !== 0) { + throw new ServerError('BAD PARAMETERS', 'Hvad der hender bookinger kan ikke inneholde produkter.') + } - if (product.amount < paramProduct.quantity) { - throw new ServerError('BAD PARAMETERS', 'Det er ikke nok av produktet til å oppfylle bookingen.') - } - } + if (params.bookingType === 'CABIN' && + params.bookingProducts.length !== 1 && + params.bookingProducts[0].quantity !== 1 + ) { + throw new ServerError('BAD PARAMETERS', 'Hyttebookinger kan bare inneholde ett produkt med mengde 1.') + } - if (params.bookingType === 'EVENT' && params.bookingProducts.length !== 0) { - throw new ServerError('BAD PARAMETERS', 'Hvad der hender bookinger kan ikke inneholde produkter.') - } + if (params.bookingType === 'BED' && params.bookingProducts.length === 0) { + throw new ServerError('BAD PARAMETERS', 'Sengebookinger må inneholde minst ett produkt.') + } - if (params.bookingType === 'CABIN' && - params.bookingProducts.length !== 1 && - params.bookingProducts[0].quantity !== 1 - ) { - throw new ServerError('BAD PARAMETERS', 'Hyttebookinger kan bare inneholde ett produkt med mengde 1.') - } + const pricePeriods = await cabinPricePeriodMethods.readMany({ bypassAuth: true }) - if (params.bookingType === 'BED' && params.bookingProducts.length === 0) { - throw new ServerError('BAD PARAMETERS', 'Sengebookinger må inneholde minst ett produkt.') - } + const priceObjects = calculateCabinBookingPrice({ + pricePeriods, + products: productsInOrder, + productAmounts: params.bookingProducts.map(prod => prod.quantity), + startDate: data.start, + endDate: data.end, + numberOfMembers: data.numberOfMembers, + numberOfNonMembers: data.numberOfNonMembers + }) - const pricePeriods = await CabinPricePeriodMethods.readMany({ bypassAuth: true }) + const totalPrice = calculateTotalCabinBookingPrice(priceObjects) + console.log('TOTAL PRICE FOR THE BOOKING:', totalPrice) - const priceObjects = calculateCabinBookingPrice({ - pricePeriods, - products: productsInOrder, - productAmounts: params.bookingProducts.map(prod => prod.quantity), - startDate: data.start, - endDate: data.end, + return await prisma.booking.create({ + data: { + type: params.bookingType, + start: data.start, + end: data.end, + tenantNotes: data.tenantNotes, numberOfMembers: data.numberOfMembers, - numberOfNonMembers: data.numberOfNonMembers - }) + numberOfNonMembers: data.numberOfNonMembers, + BookingProduct: { + create: params.bookingProducts.map(product => ({ + cabinProductId: product.cabinProductId, + quantity: product.quantity, + })) + } + } + }) + } +}) + +const createBookingWithUser = serviceMethod({ + paramsSchema: z.object({ + userId: z.number(), + bookingType: z.nativeEnum(BookingType), + bookingProducts: bookingProductParams, + }), + authorizer: ServerOnlyAuther, + dataSchema: cabinBookingSchemas.createBookingUserAttached, + method: async ({ prisma, params, data }) => { + const result = await create({ + params, + data, + bypassAuth: true, + }) - const totalPrice = calculateTotalCabinBookingPrice(priceObjects) - console.log('TOTAL PRICE FOR THE BOOKING:', totalPrice) - - return await prisma.booking.create({ - data: { - type: params.bookingType, - start: data.start, - end: data.end, - tenantNotes: data.tenantNotes, - numberOfMembers: data.numberOfMembers, - numberOfNonMembers: data.numberOfNonMembers, - BookingProduct: { - create: params.bookingProducts.map(product => ({ - cabinProductId: product.cabinProductId, - quantity: product.quantity, - })) + await prisma.booking.update({ + where: { + id: result.id, + }, + data: { + user: { + connect: { + id: params.userId, } } - }) - } - }) + } + }) - const createBookingWithUser = serviceMethod({ - paramsSchema: z.object({ - userId: z.number(), - bookingType: z.nativeEnum(BookingType), - bookingProducts: bookingProductParams, - }), - authorizer: ServerOnlyAuther, - dataSchema: CabinBookingSchemas.createBookingUserAttached, - method: async ({ prisma, params, data }) => { - const result = await create({ - params, - data, - bypassAuth: true, - }) + await notificationMethods.createSpecial({ + params: { + special: 'CABIN_BOOKING_CONFIRMATION', + }, + data: { + ...mailData, + userIdList: [params.userId], + }, + bypassAuth: true, + }) + } +}) + +const createBookingNoUser = serviceMethod({ + paramsSchema: z.object({ + bookingType: z.nativeEnum(BookingType), + bookingProducts: bookingProductParams, + }), + authorizer: ServerOnlyAuther, + dataSchema: cabinBookingSchemas.createBookingNoUser, + method: async ({ prisma, params, data }) => { + const result = await create({ + params, + data: { + ...data, + numberOfMembers: 0, + numberOfNonMembers: 0, + }, + bypassAuth: true, + }) - await prisma.booking.update({ - where: { - id: result.id, - }, - data: { - user: { - connect: { - id: params.userId, - } + await prisma.booking.update({ + where: { + id: result.id, + }, + data: { + guestUser: { + create: { + firstname: data.firstname, + lastname: data.lastname, + email: data.email, + mobile: data.mobile, } } - }) + } + }) - await NotificationMethods.createSpecial({ - params: { - special: 'CABIN_BOOKING_CONFIRMATION', - }, - data: { - ...mailData, - userIdList: [params.userId], - }, - bypassAuth: true, - }) - } - }) + await sendSystemMail( + data.email, + mailData.title, + mailData.message + ) + } +}) - export const createCabinBookingUserAttached = serviceMethod({ +export const cabinBookingMethods = { + createCabinBookingUserAttached: serviceMethod({ paramsSchema: z.object({ userId: z.number(), bookingProducts: bookingProductParams, }), - authorizer: ({ params }) => CabinBookingAuthers.createCabinBookingUserAttached.dynamicFields({ + authorizer: ({ params }) => cabinBookingAuthers.createCabinBookingUserAttached.dynamicFields({ userId: params.userId, }), - dataSchema: CabinBookingSchemas.createBookingUserAttached, + dataSchema: cabinBookingSchemas.createBookingUserAttached, method: async ({ params, data }) => createBookingWithUser({ params: { @@ -217,17 +259,17 @@ export namespace CabinBookingMethods { data, bypassAuth: true, }) - }) + }), - export const createBedBookingUserAttached = serviceMethod({ + createBedBookingUserAttached: serviceMethod({ paramsSchema: z.object({ userId: z.number(), bookingProducts: bookingProductParams, }), - authorizer: ({ params }) => CabinBookingAuthers.createBedBookingUserAttached.dynamicFields({ + authorizer: ({ params }) => cabinBookingAuthers.createBedBookingUserAttached.dynamicFields({ userId: params.userId, }), - dataSchema: CabinBookingSchemas.createBookingUserAttached, + dataSchema: cabinBookingSchemas.createBookingUserAttached, method: async ({ params, data }) => createBookingWithUser({ params: { @@ -238,56 +280,14 @@ export namespace CabinBookingMethods { data, bypassAuth: true, }) - }) + }), - const createBookingNoUser = serviceMethod({ + createCabinBookingNoUser: serviceMethod({ paramsSchema: z.object({ - bookingType: z.nativeEnum(BookingType), bookingProducts: bookingProductParams, }), - authorizer: ServerOnlyAuther, - dataSchema: CabinBookingSchemas.createBookingNoUser, - method: async ({ prisma, params, data }) => { - const result = await create({ - params, - data: { - ...data, - numberOfMembers: 0, - numberOfNonMembers: 0, - }, - bypassAuth: true, - }) - - await prisma.booking.update({ - where: { - id: result.id, - }, - data: { - guestUser: { - create: { - firstname: data.firstname, - lastname: data.lastname, - email: data.email, - mobile: data.mobile, - } - } - } - }) - - await sendSystemMail( - data.email, - mailData.title, - mailData.message - ) - } - }) - - export const createCabinBookingNoUser = serviceMethod({ - paramsSchema: z.object({ - bookingProducts: bookingProductParams, - }), - authorizer: () => CabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}), - dataSchema: CabinBookingSchemas.createBookingNoUser, + authorizer: () => cabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}), + dataSchema: cabinBookingSchemas.createBookingNoUser, method: async ({ params, data }) => createBookingNoUser({ params: { bookingType: BookingType.CABIN, @@ -296,14 +296,14 @@ export namespace CabinBookingMethods { data, bypassAuth: true, }) - }) + }), - export const createBedBookingNoUser = serviceMethod({ + createBedBookingNoUser: serviceMethod({ paramsSchema: z.object({ bookingProducts: bookingProductParams, }), - authorizer: () => CabinBookingAuthers.createBedBookingNoUser.dynamicFields({}), - dataSchema: CabinBookingSchemas.createBookingNoUser, + authorizer: () => cabinBookingAuthers.createBedBookingNoUser.dynamicFields({}), + dataSchema: cabinBookingSchemas.createBookingNoUser, method: async ({ params, data }) => createBookingNoUser({ params: { bookingType: BookingType.BED, @@ -312,13 +312,13 @@ export namespace CabinBookingMethods { data, bypassAuth: true, }) - }) + }), - export const readAvailability = serviceMethod({ - authorizer: () => CabinBookingAuthers.readAvailability.dynamicFields({}), + readAvailability: serviceMethod({ + authorizer: () => cabinBookingAuthers.readAvailability.dynamicFields({}), method: async ({ prisma }) => { const results = await prisma.booking.findMany({ - select: CabinBookingConfig.bookingFilerSelection, + select: cabinBookingFilerSelection, orderBy: { start: 'asc' }, @@ -340,28 +340,26 @@ export namespace CabinBookingMethods { return results } - }) + }), - export const readMany = serviceMethod({ - authorizer: () => CabinBookingAuthers.readMany.dynamicFields({}), + readMany: serviceMethod({ + authorizer: () => cabinBookingAuthers.readMany.dynamicFields({}), method: ({ prisma }) => prisma.booking.findMany({ orderBy: { start: 'asc', }, - include: CabinBookingConfig.bookingIncluder, + include: cabinBookingIncluder, }), // TODO: Pager - }) + }), - export const read = serviceMethod({ - authorizer: () => CabinBookingAuthers.read.dynamicFields({}), + read: serviceMethod({ + authorizer: () => cabinBookingAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), method: ({ prisma, params }) => prisma.booking.findUniqueOrThrow({ where: params, - include: CabinBookingConfig.bookingIncluder, + include: cabinBookingIncluder, }) }) - - } diff --git a/src/services/cabin/booking/schemas.ts b/src/services/cabin/booking/schemas.ts index 745b71370..c6c728ed3 100644 --- a/src/services/cabin/booking/schemas.ts +++ b/src/services/cabin/booking/schemas.ts @@ -2,40 +2,39 @@ import { dateLessThan, dateLessThanOrEqualTo } from '@/lib/dates/comparison' import { zpn } from '@/lib/fields/zpn' import { z } from 'zod' - -export namespace CabinBookingSchemas { - const fields = z.object({ - start: z.coerce.date(), - end: z.coerce.date(), - tenantNotes: z.string().optional(), - numberOfMembers: z.coerce.number().min(0), - numberOfNonMembers: z.coerce.number().min(0), - firstname: z.string().min(2), - lastname: z.string().min(2), - email: z.string().email(), - mobile: z.string().regex(/^\+?\d{4,20}$/, { message: 'Skriv kun tall, uten mellomrom.' }), - acceptedTerms: zpn.checkboxOrBoolean({ - label: '', - message: 'Du må godta vilkårene for å bruk siden.' - }) +const baseSchema = z.object({ + start: z.coerce.date(), + end: z.coerce.date(), + tenantNotes: z.string().optional(), + numberOfMembers: z.coerce.number().min(0), + numberOfNonMembers: z.coerce.number().min(0), + firstname: z.string().min(2), + lastname: z.string().min(2), + email: z.string().email(), + mobile: z.string().regex(/^\+?\d{4,20}$/, { message: 'Skriv kun tall, uten mellomrom.' }), + acceptedTerms: zpn.checkboxOrBoolean({ + label: '', + message: 'Du må godta vilkårene for å bruk siden.' }) +}) - const startEndDateRefiner = { - fcn: (data: { start: Date, end: Date }) => - dateLessThan(data.start, data.end) && dateLessThanOrEqualTo(new Date(), data.start), - message: 'Start dato må være før sluttdato. Start daten må være i ramtiden' - } +const startEndDateRefiner = { + fcn: (data: { start: Date, end: Date }) => + dateLessThan(data.start, data.end) && dateLessThanOrEqualTo(new Date(), data.start), + message: 'Start dato må være før sluttdato. Start daten må være i ramtiden' +} - export const createBookingUserAttached = fields.pick({ +export const cabinBookingSchemas = { + createBookingUserAttached: baseSchema.pick({ start: true, end: true, tenantNotes: true, acceptedTerms: true, numberOfMembers: true, numberOfNonMembers: true, - }).refine(startEndDateRefiner.fcn, startEndDateRefiner.message) + }).refine(startEndDateRefiner.fcn, startEndDateRefiner.message), - export const createBookingNoUser = fields.pick({ + createBookingNoUser: baseSchema.pick({ start: true, end: true, tenantNotes: true, @@ -44,6 +43,6 @@ export namespace CabinBookingSchemas { lastname: true, email: true, mobile: true, - }).refine(startEndDateRefiner.fcn, startEndDateRefiner.message) + }).refine(startEndDateRefiner.fcn, startEndDateRefiner.message), } diff --git a/src/services/cabin/pricePeriod/authers.ts b/src/services/cabin/pricePeriod/authers.ts index 73ac134da..1a13e37e4 100644 --- a/src/services/cabin/pricePeriod/authers.ts +++ b/src/services/cabin/pricePeriod/authers.ts @@ -1,10 +1,11 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace CabinPricePeriodAuthers { - export const create = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) - export const read = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) - export const readPublicPeriods = RequirePermission.staticFields({ permission: 'CABIN_CALENDAR_READ' }) - export const update = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) - export const destroy = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) -} +const baseAuther = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) +export const cabinPricePeriodAuthers = { + create: baseAuther, + read: baseAuther, + readPublicPeriods: RequirePermission.staticFields({ permission: 'CABIN_CALENDAR_READ' }), + update: baseAuther, + destroy: baseAuther, +} diff --git a/src/services/cabin/pricePeriod/methods.ts b/src/services/cabin/pricePeriod/methods.ts index 6629062dd..9e400cede 100644 --- a/src/services/cabin/pricePeriod/methods.ts +++ b/src/services/cabin/pricePeriod/methods.ts @@ -1,18 +1,17 @@ -import { CabinPricePeriodAuthers } from './authers' -import { CabinPricePeriodSchemas } from './schemas' -import { serviceMethod } from '@/services/serviceMethod' import 'server-only' -import { CabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' +import { cabinPricePeriodAuthers } from './authers' +import { cabinPricePeriodSchemas } from './schemas' +import { serviceMethod } from '@/services/serviceMethod' +import { cabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' import { ServerError } from '@/services/error' import { z } from 'zod' -export namespace CabinPricePeriodMethods { - - export const create = serviceMethod({ - authorizer: () => CabinPricePeriodAuthers.create.dynamicFields({}), - dataSchema: CabinPricePeriodSchemas.createPricePeriod, +export const cabinPricePeriodMethods = { + create: serviceMethod({ + authorizer: () => cabinPricePeriodAuthers.create.dynamicFields({}), + dataSchema: cabinPricePeriodSchemas.createPricePeriod, method: async ({ prisma, data }) => { - const currentReleaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) + const currentReleaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) if (currentReleaseDate && currentReleaseDate.releaseUntil >= data.validFrom) { throw new ServerError( @@ -57,15 +56,15 @@ export namespace CabinPricePeriodMethods { return result } - }) + }), - export const destroy = serviceMethod({ - authorizer: () => CabinPricePeriodAuthers.destroy.dynamicFields({}), + destroy: serviceMethod({ + authorizer: () => cabinPricePeriodAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), method: async ({ prisma, params }) => { - const currentReleasePeriod = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) + const currentReleasePeriod = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) const pricePeriod = await prisma.pricePeriod.findUniqueOrThrow({ where: params, @@ -79,17 +78,17 @@ export namespace CabinPricePeriodMethods { where: params, }) } - }) + }), - export const readMany = serviceMethod({ - authorizer: () => CabinPricePeriodAuthers.read.dynamicFields({}), + readMany: serviceMethod({ + authorizer: () => cabinPricePeriodAuthers.read.dynamicFields({}), method: async ({ prisma }) => prisma.pricePeriod.findMany() - }) + }), - export const readPublicPeriods = serviceMethod({ - authorizer: () => CabinPricePeriodAuthers.readPublicPeriods.dynamicFields({}), + readPublicPeriods: serviceMethod({ + authorizer: () => cabinPricePeriodAuthers.readPublicPeriods.dynamicFields({}), method: async ({ prisma }) => { - const releaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) + const releaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) const [currentPeriod, futurePeriods] = await Promise.all([ prisma.pricePeriod.findFirstOrThrow({ @@ -117,12 +116,12 @@ export namespace CabinPricePeriodMethods { return [currentPeriod, ...futurePeriods] } - }) + }), - export const readUnreleasedPeriods = serviceMethod({ - authorizer: () => CabinPricePeriodAuthers.read.dynamicFields({}), + readUnreleasedPeriods: serviceMethod({ + authorizer: () => cabinPricePeriodAuthers.read.dynamicFields({}), method: async ({ prisma }) => { - const releaseDate = await CabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) + const releaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) return prisma.pricePeriod.findMany({ where: { validFrom: { @@ -131,11 +130,11 @@ export namespace CabinPricePeriodMethods { } }) } - }) + }), - export const update = serviceMethod({ - authorizer: () => CabinPricePeriodAuthers.update.dynamicFields({}), - dataSchema: CabinPricePeriodSchemas.updatePricePeriod, + update: serviceMethod({ + authorizer: () => cabinPricePeriodAuthers.update.dynamicFields({}), + dataSchema: cabinPricePeriodSchemas.updatePricePeriod, paramsSchema: z.object({ pricePeriodId: z.number(), }), @@ -145,5 +144,5 @@ export namespace CabinPricePeriodMethods { }, data, }) - }) + }), } diff --git a/src/services/cabin/pricePeriod/schemas.ts b/src/services/cabin/pricePeriod/schemas.ts index 0c0573aa2..2034ba84b 100644 --- a/src/services/cabin/pricePeriod/schemas.ts +++ b/src/services/cabin/pricePeriod/schemas.ts @@ -1,21 +1,19 @@ import { zpn } from '@/lib/fields/zpn' import { z } from 'zod' -export namespace CabinPricePeriodSchemas { - const fields = z.object({ - id: z.coerce.number(), - validFrom: z.coerce.date(), - copyPreviousPrices: zpn.checkboxOrBoolean({ label: '' }), - }) +const baseSchema = z.object({ + id: z.coerce.number(), + validFrom: z.coerce.date(), + copyPreviousPrices: zpn.checkboxOrBoolean({ label: '' }), +}) - export const createPricePeriod = fields.pick({ +export const cabinPricePeriodSchemas = { + createPricePeriod: baseSchema.pick({ validFrom: true, copyPreviousPrices: true, - }) - - export const updatePricePeriod = fields.pick({ + }), + updatePricePeriod: baseSchema.pick({ id: true, validFrom: true, - }) + }), } - diff --git a/src/services/cabin/product/authers.ts b/src/services/cabin/product/authers.ts index 3210fe4ad..eb9f6594a 100644 --- a/src/services/cabin/product/authers.ts +++ b/src/services/cabin/product/authers.ts @@ -1,16 +1,16 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace CabinProductAuthers { - export const read = RequirePermission.staticFields({ +export const cabinProductAuthers = { + read: RequirePermission.staticFields({ permission: 'CABIN_CALENDAR_READ' - }) + }), - export const create = RequirePermission.staticFields({ + create: RequirePermission.staticFields({ permission: 'CABIN_PRODUCTS_ADMIN' - }) + }), - export const createPrice = RequirePermission.staticFields({ + createPrice: RequirePermission.staticFields({ permission: 'CABIN_PRODUCTS_ADMIN' - }) + }), } diff --git a/src/services/cabin/product/config.ts b/src/services/cabin/product/config.ts index ead2ef5d3..9a5271bd8 100644 --- a/src/services/cabin/product/config.ts +++ b/src/services/cabin/product/config.ts @@ -1,21 +1,17 @@ import type { Prisma } from '@prisma/client' - -export namespace CabinProductConfig { - - export const includer = { - CabinProductPrice: { - include: { - PricePeriod: true - } +export const cabinProductPriceIncluder = { + CabinProductPrice: { + include: { + PricePeriod: true } - } as const + } +} as const - export type CabinProductExtended = Prisma.CabinProductGetPayload<{ - include: typeof includer - }> +export type CabinProductExtended = Prisma.CabinProductGetPayload<{ + include: typeof cabinProductPriceIncluder +}> - export type CabinProductPriceExtended = Prisma.CabinProductPriceGetPayload<{ - include: typeof includer.CabinProductPrice.include - }> -} +export type CabinProductPriceExtended = Prisma.CabinProductPriceGetPayload<{ + include: typeof cabinProductPriceIncluder.CabinProductPrice.include +}> diff --git a/src/services/cabin/product/methods.ts b/src/services/cabin/product/methods.ts index aeee102af..a102ff69f 100644 --- a/src/services/cabin/product/methods.ts +++ b/src/services/cabin/product/methods.ts @@ -1,29 +1,30 @@ -import { CabinProductAuthers } from './authers' -import { CabinProductSchemas } from './schemas' -import { CabinProductConfig } from './config' -import { serviceMethod } from '@/services/serviceMethod' import 'server-only' + +import { cabinProductAuthers } from './authers' +import { cabinProductSchemas } from './schemas' +import { cabinProductPriceIncluder } from './config' +import { cabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' +import { serviceMethod } from '@/services/serviceMethod' import { ServerError } from '@/services/error' -import { CabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' -import { CabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' +import { cabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' import { z } from 'zod' -export namespace CabinProductMethods { +export const cabinProductMethods = { - export const create = serviceMethod({ - authorizer: () => CabinProductAuthers.create.dynamicFields({}), - dataSchema: CabinProductSchemas.createProduct, + create: serviceMethod({ + authorizer: () => cabinProductAuthers.create.dynamicFields({}), + dataSchema: cabinProductSchemas.createProduct, method: ({ prisma, data }) => prisma.cabinProduct.create({ data, }) - }) + }), - export const createPrice = serviceMethod({ - authorizer: () => CabinProductAuthers.createPrice.dynamicFields({}), + createPrice: serviceMethod({ + authorizer: () => cabinProductAuthers.createPrice.dynamicFields({}), paramsSchema: z.object({ cabinProductId: z.number(), }), - dataSchema: CabinProductSchemas.createProductPrice, + dataSchema: cabinProductSchemas.createProductPrice, method: async ({ prisma, params, data, session }) => { const [pricePeriod, releasePeriod] = await Promise.all([ prisma.pricePeriod.findUniqueOrThrow({ @@ -31,7 +32,7 @@ export namespace CabinProductMethods { id: data.pricePeriodId, } }), - CabinReleasePeriodMethods.getCurrentReleasePeriod({ + cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true, session }) @@ -50,19 +51,19 @@ export namespace CabinProductMethods { return result } - }) + }), - export const readMany = serviceMethod({ - authorizer: () => CabinProductAuthers.read.dynamicFields({}), + readMany: serviceMethod({ + authorizer: () => cabinProductAuthers.read.dynamicFields({}), method: ({ prisma }) => prisma.cabinProduct.findMany({ - include: CabinProductConfig.includer, + include: cabinProductPriceIncluder, }), - }) + }), - export const readActive = serviceMethod({ - authorizer: () => CabinProductAuthers.read.dynamicFields({}), + readActive: serviceMethod({ + authorizer: () => cabinProductAuthers.read.dynamicFields({}), method: async ({ prisma }) => { - const pricePeriods = await CabinPricePeriodMethods.readPublicPeriods({ bypassAuth: true }) + const pricePeriods = await cabinPricePeriodMethods.readPublicPeriods({ bypassAuth: true }) return await prisma.cabinProduct.findMany({ where: { @@ -74,19 +75,19 @@ export namespace CabinProductMethods { } } }, - include: CabinProductConfig.includer, + include: cabinProductPriceIncluder, }) }, - }) + }), - export const read = serviceMethod({ - authorizer: () => CabinProductAuthers.read.dynamicFields({}), + read: serviceMethod({ + authorizer: () => cabinProductAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), method: ({ prisma, params }) => prisma.cabinProduct.findUniqueOrThrow({ where: params, - include: CabinProductConfig.includer + include: cabinProductPriceIncluder, }) - }) + }), } diff --git a/src/services/cabin/product/schemas.ts b/src/services/cabin/product/schemas.ts index d9884a00f..c2904e5b5 100644 --- a/src/services/cabin/product/schemas.ts +++ b/src/services/cabin/product/schemas.ts @@ -3,32 +3,30 @@ import { convertPrice } from '@/lib/money/convert' import { BookingType } from '@prisma/client' import { z } from 'zod' +const baseSchema = z.object({ + type: z.nativeEnum(BookingType), + amount: z.coerce.number().int().min(0), + name: z.string().min(2), + description: z.string().min(0).max(20), + price: z.coerce.number().min(0).transform((val) => convertPrice(val)), + validFrom: z.coerce.date(), + cronInterval: zpn.simpleCronExpression(), + memberShare: z.coerce.number().min(0).max(100), + pricePeriodId: z.coerce.number(), +}) -export namespace CabinProductSchemas { - const fields = z.object({ - type: z.nativeEnum(BookingType), - amount: z.coerce.number().int().min(0), - name: z.string().min(2), - description: z.string().min(0).max(20), - price: z.coerce.number().min(0).transform((val) => convertPrice(val)), - validFrom: z.coerce.date(), - cronInterval: zpn.simpleCronExpression(), - memberShare: z.coerce.number().min(0).max(100), - pricePeriodId: z.coerce.number(), - }) - - export const createProduct = fields.pick({ +export const cabinProductSchemas = { + createProduct: baseSchema.pick({ name: true, type: true, amount: true, - }) + }), - export const createProductPrice = fields.pick({ + createProductPrice: baseSchema.pick({ description: true, price: true, cronInterval: true, memberShare: true, pricePeriodId: true, - }) + }), } - diff --git a/src/services/cabin/releasePeriod/authers.ts b/src/services/cabin/releasePeriod/authers.ts index 448c6efed..a0c6a6113 100644 --- a/src/services/cabin/releasePeriod/authers.ts +++ b/src/services/cabin/releasePeriod/authers.ts @@ -1,9 +1,11 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace CabinReleasePeriodAuthers { - export const createReleasePeriodAuther = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) - export const readReleasePeriodAuther = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) - export const updateReleasePeriodAuther = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) - export const deleteReleasePeriodAuther = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) +const baseAuther = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) + +export const cabinReleasePeriodAuthers = { + createReleasePeriodAuther: baseAuther, + readReleasePeriodAuther: baseAuther, + updateReleasePeriodAuther: baseAuther, + deleteReleasePeriodAuther: baseAuther, } diff --git a/src/services/cabin/releasePeriod/methods.ts b/src/services/cabin/releasePeriod/methods.ts index aea523c63..19ad0b4af 100644 --- a/src/services/cabin/releasePeriod/methods.ts +++ b/src/services/cabin/releasePeriod/methods.ts @@ -1,15 +1,15 @@ -import { CabinReleasePeriodAuthers } from './authers' -import { CabinReleasePeriodSchemas } from './schemas' -import { serviceMethod } from '@/services/serviceMethod' import 'server-only' +import { cabinReleasePeriodAuthers } from './authers' +import { cabinReleasePeriodSchemas } from './schemas' +import { serviceMethod } from '@/services/serviceMethod' import { ServerError } from '@/services/error' import { z } from 'zod' -export namespace CabinReleasePeriodMethods { +export const cabinReleasePeriodMethods = { - export const create = serviceMethod({ - authorizer: () => CabinReleasePeriodAuthers.createReleasePeriodAuther.dynamicFields({}), - dataSchema: CabinReleasePeriodSchemas.createReleasePeriod, + create: serviceMethod({ + authorizer: () => cabinReleasePeriodAuthers.createReleasePeriodAuther.dynamicFields({}), + dataSchema: cabinReleasePeriodSchemas.createReleasePeriod, method: async ({ prisma, data }) => { const latestReleasePeriod = await prisma.releasePeriod.findFirst({ orderBy: { @@ -29,10 +29,10 @@ export namespace CabinReleasePeriodMethods { data, }) } - }) + }), - export const destroy = serviceMethod({ - authorizer: () => CabinReleasePeriodAuthers.deleteReleasePeriodAuther.dynamicFields({}), + destroy: serviceMethod({ + authorizer: () => cabinReleasePeriodAuthers.deleteReleasePeriodAuther.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -49,19 +49,19 @@ export namespace CabinReleasePeriodMethods { where: params, }) } - }) + }), - export const readMany = serviceMethod({ - authorizer: () => CabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), + readMany: serviceMethod({ + authorizer: () => cabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), method: async ({ prisma }) => prisma.releasePeriod.findMany({ orderBy: { releaseUntil: 'desc', } }) - }) + }), - export const getCurrentReleasePeriod = serviceMethod({ - authorizer: () => CabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), + getCurrentReleasePeriod: serviceMethod({ + authorizer: () => cabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), method: async ({ prisma }) => prisma.releasePeriod.findFirst({ where: { releaseTime: { @@ -73,11 +73,11 @@ export namespace CabinReleasePeriodMethods { }, take: 1 }) - }) + }), - export const update = serviceMethod({ - authorizer: () => CabinReleasePeriodAuthers.updateReleasePeriodAuther.dynamicFields({}), - dataSchema: CabinReleasePeriodSchemas.updateReleasePeriod, + update: serviceMethod({ + authorizer: () => cabinReleasePeriodAuthers.updateReleasePeriodAuther.dynamicFields({}), + dataSchema: cabinReleasePeriodSchemas.updateReleasePeriod, method: async ({ prisma, data }) => prisma.releasePeriod.update({ where: { id: data.id, // TODO: Figure out why id is in data and not a param @@ -87,5 +87,5 @@ export namespace CabinReleasePeriodMethods { releaseTime: data.releaseTime, }, }) - }) + }), } diff --git a/src/services/cabin/releasePeriod/schemas.ts b/src/services/cabin/releasePeriod/schemas.ts index 7c6eb9347..d8ed47f2d 100644 --- a/src/services/cabin/releasePeriod/schemas.ts +++ b/src/services/cabin/releasePeriod/schemas.ts @@ -1,28 +1,26 @@ import { dateLessThan } from '@/lib/dates/comparison' import { z } from 'zod' +const baseSchema = z.object({ + id: z.coerce.number(), + releaseTime: z.coerce.date(), + releaseUntil: z.coerce.date(), +}) -export namespace CabinReleasePeriodSchemas { - const fields = z.object({ - id: z.coerce.number(), - releaseTime: z.coerce.date(), - releaseUntil: z.coerce.date(), - }) - - const releasePeriodRefiner = { - fcn: (data: { releaseTime: Date, releaseUntil: Date }) => dateLessThan(data.releaseTime, data.releaseUntil), - message: 'Slipp tiden må være før slutten av perioden som slippes.' - } +const releasePeriodRefiner = { + fcn: (data: { releaseTime: Date, releaseUntil: Date }) => dateLessThan(data.releaseTime, data.releaseUntil), + message: 'Slipp tiden må være før slutten av perioden som slippes.' +} - export const createReleasePeriod = fields.pick({ +export const cabinReleasePeriodSchemas = { + createReleasePeriod: baseSchema.pick({ releaseTime: true, releaseUntil: true, - }).refine(releasePeriodRefiner.fcn, releasePeriodRefiner.message) + }).refine(releasePeriodRefiner.fcn, releasePeriodRefiner.message), - export const updateReleasePeriod = fields.pick({ + updateReleasePeriod: baseSchema.pick({ id: true, releaseTime: true, releaseUntil: true, - }).refine(releasePeriodRefiner.fcn, releasePeriodRefiner.message) + }).refine(releasePeriodRefiner.fcn, releasePeriodRefiner.message), } - diff --git a/src/services/career/companies/actions.ts b/src/services/career/companies/actions.ts index 12bdbde6d..e06fb4b6b 100644 --- a/src/services/career/companies/actions.ts +++ b/src/services/career/companies/actions.ts @@ -1,12 +1,12 @@ 'use server' import { action } from '@/services/action' -import { CompanyMethods } from '@/services/career/companies/methods' +import { companyMethods } from '@/services/career/companies/methods' -export const createCompanyAction = action(CompanyMethods.create) +export const createCompanyAction = action(companyMethods.create) -export const destroyCompanyAction = action(CompanyMethods.destroy) +export const destroyCompanyAction = action(companyMethods.destroy) -export const readCompanyPageAction = action(CompanyMethods.readPage) +export const readCompanyPageAction = action(companyMethods.readPage) -export const updateComanyAction = action(CompanyMethods.update) +export const updateComanyAction = action(companyMethods.update) diff --git a/src/services/career/companies/authers.ts b/src/services/career/companies/authers.ts index 5ecaf2e80..e7ff1ec72 100644 --- a/src/services/career/companies/authers.ts +++ b/src/services/career/companies/authers.ts @@ -1,8 +1,8 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace CompanyAuthers { - export const create = RequirePermission.staticFields({ permission: 'COMPANY_ADMIN' }) - export const readPage = RequirePermission.staticFields({ permission: 'COMPANY_READ' }) - export const update = RequirePermission.staticFields({ permission: 'COMPANY_ADMIN' }) - export const destroy = RequirePermission.staticFields({ permission: 'COMPANY_ADMIN' }) +export const companyAuthers = { + create: RequirePermission.staticFields({ permission: 'COMPANY_ADMIN' }), + readPage: RequirePermission.staticFields({ permission: 'COMPANY_READ' }), + update: RequirePermission.staticFields({ permission: 'COMPANY_ADMIN' }), + destroy: RequirePermission.staticFields({ permission: 'COMPANY_ADMIN' }), } diff --git a/src/services/career/companies/config.ts b/src/services/career/companies/config.ts index b1ff503c1..57c223cdc 100644 --- a/src/services/career/companies/config.ts +++ b/src/services/career/companies/config.ts @@ -1,11 +1,9 @@ import type { Prisma } from '@prisma/client' -export namespace CompanyConfig { - export const relationIncluder = { - logo: { - include: { - image: true - } +export const logoIncluder = { + logo: { + include: { + image: true } - } as const satisfies Prisma.CompanyInclude -} + } +} as const satisfies Prisma.CompanyInclude diff --git a/src/services/career/companies/methods.ts b/src/services/career/companies/methods.ts index 674863b67..3dd0088d6 100644 --- a/src/services/career/companies/methods.ts +++ b/src/services/career/companies/methods.ts @@ -1,7 +1,7 @@ import '@pn-server-only' -import { CompanySchemas } from './schemas' -import { CompanyAuthers } from './authers' -import { CompanyConfig } from './config' +import { companyAuthers } from './authers' +import { companySchemas } from './schemas' +import { logoIncluder } from './config' import { createCmsImage } from '@/services/cms/images/create' import { serviceMethod } from '@/services/serviceMethod' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' @@ -9,10 +9,10 @@ import { readPageInputSchemaObject } from '@/lib/paging/schema' import { v4 as uuid } from 'uuid' import { z } from 'zod' -export namespace CompanyMethods { - export const create = serviceMethod({ - dataSchema: CompanySchemas.create, - authorizer: () => CompanyAuthers.create.dynamicFields({}), +export const companyMethods = { + create: serviceMethod({ + dataSchema: companySchemas.create, + authorizer: () => companyAuthers.create.dynamicFields({}), method: async ({ prisma, data }) => { //TODO: tranaction when createCmsImage is service method. const logo = await createCmsImage({ name: uuid() }) @@ -23,8 +23,8 @@ export namespace CompanyMethods { } }) } - }) - export const readPage = serviceMethod({ + }), + readPage: serviceMethod({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -34,7 +34,7 @@ export namespace CompanyMethods { name: z.string().optional(), }), ), - authorizer: () => CompanyAuthers.readPage.dynamicFields({}), + authorizer: () => companyAuthers.readPage.dynamicFields({}), method: async ({ prisma, params }) => await prisma.company.findMany({ ...cursorPageingSelection(params.paging.page), where: { @@ -43,27 +43,27 @@ export namespace CompanyMethods { mode: 'insensitive' } }, - include: CompanyConfig.relationIncluder + include: logoIncluder, }) - }) - export const update = serviceMethod({ + }), + update: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - dataSchema: CompanySchemas.update, - authorizer: () => CompanyAuthers.update.dynamicFields({}), + dataSchema: companySchemas.update, + authorizer: () => companyAuthers.update.dynamicFields({}), method: async ({ prisma, params: { id }, data }) => { await prisma.company.update({ where: { id }, data, }) }, - }) - export const destroy = serviceMethod({ + }), + destroy: serviceMethod({ paramsSchema: z.object({ id: z.number() }), - authorizer: () => CompanyAuthers.destroy.dynamicFields({}), + authorizer: () => companyAuthers.destroy.dynamicFields({}), method: async ({ prisma, params: { id } }) => { await prisma.company.delete({ where: { @@ -71,5 +71,5 @@ export namespace CompanyMethods { } }) } - }) + }), } diff --git a/src/services/career/companies/schemas.ts b/src/services/career/companies/schemas.ts index 707b896d2..17391806c 100644 --- a/src/services/career/companies/schemas.ts +++ b/src/services/career/companies/schemas.ts @@ -1,22 +1,23 @@ import { z } from 'zod' -export namespace CompanySchemas { - const fields = z.object({ - name: z.string().min( - 2, 'Navnet må være minst 3 tegn langt' - ).max( - 100, 'Navnet kan maks være 100 tegn langt' - ).trim(), - description: z.string().max( - 200, 'Beskrivelsen kan maks være 200 tegn langt' - ).trim(), - }) - export const create = fields.pick({ +const baseSchema = z.object({ + name: z.string().min( + 2, 'Navnet må være minst 3 tegn langt' + ).max( + 100, 'Navnet kan maks være 100 tegn langt' + ).trim(), + description: z.string().max( + 200, 'Beskrivelsen kan maks være 200 tegn langt' + ).trim(), +}) + +export const companySchemas = { + create: baseSchema.pick({ name: true, description: true, - }) - export const update = fields.partial().pick({ + }), + update: baseSchema.partial().pick({ name: true, description: true, - }) + }), } diff --git a/src/services/career/jobAds/actions.ts b/src/services/career/jobAds/actions.ts index f5c5d0a51..d623c28dc 100644 --- a/src/services/career/jobAds/actions.ts +++ b/src/services/career/jobAds/actions.ts @@ -1,14 +1,14 @@ 'use server' import { action } from '@/services/action' -import { JobadMethods } from '@/services/career/jobAds/methods' +import { jobAdMethods } from '@/services/career/jobAds/methods' -export const createJobAdAction = action(JobadMethods.create) +export const createJobAdAction = action(jobAdMethods.create) -export const destroyJobAdAction = action(JobadMethods.destroy) +export const destroyJobAdAction = action(jobAdMethods.destroy) -export const readJobAdAction = action(JobadMethods.read) -export const readActiveJobAdsAction = action(JobadMethods.readActive) -export const readInactiveJobAdsPageAction = action(JobadMethods.readInactivePage) +export const readJobAdAction = action(jobAdMethods.read) +export const readActiveJobAdsAction = action(jobAdMethods.readActive) +export const readInactiveJobAdsPageAction = action(jobAdMethods.readInactivePage) -export const updateJobAdAction = action(JobadMethods.update) +export const updateJobAdAction = action(jobAdMethods.update) diff --git a/src/services/career/jobAds/authers.ts b/src/services/career/jobAds/authers.ts index a3f985fb7..fa4639326 100644 --- a/src/services/career/jobAds/authers.ts +++ b/src/services/career/jobAds/authers.ts @@ -1,10 +1,10 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace JobAdAuthers { - export const create = RequirePermission.staticFields({ permission: 'JOBAD_CREATE' }) - export const read = RequirePermission.staticFields({ permission: 'JOBAD_READ' }) - export const readActive = RequirePermission.staticFields({ permission: 'JOBAD_READ' }) - export const readInactivePage = RequirePermission.staticFields({ permission: 'JOBAD_READ' }) - export const update = RequirePermission.staticFields({ permission: 'JOBAD_UPDATE' }) - export const destroy = RequirePermission.staticFields({ permission: 'JOBAD_DESTROY' }) +export const jobAdAuthers = { + create: RequirePermission.staticFields({ permission: 'JOBAD_CREATE' }), + read: RequirePermission.staticFields({ permission: 'JOBAD_READ' }), + readActive: RequirePermission.staticFields({ permission: 'JOBAD_READ' }), + readInactivePage: RequirePermission.staticFields({ permission: 'JOBAD_READ' }), + update: RequirePermission.staticFields({ permission: 'JOBAD_UPDATE' }), + destroy: RequirePermission.staticFields({ permission: 'JOBAD_DESTROY' }), } diff --git a/src/services/career/jobAds/config.ts b/src/services/career/jobAds/config.ts index cdf429f89..c9b7c5879 100644 --- a/src/services/career/jobAds/config.ts +++ b/src/services/career/jobAds/config.ts @@ -3,38 +3,39 @@ import { JobType } from '@prisma/client' import type { Prisma } from '@prisma/client' -export namespace JobAdConfig { - export const type = { - FULL_TIME: { label: 'Heltid' }, - PART_TIME: { label: 'Deltid' }, - INTERNSHIP: { label: 'Internship' }, - OTHER: { label: 'Annet' }, - CONTRACT: { label: 'Kontrakt' }, - } satisfies Record - export const relationIncluder = { - article: { - include: articleRealtionsIncluder - }, - company: true - } as const satisfies Prisma.JobAdInclude - export const simpleRelationIncluder = { - company: { - select: { - name: true, - } - }, - article: { - include: { - coverImage: { - include: { - image: true - } +export const jobAdType = { + FULL_TIME: { label: 'Heltid' }, + PART_TIME: { label: 'Deltid' }, + INTERNSHIP: { label: 'Internship' }, + OTHER: { label: 'Annet' }, + CONTRACT: { label: 'Kontrakt' }, +} satisfies Record + +export const articleAndCompanyIncluder = { + article: { + include: articleRealtionsIncluder + }, + company: true +} as const satisfies Prisma.JobAdInclude + +export const simpleArticleAndCompanyIncluder = { + company: { + select: { + name: true, + } + }, + article: { + include: { + coverImage: { + include: { + image: true } } } - } as const satisfies Prisma.JobAdInclude - export const options = Object.values(JobType).map((opt): { value: JobType, label: string } => ({ - value: opt, - label: type[opt].label - })) -} + } +} as const satisfies Prisma.JobAdInclude + +export const jobAdOptions = Object.values(JobType).map((opt): { value: JobType, label: string } => ({ + value: opt, + label: jobAdType[opt].label +})) diff --git a/src/services/career/jobAds/methods.ts b/src/services/career/jobAds/methods.ts index 831b82e20..3453aa8dc 100644 --- a/src/services/career/jobAds/methods.ts +++ b/src/services/career/jobAds/methods.ts @@ -1,11 +1,11 @@ import '@pn-server-only' -import { JobAdSchemas } from './schemas' -import { JobAdAuthers } from './authers' -import { JobAdConfig } from './config' +import { jobAdAuthers } from './authers' +import { jobAdSchemas } from './schemas' +import { articleAndCompanyIncluder, simpleArticleAndCompanyIncluder } from './config' +import { logoIncluder } from '@/services/career/companies/config' import { serviceMethod } from '@/services/serviceMethod' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createArticle } from '@/services/cms/articles/create' -import { CompanyConfig } from '@/career/companies/config' import { ServerError } from '@/services/error' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' @@ -14,10 +14,10 @@ import { z } from 'zod' import { JobType } from '@prisma/client' import type { ExpandedJobAd, SimpleJobAd } from './Types' -export namespace JobadMethods { - export const create = serviceMethod({ - dataSchema: JobAdSchemas.create, - authorizer: () => JobAdAuthers.create.dynamicFields({}), +export const jobAdMethods = { + create: serviceMethod({ + dataSchema: jobAdSchemas.create, + authorizer: () => jobAdAuthers.create.dynamicFields({}), method: async ({ prisma, data: { articleName, companyId, ...data } }) => { const article = await createArticle({ name: articleName }) @@ -42,13 +42,13 @@ export namespace JobadMethods { }, }) } - }) + }), /** * This handler reads a jobAd by id or articleName and order * @param idOrName - id or articleName and order of jobAd to read (id or {articleName: string, order: number}) * @returns ExpandedJobAd - the jobAd and its article */ - export const read = serviceMethod({ + read: serviceMethod({ paramsSchema: z.object({ idOrName: z.union([ z.number(), @@ -58,7 +58,7 @@ export namespace JobadMethods { }), ]), }), - authorizer: () => JobAdAuthers.read.dynamicFields({}), + authorizer: () => jobAdAuthers.read.dynamicFields({}), method: async ({ prisma, params: { idOrName } }): Promise => { const jobAd = await prisma.jobAd.findUnique({ where: typeof idOrName === 'number' ? { @@ -70,22 +70,22 @@ export namespace JobadMethods { } }, include: { - ...JobAdConfig.relationIncluder, + ...articleAndCompanyIncluder, company: { - include: CompanyConfig.relationIncluder, + include: logoIncluder, } } }) if (!jobAd) throw new ServerError('NOT FOUND', `job ad ${idOrName} not found`) return jobAd } - }) + }), /** * This handler reads all active jobAds * @returns SimpleJobAd[] - all jobAds with coverImage */ - export const readActive = serviceMethod({ - authorizer: () => JobAdAuthers.readActive.dynamicFields({}), + readActive: serviceMethod({ + authorizer: () => jobAdAuthers.readActive.dynamicFields({}), method: async ({ prisma }): Promise => { const jobAds = await prisma.jobAd.findMany({ orderBy: { @@ -96,7 +96,7 @@ export namespace JobadMethods { where: { active: true, }, - include: JobAdConfig.simpleRelationIncluder, + include: simpleArticleAndCompanyIncluder, }) return jobAds.map(ad => ({ ...ad, @@ -104,12 +104,12 @@ export namespace JobadMethods { companyName: ad.company.name, })) } - }) + }), /** * This handler reads a page of inactive jobAds * @param paging - the page to read, includes details to filter by name (articleName) and the type. */ - export const readInactivePage = serviceMethod({ + readInactivePage: serviceMethod({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -120,7 +120,7 @@ export namespace JobadMethods { type: z.nativeEnum(JobType).nullable(), }), ), - authorizer: () => JobAdAuthers.readInactivePage.dynamicFields({}), + authorizer: () => jobAdAuthers.readInactivePage.dynamicFields({}), method: async ({ prisma, params }): Promise => { const jobAds = await prisma.jobAd.findMany({ ...cursorPageingSelection(params.paging.page), @@ -134,7 +134,7 @@ export namespace JobadMethods { }, type: params.paging.details.type || undefined, }, - include: JobAdConfig.simpleRelationIncluder, + include: simpleArticleAndCompanyIncluder, }) return jobAds.map(ad => ({ ...ad, @@ -142,34 +142,34 @@ export namespace JobadMethods { companyName: ad.company.name, })) } - }) + }), /** * This handler destroys a jobAd. It is also responsible for cleaning up the article, * to avoid orphaned articles. It calls destroyArticle to destroy the article and its coverImage (cmsImage) * @param id - id of news article to destroy * @returns */ - export const update = serviceMethod({ + update: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - dataSchema: JobAdSchemas.update, - authorizer: () => JobAdAuthers.update.dynamicFields({}), + dataSchema: jobAdSchemas.update, + authorizer: () => jobAdAuthers.update.dynamicFields({}), method: async ({ prisma, params: { id }, data }) => await prisma.jobAd.update({ where: { id }, data, }) - }) - export const destroy = serviceMethod({ + }), + destroy: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - authorizer: () => JobAdAuthers.destroy.dynamicFields({}), + authorizer: () => jobAdAuthers.destroy.dynamicFields({}), method: async ({ prisma, params: { id } }) => { const jobAd = await prisma.jobAd.delete({ where: { id }, }) await destroyArticle(jobAd.articleId) } - }) + }), } diff --git a/src/services/career/jobAds/schemas.ts b/src/services/career/jobAds/schemas.ts index a8e5e0767..06694b1f4 100644 --- a/src/services/career/jobAds/schemas.ts +++ b/src/services/career/jobAds/schemas.ts @@ -2,32 +2,33 @@ import { zpn } from '@/lib/fields/zpn' import { z } from 'zod' import { JobType } from '@prisma/client' -export namespace JobAdSchemas { - const fields = z.object({ - companyId: z.coerce.number({ - errorMap: () => ({ message: 'Velg en bedrift' }), - }).int().positive().int(), - articleName: z.string().max(50, 'max lengde 50').min(2, 'min lengde 2'), - description: z.string().max(200, 'max lengde 200').min(2, 'min lengde 2').or(z.literal('')), - type: z.nativeEnum(JobType), - applicationDeadline: zpn.date({ label: 'Søknadsfrist' }), - active: zpn.checkboxOrBoolean({ label: 'Aktiv' }), - location: z.string().optional(), - }) - export const create = fields.pick({ +const baseSchema = z.object({ + companyId: z.coerce.number({ + errorMap: () => ({ message: 'Velg en bedrift' }), + }).int().positive().int(), + articleName: z.string().max(50, 'max lengde 50').min(2, 'min lengde 2'), + description: z.string().max(200, 'max lengde 200').min(2, 'min lengde 2').or(z.literal('')), + type: z.nativeEnum(JobType), + applicationDeadline: zpn.date({ label: 'Søknadsfrist' }), + active: zpn.checkboxOrBoolean({ label: 'Aktiv' }), + location: z.string().optional(), +}) + +export const jobAdSchemas = { + create: baseSchema.pick({ companyId: true, articleName: true, description: true, type: true, applicationDeadline: true, location: true, - }) - export const update = fields.partial().pick({ + }), + update: baseSchema.partial().pick({ companyId: true, description: true, type: true, applicationDeadline: true, active: true, location: true, - }) + }), } diff --git a/src/services/dots/authers.ts b/src/services/dots/authers.ts index 46a9de325..f0e2bc333 100644 --- a/src/services/dots/authers.ts +++ b/src/services/dots/authers.ts @@ -2,11 +2,11 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import { RequirePermissionAndUserId } from '@/auth/auther/RequirePermissionAndUserId' import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' -export namespace DotAuthers { - export const create = RequirePermissionAndUserId.staticFields({ permission: 'DOTS_ADMIN' }) - export const update = RequirePermission.staticFields({ permission: 'DOTS_ADMIN' }) - export const destroy = RequirePermission.staticFields({ permission: 'DOTS_ADMIN' }) - export const readForUser = RequireUserIdOrPermission.staticFields({ permission: 'DOTS_ADMIN' }) - export const readPage = RequirePermission.staticFields({ permission: 'DOTS_ADMIN' }) - export const readWrapperForUser = RequireUserIdOrPermission.staticFields({ permission: 'DOTS_ADMIN' }) +export const dotAuthers = { + create: RequirePermissionAndUserId.staticFields({ permission: 'DOTS_ADMIN' }), + update: RequirePermission.staticFields({ permission: 'DOTS_ADMIN' }), + destroy: RequirePermission.staticFields({ permission: 'DOTS_ADMIN' }), + readForUser: RequireUserIdOrPermission.staticFields({ permission: 'DOTS_ADMIN' }), + readPage: RequirePermission.staticFields({ permission: 'DOTS_ADMIN' }), + readWrapperForUser: RequireUserIdOrPermission.staticFields({ permission: 'DOTS_ADMIN' }), } diff --git a/src/services/dots/config.ts b/src/services/dots/config.ts index 689afd327..44eeb318e 100644 --- a/src/services/dots/config.ts +++ b/src/services/dots/config.ts @@ -1,27 +1,27 @@ import type { Prisma } from '@prisma/client' -export namespace DotConfig { - const baseDurationDays = 14 - export const baseDuration = 1000 * 60 * 60 * 24 * baseDurationDays - export const wrapperWithDotsIncluder = { - dots: { - orderBy: { - expiresAt: 'desc' - } - }, - user: { - select: { - firstname: true, - lastname: true, - username: true - } - }, - accuser: { - select: { - firstname: true, - lastname: true, - username: true - } +const dotBaseDurationDays = 14 + +export const dotBaseDuration = 1000 * 60 * 60 * 24 * dotBaseDurationDays + +export const dotsIncluder = { + dots: { + orderBy: { + expiresAt: 'desc' + } + }, + user: { + select: { + firstname: true, + lastname: true, + username: true + } + }, + accuser: { + select: { + firstname: true, + lastname: true, + username: true } - } as const satisfies Prisma.DotWrapperInclude -} + } +} as const satisfies Prisma.DotWrapperInclude diff --git a/src/services/dots/methods.ts b/src/services/dots/methods.ts index 27ddf2515..658ada69b 100644 --- a/src/services/dots/methods.ts +++ b/src/services/dots/methods.ts @@ -1,7 +1,7 @@ import '@pn-server-only' -import { DotConfig } from './config' -import { DotAuthers } from './authers' -import { DotSchemas } from './schemas' +import { dotAuthers } from './authers' +import { dotSchemas } from './schemas' +import { dotBaseDuration, dotsIncluder } from './config' import { serviceMethod } from '@/services/serviceMethod' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { readPageInputSchemaObject } from '@/lib/paging/schema' @@ -13,7 +13,7 @@ import { z } from 'zod' * @returns All dots for the user in ascending order of expiration. i.e the dot that expires first will be first in the list */ const readForUser = serviceMethod({ - authorizer: ({ params }) => DotAuthers.readForUser.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => dotAuthers.readForUser.dynamicFields({ userId: params.userId }), paramsSchema: z.object({ userId: z.number(), onlyActive: z.boolean(), @@ -34,8 +34,8 @@ const readForUser = serviceMethod({ }) const create = serviceMethod({ - dataSchema: DotSchemas.create, - authorizer: ({ data }) => DotAuthers.create.dynamicFields({ userId: data.userId }), + dataSchema: dotSchemas.create, + authorizer: ({ data }) => dotAuthers.create.dynamicFields({ userId: data.userId }), paramsSchema: z.object({ accuserId: z.number(), }), @@ -49,7 +49,7 @@ const create = serviceMethod({ let prevExpiresAt = activeDots.length > 0 ? activeDots[activeDots.length - 1].expiresAt : new Date() for (let i = 0; i < value; i++) { //TODO: Take freezes into account - const expiresAt = new Date(prevExpiresAt.getTime() + DotConfig.baseDuration) + const expiresAt = new Date(prevExpiresAt.getTime() + dotBaseDuration) dotData.push({ expiresAt }) prevExpiresAt = expiresAt } @@ -71,7 +71,7 @@ const create = serviceMethod({ }) const readWrappersForUser = serviceMethod({ - authorizer: ({ params }) => DotAuthers.readWrapperForUser.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => dotAuthers.readWrapperForUser.dynamicFields({ userId: params.userId }), paramsSchema: z.object({ userId: z.number(), }), @@ -80,7 +80,7 @@ const readWrappersForUser = serviceMethod({ where: { userId }, - include: DotConfig.wrapperWithDotsIncluder, + include: dotsIncluder, }) return wrappers.sort((a, b) => { @@ -95,7 +95,7 @@ const readWrappersForUser = serviceMethod({ }) const readPage = serviceMethod({ - authorizer: () => DotAuthers.readPage.dynamicFields({}), + authorizer: () => dotAuthers.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -123,7 +123,7 @@ const readPage = serviceMethod({ username: 'asc' } }, - include: DotConfig.wrapperWithDotsIncluder, + include: dotsIncluder, })).map(wrapper => ({ ...wrapper, dots: extendWithActive(wrapper.dots) diff --git a/src/services/dots/schemas.ts b/src/services/dots/schemas.ts index c60a25b0d..81363e1ac 100644 --- a/src/services/dots/schemas.ts +++ b/src/services/dots/schemas.ts @@ -1,23 +1,23 @@ import { z } from 'zod' +const dotSchema = z.object({ + value: z.coerce.number().int().min( + 1, 'Verdi må være et positivt heltall' + ).max( + 100, 'Verdi kan ikke være større enn 100' + ), + reason: z.string().max(200, 'Begrunnelse kan ha maks 200 tegn').trim(), + userId: z.coerce.number().int(), +}) -export namespace DotSchemas { - const dotSchemaFields = z.object({ - value: z.coerce.number().int().min( - 1, 'Verdi må være et positivt heltall' - ).max( - 100, 'Verdi kan ikke være større enn 100' - ), - reason: z.string().max(200, 'Begrunnelse kan ha maks 200 tegn').trim(), - userId: z.coerce.number().int(), - }) - export const create = dotSchemaFields.pick({ +export const dotSchemas = { + create: dotSchema.pick({ value: true, reason: true, userId: true, - }) - export const update = dotSchemaFields.partial().pick({ + }), + update: dotSchema.partial().pick({ value: true, reason: true, - }) + }), } diff --git a/src/services/events/Types.ts b/src/services/events/Types.ts index b2e6ae74d..003cfddee 100644 --- a/src/services/events/Types.ts +++ b/src/services/events/Types.ts @@ -1,10 +1,10 @@ -import type { EventConfig } from './config' +import type { eventFilterSelection } from './config' import type { ExpandedCmsImage } from '@/cms/images/Types' import type { EventTag, Prisma } from '@prisma/client' export type EventFiltered = Prisma.EventGetPayload<{ - select: typeof EventConfig.filterSeletion + select: typeof eventFilterSelection }> & { numOfRegistrations: number, numOnWaitingList: number, diff --git a/src/services/events/actions.ts b/src/services/events/actions.ts index d5fe93627..a9b8e0de5 100644 --- a/src/services/events/actions.ts +++ b/src/services/events/actions.ts @@ -1,14 +1,14 @@ 'use server' import { action } from '@/services/action' -import { EventMethods } from '@/services/events/methods' +import { eventMethods } from '@/services/events/methods' -export const createEventAction = action(EventMethods.create) +export const createEventAction = action(eventMethods.create) -export const destroyEventAction = action(EventMethods.destroy) +export const destroyEventAction = action(eventMethods.destroy) -export const readCurrentEventsAction = action(EventMethods.readManyCurrent) -export const readEventAction = action(EventMethods.read) -export const readArchivedEventsPageAction = action(EventMethods.readManyArchivedPage) +export const readCurrentEventsAction = action(eventMethods.readManyCurrent) +export const readEventAction = action(eventMethods.read) +export const readArchivedEventsPageAction = action(eventMethods.readManyArchivedPage) -export const updateEventAction = action(EventMethods.update) +export const updateEventAction = action(eventMethods.update) diff --git a/src/services/events/authers.ts b/src/services/events/authers.ts index a41786e97..5e7b503fb 100644 --- a/src/services/events/authers.ts +++ b/src/services/events/authers.ts @@ -1,12 +1,12 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace EventAuthers { - export const create = RequirePermission.staticFields({ permission: 'EVENT_CREATE' }) +export const eventAuthers = { + create: RequirePermission.staticFields({ permission: 'EVENT_CREATE' }), // TODO: Replace below with proper authers - export const read = RequireNothing.staticFields({}) - export const readManyCurrent = RequireNothing.staticFields({}) - export const readManyArchivedPage = RequireNothing.staticFields({}) - export const update = RequireNothing.staticFields({}) - export const destroy = RequireNothing.staticFields({}) + read: RequireNothing.staticFields({}), + readManyCurrent: RequireNothing.staticFields({}), + readManyArchivedPage: RequireNothing.staticFields({}), + update: RequireNothing.staticFields({}), + destroy: RequireNothing.staticFields({}), } diff --git a/src/services/events/config.ts b/src/services/events/config.ts index ab3726bd9..a79f24934 100644 --- a/src/services/events/config.ts +++ b/src/services/events/config.ts @@ -2,39 +2,36 @@ import { createSelection } from '@/services/createSelection' import { EventCanView } from '@prisma/client' import type { Event } from '@prisma/client' -export namespace EventConfig { - export const canBeViewdBy = { - ALL: { label: 'Alle' }, - CAN_REGISTER: { label: 'Alle som kan melde seg på' } - } satisfies Record +export const eventCanBeViewdBy = { + ALL: { label: 'Alle' }, + CAN_REGISTER: { label: 'Alle som kan melde seg på' } +} satisfies Record - export const canBeViewdByOptions = Object.values(EventCanView).map(opt => ({ - value: opt, - label: canBeViewdBy[opt].label - })) +export const eventCanBeViewdByOptions = Object.values(EventCanView).map(opt => ({ + value: opt, + label: eventCanBeViewdBy[opt].label +})) - export const fieldsToExpose = [ - 'id', - 'name', - 'location', - 'order', - 'eventStart', - 'eventEnd', - 'places', - 'waitingList', - 'registrationStart', - 'registrationEnd', - 'canBeViewdBy', - 'takesRegistration' - ] as const satisfies (keyof Event)[] +export const eventFieldsToExpose = [ + 'id', + 'name', + 'location', + 'order', + 'eventStart', + 'eventEnd', + 'places', + 'waitingList', + 'registrationStart', + 'registrationEnd', + 'canBeViewdBy', + 'takesRegistration' +] as const satisfies (keyof Event)[] - export const filterSeletion = { - ...createSelection(fieldsToExpose), - _count: { - select: { - eventRegistrations: true, - }, +export const eventFilterSelection = { + ...createSelection(eventFieldsToExpose), + _count: { + select: { + eventRegistrations: true, }, - } as const -} - + }, +} as const diff --git a/src/services/events/methods.ts b/src/services/events/methods.ts index 3ae2b5c5a..273bf015b 100644 --- a/src/services/events/methods.ts +++ b/src/services/events/methods.ts @@ -1,7 +1,8 @@ import '@pn-server-only' -import { EventSchemas } from './schemas' -import { EventConfig } from './config' -import { EventAuthers } from './authers' +import { eventAuthers } from './authers' +import { eventSchemas } from './schemas' +import { eventFilterSelection } from './config' +import { notificationMethods } from '@/services/notifications/methods' import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createCmsImage } from '@/services/cms/images/create' @@ -10,16 +11,15 @@ import { ServerError } from '@/services/error' import { serviceMethod } from '@/services/serviceMethod' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' -import { NotificationMethods } from '@/services/notifications/methods' import { displayDate } from '@/lib/dates/displayDate' import { v4 as uuid } from 'uuid' import { z } from 'zod' import type { EventExpanded } from './Types' -export namespace EventMethods { - export const create = serviceMethod({ - dataSchema: EventSchemas.create, - authorizer: () => EventAuthers.create.dynamicFields({}), +export const eventMethods = { + create: serviceMethod({ + dataSchema: eventSchemas.create, + authorizer: () => eventAuthers.create.dynamicFields({}), method: async ({ prisma, data, session }) => { const cmsParagraph = await createCmsParagraph({ name: uuid() }) const cmsImage = await createCmsImage({ name: uuid() }) @@ -79,7 +79,7 @@ export namespace EventMethods { })) }) - await NotificationMethods.createSpecial({ + await notificationMethods.createSpecial({ params: { special: 'NEW_EVENT', }, @@ -91,13 +91,13 @@ export namespace EventMethods { }) return event } - }) - export const read = serviceMethod({ + }), + read: serviceMethod({ paramsSchema: z.object({ order: z.number(), name: z.string(), }), - authorizer: () => EventAuthers.read.dynamicFields({}), + authorizer: () => eventAuthers.read.dynamicFields({}), method: async ({ prisma, params, session }) => { const event = await prisma.event.findUniqueOrThrow({ where: { @@ -154,16 +154,16 @@ export namespace EventMethods { tags: event.eventTagEvents.map(ete => ete.tag) } } - }) - export const readManyCurrent = serviceMethod({ + }), + readManyCurrent: serviceMethod({ paramsSchema: z.object({ tags: z.array(z.string()).nullable(), }), - authorizer: () => EventAuthers.readManyCurrent.dynamicFields({}), + authorizer: () => eventAuthers.readManyCurrent.dynamicFields({}), method: async ({ prisma, params }): Promise => { const events = await prisma.event.findMany({ select: { - ...EventConfig.filterSeletion, + ...eventFilterSelection, coverImage: { include: { image: true @@ -189,8 +189,8 @@ export namespace EventMethods { tags: event.eventTagEvents.map(ete => ete.tag) })) } - }) - export const readManyArchivedPage = serviceMethod({ + }), + readManyArchivedPage: serviceMethod({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -201,7 +201,7 @@ export namespace EventMethods { tags: z.array(z.string()).nullable(), }), ), // Converted from ReadPageInput - authorizer: () => EventAuthers.readManyArchivedPage.dynamicFields({}), + authorizer: () => eventAuthers.readManyArchivedPage.dynamicFields({}), method: async ({ prisma, params }): Promise => { const events = await prisma.event.findMany({ ...cursorPageingSelection(params.paging.page), @@ -216,7 +216,7 @@ export namespace EventMethods { eventTagEvents: eventTagSelector(params.paging.details.tags) }, select: { - ...EventConfig.filterSeletion, + ...eventFilterSelection, coverImage: { include: { image: true @@ -236,13 +236,13 @@ export namespace EventMethods { tags: event.eventTagEvents.map(ete => ete.tag) })) } - }) - export const update = serviceMethod({ + }), + update: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - dataSchema: EventSchemas.update, - authorizer: () => EventAuthers.update.dynamicFields({}), + dataSchema: eventSchemas.update, + authorizer: () => eventAuthers.update.dynamicFields({}), method: async ({ prisma, params, data: { tagIds, ...data } }) => { const event = await prisma.event.findUniqueOrThrow({ where: { id: params.id } @@ -287,12 +287,12 @@ export namespace EventMethods { // TODO: Send email to users that get promoted from waiting list return eventUpdate } - }) - export const destroy = serviceMethod({ + }), + destroy: serviceMethod({ paramsSchema: z.object({ id: z.number() }), - authorizer: () => EventAuthers.destroy.dynamicFields({}), + authorizer: () => eventAuthers.destroy.dynamicFields({}), method: async ({ prisma, params }) => { await prisma.event.delete({ where: { @@ -300,7 +300,7 @@ export namespace EventMethods { } }) } - }) + }), } function eventTagSelector(tags: string[] | null) { diff --git a/src/services/events/registration/Types.ts b/src/services/events/registration/Types.ts index a346bb2d9..8df2e67ca 100644 --- a/src/services/events/registration/Types.ts +++ b/src/services/events/registration/Types.ts @@ -1,18 +1,18 @@ -import type { EventRegistrationConfig } from './config' +import type { eventRegistrationIncluderDetailed, eventRegistrationSelection, REGISTRATION_READER_TYPE } from './config' import type { Image, Prisma } from '@prisma/client' // This type will just make sure that the image is not null export type EventRegistrationExpanded = Prisma.EventRegistrationGetPayload<{ - select: typeof EventRegistrationConfig.selection + select: typeof eventRegistrationSelection }> & { image: Image } export type EventRegistrationDetailedExpanded = Prisma.EventRegistrationGetPayload<{ - include: typeof EventRegistrationConfig.includerDetailed + include: typeof eventRegistrationIncluderDetailed, }> export type EventRegistrationFetcherDetails = { eventId: number, - type?: EventRegistrationConfig.REGISTRATION_READER_TYPE, + type?: REGISTRATION_READER_TYPE, } diff --git a/src/services/events/registration/actions.ts b/src/services/events/registration/actions.ts index f05322b16..08218e299 100644 --- a/src/services/events/registration/actions.ts +++ b/src/services/events/registration/actions.ts @@ -1,11 +1,11 @@ 'use server' import { action } from '@/services/action' -import { EventRegistrationMethods } from '@/services/events/registration/methods' +import { eventRegistrationMethods } from '@/services/events/registration/methods' -export const createEventRegistrationAction = action(EventRegistrationMethods.create) -export const createGuestEventRegistrationAction = action(EventRegistrationMethods.createGuest) -export const readManyEventRegistrationAction = action(EventRegistrationMethods.readMany) -export const eventRegistrationReadManyDetailedAction = action(EventRegistrationMethods.readManyDetailed) -export const eventRegistrationUpdateNotesAction = action(EventRegistrationMethods.updateNotes) -export const eventRegistrationDestroyAction = action(EventRegistrationMethods.destroy) +export const createEventRegistrationAction = action(eventRegistrationMethods.create) +export const createGuestEventRegistrationAction = action(eventRegistrationMethods.createGuest) +export const readManyEventRegistrationAction = action(eventRegistrationMethods.readMany) +export const eventRegistrationReadManyDetailedAction = action(eventRegistrationMethods.readManyDetailed) +export const eventRegistrationUpdateNotesAction = action(eventRegistrationMethods.updateNotes) +export const eventRegistrationDestroyAction = action(eventRegistrationMethods.destroy) diff --git a/src/services/events/registration/authers.ts b/src/services/events/registration/authers.ts index e45a57248..5bfa27c7c 100644 --- a/src/services/events/registration/authers.ts +++ b/src/services/events/registration/authers.ts @@ -3,13 +3,13 @@ import { RequirePermissionAndUser } from '@/auth/auther/RequirePermissionAndUser import { RequireUser } from '@/auth/auther/RequireUser' import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' -export namespace EventRegistrationAuthers { +export const eventRegistrationAuthers = { // TODO: Fix authing - export const create = RequireUserIdOrPermission.staticFields({ permission: 'EVENT_REGISTRATION_CREATE' }) - export const createGuest = RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }) - export const readMany = RequirePermissionAndUser.staticFields({ permission: 'EVENT_REGISTRATION_READ' }) - export const readManyDetailed = RequirePermissionAndUser.staticFields({ permission: 'EVENT_REGISTRATION_READ' }) - export const destroy = RequirePermissionAndUser.staticFields({ permission: 'EVENT_REGISTRATION_DESROY' }) + create: RequireUserIdOrPermission.staticFields({ permission: 'EVENT_REGISTRATION_CREATE' }), + createGuest: RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }), + readMany: RequirePermissionAndUser.staticFields({ permission: 'EVENT_REGISTRATION_READ' }), + readManyDetailed: RequirePermissionAndUser.staticFields({ permission: 'EVENT_REGISTRATION_READ' }), + destroy: RequirePermissionAndUser.staticFields({ permission: 'EVENT_REGISTRATION_DESROY' }), - export const updateRegistrationNotes = RequireUser.staticFields({}) // TODO: bypass permission + updateRegistrationNotes: RequireUser.staticFields({}), // TODO: bypass permission } diff --git a/src/services/events/registration/config.ts b/src/services/events/registration/config.ts index 65b6116c1..0a2936807 100644 --- a/src/services/events/registration/config.ts +++ b/src/services/events/registration/config.ts @@ -1,29 +1,26 @@ -import { UserConfig } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/config' import type { Prisma } from '@prisma/client' -export namespace EventRegistrationConfig { - - export const selection = { - user: { - select: { - ...UserConfig.filterSelection, - image: true, - }, +export const eventRegistrationSelection = { + user: { + select: { + ...userFilterSelection, + image: true, + }, + }, + contact: { + select: { + name: true, }, - contact: { - select: { - name: true, - }, - } - } satisfies Prisma.EventRegistrationSelect + } +} satisfies Prisma.EventRegistrationSelect - export const includerDetailed = { - ...selection, - contact: true, - } satisfies Prisma.EventRegistrationInclude +export const eventRegistrationIncluderDetailed = { + ...eventRegistrationSelection, + contact: true, +} satisfies Prisma.EventRegistrationInclude - export enum REGISTRATION_READER_TYPE { - REGISTRATIONS = 'REGISTRATIONS', - WAITING_LIST = 'WAITING_LIST', - } +export enum REGISTRATION_READER_TYPE { + REGISTRATIONS = 'REGISTRATIONS', + WAITING_LIST = 'WAITING_LIST', } diff --git a/src/services/events/registration/methods.ts b/src/services/events/registration/methods.ts index 37cb72d78..7e69c8f2a 100644 --- a/src/services/events/registration/methods.ts +++ b/src/services/events/registration/methods.ts @@ -1,13 +1,13 @@ -import { EventRegistrationAuthers } from './authers' -import { EventRegistrationConfig } from './config' -import { EventRegistrationSchemas } from './schemas' -import { serviceMethod } from '@/services/serviceMethod' import '@pn-server-only' +import { eventRegistrationIncluderDetailed, eventRegistrationSelection, REGISTRATION_READER_TYPE } from './config' +import { eventRegistrationAuthers } from './authers' +import { eventRegistrationSchemas } from './schemas' +import { serviceMethod } from '@/services/serviceMethod' import { Smorekopp } from '@/services/error' -import { ImageMethods } from '@/services/images/methods' -import { NotificationMethods } from '@/services/notifications/methods' -import { UserConfig } from '@/services/users/config' +import { imageMethods } from '@/services/images/methods' +import { notificationMethods } from '@/services/notifications/methods' import { sendSystemMail } from '@/services/notifications/email/send' +import { userFilterSelection } from '@/services/users/config' import { z } from 'zod' import type { Prisma } from '@prisma/client' import type { EventRegistrationExpanded } from './Types' @@ -93,7 +93,7 @@ async function calculateTakeSkip(prisma: Prisma.TransactionClient, params: { eventId: number, take?: number, skip?: number, - type?: EventRegistrationConfig.REGISTRATION_READER_TYPE, + type?: REGISTRATION_READER_TYPE, }) { let take = params.take let skip = params.skip @@ -105,7 +105,7 @@ async function calculateTakeSkip(prisma: Prisma.TransactionClient, params: { }, }) - if (params.type === EventRegistrationConfig.REGISTRATION_READER_TYPE.REGISTRATIONS) { + if (params.type === REGISTRATION_READER_TYPE.REGISTRATIONS) { skip = Math.min(skip ?? 0, event.places) take = Math.min(take, event.places - skip) } else { @@ -123,14 +123,14 @@ async function calculateTakeSkip(prisma: Prisma.TransactionClient, params: { } } -export namespace EventRegistrationMethods { +export const eventRegistrationMethods = { - export const create = serviceMethod({ + create: serviceMethod({ paramsSchema: z.object({ userId: z.number().min(0), eventId: z.number().min(0), }), - authorizer: ({ params }) => EventRegistrationAuthers.create.dynamicFields({ + authorizer: ({ params }) => eventRegistrationAuthers.create.dynamicFields({ userId: params.userId, }), opensTransaction: true, @@ -160,14 +160,14 @@ export namespace EventRegistrationMethods { onWaitingList: updatedEvent.places < updatedEvent._count.eventRegistrations, } }, - }) + }), - export const createGuest = serviceMethod({ - authorizer: () => EventRegistrationAuthers.createGuest.dynamicFields({}), + createGuest: serviceMethod({ + authorizer: () => eventRegistrationAuthers.createGuest.dynamicFields({}), paramsSchema: z.object({ eventId: z.number(), }), - dataSchema: EventRegistrationSchemas.createGuest, + dataSchema: eventRegistrationSchemas.createGuest, opensTransaction: true, method: async ({ prisma, params, data }) => { await preValidateRegistration(prisma, params.eventId, true) @@ -194,18 +194,18 @@ export namespace EventRegistrationMethods { onWaitingList: updatedEvent.places < updatedEvent._count.eventRegistrations, } }, - }) + }), - export const readMany = serviceMethod({ - authorizer: () => EventRegistrationAuthers.readMany.dynamicFields({}), + readMany: serviceMethod({ + authorizer: () => eventRegistrationAuthers.readMany.dynamicFields({}), paramsSchema: z.object({ eventId: z.number().min(0), skip: z.number().optional(), take: z.number().optional(), - type: z.nativeEnum(EventRegistrationConfig.REGISTRATION_READER_TYPE).optional(), + type: z.nativeEnum(REGISTRATION_READER_TYPE).optional(), }), method: async ({ prisma, params }): Promise => { - const defaultImage = await ImageMethods.readSpecial({ + const defaultImage = await imageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, }) @@ -220,7 +220,7 @@ export namespace EventRegistrationMethods { createdAt: 'asc', }, ...skipTake, - select: EventRegistrationConfig.selection, + select: eventRegistrationSelection, }) return reults.map(registration => ({ @@ -228,15 +228,15 @@ export namespace EventRegistrationMethods { image: registration.user?.image || defaultImage, })) }, - }) + }), - export const readManyDetailed = serviceMethod({ - authorizer: () => EventRegistrationAuthers.readManyDetailed.dynamicFields({}), + readManyDetailed: serviceMethod({ + authorizer: () => eventRegistrationAuthers.readManyDetailed.dynamicFields({}), paramsSchema: z.object({ eventId: z.number().min(0), skip: z.number().optional(), take: z.number().optional(), - type: z.nativeEnum(EventRegistrationConfig.REGISTRATION_READER_TYPE).optional(), + type: z.nativeEnum(REGISTRATION_READER_TYPE).optional(), }), method: async ({ prisma, params }) => { const skiptake = await calculateTakeSkip(prisma, params) @@ -250,17 +250,17 @@ export namespace EventRegistrationMethods { createdAt: 'asc', }, ...skiptake, - include: EventRegistrationConfig.includerDetailed, + include: eventRegistrationIncluderDetailed, }) } - }) + }), - export const updateNotes = serviceMethod({ - authorizer: () => EventRegistrationAuthers.updateRegistrationNotes.dynamicFields({}), + updateNotes: serviceMethod({ + authorizer: () => eventRegistrationAuthers.updateRegistrationNotes.dynamicFields({}), paramsSchema: z.object({ registrationId: z.number().min(0), }), - dataSchema: EventRegistrationSchemas.updateNotes, + dataSchema: eventRegistrationSchemas.updateNotes, method: async ({ prisma, params, data, session }) => { const registration = await prisma.eventRegistration.findUnique({ where: { @@ -289,10 +289,10 @@ export namespace EventRegistrationMethods { }, }) } - }) + }), - export const destroy = serviceMethod({ - authorizer: () => EventRegistrationAuthers.destroy.dynamicFields({}), + destroy: serviceMethod({ + authorizer: () => eventRegistrationAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ registrationId: z.number().min(0), }), @@ -360,7 +360,7 @@ export namespace EventRegistrationMethods { }, include: { user: { - select: UserConfig.filterSelection, + select: userFilterSelection, }, contact: true, } @@ -372,7 +372,7 @@ export namespace EventRegistrationMethods { const message = `Gratulerer! Du har rykket opp fra venteliste på arrangementet ${registration.event.name}.` if (nextInLine.user) { - await NotificationMethods.createSpecial({ + await notificationMethods.createSpecial({ params: { special: 'EVENT_WAITINGLIST_PROMOTION', }, diff --git a/src/services/events/registration/schemas.ts b/src/services/events/registration/schemas.ts index f2971ea92..755ae4332 100644 --- a/src/services/events/registration/schemas.ts +++ b/src/services/events/registration/schemas.ts @@ -1,17 +1,17 @@ import '@pn-server-only' import { z } from 'zod' -export namespace EventRegistrationSchemas { - const fields = z.object({ - note: z.string().max(200, 'Merknader kan ha maks 200 tegn'), - name: z.string().min(2), - }) +const baseSchema = z.object({ + note: z.string().max(200, 'Merknader kan ha maks 200 tegn'), + name: z.string().min(2), +}) - export const updateNotes = fields.pick({ +export const eventRegistrationSchemas = { + updateNotes: baseSchema.pick({ note: true, - }) + }), - export const createGuest = fields.pick({ + createGuest: baseSchema.pick({ name: true, note: true, }) diff --git a/src/services/events/schemas.ts b/src/services/events/schemas.ts index 06d7bf5d6..19008d8aa 100644 --- a/src/services/events/schemas.ts +++ b/src/services/events/schemas.ts @@ -2,32 +2,33 @@ import { zpn } from '@/lib/fields/zpn' import { z } from 'zod' import { EventCanView } from '@prisma/client' -export namespace EventSchemas { - const fields = z.object({ - name: z.string().min(5, 'Navnet må være minst 5 tegn').max(70, 'Navnet må være maks 70 tegn'), - location: z.string().min(2, 'Stedet må være minst 2 tegn'), - order: z.coerce.number().int().optional(), - eventStart: zpn.date({ label: 'Starttid' }), - eventEnd: zpn.date({ label: 'Sluttid' }), - canBeViewdBy: z.nativeEnum(EventCanView), - - takesRegistration: zpn.checkboxOrBoolean({ label: 'Tar påmelding' }), - places: z.coerce.number().int().optional(), - registrationStart: zpn.date({ label: 'Påmelding start' }).optional(), - registrationEnd: zpn.date({ label: 'Påmelding slutt' }).optional(), - - waitingList: zpn.checkboxOrBoolean({ label: 'Venteliste' }), - - tagIds: zpn.numberListCheckboxFriendly({ label: 'tags' }) - }) - - const waitingListRefiner = (data: { - waitingList?: boolean, - takesRegistration?: boolean - }) => (data.takesRegistration || !data.waitingList) - const waitingListMessage = 'Kan ikke ha venteliste uten påmelding' - - export const create = fields.pick({ +const baseSchema = z.object({ + name: z.string().min(5, 'Navnet må være minst 5 tegn').max(70, 'Navnet må være maks 70 tegn'), + location: z.string().min(2, 'Stedet må være minst 2 tegn'), + order: z.coerce.number().int().optional(), + eventStart: zpn.date({ label: 'Starttid' }), + eventEnd: zpn.date({ label: 'Sluttid' }), + canBeViewdBy: z.nativeEnum(EventCanView), + + takesRegistration: zpn.checkboxOrBoolean({ label: 'Tar påmelding' }), + places: z.coerce.number().int().optional(), + registrationStart: zpn.date({ label: 'Påmelding start' }).optional(), + registrationEnd: zpn.date({ label: 'Påmelding slutt' }).optional(), + + waitingList: zpn.checkboxOrBoolean({ label: 'Venteliste' }), + + tagIds: zpn.numberListCheckboxFriendly({ label: 'tags' }) +}) + +const waitingListRefiner = (data: { + waitingList?: boolean, + takesRegistration?: boolean +}) => (data.takesRegistration || !data.waitingList) + +const waitingListMessage = 'Kan ikke ha venteliste uten påmelding' + +export const eventSchemas = { + create: baseSchema.pick({ name: true, location: true, order: true, @@ -40,9 +41,9 @@ export namespace EventSchemas { registrationEnd: true, tagIds: true, waitingList: true, - }).refine(waitingListRefiner, waitingListMessage) + }).refine(waitingListRefiner, waitingListMessage), - export const update = fields.partial().pick({ + update: baseSchema.partial().pick({ name: true, location: true, order: true, @@ -55,5 +56,5 @@ export namespace EventSchemas { registrationEnd: true, tagIds: true, waitingList: true, - }).refine(waitingListRefiner, waitingListMessage) + }).refine(waitingListRefiner, waitingListMessage), } diff --git a/src/services/events/tags/actions.ts b/src/services/events/tags/actions.ts index 479d1863e..740d7d285 100644 --- a/src/services/events/tags/actions.ts +++ b/src/services/events/tags/actions.ts @@ -1,14 +1,14 @@ 'use server' import { action } from '@/services/action' -import { EventTagMethods } from '@/services/events/tags/methods' +import { eventTagMethods } from '@/services/events/tags/methods' -export const createEventTagAction = action(EventTagMethods.create) +export const createEventTagAction = action(eventTagMethods.create) -export const destroyEventTagAction = action(EventTagMethods.destroy) +export const destroyEventTagAction = action(eventTagMethods.destroy) -export const readEventTagsAction = action(EventTagMethods.readAll) -export const readSpecialEventTagAction = action(EventTagMethods.readSpecial) -export const readEventTagAction = action(EventTagMethods.read) +export const readEventTagsAction = action(eventTagMethods.readAll) +export const readSpecialEventTagAction = action(eventTagMethods.readSpecial) +export const readEventTagAction = action(eventTagMethods.read) -export const updateEventTagAction = action(EventTagMethods.update) +export const updateEventTagAction = action(eventTagMethods.update) diff --git a/src/services/events/tags/authers.ts b/src/services/events/tags/authers.ts index 4f9a9ebcf..32d666be2 100644 --- a/src/services/events/tags/authers.ts +++ b/src/services/events/tags/authers.ts @@ -1,11 +1,11 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace EventTagAuthers { - export const create = RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }) - export const readSpecial = RequireNothing.staticFields({}) - export const read = RequireNothing.staticFields({}) - export const readAll = RequireNothing.staticFields({}) - export const update = RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }) - export const destroy = RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }) +export const eventTagAuthers = { + create: RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }), + readSpecial: RequireNothing.staticFields({}), + read: RequireNothing.staticFields({}), + readAll: RequireNothing.staticFields({}), + update: RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }), + destroy: RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }), } diff --git a/src/services/events/tags/config.ts b/src/services/events/tags/config.ts index 6ddd3d0ab..875fe8756 100644 --- a/src/services/events/tags/config.ts +++ b/src/services/events/tags/config.ts @@ -1,19 +1,17 @@ import type { SpecialEventTags } from '@prisma/client' -export namespace EvantTagConfig { - export const specials = { - COMPANY_PRESENTATION: { - name: 'Bedpress', - description: 'Bedpress', - colorR: 255, - colorG: 0, - colorB: 0 - } - } satisfies Record -} +export const specialEventTags = { + COMPANY_PRESENTATION: { + name: 'Bedpress', + description: 'Bedpress', + colorR: 255, + colorG: 0, + colorB: 0 + } +} satisfies Record diff --git a/src/services/events/tags/methods.ts b/src/services/events/tags/methods.ts index 388d653ac..579dbb5f5 100644 --- a/src/services/events/tags/methods.ts +++ b/src/services/events/tags/methods.ts @@ -1,31 +1,31 @@ import '@pn-server-only' -import { EventTagAuthers } from './authers' -import { EvantTagConfig } from './config' -import { EventTagSchemas } from './schemas' -import { EventAuthers } from '@/services/events/authers' +import { eventTagAuthers } from './authers' +import { specialEventTags } from './config' +import { eventTagSchemas } from './schemas' +import { eventAuthers } from '@/services/events/authers' import logger from '@/lib/logger' import { serviceMethod } from '@/services/serviceMethod' import { ServerError } from '@/services/error' import { SpecialEventTags } from '@prisma/client' import { z } from 'zod' -export namespace EventTagMethods { - export const read = serviceMethod({ +export const eventTagMethods = { + read: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - authorizer: () => EventTagAuthers.read.dynamicFields({}), + authorizer: () => eventTagAuthers.read.dynamicFields({}), method: async ({ prisma, params: { id } }) => await prisma.eventTag.findUniqueOrThrow({ where: { id } }) - }) - export const readSpecial = serviceMethod({ + }), + readSpecial: serviceMethod({ paramsSchema: z.object({ special: z.nativeEnum(SpecialEventTags), }), - authorizer: () => EventTagAuthers.readSpecial.dynamicFields({}), + authorizer: () => eventTagAuthers.readSpecial.dynamicFields({}), method: async ({ prisma, params: { special } }) => { const tag = await prisma.eventTag.findUnique({ where: { @@ -37,20 +37,20 @@ export namespace EventTagMethods { return await prisma.eventTag.create({ data: { special, - ...EvantTagConfig.specials[special] + ...specialEventTags[special] } }) } return tag } - }) - export const readAll = serviceMethod({ - authorizer: () => EventTagAuthers.readAll.dynamicFields({}), + }), + readAll: serviceMethod({ + authorizer: () => eventTagAuthers.readAll.dynamicFields({}), method: async ({ prisma }) => await prisma.eventTag.findMany() - }) - export const create = serviceMethod({ - dataSchema: EventTagSchemas.create, - authorizer: () => EventTagAuthers.create.dynamicFields({}), + }), + create: serviceMethod({ + dataSchema: eventTagSchemas.create, + authorizer: () => eventTagAuthers.create.dynamicFields({}), method: async ({ prisma, data: { color, ...data } }) => { const colorR = parseInt(color.slice(1, 3), 16) const colorG = parseInt(color.slice(3, 5), 16) @@ -64,13 +64,13 @@ export namespace EventTagMethods { } }) } - }) - export const update = serviceMethod({ + }), + update: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - dataSchema: EventTagSchemas.update, - authorizer: () => EventAuthers.update.dynamicFields({}), + dataSchema: eventTagSchemas.update, + authorizer: () => eventAuthers.update.dynamicFields({}), method: async ({ prisma, params: { id }, data: { color, ...data } }) => { const colorR = color ? parseInt(color.slice(1, 3), 16) : undefined const colorG = color ? parseInt(color.slice(3, 5), 16) : undefined @@ -87,12 +87,12 @@ export namespace EventTagMethods { } }) } - }) - export const destroy = serviceMethod({ + }), + destroy: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - authorizer: () => EventAuthers.destroy.dynamicFields({}), + authorizer: () => eventAuthers.destroy.dynamicFields({}), method: async ({ prisma, params }) => { const tag = await prisma.eventTag.findUniqueOrThrow({ where: { id: params.id } @@ -104,5 +104,5 @@ export namespace EventTagMethods { where: { id: params.id } }) } - }) + }), } diff --git a/src/services/events/tags/schemas.ts b/src/services/events/tags/schemas.ts index 78ed36871..104021df2 100644 --- a/src/services/events/tags/schemas.ts +++ b/src/services/events/tags/schemas.ts @@ -1,21 +1,22 @@ import { z } from 'zod' -export namespace EventTagSchemas { - const fields = z.object({ - name: z.string().min(3, 'Navn må ha minst 3 tegn').max(30, 'Navn kan ha maks 30 tegn').trim(), - description: z.string().max(200, 'Beskrivelse kan ha maks 200 tegn').trim(), - color: z.string().regex( - /^#[0-9A-Fa-f]{6}$/, 'Farge må være en gyldig hex-farge' - ).transform(value => value.toUpperCase()), - }) - export const create = fields.pick({ +const baseSchemas = z.object({ + name: z.string().min(3, 'Navn må ha minst 3 tegn').max(30, 'Navn kan ha maks 30 tegn').trim(), + description: z.string().max(200, 'Beskrivelse kan ha maks 200 tegn').trim(), + color: z.string().regex( + /^#[0-9A-Fa-f]{6}$/, 'Farge må være en gyldig hex-farge' + ).transform(value => value.toUpperCase()), +}) + +export const eventTagSchemas = { + create: baseSchemas.pick({ name: true, description: true, color: true, - }) - export const update = fields.partial().pick({ + }), + update: baseSchemas.partial().pick({ name: true, description: true, color: true, - }) + }), } diff --git a/src/services/groups/actions.ts b/src/services/groups/actions.ts index 1ba6e20c3..d226b5771 100644 --- a/src/services/groups/actions.ts +++ b/src/services/groups/actions.ts @@ -1,9 +1,9 @@ 'use server' import { action } from '@/services/action' -import { GroupMethods } from '@/services/groups/methods' +import { groupMethods } from '@/services/groups/methods' -export const readGroupsAction = action(GroupMethods.readGroups) -export const readGroupExpandedAction = action(GroupMethods.readGroupExpanded) -export const readGroupsExpandedAction = action(GroupMethods.readGroupsExpanded) -export const readGroupsStructuredAction = action(GroupMethods.readGroupsStructured) +export const readGroupsAction = action(groupMethods.readGroups) +export const readGroupExpandedAction = action(groupMethods.readGroupExpanded) +export const readGroupsExpandedAction = action(groupMethods.readGroupsExpanded) +export const readGroupsStructuredAction = action(groupMethods.readGroupsStructured) diff --git a/src/services/groups/authers.ts b/src/services/groups/authers.ts index 578825ca4..0dddbedf8 100644 --- a/src/services/groups/authers.ts +++ b/src/services/groups/authers.ts @@ -1,5 +1,5 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace GroupAuthers { - export const read = RequirePermission.staticFields({ permission: 'GROUP_READ' }) +export const groupAuthers = { + read: RequirePermission.staticFields({ permission: 'GROUP_READ' }), } diff --git a/src/services/groups/committees/actions.ts b/src/services/groups/committees/actions.ts index f841dffa6..0ac4436b6 100644 --- a/src/services/groups/committees/actions.ts +++ b/src/services/groups/committees/actions.ts @@ -4,7 +4,7 @@ import { action } from '@/services/action' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createCommittee } from '@/services/groups/committees/create' -import { CommitteeMethods } from '@/services/groups/committees/methods' +import { committeeMethods } from '@/services/groups/committees/methods' import { updateCommittee } from '@/services/groups/committees/update' import { createCommitteeValidation, updateCommitteeValidation } from '@/services/groups/committees/validation' import type { ExpandedCommittee } from '@/services/groups/committees/Types' @@ -27,11 +27,11 @@ export async function createCommitteeAction( return await safeServerCall(() => createCommittee(parse.data)) } -export const readCommitteesAction = action(CommitteeMethods.readCommittees) -export const readCommitteeAction = action(CommitteeMethods.readCommittee) -export const readCommitteeArticleAction = action(CommitteeMethods.readCommitteArticle) -export const readCommitteeParagraphAction = action(CommitteeMethods.readCommitteeParagraph) -export const readCommitteeMembersAction = action(CommitteeMethods.readCommitteeMembers) +export const readCommitteesAction = action(committeeMethods.readCommittees) +export const readCommitteeAction = action(committeeMethods.readCommittee) +export const readCommitteeArticleAction = action(committeeMethods.readCommitteArticle) +export const readCommitteeParagraphAction = action(committeeMethods.readCommitteeParagraph) +export const readCommitteeMembersAction = action(committeeMethods.readCommitteeMembers) export async function updateCommitteeAction( id: number, diff --git a/src/services/groups/committees/authers.ts b/src/services/groups/committees/authers.ts index 20b6fad4e..8d07f05de 100644 --- a/src/services/groups/committees/authers.ts +++ b/src/services/groups/committees/authers.ts @@ -1,5 +1,5 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace CommitteeAuthers { - export const read = RequirePermission.staticFields({ permission: 'COMMITTEE_READ' }) +export const committeeAuthers = { + read: RequirePermission.staticFields({ permission: 'COMMITTEE_READ' }), } diff --git a/src/services/groups/committees/config.ts b/src/services/groups/committees/config.ts index 2f7161646..844f1f3c7 100644 --- a/src/services/groups/committees/config.ts +++ b/src/services/groups/committees/config.ts @@ -1,46 +1,42 @@ -import { UserConfig } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/config' import type { Prisma } from '@prisma/client' - -export namespace CommitteeConfig { - - export const committeeLogoIncluder = { - logoImage: { - include: { - image: true - } +export const committeeLogoIncluder = { + logoImage: { + include: { + image: true } - } satisfies Prisma.CommitteeInclude + } +} satisfies Prisma.CommitteeInclude - export const membershipIncluder = { - user: { - select: { - ...UserConfig.filterSelection, - image: true - } +export const membershipIncluder = { + user: { + select: { + ...userFilterSelection, + image: true } - } satisfies Prisma.MembershipInclude + } +} satisfies Prisma.MembershipInclude - export const committeeExpandedIncluder = { - ...committeeLogoIncluder, - committeeArticle: { - include: { - coverImage: { - include: { - image: true, - } +export const committeeExpandedIncluder = { + ...committeeLogoIncluder, + committeeArticle: { + include: { + coverImage: { + include: { + image: true, } } - }, - group: { - include: { - memberships: { - include: membershipIncluder, - where: { - active: true, - } + } + }, + group: { + include: { + memberships: { + include: membershipIncluder, + where: { + active: true, } } } - } satisfies Prisma.CommitteeInclude -} + } +} satisfies Prisma.CommitteeInclude diff --git a/src/services/groups/committees/create.ts b/src/services/groups/committees/create.ts index ca082c87f..7197151a3 100644 --- a/src/services/groups/committees/create.ts +++ b/src/services/groups/committees/create.ts @@ -4,7 +4,7 @@ import { prismaCall } from '@/services/prismaCall' import { createArticle } from '@/services/cms/articles/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createCmsParagraph } from '@/services/cms/paragraphs/create' -import { ImageMethods } from '@/services/images/methods' +import { imageMethods } from '@/services/images/methods' import { GroupType } from '@prisma/client' import type { ExpandedCommittee } from './Types' import type { CreateCommitteeTypes } from './validation' @@ -13,7 +13,7 @@ export async function createCommittee(rawdata: CreateCommitteeTypes['Detailed']) const { name, shortName, logoImageId } = createCommitteeValidation.detailedValidate(rawdata) let defaultLogoImageId: number if (!logoImageId) { - defaultLogoImageId = await ImageMethods.readSpecial({ + defaultLogoImageId = await imageMethods.readSpecial({ params: { special: 'DAFAULT_COMMITTEE_LOGO' }, //TODO: pass session }).then(res => res.id) } diff --git a/src/services/groups/committees/methods.ts b/src/services/groups/committees/methods.ts index e3b63030d..12b039b60 100644 --- a/src/services/groups/committees/methods.ts +++ b/src/services/groups/committees/methods.ts @@ -1,35 +1,35 @@ -import { CommitteeAuthers } from './authers' -import { CommitteeConfig } from './config' +import { committeeAuthers } from './authers' +import { committeeExpandedIncluder, committeeLogoIncluder, membershipIncluder } from './config' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' -import { ImageMethods } from '@/services/images/methods' import { serviceMethod } from '@/services/serviceMethod' import { articleRealtionsIncluder } from '@/cms/articles/ConfigVars' +import { imageMethods } from '@/services/images/methods' import { z } from 'zod' -export namespace CommitteeMethods { +export const committeeMethods = { - export const readCommittees = serviceMethod({ - authorizer: () => CommitteeAuthers.read.dynamicFields({}), + readCommittees: serviceMethod({ + authorizer: () => committeeAuthers.read.dynamicFields({}), method: async ({ prisma }) => prisma.committee.findMany({ - include: CommitteeConfig.committeeLogoIncluder, + include: committeeLogoIncluder, }) - }) + }), - export const readCommittee = serviceMethod({ - authorizer: () => CommitteeAuthers.read.dynamicFields({}), + readCommittee: serviceMethod({ + authorizer: () => committeeAuthers.read.dynamicFields({}), paramsSchema: z.union([ z.object({ id: z.number() }), z.object({ shortName: z.string() }) ]), method: async ({ prisma, params }) => { - const defaultImage = await ImageMethods.readSpecial({ + const defaultImage = await imageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, bypassAuth: true }) const result = await prisma.committee.findUniqueOrThrow({ where: params, - include: CommitteeConfig.committeeExpandedIncluder + include: committeeExpandedIncluder, }) return { @@ -47,10 +47,10 @@ export namespace CommitteeMethods { } } } - }) + }), - export const readCommitteArticle = serviceMethod({ - authorizer: () => CommitteeAuthers.read.dynamicFields({}), + readCommitteArticle: serviceMethod({ + authorizer: () => committeeAuthers.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), }), @@ -62,9 +62,9 @@ export namespace CommitteeMethods { } } })).committeeArticle - }) + }), - export const readCommitteesFromGroupIds = serviceMethod({ + readCommitteesFromGroupIds: serviceMethod({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ ids: z.number().int().array() @@ -75,12 +75,12 @@ export namespace CommitteeMethods { in: params.ids } }, - include: CommitteeConfig.committeeLogoIncluder, + include: committeeLogoIncluder, }) - }) + }), - export const readCommitteeParagraph = serviceMethod({ - authorizer: () => CommitteeAuthers.read.dynamicFields({}), + readCommitteeParagraph: serviceMethod({ + authorizer: () => committeeAuthers.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), }), @@ -90,16 +90,16 @@ export namespace CommitteeMethods { paragraph: true, } })).paragraph - }) + }), - export const readCommitteeMembers = serviceMethod({ - authorizer: () => CommitteeAuthers.read.dynamicFields({}), + readCommitteeMembers: serviceMethod({ + authorizer: () => committeeAuthers.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), active: z.boolean().optional(), }), method: async ({ prisma, params }) => { - const defaultImage = await ImageMethods.readSpecial({ + const defaultImage = await imageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, }) @@ -112,7 +112,7 @@ export namespace CommitteeMethods { group: { select: { memberships: { - include: CommitteeConfig.membershipIncluder, + include: membershipIncluder, where: { active: params.active } @@ -131,5 +131,5 @@ export namespace CommitteeMethods { } })) } - }) + }), } diff --git a/src/services/groups/committees/read.ts b/src/services/groups/committees/read.ts index 1e5fb474b..df6c7b356 100644 --- a/src/services/groups/committees/read.ts +++ b/src/services/groups/committees/read.ts @@ -2,8 +2,8 @@ import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { articleRealtionsIncluder } from '@/services/cms/articles/ConfigVars' -import { UserConfig } from '@/services/users/config' -import { ImageMethods } from '@/services/images/methods' +import { imageMethods } from '@/services/images/methods' +import { userFilterSelection } from '@/services/users/config' import type { ExpandedArticle } from '@/services/cms/articles/Types' import type { CmsParagraph } from '@prisma/client' import type { ExpandedCommittee, ExpandedCommitteeWithCover } from './Types' @@ -90,7 +90,7 @@ export async function readCommitteeParagraph(shortName: string) : Promise res.id) } diff --git a/src/services/groups/config.ts b/src/services/groups/config.ts index a4c619a6d..83bfe7158 100644 --- a/src/services/groups/config.ts +++ b/src/services/groups/config.ts @@ -4,7 +4,7 @@ import type { GroupTypeInfo } from './Types' /** * A object that describes the different group types in a friendly way */ -export const GroupTypesConfig = { +export const groupTypesConfig = { OMEGA_MEMBERSHIP_GROUP: { name: 'Medlemsgruppe', namePlural: 'Medlemsgrupper', diff --git a/src/services/groups/interestGroups/actions.ts b/src/services/groups/interestGroups/actions.ts index 4c8faa53d..cbb1177de 100644 --- a/src/services/groups/interestGroups/actions.ts +++ b/src/services/groups/interestGroups/actions.ts @@ -1,12 +1,12 @@ 'use server' import { action } from '@/services/action' -import { InterestGroupMethods } from '@/services/groups/interestGroups/methods' +import { interestGroupMethods } from '@/services/groups/interestGroups/methods' -export const createInterestGroupAction = action(InterestGroupMethods.create) +export const createInterestGroupAction = action(interestGroupMethods.create) -export const destroyInterestGroupAction = action(InterestGroupMethods.destroy) +export const destroyInterestGroupAction = action(interestGroupMethods.destroy) -export const readInterestGroupsAction = action(InterestGroupMethods.readMany) +export const readInterestGroupsAction = action(interestGroupMethods.readMany) -export const updateInterestGroupAction = action(InterestGroupMethods.update) +export const updateInterestGroupAction = action(interestGroupMethods.update) diff --git a/src/services/groups/interestGroups/authers.ts b/src/services/groups/interestGroups/authers.ts index 4ae3bb7bb..c8d01f33f 100644 --- a/src/services/groups/interestGroups/authers.ts +++ b/src/services/groups/interestGroups/authers.ts @@ -1,10 +1,10 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import { RequirePermissionOrGroupAdmin } from '@/auth/auther/RequirePermissionOrGroupAdmin' -export namespace InterestGroupAuthers { - export const create = RequirePermission.staticFields({ permission: 'INTEREST_GROUP_ADMIN' }) - export const read = RequirePermission.staticFields({ permission: 'INTEREST_GROUP_READ' }) - export const readMany = RequirePermission.staticFields({ permission: 'INTEREST_GROUP_READ' }) - export const update = RequirePermissionOrGroupAdmin.staticFields({ permission: 'INTEREST_GROUP_ADMIN' }) - export const destroy = RequirePermission.staticFields({ permission: 'INTEREST_GROUP_ADMIN' }) +export const interestGroupAuthers = { + create: RequirePermission.staticFields({ permission: 'INTEREST_GROUP_ADMIN' }), + read: RequirePermission.staticFields({ permission: 'INTEREST_GROUP_READ' }), + readMany: RequirePermission.staticFields({ permission: 'INTEREST_GROUP_READ' }), + update: RequirePermissionOrGroupAdmin.staticFields({ permission: 'INTEREST_GROUP_ADMIN' }), + destroy: RequirePermission.staticFields({ permission: 'INTEREST_GROUP_ADMIN' }), } diff --git a/src/services/groups/interestGroups/methods.ts b/src/services/groups/interestGroups/methods.ts index b081f5e20..9d7efdace 100644 --- a/src/services/groups/interestGroups/methods.ts +++ b/src/services/groups/interestGroups/methods.ts @@ -1,16 +1,16 @@ import '@pn-server-only' -import { InterestGroupAuthers } from './authers' -import { InterestGroupSchemas } from './schemas' +import { interestGroupAuthers } from './authers' +import { interestGroupSchemas } from './schemas' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { serviceMethod } from '@/services/serviceMethod' import { articleSectionsRealtionsIncluder } from '@/services/cms/articleSections/ConfigVars' import { z } from 'zod' import type { ExpandedInterestGroup } from './Types' -export namespace InterestGroupMethods { - export const create = serviceMethod({ - dataSchema: InterestGroupSchemas.create, - authorizer: () => InterestGroupAuthers.create.dynamicFields({}), +export const interestGroupMethods = { + create: serviceMethod({ + dataSchema: interestGroupSchemas.create, + authorizer: () => interestGroupAuthers.create.dynamicFields({}), method: async ({ prisma, data }) => { const { order } = await readCurrentOmegaOrder() @@ -33,10 +33,10 @@ export namespace InterestGroupMethods { } }) } - }) + }), - export const readMany = serviceMethod({ - authorizer: () => InterestGroupAuthers.readMany.dynamicFields({}), + readMany: serviceMethod({ + authorizer: () => interestGroupAuthers.readMany.dynamicFields({}), method: async ({ prisma }): Promise => prisma.interestGroup.findMany({ include: { articleSection: { @@ -48,14 +48,14 @@ export namespace InterestGroupMethods { { id: 'asc' }, ] }) - }) + }), - export const read = serviceMethod({ + read: serviceMethod({ paramsSchema: z.object({ id: z.number().optional(), shortName: z.string().optional(), }), - authorizer: () => InterestGroupAuthers.read.dynamicFields({}), + authorizer: () => interestGroupAuthers.read.dynamicFields({}), method: async ({ prisma, params: { id, shortName } }) => await prisma.interestGroup.findUniqueOrThrow({ where: { id, @@ -67,32 +67,34 @@ export namespace InterestGroupMethods { }, } }) - }) + }), - export const update = serviceMethod({ + update: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - dataSchema: InterestGroupSchemas.update, - authorizer: async ({ params }) => InterestGroupAuthers.update.dynamicFields({ - groupId: ( - await read({ - params: { id: params.id }, - bypassAuth: true, - }) - ).groupId, - }), + dataSchema: interestGroupSchemas.update, + authorizer: async ({ prisma, params }) => { + const { groupId } = await prisma.interestGroup.findUniqueOrThrow({ + where: { id: params.id }, + select: { groupId: true }, + }) + + return interestGroupAuthers.update.dynamicFields({ + groupId, + }) + }, method: async ({ prisma, params: { id }, data }) => prisma.interestGroup.update({ where: { id }, data, }), - }) + }), - export const destroy = serviceMethod({ + destroy: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - authorizer: () => InterestGroupAuthers.destroy.dynamicFields({}), + authorizer: () => interestGroupAuthers.destroy.dynamicFields({}), opensTransaction: true, method: async ({ prisma, params: { id } }) => { await prisma.$transaction(async tx => { @@ -104,5 +106,5 @@ export namespace InterestGroupMethods { }) }) } - }) + }), } diff --git a/src/services/groups/interestGroups/schemas.ts b/src/services/groups/interestGroups/schemas.ts index 9c044de54..c0ffcd08a 100644 --- a/src/services/groups/interestGroups/schemas.ts +++ b/src/services/groups/interestGroups/schemas.ts @@ -1,26 +1,24 @@ import { z } from 'zod' -export namespace InterestGroupSchemas { - const fields = z.object({ - name: z.string().min( - 3, 'Navn må ha minst 3 tegn' - ).max( - 30, 'Navn kan ha maks 30 tegn' - ).trim(), - shortName: z.string().min( - 3, 'Kortnavn må ha minst 3 tegn' - ).max( - 10, 'Kortnavn kan ha maks 10 tegn' - ).trim(), - }) +const baseSchema = z.object({ + name: z.string() + .min(3, 'Navn må ha minst 3 tegn') + .max(30, 'Navn kan ha maks 30 tegn') + .trim(), + shortName: z.string() + .min(3, 'Kortnavn må ha minst 3 tegn') + .max(10, 'Kortnavn kan ha maks 10 tegn') + .trim(), +}) - export const create = fields.pick({ +export const interestGroupSchemas = { + create: baseSchema.pick({ name: true, shortName: true, - }) + }), - export const update = fields.partial().pick({ + update: baseSchema.partial().pick({ name: true, shortName: true, - }) + }), } diff --git a/src/services/groups/memberships/create.ts b/src/services/groups/memberships/create.ts index f91913d72..bcbf47009 100644 --- a/src/services/groups/memberships/create.ts +++ b/src/services/groups/memberships/create.ts @@ -5,7 +5,7 @@ import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { prisma } from '@/prisma/client' import { invalidateManyUserSessionData, invalidateOneUserSessionData } from '@/services/auth/invalidateSession' -import { GroupMethods } from '@/services/groups/methods' +import { groupMethods } from '@/services/groups/methods' import type { ExpandedMembership } from './Types' export async function createMembershipForUser( @@ -18,7 +18,7 @@ export async function createMembershipForUser( throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ + const order = orderArg ?? await groupMethods.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId, @@ -64,7 +64,7 @@ export async function createMembershipsForGroup( if (!await canEasilyManageMembershipOfGroup(groupId)) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ + const order = orderArg ?? await groupMethods.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId, @@ -111,7 +111,7 @@ export async function createMembershipsForUser( if (!await canEasilyManageMembershipOfGroups(data.map(group => group.groupId))) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const ordersMap = await GroupMethods.readCurrentGroupOrders({ + const ordersMap = await groupMethods.readCurrentGroupOrders({ bypassAuth: true, params: { ids: data.map(group => group.groupId) diff --git a/src/services/groups/memberships/destroy.ts b/src/services/groups/memberships/destroy.ts index c07813bc9..99545a2c4 100644 --- a/src/services/groups/memberships/destroy.ts +++ b/src/services/groups/memberships/destroy.ts @@ -4,7 +4,7 @@ import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { prisma } from '@/prisma/client' import { invalidateManyUserSessionData, invalidateOneUserSessionData } from '@/services/auth/invalidateSession' -import { GroupMethods } from '@/services/groups/methods' +import { groupMethods } from '@/services/groups/methods' import type { ExpandedMembership } from './Types' export async function destoryMembershipOfUser({ @@ -19,7 +19,7 @@ export async function destoryMembershipOfUser({ if (!await canEasilyManageMembershipOfGroup(groupId)) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ + const order = orderArg ?? await groupMethods.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId @@ -47,7 +47,7 @@ export async function destroyMembershipOfUsers( if (!await canEasilyManageMembershipOfGroup(groupId)) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await GroupMethods.readCurrentGroupOrder({ + const order = orderArg ?? await groupMethods.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId, diff --git a/src/services/groups/memberships/update.ts b/src/services/groups/memberships/update.ts index d3f842453..943d117a4 100644 --- a/src/services/groups/memberships/update.ts +++ b/src/services/groups/memberships/update.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' import { prisma } from '@/prisma/client' import { invalidateOneUserSessionData } from '@/services/auth/invalidateSession' -import { GroupMethods } from '@/services/groups/methods' +import { groupMethods } from '@/services/groups/methods' import type { ExpandedMembership } from './Types' export async function updateMembership({ @@ -18,7 +18,7 @@ export async function updateMembership({ active?: boolean }): Promise { const order = (orderArg && typeof orderArg === 'number') ? orderArg : ( - await GroupMethods.readCurrentGroupOrder({ + await groupMethods.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId diff --git a/src/services/groups/methods.ts b/src/services/groups/methods.ts index e18a36dbc..0b8ddeef7 100644 --- a/src/services/groups/methods.ts +++ b/src/services/groups/methods.ts @@ -1,7 +1,7 @@ import '@pn-server-only' -import { groupsExpandedIncluder, GroupTypesConfig, OmegaMembershipLevelConfig, readGroupsOfUserIncluder } from './config' -import { GroupAuthers } from './authers' -import { UserConfig } from '@/services/users/config' +import { groupsExpandedIncluder, groupTypesConfig, OmegaMembershipLevelConfig, readGroupsOfUserIncluder } from './config' +import { groupAuthers } from './authers' +import { userFilterSelection } from '@/services/users/config' import { ServerError } from '@/services/error' import { serviceMethod } from '@/services/serviceMethod' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' @@ -187,14 +187,13 @@ export function checkGroupValidity< } } -export namespace GroupMethods { - - export const readGroups = serviceMethod({ - authorizer: () => GroupAuthers.read.dynamicFields({}), +export const groupMethods = { + readGroups: serviceMethod({ + authorizer: () => groupAuthers.read.dynamicFields({}), method: async ({ prisma }) => prisma.group.findMany() - }) + }), - export const readCurrentGroupOrder = serviceMethod({ + readCurrentGroupOrder: serviceMethod({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ id: z.number(), @@ -207,9 +206,9 @@ export namespace GroupMethods { order: true, } })).order - }) + }), - export const readCurrentGroupOrders = serviceMethod({ + readCurrentGroupOrders: serviceMethod({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ ids: z.number().array(), @@ -225,9 +224,9 @@ export namespace GroupMethods { order: true, } }) - }) + }), - export const readGroup = serviceMethod({ + readGroup: serviceMethod({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ id: z.number(), @@ -237,10 +236,10 @@ export namespace GroupMethods { id: params.id, }, }) - }) + }), - export const readGroupExpanded = serviceMethod({ - authorizer: () => GroupAuthers.read.dynamicFields({}), + readGroupExpanded: serviceMethod({ + authorizer: () => groupAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -253,10 +252,10 @@ export namespace GroupMethods { }).then(checkGroupValidity).then(grp => ({ ...grp, membershipsToInferFirstOrder: grp.memberships })) return expandGroup(group, prisma) } - }) + }), - export const readGroupsExpanded = serviceMethod({ - authorizer: () => GroupAuthers.read.dynamicFields({}), + readGroupsExpanded: serviceMethod({ + authorizer: () => groupAuthers.read.dynamicFields({}), method: async ({ prisma }) => { const groups = (await prisma.group.findMany({ include: groupsExpandedIncluder, @@ -264,39 +263,39 @@ export namespace GroupMethods { return await Promise.all(groups.map(group => expandGroup(group, prisma))) } - }) + }), - export const readGroupsStructured = serviceMethod({ - authorizer: () => GroupAuthers.read.dynamicFields({}), + readGroupsStructured: serviceMethod({ + authorizer: () => groupAuthers.read.dynamicFields({}), method: async () => { const groupsStructured: GroupsStructured = { CLASS: { - ...GroupTypesConfig.CLASS, + ...groupTypesConfig.CLASS, groups: [], }, COMMITTEE: { - ...GroupTypesConfig.COMMITTEE, + ...groupTypesConfig.COMMITTEE, groups: [], }, INTEREST_GROUP: { - ...GroupTypesConfig.INTEREST_GROUP, + ...groupTypesConfig.INTEREST_GROUP, groups: [], }, MANUAL_GROUP: { - ...GroupTypesConfig.MANUAL_GROUP, + ...groupTypesConfig.MANUAL_GROUP, groups: [], }, OMEGA_MEMBERSHIP_GROUP: { - ...GroupTypesConfig.OMEGA_MEMBERSHIP_GROUP, + ...groupTypesConfig.OMEGA_MEMBERSHIP_GROUP, groups: [], }, STUDY_PROGRAMME: { - ...GroupTypesConfig.STUDY_PROGRAMME, + ...groupTypesConfig.STUDY_PROGRAMME, groups: [], }, } satisfies GroupsStructured - const groupExpanded = await readGroupsExpanded({ bypassAuth: true }) + const groupExpanded = await groupMethods.readGroupsExpanded({ bypassAuth: true }) groupExpanded.forEach(group => { groupsStructured[group.groupType].groups.push(group) @@ -304,9 +303,9 @@ export namespace GroupMethods { return groupsStructured } - }) + }), - export const readUsersOfGroups = serviceMethod({ + readUsersOfGroups: serviceMethod({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ groups: z.array(z.object({ @@ -324,16 +323,16 @@ export namespace GroupMethods { }, select: { user: { - select: UserConfig.filterSelection, + select: userFilterSelection, } } }) return memberships.map(({ user }) => user) } - }) + }), - export const readGroupsOfUser = serviceMethod({ + readGroupsOfUser: serviceMethod({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ userId: z.number(), @@ -354,5 +353,5 @@ export namespace GroupMethods { return groups }, - }) + }), } diff --git a/src/services/images/actions.ts b/src/services/images/actions.ts index 4ffe7d95b..972d10fb2 100644 --- a/src/services/images/actions.ts +++ b/src/services/images/actions.ts @@ -1,24 +1,24 @@ 'use server' import { action } from '@/services/action' -import { ImageMethods } from '@/services/images/methods' +import { imageMethods } from '@/services/images/methods' -export const createImageAction = action(ImageMethods.create) -export const createImagesAction = action(ImageMethods.createMany) +export const createImageAction = action(imageMethods.create) +export const createImagesAction = action(imageMethods.createMany) -export const destroyImageAction = action(ImageMethods.destroy) +export const destroyImageAction = action(imageMethods.destroy) /** * Read one image. */ -export const readImageAction = action(ImageMethods.read) +export const readImageAction = action(imageMethods.read) /** * Read one page of images. */ -export const readImagesPageAction = action(ImageMethods.readPage) +export const readImagesPageAction = action(imageMethods.readPage) /** * Read one special image. */ -export const readSpecialImageAction = action(ImageMethods.readSpecial) +export const readSpecialImageAction = action(imageMethods.readSpecial) -export const updateImageAction = action(ImageMethods.update) +export const updateImageAction = action(imageMethods.update) diff --git a/src/services/images/authers.ts b/src/services/images/authers.ts index df564e683..6dcea3636 100644 --- a/src/services/images/authers.ts +++ b/src/services/images/authers.ts @@ -1,13 +1,13 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' //TODO: Implement proper authers -export namespace ImageAuthers { - export const create = RequireNothing.staticFields({}) - export const createMany = RequireNothing.staticFields({}) - export const createSourcelessImage = RequireNothing.staticFields({}) - export const read = RequireNothing.staticFields({}) - export const readPage = RequireNothing.staticFields({}) - export const readSpecial = RequireNothing.staticFields({}) - export const update = RequireNothing.staticFields({}) - export const destroy = RequireNothing.staticFields({}) +export const imageAuthers = { + create: RequireNothing.staticFields({}), + createMany: RequireNothing.staticFields({}), + createSourcelessImage: RequireNothing.staticFields({}), + read: RequireNothing.staticFields({}), + readPage: RequireNothing.staticFields({}), + readSpecial: RequireNothing.staticFields({}), + update: RequireNothing.staticFields({}), + destroy: RequireNothing.staticFields({}), } diff --git a/src/services/images/collections/read.ts b/src/services/images/collections/read.ts index c92a618e5..5fe5ab2c7 100644 --- a/src/services/images/collections/read.ts +++ b/src/services/images/collections/read.ts @@ -6,7 +6,7 @@ import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { readSpecialVisibility } from '@/services/visibility/read' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' -import { ImageMethods } from '@/services/images/methods' +import { imageMethods } from '@/services/images/methods' import type { SpecialCollection, ImageCollection, Image } from '@prisma/client' import type { ExpandedImageCollection, @@ -68,7 +68,7 @@ export async function readImageCollectionsPage( ...cursorPageingSelection(page) })) - const lensCamera = await ImageMethods.readSpecial({ + const lensCamera = await imageMethods.readSpecial({ params: { special: 'DEFAULT_IMAGE_COLLECTION_COVER' }, diff --git a/src/services/images/config.ts b/src/services/images/config.ts index c216c56ab..f39a18619 100644 --- a/src/services/images/config.ts +++ b/src/services/images/config.ts @@ -1,20 +1,18 @@ -export namespace ImageConfig { - export const maxFileSize = 100 * 1024 * 1024 // 100mb +export const maxImageFileSize = 100 * 1024 * 1024 // 100mb - export const maxNumberInOneBatch = 10 +export const maxImageCountInOneBatch = 10 - export const sizes = { - small: 180, - medium: 360, - large: 720, - } - - export const avifConvertionOptions = { - quality: 50, - lossless: false, - speed: 8, // default is 5 - chromaSubsampling: '4:2:0', - } +export const imageSizes = { + small: 180, + medium: 360, + large: 720, +} - export const allowedExtUpload = ['png', 'jpg', 'jpeg', 'heic', 'avif', 'webp'] +export const avifConvertionOptions = { + quality: 50, + lossless: false, + speed: 8, // default is 5 + chromaSubsampling: '4:2:0', } + +export const allowedExtensions = ['png', 'jpg', 'jpeg', 'heic', 'avif', 'webp'] diff --git a/src/services/images/methods.ts b/src/services/images/methods.ts index ec8222a7b..e9071f962 100644 --- a/src/services/images/methods.ts +++ b/src/services/images/methods.ts @@ -1,8 +1,8 @@ import '@pn-server-only' import { readSpecialImageCollection } from './collections/read' -import { ImageConfig } from './config' -import { ImageAuthers } from './authers' -import { ImageSchemas } from './schemas' +import { imageAuthers } from './authers' +import { imageSchemas } from './schemas' +import { allowedExtensions, avifConvertionOptions, imageSizes } from './config' import { ServerError } from '@/services/error' import { createFile } from '@/services/store/createFile' import logger from '@/lib/logger' @@ -13,7 +13,62 @@ import sharp from 'sharp' import { SpecialImage } from '@prisma/client' import { z } from 'zod' -export namespace ImageMethods { +/** + * Creates one image from a file. + * @param file - The file to create the image from + * @param allowedExt - The allowed extensions for the file + * @param size - The size to resize the image to + * @returns + */ +async function createOneInStore(file: File, allowedExt: string[], size: number) { + const ret = await createFile(file, 'images', allowedExt, async (buffer) => await sharp(buffer).resize(size, size, { + fit: sharp.fit.inside, + withoutEnlargement: true + }).toBuffer()) + return ret +} + +/** + * WARNING: This function should only be used in extreme cases, Therefore it is not exported. + * Creates bad image this should really only happen in worst case scenario + * where the server has lost a image and needs to be replaced with a bad image. + * A bad image is an image that has no correct fsLocation attributes. + * @param name - the name of the image + * @param config - the config for the image (special) + */ +const createSourceless = serviceMethod({ + authorizer: () => imageAuthers.createSourcelessImage.dynamicFields({}), + paramsSchema: z.object({ + name: z.string(), + special: z.nativeEnum(SpecialImage), + }), + method: async ({ prisma, params: { name, special } }) => { + const standardCollection = await readSpecialImageCollection('STANDARDIMAGES') + logger.warn(` + creating a bad image, Something has caused the server to lose a neccesary image. + It was replaced with an image model with no correct fsLocation atrributes. + `) + return await prisma.image.create({ + data: { + name, + special, + fsLocationOriginal: 'not_found', + fsLocationMediumSize: 'not_found', + fsLocationSmallSize: 'not_found', + fsLocationLargeSize: 'not_found', + extOriginal: 'jpg', + alt: 'not found', + collection: { + connect: { + id: standardCollection.id + } + } + }, + }) + } +}) + +export const imageMethods = { /** * Creates an image. * The method will resize the image to the correct sizes and save it to the store. @@ -21,23 +76,23 @@ export namespace ImageMethods { * All images are saved as avif (except the original). * @param collectionId - The id of the collection to add the image to */ - export const create = serviceMethod({ - authorizer: () => ImageAuthers.create.dynamicFields({}), + create: serviceMethod({ + authorizer: () => imageAuthers.create.dynamicFields({}), paramsSchema: z.object({ collectionId: z.number(), }), - dataSchema: ImageSchemas.create, + dataSchema: imageSchemas.create, method: async ({ prisma, params: { collectionId }, data }) => { const { file, ...meta } = data const buffer = Buffer.from(await file.arrayBuffer()) - const avifBuffer = await sharp(buffer).toFormat('avif').avif(ImageConfig.avifConvertionOptions).toBuffer() + const avifBuffer = await sharp(buffer).toFormat('avif').avif(avifConvertionOptions).toBuffer() const avifFile = new File([avifBuffer], 'image.avif', { type: 'image/avif' }) const uploadPromises = [ - createOneInStore(avifFile, ['avif'], ImageConfig.sizes.small), - createOneInStore(avifFile, ['avif'], ImageConfig.sizes.medium), - createOneInStore(avifFile, ['avif'], ImageConfig.sizes.large), - createFile(file, 'images', [...ImageConfig.allowedExtUpload]), + createOneInStore(avifFile, ['avif'], imageSizes.small), + createOneInStore(avifFile, ['avif'], imageSizes.medium), + createOneInStore(avifFile, ['avif'], imageSizes.large), + createFile(file, 'images', [...allowedExtensions]), ] const [smallSize, mediumSize, largeSize, original] = await Promise.all(uploadPromises) @@ -65,18 +120,18 @@ export namespace ImageMethods { } }) } - }) + }), /** * Creates many images from files. * The method will resize the images to the correct sizes and save them to the store. */ - export const createMany = serviceMethod({ - authorizer: () => ImageAuthers.createMany.dynamicFields({}), + createMany: serviceMethod({ + authorizer: () => imageAuthers.createMany.dynamicFields({}), paramsSchema: z.object({ useFileName: z.boolean(), collectionId: z.number(), }), - dataSchema: ImageSchemas.createMany, + dataSchema: imageSchemas.createMany, method: async ({ params: { useFileName, collectionId }, data, @@ -85,59 +140,19 @@ export namespace ImageMethods { for (const file of data.files) { console.log('file', file) const name = useFileName ? file.name.split('.')[0] : undefined - await create({ + await imageMethods.create({ params: { collectionId }, data: { file, name, alt: file.name.split('.')[0], licenseId: data.licenseId, credit: data.credit }, }) } } - }) - - /** - * WARNING: This function should only be used in extreme cases, Therefore it is not exported. - * Creates bad image this should really only happen in worst case scenario - * where the server has lost a image and needs to be replaced with a bad image. - * A bad image is an image that has no correct fsLocation attributes. - * @param name - the name of the image - * @param config - the config for the image (special) - */ - const createSourceless = serviceMethod({ - authorizer: () => ImageAuthers.createSourcelessImage.dynamicFields({}), - paramsSchema: z.object({ - name: z.string(), - special: z.nativeEnum(SpecialImage), - }), - method: async ({ prisma, params: { name, special } }) => { - const standardCollection = await readSpecialImageCollection('STANDARDIMAGES') - logger.warn(` - creating a bad image, Something has caused the server to lose a neccesary image. - It was replaced with an image model with no correct fsLocation atrributes. - `) - return await prisma.image.create({ - data: { - name, - special, - fsLocationOriginal: 'not_found', - fsLocationMediumSize: 'not_found', - fsLocationSmallSize: 'not_found', - fsLocationLargeSize: 'not_found', - extOriginal: 'jpg', - alt: 'not found', - collection: { - connect: { - id: standardCollection.id - } - } - }, - }) - } - }) + }), /** * Reads an image by id. */ - export const read = serviceMethod({ - authorizer: () => ImageAuthers.read.dynamicFields({}), + read: serviceMethod({ + authorizer: () => imageAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -151,13 +166,13 @@ export namespace ImageMethods { if (!image) throw new ServerError('NOT FOUND', 'Image not found') return image } - }) + }), /** * Reads a page of images in a collection by collectionId. */ - export const readPage = serviceMethod({ - authorizer: () => ImageAuthers.readPage.dynamicFields({}), + readPage: serviceMethod({ + authorizer: () => imageAuthers.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -176,14 +191,14 @@ export namespace ImageMethods { ...cursorPageingSelection(params.paging.page) }) } - }) + }), /** * Reads a special image by name (special atr.). * In the case that the special image does not exist (bad state) a "bad" image will be created. */ - export const readSpecial = serviceMethod({ - authorizer: () => ImageAuthers.readSpecial.dynamicFields({}), + readSpecial: serviceMethod({ + authorizer: () => imageAuthers.readSpecial.dynamicFields({}), paramsSchema: z.object({ special: z.nativeEnum(SpecialImage) }), @@ -201,17 +216,17 @@ export namespace ImageMethods { } return image } - }) + }), /** * Update a image by id and data. Also can give the image a new license by data.licenseId. */ - export const update = serviceMethod({ - authorizer: () => ImageAuthers.update.dynamicFields({}), + update: serviceMethod({ + authorizer: () => imageAuthers.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - dataSchema: ImageSchemas.update, + dataSchema: imageSchemas.update, method: async ({ prisma, params: { id }, data: { licenseId, ...data } }) => { console.log('lic', licenseId) return await prisma.image.update({ @@ -226,10 +241,10 @@ export namespace ImageMethods { } }) } - }) + }), - export const destroy = serviceMethod({ - authorizer: () => ImageAuthers.destroy.dynamicFields({}), + destroy: serviceMethod({ + authorizer: () => imageAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -250,20 +265,5 @@ export namespace ImageMethods { }, }) } - }) - - /** - * Creates one image from a file. - * @param file - The file to create the image from - * @param allowedExt - The allowed extensions for the file - * @param size - The size to resize the image to - * @returns - */ - export async function createOneInStore(file: File, allowedExt: string[], size: number) { - const ret = await createFile(file, 'images', allowedExt, async (buffer) => await sharp(buffer).resize(size, size, { - fit: sharp.fit.inside, - withoutEnlargement: true - }).toBuffer()) - return ret - } + }), } diff --git a/src/services/images/schemas.ts b/src/services/images/schemas.ts index 036963088..f7fa046b2 100644 --- a/src/services/images/schemas.ts +++ b/src/services/images/schemas.ts @@ -1,58 +1,62 @@ -import { ImageConfig } from '@/services/images/config' +import { allowedExtensions, maxImageCountInOneBatch, maxImageFileSize } from './config' import { z } from 'zod' import { zfd } from 'zod-form-data' -export namespace ImageSchemas { - const maxFileSizeMb = Math.round(ImageConfig.maxFileSize / 1024 / 1024) - export const fileSchema = z.instanceof(File).refine( - file => file.size < ImageConfig.maxFileSize, `File size must be less than ${maxFileSizeMb}mb` +const maxFileSizeMb = Math.round(maxImageFileSize / 1024 / 1024) + +export const imageFileSchema = z.instanceof(File).refine( + file => file.size < maxImageFileSize, `File size must be less than ${maxFileSizeMb}mb` +).refine( + file => allowedExtensions.includes(file.type.split('/')[1]), + `File type must be one of ${allowedExtensions.join(', ')}` +) + +const baseSchema = z.object({ + file: imageFileSchema, + name: z.string().max(50, 'max length in 50').min(2, 'min length is 2').optional(), + alt: z.string().max(100, 'max length in 50').min(2, 'min length is 2'), + files: zfd.repeatable(z.array(z.instanceof(File)).refine( + files => files.every(file => file.size < maxImageFileSize), + `All file size must be less than ${maxFileSizeMb}mb` + )).refine( + files => files.every(file => allowedExtensions.includes(file.type.split('/')[1])), + `File type must be one of ${allowedExtensions.join(', ')}` ).refine( - file => ImageConfig.allowedExtUpload.includes(file.type.split('/')[1]), - `File type must be one of ${ImageConfig.allowedExtUpload.join(', ')}` - ) - const fields = z.object({ - file: fileSchema, - name: z.string().max(50, 'max length in 50').min(2, 'min length is 2').optional(), - alt: z.string().max(100, 'max length in 50').min(2, 'min length is 2'), - files: zfd.repeatable(z.array(z.instanceof(File)).refine( - files => files.every(file => file.size < ImageConfig.maxFileSize), - `All file size must be less than ${maxFileSizeMb}mb` - )).refine( - files => files.every(file => ImageConfig.allowedExtUpload.includes(file.type.split('/')[1])), - `File type must be one of ${ImageConfig.allowedExtUpload.join(', ')}` - ).refine( - files => files.length <= ImageConfig.maxNumberInOneBatch && files.length > 0, - `Du kan bare laste opp mellom 1 og ${ImageConfig.maxNumberInOneBatch} bilder av gangen` - ), - licenseId: z.union([ - z.string().optional().nullable(), - z.coerce.number().optional().or(z.literal('NULL')), - ]).transform( - value => { - if (typeof value === 'string' && value === 'NULL') return null - if (typeof value === 'string') return parseInt(value, 10) - return value - } - ), - credit: z.string().optional(), - }) + files => files.length <= maxImageCountInOneBatch && files.length > 0, + `Du kan bare laste opp mellom 1 og ${maxImageCountInOneBatch} bilder av gangen` + ), + licenseId: z.union([ + z.string().optional().nullable(), + z.coerce.number().optional().or(z.literal('NULL')), + ]).transform( + value => { + if (typeof value === 'string' && value === 'NULL') return null + if (typeof value === 'string') return parseInt(value, 10) + return value + } + ), + credit: z.string().optional(), +}) - export const create = fields.pick({ +export const imageSchemas = { + create: baseSchema.pick({ name: true, alt: true, file: true, licenseId: true, credit: true, - }) - export const createMany = fields.pick({ + }), + + createMany: baseSchema.pick({ files: true, licenseId: true, credit: true, - }) - export const update = fields.partial().pick({ + }), + + update: baseSchema.partial().pick({ name: true, alt: true, credit: true, licenseId: true, - }) + }), } diff --git a/src/services/licenses/actions.ts b/src/services/licenses/actions.ts index f6043b3d2..6e607c63f 100644 --- a/src/services/licenses/actions.ts +++ b/src/services/licenses/actions.ts @@ -1,12 +1,12 @@ 'use server' import { action } from '@/services/action' -import { LicenseMethods } from '@/services/licenses/methods' +import { licenseMethods } from '@/services/licenses/methods' -export const createLicenseAction = action(LicenseMethods.create) +export const createLicenseAction = action(licenseMethods.create) -export const destroyLicenseAction = action(LicenseMethods.destroy) +export const destroyLicenseAction = action(licenseMethods.destroy) -export const readAllLicensesAction = action(LicenseMethods.readAll) +export const readAllLicensesAction = action(licenseMethods.readAll) -export const updateLicenseAction = action(LicenseMethods.update) +export const updateLicenseAction = action(licenseMethods.update) diff --git a/src/services/licenses/authers.ts b/src/services/licenses/authers.ts index 6afc4cdd0..ce2890d70 100644 --- a/src/services/licenses/authers.ts +++ b/src/services/licenses/authers.ts @@ -1,8 +1,8 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace LicenseAuthers { - export const create = RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }) - export const read = RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }) - export const update = RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }) - export const destroy = RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }) +export const licenseAuthers = { + create: RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }), + read: RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }), + update: RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }), + destroy: RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }), } diff --git a/src/services/licenses/methods.ts b/src/services/licenses/methods.ts index bfbaefb33..c1e0e52f6 100644 --- a/src/services/licenses/methods.ts +++ b/src/services/licenses/methods.ts @@ -1,27 +1,27 @@ import '@pn-server-only' -import { LicenseSchemas } from './schemas' -import { LicenseAuthers } from './authers' +import { licenseSchemas } from './schemas' +import { licenseAuthers } from './authers' import { ServerError } from '@/services/error' import { serviceMethod } from '@/services/serviceMethod' import { z } from 'zod' -export namespace LicenseMethods { - export const create = serviceMethod({ - authorizer: () => LicenseAuthers.create.dynamicFields({}), - dataSchema: LicenseSchemas.create, +export const licenseMethods = { + create: serviceMethod({ + authorizer: () => licenseAuthers.create.dynamicFields({}), + dataSchema: licenseSchemas.create, method: async ({ prisma, data }) => await prisma.license.create({ data, }), - }) - export const readAll = serviceMethod({ - authorizer: () => LicenseAuthers.destroy.dynamicFields({}), + }), + readAll: serviceMethod({ + authorizer: () => licenseAuthers.destroy.dynamicFields({}), method: async ({ prisma }) => await prisma.license.findMany() - }) - export const destroy = serviceMethod({ + }), + destroy: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - authorizer: () => LicenseAuthers.destroy.dynamicFields({}), + authorizer: () => licenseAuthers.destroy.dynamicFields({}), method: async ({ prisma, params }) => { const { name: licenseName } = await prisma.license.findUniqueOrThrow({ where: { id: params.id }, @@ -43,13 +43,13 @@ export namespace LicenseMethods { await prisma.license.delete({ where: { id: params.id } }) } - }) - export const update = serviceMethod({ + }), + update: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - dataSchema: LicenseSchemas.update, - authorizer: () => LicenseAuthers.update.dynamicFields({}), + dataSchema: licenseSchemas.update, + authorizer: () => licenseAuthers.update.dynamicFields({}), method: async ({ prisma, params, data }) => { await prisma.license.update({ where: { @@ -58,5 +58,5 @@ export namespace LicenseMethods { data }) } - }) + }), } diff --git a/src/services/licenses/schemas.ts b/src/services/licenses/schemas.ts index 917aa9ac8..bfbb1d32f 100644 --- a/src/services/licenses/schemas.ts +++ b/src/services/licenses/schemas.ts @@ -1,22 +1,23 @@ import { z } from 'zod' -export namespace LicenseSchemas { - const fields = z.object({ - name: z.string().min( - 5, 'Navn må være minst 5 tegn langt' - ).max( - 50, 'Navn kan maks være 50 tegn langt' - ), - link: z.string().min( - 1, 'Link må være minst 1 tegn langt' - ) - }) - export const create = fields.pick({ +const baseSchema = z.object({ + name: z.string().min( + 5, 'Navn må være minst 5 tegn langt' + ).max( + 50, 'Navn kan maks være 50 tegn langt' + ), + link: z.string().min( + 1, 'Link må være minst 1 tegn langt' + ) +}) + +export const licenseSchemas = { + create: baseSchema.pick({ name: true, link: true, - }) - export const update = fields.partial().pick({ + }), + update: baseSchema.partial().pick({ name: true, link: true, - }) + }), } diff --git a/src/services/lockers/actions.ts b/src/services/lockers/actions.ts index 2cdf11090..430622d56 100644 --- a/src/services/lockers/actions.ts +++ b/src/services/lockers/actions.ts @@ -1,16 +1,16 @@ 'use server' import { action } from '@/services/action' -import { LockerLocationMethods } from '@/services/lockers/locations/methods' -import { LockerMethods } from '@/services/lockers/methods' -import { LockerReservationMethods } from '@/services/lockers/reservations/methods' +import { lockerLocationMethods } from '@/services/lockers/locations/methods' +import { lockerMethods } from '@/services/lockers/methods' +import { lockerReservationMethods } from '@/services/lockers/reservations/methods' -export const createLockerLocationAction = action(LockerLocationMethods.create) -export const readAllLockerLocationsAction = action(LockerLocationMethods.readAll) +export const createLockerLocationAction = action(lockerLocationMethods.create) +export const readAllLockerLocationsAction = action(lockerLocationMethods.readAll) -export const createLockerAction = action(LockerMethods.create) -export const readLockerAction = action(LockerMethods.read) -export const readLockerPageAction = action(LockerMethods.readPage) +export const createLockerAction = action(lockerMethods.create) +export const readLockerAction = action(lockerMethods.read) +export const readLockerPageAction = action(lockerMethods.readPage) -export const updateLockerReservationAction = action(LockerReservationMethods.update) -export const createLockerReservationAction = action(LockerReservationMethods.create) +export const updateLockerReservationAction = action(lockerReservationMethods.update) +export const createLockerReservationAction = action(lockerReservationMethods.create) diff --git a/src/services/lockers/authers.ts b/src/services/lockers/authers.ts index 07f61af08..cc4ebe32e 100644 --- a/src/services/lockers/authers.ts +++ b/src/services/lockers/authers.ts @@ -1,7 +1,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace LockerAuthers { - export const create = RequirePermission.staticFields({ permission: 'LOCKER_ADMIN' }) - export const read = RequirePermission.staticFields({ permission: 'LOCKER_USE' }) - export const readPage = RequirePermission.staticFields({ permission: 'LOCKER_USE' }) +export const lockerAuthers = { + create: RequirePermission.staticFields({ permission: 'LOCKER_ADMIN' }), + read: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), + readPage: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), } diff --git a/src/services/lockers/locations/authers.ts b/src/services/lockers/locations/authers.ts index 78309ac1d..c10d0bd2a 100644 --- a/src/services/lockers/locations/authers.ts +++ b/src/services/lockers/locations/authers.ts @@ -1,7 +1,7 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace LockerLocationAuthers { - export const create = RequirePermission.staticFields({ permission: 'LOCKER_ADMIN' }) - export const readAll = RequireNothing.staticFields({}) +export const lockerLocationAuthers = { + create: RequirePermission.staticFields({ permission: 'LOCKER_ADMIN' }), + readAll: RequireNothing.staticFields({}), } diff --git a/src/services/lockers/locations/methods.ts b/src/services/lockers/locations/methods.ts index 145d05d3c..238e964e8 100644 --- a/src/services/lockers/locations/methods.ts +++ b/src/services/lockers/locations/methods.ts @@ -1,8 +1,8 @@ -import { LockerLocationAuthers } from './authers' -import { LockersSchemas } from '@/services/lockers/schemas' +import { lockerLocationAuthers } from './authers' +import { lockersSchemas } from '@/services/lockers/schemas' import { serviceMethod } from '@/services/serviceMethod' -export namespace LockerLocationMethods { +export const lockerLocationMethods = { /** * Creates a new locker location. * @@ -10,24 +10,24 @@ export namespace LockerLocationMethods { * * @returns The newly created locker location object. */ - export const create = serviceMethod({ - authorizer: () => LockerLocationAuthers.create.dynamicFields({}), - dataSchema: LockersSchemas.createLocation, + create: serviceMethod({ + authorizer: () => lockerLocationAuthers.create.dynamicFields({}), + dataSchema: lockersSchemas.createLocation, method: async ({ prisma, data }) => prisma.lockerLocation.create({ data: { building: data.building, floor: data.floor } }) - }) + }), /** * Reads all locker locations. * * @returns All locker location objects. */ - export const readAll = serviceMethod({ - authorizer: () => LockerLocationAuthers.readAll.dynamicFields({}), + readAll: serviceMethod({ + authorizer: () => lockerLocationAuthers.readAll.dynamicFields({}), method: async ({ prisma }) => prisma.lockerLocation.findMany() - }) + }), } diff --git a/src/services/lockers/methods.ts b/src/services/lockers/methods.ts index 47f19b79c..34dced335 100644 --- a/src/services/lockers/methods.ts +++ b/src/services/lockers/methods.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { lockerReservationIncluder } from './reservations/config' -import { LockerAuthers } from './authers' -import { LockersSchemas } from './schemas' +import { lockerAuthers } from './authers' +import { lockersSchemas } from './schemas' import { serviceMethod } from '@/services/serviceMethod' import { ServerError } from '@/services/error' import { readPageInputSchemaObject } from '@/lib/paging/schema' @@ -32,7 +32,7 @@ export async function updateLockerReservationIfExpired(prisma: Prisma.Transactio locker.LockerReservation = [] } } -export namespace LockerMethods { +export const lockerMethods = { /** * Creates a new locker. * @@ -40,17 +40,16 @@ export namespace LockerMethods { * * @returns The newly created locker object. */ - export const create = serviceMethod({ - authorizer: () => LockerAuthers.create.dynamicFields({}), - dataSchema: LockersSchemas.create, + create: serviceMethod({ + authorizer: () => lockerAuthers.create.dynamicFields({}), + dataSchema: lockersSchemas.create, method: async ({ prisma, data }) => { console.log(data) return await prisma.locker.create({ data, }) } - - }) + }), /** * Reads a locker. Expired locker reservations are updated when reading. @@ -59,8 +58,8 @@ export namespace LockerMethods { * * @returns The locker object. */ - export const read = serviceMethod({ - authorizer: () => LockerAuthers.read.dynamicFields({}), + read: serviceMethod({ + authorizer: () => lockerAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -76,7 +75,7 @@ export namespace LockerMethods { return locker } - }) + }), /** * Reads a page of lockers. Expired locker reservations are updated when reading. @@ -85,8 +84,8 @@ export namespace LockerMethods { * * @returns A list of locker objects. */ - export const readPage = serviceMethod({ - authorizer: () => LockerAuthers.readPage.dynamicFields({}), + readPage: serviceMethod({ + authorizer: () => lockerAuthers.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -107,5 +106,5 @@ export namespace LockerMethods { return lockers } - }) + }), } diff --git a/src/services/lockers/reservations/authers.ts b/src/services/lockers/reservations/authers.ts index 77068334a..2a0861774 100644 --- a/src/services/lockers/reservations/authers.ts +++ b/src/services/lockers/reservations/authers.ts @@ -1,7 +1,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace LockerReservationAuthers { - export const create = RequirePermission.staticFields({ permission: 'LOCKER_USE' }) - export const read = RequirePermission.staticFields({ permission: 'LOCKER_USE' }) - export const update = RequirePermission.staticFields({ permission: 'LOCKER_USE' }) +export const lockerReservationAuthers = { + create: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), + read: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), + update: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), } diff --git a/src/services/lockers/reservations/methods.ts b/src/services/lockers/reservations/methods.ts index a40f3ff00..19fe315b7 100644 --- a/src/services/lockers/reservations/methods.ts +++ b/src/services/lockers/reservations/methods.ts @@ -1,13 +1,13 @@ import '@pn-server-only' -import { LockerReservationAuthers } from './authers' -import { LockerReservationSchemas } from './schemas' +import { lockerReservationAuthers } from './authers' +import { lockerReservationSchemas } from './schemas' import { serviceMethod } from '@/services/serviceMethod' import { Smorekopp } from '@/services/error' -import { GroupMethods } from '@/services/groups/methods' +import { groupMethods } from '@/services/groups/methods' import { z } from 'zod' -export namespace LockerReservationMethods { +export const lockerReservationMethods = { /** * Creates a new locker reservation for a given user and locker. * @@ -16,17 +16,17 @@ export namespace LockerReservationMethods { * * @returns The newly created reservation object. */ - export const create = serviceMethod({ - authorizer: () => LockerReservationAuthers.create.dynamicFields({}), + create: serviceMethod({ + authorizer: () => lockerReservationAuthers.create.dynamicFields({}), paramsSchema: z.object({ lockerId: z.number(), }), - dataSchema: LockerReservationSchemas.create, + dataSchema: lockerReservationSchemas.create, method: async ({ prisma, session, data, params }) => { // TODO: Use authers for authing in stead of this // Verify that user is in group if (data.groupId) { - const groupUsers = await GroupMethods.readUsersOfGroups({ + const groupUsers = await groupMethods.readUsersOfGroups({ bypassAuth: true, params: { groups: [{ groupId: data.groupId, admin: false }] @@ -53,7 +53,7 @@ export namespace LockerReservationMethods { } }) }, - }) + }), /** * Updates an existing locker reservation. @@ -63,8 +63,8 @@ export namespace LockerReservationMethods { * * @returns The updated reservation object. */ - export const read = serviceMethod({ - authorizer: () => LockerReservationAuthers.read.dynamicFields({}), + read: serviceMethod({ + authorizer: () => lockerReservationAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -73,7 +73,7 @@ export namespace LockerReservationMethods { id, }, }) - }) + }), /** * Updates an existing locker reservation. @@ -83,12 +83,12 @@ export namespace LockerReservationMethods { * * @returns The updated reservation object. */ - export const update = serviceMethod({ - authorizer: () => LockerReservationAuthers.update.dynamicFields({}), + update: serviceMethod({ + authorizer: () => lockerReservationAuthers.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - dataSchema: LockerReservationSchemas.update, + dataSchema: lockerReservationSchemas.update, method: async ({ prisma, session, data, params: { id } }) => { // TODO: Use authers for authing in stead of this // Verify that the user updating is the creator of the reservation @@ -107,7 +107,7 @@ export namespace LockerReservationMethods { // Verify that user is in group if (data.groupId) { - const groupUsers = await GroupMethods.readUsersOfGroups({ + const groupUsers = await groupMethods.readUsersOfGroups({ bypassAuth: true, params: { groups: [{ groupId: data.groupId, admin: false }] @@ -131,6 +131,6 @@ export namespace LockerReservationMethods { } }) }, - }) + }), } diff --git a/src/services/lockers/reservations/schemas.ts b/src/services/lockers/reservations/schemas.ts index 391621ed7..68daee3ae 100644 --- a/src/services/lockers/reservations/schemas.ts +++ b/src/services/lockers/reservations/schemas.ts @@ -1,21 +1,16 @@ import { z } from 'zod' -export namespace LockerReservationSchemas { - const fields = z.object({ - groupId: z.string(), - indefinateDate: z.string().optional(), - endDate: z.string().optional() - }) +const baseSchema = z.object({ + groupId: z.string(), + indefinateDate: z.string().optional(), + endDate: z.string().optional() +}).transform(data => ({ + groupId: data.groupId === 'null' ? null : parseInt(data.groupId, 10), + indefinateDate: data.indefinateDate ? data.indefinateDate === 'on' : false, + endDate: data.endDate ? (new Date(data.endDate)) : null +})) - export const create = fields.pick({ - groupId: true, - indefinateDate: true, - endDate: true, - }).transform(data => ({ - groupId: data.groupId === 'null' ? null : parseInt(data.groupId, 10), - indefinateDate: data.indefinateDate ? data.indefinateDate === 'on' : false, - endDate: data.endDate ? (new Date(data.endDate)) : null - })) - - export const update = create +export const lockerReservationSchemas = { + create: baseSchema, + update: baseSchema, } diff --git a/src/services/lockers/schemas.ts b/src/services/lockers/schemas.ts index d85ed054b..5de96929d 100644 --- a/src/services/lockers/schemas.ts +++ b/src/services/lockers/schemas.ts @@ -1,19 +1,20 @@ import { z } from 'zod' -export namespace LockersSchemas { - const fields = z.object({ - building: z.string(), - floor: z.coerce.number(), - id: z.coerce.number() - }) - export const create = fields.pick({ +const baseSchema = z.object({ + building: z.string(), + floor: z.coerce.number(), + id: z.coerce.number() +}) + +export const lockersSchemas = { + create: baseSchema.pick({ building: true, floor: true, id: true - }) + }), - export const createLocation = fields.pick({ + createLocation: baseSchema.pick({ building: true, floor: true, - }) + }), } diff --git a/src/services/mail/read.ts b/src/services/mail/read.ts index 8cbc0d622..9a8eb1f33 100644 --- a/src/services/mail/read.ts +++ b/src/services/mail/read.ts @@ -1,8 +1,8 @@ import '@pn-server-only' +import { userFilterSelection } from '@/services/users/config' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { prisma } from '@/prisma/client' -import { UserConfig } from '@/services/users/config' import type { MailFlowObject, MailListTypes, ViaArrayType, ViaType } from './Types' @@ -89,7 +89,7 @@ async function readAliasTraversal(id: number): Promise { // TODO: only find valid memberships include: { user: { - select: UserConfig.filterSelection, + select: userFilterSelection, } } } @@ -100,7 +100,7 @@ async function readAliasTraversal(id: number): Promise { users: { include: { user: { - select: UserConfig.filterSelection, + select: userFilterSelection, }, }, }, @@ -220,7 +220,7 @@ async function readMailingListTraversal(id: number): Promise { },*/ include: { user: { - select: UserConfig.filterSelection, + select: userFilterSelection, } } } @@ -231,7 +231,7 @@ async function readMailingListTraversal(id: number): Promise { users: { include: { user: { - select: UserConfig.filterSelection, + select: userFilterSelection, }, }, }, @@ -355,7 +355,7 @@ async function readGroupTraversal(id: number): Promise { memberships: { include: { user: { - select: UserConfig.filterSelection, + select: userFilterSelection, } } }, diff --git a/src/services/news/actions.ts b/src/services/news/actions.ts index be62da560..3e4917dbe 100644 --- a/src/services/news/actions.ts +++ b/src/services/news/actions.ts @@ -6,7 +6,7 @@ import { destroyNews } from '@/services/news/destroy' import { readNews, readNewsCurrent, readOldNewsPage } from '@/services/news/read' import { updateNews } from '@/services/news/update' import { createNewsArticleValidation, updateNewsArticleValidation } from '@/services/news/validation' -import { NotificationMethods } from '@/services/notifications/methods' +import { notificationMethods } from '@/services/notifications/methods' import type { CreateNewsArticleTypes, UpdateNewsArticleTypes } from '@/services/news/validation' import type { ExpandedNewsArticle, NewsCursor, SimpleNewsArticle } from '@/services/news/Types' import type { ReadPageInput } from '@/lib/paging/Types' @@ -67,7 +67,7 @@ export async function publishNewsAction( // eslint-disable-next-line @typescript-eslint/no-unused-vars shouldPublish: boolean ): Promise>> { - NotificationMethods.createSpecial({ + notificationMethods.createSpecial({ params: { special: 'NEW_NEWS_ARTICLE', }, diff --git a/src/services/notifications/Types.ts b/src/services/notifications/Types.ts index 562343e7b..a35ae157e 100644 --- a/src/services/notifications/Types.ts +++ b/src/services/notifications/Types.ts @@ -1,13 +1,18 @@ -import type { NotificationConfig } from './config' -import type { NotificationChannelConfig } from './channel/config' -import type { NotificationMethod, Prisma } from '@prisma/client' +import type { availableNotificationMethodIncluder } from './channel/config' +import type { notificationMethodsArray, notificationMethodTypes } from './config' +import type { Notification, NotificationMethod, Prisma } from '@prisma/client' -export type NotificationMethodTypes = typeof NotificationConfig.methodTypes[number] +export type NotificationMethodTypes = typeof notificationMethodTypes[number] -export type NotificationMethods = typeof NotificationConfig.methods[number] +export type NotificationMethods = typeof notificationMethodsArray[number] export type NotificationMethodGeneral = Omit export type ExpandedNotificationChannel = Prisma.NotificationChannelGetPayload<{ - include: typeof NotificationChannelConfig.includer + include: typeof availableNotificationMethodIncluder }> + +export type NotificationResult = { + notification: Notification | null, + recipients: number +} diff --git a/src/services/notifications/actions.ts b/src/services/notifications/actions.ts index 4020e9a03..a1ab9c884 100644 --- a/src/services/notifications/actions.ts +++ b/src/services/notifications/actions.ts @@ -1,15 +1,15 @@ 'use server' import { action } from '@/services/action' -import { NotificationChannelMethods } from '@/services/notifications/channel/methods' -import { NotificationMethods } from '@/services/notifications/methods' -import { NotificationSubscriptionMethods } from '@/services/notifications/subscription/methods' +import { notificationChannelMethods } from '@/services/notifications/channel/methods' +import { notificationMethods } from '@/services/notifications/methods' +import { notificationSubscriptionMethods } from '@/services/notifications/subscription/methods' -export const createNotificationChannelAction = action(NotificationChannelMethods.create) -export const updateNotificationChannelAction = action(NotificationChannelMethods.update) -export const readNotificationChannelsAction = action(NotificationChannelMethods.readMany) +export const createNotificationChannelAction = action(notificationChannelMethods.create) +export const updateNotificationChannelAction = action(notificationChannelMethods.update) +export const readNotificationChannelsAction = action(notificationChannelMethods.readMany) -export const createNotificationAction = action(NotificationMethods.create) +export const createNotificationAction = action(notificationMethods.create) -export const readNotificationSubscriptionsAction = action(NotificationSubscriptionMethods.read) -export const updateNotificationSubscriptionsAction = action(NotificationSubscriptionMethods.update) +export const readNotificationSubscriptionsAction = action(notificationSubscriptionMethods.read) +export const updateNotificationSubscriptionsAction = action(notificationSubscriptionMethods.update) diff --git a/src/services/notifications/authers.ts b/src/services/notifications/authers.ts index 7f16cf222..9f4459501 100644 --- a/src/services/notifications/authers.ts +++ b/src/services/notifications/authers.ts @@ -1,7 +1,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import '@pn-server-only' -export namespace NotificationAuthers { - export const create = RequirePermission.staticFields({ permission: 'NOTIFICATION_CREATE' }) - export const sendMail = RequirePermission.staticFields({ permission: 'MAIL_SEND' }) +export const notificationAuthers = { + create: RequirePermission.staticFields({ permission: 'NOTIFICATION_CREATE' }), + sendMail: RequirePermission.staticFields({ permission: 'MAIL_SEND' }), } diff --git a/src/services/notifications/channel/authers.ts b/src/services/notifications/channel/authers.ts index 425492732..f9ab00947 100644 --- a/src/services/notifications/channel/authers.ts +++ b/src/services/notifications/channel/authers.ts @@ -1,9 +1,9 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import '@pn-server-only' -export namespace NotificationChannelAuthers { - export const create = RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_CREATE' }) - export const read = RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_READ' }) - export const update = RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_UPDATE' }) - export const destroy = RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_UPDATE' }) +export const notificationChannelAuthers = { + create: RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_CREATE' }), + read: RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_READ' }), + update: RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_UPDATE' }), + destroy: RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_UPDATE' }), } diff --git a/src/services/notifications/channel/config.ts b/src/services/notifications/channel/config.ts index a1ae4c7f3..96bb0d3e6 100644 --- a/src/services/notifications/channel/config.ts +++ b/src/services/notifications/channel/config.ts @@ -1,17 +1,12 @@ -import { NotificationConfig } from '@/services/notifications/config' +import { allNotificationMethodsOn } from '@/services/notifications/config' - -export namespace NotificationChannelConfig { - - export const includer = { - availableMethods: { - select: NotificationConfig.allMethodsOn, - }, - defaultMethods: { - select: NotificationConfig.allMethodsOn, - }, - } as const -} +export const availableNotificationMethodIncluder = { + availableMethods: { + select: allNotificationMethodsOn, + }, + defaultMethods: { + select: allNotificationMethodsOn, + }, +} as const export const INFINITE_LOOP_PREVENTION_MAX_ITERATIONS = 1000 - diff --git a/src/services/notifications/channel/methods.ts b/src/services/notifications/channel/methods.ts index dfea0ef3a..b739d009c 100644 --- a/src/services/notifications/channel/methods.ts +++ b/src/services/notifications/channel/methods.ts @@ -1,28 +1,31 @@ import '@pn-server-only' -import { NotificationChannelAuthers } from './authers' -import { NotificationChannelSchemas } from './schemas' -import { NotificationChannelConfig } from './config' +import { notificationChannelAuthers } from './authers' +import { notificationChannelSchemas, validateMethods, validateNewParent } from './schemas' +import { availableNotificationMethodIncluder } from './config' +import { + allNotificationMethodsOff, + allNotificationMethodsOn, + notificationMethodsArray, +} from '@/services/notifications/config' +import { notificationMethodSchema } from '@/services/notifications/schemas' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' import { serviceMethod } from '@/services/serviceMethod' import { DEFAULT_NOTIFICATION_ALIAS } from '@/services/notifications/email/config' -import { NotificationConfig } from '@/services/notifications/config' import { ServerError } from '@/services/error' -import { NotificationSchemas } from '@/services/notifications/schemas' import { z } from 'zod' import type { ExpandedNotificationChannel, NotificationMethodGeneral } from '@/services/notifications/Types' -export namespace NotificationChannelMethods { - - export const create = serviceMethod({ - authorizer: () => NotificationChannelAuthers.create.dynamicFields({}), - dataSchema: NotificationChannelSchemas.create, +export const notificationChannelMethods = { + create: serviceMethod({ + authorizer: () => notificationChannelAuthers.create.dynamicFields({}), + dataSchema: notificationChannelSchemas.create, opensTransaction: true, paramsSchema: z.object({ - availableMethods: NotificationSchemas.notificationMethodFields, - defaultMethods: NotificationSchemas.notificationMethodFields, + availableMethods: notificationMethodSchema, + defaultMethods: notificationMethodSchema, }), method: async ({ prisma, data, params }): Promise => { - if (!NotificationChannelSchemas.validateMethods(params.availableMethods, params.defaultMethods)) { + if (!validateMethods(params.availableMethods, params.defaultMethods)) { throw new ServerError('BAD PARAMETERS', 'Default methods cannot exceed available methods.') } @@ -47,10 +50,10 @@ export namespace NotificationChannelMethods { } } }, - include: NotificationChannelConfig.includer, + include: availableNotificationMethodIncluder, }) - if (NotificationChannelSchemas.validateMethods(NotificationConfig.allMethodsOff, params.defaultMethods)) { + if (validateMethods(allNotificationMethodsOff, params.defaultMethods)) { return channel } @@ -61,7 +64,7 @@ export namespace NotificationChannelMethods { }, include: { methods: { - select: NotificationConfig.allMethodsOn, + select: allNotificationMethodsOn, } } }) @@ -72,8 +75,8 @@ export namespace NotificationChannelMethods { subscriptionMethods: booleanOperationOnMethods(subscription.methods, channel.defaultMethods, 'AND') })) .filter(sub => - !NotificationChannelSchemas.validateMethods( - NotificationConfig.allMethodsOff, + !validateMethods( + allNotificationMethodsOff, sub.subscriptionMethods ) ) @@ -99,40 +102,40 @@ export namespace NotificationChannelMethods { return channel } - }) + }), - export const readMany = serviceMethod({ - authorizer: () => NotificationChannelAuthers.read.dynamicFields({}), + readMany: serviceMethod({ + authorizer: () => notificationChannelAuthers.read.dynamicFields({}), method: async ({ prisma }) => await prisma.notificationChannel.findMany({ - include: NotificationChannelConfig.includer, + include: availableNotificationMethodIncluder, }) - }) + }), - export const readDefault = serviceMethod({ - authorizer: () => NotificationChannelAuthers.read.dynamicFields({}), + readDefault: serviceMethod({ + authorizer: () => notificationChannelAuthers.read.dynamicFields({}), method: async ({ prisma }) => await prisma.notificationChannel.findMany({ where: { defaultMethods: { - OR: NotificationConfig.methods.map(method => ({ + OR: notificationMethodsArray.map(method => ({ [method]: true })) } }, - include: NotificationChannelConfig.includer, + include: availableNotificationMethodIncluder, }) - }) + }), - export const update = serviceMethod({ - authorizer: () => NotificationChannelAuthers.update.dynamicFields({}), - dataSchema: NotificationChannelSchemas.update, + update: serviceMethod({ + authorizer: () => notificationChannelAuthers.update.dynamicFields({}), + dataSchema: notificationChannelSchemas.update, paramsSchema: z.object({ id: z.number(), - availableMethods: NotificationSchemas.notificationMethodFields, - defaultMethods: NotificationSchemas.notificationMethodFields, + availableMethods: notificationMethodSchema, + defaultMethods: notificationMethodSchema, }), opensTransaction: true, method: async ({ prisma, data, params }) => { - if (!NotificationChannelSchemas.validateMethods(params.availableMethods, params.defaultMethods)) { + if (!validateMethods(params.availableMethods, params.defaultMethods)) { throw new ServerError('BAD PARAMETERS', 'Default methods cannot exceed available methods.') } @@ -153,11 +156,11 @@ export namespace NotificationChannelMethods { // Not allowed to change the parent of ROOT if (channel.special !== 'ROOT') { - const allChannels = await readMany({ + const allChannels = await notificationChannelMethods.readMany({ bypassAuth: true, }) - if (!NotificationChannelSchemas.validateNewParent(params.id, data.parentId, allChannels)) { + if (!validateNewParent(params.id, data.parentId, allChannels)) { throw new ServerError('BAD PARAMETERS', 'Cannot set parentId in a loop') } @@ -165,8 +168,8 @@ export namespace NotificationChannelMethods { } function methodsAreEqual(lhs: NotificationMethodGeneral, rhs: NotificationMethodGeneral) { - for (let i = 0; i < NotificationConfig.methods.length; i++) { - if (lhs[NotificationConfig.methods[i]] !== rhs[NotificationConfig.methods[i]]) { + for (let i = 0; i < notificationMethodsArray.length; i++) { + if (lhs[notificationMethodsArray[i]] !== rhs[notificationMethodsArray[i]]) { return false } } @@ -208,15 +211,15 @@ export namespace NotificationChannelMethods { } } }, - include: NotificationChannelConfig.includer, + include: availableNotificationMethodIncluder, }) }) } - }) + }), // It doesn't seem that this function is used yet. -Theodor - export const destroy = serviceMethod({ - authorizer: () => NotificationChannelAuthers.destroy.dynamicFields({}), + destroy: serviceMethod({ + authorizer: () => notificationChannelAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -228,7 +231,7 @@ export namespace NotificationChannelMethods { where: { id: params.id, }, - include: NotificationChannelConfig.includer, + include: availableNotificationMethodIncluder, }) await tx.notificationMethod.deleteMany({ @@ -242,6 +245,5 @@ export namespace NotificationChannelMethods { return results }) - }) - + }), } diff --git a/src/services/notifications/channel/schemas.ts b/src/services/notifications/channel/schemas.ts index 81d2a8101..6e745edb5 100644 --- a/src/services/notifications/channel/schemas.ts +++ b/src/services/notifications/channel/schemas.ts @@ -1,5 +1,5 @@ import { INFINITE_LOOP_PREVENTION_MAX_ITERATIONS } from './config' -import { NotificationConfig } from '@/services/notifications/config' +import { notificationMethodsArray } from '@/services/notifications/config' import { SpecialNotificationChannel } from '@prisma/client' import { z } from 'zod' import type { @@ -8,100 +8,98 @@ import type { NotificationMethodTypes } from '@/services/notifications/Types' +export function parseMethods(data: FormData, prefix?: NotificationMethodTypes) { + return Object.fromEntries( + notificationMethodsArray.filter(method => notificationMethodsArray.includes(method)).map(method => { + const compare = prefix ? `${prefix}_${method}` : method + const value = data.get(compare) + if (!value) { + return [method, false] + } -export namespace NotificationChannelSchemas { - - export function parseMethods(data: FormData, prefix?: NotificationMethodTypes) { - return Object.fromEntries( - NotificationConfig.methods.filter(method => NotificationConfig.methods.includes(method)).map(method => { - const compare = prefix ? `${prefix}_${method}` : method - const value = data.get(compare) - if (!value) { - return [method, false] - } - - return [method, value === 'on'] - }) - ) as NotificationMethodGeneral - } - - /** - * Validates the available notification methods against the default methods. - * @param availableMethods - The available notification methods. - * @param defaultMethods - The default notification methods. - * @returns A boolean indicating whether the available methods are valid. - */ - export function validateMethods( - availableMethods: NotificationMethodGeneral, - defaultMethods: NotificationMethodGeneral - ): boolean { - for (let i = 0; i < NotificationConfig.methods.length; i++) { - const availableMethod = availableMethods[NotificationConfig.methods[i]] - const defaultMethod = defaultMethods[NotificationConfig.methods[i]] - - if (defaultMethod && !availableMethod) return false - } - - return true - } + return [method, value === 'on'] + }) + ) as NotificationMethodGeneral +} - export function validateNewParent( - channelId: number, - newParentId: number, - channels: ExpandedNotificationChannel[] - ): boolean { - return findValidParents(channelId, channels).map(channel => channel.id).includes(newParentId) +/** + * Validates the available notification methods against the default methods. + * @param availableMethods - The available notification methods. + * @param defaultMethods - The default notification methods. + * @returns A boolean indicating whether the available methods are valid. + */ +export function validateMethods( + availableMethods: NotificationMethodGeneral, + defaultMethods: NotificationMethodGeneral +): boolean { + for (let i = 0; i < notificationMethodsArray.length; i++) { + const availableMethod = availableMethods[notificationMethodsArray[i]] + const defaultMethod = defaultMethods[notificationMethodsArray[i]] + + if (defaultMethod && !availableMethod) return false } - export function findValidParents( - channelId: number, - channels: ExpandedNotificationChannel[] - ): ExpandedNotificationChannel[] { - const validParents = channels.filter(channel => channel.id !== channelId) - // Remove chrildren of the current channel - const channelIDS = new Set(validParents.map(channel => channel.id)) - for (let i = 0; i < INFINITE_LOOP_PREVENTION_MAX_ITERATIONS; i++) { - const lengthBeforeReduction = channelIDS.size + return true +} - for (let j = validParents.length - 1; j >= 0; j--) { - if (!channelIDS.has(validParents[j].parentId)) { - channelIDS.delete(validParents[j].id) - validParents.splice(j, 1) - } - } +export function validateNewParent( + channelId: number, + newParentId: number, + channels: ExpandedNotificationChannel[] +): boolean { + return findValidParents(channelId, channels).map(channel => channel.id).includes(newParentId) +} - // Quit the loop if the last round didn't remove any more parent - if (lengthBeforeReduction === channelIDS.size) { - break +export function findValidParents( + channelId: number, + channels: ExpandedNotificationChannel[] +): ExpandedNotificationChannel[] { + const validParents = channels.filter(channel => channel.id !== channelId) + // Remove chrildren of the current channel + const channelIDS = new Set(validParents.map(channel => channel.id)) + for (let i = 0; i < INFINITE_LOOP_PREVENTION_MAX_ITERATIONS; i++) { + const lengthBeforeReduction = channelIDS.size + + for (let j = validParents.length - 1; j >= 0; j--) { + if (!channelIDS.has(validParents[j].parentId)) { + channelIDS.delete(validParents[j].id) + validParents.splice(j, 1) } + } - if (i >= INFINITE_LOOP_PREVENTION_MAX_ITERATIONS - 1) { - // It's highly unlikely that this wil ever throw - throw new Error('Stopping infinite loop, while finding valid parents.') - } + // Quit the loop if the last round didn't remove any more parent + if (lengthBeforeReduction === channelIDS.size) { + break } - return validParents + if (i >= INFINITE_LOOP_PREVENTION_MAX_ITERATIONS - 1) { + // It's highly unlikely that this wil ever throw + throw new Error('Stopping infinite loop, while finding valid parents.') + } } - const fields = z.object({ - name: z.string().min(2), - description: z.string(), - special: z.nativeEnum(SpecialNotificationChannel), - parentId: z.coerce.number().min(1), - mailAliasId: z.coerce.number().min(1), - }) + return validParents +} + +const baseSchema = z.object({ + name: z.string().min(2), + description: z.string(), + special: z.nativeEnum(SpecialNotificationChannel), + parentId: z.coerce.number().min(1), + mailAliasId: z.coerce.number().min(1), +}) - export const create = fields.pick({ +export const notificationChannelSchemas = { + create: baseSchema.pick({ name: true, description: true, parentId: true, - }) + }), - export const update = fields.pick({ + update: baseSchema.pick({ name: true, description: true, parentId: true, mailAliasId: true, - }) + }), } diff --git a/src/services/notifications/config.ts b/src/services/notifications/config.ts index 548e8aa39..37b06f284 100644 --- a/src/services/notifications/config.ts +++ b/src/services/notifications/config.ts @@ -1,23 +1,19 @@ import type { NotificationMethodGeneral } from './Types' +export const notificationMethodsDisplayMap = { + email: 'E-post', + emailWeekly: 'Ukentlig e-post', +} satisfies Record -export namespace NotificationConfig { - export const methodsDisplayMap = { - email: 'E-post', - emailWeekly: 'Ukentlig e-post', - } satisfies Record - - export const allMethodsOn: NotificationMethodGeneral = { - email: true, - emailWeekly: true, - } - - export const allMethodsOff: NotificationMethodGeneral = { - email: false, - emailWeekly: false, - } +export const allNotificationMethodsOn: NotificationMethodGeneral = { + email: true, + emailWeekly: true, +} - export const methodTypes = ['availableMethods', 'defaultMethods'] as const - export const methods = ['email', 'emailWeekly'] as const satisfies (keyof NotificationMethodGeneral)[] +export const allNotificationMethodsOff: NotificationMethodGeneral = { + email: false, + emailWeekly: false, } +export const notificationMethodTypes = ['availableMethods', 'defaultMethods'] as const +export const notificationMethodsArray = ['email', 'emailWeekly'] as const satisfies (keyof NotificationMethodGeneral)[] diff --git a/src/services/notifications/email/dispatch.tsx b/src/services/notifications/email/dispatch.tsx index 78a5c43f5..5fb50555c 100644 --- a/src/services/notifications/email/dispatch.tsx +++ b/src/services/notifications/email/dispatch.tsx @@ -2,7 +2,7 @@ import { sendBulkMail } from './send' import { DEFAULT_NOTIFICATION_ALIAS } from './config' import { sendEmailValidation } from './validation' import { DefaultEmailTemplate } from './templates/default' -import { NotificationMethods } from '@/services/notifications/methods' +import { repalceSpecialSymbols } from '@/services/notifications/methods' import { prismaCall } from '@/services/prismaCall' import { prisma } from '@/prisma/client' import { render } from '@react-email/render' @@ -39,8 +39,8 @@ export async function dispatchEmailNotifications( const parsed = sendEmailValidation.detailedValidate({ from: senderAlias, to: user.email, - subject: NotificationMethods.repalceSpecialSymbols(notificaion.title, user), - text: NotificationMethods.repalceSpecialSymbols(notificaion.message, user), + subject: repalceSpecialSymbols(notificaion.title, user), + text: repalceSpecialSymbols(notificaion.message, user), }) return { diff --git a/src/services/notifications/email/systemMail/resetPassword.tsx b/src/services/notifications/email/systemMail/resetPassword.tsx index 425a4274e..acf1ed47e 100644 --- a/src/services/notifications/email/systemMail/resetPassword.tsx +++ b/src/services/notifications/email/systemMail/resetPassword.tsx @@ -2,7 +2,7 @@ import '@pn-server-only' import { sendSystemMail } from '@/services/notifications/email/send' import { ResetPasswordTemplate } from '@/services/notifications/email/templates/resetPassword' import { generateJWT } from '@/jwt/jwt' -import { UserMethods } from '@/services/users/methods' +import { userMethods } from '@/services/users/methods' import { ServerError } from '@/services/error' import { z } from 'zod' @@ -10,7 +10,7 @@ export async function sendResetPasswordMail(email: string) { const emailParsed = z.string().email().parse(email) try { - const user = await UserMethods.read({ + const user = await userMethods.read({ params: { email: emailParsed }, bypassAuth: true, }) diff --git a/src/services/notifications/email/systemMail/verifyEmail.tsx b/src/services/notifications/email/systemMail/verifyEmail.tsx index 23e1cfd68..8905ed6a9 100644 --- a/src/services/notifications/email/systemMail/verifyEmail.tsx +++ b/src/services/notifications/email/systemMail/verifyEmail.tsx @@ -3,12 +3,12 @@ import { emailValidationExpiration } from './ConfigVars' import { VerifyEmailTemplate } from '@/services/notifications/email/templates/verifyEmail' import { sendSystemMail } from '@/services/notifications/email/send' import { generateJWT } from '@/jwt/jwt' -import { UserSchemas } from '@/services/users/schemas' +import { userSchemas } from '@/services/users/schemas' import type { UserFiltered } from '@/services/users/Types' // TODO: Fix this with new validation export async function sendVerifyEmail(user: UserFiltered, email: string) { - const parse = UserSchemas.verifyEmail.parse({ email }) + const parse = userSchemas.verifyEmail.parse({ email }) const jwt = generateJWT('verifyemail', { email: parse.email, diff --git a/src/services/notifications/methods.ts b/src/services/notifications/methods.ts index 983aa839d..345b65983 100644 --- a/src/services/notifications/methods.ts +++ b/src/services/notifications/methods.ts @@ -1,45 +1,44 @@ import '@pn-server-only' -import { NotificationSchemas } from './schemas' -import { NotificationConfig } from './config' -import { NotificationChannelConfig } from './channel/config' import { dispatchEmailNotifications } from './email/dispatch' -import { NotificationAuthers } from './authers' +import { notificationAuthers } from './authers' +import { notificationSchemas } from './schemas' +import { allNotificationMethodsOn, notificationMethodsArray } from './config' +import { availableNotificationMethodIncluder } from './channel/config' +import { userFilterSelection } from '@/services/users/config' import { serviceMethod } from '@/services/serviceMethod' import { ServerOnly } from '@/auth/auther/ServerOnly' -import { UserConfig } from '@/services/users/config' import { z } from 'zod' import { SpecialNotificationChannel } from '@prisma/client' import type { Notification } from '@prisma/client' -import type { ExpandedNotificationChannel } from './Types' +import type { ExpandedNotificationChannel, NotificationResult } from './Types' import type { UserFiltered } from '@/services/users/Types' -export namespace NotificationMethods { +const dispathMethod = { + email: dispatchEmailNotifications, + emailWeekly: async () => { }, +} satisfies Record< + typeof notificationMethodsArray[number], + ((channel: ExpandedNotificationChannel, notification: Notification, users: UserFiltered[]) => Promise) +> - const dispathMethod = { - email: dispatchEmailNotifications, - emailWeekly: async () => { }, - } satisfies Record< - typeof NotificationConfig.methods[number], - ((channel: ExpandedNotificationChannel, notification: Notification, users: UserFiltered[]) => Promise) - > - - export function repalceSpecialSymbols(text: string, user: UserFiltered) { - return text - .replaceAll('%u', user.username) - .replaceAll('%n', user.firstname) - .replaceAll('%N', `${user.firstname} ${user.lastname}`) - } +export function repalceSpecialSymbols(text: string, user: UserFiltered) { + return text + .replaceAll('%u', user.username) + .replaceAll('%n', user.firstname) + .replaceAll('%N', `${user.firstname} ${user.lastname}`) +} +export const notificationMethods = { /** * Creates a notification with the specified data. * * @param data - The detailed data for dispatching the notification. * @returns A promise that resolves with an object containing the dispatched notification and the number of recipients. */ - export const create = serviceMethod({ - authorizer: () => NotificationAuthers.create.dynamicFields({}), - dataSchema: NotificationSchemas.create, - method: async ({ prisma, data }) => { + create: serviceMethod({ + authorizer: () => notificationAuthers.create.dynamicFields({}), + dataSchema: notificationSchemas.create, + method: async ({ prisma, data }): Promise => { // This prevent notifications from beeing sent during seeding if (process.env.IGNORE_SERVER_ONLY) { return { @@ -65,14 +64,14 @@ export namespace NotificationMethods { id: data.channelId, }, include: { - ...NotificationChannelConfig.includer, + ...availableNotificationMethodIncluder, subscriptions: { select: { methods: { - select: NotificationConfig.allMethodsOn, + select: allNotificationMethodsOn, }, user: { - select: UserConfig.filterSelection, + select: userFilterSelection, }, }, }, @@ -88,7 +87,7 @@ export namespace NotificationMethods { // TODO: Filter the users by visibility - NotificationConfig.methods.forEach(method => { + notificationMethodsArray.forEach(method => { if (!results.availableMethods[method]) { return } @@ -108,8 +107,7 @@ export namespace NotificationMethods { recipients: results.subscriptions.length } } - }) - + }), /** * Createses a notification to a special notification channel. @@ -119,20 +117,20 @@ export namespace NotificationMethods { * @param message - The message content of the notification. * @returns A promise that resolves with an object containing the dispatched notification and the number of recipients. */ - export const createSpecial = serviceMethod({ + createSpecial: serviceMethod({ authorizer: ServerOnly, paramsSchema: z.object({ special: z.nativeEnum(SpecialNotificationChannel), }), - dataSchema: NotificationSchemas.createSpecial, - method: async ({ prisma, params, data, session }) => { + dataSchema: notificationSchemas.createSpecial, + method: async ({ prisma, params, data, session }): Promise => { const channel = await prisma.notificationChannel.findUniqueOrThrow({ where: { special: params.special, } }) - return await create({ + return await notificationMethods.create({ session, bypassAuth: true, data: { @@ -143,5 +141,5 @@ export namespace NotificationMethods { } }) } - }) + }), } diff --git a/src/services/notifications/notificationMethodOperations.ts b/src/services/notifications/notificationMethodOperations.ts index 1251a26b4..57faa8626 100644 --- a/src/services/notifications/notificationMethodOperations.ts +++ b/src/services/notifications/notificationMethodOperations.ts @@ -1,12 +1,12 @@ -import { NotificationConfig } from './config' +import { allNotificationMethodsOff, allNotificationMethodsOn, notificationMethodsArray } from './config' import type { NotificationMethodGeneral } from './Types' export function newAllMethodsOff() { - return { ...NotificationConfig.allMethodsOff } + return { ...allNotificationMethodsOff } } export function newAllMethodsOn() { - return { ...NotificationConfig.allMethodsOn } + return { ...allNotificationMethodsOn } } export function booleanOperationOnMethods( @@ -16,7 +16,7 @@ export function booleanOperationOnMethods( ): NotificationMethodGeneral { const ret = Object.assign({}, lhs) - for (const key of NotificationConfig.methods) { + for (const key of notificationMethodsArray) { switch (operation) { case 'AND': ret[key] &&= rhs[key] diff --git a/src/services/notifications/schemas.ts b/src/services/notifications/schemas.ts index 76e431e4f..018b9d6e0 100644 --- a/src/services/notifications/schemas.ts +++ b/src/services/notifications/schemas.ts @@ -1,40 +1,38 @@ import { z } from 'zod' - -export namespace NotificationSchemas { - - export const notificationMethodFields = z.object({ - email: z.boolean(), - emailWeekly: z.boolean(), - }) - - const fields = z.object({ - channelId: z.coerce.number().min(1), - title: z.string().min(2), - message: z.string().min(10), - email: z.string().email(), - userIdList: z.number().array().optional(), - }) - - export const create = fields.pick({ +export const notificationMethodSchema = z.object({ + email: z.boolean(), + emailWeekly: z.boolean(), +}) + +const baseSchema = z.object({ + channelId: z.coerce.number().min(1), + title: z.string().min(2), + message: z.string().min(10), + email: z.string().email(), + userIdList: z.number().array().optional(), +}) + +export const notificationSchemas = { + create: baseSchema.pick({ channelId: true, title: true, message: true, userIdList: true, - }) + }), - export const createSpecial = fields.pick({ + createSpecial: baseSchema.pick({ title: true, message: true, userIdList: true, - }) + }), - export const sendMail = fields.pick({ + sendMail: baseSchema.pick({ email: true, - }) + }), - export const sendEmail = fields.pick({ + sendEmail: baseSchema.pick({ title: true, message: true, - }) + }), } diff --git a/src/services/notifications/subscription/Types.ts b/src/services/notifications/subscription/Types.ts index c4e07c9d8..c345925ec 100644 --- a/src/services/notifications/subscription/Types.ts +++ b/src/services/notifications/subscription/Types.ts @@ -1,9 +1,9 @@ -import type { NotificationSubscriptionConfig } from './config' +import type { notificationMethodIncluder } from './config' import type { Prisma } from '@prisma/client' export type Subscription = Prisma.NotificationSubscriptionGetPayload<{ - include: typeof NotificationSubscriptionConfig.includer + include: typeof notificationMethodIncluder }> export type MinimizedSubscription = Pick diff --git a/src/services/notifications/subscription/authers.ts b/src/services/notifications/subscription/authers.ts index 925a42673..9e400742e 100644 --- a/src/services/notifications/subscription/authers.ts +++ b/src/services/notifications/subscription/authers.ts @@ -1,6 +1,6 @@ import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' -export namespace NotificationSubscriptionAuthers { - export const read = RequireUserIdOrPermission.staticFields({ permission: 'NOTIFICATION_SUBSCRIPTION_READ' }) - export const update = RequireUserIdOrPermission.staticFields({ permission: 'NOTIFICATION_SUBSCRIPTION_UPDATE' }) +export const notificationSubscriptionAuthers = { + read: RequireUserIdOrPermission.staticFields({ permission: 'NOTIFICATION_SUBSCRIPTION_READ' }), + update: RequireUserIdOrPermission.staticFields({ permission: 'NOTIFICATION_SUBSCRIPTION_UPDATE' }), } diff --git a/src/services/notifications/subscription/config.ts b/src/services/notifications/subscription/config.ts index c60fe2e08..eafc7128f 100644 --- a/src/services/notifications/subscription/config.ts +++ b/src/services/notifications/subscription/config.ts @@ -1,11 +1,8 @@ -import { NotificationConfig } from '@/services/notifications/config' +import { allNotificationMethodsOn } from '@/services/notifications/config' import type { Prisma } from '@prisma/client' - -export namespace NotificationSubscriptionConfig { - export const includer = { - methods: { - select: NotificationConfig.allMethodsOn, - }, - } satisfies Prisma.NotificationSubscriptionInclude -} +export const notificationMethodIncluder = { + methods: { + select: allNotificationMethodsOn, + }, +} satisfies Prisma.NotificationSubscriptionInclude diff --git a/src/services/notifications/subscription/methods.ts b/src/services/notifications/subscription/methods.ts index c51553eb2..4ec016aac 100644 --- a/src/services/notifications/subscription/methods.ts +++ b/src/services/notifications/subscription/methods.ts @@ -1,10 +1,10 @@ -import { NotificationSubscriptionAuthers } from './authers' -import { NotificationSubscriptionConfig } from './config' -import { SubscriptionSchemas } from './schemas' -import { NotificationChannelConfig } from '@/services/notifications/channel/config' -import { NotificationConfig } from '@/services/notifications/config' -import { NotificationChannelSchemas } from '@/services/notifications/channel/schemas' -import { NotificationChannelMethods } from '@/services/notifications/channel/methods' +import { notificationMethodIncluder } from './config' +import { notificationSubscriptionAuthers } from './authers' +import { subscriptionSchemas } from './schemas' +import { validateMethods } from '@/services/notifications/channel/schemas' +import { allNotificationMethodsOff, allNotificationMethodsOn } from '@/services/notifications/config' +import { availableNotificationMethodIncluder } from '@/services/notifications/channel/config' +import { notificationChannelMethods } from '@/services/notifications/channel/methods' import { serviceMethod } from '@/services/serviceMethod' import { ServerOnly } from '@/auth/auther/ServerOnly' import { ServerError } from '@/services/error' @@ -13,30 +13,123 @@ import type { Prisma } from '@prisma/client' import type { Subscription } from './Types' import type { NotificationMethodGeneral } from '@/services/notifications/Types' +// eslint-disable-next-line +async function createTransactionPart( + prisma: Prisma.TransactionClient, + userId: number, + channelId: number, + methods: NotificationMethodGeneral +): Promise<(() => Promise) | null> { + const whereFilter = { + userId_channelId: { + userId, + channelId, + } + } + + const subscription = await prisma.notificationSubscription.findUnique({ + where: whereFilter + }) + + const subscriptionExists = subscription !== null + + // If all methods are off, we delete the relation + if (validateMethods(allNotificationMethodsOff, methods)) { + // No change, do nothing + if (!subscriptionExists) { + return null + } + + // Delete the realtion + return async () => { + const sub = await prisma.notificationSubscription.delete({ + where: whereFilter, + include: notificationMethodIncluder, + }) + + await prisma.notificationMethod.delete({ + where: { + id: sub.methodsId + } + }) + + return sub + } + } + + // Verify that the new methods are a subset of the available methods + const notificaionChannel = await prisma.notificationChannel.findUniqueOrThrow({ + where: { + id: channelId, + }, + include: availableNotificationMethodIncluder, + }) -export namespace NotificationSubscriptionMethods { + if (!validateMethods(notificaionChannel.availableMethods, methods)) { + throw new ServerError('BAD PARAMETERS', 'The methods must a subset of the available methods') + } - export const read = serviceMethod({ + // Update the relation + if (subscriptionExists) { + return async () => { + const results = await prisma.notificationMethod.update({ + where: { + id: subscription.methodsId, + }, + data: methods, + select: allNotificationMethodsOn, + }) + + return { + ...subscription, + methods: results, + } + } + } + + // Create the relation + return () => prisma.notificationSubscription.create({ + data: { + channel: { + connect: { + id: channelId, + }, + }, + user: { + connect: { + id: userId, + }, + }, + methods: { + create: methods, + }, + }, + include: notificationMethodIncluder, + }) +} + +export const notificationSubscriptionMethods = { + read: serviceMethod({ paramsSchema: z.object({ userId: z.number(), }), - authorizer: ({ params }) => NotificationSubscriptionAuthers.read.dynamicFields(params), + authorizer: ({ params }) => notificationSubscriptionAuthers.read.dynamicFields(params), method: async ({ prisma, params }) => await prisma.notificationSubscription.findMany({ where: { userId: params.userId, }, - include: NotificationSubscriptionConfig.includer, + include: notificationMethodIncluder, }), - }) + }), - export const createDefault = serviceMethod({ + createDefault: serviceMethod({ authorizer: ServerOnly, paramsSchema: z.object({ userId: z.number(), }), opensTransaction: true, method: async ({ prisma, params, session }) => { - const channels = await NotificationChannelMethods.readDefault({ + const channels = await notificationChannelMethods.readDefault({ session, bypassAuth: true, }) @@ -61,110 +154,15 @@ export namespace NotificationSubscriptionMethods { }) )) } - }) - - - // eslint-disable-next-line - async function createTransactionPart( - prisma: Prisma.TransactionClient, - userId: number, - channelId: number, - methods: NotificationMethodGeneral - ): Promise<(() => Promise) | null> { - const whereFilter = { - userId_channelId: { - userId, - channelId, - } - } - - const subscription = await prisma.notificationSubscription.findUnique({ - where: whereFilter - }) - - const subscriptionExists = subscription !== null - - // If all methods are off, we delete the relation - if (NotificationChannelSchemas.validateMethods(NotificationConfig.allMethodsOff, methods)) { - // No change, do nothing - if (!subscriptionExists) { - return null - } - - // Delete the realtion - return async () => { - const sub = await prisma.notificationSubscription.delete({ - where: whereFilter, - include: NotificationSubscriptionConfig.includer, - }) - - await prisma.notificationMethod.delete({ - where: { - id: sub.methodsId - } - }) - - return sub - } - } + }), - // Verify that the new methods are a subset of the available methods - const notificaionChannel = await prisma.notificationChannel.findUniqueOrThrow({ - where: { - id: channelId, - }, - include: NotificationChannelConfig.includer, - }) - if (!NotificationChannelSchemas.validateMethods(notificaionChannel.availableMethods, methods)) { - throw new ServerError('BAD PARAMETERS', 'The methods must a subset of the available methods') - } - - // Update the relation - if (subscriptionExists) { - return async () => { - const results = await prisma.notificationMethod.update({ - where: { - id: subscription.methodsId, - }, - data: methods, - select: NotificationConfig.allMethodsOn, - }) - - return { - ...subscription, - methods: results, - } - } - } - - // Create the relation - return () => prisma.notificationSubscription.create({ - data: { - channel: { - connect: { - id: channelId, - }, - }, - user: { - connect: { - id: userId, - }, - }, - methods: { - create: methods, - }, - }, - include: NotificationSubscriptionConfig.includer, - }) - } - - export const update = serviceMethod({ - authorizer: ({ params }) => NotificationSubscriptionAuthers.update.dynamicFields(params), + update: serviceMethod({ + authorizer: ({ params }) => notificationSubscriptionAuthers.update.dynamicFields(params), paramsSchema: z.object({ userId: z.number(), }), - dataSchema: SubscriptionSchemas.update, + dataSchema: subscriptionSchemas.update, method: async ({ prisma, params, data }): Promise => { // Prepare updates and validate the data with the data in the database const transactionParts = (await Promise.all( @@ -178,5 +176,5 @@ export namespace NotificationSubscriptionMethods { transactionParts.map(part => part()) ) } - }) + }), } diff --git a/src/services/notifications/subscription/schemas.ts b/src/services/notifications/subscription/schemas.ts index ad09958d1..8683e7f9c 100644 --- a/src/services/notifications/subscription/schemas.ts +++ b/src/services/notifications/subscription/schemas.ts @@ -1,17 +1,15 @@ -import { NotificationSchemas } from '@/services/notifications/schemas' +import { notificationMethodSchema } from '@/services/notifications/schemas' import { z } from 'zod' +const baseSchema = z.object({ + subscriptions: z.array(z.object({ + channelId: z.number().min(1), + methods: notificationMethodSchema, + })), +}) -export namespace SubscriptionSchemas { - - const fields = z.object({ - subscriptions: z.array(z.object({ - channelId: z.number().min(1), - methods: NotificationSchemas.notificationMethodFields, - })), - }) - - export const update = fields.pick({ +export const subscriptionSchemas = { + update: baseSchema.pick({ subscriptions: true, - }) + }), } diff --git a/src/services/ombul/create.ts b/src/services/ombul/create.ts index 1cad872cd..226a22799 100644 --- a/src/services/ombul/create.ts +++ b/src/services/ombul/create.ts @@ -5,8 +5,8 @@ import { readSpecialImageCollection } from '@/services/images/collections/read' import { createCmsImage } from '@/services/cms/images/create' import { prisma } from '@/prisma/client' import { createFile } from '@/services/store/createFile' -import { ImageMethods } from '@/services/images/methods' -import { NotificationMethods } from '@/services/notifications/methods' +import { imageMethods } from '@/services/images/methods' +import { notificationMethods } from '@/services/notifications/methods' import type { CreateOmbulTypes } from './validation' import type { Ombul } from '@prisma/client' @@ -43,7 +43,7 @@ export async function createOmbul( // create coverimage const ombulCoverCollection = await readSpecialImageCollection('OMBULCOVERS') - const coverImage = await ImageMethods.create({ + const coverImage = await imageMethods.create({ params: { collectionId: ombulCoverCollection.id, }, @@ -70,7 +70,7 @@ export async function createOmbul( } })) - NotificationMethods.createSpecial({ + notificationMethods.createSpecial({ params: { special: 'NEW_OMBUL', }, diff --git a/src/services/ombul/validation.ts b/src/services/ombul/validation.ts index f543cd9f2..588f24781 100644 --- a/src/services/ombul/validation.ts +++ b/src/services/ombul/validation.ts @@ -1,13 +1,13 @@ +import { imageFileSchema } from '@/services/images/schemas' import { ValidationBase } from '@/services/Validation' import { maxOmbulFileSize } from '@/services/ombul/ConfigVars' -import { ImageSchemas } from '@/services/images/schemas' import { z } from 'zod' import type { ValidationTypes } from '@/services/Validation' export const baseOmbulValidation = new ValidationBase({ type: { ombulFile: z.instanceof(File), - ombulCoverImage: ImageSchemas.fileSchema, + ombulCoverImage: imageFileSchema, year: z.string().optional(), issueNumber: z.string().optional(), name: z.string(), @@ -15,7 +15,7 @@ export const baseOmbulValidation = new ValidationBase({ }, details: { ombulFile: z.instanceof(File).refine(file => file.size < maxOmbulFileSize, 'Fil må være mindre enn 10mb'), - ombulCoverImage: ImageSchemas.fileSchema, + ombulCoverImage: imageFileSchema, year: z.number().refine(val => (val === undefined) || (val >= 1919 && val <= (new Date()).getFullYear()), 'Må være mellom 1919 og nåværende år' diff --git a/src/services/omegaquotes/create.ts b/src/services/omegaquotes/create.ts index 2928ea6d7..94465ab45 100644 --- a/src/services/omegaquotes/create.ts +++ b/src/services/omegaquotes/create.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { createOmegaquotesValidation } from './validation' import { prismaCall } from '@/services/prismaCall' import { prisma } from '@/prisma/client' -import { NotificationMethods } from '@/services/notifications/methods' +import { notificationMethods } from '@/services/notifications/methods' import type { CreateOmegaguotesTypes } from './validation' import type { OmegaQuote } from '@prisma/client' @@ -28,7 +28,7 @@ export async function createQuote( } })) - NotificationMethods.createSpecial({ + notificationMethods.createSpecial({ params: { special: 'NEW_OMEGAQUOTE', }, diff --git a/src/services/permissions/actions.ts b/src/services/permissions/actions.ts index 65e9cd60d..f7d1a69d0 100644 --- a/src/services/permissions/actions.ts +++ b/src/services/permissions/actions.ts @@ -1,10 +1,10 @@ 'use server' import { action } from '@/services/action' -import { PermissionMethods } from '@/services/permissions/methods' +import { permissionMethods } from '@/services/permissions/methods' -export const readPermissionOfGroupAction = action(PermissionMethods.readPermissionsOfGroup) -export const readPermissionMatrixAction = action(PermissionMethods.readPermissionMatrix) -export const readDefaultPermissionsAction = action(PermissionMethods.readDefaultPermissions) -export const updateDefaultPermissionsAction = action(PermissionMethods.updateDefaultPermissions) -export const updateGroupPermissionAction = action(PermissionMethods.updateGroupPermission) +export const readPermissionOfGroupAction = action(permissionMethods.readPermissionsOfGroup) +export const readPermissionMatrixAction = action(permissionMethods.readPermissionMatrix) +export const readDefaultPermissionsAction = action(permissionMethods.readDefaultPermissions) +export const updateDefaultPermissionsAction = action(permissionMethods.updateDefaultPermissions) +export const updateGroupPermissionAction = action(permissionMethods.updateGroupPermission) diff --git a/src/services/permissions/auther.ts b/src/services/permissions/auther.ts index d91f9fefe..796ad3904 100644 --- a/src/services/permissions/auther.ts +++ b/src/services/permissions/auther.ts @@ -2,11 +2,11 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace PermissionAuthers { - export const readGroupPermissions = RequirePermission.staticFields({ permission: 'PERMISSION_GROUP_READ' }) - export const readPermissionMatrix = RequirePermission.staticFields({ permission: 'PERMISSION_GROUP_READ' }) - export const updateGroupPermission = RequirePermission.staticFields({ permission: 'PERMISSION_GROUP_ADMIN' }) +export const permissionAuthers = { + readGroupPermissions: RequirePermission.staticFields({ permission: 'PERMISSION_GROUP_READ' }), + readPermissionMatrix: RequirePermission.staticFields({ permission: 'PERMISSION_GROUP_READ' }), + updateGroupPermission: RequirePermission.staticFields({ permission: 'PERMISSION_GROUP_ADMIN' }), - export const readDefaultPermissions = RequireNothing.staticFields({}) - export const updateDefaultPermissions = RequirePermission.staticFields({ permission: 'PERMISSION_DEFAULT_ADMIN' }) + readDefaultPermissions: RequireNothing.staticFields({}), + updateDefaultPermissions: RequirePermission.staticFields({ permission: 'PERMISSION_DEFAULT_ADMIN' }), } diff --git a/src/services/permissions/config.ts b/src/services/permissions/config.ts index 02d8ac710..1179af6d5 100644 --- a/src/services/permissions/config.ts +++ b/src/services/permissions/config.ts @@ -20,7 +20,7 @@ export const permissionCategories = [ 'applications', ] as const satisfies string[] -export const PermissionConfig = { +export const permissionConfig = { OMEGAQUOTES_READ: { name: 'Les OmegaQuotes', description: 'kan lese OmegaQuotes', diff --git a/src/services/permissions/methods.ts b/src/services/permissions/methods.ts index df3ef4ab6..450ebdb59 100644 --- a/src/services/permissions/methods.ts +++ b/src/services/permissions/methods.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { PermissionAuthers } from './auther' +import { permissionAuthers } from './auther' import { serviceMethod } from '@/services/serviceMethod' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { invalidateAllUserSessionData, invalidateManyUserSessionData } from '@/services/auth/invalidateSession' @@ -9,22 +9,21 @@ import { Permission } from '@prisma/client' import { z } from 'zod' -export namespace PermissionMethods { - - export const readDefaultPermissions = serviceMethod({ - authorizer: () => PermissionAuthers.readDefaultPermissions.dynamicFields({}), +export const permissionMethods = { + readDefaultPermissions: serviceMethod({ + authorizer: () => permissionAuthers.readDefaultPermissions.dynamicFields({}), method: async ({ prisma }) => (await prisma.defaultPermission.findMany()).map(perm => perm.permission) - }) + }), - export const readPermissionsOfUser = serviceMethod({ + readPermissionsOfUser: serviceMethod({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ userId: z.number(), }), method: async ({ prisma, params }) => { const [defaultPermissions, groupPermissions] = await Promise.all([ - readDefaultPermissions({}), + permissionMethods.readDefaultPermissions({}), prisma.membership.findMany({ where: { userId: params.userId, @@ -44,14 +43,14 @@ export namespace PermissionMethods { const groupPermsFlatten = groupPermissions.map(group => group.group.permissions.map(permission => permission.permission) ).flat() - const ret = defaultPermissions.concat(groupPermsFlatten) + const ret: Permission[] = defaultPermissions.concat(groupPermsFlatten) return ret.filter((permission, i) => ret.indexOf(permission) === i) } - }) + }), - export const readPermissionsOfGroup = serviceMethod({ - authorizer: () => PermissionAuthers.readGroupPermissions.dynamicFields({}), + readPermissionsOfGroup: serviceMethod({ + authorizer: () => permissionAuthers.readGroupPermissions.dynamicFields({}), paramsSchema: z.object({ groupId: z.number() }), @@ -60,10 +59,10 @@ export namespace PermissionMethods { groupId: params.groupId } })).map(permission => permission.permission) - }) + }), - export const readPermissionMatrix = serviceMethod({ - authorizer: () => PermissionAuthers.readPermissionMatrix.dynamicFields({}), + readPermissionMatrix: serviceMethod({ + authorizer: () => permissionAuthers.readPermissionMatrix.dynamicFields({}), method: async ({ prisma }) => { const groupsPermission = await prisma.group.findMany({ include: { @@ -78,10 +77,10 @@ export namespace PermissionMethods { permissions: group.permissions.map(permission => permission.permission) })) } - }) + }), - export const updateDefaultPermissions = serviceMethod({ - authorizer: () => PermissionAuthers.updateDefaultPermissions.dynamicFields({}), + updateDefaultPermissions: serviceMethod({ + authorizer: () => permissionAuthers.updateDefaultPermissions.dynamicFields({}), dataSchema: z.object({ permissions: z.nativeEnum(Permission).array(), }), @@ -106,10 +105,10 @@ export namespace PermissionMethods { return data.permissions } - }) + }), - export const updateGroupPermission = serviceMethod({ - authorizer: () => PermissionAuthers.updateGroupPermission.dynamicFields({}), + updateGroupPermission: serviceMethod({ + authorizer: () => permissionAuthers.updateGroupPermission.dynamicFields({}), paramsSchema: z.object({ groupId: z.number(), permission: z.nativeEnum(Permission), @@ -157,5 +156,5 @@ export namespace PermissionMethods { return data.value } - }) + }), } diff --git a/src/services/serviceMethod.ts b/src/services/serviceMethod.ts index a5895aaa6..80e2b7fc7 100644 --- a/src/services/serviceMethod.ts +++ b/src/services/serviceMethod.ts @@ -8,7 +8,7 @@ import { AsyncLocalStorage } from 'async_hooks' import type { z } from 'zod' import type { Prisma, PrismaClient } from '@prisma/client' import type { SessionMaybeUser } from '@/auth/Session' -import type { AutherStaticFieldsBound } from '@/auth/auther/Auther' +import type { AutherResult } from '@/auth/auther/Auther' /** * This is the type for the prisma client that is passed to the service method. @@ -66,7 +66,6 @@ export type ServiceMethodInputUnchecked = { * I.e. what is passed to the ServiceMethod function when creating a service method. */ type ServiceMethodConfig< - DynamicFields extends object, OpensTransaction extends boolean, Return, ParamsSchema extends z.ZodTypeAny | undefined, @@ -76,9 +75,7 @@ type ServiceMethodConfig< dataSchema?: DataSchema, opensTransaction?: OpensTransaction, authorizer?: (args: ServiceMethodInputParsed & ServiceMethodContext) => - // Todo: Make prettier type for return type of dynamic fields - | ReturnType['dynamicFields']> - | Promise['dynamicFields']>>, + AutherResult| Promise, method: (args: ServiceMethodInputParsed & ServiceMethodContext) => Return | Promise, } @@ -159,13 +156,12 @@ function withContext(contextOverride: Partial, callback * @param [config.opensTransaction=false] - Determines the type of prisma client that is passed to the service method. */ export function serviceMethod< - DynamicFields extends object, OpensTransaction extends boolean, Return, ParamsSchema extends z.ZodTypeAny | undefined = undefined, DataSchema extends z.ZodTypeAny | undefined = undefined, >( - config: ServiceMethodConfig, + config: ServiceMethodConfig, ): ServiceMethod { // Guard to check if params and data are only present if there are corresponding schemas. const expectedInputsIsPresent = ( diff --git a/src/services/shop/actions.ts b/src/services/shop/actions.ts index 08db0529d..dda7d92f6 100644 --- a/src/services/shop/actions.ts +++ b/src/services/shop/actions.ts @@ -1,19 +1,19 @@ 'use server' import { action } from '@/services/action' -import { ProductMethods } from '@/services/shop/product/methods' -import { ShopMethods } from '@/services/shop/shop/methods' +import { productMethods } from '@/services/shop/product/methods' +import { shopMethods } from '@/services/shop/shop/methods' -export const readProductsAction = action(ProductMethods.readMany) -export const readProductAction = action(ProductMethods.read) -export const createProductAction = action(ProductMethods.create) -export const updateProductAction = action(ProductMethods.update) +export const readProductsAction = action(productMethods.readMany) +export const readProductAction = action(productMethods.read) +export const createProductAction = action(productMethods.create) +export const updateProductAction = action(productMethods.update) -export const createProductForShopAction = action(ProductMethods.createForShop) -export const updateProductForShopAction = action(ProductMethods.updateForShop) +export const createProductForShopAction = action(productMethods.createForShop) +export const updateProductForShopAction = action(productMethods.updateForShop) -export const createShopProductConnectionAction = action(ProductMethods.createShopConnection) +export const createShopProductConnectionAction = action(productMethods.createShopConnection) -export const readShopsAction = action(ShopMethods.readMany) -export const readShopAction = action(ShopMethods.read) -export const createShopAction = action(ShopMethods.create) +export const readShopsAction = action(shopMethods.readMany) +export const readShopAction = action(shopMethods.read) +export const createShopAction = action(shopMethods.create) diff --git a/src/services/shop/product/authers.ts b/src/services/shop/product/authers.ts index db48ebf94..3751d9189 100644 --- a/src/services/shop/product/authers.ts +++ b/src/services/shop/product/authers.ts @@ -1,8 +1,8 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace ProductAuthers { - export const read = RequirePermission.staticFields({ permission: 'PRODUCT_READ' }) - export const create = RequirePermission.staticFields({ permission: 'PRODUCT_ADMIN' }) - export const update = RequirePermission.staticFields({ permission: 'PRODUCT_ADMIN' }) - export const createShopConnection = RequirePermission.staticFields({ permission: 'SHOP_ADMIN' }) +export const productAuthers = { + read: RequirePermission.staticFields({ permission: 'PRODUCT_READ' }), + create: RequirePermission.staticFields({ permission: 'PRODUCT_ADMIN' }), + update: RequirePermission.staticFields({ permission: 'PRODUCT_ADMIN' }), + createShopConnection: RequirePermission.staticFields({ permission: 'SHOP_ADMIN' }), } diff --git a/src/services/shop/product/methods.ts b/src/services/shop/product/methods.ts index 11c0ba5f8..e944720d6 100644 --- a/src/services/shop/product/methods.ts +++ b/src/services/shop/product/methods.ts @@ -1,15 +1,15 @@ -import { ProductAuthers } from './authers' -import { ProductSchemas } from './schemas' import { serviceMethod } from '@/services/serviceMethod' import '@pn-server-only' import { ServerError } from '@/services/error' import { z } from 'zod' import type { ExtendedProduct } from './Types' +import { productAuthers } from './authers' +import { productSchemas } from './schemas' -export namespace ProductMethods { - export const create = serviceMethod({ - authorizer: () => ProductAuthers.create.dynamicFields({}), - dataSchema: ProductSchemas.create, +export const productMethods = { + create: serviceMethod({ + authorizer: () => productAuthers.create.dynamicFields({}), + dataSchema: productSchemas.create, method: async ({ prisma, data }) => prisma.product.create({ data: { ...data, @@ -17,14 +17,14 @@ export namespace ProductMethods { name: data.name.toUpperCase() } }) - }) + }), - export const createForShop = serviceMethod({ - authorizer: () => ProductAuthers.create.dynamicFields({}), + createForShop: serviceMethod({ + authorizer: () => productAuthers.create.dynamicFields({}), paramsSchema: z.object({ shopId: z.number(), }), - dataSchema: ProductSchemas.createForShop, + dataSchema: productSchemas.createForShop, method: async ({ prisma, params, data }) => prisma.product.create({ data: { name: data.name.toUpperCase(), @@ -42,11 +42,11 @@ export namespace ProductMethods { }, }, }) - }) + }), - export const createShopConnection = serviceMethod({ - authorizer: () => ProductAuthers.createShopConnection.dynamicFields({}), - dataSchema: ProductSchemas.createShopConnection, + createShopConnection: serviceMethod({ + authorizer: () => productAuthers.createShopConnection.dynamicFields({}), + dataSchema: productSchemas.createShopConnection, method: async ({ prisma, data }) => prisma.shopProduct.create({ data: { shop: { @@ -62,15 +62,15 @@ export namespace ProductMethods { price: data.price, } }) - }) + }), - export const readMany = serviceMethod({ - authorizer: () => ProductAuthers.read.dynamicFields({}), + readMany: serviceMethod({ + authorizer: () => productAuthers.read.dynamicFields({}), method: async ({ prisma }) => await prisma.product.findMany() - }) + }), - export const read = serviceMethod({ - authorizer: () => ProductAuthers.read.dynamicFields({}), + read: serviceMethod({ + authorizer: () => productAuthers.read.dynamicFields({}), paramsSchema: z.object({ productId: z.number(), }), @@ -86,11 +86,11 @@ export namespace ProductMethods { } } }) - }) + }), - export const readByBarCode = serviceMethod({ - authorizer: () => ProductAuthers.read.dynamicFields({}), - dataSchema: ProductSchemas.readByBarCode, + readByBarCode: serviceMethod({ + authorizer: () => productAuthers.read.dynamicFields({}), + dataSchema: productSchemas.readByBarCode, method: async ({ prisma, data }): Promise => { if (!data.barcode) { throw new ServerError('BAD PARAMETERS', 'Barcode is required.') @@ -128,11 +128,11 @@ export namespace ProductMethods { return ret } - }) + }), - export const update = serviceMethod({ - authorizer: () => ProductAuthers.update.dynamicFields({}), - dataSchema: ProductSchemas.update, + update: serviceMethod({ + authorizer: () => productAuthers.update.dynamicFields({}), + dataSchema: productSchemas.update, method: async ({ prisma, data }) => prisma.product.update({ where: { id: data.productId, @@ -143,11 +143,11 @@ export namespace ProductMethods { barcode: convertBarcode(data.barcode), }, }) - }) + }), - export const updateForShop = serviceMethod({ - authorizer: () => ProductAuthers.update.dynamicFields({}), - dataSchema: ProductSchemas.updateForShop, + updateForShop: serviceMethod({ + authorizer: () => productAuthers.update.dynamicFields({}), + dataSchema: productSchemas.updateForShop, paramsSchema: z.object({ shopId: z.number(), productId: z.number(), @@ -176,7 +176,7 @@ export namespace ProductMethods { }, }, }) - }) + }), } export function convertBarcode(barcode?: string | number) { diff --git a/src/services/shop/product/schemas.ts b/src/services/shop/product/schemas.ts index 63771f1b5..f44b7771b 100644 --- a/src/services/shop/product/schemas.ts +++ b/src/services/shop/product/schemas.ts @@ -2,54 +2,53 @@ import { zpn } from '@/lib/fields/zpn' import { convertPrice } from '@/lib/money/convert' import { z } from 'zod' -export namespace ProductSchemas { - const fields = z.object({ - shopId: z.coerce.number().int(), - name: z.string().min(3), - description: z.string(), - price: z.coerce.number().int().min(1).transform((val) => convertPrice(val)), - barcode: z.string().or(z.number()).optional(), - active: zpn.checkboxOrBoolean({ label: 'Active' }), - productId: z.coerce.number().int(), - }) - - export const create = fields.pick({ +const baseSchema = z.object({ + shopId: z.coerce.number().int(), + name: z.string().min(3), + description: z.string(), + price: z.coerce.number().int().min(1).transform((val) => convertPrice(val)), + barcode: z.string().or(z.number()).optional(), + active: zpn.checkboxOrBoolean({ label: 'Active' }), + productId: z.coerce.number().int(), +}) + +export const productSchemas = { + create: baseSchema.pick({ name: true, description: true, barcode: true, - }) + }), - export const update = fields.pick({ + update: baseSchema.pick({ productId: true, name: true, description: true, barcode: true, - }) + }), - export const readByBarCode = fields.pick({ + readByBarCode: baseSchema.pick({ barcode: true, shopId: true, - }) + }), - export const createForShop = fields.pick({ + createForShop: baseSchema.pick({ name: true, description: true, price: true, barcode: true, - }) + }), - export const updateForShop = fields.pick({ + updateForShop: baseSchema.pick({ name: true, description: true, price: true, barcode: true, active: true, - }) + }), - export const createShopConnection = fields.pick({ + createShopConnection: baseSchema.pick({ shopId: true, productId: true, price: true, - }) + }), } - diff --git a/src/services/shop/purchase/authers.ts b/src/services/shop/purchase/authers.ts index b640cf651..3f49f2565 100644 --- a/src/services/shop/purchase/authers.ts +++ b/src/services/shop/purchase/authers.ts @@ -1,8 +1,8 @@ import { RequirePermissionAndDynamicPermission } from '@/auth/auther/RequirePermissionAndDynamicPermission' -export namespace PurchaseAuthers { - export const createByStudentCard = RequirePermissionAndDynamicPermission.staticFields({ +export const purchaseAuthers = { + createByStudentCard: RequirePermissionAndDynamicPermission.staticFields({ permission: 'PURCHASE_CREATE_ONBEHALF', dynamicPermission: 'PURCHASE_CREATE', errorMessage: 'Brukeren har ikke lov til å handle i butikker.' diff --git a/src/services/shop/purchase/methods.ts b/src/services/shop/purchase/methods.ts index 874914fcf..92c51fea1 100644 --- a/src/services/shop/purchase/methods.ts +++ b/src/services/shop/purchase/methods.ts @@ -1,19 +1,19 @@ import '@pn-server-only' -import { PurchaseAuthers } from './authers' -import { PurchaseSchemas } from './schemas' +import { purchaseAuthers } from './authers' +import { purchaseSchemas } from './schemas' import { ServerError } from '@/services/error' import { serviceMethod } from '@/services/serviceMethod' -import { UserMethods } from '@/services/users/methods' -import { UserConfig } from '@/services/users/config' -import { PermissionMethods } from '@/services/permissions/methods' +import { userMethods } from '@/services/users/methods' +import { permissionMethods } from '@/services/permissions/methods' +import { userFilterSelection } from '@/services/users/config' import { PurchaseMethod } from '@prisma/client' -export namespace PurchaseMethods { - export const createByStudentCard = serviceMethod({ +export const purchaseMethods = { + createByStudentCard: serviceMethod({ authorizer: async ({ data }) => { let user try { - user = await UserMethods.read({ + user = await userMethods.read({ params: { studentCard: data.studentCard, }, @@ -26,18 +26,18 @@ export namespace PurchaseMethods { throw e } - const permissions = await PermissionMethods.readPermissionsOfUser({ + const permissions = await permissionMethods.readPermissionsOfUser({ bypassAuth: true, params: { userId: user.id, }, }) - return PurchaseAuthers.createByStudentCard.dynamicFields({ + return purchaseAuthers.createByStudentCard.dynamicFields({ permissions, }) }, - dataSchema: PurchaseSchemas.createFromStudentCard, + dataSchema: purchaseSchemas.createFromStudentCard, method: async ({ prisma, data }) => { if (data.products.length === 0) { throw new ServerError('BAD PARAMETERS', 'The list of products to buy cannot be empty') @@ -47,7 +47,7 @@ export namespace PurchaseMethods { where: { studentCard: data.studentCard, }, - select: UserConfig.filterSelection + select: userFilterSelection, }) // Find the price of the different products @@ -104,5 +104,4 @@ export namespace PurchaseMethods { } } }) - } diff --git a/src/services/shop/purchase/schemas.ts b/src/services/shop/purchase/schemas.ts index a08a445bb..c3f2b2195 100644 --- a/src/services/shop/purchase/schemas.ts +++ b/src/services/shop/purchase/schemas.ts @@ -1,22 +1,21 @@ -import { UserSchemas } from '@/services/users/schemas' +import { studentCardSchema } from '@/services/users/schemas' import { z } from 'zod' -export namespace PurchaseSchemas { - const productsZodObject = z.array(z.object({ - id: z.number().int(), - quantity: z.number().int().min(1) - })) +const productSchema = z.array(z.object({ + id: z.number().int(), + quantity: z.number().int().min(1) +})) - const fields = z.object({ - shopId: z.coerce.number().int(), - studentCard: UserSchemas.studentCardZodValidation, - products: productsZodObject, - }) +const baseSchema = z.object({ + shopId: z.coerce.number().int(), + studentCard: studentCardSchema, + products: productSchema, +}) - export const createFromStudentCard = fields.pick({ +export const purchaseSchemas = { + createFromStudentCard: baseSchema.pick({ shopId: true, products: true, studentCard: true, }) } - diff --git a/src/services/shop/shop/authers.ts b/src/services/shop/shop/authers.ts index 63229066d..8df1d9ff4 100644 --- a/src/services/shop/shop/authers.ts +++ b/src/services/shop/shop/authers.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export namespace ShopAuthers { - export const read = RequirePermission.staticFields({ permission: 'SHOP_READ' }) - export const create = RequirePermission.staticFields({ permission: 'SHOP_ADMIN' }) +export const shopAuthers = { + read: RequirePermission.staticFields({ permission: 'SHOP_READ' }), + create: RequirePermission.staticFields({ permission: 'SHOP_ADMIN' }), } diff --git a/src/services/shop/shop/methods.ts b/src/services/shop/shop/methods.ts index 29b42fb19..f751ec101 100644 --- a/src/services/shop/shop/methods.ts +++ b/src/services/shop/shop/methods.ts @@ -1,26 +1,26 @@ -import { ShopAuthers } from './authers' -import { ShopSchemas } from './schema' import { serviceMethod } from '@/services/serviceMethod' import '@pn-server-only' import { z } from 'zod' import type { ExtendedShop } from './Types' +import { shopSchemas } from './schema' +import { shopAuthers } from './authers' -export namespace ShopMethods { - export const create = serviceMethod({ - dataSchema: ShopSchemas.create, - authorizer: () => ShopAuthers.create.dynamicFields({}), +export const shopMethods = { + create: serviceMethod({ + dataSchema: shopSchemas.create, + authorizer: () => shopAuthers.create.dynamicFields({}), method: async ({ prisma, data }) => prisma.shop.create({ data }) - }) + }), - export const readMany = serviceMethod({ - authorizer: () => ShopAuthers.read.dynamicFields({}), + readMany: serviceMethod({ + authorizer: () => shopAuthers.read.dynamicFields({}), method: ({ prisma }) => prisma.shop.findMany(), - }) + }), - export const read = serviceMethod({ - authorizer: () => ShopAuthers.read.dynamicFields({}), + read: serviceMethod({ + authorizer: () => shopAuthers.read.dynamicFields({}), paramsSchema: z.object({ shopId: z.number(), }), @@ -52,6 +52,6 @@ export namespace ShopMethods { return ret } - }) + }), } diff --git a/src/services/shop/shop/schema.ts b/src/services/shop/shop/schema.ts index c82135a4d..5214f3b51 100644 --- a/src/services/shop/shop/schema.ts +++ b/src/services/shop/shop/schema.ts @@ -1,13 +1,12 @@ import { z } from 'zod' -export namespace ShopSchemas { +const baseSchema = z.object({ + name: z.string().min(3), + description: z.string(), +}) - const fields = z.object({ - name: z.string().min(3), - description: z.string(), - }) - - export const create = fields.pick({ +export const shopSchemas = { + create: baseSchema.pick({ name: true, description: true, }) diff --git a/src/services/users/Types.ts b/src/services/users/Types.ts index 24459dfde..c8b3cbfef 100644 --- a/src/services/users/Types.ts +++ b/src/services/users/Types.ts @@ -1,8 +1,8 @@ +import type { userFieldsToExpose } from './config' import type { MembershipFiltered } from '@/services/groups/memberships/Types' -import type { UserConfig } from './config' import type { OmegaMembershipLevel, User, Image, Permission } from '@prisma/client' -export type UserFiltered = Pick +export type UserFiltered = Pick export type StandardMembeships = { class?: number diff --git a/src/services/users/actions.ts b/src/services/users/actions.ts index 1cc88547a..33b4d3b1a 100644 --- a/src/services/users/actions.ts +++ b/src/services/users/actions.ts @@ -1,22 +1,22 @@ 'use server' import { action } from '@/services/action' -import { GroupMethods } from '@/services/groups/methods' -import { UserMethods } from '@/services/users/methods' +import { groupMethods } from '@/services/groups/methods' +import { userMethods } from '@/services/users/methods' /** * A action that creates a user by the given data. It will also hash the password * @param rawdata - The user to create * @returns - The created user */ -export const createUserAction = action(UserMethods.create) +export const createUserAction = action(userMethods.create) /** * Action to destroy a user by the given id * @param id - The id of the user to destroy * @returns */ -export const destroyUserAction = action(UserMethods.destroy) +export const destroyUserAction = action(userMethods.destroy) /** * A action to read a page of users with the given details (filtering) @@ -24,7 +24,7 @@ export const destroyUserAction = action(UserMethods.destroy) * name and groups * @returns */ -export const readUserPageAction = action(UserMethods.readPage) +export const readUserPageAction = action(userMethods.readPage) /** * Action meant to read the profile of a user. @@ -32,13 +32,13 @@ export const readUserPageAction = action(UserMethods.readPage) * @param username - The username of the user to read * @returns - The profile of the user */ -export const readUserProfileAction = action(UserMethods.readProfile) +export const readUserProfileAction = action(userMethods.readProfile) -export const readUserAction = action(UserMethods.read) +export const readUserAction = action(userMethods.read) -export const readGroupsForPageFilteringAction = action(GroupMethods.readGroupsExpanded) +export const readGroupsForPageFilteringAction = action(groupMethods.readGroupsExpanded) -export const updateUserAction = action(UserMethods.update) -export const registerNewEmailAction = action(UserMethods.registerNewEmail) -export const registerUser = action(UserMethods.register) -export const registerStudentCardInQueueAction = action(UserMethods.registerStudentCardInQueue) +export const updateUserAction = action(userMethods.update) +export const registerNewEmailAction = action(userMethods.registerNewEmail) +export const registerUser = action(userMethods.register) +export const registerStudentCardInQueueAction = action(userMethods.registerStudentCardInQueue) diff --git a/src/services/users/authers.ts b/src/services/users/authers.ts index fba65d30d..1adfdd3e0 100644 --- a/src/services/users/authers.ts +++ b/src/services/users/authers.ts @@ -4,23 +4,22 @@ import { RequireUserId } from '@/auth/auther/RequireUserId' import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' import { RequireUsernameOrPermission } from '@/auth/auther/RequireUsernameOrPermission' -export namespace UserAuthers { - export const readProfile = RequireUsernameOrPermission.staticFields({ permission: 'USERS_READ' }) - export const read = RequireUserFieldOrPermission.staticFields({ permission: 'USERS_READ' }) - export const readOrNull = RequireUserFieldOrPermission.staticFields({ permission: 'USERS_READ' }) - export const readPage = RequirePermission.staticFields({ permission: 'USERS_READ' }) - export const create = RequirePermission.staticFields({ permission: 'USERS_CREATE' }) - export const connectStudentCard = RequirePermission.staticFields({ permission: 'USERS_CONNECT_STUDENT_CARD' }) - export const registerStudentCardInQueue = - RequireUserIdOrPermission.staticFields({ permission: 'USERS_CONNECT_STUDENT_CARD' }) - export const registerNewEmail = RequireUserIdOrPermission.staticFields({ permission: 'USERS_UPDATE' }) - export const updatePassword = RequireUserIdOrPermission.staticFields({ permission: 'USERS_UPDATE' }) - export const update = RequirePermission.staticFields({ permission: 'USERS_UPDATE' }) +export const userAuthers = { + readProfile: RequireUsernameOrPermission.staticFields({ permission: 'USERS_READ' }), + read: RequireUserFieldOrPermission.staticFields({ permission: 'USERS_READ' }), + readOrNull: RequireUserFieldOrPermission.staticFields({ permission: 'USERS_READ' }), + readPage: RequirePermission.staticFields({ permission: 'USERS_READ' }), + create: RequirePermission.staticFields({ permission: 'USERS_CREATE' }), + connectStudentCard: RequirePermission.staticFields({ permission: 'USERS_CONNECT_STUDENT_CARD' }), + registerStudentCardInQueue: RequireUserIdOrPermission.staticFields({ permission: 'USERS_CONNECT_STUDENT_CARD' }), + registerNewEmail: RequireUserIdOrPermission.staticFields({ permission: 'USERS_UPDATE' }), + updatePassword: RequireUserIdOrPermission.staticFields({ permission: 'USERS_UPDATE' }), + update: RequirePermission.staticFields({ permission: 'USERS_UPDATE' }), // TODO: Implement method for updating profile, // IDEA: profile = a user can do it themselvs. Just user - only an admin can do it - export const updateProfile = RequireUsernameOrPermission.staticFields({ permission: 'USERS_UPDATE' }) + updateProfile: RequireUsernameOrPermission.staticFields({ permission: 'USERS_UPDATE' }), - export const register = RequireUserId.staticFields({}) - export const destroy = RequirePermission.staticFields({ permission: 'USERS_DESTROY' }) + register: RequireUserId.staticFields({}), + destroy: RequirePermission.staticFields({ permission: 'USERS_DESTROY' }), } diff --git a/src/services/users/config.ts b/src/services/users/config.ts index 2fdcd0d31..fd21e4d5e 100644 --- a/src/services/users/config.ts +++ b/src/services/users/config.ts @@ -1,62 +1,60 @@ import { createSelection } from '@/services/createSelection' import type { Prisma, User, SEX } from '@prisma/client' -export namespace UserConfig { - export const maxNumberOfGroupsInFilter = 7 - export const studentCardRegistrationExpiry = 2 // minutter +export const maxNumberOfGroupsInFilter = 7 +export const studentCardRegistrationExpiry = 2 // minutter - // TODO: This needs to be divived into seperate filters, depending on how much information is needed - export const fieldsToExpose = [ - 'id', - 'username', - 'firstname', - 'lastname', - 'email', - 'emailVerified', - 'mobile', - 'createdAt', - 'updatedAt', - 'acceptedTerms', - 'sex', - 'allergies', - ] as const satisfies (keyof User)[] +// TODO: This needs to be divived into seperate filters, depending on how much information is needed +export const userFieldsToExpose = [ + 'id', + 'username', + 'firstname', + 'lastname', + 'email', + 'emailVerified', + 'mobile', + 'createdAt', + 'updatedAt', + 'acceptedTerms', + 'sex', + 'allergies', +] as const satisfies (keyof User)[] - export const filterSelection = createSelection([...fieldsToExpose]) +export const userFilterSelection = createSelection([...userFieldsToExpose]) - export const standardMembershipSelection = [ - { - group: { - groupType: 'CLASS' - } - }, - { - group: { - groupType: 'OMEGA_MEMBERSHIP_GROUP' - } - }, - { - group: { - groupType: 'STUDY_PROGRAMME' - } - }, - ] satisfies Prisma.MembershipWhereInput[] +export const standardMembershipSelection = [ + { + group: { + groupType: 'CLASS' + } + }, + { + group: { + groupType: 'OMEGA_MEMBERSHIP_GROUP' + } + }, + { + group: { + groupType: 'STUDY_PROGRAMME' + } + }, +] satisfies Prisma.MembershipWhereInput[] - export const sexConfig = { - MALE: { - title: 'Broder', - pronoun: 'Hands', - label: 'Mann', - }, - FEMALE: { - title: 'Syster', - pronoun: 'Hendes', - label: 'Kvinne', - }, - OTHER: { - title: 'Søsken', - pronoun: 'Hends', - label: 'Annet', - } - } as const satisfies { [key in SEX]: { title: string, pronoun: string, label: string } } -} +export const sexConfig = { + MALE: { + title: 'Broder', + pronoun: 'Hands', + label: 'Mann', + }, + FEMALE: { + title: 'Syster', + pronoun: 'Hendes', + label: 'Kvinne', + }, + OTHER: { + title: 'Søsken', + pronoun: 'Hends', + label: 'Annet', + } +} as const satisfies { [key in SEX]: { title: string, pronoun: string, label: string } } diff --git a/src/services/users/methods.ts b/src/services/users/methods.ts index 038fde9cc..e190cd347 100644 --- a/src/services/users/methods.ts +++ b/src/services/users/methods.ts @@ -1,34 +1,39 @@ import '@pn-server-only' -import { UserAuthers } from './authers' -import { UserConfig } from './config' -import { NotificationSubscriptionMethods } from '@/services/notifications/subscription/methods' +import { userSchemas } from './schemas' +import { userAuthers } from './authers' +import { + maxNumberOfGroupsInFilter, + standardMembershipSelection, + studentCardRegistrationExpiry, + userFilterSelection +} from './config' +import { imageMethods } from '@/services/images/methods' +import { notificationSubscriptionMethods } from '@/services/notifications/subscription/methods' import { readMembershipsOfUser } from '@/services/groups/memberships/read' import { NTNUEmailDomain } from '@/services/mail/mailAddressExternal/ConfigVars' import { sendVerifyEmail } from '@/services/notifications/email/systemMail/verifyEmail' import { updateUserOmegaMembershipGroup } from '@/services/groups/omegaMembershipGroups/update' import { sendUserInvitationEmail } from '@/services/notifications/email/systemMail/userInvitivation' import { readOmegaMembershipGroup } from '@/services/groups/omegaMembershipGroups/read' -import { UserSchemas } from '@/services/users/schemas' import { serviceMethod } from '@/services/serviceMethod' -import { ImageMethods } from '@/services/images/methods' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { ServerError } from '@/services/error' import { getMembershipFilter } from '@/auth/getMembershipFilter' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { hashAndEncryptPassword } from '@/auth/password' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' -import { PermissionMethods } from '@/services/permissions/methods' +import { permissionMethods } from '@/services/permissions/methods' import { z } from 'zod' import type { UserPagingReturn } from './Types' -export namespace UserMethods { +export const userMethods = { /** * This Method creates an user by invitation, and sends the invitation email. * WARNING: This should not be used to create users registered by Feide. */ - export const create = serviceMethod({ - dataSchema: UserSchemas.create, - authorizer: () => UserAuthers.create.dynamicFields({}), + create: serviceMethod({ + dataSchema: userSchemas.create, + authorizer: () => userAuthers.create.dynamicFields({}), method: async ({ prisma, data }) => { const omegaMembership = await readOmegaMembershipGroup('EXTERNAL') const omegaOrder = await readCurrentOmegaOrder() @@ -54,55 +59,55 @@ export namespace UserMethods { return user } - }) + }), - export const read = serviceMethod({ + read: serviceMethod({ paramsSchema: z.object({ username: z.string().optional(), id: z.coerce.number().optional(), email: z.string().optional(), studentCard: z.string().optional(), }), - authorizer: ({ params }) => UserAuthers.read.dynamicFields(params), + authorizer: ({ params }) => userAuthers.read.dynamicFields(params), method: async ({ prisma, params }) => await prisma.user.findUniqueOrThrow({ where: { id: params.id, ...params }, - select: UserConfig.filterSelection + select: userFilterSelection }) - }) + }), - export const readOrNull = serviceMethod({ + readOrNull: serviceMethod({ paramsSchema: z.object({ username: z.string().optional(), id: z.coerce.number().optional(), email: z.string().optional(), studentCard: z.string().optional(), }), - authorizer: ({ params }) => UserAuthers.read.dynamicFields(params), + authorizer: ({ params }) => userAuthers.read.dynamicFields(params), method: async ({ prisma, params }) => await prisma.user.findUnique({ where: { id: params.id, // This is a bit wierd, but now ts is satisfied. ...params }, - select: UserConfig.filterSelection + select: userFilterSelection }) - }) + }), - export const readProfile = serviceMethod({ + readProfile: serviceMethod({ paramsSchema: z.object({ username: z.string(), }), - authorizer: ({ params }) => UserAuthers.readProfile.dynamicFields({ username: params.username }), + authorizer: ({ params }) => userAuthers.readProfile.dynamicFields({ username: params.username }), method: async ({ prisma, params }) => { - const defaultProfileImage = await ImageMethods.readSpecial({ + const defaultProfileImage = await imageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, }) const user = await prisma.user.findUniqueOrThrow({ where: { username: params.username.toLowerCase() }, select: { - ...UserConfig.filterSelection, + ...userFilterSelection, bio: true, image: true, }, @@ -112,7 +117,7 @@ export namespace UserMethods { })) const memberships = await readMembershipsOfUser(user.id) - const permissions = await PermissionMethods.readPermissionsOfUser({ + const permissions = await permissionMethods.readPermissionsOfUser({ bypassAuth: true, params: { userId: user.id @@ -121,9 +126,9 @@ export namespace UserMethods { return { user, memberships, permissions } } - }) + }), - export const readPage = serviceMethod({ + readPage: serviceMethod({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -141,12 +146,12 @@ export namespace UserMethods { }).nullable().optional() }) ), - authorizer: () => UserAuthers.readPage.dynamicFields({}), + authorizer: () => userAuthers.readPage.dynamicFields({}), method: async ({ prisma, params }): Promise => { const { page, details } = params.paging const words = details.partOfName.split(' ') - if (details.groups.length > UserConfig.maxNumberOfGroupsInFilter) { + if (details.groups.length > maxNumberOfGroupsInFilter) { throw new ServerError('BAD PARAMETERS', 'Too many groups in filter') } const groupSelection = details.selectedGroup ? [ @@ -158,7 +163,7 @@ export namespace UserMethods { const users = await prisma.user.findMany({ ...cursorPageingSelection(page), select: { - ...UserConfig.filterSelection, + ...userFilterSelection, memberships: { select: { admin: true, @@ -177,7 +182,7 @@ export namespace UserMethods { { AND: [ { - OR: UserConfig.standardMembershipSelection, + OR: standardMembershipSelection, }, getMembershipFilter('ACTIVE') ] @@ -248,11 +253,11 @@ export namespace UserMethods { } }) } - }) + }), - export const connectStudentCard = serviceMethod({ - authorizer: () => UserAuthers.connectStudentCard.dynamicFields({}), - dataSchema: UserSchemas.connectStudentCard, + connectStudentCard: serviceMethod({ + authorizer: () => userAuthers.connectStudentCard.dynamicFields({}), + dataSchema: userSchemas.connectStudentCard, opensTransaction: true, method: async ({ prisma, data }) => { const currentQueue = await prisma.registerStudentCardQueue.findMany({ @@ -288,21 +293,21 @@ export namespace UserMethods { data: { studentCard: data.studentCard, }, - select: UserConfig.filterSelection, + select: userFilterSelection, }) ]) return result[1] } - }) + }), - export const registerStudentCardInQueue = serviceMethod({ + registerStudentCardInQueue: serviceMethod({ paramsSchema: z.object({ userId: z.number(), }), - authorizer: ({ params }) => UserAuthers.registerStudentCardInQueue.dynamicFields(params), + authorizer: ({ params }) => userAuthers.registerStudentCardInQueue.dynamicFields(params), method: async (args) => { - const expiry = (new Date()).getTime() + UserConfig.studentCardRegistrationExpiry * 60 * 1000 + const expiry = (new Date()).getTime() + studentCardRegistrationExpiry * 60 * 1000 await args.prisma.registerStudentCardQueue.upsert({ where: { userId: args.params.userId, @@ -320,25 +325,25 @@ export namespace UserMethods { } }) } - }) + }), - export const update = serviceMethod({ + update: serviceMethod({ paramsSchema: z.union([z.object({ id: z.number() }), z.object({ username: z.string() })]), - dataSchema: UserSchemas.update, - authorizer: () => UserAuthers.update.dynamicFields({}), + dataSchema: userSchemas.update, + authorizer: () => userAuthers.update.dynamicFields({}), method: async ({ prisma: prisma_, params, data }) => prisma_.user.update({ where: params, data }) - }) + }), - export const updatePassword = serviceMethod({ + updatePassword: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - dataSchema: UserSchemas.updatePassword, - authorizer: ({ params }) => UserAuthers.updatePassword.dynamicFields({ userId: params.id }), + dataSchema: userSchemas.updatePassword, + authorizer: ({ params }) => userAuthers.updatePassword.dynamicFields({ userId: params.id }), method: async ({ prisma, data, params }) => { const passwordHash = await hashAndEncryptPassword(data.password) @@ -353,21 +358,21 @@ export namespace UserMethods { return null } - }) + }), - export const registerNewEmail = serviceMethod({ + registerNewEmail: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - authorizer: ({ params }) => UserAuthers.registerNewEmail.dynamicFields({ userId: params.id }), - dataSchema: UserSchemas.registerNewEmail, + authorizer: ({ params }) => userAuthers.registerNewEmail.dynamicFields({ userId: params.id }), + dataSchema: userSchemas.registerNewEmail, method: async ({ prisma, params, data }) => { const storedUser = await prisma.user.findUniqueOrThrow({ where: { id: params.id, }, select: { - ...UserConfig.filterSelection, + ...userFilterSelection, feideAccount: { select: { email: true, @@ -409,7 +414,7 @@ export namespace UserMethods { email: data.email, } } - }) + }), /** * This function completes the last step of user creation: registration. @@ -419,12 +424,12 @@ export namespace UserMethods { * @param rawdata - Registration data. * @returns null */ - export const register = serviceMethod({ + register: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - dataSchema: UserSchemas.register, - authorizer: ({ params }) => UserAuthers.register.dynamicFields({ userId: params.id }), + dataSchema: userSchemas.register, + authorizer: ({ params }) => userAuthers.register.dynamicFields({ userId: params.id }), opensTransaction: true, method: async ({ prisma, data, params }) => { const { sex, password, mobile, allergies } = data @@ -477,7 +482,7 @@ export namespace UserMethods { mobile, allergies, }, - select: UserConfig.filterSelection + select: userFilterSelection }), prisma.credentials.upsert({ where: { @@ -498,7 +503,7 @@ export namespace UserMethods { ]) try { - await NotificationSubscriptionMethods.createDefault({ + await notificationSubscriptionMethods.createDefault({ params: { userId: params.id, }, @@ -523,9 +528,10 @@ export namespace UserMethods { return results[0] } - }) - export const readUserWithBalance = serviceMethod({ - authorizer: ({ params }) => UserAuthers.read.dynamicFields({ + }), + + readUserWithBalance: serviceMethod({ + authorizer: ({ params }) => userAuthers.read.dynamicFields({ username: params.username || '', }), paramsSchema: z.object({ @@ -547,17 +553,17 @@ export namespace UserMethods { user, } } - }) + }), //TODO: Make soft delete? /** * This function deletes a user from the database. */ - export const destroy = serviceMethod({ + destroy: serviceMethod({ paramsSchema: z.object({ id: z.number(), }), - authorizer: () => UserAuthers.destroy.dynamicFields({}), + authorizer: () => userAuthers.destroy.dynamicFields({}), method: async ({ prisma, params }) => { await prisma.user.delete({ where: { @@ -565,5 +571,5 @@ export namespace UserMethods { } }) } - }) + }), } diff --git a/src/services/users/schemas.ts b/src/services/users/schemas.ts index 00ab69647..0f6d0172f 100644 --- a/src/services/users/schemas.ts +++ b/src/services/users/schemas.ts @@ -2,71 +2,71 @@ import { zpn } from '@/lib/fields/zpn' import { SEX } from '@prisma/client' import { z } from 'zod' -export namespace UserSchemas { - export const studentCardZodValidation = z.string() +export const studentCardSchema = z.string() - export const fields = z.object({ - username: z.string().max(50).min(2).toLowerCase(), - sex: z.nativeEnum(SEX).optional().nullable(), - email: z.string().max(200).min(2).email(), - emailVerified: z.string().datetime({}).optional().nullable(), - mobile: z.string().regex(/^\+?\d{4,20}$/, { message: 'Skriv kun tall, uten mellomrom.' }), - firstname: z.string().max(50).min(2), - lastname: z.string().max(50).min(2), - allergies: z.string().max(150).optional().nullable(), - studentCard: studentCardZodValidation, - password: z.string().max(50).min(12, { - // eslint-disable-next-line - message: 'Passoret må minst ha 12 tegn, en stor og en liten bokstav, et tall, en rune, to emojier, en musikk note, en magisk sopp og en dråpe smørekopp-blod (avsky).' - }), - confirmPassword: z.string().max(50).min(12), - acceptedTerms: zpn.checkboxOrBoolean({ - label: 'Accepted terms', - }).refine(value => value, 'Du må godta vilkårene for å bruke siden.'), - }) - const refinePassword = { - fcn: (data: { password?: string, confirmPassword?: string }) => data.password === data.confirmPassword, - message: 'Passordene må være like' - } +export const userSchema = z.object({ + username: z.string().max(50).min(2).toLowerCase(), + sex: z.nativeEnum(SEX).optional().nullable(), + email: z.string().max(200).min(2).email(), + emailVerified: z.string().datetime({}).optional().nullable(), + mobile: z.string().regex(/^\+?\d{4,20}$/, { message: 'Skriv kun tall, uten mellomrom.' }), + firstname: z.string().max(50).min(2), + lastname: z.string().max(50).min(2), + allergies: z.string().max(150).optional().nullable(), + studentCard: studentCardSchema, + password: z.string().max(50).min(12, { + // eslint-disable-next-line + message: 'Passoret må minst ha 12 tegn, en stor og en liten bokstav, et tall, en rune, to emojier, en musikk note, en magisk sopp og en dråpe smørekopp-blod (avsky).' + }), + confirmPassword: z.string().max(50).min(12), + acceptedTerms: zpn.checkboxOrBoolean({ + label: 'Accepted terms', + }).refine(value => value, 'Du må godta vilkårene for å bruke siden.'), +}) +const refinePassword = { + fcn: (data: { password?: string, confirmPassword?: string }) => data.password === data.confirmPassword, + message: 'Passordene må være like' +} - export const create = fields.pick({ +export const userSchemas = { + create: userSchema.pick({ email: true, firstname: true, lastname: true, username: true, emailVerified: true, - }) + }), - export const update = fields.partial().pick({ + update: userSchema.partial().pick({ email: true, firstname: true, lastname: true, username: true, - }) + }), - export const register = fields.pick({ + register: userSchema.pick({ mobile: true, allergies: true, password: true, confirmPassword: true, sex: true, acceptedTerms: true, - }).refine(refinePassword.fcn, refinePassword.message) + }).refine(refinePassword.fcn, refinePassword.message), - export const updatePassword = fields.pick({ + updatePassword: userSchema.pick({ password: true, confirmPassword: true, - }).refine(refinePassword.fcn, refinePassword.message) + }).refine(refinePassword.fcn, refinePassword.message), - export const registerNewEmail = fields.pick({ + registerNewEmail: userSchema.pick({ email: true, - }) + }), - export const connectStudentCard = fields.pick({ + connectStudentCard: userSchema.pick({ studentCard: true, - }) + }), - export const verifyEmail = fields.pick({ + verifyEmail: userSchema.pick({ email: true, - }) + }), } diff --git a/src/services/visibility/ConfigVars.ts b/src/services/visibility/ConfigVars.ts index 0928cbb58..b2bd7eb87 100644 --- a/src/services/visibility/ConfigVars.ts +++ b/src/services/visibility/ConfigVars.ts @@ -14,7 +14,7 @@ export const BypassPermissions = { export type BypassPermissions = typeof BypassPermissions[keyof typeof BypassPermissions] -export const PurposeTextsConfig = { +export const purposeTextsConfig = { IMAGE: 'Bilder', NEWS_ARTICLE: 'Nyheter', ARTICLE_CATEGORY: 'Artikkelkategorier', @@ -26,7 +26,7 @@ export const PurposeTextsConfig = { * Which permissions link to special visibility purposes * If the special visibility were to disappear, it will be regenerated from this. */ -export const SpecialVisibilityConfig = { +export const specialVisibilityConfig = { OMBUL: { regularLevel: 'OMBUL_READ', adminLevel: 'OMBUL_CREATE' diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index 12535e7a7..dc27c0987 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -3,9 +3,9 @@ import { createActionError, safeServerCall } from '@/services/actionError' import { checkVisibility } from '@/auth/checkVisibility' import { getUser } from '@/auth/getUser' -import { GroupTypesConfig } from '@/services/groups/config' -import { GroupMethods } from '@/services/groups/methods' -import { PurposeTextsConfig } from '@/services/visibility/ConfigVars' +import { groupTypesConfig } from '@/services/groups/config' +import { groupMethods } from '@/services/groups/methods' +import { purposeTextsConfig } from '@/services/visibility/ConfigVars' import { readVisibilityCollapsed } from '@/services/visibility/read' import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' import type { ActionReturn } from '@/services/actionTypes' @@ -21,13 +21,13 @@ export async function readVisibilityForAdminAction(id: number): Promise readVisibilityCollapsed(id)), // TODO: Fix Authing here. The bypass should be false - safeServerCall(() => GroupMethods.readGroupsStructured({ bypassAuth: true })) + safeServerCall(() => groupMethods.readGroupsStructured({ bypassAuth: true })) ]) if (!visibilityRes.success || !groupsRes.success) return createActionError('UNKNOWN ERROR', 'noe gikk galt') const visibility = visibilityRes.data const groups = groupsRes.data - const purpose = PurposeTextsConfig[visibility.purpose] + const purpose = purposeTextsConfig[visibility.purpose] if (!checkVisibility(await getUser(), visibility, 'ADMIN')) { return createActionError('UNAUTHORIZED', 'You do not have permission to admin this collection') @@ -69,7 +69,7 @@ function expandOneLevel( standardGroupings.forEach(groupType => { if (!groups[groupType]) return const standardRequriment: VisibilityRequiermentForAdmin = { - name: GroupTypesConfig[groupType].name, + name: groupTypesConfig[groupType].name, groups: groups[groupType].groups.map(group => ({ ...group, selected: false diff --git a/src/services/visibility/read.ts b/src/services/visibility/read.ts index 7536df68a..4c0516bec 100644 --- a/src/services/visibility/read.ts +++ b/src/services/visibility/read.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { SpecialVisibilityConfig } from './ConfigVars' +import { specialVisibilityConfig } from './ConfigVars' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { prisma } from '@/prisma/client' @@ -75,12 +75,12 @@ export async function readSpecialVisibility(specialPurpose: SpecialVisibilityPur published: true, regularLevel: { create: { - permission: SpecialVisibilityConfig[specialPurpose].regularLevel + permission: specialVisibilityConfig[specialPurpose].regularLevel } }, adminLevel: { create: { - permission: SpecialVisibilityConfig[specialPurpose].adminLevel + permission: specialVisibilityConfig[specialPurpose].adminLevel } }, }, diff --git a/tests/services/jobads.test.ts b/tests/services/jobads.test.ts index 8f4a67eae..b78f86574 100644 --- a/tests/services/jobads.test.ts +++ b/tests/services/jobads.test.ts @@ -1,7 +1,7 @@ import { Session } from '@/auth/Session' import { Smorekopp } from '@/services/error' import { prisma } from '@/prisma/client' -import { JobadMethods } from '@/services/career/jobAds/methods' +import { jobAdMethods } from '@/services/career/jobAds/methods' import { afterEach, beforeAll, describe, expect, test } from '@jest/globals' // NOTE: This is file contains a lot of boiler plate which should be refactored to be more reusable. @@ -39,7 +39,7 @@ afterEach(async () => { const jobAds = await prisma.jobAd.findMany() await Promise.all(jobAds.map(jobAd => - JobadMethods.destroy({ + jobAdMethods.destroy({ params: { id: jobAd.id }, @@ -50,7 +50,7 @@ afterEach(async () => { describe('job ads', () => { test('create with unauthenticated user', async () => { - expect(JobadMethods.create({ + expect(jobAdMethods.create({ data: CREATE_JOB_AD, session: Session.empty() })).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) @@ -69,7 +69,7 @@ describe('job ads', () => { user: null, }) - await JobadMethods.create({ data: CREATE_JOB_AD, session }) + await jobAdMethods.create({ data: CREATE_JOB_AD, session }) const res = await prisma.jobAd.findFirst({}) expect(res).toMatchObject(CREATE_JOB_AD) @@ -77,18 +77,18 @@ describe('job ads', () => { test('(create and then) read with unauthenticated user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create({ + const createRes = await jobAdMethods.create({ data: CREATE_JOB_AD, bypassAuth: true }) - expect(JobadMethods.read({ params: { idOrName: createRes.id }, session: Session.empty() })) + expect(jobAdMethods.read({ params: { idOrName: createRes.id }, session: Session.empty() })) .rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) }) test('(create and then) read with authorized user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create({ + const createRes = await jobAdMethods.create({ data: CREATE_JOB_AD, bypassAuth: true }) @@ -99,18 +99,18 @@ describe('job ads', () => { user: null, }) - const readRes = await JobadMethods.read({ params: { idOrName: createRes.id }, session }) + const readRes = await jobAdMethods.read({ params: { idOrName: createRes.id }, session }) expect(readRes).toMatchObject(CREATE_JOB_AD) }) test('update with unauthenticated user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create({ + const createRes = await jobAdMethods.create({ data: CREATE_JOB_AD, bypassAuth: true }) - expect(JobadMethods.update({ + expect(jobAdMethods.update({ params: { id: createRes.id, }, @@ -124,7 +124,7 @@ describe('job ads', () => { test('update with authorized user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create({ + const createRes = await jobAdMethods.create({ data: CREATE_JOB_AD, bypassAuth: true }) @@ -135,7 +135,7 @@ describe('job ads', () => { user: null, }) - await JobadMethods.update({ + await jobAdMethods.update({ params: { id: createRes.id, }, @@ -149,12 +149,12 @@ describe('job ads', () => { test('destroy with unauthenticated user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create({ + const createRes = await jobAdMethods.create({ data: CREATE_JOB_AD, bypassAuth: true }) - expect(JobadMethods.destroy({ params: { id: createRes.id }, session: Session.empty() })) + expect(jobAdMethods.destroy({ params: { id: createRes.id }, session: Session.empty() })) .rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) const count = await prisma.jobAd.count() @@ -163,7 +163,7 @@ describe('job ads', () => { test('destroy with authorized user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await JobadMethods.create({ + const createRes = await jobAdMethods.create({ data: CREATE_JOB_AD, bypassAuth: true }) @@ -174,7 +174,7 @@ describe('job ads', () => { user: null, }) - await JobadMethods.destroy({ params: { id: createRes.id }, session }) + await jobAdMethods.destroy({ params: { id: createRes.id }, session }) const count = await prisma.jobAd.count() expect(count).toBe(0) From a18866df137328243f949a11c19b5ab10ed70572 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Fri, 10 Oct 2025 21:40:13 +0200 Subject: [PATCH 18/24] refactor: rename service method to service operation --- src/app/api/apiHandler.ts | 4 +- src/lib/fields/zpn.ts | 2 +- src/services/action.ts | 12 +-- src/services/admission/methods.ts | 10 +- src/services/api-keys/methods.ts | 30 +++--- src/services/api-keys/schemas.ts | 6 +- src/services/applications/methods.ts | 18 ++-- src/services/applications/periods/methods.ts | 30 +++--- src/services/applications/periods/schemas.ts | 10 +- src/services/auth/methods.ts | 18 ++-- src/services/cabin/booking/methods.ts | 46 ++++----- src/services/cabin/booking/schemas.ts | 4 +- src/services/cabin/pricePeriod/methods.ts | 26 ++--- src/services/cabin/pricePeriod/schemas.ts | 4 +- src/services/cabin/product/methods.ts | 22 ++--- src/services/cabin/product/schemas.ts | 4 +- src/services/cabin/releasePeriod/methods.ts | 22 ++--- src/services/career/companies/methods.ts | 20 ++-- src/services/career/jobAds/methods.ts | 26 ++--- src/services/career/jobAds/schemas.ts | 6 +- src/services/cms/links/read.ts | 6 +- src/services/dots/methods.ts | 18 ++-- src/services/events/methods.ts | 26 ++--- src/services/events/registration/methods.ts | 26 ++--- src/services/events/schemas.ts | 16 +-- src/services/events/tags/methods.ts | 26 ++--- src/services/groups/committees/methods.ts | 26 ++--- src/services/groups/interestGroups/methods.ts | 22 ++--- src/services/groups/methods.ts | 38 +++---- src/services/images/methods.ts | 34 +++---- src/services/licenses/methods.ts | 18 ++-- src/services/lockers/locations/methods.ts | 10 +- src/services/lockers/methods.ts | 16 +-- src/services/lockers/reservations/methods.ts | 14 +-- src/services/notifications/channel/methods.ts | 22 ++--- src/services/notifications/methods.ts | 10 +- .../notifications/subscription/methods.ts | 14 +-- src/services/permissions/methods.ts | 26 ++--- .../{serviceMethod.ts => serviceOperation.ts} | 99 ++++++++++--------- src/services/shop/product/methods.ts | 34 +++---- src/services/shop/product/schemas.ts | 4 +- src/services/shop/purchase/methods.ts | 6 +- src/services/shop/shop/methods.ts | 14 +-- src/services/users/methods.ts | 54 +++++----- src/services/users/schemas.ts | 4 +- tests/services/service-method.test.ts | 14 +-- 46 files changed, 460 insertions(+), 457 deletions(-) rename src/services/{serviceMethod.ts => serviceOperation.ts} (68%) diff --git a/src/app/api/apiHandler.ts b/src/app/api/apiHandler.ts index 8b8f9e3fb..845767689 100644 --- a/src/app/api/apiHandler.ts +++ b/src/app/api/apiHandler.ts @@ -1,8 +1,8 @@ import '@pn-server-only' import { Session } from '@/auth/Session' import { getHttpErrorCode, ServerError, Smorekopp } from '@/services/error' +import type { ServiceOperation } from '@/services/serviceOperation' import type { ErrorCode, ErrorMessage } from '@/services/error' -import type { ServiceMethod } from '@/services/serviceMethod' import type { SessionNoUser } from '@/auth/Session' import type { z } from 'zod' @@ -12,7 +12,7 @@ type APIHandler< ParamsSchema extends z.ZodTypeAny | undefined = undefined, DataSchema extends z.ZodTypeAny | undefined = undefined, > = { - serviceMethod: ServiceMethod, + serviceMethod: ServiceOperation, } & (ParamsSchema extends undefined ? { params?: undefined, } : { diff --git a/src/lib/fields/zpn.ts b/src/lib/fields/zpn.ts index 6dc0d023c..c49792c96 100644 --- a/src/lib/fields/zpn.ts +++ b/src/lib/fields/zpn.ts @@ -4,7 +4,7 @@ import { z } from 'zod' import { zfd } from 'zod-form-data' import type { EnumLike } from 'zod' -export namespace zpn { +export namespace Zpn { /** * This field is used to represent a boolean that could be a checkbox in frontend with no specified value * That is: the value is 'on' or not present at all (default behavior of checkboxes) diff --git a/src/services/action.ts b/src/services/action.ts index 92f08f0f5..76bb67609 100644 --- a/src/services/action.ts +++ b/src/services/action.ts @@ -2,24 +2,24 @@ import '@pn-server-only' import { safeServerCall } from './actionError' import { Session } from '@/auth/Session' import type { ActionReturn } from './actionTypes' -import type { ServiceMethod } from '@/services/serviceMethod' +import type { ServiceOperation } from '@/services/serviceOperation' import type { z } from 'zod' export function action( - serviceMethod: ServiceMethod + serviceMethod: ServiceOperation ): () => Promise> export function action( - serviceMethod: ServiceMethod + serviceMethod: ServiceOperation ): (params: z.input) => Promise> export function action( - serviceMethod: ServiceMethod + serviceMethod: ServiceOperation ): (data: z.input | FormData) => Promise> // This function is overloaded to allow for different combinations of parameters and data. export function action( - serviceMethod: ServiceMethod + serviceMethod: ServiceOperation ): (params: z.input, data: z.input | FormData) => Promise> /** @@ -33,7 +33,7 @@ export function action< ParamsSchema extends z.ZodTypeAny | undefined = undefined, DataSchema extends z.ZodTypeAny | undefined = undefined, >( - serviceMethod: ServiceMethod + serviceMethod: ServiceOperation ) { // Letting the arguments to the actual function be unknown is safer as anything can be passed to it form the client. // The action and service method will validate the parameter and data before it is used. diff --git a/src/services/admission/methods.ts b/src/services/admission/methods.ts index 5e6712b82..dbd5d086b 100644 --- a/src/services/admission/methods.ts +++ b/src/services/admission/methods.ts @@ -2,31 +2,31 @@ import '@pn-server-only' import { admissionSchemas } from './schemas' import { admissionAuthers } from './authers' import { userFilterSelection } from '@/services/users/config' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { updateUserOmegaMembershipGroup } from '@/services/groups/omegaMembershipGroups/update' import { Admission } from '@prisma/client' import { z } from 'zod' import type { ExpandedAdmissionTrail } from './Types' export const admissionMethods = { - readTrial: serviceMethod({ + readTrial: defineOperation({ authorizer: () => admissionAuthers.readTrial.dynamicFields({}), paramsSchema: z.object({ userId: z.number(), }), - method: async ({ prisma, params: { userId } }) => await prisma.admissionTrial.findMany({ + operation: async ({ prisma, params: { userId } }) => await prisma.admissionTrial.findMany({ where: { userId, } }) }), - createTrial: serviceMethod({ + createTrial: defineOperation({ authorizer: () => admissionAuthers.createTrial.dynamicFields({}), paramsSchema: z.object({ admission: z.nativeEnum(Admission), }), dataSchema: admissionSchemas.createTrial, - method: async ({ prisma, session, params, data }): Promise => { + operation: async ({ prisma, session, params, data }): Promise => { const results = await prisma.admissionTrial.create({ data: { user: { diff --git a/src/services/api-keys/methods.ts b/src/services/api-keys/methods.ts index 5eb7c43fb..1d61f61a1 100644 --- a/src/services/api-keys/methods.ts +++ b/src/services/api-keys/methods.ts @@ -5,7 +5,7 @@ import { apiKeyHashAndEncrypt } from './hashEncryptKey' import { encodeApiKey } from './apiKeyEncoder' import { apiFilterSelection, apiKeyLength } from './config' import { ServerError } from '@/services/error' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import logger from '@/lib/logger' import { z } from 'zod' import crypto from 'crypto' @@ -17,14 +17,14 @@ import type { ApiKeyFiltered, ApiKeyFilteredWithKey } from './Types' * * Note: This operaiton is only used internally. */ -const updateIfExpired = serviceMethod({ +const updateIfExpired = defineOperation({ authorizer: () => apiKeyAuthers.updateIfExpired.dynamicFields({}), paramsSchema: z.object({ id: z.number(), expiresAt: z.date().nullable(), active: z.boolean(), }), - method: async ({ prisma, params: apiKey }) => { + operation: async ({ prisma, params: apiKey }) => { if (!apiKey) { throw new ServerError('NOT FOUND', 'Nøkkelen finnes ikke') } @@ -44,10 +44,10 @@ const updateIfExpired = serviceMethod({ }) export const apiKeyMethods = { - create: serviceMethod({ + create: defineOperation({ authorizer: () => apiKeyAuthers.create.dynamicFields({}), dataSchema: apiKeySchemas.create, - method: async ({ prisma, data }): Promise => { + operation: async ({ prisma, data }): Promise => { const NODE_ENV = process.env.NODE_ENV const prepend = NODE_ENV === 'production' ? 'prod' : 'dev' @@ -65,10 +65,10 @@ export const apiKeyMethods = { return { ...apiKey, key: encodeApiKey({ key, id: apiKey.id }) } } }), - read: serviceMethod({ + read: defineOperation({ authorizer: () => apiKeyAuthers.read.dynamicFields({}), paramsSchema: z.union([z.object({ id: z.number() }), z.object({ name: z.string() })]), - method: async ({ prisma, params }): Promise => { + operation: async ({ prisma, params }): Promise => { const apiKey = await prisma.apiKey.findUnique({ where: { id: 'id' in params ? params.id : undefined, @@ -87,9 +87,9 @@ export const apiKeyMethods = { } } }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => apiKeyAuthers.readMany.dynamicFields({}), - method: async ({ prisma }): Promise => { + operation: async ({ prisma }): Promise => { const apiKeys = await prisma.apiKey.findMany({ select: apiFilterSelection, orderBy: [ @@ -107,12 +107,12 @@ export const apiKeyMethods = { }))) } }), - readWithHash: serviceMethod({ + readWithHash: defineOperation({ authorizer: () => apiKeyAuthers.readWithHash.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const apiKey = await prisma.apiKey.findUniqueOrThrow({ where: { id: params.id }, select: { @@ -133,13 +133,13 @@ export const apiKeyMethods = { } } }), - update: serviceMethod({ + update: defineOperation({ authorizer: () => apiKeyAuthers.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), dataSchema: apiKeySchemas.update, - method: async ({ prisma, params, data }) => { + operation: async ({ prisma, params, data }) => { if (data.active && data.expiresAt && data.expiresAt < new Date()) { throw new ServerError('BAD PARAMETERS', 'Hvis du vil aktivere en nøkkel, kan den ikke ha utløpt') } @@ -151,13 +151,13 @@ export const apiKeyMethods = { return { name } }, }), - destroy: serviceMethod({ + destroy: defineOperation({ authorizer: () => apiKeyAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), opensTransaction: true, - method: async ({ prisma, params }): Promise => { + operation: async ({ prisma, params }): Promise => { await prisma.$transaction(async (tx) => { const apiKey = await tx.apiKey.findUniqueOrThrow({ where: { id: params.id }, diff --git a/src/services/api-keys/schemas.ts b/src/services/api-keys/schemas.ts index 81310fe7c..54ba6ea63 100644 --- a/src/services/api-keys/schemas.ts +++ b/src/services/api-keys/schemas.ts @@ -1,12 +1,12 @@ -import { zpn } from '@/lib/fields/zpn' +import { Zpn } from '@/lib/fields/zpn' import { z } from 'zod' import { Permission } from '@prisma/client' const baseSchema = z.object({ name: z.string().min(10, 'minimum lengde 10').max(100, 'maksimum lengde 100'), expiresAt: z.coerce.date().optional(), - active: zpn.checkboxOrBoolean({ label: 'Aktiv' }), - permissions: zpn.enumListCheckboxFriendly({ label: 'Tillatelser', enum: Permission }) + active: Zpn.checkboxOrBoolean({ label: 'Aktiv' }), + permissions: Zpn.enumListCheckboxFriendly({ label: 'Tillatelser', enum: Permission }) }) export const apiKeySchemas = { diff --git a/src/services/applications/methods.ts b/src/services/applications/methods.ts index 8b82ddb0c..1112c9a4c 100644 --- a/src/services/applications/methods.ts +++ b/src/services/applications/methods.ts @@ -2,17 +2,17 @@ import '@pn-server-only' import { applicationAuthers } from './authers' import { applicationSchemas } from './schemas' import { ServerError } from '@/services/error' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' export const applicationMethods = { - readForUser: serviceMethod({ + readForUser: defineOperation({ paramsSchema: z.object({ userId: z.number(), periodId: z.number() }), authorizer: ({ params }) => applicationAuthers.readForUser.dynamicFields({ userId: params.userId }), - method: async ({ prisma, params }) => prisma.application.findMany({ + operation: async ({ prisma, params }) => prisma.application.findMany({ where: { userId: params.userId, applicationPeriodId: params.periodId @@ -20,14 +20,14 @@ export const applicationMethods = { }) }), - create: serviceMethod({ + create: defineOperation({ dataSchema: applicationSchemas.create, paramsSchema: z.object({ userId: z.number(), commiteeParticipationId: z.number() }), authorizer: ({ params }) => applicationAuthers.create.dynamicFields({ userId: params.userId }), - method: async ({ prisma, data, params }) => { + operation: async ({ prisma, data, params }) => { const commiteeParticipation = await prisma.committeeParticipationInApplicationPeriod.findUniqueOrThrow({ where: { id: params.commiteeParticipationId @@ -78,7 +78,7 @@ export const applicationMethods = { }, }), - update: serviceMethod({ + update: defineOperation({ dataSchema: applicationSchemas.update, paramsSchema: z.object({ userId: z.number(), @@ -86,7 +86,7 @@ export const applicationMethods = { }), opensTransaction: true, authorizer: ({ params }) => applicationAuthers.update.dynamicFields({ userId: params.userId }), - method: async ({ prisma, data, params }) => { + operation: async ({ prisma, data, params }) => { const application = await prisma.application.findUniqueOrThrow({ where: { userId_applicationPeriodCommiteeId: { @@ -194,14 +194,14 @@ export const applicationMethods = { }, }), - destroy: serviceMethod({ + destroy: defineOperation({ paramsSchema: z.object({ userId: z.number(), commiteeParticipationId: z.number() }), authorizer: ({ params }) => applicationAuthers.destroy.dynamicFields({ userId: params.userId }), opensTransaction: true, - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { prisma.$transaction(async (tx) => { const application = await tx.application.delete({ where: { diff --git a/src/services/applications/periods/methods.ts b/src/services/applications/periods/methods.ts index 4ad811ab8..19ae53092 100644 --- a/src/services/applications/periods/methods.ts +++ b/src/services/applications/periods/methods.ts @@ -4,30 +4,30 @@ import { applicationPeriodSchemas } from './schemas' import { committeesParticipatingincluder } from './config' import { applicationMethods } from '@/services/applications/methods' import { ServerError } from '@/services/error' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' export const applicationPeriodMethods = { - readAll: serviceMethod({ + readAll: defineOperation({ authorizer: () => applicationPeriodAuthers.readAll.dynamicFields({}), - method: async ({ prisma }) => prisma.applicationPeriod.findMany() + operation: async ({ prisma }) => prisma.applicationPeriod.findMany() }), - read: serviceMethod({ + read: defineOperation({ authorizer: () => applicationPeriodAuthers.read.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), - method: async ({ prisma, params }) => prisma.applicationPeriod.findUniqueOrThrow({ + operation: async ({ prisma, params }) => prisma.applicationPeriod.findUniqueOrThrow({ where: { name: params.name }, include: committeesParticipatingincluder, }) }), - create: serviceMethod({ + create: defineOperation({ authorizer: () => applicationPeriodAuthers.create.dynamicFields({}), dataSchema: applicationPeriodSchemas.create, - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { await prisma.applicationPeriod.create({ data: { name: data.name, @@ -43,13 +43,13 @@ export const applicationPeriodMethods = { } }), - update: serviceMethod({ + update: defineOperation({ authorizer: () => applicationPeriodAuthers.update.dynamicFields({}), dataSchema: applicationPeriodSchemas.update, paramsSchema: z.object({ name: z.string() }), - method: async ({ prisma, data, params }) => { + operation: async ({ prisma, data, params }) => { const period = await prisma.applicationPeriod.update({ where: { name: params.name }, data: { @@ -122,12 +122,12 @@ export const applicationPeriodMethods = { } }), - removeAllApplicationTexts: serviceMethod({ + removeAllApplicationTexts: defineOperation({ paramsSchema: z.object({ name: z.string() }), authorizer: () => applicationPeriodAuthers.removeAllApplicationTexts.dynamicFields({}), - method: async ({ prisma, params, session }) => { + operation: async ({ prisma, params, session }) => { const period = await applicationPeriodMethods.read({ params: { name: params.name }, session @@ -148,24 +148,24 @@ export const applicationPeriodMethods = { } }), - destroy: serviceMethod({ + destroy: defineOperation({ authorizer: () => applicationPeriodAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { await prisma.applicationPeriod.delete({ where: { name: params.name } }) } }), - readNumberOfApplications: serviceMethod({ + readNumberOfApplications: defineOperation({ authorizer: () => applicationPeriodAuthers.readNumberOfApplications.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const period = await prisma.applicationPeriod.findUniqueOrThrow({ where: { name: params.name }, select: { diff --git a/src/services/applications/periods/schemas.ts b/src/services/applications/periods/schemas.ts index b98505628..9468860fd 100644 --- a/src/services/applications/periods/schemas.ts +++ b/src/services/applications/periods/schemas.ts @@ -1,12 +1,12 @@ -import { zpn } from '@/lib/fields/zpn' +import { Zpn } from '@/lib/fields/zpn' import { z } from 'zod' const fields = z.object({ name: z.string().trim().min(2, { message: 'Navnet må være minst 2 tegn.' }), - startDate: zpn.date({ label: 'Start' }), - endDate: zpn.date({ label: 'Siste frist for søknader' }), - endPriorityDate: zpn.date({ label: 'Siste frist for prioritering' }), - participatingCommitteeIds: zpn.numberListCheckboxFriendly({ label: 'Deltakende komiteer' }) + startDate: Zpn.date({ label: 'Start' }), + endDate: Zpn.date({ label: 'Siste frist for søknader' }), + endPriorityDate: Zpn.date({ label: 'Siste frist for prioritering' }), + participatingCommitteeIds: Zpn.numberListCheckboxFriendly({ label: 'Deltakende komiteer' }) }) const refineDates = { diff --git a/src/services/auth/methods.ts b/src/services/auth/methods.ts index 6ed3c2329..62a24daa8 100644 --- a/src/services/auth/methods.ts +++ b/src/services/auth/methods.ts @@ -3,7 +3,7 @@ import { authSchemas } from './schemas' import { userFilterSelection } from '@/services/users/config' import { userSchemas } from '@/services/users/schemas' import { sendResetPasswordMail } from '@/services/notifications/email/systemMail/resetPassword' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' import { userMethods } from '@/services/users/methods' import { readJWTPayload } from '@/lib/jwt/jwtReadUnsecure' @@ -11,12 +11,12 @@ import { z } from 'zod' export const authMethods = { - verifyEmail: serviceMethod({ + verifyEmail: defineOperation({ paramsSchema: z.object({ token: z.string(), }), authorizer: ({ params }) => authAuthers.verifyEmail.dynamicFields(params), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { // INFO: Safe to parse unsafe since the auther has verified the token. const payload = readJWTPayload(params.token) @@ -53,12 +53,12 @@ export const authMethods = { } }), - verifyResetPasswordToken: serviceMethod({ + verifyResetPasswordToken: defineOperation({ paramsSchema: z.object({ token: z.string() }), authorizer: ({ params }) => authAuthers.resetPassword.dynamicFields(params), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { // INFO: Safe to parse unsafe since the auther has verified the token. const payload = readJWTPayload(params.token) @@ -85,13 +85,13 @@ export const authMethods = { } }), - resetPassword: serviceMethod({ + resetPassword: defineOperation({ paramsSchema: z.object({ token: z.string() }), dataSchema: userSchemas.updatePassword, authorizer: ({ params }) => authAuthers.resetPassword.dynamicFields(params), - method: async ({ params, data }) => { + operation: async ({ params, data }) => { const userId = await authMethods.verifyResetPasswordToken({ params }) userMethods.updatePassword({ @@ -104,10 +104,10 @@ export const authMethods = { } }), - sendResetPasswordEmail: serviceMethod({ + sendResetPasswordEmail: defineOperation({ dataSchema: authSchemas.sendResetPasswordEmail, authorizer: () => authAuthers.sendResetPasswordEmail.dynamicFields({}), - method: async ({ data }) => { + operation: async ({ data }) => { console.log(data) try { const user = await userMethods.read({ diff --git a/src/services/cabin/booking/methods.ts b/src/services/cabin/booking/methods.ts index 244870f4b..ce86a8b8d 100644 --- a/src/services/cabin/booking/methods.ts +++ b/src/services/cabin/booking/methods.ts @@ -5,7 +5,7 @@ import { cabinBookingAuthers } from './authers' import { cabinBookingFilerSelection, cabinBookingIncluder } from './config' import { cabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' import { cabinProductPriceIncluder } from '@/services/cabin/product/config' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { ServerError } from '@/services/error' import { cabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' @@ -21,13 +21,13 @@ const mailData = { Dette skal være en bookingbekreftelse, så det bør nok komme noe nyttig info her snart.`, } -const cabinAvailable = serviceMethod({ +const cabinAvailable = defineOperation({ paramsSchema: z.object({ start: z.date(), end: z.date() }), authorizer: ServerOnlyAuther, - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const results = await prisma.booking.findMany({ where: { start: { @@ -48,14 +48,14 @@ const bookingProductParams = z.array(z.object({ })) -const create = serviceMethod({ +const create = defineOperation({ paramsSchema: z.object({ bookingType: z.nativeEnum(BookingType), bookingProducts: bookingProductParams, }), authorizer: ServerOnlyAuther, dataSchema: cabinBookingSchemas.createBookingUserAttached, - method: async ({ prisma, params, data }) => { + operation: async ({ prisma, params, data }) => { // TODO: Prevent Race conditions const latestReleaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ @@ -156,7 +156,7 @@ const create = serviceMethod({ } }) -const createBookingWithUser = serviceMethod({ +const createBookingWithUser = defineOperation({ paramsSchema: z.object({ userId: z.number(), bookingType: z.nativeEnum(BookingType), @@ -164,7 +164,7 @@ const createBookingWithUser = serviceMethod({ }), authorizer: ServerOnlyAuther, dataSchema: cabinBookingSchemas.createBookingUserAttached, - method: async ({ prisma, params, data }) => { + operation: async ({ prisma, params, data }) => { const result = await create({ params, data, @@ -197,14 +197,14 @@ const createBookingWithUser = serviceMethod({ } }) -const createBookingNoUser = serviceMethod({ +const createBookingNoUser = defineOperation({ paramsSchema: z.object({ bookingType: z.nativeEnum(BookingType), bookingProducts: bookingProductParams, }), authorizer: ServerOnlyAuther, dataSchema: cabinBookingSchemas.createBookingNoUser, - method: async ({ prisma, params, data }) => { + operation: async ({ prisma, params, data }) => { const result = await create({ params, data: { @@ -240,7 +240,7 @@ const createBookingNoUser = serviceMethod({ }) export const cabinBookingMethods = { - createCabinBookingUserAttached: serviceMethod({ + createCabinBookingUserAttached: defineOperation({ paramsSchema: z.object({ userId: z.number(), bookingProducts: bookingProductParams, @@ -249,7 +249,7 @@ export const cabinBookingMethods = { userId: params.userId, }), dataSchema: cabinBookingSchemas.createBookingUserAttached, - method: async ({ params, data }) => + operation: async ({ params, data }) => createBookingWithUser({ params: { userId: params.userId, @@ -261,7 +261,7 @@ export const cabinBookingMethods = { }) }), - createBedBookingUserAttached: serviceMethod({ + createBedBookingUserAttached: defineOperation({ paramsSchema: z.object({ userId: z.number(), bookingProducts: bookingProductParams, @@ -270,7 +270,7 @@ export const cabinBookingMethods = { userId: params.userId, }), dataSchema: cabinBookingSchemas.createBookingUserAttached, - method: async ({ params, data }) => + operation: async ({ params, data }) => createBookingWithUser({ params: { userId: params.userId, @@ -282,13 +282,13 @@ export const cabinBookingMethods = { }) }), - createCabinBookingNoUser: serviceMethod({ + createCabinBookingNoUser: defineOperation({ paramsSchema: z.object({ bookingProducts: bookingProductParams, }), authorizer: () => cabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}), dataSchema: cabinBookingSchemas.createBookingNoUser, - method: async ({ params, data }) => createBookingNoUser({ + operation: async ({ params, data }) => createBookingNoUser({ params: { bookingType: BookingType.CABIN, bookingProducts: params.bookingProducts, @@ -298,13 +298,13 @@ export const cabinBookingMethods = { }) }), - createBedBookingNoUser: serviceMethod({ + createBedBookingNoUser: defineOperation({ paramsSchema: z.object({ bookingProducts: bookingProductParams, }), authorizer: () => cabinBookingAuthers.createBedBookingNoUser.dynamicFields({}), dataSchema: cabinBookingSchemas.createBookingNoUser, - method: async ({ params, data }) => createBookingNoUser({ + operation: async ({ params, data }) => createBookingNoUser({ params: { bookingType: BookingType.BED, bookingProducts: params.bookingProducts, @@ -314,9 +314,9 @@ export const cabinBookingMethods = { }) }), - readAvailability: serviceMethod({ + readAvailability: defineOperation({ authorizer: () => cabinBookingAuthers.readAvailability.dynamicFields({}), - method: async ({ prisma }) => { + operation: async ({ prisma }) => { const results = await prisma.booking.findMany({ select: cabinBookingFilerSelection, orderBy: { @@ -342,9 +342,9 @@ export const cabinBookingMethods = { } }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => cabinBookingAuthers.readMany.dynamicFields({}), - method: ({ prisma }) => prisma.booking.findMany({ + operation: ({ prisma }) => prisma.booking.findMany({ orderBy: { start: 'asc', }, @@ -352,12 +352,12 @@ export const cabinBookingMethods = { }), // TODO: Pager }), - read: serviceMethod({ + read: defineOperation({ authorizer: () => cabinBookingAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: ({ prisma, params }) => prisma.booking.findUniqueOrThrow({ + operation: ({ prisma, params }) => prisma.booking.findUniqueOrThrow({ where: params, include: cabinBookingIncluder, }) diff --git a/src/services/cabin/booking/schemas.ts b/src/services/cabin/booking/schemas.ts index c6c728ed3..78ff9a02f 100644 --- a/src/services/cabin/booking/schemas.ts +++ b/src/services/cabin/booking/schemas.ts @@ -1,5 +1,5 @@ import { dateLessThan, dateLessThanOrEqualTo } from '@/lib/dates/comparison' -import { zpn } from '@/lib/fields/zpn' +import { Zpn } from '@/lib/fields/zpn' import { z } from 'zod' const baseSchema = z.object({ @@ -12,7 +12,7 @@ const baseSchema = z.object({ lastname: z.string().min(2), email: z.string().email(), mobile: z.string().regex(/^\+?\d{4,20}$/, { message: 'Skriv kun tall, uten mellomrom.' }), - acceptedTerms: zpn.checkboxOrBoolean({ + acceptedTerms: Zpn.checkboxOrBoolean({ label: '', message: 'Du må godta vilkårene for å bruk siden.' }) diff --git a/src/services/cabin/pricePeriod/methods.ts b/src/services/cabin/pricePeriod/methods.ts index 9e400cede..f75162e09 100644 --- a/src/services/cabin/pricePeriod/methods.ts +++ b/src/services/cabin/pricePeriod/methods.ts @@ -1,16 +1,16 @@ import 'server-only' import { cabinPricePeriodAuthers } from './authers' import { cabinPricePeriodSchemas } from './schemas' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { cabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' import { ServerError } from '@/services/error' import { z } from 'zod' export const cabinPricePeriodMethods = { - create: serviceMethod({ + create: defineOperation({ authorizer: () => cabinPricePeriodAuthers.create.dynamicFields({}), dataSchema: cabinPricePeriodSchemas.createPricePeriod, - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { const currentReleaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) if (currentReleaseDate && currentReleaseDate.releaseUntil >= data.validFrom) { @@ -58,12 +58,12 @@ export const cabinPricePeriodMethods = { } }), - destroy: serviceMethod({ + destroy: defineOperation({ authorizer: () => cabinPricePeriodAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const currentReleasePeriod = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) const pricePeriod = await prisma.pricePeriod.findUniqueOrThrow({ @@ -80,14 +80,14 @@ export const cabinPricePeriodMethods = { } }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => cabinPricePeriodAuthers.read.dynamicFields({}), - method: async ({ prisma }) => prisma.pricePeriod.findMany() + operation: async ({ prisma }) => prisma.pricePeriod.findMany() }), - readPublicPeriods: serviceMethod({ + readPublicPeriods: defineOperation({ authorizer: () => cabinPricePeriodAuthers.readPublicPeriods.dynamicFields({}), - method: async ({ prisma }) => { + operation: async ({ prisma }) => { const releaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) const [currentPeriod, futurePeriods] = await Promise.all([ @@ -118,9 +118,9 @@ export const cabinPricePeriodMethods = { } }), - readUnreleasedPeriods: serviceMethod({ + readUnreleasedPeriods: defineOperation({ authorizer: () => cabinPricePeriodAuthers.read.dynamicFields({}), - method: async ({ prisma }) => { + operation: async ({ prisma }) => { const releaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) return prisma.pricePeriod.findMany({ where: { @@ -132,13 +132,13 @@ export const cabinPricePeriodMethods = { } }), - update: serviceMethod({ + update: defineOperation({ authorizer: () => cabinPricePeriodAuthers.update.dynamicFields({}), dataSchema: cabinPricePeriodSchemas.updatePricePeriod, paramsSchema: z.object({ pricePeriodId: z.number(), }), - method: async ({ prisma, data, params }) => prisma.pricePeriod.update({ + operation: async ({ prisma, data, params }) => prisma.pricePeriod.update({ where: { id: params.pricePeriodId, }, diff --git a/src/services/cabin/pricePeriod/schemas.ts b/src/services/cabin/pricePeriod/schemas.ts index 2034ba84b..1875722fe 100644 --- a/src/services/cabin/pricePeriod/schemas.ts +++ b/src/services/cabin/pricePeriod/schemas.ts @@ -1,10 +1,10 @@ -import { zpn } from '@/lib/fields/zpn' +import { Zpn } from '@/lib/fields/zpn' import { z } from 'zod' const baseSchema = z.object({ id: z.coerce.number(), validFrom: z.coerce.date(), - copyPreviousPrices: zpn.checkboxOrBoolean({ label: '' }), + copyPreviousPrices: Zpn.checkboxOrBoolean({ label: '' }), }) export const cabinPricePeriodSchemas = { diff --git a/src/services/cabin/product/methods.ts b/src/services/cabin/product/methods.ts index a102ff69f..398432db1 100644 --- a/src/services/cabin/product/methods.ts +++ b/src/services/cabin/product/methods.ts @@ -4,28 +4,28 @@ import { cabinProductAuthers } from './authers' import { cabinProductSchemas } from './schemas' import { cabinProductPriceIncluder } from './config' import { cabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' import { cabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' import { z } from 'zod' export const cabinProductMethods = { - create: serviceMethod({ + create: defineOperation({ authorizer: () => cabinProductAuthers.create.dynamicFields({}), dataSchema: cabinProductSchemas.createProduct, - method: ({ prisma, data }) => prisma.cabinProduct.create({ + operation: ({ prisma, data }) => prisma.cabinProduct.create({ data, }) }), - createPrice: serviceMethod({ + createPrice: defineOperation({ authorizer: () => cabinProductAuthers.createPrice.dynamicFields({}), paramsSchema: z.object({ cabinProductId: z.number(), }), dataSchema: cabinProductSchemas.createProductPrice, - method: async ({ prisma, params, data, session }) => { + operation: async ({ prisma, params, data, session }) => { const [pricePeriod, releasePeriod] = await Promise.all([ prisma.pricePeriod.findUniqueOrThrow({ where: { @@ -53,16 +53,16 @@ export const cabinProductMethods = { } }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => cabinProductAuthers.read.dynamicFields({}), - method: ({ prisma }) => prisma.cabinProduct.findMany({ + operation: ({ prisma }) => prisma.cabinProduct.findMany({ include: cabinProductPriceIncluder, }), }), - readActive: serviceMethod({ + readActive: defineOperation({ authorizer: () => cabinProductAuthers.read.dynamicFields({}), - method: async ({ prisma }) => { + operation: async ({ prisma }) => { const pricePeriods = await cabinPricePeriodMethods.readPublicPeriods({ bypassAuth: true }) return await prisma.cabinProduct.findMany({ @@ -80,12 +80,12 @@ export const cabinProductMethods = { }, }), - read: serviceMethod({ + read: defineOperation({ authorizer: () => cabinProductAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: ({ prisma, params }) => prisma.cabinProduct.findUniqueOrThrow({ + operation: ({ prisma, params }) => prisma.cabinProduct.findUniqueOrThrow({ where: params, include: cabinProductPriceIncluder, }) diff --git a/src/services/cabin/product/schemas.ts b/src/services/cabin/product/schemas.ts index c2904e5b5..bd8af5166 100644 --- a/src/services/cabin/product/schemas.ts +++ b/src/services/cabin/product/schemas.ts @@ -1,4 +1,4 @@ -import { zpn } from '@/lib/fields/zpn' +import { Zpn } from '@/lib/fields/zpn' import { convertPrice } from '@/lib/money/convert' import { BookingType } from '@prisma/client' import { z } from 'zod' @@ -10,7 +10,7 @@ const baseSchema = z.object({ description: z.string().min(0).max(20), price: z.coerce.number().min(0).transform((val) => convertPrice(val)), validFrom: z.coerce.date(), - cronInterval: zpn.simpleCronExpression(), + cronInterval: Zpn.simpleCronExpression(), memberShare: z.coerce.number().min(0).max(100), pricePeriodId: z.coerce.number(), }) diff --git a/src/services/cabin/releasePeriod/methods.ts b/src/services/cabin/releasePeriod/methods.ts index 19ad0b4af..343228e29 100644 --- a/src/services/cabin/releasePeriod/methods.ts +++ b/src/services/cabin/releasePeriod/methods.ts @@ -1,16 +1,16 @@ import 'server-only' import { cabinReleasePeriodAuthers } from './authers' import { cabinReleasePeriodSchemas } from './schemas' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' import { z } from 'zod' export const cabinReleasePeriodMethods = { - create: serviceMethod({ + create: defineOperation({ authorizer: () => cabinReleasePeriodAuthers.createReleasePeriodAuther.dynamicFields({}), dataSchema: cabinReleasePeriodSchemas.createReleasePeriod, - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { const latestReleasePeriod = await prisma.releasePeriod.findFirst({ orderBy: { releaseTime: 'desc', @@ -31,12 +31,12 @@ export const cabinReleasePeriodMethods = { } }), - destroy: serviceMethod({ + destroy: defineOperation({ authorizer: () => cabinReleasePeriodAuthers.deleteReleasePeriodAuther.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const releasePeriod = await prisma.releasePeriod.findUniqueOrThrow({ where: params, }) @@ -51,18 +51,18 @@ export const cabinReleasePeriodMethods = { } }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => cabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), - method: async ({ prisma }) => prisma.releasePeriod.findMany({ + operation: async ({ prisma }) => prisma.releasePeriod.findMany({ orderBy: { releaseUntil: 'desc', } }) }), - getCurrentReleasePeriod: serviceMethod({ + getCurrentReleasePeriod: defineOperation({ authorizer: () => cabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), - method: async ({ prisma }) => prisma.releasePeriod.findFirst({ + operation: async ({ prisma }) => prisma.releasePeriod.findFirst({ where: { releaseTime: { lte: new Date(), @@ -75,10 +75,10 @@ export const cabinReleasePeriodMethods = { }) }), - update: serviceMethod({ + update: defineOperation({ authorizer: () => cabinReleasePeriodAuthers.updateReleasePeriodAuther.dynamicFields({}), dataSchema: cabinReleasePeriodSchemas.updateReleasePeriod, - method: async ({ prisma, data }) => prisma.releasePeriod.update({ + operation: async ({ prisma, data }) => prisma.releasePeriod.update({ where: { id: data.id, // TODO: Figure out why id is in data and not a param }, diff --git a/src/services/career/companies/methods.ts b/src/services/career/companies/methods.ts index 3dd0088d6..43eb35ff5 100644 --- a/src/services/career/companies/methods.ts +++ b/src/services/career/companies/methods.ts @@ -1,19 +1,19 @@ import '@pn-server-only' import { companyAuthers } from './authers' -import { companySchemas } from './schemas' import { logoIncluder } from './config' +import { companySchemas } from './schemas' import { createCmsImage } from '@/services/cms/images/create' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { v4 as uuid } from 'uuid' import { z } from 'zod' export const companyMethods = { - create: serviceMethod({ + create: defineOperation({ dataSchema: companySchemas.create, authorizer: () => companyAuthers.create.dynamicFields({}), - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { //TODO: tranaction when createCmsImage is service method. const logo = await createCmsImage({ name: uuid() }) return await prisma.company.create({ @@ -24,7 +24,7 @@ export const companyMethods = { }) } }), - readPage: serviceMethod({ + readPage: defineOperation({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -35,7 +35,7 @@ export const companyMethods = { }), ), authorizer: () => companyAuthers.readPage.dynamicFields({}), - method: async ({ prisma, params }) => await prisma.company.findMany({ + operation: async ({ prisma, params }) => await prisma.company.findMany({ ...cursorPageingSelection(params.paging.page), where: { name: { @@ -46,25 +46,25 @@ export const companyMethods = { include: logoIncluder, }) }), - update: serviceMethod({ + update: defineOperation({ paramsSchema: z.object({ id: z.number(), }), dataSchema: companySchemas.update, authorizer: () => companyAuthers.update.dynamicFields({}), - method: async ({ prisma, params: { id }, data }) => { + operation: async ({ prisma, params: { id }, data }) => { await prisma.company.update({ where: { id }, data, }) }, }), - destroy: serviceMethod({ + destroy: defineOperation({ paramsSchema: z.object({ id: z.number() }), authorizer: () => companyAuthers.destroy.dynamicFields({}), - method: async ({ prisma, params: { id } }) => { + operation: async ({ prisma, params: { id } }) => { await prisma.company.delete({ where: { id diff --git a/src/services/career/jobAds/methods.ts b/src/services/career/jobAds/methods.ts index 3453aa8dc..3e0a6cfa8 100644 --- a/src/services/career/jobAds/methods.ts +++ b/src/services/career/jobAds/methods.ts @@ -3,7 +3,7 @@ import { jobAdAuthers } from './authers' import { jobAdSchemas } from './schemas' import { articleAndCompanyIncluder, simpleArticleAndCompanyIncluder } from './config' import { logoIncluder } from '@/services/career/companies/config' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createArticle } from '@/services/cms/articles/create' import { ServerError } from '@/services/error' @@ -15,10 +15,10 @@ import { JobType } from '@prisma/client' import type { ExpandedJobAd, SimpleJobAd } from './Types' export const jobAdMethods = { - create: serviceMethod({ + create: defineOperation({ dataSchema: jobAdSchemas.create, authorizer: () => jobAdAuthers.create.dynamicFields({}), - method: async ({ prisma, data: { articleName, companyId, ...data } }) => { + operation: async ({ prisma, data: { articleName, companyId, ...data } }) => { const article = await createArticle({ name: articleName }) const currentOrder = await readCurrentOmegaOrder() @@ -48,7 +48,7 @@ export const jobAdMethods = { * @param idOrName - id or articleName and order of jobAd to read (id or {articleName: string, order: number}) * @returns ExpandedJobAd - the jobAd and its article */ - read: serviceMethod({ + read: defineOperation({ paramsSchema: z.object({ idOrName: z.union([ z.number(), @@ -59,7 +59,7 @@ export const jobAdMethods = { ]), }), authorizer: () => jobAdAuthers.read.dynamicFields({}), - method: async ({ prisma, params: { idOrName } }): Promise => { + operation: async ({ prisma, params: { idOrName } }): Promise => { const jobAd = await prisma.jobAd.findUnique({ where: typeof idOrName === 'number' ? { id: idOrName @@ -84,9 +84,9 @@ export const jobAdMethods = { * This handler reads all active jobAds * @returns SimpleJobAd[] - all jobAds with coverImage */ - readActive: serviceMethod({ + readActive: defineOperation({ authorizer: () => jobAdAuthers.readActive.dynamicFields({}), - method: async ({ prisma }): Promise => { + operation: async ({ prisma }): Promise => { const jobAds = await prisma.jobAd.findMany({ orderBy: { article: { @@ -109,7 +109,7 @@ export const jobAdMethods = { * This handler reads a page of inactive jobAds * @param paging - the page to read, includes details to filter by name (articleName) and the type. */ - readInactivePage: serviceMethod({ + readInactivePage: defineOperation({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -121,7 +121,7 @@ export const jobAdMethods = { }), ), authorizer: () => jobAdAuthers.readInactivePage.dynamicFields({}), - method: async ({ prisma, params }): Promise => { + operation: async ({ prisma, params }): Promise => { const jobAds = await prisma.jobAd.findMany({ ...cursorPageingSelection(params.paging.page), where: { @@ -149,23 +149,23 @@ export const jobAdMethods = { * @param id - id of news article to destroy * @returns */ - update: serviceMethod({ + update: defineOperation({ paramsSchema: z.object({ id: z.number(), }), dataSchema: jobAdSchemas.update, authorizer: () => jobAdAuthers.update.dynamicFields({}), - method: async ({ prisma, params: { id }, data }) => await prisma.jobAd.update({ + operation: async ({ prisma, params: { id }, data }) => await prisma.jobAd.update({ where: { id }, data, }) }), - destroy: serviceMethod({ + destroy: defineOperation({ paramsSchema: z.object({ id: z.number(), }), authorizer: () => jobAdAuthers.destroy.dynamicFields({}), - method: async ({ prisma, params: { id } }) => { + operation: async ({ prisma, params: { id } }) => { const jobAd = await prisma.jobAd.delete({ where: { id }, }) diff --git a/src/services/career/jobAds/schemas.ts b/src/services/career/jobAds/schemas.ts index 06694b1f4..835405bd6 100644 --- a/src/services/career/jobAds/schemas.ts +++ b/src/services/career/jobAds/schemas.ts @@ -1,4 +1,4 @@ -import { zpn } from '@/lib/fields/zpn' +import { Zpn } from '@/lib/fields/zpn' import { z } from 'zod' import { JobType } from '@prisma/client' @@ -9,8 +9,8 @@ const baseSchema = z.object({ articleName: z.string().max(50, 'max lengde 50').min(2, 'min lengde 2'), description: z.string().max(200, 'max lengde 200').min(2, 'min lengde 2').or(z.literal('')), type: z.nativeEnum(JobType), - applicationDeadline: zpn.date({ label: 'Søknadsfrist' }), - active: zpn.checkboxOrBoolean({ label: 'Aktiv' }), + applicationDeadline: Zpn.date({ label: 'Søknadsfrist' }), + active: Zpn.checkboxOrBoolean({ label: 'Aktiv' }), location: z.string().optional(), }) diff --git a/src/services/cms/links/read.ts b/src/services/cms/links/read.ts index 66b14dd47..70ba09c49 100644 --- a/src/services/cms/links/read.ts +++ b/src/services/cms/links/read.ts @@ -1,16 +1,16 @@ import '@pn-server-only' import { readSpecialCmsLinkAuther } from './authers' import logger from '@/lib/logger' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { SpecialCmsLink } from '@prisma/client' import { z } from 'zod' -export const readSpecialCmsLink = serviceMethod({ +export const readSpecialCmsLink = defineOperation({ paramsSchema: z.object({ special: z.nativeEnum(SpecialCmsLink), }), authorizer: () => readSpecialCmsLinkAuther.dynamicFields({}), - method: async ({ prisma, params: { special } }) => { + operation: async ({ prisma, params: { special } }) => { const cmsLink = await prisma.cmsLink.findUnique({ where: { special } }) diff --git a/src/services/dots/methods.ts b/src/services/dots/methods.ts index 658ada69b..b1ee6a7ce 100644 --- a/src/services/dots/methods.ts +++ b/src/services/dots/methods.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { dotAuthers } from './authers' import { dotSchemas } from './schemas' import { dotBaseDuration, dotsIncluder } from './config' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { z } from 'zod' @@ -12,13 +12,13 @@ import { z } from 'zod' * @param userId - The user id to read dots for * @returns All dots for the user in ascending order of expiration. i.e the dot that expires first will be first in the list */ -const readForUser = serviceMethod({ +const readForUser = defineOperation({ authorizer: ({ params }) => dotAuthers.readForUser.dynamicFields({ userId: params.userId }), paramsSchema: z.object({ userId: z.number(), onlyActive: z.boolean(), }), - method: async ({ prisma, params: { userId, onlyActive } }) => prisma.dot.findMany({ + operation: async ({ prisma, params: { userId, onlyActive } }) => prisma.dot.findMany({ where: { wrapper: { userId, @@ -33,14 +33,14 @@ const readForUser = serviceMethod({ }) }) -const create = serviceMethod({ +const create = defineOperation({ dataSchema: dotSchemas.create, authorizer: ({ data }) => dotAuthers.create.dynamicFields({ userId: data.userId }), paramsSchema: z.object({ accuserId: z.number(), }), opensTransaction: true, - method: async ({ prisma, params, data: { value, ...data } }) => { + operation: async ({ prisma, params, data: { value, ...data } }) => { const activeDots = await readForUser({ params: { userId: data.userId, onlyActive: true } }) @@ -70,12 +70,12 @@ const create = serviceMethod({ } }) -const readWrappersForUser = serviceMethod({ +const readWrappersForUser = defineOperation({ authorizer: ({ params }) => dotAuthers.readWrapperForUser.dynamicFields({ userId: params.userId }), paramsSchema: z.object({ userId: z.number(), }), - method: async ({ prisma, params: { userId } }) => { + operation: async ({ prisma, params: { userId } }) => { const wrappers = await prisma.dotWrapper.findMany({ where: { userId @@ -94,7 +94,7 @@ const readWrappersForUser = serviceMethod({ } }) -const readPage = serviceMethod({ +const readPage = defineOperation({ authorizer: () => dotAuthers.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), @@ -106,7 +106,7 @@ const readPage = serviceMethod({ onlyActive: z.boolean(), }), ), - method: async ({ prisma, params }) => (await prisma.dotWrapper.findMany({ + operation: async ({ prisma, params }) => (await prisma.dotWrapper.findMany({ ...cursorPageingSelection(params.paging.page), where: { userId: params.paging.details.userId ?? undefined, diff --git a/src/services/events/methods.ts b/src/services/events/methods.ts index 273bf015b..100054e51 100644 --- a/src/services/events/methods.ts +++ b/src/services/events/methods.ts @@ -8,7 +8,7 @@ import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createCmsImage } from '@/services/cms/images/create' import { getOsloTime } from '@/lib/dates/getOsloTime' import { ServerError } from '@/services/error' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { displayDate } from '@/lib/dates/displayDate' @@ -17,10 +17,10 @@ import { z } from 'zod' import type { EventExpanded } from './Types' export const eventMethods = { - create: serviceMethod({ + create: defineOperation({ dataSchema: eventSchemas.create, authorizer: () => eventAuthers.create.dynamicFields({}), - method: async ({ prisma, data, session }) => { + operation: async ({ prisma, data, session }) => { const cmsParagraph = await createCmsParagraph({ name: uuid() }) const cmsImage = await createCmsImage({ name: uuid() }) @@ -92,13 +92,13 @@ export const eventMethods = { return event } }), - read: serviceMethod({ + read: defineOperation({ paramsSchema: z.object({ order: z.number(), name: z.string(), }), authorizer: () => eventAuthers.read.dynamicFields({}), - method: async ({ prisma, params, session }) => { + operation: async ({ prisma, params, session }) => { const event = await prisma.event.findUniqueOrThrow({ where: { order_name: { @@ -155,12 +155,12 @@ export const eventMethods = { } } }), - readManyCurrent: serviceMethod({ + readManyCurrent: defineOperation({ paramsSchema: z.object({ tags: z.array(z.string()).nullable(), }), authorizer: () => eventAuthers.readManyCurrent.dynamicFields({}), - method: async ({ prisma, params }): Promise => { + operation: async ({ prisma, params }): Promise => { const events = await prisma.event.findMany({ select: { ...eventFilterSelection, @@ -190,7 +190,7 @@ export const eventMethods = { })) } }), - readManyArchivedPage: serviceMethod({ + readManyArchivedPage: defineOperation({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -202,7 +202,7 @@ export const eventMethods = { }), ), // Converted from ReadPageInput authorizer: () => eventAuthers.readManyArchivedPage.dynamicFields({}), - method: async ({ prisma, params }): Promise => { + operation: async ({ prisma, params }): Promise => { const events = await prisma.event.findMany({ ...cursorPageingSelection(params.paging.page), where: { @@ -237,13 +237,13 @@ export const eventMethods = { })) } }), - update: serviceMethod({ + update: defineOperation({ paramsSchema: z.object({ id: z.number(), }), dataSchema: eventSchemas.update, authorizer: () => eventAuthers.update.dynamicFields({}), - method: async ({ prisma, params, data: { tagIds, ...data } }) => { + operation: async ({ prisma, params, data: { tagIds, ...data } }) => { const event = await prisma.event.findUniqueOrThrow({ where: { id: params.id } }) @@ -288,12 +288,12 @@ export const eventMethods = { return eventUpdate } }), - destroy: serviceMethod({ + destroy: defineOperation({ paramsSchema: z.object({ id: z.number() }), authorizer: () => eventAuthers.destroy.dynamicFields({}), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { await prisma.event.delete({ where: { id: params.id diff --git a/src/services/events/registration/methods.ts b/src/services/events/registration/methods.ts index 7e69c8f2a..51edbb2d7 100644 --- a/src/services/events/registration/methods.ts +++ b/src/services/events/registration/methods.ts @@ -2,12 +2,12 @@ import '@pn-server-only' import { eventRegistrationIncluderDetailed, eventRegistrationSelection, REGISTRATION_READER_TYPE } from './config' import { eventRegistrationAuthers } from './authers' import { eventRegistrationSchemas } from './schemas' -import { serviceMethod } from '@/services/serviceMethod' import { Smorekopp } from '@/services/error' import { imageMethods } from '@/services/images/methods' import { notificationMethods } from '@/services/notifications/methods' import { sendSystemMail } from '@/services/notifications/email/send' import { userFilterSelection } from '@/services/users/config' +import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' import type { Prisma } from '@prisma/client' import type { EventRegistrationExpanded } from './Types' @@ -125,7 +125,7 @@ async function calculateTakeSkip(prisma: Prisma.TransactionClient, params: { export const eventRegistrationMethods = { - create: serviceMethod({ + create: defineOperation({ paramsSchema: z.object({ userId: z.number().min(0), eventId: z.number().min(0), @@ -134,7 +134,7 @@ export const eventRegistrationMethods = { userId: params.userId, }), opensTransaction: true, - method: async ({ prisma, params, session }) => { + operation: async ({ prisma, params, session }) => { const isAdmin = session.permissions.includes('EVENT_ADMIN') await preValidateRegistration(prisma, params.eventId, isAdmin) @@ -162,14 +162,14 @@ export const eventRegistrationMethods = { }, }), - createGuest: serviceMethod({ + createGuest: defineOperation({ authorizer: () => eventRegistrationAuthers.createGuest.dynamicFields({}), paramsSchema: z.object({ eventId: z.number(), }), dataSchema: eventRegistrationSchemas.createGuest, opensTransaction: true, - method: async ({ prisma, params, data }) => { + operation: async ({ prisma, params, data }) => { await preValidateRegistration(prisma, params.eventId, true) const result = await prisma.eventRegistration.create({ data: { @@ -196,7 +196,7 @@ export const eventRegistrationMethods = { }, }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => eventRegistrationAuthers.readMany.dynamicFields({}), paramsSchema: z.object({ eventId: z.number().min(0), @@ -204,7 +204,7 @@ export const eventRegistrationMethods = { take: z.number().optional(), type: z.nativeEnum(REGISTRATION_READER_TYPE).optional(), }), - method: async ({ prisma, params }): Promise => { + operation: async ({ prisma, params }): Promise => { const defaultImage = await imageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, }) @@ -230,7 +230,7 @@ export const eventRegistrationMethods = { }, }), - readManyDetailed: serviceMethod({ + readManyDetailed: defineOperation({ authorizer: () => eventRegistrationAuthers.readManyDetailed.dynamicFields({}), paramsSchema: z.object({ eventId: z.number().min(0), @@ -238,7 +238,7 @@ export const eventRegistrationMethods = { take: z.number().optional(), type: z.nativeEnum(REGISTRATION_READER_TYPE).optional(), }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const skiptake = await calculateTakeSkip(prisma, params) if (skiptake.take === 0) return [] @@ -255,13 +255,13 @@ export const eventRegistrationMethods = { } }), - updateNotes: serviceMethod({ + updateNotes: defineOperation({ authorizer: () => eventRegistrationAuthers.updateRegistrationNotes.dynamicFields({}), paramsSchema: z.object({ registrationId: z.number().min(0), }), dataSchema: eventRegistrationSchemas.updateNotes, - method: async ({ prisma, params, data, session }) => { + operation: async ({ prisma, params, data, session }) => { const registration = await prisma.eventRegistration.findUnique({ where: { id: params.registrationId, @@ -291,12 +291,12 @@ export const eventRegistrationMethods = { } }), - destroy: serviceMethod({ + destroy: defineOperation({ authorizer: () => eventRegistrationAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ registrationId: z.number().min(0), }), - method: async ({ prisma, params, session }) => { + operation: async ({ prisma, params, session }) => { const isAdmin = session.permissions.includes('EVENT_ADMIN') const registration = await prisma.eventRegistration.findUniqueOrThrow({ where: { diff --git a/src/services/events/schemas.ts b/src/services/events/schemas.ts index 19008d8aa..7854d55d7 100644 --- a/src/services/events/schemas.ts +++ b/src/services/events/schemas.ts @@ -1,4 +1,4 @@ -import { zpn } from '@/lib/fields/zpn' +import { Zpn } from '@/lib/fields/zpn' import { z } from 'zod' import { EventCanView } from '@prisma/client' @@ -6,18 +6,18 @@ const baseSchema = z.object({ name: z.string().min(5, 'Navnet må være minst 5 tegn').max(70, 'Navnet må være maks 70 tegn'), location: z.string().min(2, 'Stedet må være minst 2 tegn'), order: z.coerce.number().int().optional(), - eventStart: zpn.date({ label: 'Starttid' }), - eventEnd: zpn.date({ label: 'Sluttid' }), + eventStart: Zpn.date({ label: 'Starttid' }), + eventEnd: Zpn.date({ label: 'Sluttid' }), canBeViewdBy: z.nativeEnum(EventCanView), - takesRegistration: zpn.checkboxOrBoolean({ label: 'Tar påmelding' }), + takesRegistration: Zpn.checkboxOrBoolean({ label: 'Tar påmelding' }), places: z.coerce.number().int().optional(), - registrationStart: zpn.date({ label: 'Påmelding start' }).optional(), - registrationEnd: zpn.date({ label: 'Påmelding slutt' }).optional(), + registrationStart: Zpn.date({ label: 'Påmelding start' }).optional(), + registrationEnd: Zpn.date({ label: 'Påmelding slutt' }).optional(), - waitingList: zpn.checkboxOrBoolean({ label: 'Venteliste' }), + waitingList: Zpn.checkboxOrBoolean({ label: 'Venteliste' }), - tagIds: zpn.numberListCheckboxFriendly({ label: 'tags' }) + tagIds: Zpn.numberListCheckboxFriendly({ label: 'tags' }) }) const waitingListRefiner = (data: { diff --git a/src/services/events/tags/methods.ts b/src/services/events/tags/methods.ts index 579dbb5f5..d71f95244 100644 --- a/src/services/events/tags/methods.ts +++ b/src/services/events/tags/methods.ts @@ -4,29 +4,29 @@ import { specialEventTags } from './config' import { eventTagSchemas } from './schemas' import { eventAuthers } from '@/services/events/authers' import logger from '@/lib/logger' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' import { SpecialEventTags } from '@prisma/client' import { z } from 'zod' export const eventTagMethods = { - read: serviceMethod({ + read: defineOperation({ paramsSchema: z.object({ id: z.number(), }), authorizer: () => eventTagAuthers.read.dynamicFields({}), - method: async ({ prisma, params: { id } }) => await prisma.eventTag.findUniqueOrThrow({ + operation: async ({ prisma, params: { id } }) => await prisma.eventTag.findUniqueOrThrow({ where: { id } }) }), - readSpecial: serviceMethod({ + readSpecial: defineOperation({ paramsSchema: z.object({ special: z.nativeEnum(SpecialEventTags), }), authorizer: () => eventTagAuthers.readSpecial.dynamicFields({}), - method: async ({ prisma, params: { special } }) => { + operation: async ({ prisma, params: { special } }) => { const tag = await prisma.eventTag.findUnique({ where: { special @@ -44,14 +44,14 @@ export const eventTagMethods = { return tag } }), - readAll: serviceMethod({ + readAll: defineOperation({ authorizer: () => eventTagAuthers.readAll.dynamicFields({}), - method: async ({ prisma }) => await prisma.eventTag.findMany() + operation: async ({ prisma }) => await prisma.eventTag.findMany() }), - create: serviceMethod({ + create: defineOperation({ dataSchema: eventTagSchemas.create, authorizer: () => eventTagAuthers.create.dynamicFields({}), - method: async ({ prisma, data: { color, ...data } }) => { + operation: async ({ prisma, data: { color, ...data } }) => { const colorR = parseInt(color.slice(1, 3), 16) const colorG = parseInt(color.slice(3, 5), 16) const colorB = parseInt(color.slice(5, 7), 16) @@ -65,13 +65,13 @@ export const eventTagMethods = { }) } }), - update: serviceMethod({ + update: defineOperation({ paramsSchema: z.object({ id: z.number(), }), dataSchema: eventTagSchemas.update, authorizer: () => eventAuthers.update.dynamicFields({}), - method: async ({ prisma, params: { id }, data: { color, ...data } }) => { + operation: async ({ prisma, params: { id }, data: { color, ...data } }) => { const colorR = color ? parseInt(color.slice(1, 3), 16) : undefined const colorG = color ? parseInt(color.slice(3, 5), 16) : undefined const colorB = color ? parseInt(color.slice(5, 7), 16) : undefined @@ -88,12 +88,12 @@ export const eventTagMethods = { }) } }), - destroy: serviceMethod({ + destroy: defineOperation({ paramsSchema: z.object({ id: z.number(), }), authorizer: () => eventAuthers.destroy.dynamicFields({}), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const tag = await prisma.eventTag.findUniqueOrThrow({ where: { id: params.id } }) diff --git a/src/services/groups/committees/methods.ts b/src/services/groups/committees/methods.ts index 12b039b60..f862517d8 100644 --- a/src/services/groups/committees/methods.ts +++ b/src/services/groups/committees/methods.ts @@ -1,27 +1,27 @@ import { committeeAuthers } from './authers' import { committeeExpandedIncluder, committeeLogoIncluder, membershipIncluder } from './config' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' -import { serviceMethod } from '@/services/serviceMethod' import { articleRealtionsIncluder } from '@/cms/articles/ConfigVars' import { imageMethods } from '@/services/images/methods' +import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' export const committeeMethods = { - readCommittees: serviceMethod({ + readCommittees: defineOperation({ authorizer: () => committeeAuthers.read.dynamicFields({}), - method: async ({ prisma }) => prisma.committee.findMany({ + operation: async ({ prisma }) => prisma.committee.findMany({ include: committeeLogoIncluder, }) }), - readCommittee: serviceMethod({ + readCommittee: defineOperation({ authorizer: () => committeeAuthers.read.dynamicFields({}), paramsSchema: z.union([ z.object({ id: z.number() }), z.object({ shortName: z.string() }) ]), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const defaultImage = await imageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, bypassAuth: true @@ -49,12 +49,12 @@ export const committeeMethods = { } }), - readCommitteArticle: serviceMethod({ + readCommitteArticle: defineOperation({ authorizer: () => committeeAuthers.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), }), - method: async ({ prisma, params }) => (await prisma.committee.findUniqueOrThrow({ + operation: async ({ prisma, params }) => (await prisma.committee.findUniqueOrThrow({ where: params, select: { committeeArticle: { @@ -64,12 +64,12 @@ export const committeeMethods = { })).committeeArticle }), - readCommitteesFromGroupIds: serviceMethod({ + readCommitteesFromGroupIds: defineOperation({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ ids: z.number().int().array() }), - method: async ({ prisma, params }) => await prisma.committee.findMany({ + operation: async ({ prisma, params }) => await prisma.committee.findMany({ where: { groupId: { in: params.ids @@ -79,12 +79,12 @@ export const committeeMethods = { }) }), - readCommitteeParagraph: serviceMethod({ + readCommitteeParagraph: defineOperation({ authorizer: () => committeeAuthers.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), }), - method: async ({ prisma, params }) => (await prisma.committee.findUniqueOrThrow({ + operation: async ({ prisma, params }) => (await prisma.committee.findUniqueOrThrow({ where: params, select: { paragraph: true, @@ -92,13 +92,13 @@ export const committeeMethods = { })).paragraph }), - readCommitteeMembers: serviceMethod({ + readCommitteeMembers: defineOperation({ authorizer: () => committeeAuthers.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), active: z.boolean().optional(), }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const defaultImage = await imageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, }) diff --git a/src/services/groups/interestGroups/methods.ts b/src/services/groups/interestGroups/methods.ts index 9d7efdace..358282755 100644 --- a/src/services/groups/interestGroups/methods.ts +++ b/src/services/groups/interestGroups/methods.ts @@ -2,16 +2,16 @@ import '@pn-server-only' import { interestGroupAuthers } from './authers' import { interestGroupSchemas } from './schemas' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' -import { serviceMethod } from '@/services/serviceMethod' import { articleSectionsRealtionsIncluder } from '@/services/cms/articleSections/ConfigVars' +import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' import type { ExpandedInterestGroup } from './Types' export const interestGroupMethods = { - create: serviceMethod({ + create: defineOperation({ dataSchema: interestGroupSchemas.create, authorizer: () => interestGroupAuthers.create.dynamicFields({}), - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { const { order } = await readCurrentOmegaOrder() await prisma.interestGroup.create({ @@ -35,9 +35,9 @@ export const interestGroupMethods = { } }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => interestGroupAuthers.readMany.dynamicFields({}), - method: async ({ prisma }): Promise => prisma.interestGroup.findMany({ + operation: async ({ prisma }): Promise => prisma.interestGroup.findMany({ include: { articleSection: { include: articleSectionsRealtionsIncluder, @@ -50,13 +50,13 @@ export const interestGroupMethods = { }) }), - read: serviceMethod({ + read: defineOperation({ paramsSchema: z.object({ id: z.number().optional(), shortName: z.string().optional(), }), authorizer: () => interestGroupAuthers.read.dynamicFields({}), - method: async ({ prisma, params: { id, shortName } }) => await prisma.interestGroup.findUniqueOrThrow({ + operation: async ({ prisma, params: { id, shortName } }) => await prisma.interestGroup.findUniqueOrThrow({ where: { id, shortName, @@ -69,7 +69,7 @@ export const interestGroupMethods = { }) }), - update: serviceMethod({ + update: defineOperation({ paramsSchema: z.object({ id: z.number(), }), @@ -84,19 +84,19 @@ export const interestGroupMethods = { groupId, }) }, - method: async ({ prisma, params: { id }, data }) => prisma.interestGroup.update({ + operation: async ({ prisma, params: { id }, data }) => prisma.interestGroup.update({ where: { id }, data, }), }), - destroy: serviceMethod({ + destroy: defineOperation({ paramsSchema: z.object({ id: z.number(), }), authorizer: () => interestGroupAuthers.destroy.dynamicFields({}), opensTransaction: true, - method: async ({ prisma, params: { id } }) => { + operation: async ({ prisma, params: { id } }) => { await prisma.$transaction(async tx => { const intrestGroup = await tx.interestGroup.delete({ where: { id } diff --git a/src/services/groups/methods.ts b/src/services/groups/methods.ts index 0b8ddeef7..ccc187972 100644 --- a/src/services/groups/methods.ts +++ b/src/services/groups/methods.ts @@ -3,7 +3,7 @@ import { groupsExpandedIncluder, groupTypesConfig, OmegaMembershipLevelConfig, r import { groupAuthers } from './authers' import { userFilterSelection } from '@/services/users/config' import { ServerError } from '@/services/error' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { getMembershipFilter } from '@/auth/getMembershipFilter' import logger from '@/lib/logger' @@ -188,17 +188,17 @@ export function checkGroupValidity< } export const groupMethods = { - readGroups: serviceMethod({ + readGroups: defineOperation({ authorizer: () => groupAuthers.read.dynamicFields({}), - method: async ({ prisma }) => prisma.group.findMany() + operation: async ({ prisma }) => prisma.group.findMany() }), - readCurrentGroupOrder: serviceMethod({ + readCurrentGroupOrder: defineOperation({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params }) => (await prisma.group.findUniqueOrThrow({ + operation: async ({ prisma, params }) => (await prisma.group.findUniqueOrThrow({ where: { id: params.id, }, @@ -208,12 +208,12 @@ export const groupMethods = { })).order }), - readCurrentGroupOrders: serviceMethod({ + readCurrentGroupOrders: defineOperation({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ ids: z.number().array(), }), - method: async ({ prisma, params }) => prisma.group.findMany({ + operation: async ({ prisma, params }) => prisma.group.findMany({ where: { id: { in: params.ids, @@ -226,24 +226,24 @@ export const groupMethods = { }) }), - readGroup: serviceMethod({ + readGroup: defineOperation({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params }) => prisma.group.findUniqueOrThrow({ + operation: async ({ prisma, params }) => prisma.group.findUniqueOrThrow({ where: { id: params.id, }, }) }), - readGroupExpanded: serviceMethod({ + readGroupExpanded: defineOperation({ authorizer: () => groupAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const group = await prisma.group.findFirstOrThrow({ where: { id: params.id, @@ -254,9 +254,9 @@ export const groupMethods = { } }), - readGroupsExpanded: serviceMethod({ + readGroupsExpanded: defineOperation({ authorizer: () => groupAuthers.read.dynamicFields({}), - method: async ({ prisma }) => { + operation: async ({ prisma }) => { const groups = (await prisma.group.findMany({ include: groupsExpandedIncluder, })).map(checkGroupValidity).map(grp => ({ ...grp, membershipsToInferFirstOrder: grp.memberships })) @@ -265,9 +265,9 @@ export const groupMethods = { } }), - readGroupsStructured: serviceMethod({ + readGroupsStructured: defineOperation({ authorizer: () => groupAuthers.read.dynamicFields({}), - method: async () => { + operation: async () => { const groupsStructured: GroupsStructured = { CLASS: { ...groupTypesConfig.CLASS, @@ -305,7 +305,7 @@ export const groupMethods = { } }), - readUsersOfGroups: serviceMethod({ + readUsersOfGroups: defineOperation({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ groups: z.array(z.object({ @@ -313,7 +313,7 @@ export const groupMethods = { admin: z.boolean(), })), }), - method: async ({ prisma, params }): Promise => { + operation: async ({ prisma, params }): Promise => { const memberships = await prisma.membership.findMany({ where: { OR: params.groups.map(({ admin, groupId }) => ({ @@ -332,12 +332,12 @@ export const groupMethods = { } }), - readGroupsOfUser: serviceMethod({ + readGroupsOfUser: defineOperation({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ userId: z.number(), }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const memberships = await prisma.membership.findMany({ where: { userId: params.userId, diff --git a/src/services/images/methods.ts b/src/services/images/methods.ts index e9071f962..415e363e3 100644 --- a/src/services/images/methods.ts +++ b/src/services/images/methods.ts @@ -3,10 +3,10 @@ import { readSpecialImageCollection } from './collections/read' import { imageAuthers } from './authers' import { imageSchemas } from './schemas' import { allowedExtensions, avifConvertionOptions, imageSizes } from './config' +import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' import { createFile } from '@/services/store/createFile' import logger from '@/lib/logger' -import { serviceMethod } from '@/services/serviceMethod' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import sharp from 'sharp' @@ -36,13 +36,13 @@ async function createOneInStore(file: File, allowedExt: string[], size: number) * @param name - the name of the image * @param config - the config for the image (special) */ -const createSourceless = serviceMethod({ +const createSourceless = defineOperation({ authorizer: () => imageAuthers.createSourcelessImage.dynamicFields({}), paramsSchema: z.object({ name: z.string(), special: z.nativeEnum(SpecialImage), }), - method: async ({ prisma, params: { name, special } }) => { + operation: async ({ prisma, params: { name, special } }) => { const standardCollection = await readSpecialImageCollection('STANDARDIMAGES') logger.warn(` creating a bad image, Something has caused the server to lose a neccesary image. @@ -76,13 +76,13 @@ export const imageMethods = { * All images are saved as avif (except the original). * @param collectionId - The id of the collection to add the image to */ - create: serviceMethod({ + create: defineOperation({ authorizer: () => imageAuthers.create.dynamicFields({}), paramsSchema: z.object({ collectionId: z.number(), }), dataSchema: imageSchemas.create, - method: async ({ prisma, params: { collectionId }, data }) => { + operation: async ({ prisma, params: { collectionId }, data }) => { const { file, ...meta } = data const buffer = Buffer.from(await file.arrayBuffer()) const avifBuffer = await sharp(buffer).toFormat('avif').avif(avifConvertionOptions).toBuffer() @@ -125,14 +125,14 @@ export const imageMethods = { * Creates many images from files. * The method will resize the images to the correct sizes and save them to the store. */ - createMany: serviceMethod({ + createMany: defineOperation({ authorizer: () => imageAuthers.createMany.dynamicFields({}), paramsSchema: z.object({ useFileName: z.boolean(), collectionId: z.number(), }), dataSchema: imageSchemas.createMany, - method: async ({ + operation: async ({ params: { useFileName, collectionId }, data, }) => { @@ -151,12 +151,12 @@ export const imageMethods = { /** * Reads an image by id. */ - read: serviceMethod({ + read: defineOperation({ authorizer: () => imageAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params: { id } }) => { + operation: async ({ prisma, params: { id } }) => { const image = await prisma.image.findUnique({ where: { id, @@ -171,7 +171,7 @@ export const imageMethods = { /** * Reads a page of images in a collection by collectionId. */ - readPage: serviceMethod({ + readPage: defineOperation({ authorizer: () => imageAuthers.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), @@ -182,7 +182,7 @@ export const imageMethods = { collectionId: z.number(), }), ), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const { collectionId } = params.paging.details return await prisma.image.findMany({ where: { @@ -197,12 +197,12 @@ export const imageMethods = { * Reads a special image by name (special atr.). * In the case that the special image does not exist (bad state) a "bad" image will be created. */ - readSpecial: serviceMethod({ + readSpecial: defineOperation({ authorizer: () => imageAuthers.readSpecial.dynamicFields({}), paramsSchema: z.object({ special: z.nativeEnum(SpecialImage) }), - method: async ({ prisma, params: { special }, session }) => { + operation: async ({ prisma, params: { special }, session }) => { const image = await prisma.image.findUnique({ where: { special, @@ -221,13 +221,13 @@ export const imageMethods = { /** * Update a image by id and data. Also can give the image a new license by data.licenseId. */ - update: serviceMethod({ + update: defineOperation({ authorizer: () => imageAuthers.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), dataSchema: imageSchemas.update, - method: async ({ prisma, params: { id }, data: { licenseId, ...data } }) => { + operation: async ({ prisma, params: { id }, data: { licenseId, ...data } }) => { console.log('lic', licenseId) return await prisma.image.update({ where: { @@ -243,12 +243,12 @@ export const imageMethods = { } }), - destroy: serviceMethod({ + destroy: defineOperation({ authorizer: () => imageAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params: { id } }) => { + operation: async ({ prisma, params: { id } }) => { const image = await prisma.image.findUnique({ where: { id, diff --git a/src/services/licenses/methods.ts b/src/services/licenses/methods.ts index c1e0e52f6..419c8ae12 100644 --- a/src/services/licenses/methods.ts +++ b/src/services/licenses/methods.ts @@ -2,27 +2,27 @@ import '@pn-server-only' import { licenseSchemas } from './schemas' import { licenseAuthers } from './authers' import { ServerError } from '@/services/error' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' export const licenseMethods = { - create: serviceMethod({ + create: defineOperation({ authorizer: () => licenseAuthers.create.dynamicFields({}), dataSchema: licenseSchemas.create, - method: async ({ prisma, data }) => await prisma.license.create({ + operation: async ({ prisma, data }) => await prisma.license.create({ data, }), }), - readAll: serviceMethod({ + readAll: defineOperation({ authorizer: () => licenseAuthers.destroy.dynamicFields({}), - method: async ({ prisma }) => await prisma.license.findMany() + operation: async ({ prisma }) => await prisma.license.findMany() }), - destroy: serviceMethod({ + destroy: defineOperation({ paramsSchema: z.object({ id: z.number(), }), authorizer: () => licenseAuthers.destroy.dynamicFields({}), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const { name: licenseName } = await prisma.license.findUniqueOrThrow({ where: { id: params.id }, select: { name: true } @@ -44,13 +44,13 @@ export const licenseMethods = { await prisma.license.delete({ where: { id: params.id } }) } }), - update: serviceMethod({ + update: defineOperation({ paramsSchema: z.object({ id: z.number(), }), dataSchema: licenseSchemas.update, authorizer: () => licenseAuthers.update.dynamicFields({}), - method: async ({ prisma, params, data }) => { + operation: async ({ prisma, params, data }) => { await prisma.license.update({ where: { id: params.id diff --git a/src/services/lockers/locations/methods.ts b/src/services/lockers/locations/methods.ts index 238e964e8..7d4bd9246 100644 --- a/src/services/lockers/locations/methods.ts +++ b/src/services/lockers/locations/methods.ts @@ -1,6 +1,6 @@ import { lockerLocationAuthers } from './authers' import { lockersSchemas } from '@/services/lockers/schemas' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' export const lockerLocationMethods = { /** @@ -10,10 +10,10 @@ export const lockerLocationMethods = { * * @returns The newly created locker location object. */ - create: serviceMethod({ + create: defineOperation({ authorizer: () => lockerLocationAuthers.create.dynamicFields({}), dataSchema: lockersSchemas.createLocation, - method: async ({ prisma, data }) => prisma.lockerLocation.create({ + operation: async ({ prisma, data }) => prisma.lockerLocation.create({ data: { building: data.building, floor: data.floor @@ -26,8 +26,8 @@ export const lockerLocationMethods = { * * @returns All locker location objects. */ - readAll: serviceMethod({ + readAll: defineOperation({ authorizer: () => lockerLocationAuthers.readAll.dynamicFields({}), - method: async ({ prisma }) => prisma.lockerLocation.findMany() + operation: async ({ prisma }) => prisma.lockerLocation.findMany() }), } diff --git a/src/services/lockers/methods.ts b/src/services/lockers/methods.ts index 34dced335..217579dbc 100644 --- a/src/services/lockers/methods.ts +++ b/src/services/lockers/methods.ts @@ -1,8 +1,8 @@ import '@pn-server-only' import { lockerReservationIncluder } from './reservations/config' -import { lockerAuthers } from './authers' import { lockersSchemas } from './schemas' -import { serviceMethod } from '@/services/serviceMethod' +import { lockerAuthers } from './authers' +import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' @@ -40,10 +40,10 @@ export const lockerMethods = { * * @returns The newly created locker object. */ - create: serviceMethod({ + create: defineOperation({ authorizer: () => lockerAuthers.create.dynamicFields({}), dataSchema: lockersSchemas.create, - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { console.log(data) return await prisma.locker.create({ data, @@ -58,12 +58,12 @@ export const lockerMethods = { * * @returns The locker object. */ - read: serviceMethod({ + read: defineOperation({ authorizer: () => lockerAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: async ({ prisma, params: { id } }) => { + operation: async ({ prisma, params: { id } }) => { const locker = await prisma.locker.findUniqueOrThrow({ where: { id, @@ -84,7 +84,7 @@ export const lockerMethods = { * * @returns A list of locker objects. */ - readPage: serviceMethod({ + readPage: defineOperation({ authorizer: () => lockerAuthers.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), @@ -93,7 +93,7 @@ export const lockerMethods = { }), z.any(), ), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const lockers = await prisma.locker.findMany({ ...cursorPageingSelection(params.paging.page), orderBy: { diff --git a/src/services/lockers/reservations/methods.ts b/src/services/lockers/reservations/methods.ts index 19fe315b7..a0a8fabc9 100644 --- a/src/services/lockers/reservations/methods.ts +++ b/src/services/lockers/reservations/methods.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { lockerReservationAuthers } from './authers' import { lockerReservationSchemas } from './schemas' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { Smorekopp } from '@/services/error' import { groupMethods } from '@/services/groups/methods' import { z } from 'zod' @@ -16,13 +16,13 @@ export const lockerReservationMethods = { * * @returns The newly created reservation object. */ - create: serviceMethod({ + create: defineOperation({ authorizer: () => lockerReservationAuthers.create.dynamicFields({}), paramsSchema: z.object({ lockerId: z.number(), }), dataSchema: lockerReservationSchemas.create, - method: async ({ prisma, session, data, params }) => { + operation: async ({ prisma, session, data, params }) => { // TODO: Use authers for authing in stead of this // Verify that user is in group if (data.groupId) { @@ -63,12 +63,12 @@ export const lockerReservationMethods = { * * @returns The updated reservation object. */ - read: serviceMethod({ + read: defineOperation({ authorizer: () => lockerReservationAuthers.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), - method: ({ prisma, params: { id } }) => prisma.lockerReservation.findUniqueOrThrow({ + operation: ({ prisma, params: { id } }) => prisma.lockerReservation.findUniqueOrThrow({ where: { id, }, @@ -83,13 +83,13 @@ export const lockerReservationMethods = { * * @returns The updated reservation object. */ - update: serviceMethod({ + update: defineOperation({ authorizer: () => lockerReservationAuthers.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), dataSchema: lockerReservationSchemas.update, - method: async ({ prisma, session, data, params: { id } }) => { + operation: async ({ prisma, session, data, params: { id } }) => { // TODO: Use authers for authing in stead of this // Verify that the user updating is the creator of the reservation const reservation = await prisma.lockerReservation.findUniqueOrThrow({ diff --git a/src/services/notifications/channel/methods.ts b/src/services/notifications/channel/methods.ts index b739d009c..324af1d91 100644 --- a/src/services/notifications/channel/methods.ts +++ b/src/services/notifications/channel/methods.ts @@ -9,14 +9,14 @@ import { } from '@/services/notifications/config' import { notificationMethodSchema } from '@/services/notifications/schemas' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { DEFAULT_NOTIFICATION_ALIAS } from '@/services/notifications/email/config' import { ServerError } from '@/services/error' import { z } from 'zod' import type { ExpandedNotificationChannel, NotificationMethodGeneral } from '@/services/notifications/Types' export const notificationChannelMethods = { - create: serviceMethod({ + create: defineOperation({ authorizer: () => notificationChannelAuthers.create.dynamicFields({}), dataSchema: notificationChannelSchemas.create, opensTransaction: true, @@ -24,7 +24,7 @@ export const notificationChannelMethods = { availableMethods: notificationMethodSchema, defaultMethods: notificationMethodSchema, }), - method: async ({ prisma, data, params }): Promise => { + operation: async ({ prisma, data, params }): Promise => { if (!validateMethods(params.availableMethods, params.defaultMethods)) { throw new ServerError('BAD PARAMETERS', 'Default methods cannot exceed available methods.') } @@ -104,16 +104,16 @@ export const notificationChannelMethods = { } }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => notificationChannelAuthers.read.dynamicFields({}), - method: async ({ prisma }) => await prisma.notificationChannel.findMany({ + operation: async ({ prisma }) => await prisma.notificationChannel.findMany({ include: availableNotificationMethodIncluder, }) }), - readDefault: serviceMethod({ + readDefault: defineOperation({ authorizer: () => notificationChannelAuthers.read.dynamicFields({}), - method: async ({ prisma }) => await prisma.notificationChannel.findMany({ + operation: async ({ prisma }) => await prisma.notificationChannel.findMany({ where: { defaultMethods: { OR: notificationMethodsArray.map(method => ({ @@ -125,7 +125,7 @@ export const notificationChannelMethods = { }) }), - update: serviceMethod({ + update: defineOperation({ authorizer: () => notificationChannelAuthers.update.dynamicFields({}), dataSchema: notificationChannelSchemas.update, paramsSchema: z.object({ @@ -134,7 +134,7 @@ export const notificationChannelMethods = { defaultMethods: notificationMethodSchema, }), opensTransaction: true, - method: async ({ prisma, data, params }) => { + operation: async ({ prisma, data, params }) => { if (!validateMethods(params.availableMethods, params.defaultMethods)) { throw new ServerError('BAD PARAMETERS', 'Default methods cannot exceed available methods.') } @@ -218,13 +218,13 @@ export const notificationChannelMethods = { }), // It doesn't seem that this function is used yet. -Theodor - destroy: serviceMethod({ + destroy: defineOperation({ authorizer: () => notificationChannelAuthers.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), opensTransaction: true, - method: async ({ prisma, params }) => prisma.$transaction(async (tx) => { + operation: async ({ prisma, params }) => prisma.$transaction(async (tx) => { // NOTE: this should maybe be just a archive not a delete const results = await tx.notificationChannel.delete({ diff --git a/src/services/notifications/methods.ts b/src/services/notifications/methods.ts index 345b65983..ea7dd044c 100644 --- a/src/services/notifications/methods.ts +++ b/src/services/notifications/methods.ts @@ -5,7 +5,7 @@ import { notificationSchemas } from './schemas' import { allNotificationMethodsOn, notificationMethodsArray } from './config' import { availableNotificationMethodIncluder } from './channel/config' import { userFilterSelection } from '@/services/users/config' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { ServerOnly } from '@/auth/auther/ServerOnly' import { z } from 'zod' import { SpecialNotificationChannel } from '@prisma/client' @@ -35,10 +35,10 @@ export const notificationMethods = { * @param data - The detailed data for dispatching the notification. * @returns A promise that resolves with an object containing the dispatched notification and the number of recipients. */ - create: serviceMethod({ + create: defineOperation({ authorizer: () => notificationAuthers.create.dynamicFields({}), dataSchema: notificationSchemas.create, - method: async ({ prisma, data }): Promise => { + operation: async ({ prisma, data }): Promise => { // This prevent notifications from beeing sent during seeding if (process.env.IGNORE_SERVER_ONLY) { return { @@ -117,13 +117,13 @@ export const notificationMethods = { * @param message - The message content of the notification. * @returns A promise that resolves with an object containing the dispatched notification and the number of recipients. */ - createSpecial: serviceMethod({ + createSpecial: defineOperation({ authorizer: ServerOnly, paramsSchema: z.object({ special: z.nativeEnum(SpecialNotificationChannel), }), dataSchema: notificationSchemas.createSpecial, - method: async ({ prisma, params, data, session }): Promise => { + operation: async ({ prisma, params, data, session }): Promise => { const channel = await prisma.notificationChannel.findUniqueOrThrow({ where: { special: params.special, diff --git a/src/services/notifications/subscription/methods.ts b/src/services/notifications/subscription/methods.ts index 4ec016aac..30f2a5653 100644 --- a/src/services/notifications/subscription/methods.ts +++ b/src/services/notifications/subscription/methods.ts @@ -5,7 +5,7 @@ import { validateMethods } from '@/services/notifications/channel/schemas' import { allNotificationMethodsOff, allNotificationMethodsOn } from '@/services/notifications/config' import { availableNotificationMethodIncluder } from '@/services/notifications/channel/config' import { notificationChannelMethods } from '@/services/notifications/channel/methods' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { ServerOnly } from '@/auth/auther/ServerOnly' import { ServerError } from '@/services/error' import { z } from 'zod' @@ -109,12 +109,12 @@ async function createTransactionPart( } export const notificationSubscriptionMethods = { - read: serviceMethod({ + read: defineOperation({ paramsSchema: z.object({ userId: z.number(), }), authorizer: ({ params }) => notificationSubscriptionAuthers.read.dynamicFields(params), - method: async ({ prisma, params }) => await prisma.notificationSubscription.findMany({ + operation: async ({ prisma, params }) => await prisma.notificationSubscription.findMany({ where: { userId: params.userId, }, @@ -122,13 +122,13 @@ export const notificationSubscriptionMethods = { }), }), - createDefault: serviceMethod({ + createDefault: defineOperation({ authorizer: ServerOnly, paramsSchema: z.object({ userId: z.number(), }), opensTransaction: true, - method: async ({ prisma, params, session }) => { + operation: async ({ prisma, params, session }) => { const channels = await notificationChannelMethods.readDefault({ session, bypassAuth: true, @@ -157,13 +157,13 @@ export const notificationSubscriptionMethods = { }), - update: serviceMethod({ + update: defineOperation({ authorizer: ({ params }) => notificationSubscriptionAuthers.update.dynamicFields(params), paramsSchema: z.object({ userId: z.number(), }), dataSchema: subscriptionSchemas.update, - method: async ({ prisma, params, data }): Promise => { + operation: async ({ prisma, params, data }): Promise => { // Prepare updates and validate the data with the data in the database const transactionParts = (await Promise.all( data.subscriptions.map(subscription => diff --git a/src/services/permissions/methods.ts b/src/services/permissions/methods.ts index 450ebdb59..cc48b8054 100644 --- a/src/services/permissions/methods.ts +++ b/src/services/permissions/methods.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { permissionAuthers } from './auther' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { invalidateAllUserSessionData, invalidateManyUserSessionData } from '@/services/auth/invalidateSession' import { groupsWithRelationsIncluder } from '@/services/groups/config' @@ -10,18 +10,18 @@ import { z } from 'zod' export const permissionMethods = { - readDefaultPermissions: serviceMethod({ + readDefaultPermissions: defineOperation({ authorizer: () => permissionAuthers.readDefaultPermissions.dynamicFields({}), - method: async ({ prisma }) => + operation: async ({ prisma }) => (await prisma.defaultPermission.findMany()).map(perm => perm.permission) }), - readPermissionsOfUser: serviceMethod({ + readPermissionsOfUser: defineOperation({ authorizer: ServerOnlyAuther, paramsSchema: z.object({ userId: z.number(), }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const [defaultPermissions, groupPermissions] = await Promise.all([ permissionMethods.readDefaultPermissions({}), prisma.membership.findMany({ @@ -49,21 +49,21 @@ export const permissionMethods = { } }), - readPermissionsOfGroup: serviceMethod({ + readPermissionsOfGroup: defineOperation({ authorizer: () => permissionAuthers.readGroupPermissions.dynamicFields({}), paramsSchema: z.object({ groupId: z.number() }), - method: async ({ prisma, params }) => (await prisma.groupPermission.findMany({ + operation: async ({ prisma, params }) => (await prisma.groupPermission.findMany({ where: { groupId: params.groupId } })).map(permission => permission.permission) }), - readPermissionMatrix: serviceMethod({ + readPermissionMatrix: defineOperation({ authorizer: () => permissionAuthers.readPermissionMatrix.dynamicFields({}), - method: async ({ prisma }) => { + operation: async ({ prisma }) => { const groupsPermission = await prisma.group.findMany({ include: { ...groupsWithRelationsIncluder, @@ -79,12 +79,12 @@ export const permissionMethods = { } }), - updateDefaultPermissions: serviceMethod({ + updateDefaultPermissions: defineOperation({ authorizer: () => permissionAuthers.updateDefaultPermissions.dynamicFields({}), dataSchema: z.object({ permissions: z.nativeEnum(Permission).array(), }), - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { await prisma.defaultPermission.deleteMany({ where: { permission: { @@ -107,7 +107,7 @@ export const permissionMethods = { } }), - updateGroupPermission: serviceMethod({ + updateGroupPermission: defineOperation({ authorizer: () => permissionAuthers.updateGroupPermission.dynamicFields({}), paramsSchema: z.object({ groupId: z.number(), @@ -116,7 +116,7 @@ export const permissionMethods = { dataSchema: z.object({ value: z.boolean() }), - method: async ({ prisma, params, data }) => { + operation: async ({ prisma, params, data }) => { if (data.value) { await prisma.groupPermission.create({ data: { diff --git a/src/services/serviceMethod.ts b/src/services/serviceOperation.ts similarity index 68% rename from src/services/serviceMethod.ts rename to src/services/serviceOperation.ts index 80e2b7fc7..bf75379d7 100644 --- a/src/services/serviceMethod.ts +++ b/src/services/serviceOperation.ts @@ -11,11 +11,11 @@ import type { SessionMaybeUser } from '@/auth/Session' import type { AutherResult } from '@/auth/auther/Auther' /** - * This is the type for the prisma client that is passed to the service method. - * It can't simply be PrismaClient because it can be usefull to use a service method + * This is the type for the prisma client that is passed to the service operation. + * It can't simply be PrismaClient because it can be usefull to use a service operation * inside a transaction. In that case, the prisma client is a Prisma.TransactionClient. * The caveat is that a Prisma.TransactionClient can't be used to open a new transaction - * so if the service method opens a transaction, the prisma client can only be a PrismaClient. + * so if the service operation opens a transaction, the prisma client can only be a PrismaClient. */ type PrismaPossibleTransaction< OpensTransaction extends boolean @@ -29,10 +29,10 @@ type HideNever = { } /** - * The input type which should will be passed to the service method. + * The input type which should will be passed to the service operation. * This is what the zod schemas will parse. */ -export type ServiceMethodInputUnparsed< +export type ServiceOperationInputUnparsed< ParamsSchema extends z.ZodTypeAny | undefined, DataSchema extends z.ZodTypeAny | undefined, > = HideNever<{ @@ -41,10 +41,10 @@ export type ServiceMethodInputUnparsed< }> /** - * The input that is provided to the a service method implementation. + * The input that is provided to the a service operation implementation. * This is the the input after is has been parsed with zod. */ -export type ServiceMethodInputParsed< +export type ServiceOperationInputParsed< ParamsSchema extends z.ZodTypeAny | undefined, DataSchema extends z.ZodTypeAny | undefined, > = HideNever<{ @@ -53,19 +53,19 @@ export type ServiceMethodInputParsed< }> /** - * This is the actual input type for the service method function used under the hood + * This is the actual input type for the service operation function used under the hood * since the input can be from the client we can't guarantee type safety. */ -export type ServiceMethodInputUnchecked = { +export type ServiceOperationInputUnchecked = { params?: unknown, data?: unknown, } /** - * This is the type for the configuration of a service method. - * I.e. what is passed to the ServiceMethod function when creating a service method. + * This is the type for the configuration of a service operation. + * I.e. what is passed to the ServiceOperation function when creating a service operation. */ -type ServiceMethodConfig< +type ServiceOperationConfig< OpensTransaction extends boolean, Return, ParamsSchema extends z.ZodTypeAny | undefined, @@ -74,14 +74,14 @@ type ServiceMethodConfig< paramsSchema?: ParamsSchema, dataSchema?: DataSchema, opensTransaction?: OpensTransaction, - authorizer?: (args: ServiceMethodInputParsed & ServiceMethodContext) => + authorizer?: (args: ServiceOperationInputParsed & ServiceOperationContext) => AutherResult| Promise, - method: (args: ServiceMethodInputParsed & ServiceMethodContext) => + operation: (args: ServiceOperationInputParsed & ServiceOperationContext) => Return | Promise, } /** - * The function signature for a service method. + * The function signature for a service operation. * * The generic `Checked` determines whether to use compile time type checking or not for the argument. * @@ -92,7 +92,7 @@ type ServiceMethodConfig< * Importantly, this will not skip the runtime validation with zod. * `UNCHECKED` is used when handling untyped input, e.g. from an HTTP request. */ -export type ServiceMethod< +export type ServiceOperation< OpensTransaction extends boolean, Return, ParamsSchema extends z.ZodTypeAny | undefined, @@ -101,42 +101,45 @@ export type ServiceMethod< ( args: ( Checked extends 'CHECKED' - ? ServiceMethodInputUnparsed - : ServiceMethodInputUnchecked - ) & Partial> + ? ServiceOperationInputUnparsed + : ServiceOperationInputUnchecked + ) & Partial> ): Promise paramsSchema?: ParamsSchema, dataSchema?: DataSchema, } /** - * In addition to custom data arguments, every service method receives a context object. + * In addition to custom data arguments, every service operation receives a context object. */ -type ServiceMethodContext = { +type ServiceOperationContext = { prisma: PrismaPossibleTransaction, session: SessionMaybeUser, bypassAuth: boolean, } /** - * Async local storage is used to store the context of the current service method call. - * All service methods called within the context of another service method will - * inherit the context of the parent service method, unless explicitly overridden. + * Async local storage is used to store the context of the current service operation call. + * All service operations called within the context of another service operation will + * inherit the context of the parent service operation, unless explicitly overridden. * * Read more about async local storage here: https://nodejs.org/api/async_context.html */ -const asyncLocalStorage = new AsyncLocalStorage() +const asyncLocalStorage = new AsyncLocalStorage() /** - * Runs a callback with a specific service method context. + * Runs a callback with a specific service operation context. * * @param contextOverride Partial context to override the current context with. * @param callback The callback to run with the context. * @returns The return value of the callback. */ -function withContext(contextOverride: Partial, callback: (context: ServiceMethodContext) => T): T { +function withContext( + contextOverride: Partial, + callback: (context: ServiceOperationContext) => T, +): T { const localContext = asyncLocalStorage.getStore() - const context: ServiceMethodContext = { + const context: ServiceOperationContext = { prisma: contextOverride.prisma ?? localContext?.prisma ?? globalPrisma, session: contextOverride.session ?? localContext?.session ?? Session.empty(), bypassAuth: contextOverride.bypassAuth ?? localContext?.bypassAuth ?? false, @@ -146,41 +149,41 @@ function withContext(contextOverride: Partial, callback } /** - * Wrapper for creating service methods. It handles validation, authorization, and errors for you. + * Wrapper for creating service operations. It handles validation, authorization, and errors for you. * - * @param config - The configuration for the service method. + * @param config - The configuration for the service operation. * @param config.authorizer - A function which returns the authorizer that will be used to authorize the user. * @param config.paramsSchema - The zod schemas that will be used to validate the parameters which are passed. * @param config.dataSchema - The zod schemas that will be used to validate the data which is passed. - * @param config.method - The method that will be called when the service method is executed. - * @param [config.opensTransaction=false] - Determines the type of prisma client that is passed to the service method. + * @param config.operation - The operation that will be called when the service operation is executed. + * @param [config.opensTransaction=false] - Determines the type of prisma client that is passed to the service operation. */ -export function serviceMethod< +export function defineOperation< OpensTransaction extends boolean, Return, ParamsSchema extends z.ZodTypeAny | undefined = undefined, DataSchema extends z.ZodTypeAny | undefined = undefined, >( - config: ServiceMethodConfig, -): ServiceMethod { + config: ServiceOperationConfig, +): ServiceOperation { // Guard to check if params and data are only present if there are corresponding schemas. const expectedInputsIsPresent = ( - input: ServiceMethodInputUnchecked - ): input is ServiceMethodInputParsed => { + input: ServiceOperationInputUnchecked + ): input is ServiceOperationInputParsed => { const paramsMatch = (input.params !== undefined) === (config.paramsSchema !== undefined) const dataMatches = (input.data !== undefined) === (config.dataSchema !== undefined) return paramsMatch && dataMatches } - // Guard to check if the prisma client can be used for this service method. + // Guard to check if the prisma client can be used for this service operation. const isAppropriateClient = ( prisma: PrismaClient | Prisma.TransactionClient ): prisma is PrismaPossibleTransaction => !config.opensTransaction || '$transaction' in prisma - // Wraps the execution of the method with parsing, authorization, and context handling. + // Wraps the execution of the operation with parsing, authorization, and context handling. const execute = async ( - { params, data, ...context }: ServiceMethodInputUnchecked & Partial> + { params, data, ...context }: ServiceOperationInputUnchecked & Partial> ) => { const input = { params, data } @@ -189,14 +192,14 @@ export function serviceMethod< if (!config.paramsSchema) { throw new Smorekopp( 'BAD PARAMETERS', - 'Service method received params, but has no params schema.', + 'Service operation received params, but has no params schema.', ) } const paramsParse = config.paramsSchema.safeParse(input.params) if (!paramsParse.success) { throw new Smorekopp( 'BAD PARAMETERS', - 'Invalid params passed to service method.', + 'Invalid params passed to service operation.', ) } input.params = paramsParse.data @@ -207,7 +210,7 @@ export function serviceMethod< if (!config.dataSchema) { throw new Smorekopp( 'BAD DATA', - 'Service method received data, but has no dataValidation or dataSchema.', + 'Service operation received data, but has no dataValidation or dataSchema.', ) } const parse = zfd.formData(config.dataSchema).safeParse(input.data) @@ -219,7 +222,7 @@ export function serviceMethod< } if (!expectedInputsIsPresent(input)) { - throw new Smorekopp('SERVER ERROR', 'Service method received invalid input.') + throw new Smorekopp('SERVER ERROR', 'Service operation received invalid input.') } // Then, get the context (which includes the prisma client, the session and the bypassAuth flag). @@ -229,7 +232,7 @@ export function serviceMethod< if (!isAppropriateClient(prisma)) { throw new Smorekopp( 'SERVER ERROR', - 'Service method that opens a transaction cannot be called from within a transaction.', + 'Service operation that opens a transaction cannot be called from within a transaction.', ) } @@ -239,7 +242,7 @@ export function serviceMethod< if (!config.authorizer) { throw new Smorekopp( 'UNAUTHENTICATED', - 'This service method is not externally callable.' + 'This service operation is not externally callable.' ) } @@ -251,8 +254,8 @@ export function serviceMethod< } } - // Finally, call the method. - return prismaErrorWrapper(() => config.method({ ...input, prisma, bypassAuth, session })) + // Finally, call the operation. + return prismaErrorWrapper(() => config.operation({ ...input, prisma, bypassAuth, session })) }) } diff --git a/src/services/shop/product/methods.ts b/src/services/shop/product/methods.ts index e944720d6..82076ad0a 100644 --- a/src/services/shop/product/methods.ts +++ b/src/services/shop/product/methods.ts @@ -1,4 +1,4 @@ -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import '@pn-server-only' import { ServerError } from '@/services/error' import { z } from 'zod' @@ -7,10 +7,10 @@ import { productAuthers } from './authers' import { productSchemas } from './schemas' export const productMethods = { - create: serviceMethod({ + create: defineOperation({ authorizer: () => productAuthers.create.dynamicFields({}), dataSchema: productSchemas.create, - method: async ({ prisma, data }) => prisma.product.create({ + operation: async ({ prisma, data }) => prisma.product.create({ data: { ...data, barcode: convertBarcode(data.barcode), @@ -19,13 +19,13 @@ export const productMethods = { }) }), - createForShop: serviceMethod({ + createForShop: defineOperation({ authorizer: () => productAuthers.create.dynamicFields({}), paramsSchema: z.object({ shopId: z.number(), }), dataSchema: productSchemas.createForShop, - method: async ({ prisma, params, data }) => prisma.product.create({ + operation: async ({ prisma, params, data }) => prisma.product.create({ data: { name: data.name.toUpperCase(), description: data.description, @@ -44,10 +44,10 @@ export const productMethods = { }) }), - createShopConnection: serviceMethod({ + createShopConnection: defineOperation({ authorizer: () => productAuthers.createShopConnection.dynamicFields({}), dataSchema: productSchemas.createShopConnection, - method: async ({ prisma, data }) => prisma.shopProduct.create({ + operation: async ({ prisma, data }) => prisma.shopProduct.create({ data: { shop: { connect: { @@ -64,17 +64,17 @@ export const productMethods = { }) }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => productAuthers.read.dynamicFields({}), - method: async ({ prisma }) => await prisma.product.findMany() + operation: async ({ prisma }) => await prisma.product.findMany() }), - read: serviceMethod({ + read: defineOperation({ authorizer: () => productAuthers.read.dynamicFields({}), paramsSchema: z.object({ productId: z.number(), }), - method: async ({ prisma, params }) => await prisma.product.findUniqueOrThrow({ + operation: async ({ prisma, params }) => await prisma.product.findUniqueOrThrow({ where: { id: params.productId }, @@ -88,10 +88,10 @@ export const productMethods = { }) }), - readByBarCode: serviceMethod({ + readByBarCode: defineOperation({ authorizer: () => productAuthers.read.dynamicFields({}), dataSchema: productSchemas.readByBarCode, - method: async ({ prisma, data }): Promise => { + operation: async ({ prisma, data }): Promise => { if (!data.barcode) { throw new ServerError('BAD PARAMETERS', 'Barcode is required.') } @@ -130,10 +130,10 @@ export const productMethods = { } }), - update: serviceMethod({ + update: defineOperation({ authorizer: () => productAuthers.update.dynamicFields({}), dataSchema: productSchemas.update, - method: async ({ prisma, data }) => prisma.product.update({ + operation: async ({ prisma, data }) => prisma.product.update({ where: { id: data.productId, }, @@ -145,14 +145,14 @@ export const productMethods = { }) }), - updateForShop: serviceMethod({ + updateForShop: defineOperation({ authorizer: () => productAuthers.update.dynamicFields({}), dataSchema: productSchemas.updateForShop, paramsSchema: z.object({ shopId: z.number(), productId: z.number(), }), - method: async ({ prisma, params, data }) => prisma.product.update({ + operation: async ({ prisma, params, data }) => prisma.product.update({ where: { id: params.productId, }, diff --git a/src/services/shop/product/schemas.ts b/src/services/shop/product/schemas.ts index f44b7771b..1d4e48275 100644 --- a/src/services/shop/product/schemas.ts +++ b/src/services/shop/product/schemas.ts @@ -1,4 +1,4 @@ -import { zpn } from '@/lib/fields/zpn' +import { Zpn } from '@/lib/fields/zpn' import { convertPrice } from '@/lib/money/convert' import { z } from 'zod' @@ -8,7 +8,7 @@ const baseSchema = z.object({ description: z.string(), price: z.coerce.number().int().min(1).transform((val) => convertPrice(val)), barcode: z.string().or(z.number()).optional(), - active: zpn.checkboxOrBoolean({ label: 'Active' }), + active: Zpn.checkboxOrBoolean({ label: 'Active' }), productId: z.coerce.number().int(), }) diff --git a/src/services/shop/purchase/methods.ts b/src/services/shop/purchase/methods.ts index 92c51fea1..ed1f311de 100644 --- a/src/services/shop/purchase/methods.ts +++ b/src/services/shop/purchase/methods.ts @@ -2,14 +2,14 @@ import '@pn-server-only' import { purchaseAuthers } from './authers' import { purchaseSchemas } from './schemas' import { ServerError } from '@/services/error' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { userMethods } from '@/services/users/methods' import { permissionMethods } from '@/services/permissions/methods' import { userFilterSelection } from '@/services/users/config' import { PurchaseMethod } from '@prisma/client' export const purchaseMethods = { - createByStudentCard: serviceMethod({ + createByStudentCard: defineOperation({ authorizer: async ({ data }) => { let user try { @@ -38,7 +38,7 @@ export const purchaseMethods = { }) }, dataSchema: purchaseSchemas.createFromStudentCard, - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { if (data.products.length === 0) { throw new ServerError('BAD PARAMETERS', 'The list of products to buy cannot be empty') } diff --git a/src/services/shop/shop/methods.ts b/src/services/shop/shop/methods.ts index f751ec101..8c2d466cd 100644 --- a/src/services/shop/shop/methods.ts +++ b/src/services/shop/shop/methods.ts @@ -1,4 +1,4 @@ -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import '@pn-server-only' import { z } from 'zod' import type { ExtendedShop } from './Types' @@ -6,25 +6,25 @@ import { shopSchemas } from './schema' import { shopAuthers } from './authers' export const shopMethods = { - create: serviceMethod({ + create: defineOperation({ dataSchema: shopSchemas.create, authorizer: () => shopAuthers.create.dynamicFields({}), - method: async ({ prisma, data }) => prisma.shop.create({ + operation: async ({ prisma, data }) => prisma.shop.create({ data }) }), - readMany: serviceMethod({ + readMany: defineOperation({ authorizer: () => shopAuthers.read.dynamicFields({}), - method: ({ prisma }) => prisma.shop.findMany(), + operation: ({ prisma }) => prisma.shop.findMany(), }), - read: serviceMethod({ + read: defineOperation({ authorizer: () => shopAuthers.read.dynamicFields({}), paramsSchema: z.object({ shopId: z.number(), }), - method: async ({ prisma, params }): Promise => { + operation: async ({ prisma, params }): Promise => { const results = await prisma.shop.findFirst({ where: { id: params.shopId diff --git a/src/services/users/methods.ts b/src/services/users/methods.ts index e190cd347..976d59ca7 100644 --- a/src/services/users/methods.ts +++ b/src/services/users/methods.ts @@ -15,7 +15,7 @@ import { sendVerifyEmail } from '@/services/notifications/email/systemMail/verif import { updateUserOmegaMembershipGroup } from '@/services/groups/omegaMembershipGroups/update' import { sendUserInvitationEmail } from '@/services/notifications/email/systemMail/userInvitivation' import { readOmegaMembershipGroup } from '@/services/groups/omegaMembershipGroups/read' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { readPageInputSchemaObject } from '@/lib/paging/schema' import { ServerError } from '@/services/error' import { getMembershipFilter } from '@/auth/getMembershipFilter' @@ -31,10 +31,10 @@ export const userMethods = { * This Method creates an user by invitation, and sends the invitation email. * WARNING: This should not be used to create users registered by Feide. */ - create: serviceMethod({ + create: defineOperation({ dataSchema: userSchemas.create, authorizer: () => userAuthers.create.dynamicFields({}), - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { const omegaMembership = await readOmegaMembershipGroup('EXTERNAL') const omegaOrder = await readCurrentOmegaOrder() @@ -61,7 +61,7 @@ export const userMethods = { } }), - read: serviceMethod({ + read: defineOperation({ paramsSchema: z.object({ username: z.string().optional(), id: z.coerce.number().optional(), @@ -69,7 +69,7 @@ export const userMethods = { studentCard: z.string().optional(), }), authorizer: ({ params }) => userAuthers.read.dynamicFields(params), - method: async ({ prisma, params }) => await prisma.user.findUniqueOrThrow({ + operation: async ({ prisma, params }) => await prisma.user.findUniqueOrThrow({ where: { id: params.id, ...params @@ -78,7 +78,7 @@ export const userMethods = { }) }), - readOrNull: serviceMethod({ + readOrNull: defineOperation({ paramsSchema: z.object({ username: z.string().optional(), id: z.coerce.number().optional(), @@ -86,7 +86,7 @@ export const userMethods = { studentCard: z.string().optional(), }), authorizer: ({ params }) => userAuthers.read.dynamicFields(params), - method: async ({ prisma, params }) => await prisma.user.findUnique({ + operation: async ({ prisma, params }) => await prisma.user.findUnique({ where: { id: params.id, // This is a bit wierd, but now ts is satisfied. ...params @@ -95,12 +95,12 @@ export const userMethods = { }) }), - readProfile: serviceMethod({ + readProfile: defineOperation({ paramsSchema: z.object({ username: z.string(), }), authorizer: ({ params }) => userAuthers.readProfile.dynamicFields({ username: params.username }), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { const defaultProfileImage = await imageMethods.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, }) @@ -128,7 +128,7 @@ export const userMethods = { } }), - readPage: serviceMethod({ + readPage: defineOperation({ paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -147,7 +147,7 @@ export const userMethods = { }) ), authorizer: () => userAuthers.readPage.dynamicFields({}), - method: async ({ prisma, params }): Promise => { + operation: async ({ prisma, params }): Promise => { const { page, details } = params.paging const words = details.partOfName.split(' ') @@ -255,11 +255,11 @@ export const userMethods = { } }), - connectStudentCard: serviceMethod({ + connectStudentCard: defineOperation({ authorizer: () => userAuthers.connectStudentCard.dynamicFields({}), dataSchema: userSchemas.connectStudentCard, opensTransaction: true, - method: async ({ prisma, data }) => { + operation: async ({ prisma, data }) => { const currentQueue = await prisma.registerStudentCardQueue.findMany({ where: { expiry: { @@ -301,12 +301,12 @@ export const userMethods = { } }), - registerStudentCardInQueue: serviceMethod({ + registerStudentCardInQueue: defineOperation({ paramsSchema: z.object({ userId: z.number(), }), authorizer: ({ params }) => userAuthers.registerStudentCardInQueue.dynamicFields(params), - method: async (args) => { + operation: async (args) => { const expiry = (new Date()).getTime() + studentCardRegistrationExpiry * 60 * 1000 await args.prisma.registerStudentCardQueue.upsert({ where: { @@ -327,24 +327,24 @@ export const userMethods = { } }), - update: serviceMethod({ + update: defineOperation({ paramsSchema: z.union([z.object({ id: z.number() }), z.object({ username: z.string() })]), dataSchema: userSchemas.update, authorizer: () => userAuthers.update.dynamicFields({}), - method: async ({ prisma: prisma_, params, data }) => prisma_.user.update({ + operation: async ({ prisma: prisma_, params, data }) => prisma_.user.update({ where: params, data }) }), - updatePassword: serviceMethod({ + updatePassword: defineOperation({ paramsSchema: z.object({ id: z.number(), }), dataSchema: userSchemas.updatePassword, authorizer: ({ params }) => userAuthers.updatePassword.dynamicFields({ userId: params.id }), - method: async ({ prisma, data, params }) => { + operation: async ({ prisma, data, params }) => { const passwordHash = await hashAndEncryptPassword(data.password) await prisma.credentials.update({ @@ -360,13 +360,13 @@ export const userMethods = { } }), - registerNewEmail: serviceMethod({ + registerNewEmail: defineOperation({ paramsSchema: z.object({ id: z.number(), }), authorizer: ({ params }) => userAuthers.registerNewEmail.dynamicFields({ userId: params.id }), dataSchema: userSchemas.registerNewEmail, - method: async ({ prisma, params, data }) => { + operation: async ({ prisma, params, data }) => { const storedUser = await prisma.user.findUniqueOrThrow({ where: { id: params.id, @@ -424,14 +424,14 @@ export const userMethods = { * @param rawdata - Registration data. * @returns null */ - register: serviceMethod({ + register: defineOperation({ paramsSchema: z.object({ id: z.number(), }), dataSchema: userSchemas.register, authorizer: ({ params }) => userAuthers.register.dynamicFields({ userId: params.id }), opensTransaction: true, - method: async ({ prisma, data, params }) => { + operation: async ({ prisma, data, params }) => { const { sex, password, mobile, allergies } = data if (!password) throw new ServerError('BAD PARAMETERS', 'Passord er obligatorisk.') @@ -530,7 +530,7 @@ export const userMethods = { } }), - readUserWithBalance: serviceMethod({ + readUserWithBalance: defineOperation({ authorizer: ({ params }) => userAuthers.read.dynamicFields({ username: params.username || '', }), @@ -540,7 +540,7 @@ export const userMethods = { email: z.string().optional(), studentCard: z.string().optional(), }), - method: async ({ prisma: prisma_, params }) => { + operation: async ({ prisma: prisma_, params }) => { const user = await prisma_.user.findFirstOrThrow({ where: params, include: { @@ -559,12 +559,12 @@ export const userMethods = { /** * This function deletes a user from the database. */ - destroy: serviceMethod({ + destroy: defineOperation({ paramsSchema: z.object({ id: z.number(), }), authorizer: () => userAuthers.destroy.dynamicFields({}), - method: async ({ prisma, params }) => { + operation: async ({ prisma, params }) => { await prisma.user.delete({ where: { id: params.id, diff --git a/src/services/users/schemas.ts b/src/services/users/schemas.ts index 0f6d0172f..0308e6501 100644 --- a/src/services/users/schemas.ts +++ b/src/services/users/schemas.ts @@ -1,4 +1,4 @@ -import { zpn } from '@/lib/fields/zpn' +import { Zpn } from '@/lib/fields/zpn' import { SEX } from '@prisma/client' import { z } from 'zod' @@ -19,7 +19,7 @@ export const userSchema = z.object({ message: 'Passoret må minst ha 12 tegn, en stor og en liten bokstav, et tall, en rune, to emojier, en musikk note, en magisk sopp og en dråpe smørekopp-blod (avsky).' }), confirmPassword: z.string().max(50).min(12), - acceptedTerms: zpn.checkboxOrBoolean({ + acceptedTerms: Zpn.checkboxOrBoolean({ label: 'Accepted terms', }).refine(value => value, 'Du må godta vilkårene for å bruke siden.'), }) diff --git a/tests/services/service-method.test.ts b/tests/services/service-method.test.ts index 96e0b7c2f..dfcc0e1b4 100644 --- a/tests/services/service-method.test.ts +++ b/tests/services/service-method.test.ts @@ -1,14 +1,14 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequireServerOnly } from '@/auth/auther/ServerOnly' import { Session } from '@/auth/Session' -import { serviceMethod } from '@/services/serviceMethod' +import { defineOperation } from '@/services/serviceOperation' import { prisma as globalPrisma } from '@/prisma/client' import { describe, expect, test } from '@jest/globals' import { z } from 'zod' describe('service method', () => { describe('simple', () => { - const addPositiveOnly = serviceMethod({ + const addPositiveOnly = defineOperation({ authorizer: ({ data: { a, b } }) => { if (a < 0 || b < 0) { return RequireServerOnly.staticFields({}).dynamicFields({}) @@ -20,7 +20,7 @@ describe('service method', () => { a: z.number(), b: z.number(), }), - method: ({ data: { a, b } }) => a + b, + operation: ({ data: { a, b } }) => a + b, }) test('method result', async () => { @@ -58,15 +58,15 @@ describe('service method', () => { describe('nested', () => { // Simple service method that just returns its own context - const inner = serviceMethod({ + const inner = defineOperation({ authorizer: () => RequireNothing.staticFields({}).dynamicFields({}), - method: async (context) => context, + operation: async (context) => context, }) // Outer service method that calls the inner one and returns its context - const outer = serviceMethod({ + const outer = defineOperation({ authorizer: () => RequireNothing.staticFields({}).dynamicFields({}), - method: async () => await inner({}), + operation: async () => await inner({}), }) test('nested context global defaults', async () => { From 0b4041693e27751b88b75e9b18e96421313eb043 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sat, 11 Oct 2025 01:13:16 +0200 Subject: [PATCH 19/24] refactor: rename methos -> operations --- src/app/api/shop/getAll/route.ts | 4 +- src/app/api/shop/product/barcode/route.ts | 4 +- .../purchase/createByStudentCard/route.ts | 4 +- src/app/api/users/connectStudentCard/route.ts | 4 +- src/app/api/users/get/[username]/route.ts | 6 +-- .../getWithBalance/[studentCard]/route.ts | 4 +- src/app/api/users/route.ts | 4 +- src/app/lockers/[id]/page.tsx | 4 +- src/auth/Session.ts | 10 ++-- src/auth/VevenAdapter.ts | 6 +-- src/auth/authoptions.ts | 10 ++-- src/auth/getUser.ts | 4 +- .../seeder/src/development/seedDevEvents.ts | 6 +-- .../seeder/src/development/seedDevJobAds.ts | 4 +- src/services/admission/actions.ts | 4 +- .../admission/{methods.ts => operations.ts} | 4 +- src/services/api-keys/actions.ts | 12 ++--- .../api-keys/{methods.ts => operations.ts} | 2 +- src/services/applications/actions.ts | 10 ++-- .../{methods.ts => operations.ts} | 2 +- src/services/applications/periods/actions.ts | 16 +++--- .../periods/{methods.ts => operations.ts} | 10 ++-- src/services/auth/actions.ts | 10 ++-- .../auth/{methods.ts => operations.ts} | 12 ++--- src/services/cabin/actions.ts | 50 +++++++++---------- .../booking/{methods.ts => operations.ts} | 14 +++--- .../pricePeriod/{methods.ts => operations.ts} | 12 ++--- .../product/{methods.ts => operations.ts} | 10 ++-- .../{methods.ts => operations.ts} | 2 +- src/services/career/companies/actions.ts | 10 ++-- .../companies/{methods.ts => operations.ts} | 2 +- src/services/career/jobAds/actions.ts | 14 +++--- .../jobAds/{methods.ts => operations.ts} | 2 +- src/services/dots/actions.ts | 8 +-- .../dots/{methods.ts => operations.ts} | 2 +- src/services/events/actions.ts | 14 +++--- .../events/{methods.ts => operations.ts} | 6 +-- src/services/events/registration/actions.ts | 14 +++--- .../{methods.ts => operations.ts} | 10 ++-- src/services/events/tags/actions.ts | 14 +++--- .../events/tags/{methods.ts => operations.ts} | 2 +- src/services/groups/actions.ts | 10 ++-- src/services/groups/committees/actions.ts | 12 ++--- src/services/groups/committees/create.ts | 4 +- .../committees/{methods.ts => operations.ts} | 8 +-- src/services/groups/committees/read.ts | 4 +- src/services/groups/committees/update.ts | 4 +- src/services/groups/interestGroups/actions.ts | 10 ++-- .../{methods.ts => operations.ts} | 2 +- src/services/groups/memberships/create.ts | 8 +-- src/services/groups/memberships/destroy.ts | 6 +-- src/services/groups/memberships/update.ts | 4 +- .../groups/{methods.ts => operations.ts} | 4 +- src/services/images/actions.ts | 16 +++--- src/services/images/collections/read.ts | 4 +- .../images/{methods.ts => operations.ts} | 4 +- src/services/licenses/actions.ts | 10 ++-- .../licenses/{methods.ts => operations.ts} | 2 +- src/services/lockers/actions.ts | 20 ++++---- .../locations/{methods.ts => operations.ts} | 2 +- .../lockers/{methods.ts => operations.ts} | 2 +- .../{methods.ts => operations.ts} | 8 +-- src/services/news/actions.ts | 4 +- src/services/notifications/actions.ts | 18 +++---- .../channel/{methods.ts => operations.ts} | 4 +- src/services/notifications/email/dispatch.tsx | 2 +- .../email/systemMail/resetPassword.tsx | 4 +- .../{methods.ts => operations.ts} | 4 +- .../{methods.ts => operations.ts} | 6 +-- src/services/ombul/create.ts | 8 +-- src/services/omegaquotes/create.ts | 4 +- src/services/permissions/actions.ts | 12 ++--- .../permissions/{methods.ts => operations.ts} | 6 +-- src/services/shop/actions.ts | 24 ++++----- .../product/{methods.ts => operations.ts} | 2 +- .../purchase/{methods.ts => operations.ts} | 10 ++-- .../shop/shop/{methods.ts => operations.ts} | 2 +- src/services/users/actions.ts | 24 ++++----- .../users/{methods.ts => operations.ts} | 14 +++--- src/services/visibility/actions.ts | 4 +- tests/services/apiKeys.test.ts | 14 +++--- tests/services/jobads.test.ts | 32 ++++++------ 82 files changed, 342 insertions(+), 342 deletions(-) rename src/services/admission/{methods.ts => operations.ts} (95%) rename src/services/api-keys/{methods.ts => operations.ts} (99%) rename src/services/applications/{methods.ts => operations.ts} (99%) rename src/services/applications/periods/{methods.ts => operations.ts} (95%) rename src/services/auth/{methods.ts => operations.ts} (92%) rename src/services/cabin/booking/{methods.ts => operations.ts} (95%) rename src/services/cabin/pricePeriod/{methods.ts => operations.ts} (90%) rename src/services/cabin/product/{methods.ts => operations.ts} (88%) rename src/services/cabin/releasePeriod/{methods.ts => operations.ts} (98%) rename src/services/career/companies/{methods.ts => operations.ts} (98%) rename src/services/career/jobAds/{methods.ts => operations.ts} (99%) rename src/services/dots/{methods.ts => operations.ts} (99%) rename src/services/events/{methods.ts => operations.ts} (98%) rename src/services/events/registration/{methods.ts => operations.ts} (97%) rename src/services/events/tags/{methods.ts => operations.ts} (99%) rename src/services/groups/committees/{methods.ts => operations.ts} (94%) rename src/services/groups/interestGroups/{methods.ts => operations.ts} (98%) rename src/services/groups/{methods.ts => operations.ts} (98%) rename src/services/images/{methods.ts => operations.ts} (99%) rename src/services/licenses/{methods.ts => operations.ts} (98%) rename src/services/lockers/locations/{methods.ts => operations.ts} (96%) rename src/services/lockers/{methods.ts => operations.ts} (99%) rename src/services/lockers/reservations/{methods.ts => operations.ts} (94%) rename src/services/notifications/channel/{methods.ts => operations.ts} (98%) rename src/services/notifications/{methods.ts => operations.ts} (98%) rename src/services/notifications/subscription/{methods.ts => operations.ts} (96%) rename src/services/permissions/{methods.ts => operations.ts} (97%) rename src/services/shop/product/{methods.ts => operations.ts} (99%) rename src/services/shop/purchase/{methods.ts => operations.ts} (91%) rename src/services/shop/shop/{methods.ts => operations.ts} (98%) rename src/services/users/{methods.ts => operations.ts} (97%) diff --git a/src/app/api/shop/getAll/route.ts b/src/app/api/shop/getAll/route.ts index dda61a298..34fe2420b 100644 --- a/src/app/api/shop/getAll/route.ts +++ b/src/app/api/shop/getAll/route.ts @@ -1,6 +1,6 @@ import { apiHandler } from '@/app/api/apiHandler' -import { shopMethods } from '@/services/shop/shop/methods' +import { shopOperations } from '@/services/shop/shop/operations' export const GET = apiHandler({ - serviceMethod: shopMethods.readMany, + serviceMethod: shopOperations.readMany, }) diff --git a/src/app/api/shop/product/barcode/route.ts b/src/app/api/shop/product/barcode/route.ts index b8182243d..c09295c9b 100644 --- a/src/app/api/shop/product/barcode/route.ts +++ b/src/app/api/shop/product/barcode/route.ts @@ -1,6 +1,6 @@ import { apiHandler } from '@/app/api/apiHandler' -import { productMethods } from '@/services/shop/product/methods' +import { productOperations } from '@/services/shop/product/operations' export const POST = apiHandler({ - serviceMethod: productMethods.readByBarCode, + serviceMethod: productOperations.readByBarCode, }) diff --git a/src/app/api/shop/purchase/createByStudentCard/route.ts b/src/app/api/shop/purchase/createByStudentCard/route.ts index 0ec270027..f6de3e734 100644 --- a/src/app/api/shop/purchase/createByStudentCard/route.ts +++ b/src/app/api/shop/purchase/createByStudentCard/route.ts @@ -1,6 +1,6 @@ import { apiHandler } from '@/app/api/apiHandler' -import { purchaseMethods } from '@/services/shop/purchase/methods' +import { purchaseOperations } from '@/services/shop/purchase/operations' export const POST = apiHandler({ - serviceMethod: purchaseMethods.createByStudentCard, + serviceMethod: purchaseOperations.createByStudentCard, }) diff --git a/src/app/api/users/connectStudentCard/route.ts b/src/app/api/users/connectStudentCard/route.ts index 7d6fe9c0b..7b90bc918 100644 --- a/src/app/api/users/connectStudentCard/route.ts +++ b/src/app/api/users/connectStudentCard/route.ts @@ -1,7 +1,7 @@ import { apiHandler } from '@/api/apiHandler' -import { userMethods } from '@/services/users/methods' +import { userOperations } from '@/services/users/operations' export const POST = apiHandler({ - serviceMethod: userMethods.connectStudentCard + serviceMethod: userOperations.connectStudentCard }) diff --git a/src/app/api/users/get/[username]/route.ts b/src/app/api/users/get/[username]/route.ts index f275a4763..c8bc2faae 100644 --- a/src/app/api/users/get/[username]/route.ts +++ b/src/app/api/users/get/[username]/route.ts @@ -1,12 +1,12 @@ import { apiHandler } from '@/api/apiHandler' -import { userMethods } from '@/services/users/methods' +import { userOperations } from '@/services/users/operations' export const GET = apiHandler({ - serviceMethod: userMethods.readProfile, + serviceMethod: userOperations.readProfile, params: (rawparams: {username: string}) => ({ username: rawparams.username }) }) export const PATCH = apiHandler({ - serviceMethod: userMethods.update, + serviceMethod: userOperations.update, params: (rawparams: { username: string }) => ({ username: rawparams.username }) }) diff --git a/src/app/api/users/getWithBalance/[studentCard]/route.ts b/src/app/api/users/getWithBalance/[studentCard]/route.ts index 57e5a66cc..718ec5343 100644 --- a/src/app/api/users/getWithBalance/[studentCard]/route.ts +++ b/src/app/api/users/getWithBalance/[studentCard]/route.ts @@ -1,9 +1,9 @@ import { apiHandler } from '@/api/apiHandler' -import { userMethods } from '@/services/users/methods' +import { userOperations } from '@/services/users/operations' export const GET = apiHandler({ params: (rawparams: { studentCard: string }) => ({ studentCard: rawparams.studentCard, }), - serviceMethod: userMethods.readUserWithBalance, + serviceMethod: userOperations.readUserWithBalance, }) diff --git a/src/app/api/users/route.ts b/src/app/api/users/route.ts index 65b213005..768857257 100644 --- a/src/app/api/users/route.ts +++ b/src/app/api/users/route.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { apiHandler } from '@/api/apiHandler' -import { userMethods } from '@/services/users/methods' +import { userOperations } from '@/services/users/operations' export const POST = apiHandler({ - serviceMethod: userMethods.create + serviceMethod: userOperations.create }) diff --git a/src/app/lockers/[id]/page.tsx b/src/app/lockers/[id]/page.tsx index 18f8e24be..f4c48c1f9 100644 --- a/src/app/lockers/[id]/page.tsx +++ b/src/app/lockers/[id]/page.tsx @@ -5,7 +5,7 @@ import UpdateLockerReservationForm from './UpdateLockerReservationForm' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { readLockerAction } from '@/services/lockers/actions' import { getUser } from '@/auth/getUser' -import { checkGroupValidity, groupMethods, inferGroupName } from '@/services/groups/methods' +import { checkGroupValidity, groupOperations, inferGroupName } from '@/services/groups/operations' type PropTypes = { @@ -33,7 +33,7 @@ export default async function Locker({ params }: PropTypes) { const reservation = locker.data.LockerReservation[0] const groupName = (isReserved && reservation.group) ? inferGroupName(checkGroupValidity(reservation.group)) : '' - const groups = await groupMethods.readGroupsOfUser({ + const groups = await groupOperations.readGroupsOfUser({ bypassAuth: true, params: { userId: user.id, diff --git a/src/auth/Session.ts b/src/auth/Session.ts index acfe3aa58..a666e1a28 100644 --- a/src/auth/Session.ts +++ b/src/auth/Session.ts @@ -1,9 +1,9 @@ import { authOptions } from './authoptions' -import { apiKeyMethods } from '@/services/api-keys/methods' +import { apiKeyOperations } from '@/services/api-keys/operations' import { apiKeyDecryptAndCompare } from '@/services/api-keys/hashEncryptKey' import { decodeApiKey } from '@/services/api-keys/apiKeyEncoder' import { ServerError } from '@/services/error' -import { permissionMethods } from '@/services/permissions/methods' +import { permissionOperations } from '@/services/permissions/operations' import { getServerSession as getSessionNextAuth } from 'next-auth' import type { Permission } from '@prisma/client' import type { UserFiltered } from '@/services/users/Types' @@ -71,7 +71,7 @@ export class Session { public static async fromNextAuth(): Promise | Session<'HAS_USER'>> { const { user = null, - permissions = await permissionMethods.readDefaultPermissions({ + permissions = await permissionOperations.readDefaultPermissions({ bypassAuth: true, }), memberships = [], @@ -86,7 +86,7 @@ export class Session { * If the key is null, the session will be cratedwith only default permissios */ public static async fromApiKey(keyAndIdEncoded: string | null): Promise> { - const defaultPermissions = await permissionMethods.readDefaultPermissions({ + const defaultPermissions = await permissionOperations.readDefaultPermissions({ bypassAuth: true, }) if (!keyAndIdEncoded) return new Session<'NO_USER'>({ user: null, permissions: defaultPermissions, memberships: [] }) @@ -97,7 +97,7 @@ export class Session { let apiKeyFetch try { - apiKeyFetch = await apiKeyMethods.readWithHash({ + apiKeyFetch = await apiKeyOperations.readWithHash({ bypassAuth: true, params: { id } }) diff --git a/src/auth/VevenAdapter.ts b/src/auth/VevenAdapter.ts index 4621233a5..2203f28a4 100644 --- a/src/auth/VevenAdapter.ts +++ b/src/auth/VevenAdapter.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { readJWTPayload } from '@/jwt/jwtReadUnsecure' import { createFeideAccount } from '@/services/auth/feideAccounts/create' import { readUserOrNullOfFeideAccount } from '@/services/auth/feideAccounts/read' -import { userMethods } from '@/services/users/methods' +import { userOperations } from '@/services/users/operations' import { userFilterSelection } from '@/services/users/config' import type { UserFiltered } from '@/services/users/Types' import type { PrismaClient } from '@prisma/client' @@ -105,7 +105,7 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { async getUser(id) { console.log('get id') - const user = await userMethods.readOrNull({ + const user = await userOperations.readOrNull({ params: { id: Number(id) }, bypassAuth: true, }) @@ -116,7 +116,7 @@ export default function VevenAdapter(prisma: PrismaClient): Adapter { async getUserByEmail(email) { console.log('get email') console.log(email) - const user = await userMethods.readOrNull({ + const user = await userOperations.readOrNull({ params: { email }, bypassAuth: true, }) diff --git a/src/auth/authoptions.ts b/src/auth/authoptions.ts index eaf45e4a6..17cd9b560 100644 --- a/src/auth/authoptions.ts +++ b/src/auth/authoptions.ts @@ -6,8 +6,8 @@ import { updateUserStudyProgrammes } from '@/lib/feide/userRoutines' import { prisma } from '@/prisma/client' import { readMembershipsOfUser } from '@/services/groups/memberships/read' import { updateEmailForFeideAccount } from '@/services/auth/feideAccounts/update' -import { userMethods } from '@/services/users/methods' -import { permissionMethods } from '@/services/permissions/methods' +import { userOperations } from '@/services/users/operations' +import { permissionOperations } from '@/services/permissions/operations' import CredentialsProvider from 'next-auth/providers/credentials' import { decode } from 'next-auth/jwt' import type { AuthOptions } from 'next-auth' @@ -127,7 +127,7 @@ export const authOptions: AuthOptions = { } // Trigger is undefined for subsequent calls case undefined: { - const dbUser = await userMethods.read({ + const dbUser = await userOperations.read({ params: { id: token.user.id }, bypassAuth: true, }) @@ -164,11 +164,11 @@ export const authOptions: AuthOptions = { return { provider, - user: await userMethods.read({ + user: await userOperations.read({ params: { id: userId }, bypassAuth: true, }), - permissions: await permissionMethods.readPermissionsOfUser({ + permissions: await permissionOperations.readPermissionsOfUser({ bypassAuth: true, params: { userId, diff --git a/src/auth/getUser.ts b/src/auth/getUser.ts index e11af0c2a..3e728c66d 100644 --- a/src/auth/getUser.ts +++ b/src/auth/getUser.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { authOptions } from './authoptions' import checkMatrix from '@/utils/checkMatrix' -import { permissionMethods } from '@/services/permissions/methods' +import { permissionOperations } from '@/services/permissions/operations' import { getServerSession } from 'next-auth' import { notFound, redirect } from 'next/navigation' import type { Matrix } from '@/utils/checkMatrix' @@ -92,7 +92,7 @@ export async function getUser({ }: GetUserArgsType = {}): Promise> { const { user = null, - permissions = await permissionMethods.readDefaultPermissions({ + permissions = await permissionOperations.readDefaultPermissions({ bypassAuth: true, }), memberships = [], diff --git a/src/prisma/seeder/src/development/seedDevEvents.ts b/src/prisma/seeder/src/development/seedDevEvents.ts index 3d29e6230..17b1114bd 100644 --- a/src/prisma/seeder/src/development/seedDevEvents.ts +++ b/src/prisma/seeder/src/development/seedDevEvents.ts @@ -1,4 +1,4 @@ -import { eventMethods } from '@/services/events/methods' +import { eventOperations } from '@/services/events/operations' import type { PrismaClient } from '@prisma/client' export default async function seedDevEvents(prisma: PrismaClient) { @@ -17,7 +17,7 @@ export default async function seedDevEvents(prisma: PrismaClient) { } }) - const bedpres = await eventMethods.create({ + const bedpres = await eventOperations.create({ prisma, bypassAuth: true, data: { @@ -37,7 +37,7 @@ export default async function seedDevEvents(prisma: PrismaClient) { } }) - await eventMethods.create({ + await eventOperations.create({ prisma, bypassAuth: true, data: { diff --git a/src/prisma/seeder/src/development/seedDevJobAds.ts b/src/prisma/seeder/src/development/seedDevJobAds.ts index 4a279c6bf..50378ef0c 100644 --- a/src/prisma/seeder/src/development/seedDevJobAds.ts +++ b/src/prisma/seeder/src/development/seedDevJobAds.ts @@ -1,4 +1,4 @@ -import { jobAdMethods } from '@/services/career/jobAds/methods' +import { jobAdOperations } from '@/services/career/jobAds/operations' import type { JobType, PrismaClient } from '@prisma/client' @@ -51,7 +51,7 @@ export default async function seedDevJobAds(prisma: PrismaClient) { ] for (const jobAd of jobAdData) { - const restult = await jobAdMethods.create({ + const restult = await jobAdOperations.create({ prisma, data: { ...jobAd, diff --git a/src/services/admission/actions.ts b/src/services/admission/actions.ts index 1599061ed..5da8a9206 100644 --- a/src/services/admission/actions.ts +++ b/src/services/admission/actions.ts @@ -1,6 +1,6 @@ 'use server' import { action } from '@/services/action' -import { admissionMethods } from '@/services/admission/methods' +import { admissionOperations } from '@/services/admission/operations' -export const createAdmissionTrialAction = action(admissionMethods.createTrial) +export const createAdmissionTrialAction = action(admissionOperations.createTrial) diff --git a/src/services/admission/methods.ts b/src/services/admission/operations.ts similarity index 95% rename from src/services/admission/methods.ts rename to src/services/admission/operations.ts index dbd5d086b..70e08ea7e 100644 --- a/src/services/admission/methods.ts +++ b/src/services/admission/operations.ts @@ -8,7 +8,7 @@ import { Admission } from '@prisma/client' import { z } from 'zod' import type { ExpandedAdmissionTrail } from './Types' -export const admissionMethods = { +export const admissionOperations = { readTrial: defineOperation({ authorizer: () => admissionAuthers.readTrial.dynamicFields({}), paramsSchema: z.object({ @@ -49,7 +49,7 @@ export const admissionMethods = { }) // check if user has taken all admissions - const userTrials = await admissionMethods.readTrial({ + const userTrials = await admissionOperations.readTrial({ params: { userId: data.userId }, diff --git a/src/services/api-keys/actions.ts b/src/services/api-keys/actions.ts index dc3a2364d..2fbe460cc 100644 --- a/src/services/api-keys/actions.ts +++ b/src/services/api-keys/actions.ts @@ -1,13 +1,13 @@ 'use server' import { action } from '@/services/action' -import { apiKeyMethods } from '@/services/api-keys/methods' +import { apiKeyOperations } from '@/services/api-keys/operations' -export const createApiKeyAction = action(apiKeyMethods.create) +export const createApiKeyAction = action(apiKeyOperations.create) -export const destroyApiKeyAction = action(apiKeyMethods.destroy) +export const destroyApiKeyAction = action(apiKeyOperations.destroy) -export const readApiKeysAction = action(apiKeyMethods.readMany) -export const readApiKeyAction = action(apiKeyMethods.read) +export const readApiKeysAction = action(apiKeyOperations.readMany) +export const readApiKeyAction = action(apiKeyOperations.read) -export const updateApiKeyAction = action(apiKeyMethods.update) +export const updateApiKeyAction = action(apiKeyOperations.update) diff --git a/src/services/api-keys/methods.ts b/src/services/api-keys/operations.ts similarity index 99% rename from src/services/api-keys/methods.ts rename to src/services/api-keys/operations.ts index 1d61f61a1..15b4813a9 100644 --- a/src/services/api-keys/methods.ts +++ b/src/services/api-keys/operations.ts @@ -43,7 +43,7 @@ const updateIfExpired = defineOperation({ } }) -export const apiKeyMethods = { +export const apiKeyOperations = { create: defineOperation({ authorizer: () => apiKeyAuthers.create.dynamicFields({}), dataSchema: apiKeySchemas.create, diff --git a/src/services/applications/actions.ts b/src/services/applications/actions.ts index 29922f1db..8dd7e0d1d 100644 --- a/src/services/applications/actions.ts +++ b/src/services/applications/actions.ts @@ -1,12 +1,12 @@ 'use server' -import { applicationMethods } from './methods' +import { applicationOperations } from './operations' import { action } from '@/services/action' -export const createApplicationAction = action(applicationMethods.create) +export const createApplicationAction = action(applicationOperations.create) -export const destroyApplicationAction = action(applicationMethods.destroy) +export const destroyApplicationAction = action(applicationOperations.destroy) -export const readApplicationsForUserAction = action(applicationMethods.readForUser) +export const readApplicationsForUserAction = action(applicationOperations.readForUser) -export const updateApplicationAction = action(applicationMethods.update) +export const updateApplicationAction = action(applicationOperations.update) diff --git a/src/services/applications/methods.ts b/src/services/applications/operations.ts similarity index 99% rename from src/services/applications/methods.ts rename to src/services/applications/operations.ts index 1112c9a4c..a60b5a537 100644 --- a/src/services/applications/methods.ts +++ b/src/services/applications/operations.ts @@ -5,7 +5,7 @@ import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' -export const applicationMethods = { +export const applicationOperations = { readForUser: defineOperation({ paramsSchema: z.object({ userId: z.number(), diff --git a/src/services/applications/periods/actions.ts b/src/services/applications/periods/actions.ts index dec1af610..2710e64c1 100644 --- a/src/services/applications/periods/actions.ts +++ b/src/services/applications/periods/actions.ts @@ -1,15 +1,15 @@ 'use server' import { action } from '@/services/action' -import { applicationPeriodMethods } from '@/services/applications/periods/methods' +import { applicationPeriodOperations } from '@/services/applications/periods/operations' -export const createApplicationPeriodAction = action(applicationPeriodMethods.create) +export const createApplicationPeriodAction = action(applicationPeriodOperations.create) -export const destroyApplicationPeriodAction = action(applicationPeriodMethods.destroy) -export const removeAllApplicationTextsAction = action(applicationPeriodMethods.removeAllApplicationTexts) +export const destroyApplicationPeriodAction = action(applicationPeriodOperations.destroy) +export const removeAllApplicationTextsAction = action(applicationPeriodOperations.removeAllApplicationTexts) -export const readApplicationPeriodsAction = action(applicationPeriodMethods.readAll) -export const readApplicationPeriodAction = action(applicationPeriodMethods.read) -export const readNumberOfApplicationsAction = action(applicationPeriodMethods.readNumberOfApplications) +export const readApplicationPeriodsAction = action(applicationPeriodOperations.readAll) +export const readApplicationPeriodAction = action(applicationPeriodOperations.read) +export const readNumberOfApplicationsAction = action(applicationPeriodOperations.readNumberOfApplications) -export const updateApplicationPeriodAction = action(applicationPeriodMethods.update) +export const updateApplicationPeriodAction = action(applicationPeriodOperations.update) diff --git a/src/services/applications/periods/methods.ts b/src/services/applications/periods/operations.ts similarity index 95% rename from src/services/applications/periods/methods.ts rename to src/services/applications/periods/operations.ts index 19ae53092..bb0951a99 100644 --- a/src/services/applications/periods/methods.ts +++ b/src/services/applications/periods/operations.ts @@ -2,12 +2,12 @@ import '@pn-server-only' import { applicationPeriodAuthers } from './authers' import { applicationPeriodSchemas } from './schemas' import { committeesParticipatingincluder } from './config' -import { applicationMethods } from '@/services/applications/methods' +import { applicationOperations } from '@/services/applications/operations' import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' -export const applicationPeriodMethods = { +export const applicationPeriodOperations = { readAll: defineOperation({ authorizer: () => applicationPeriodAuthers.readAll.dynamicFields({}), operation: async ({ prisma }) => prisma.applicationPeriod.findMany() @@ -69,7 +69,7 @@ export const applicationPeriodMethods = { if (data.participatingCommitteeIds) { // Remove applications to committees that are no longer participating - // This must be done through the applicationMethods.destroy method to ensure + // This must be done through the applicationOperations.destroy method to ensure // that reordering priorities is handled correctly. await Promise.all( period.committeesParticipating @@ -90,7 +90,7 @@ export const applicationPeriodMethods = { }) await Promise.all( removeApplications.map(async application => - await applicationMethods.destroy({ + await applicationOperations.destroy({ params: { userId: application.userId, commiteeParticipationId: application.applicationPeriodCommiteeId @@ -128,7 +128,7 @@ export const applicationPeriodMethods = { }), authorizer: () => applicationPeriodAuthers.removeAllApplicationTexts.dynamicFields({}), operation: async ({ prisma, params, session }) => { - const period = await applicationPeriodMethods.read({ + const period = await applicationPeriodOperations.read({ params: { name: params.name }, session }) diff --git a/src/services/auth/actions.ts b/src/services/auth/actions.ts index 3f000c5da..5b489325d 100644 --- a/src/services/auth/actions.ts +++ b/src/services/auth/actions.ts @@ -1,9 +1,9 @@ 'use server' import { action } from '@/services/action' -import { authMethods } from '@/services/auth/methods' +import { authOperations } from '@/services/auth/operations' -export const verifyResetPasswordTokenAction = action(authMethods.verifyResetPasswordToken) -export const resetPasswordAction = action(authMethods.resetPassword) -export const sendResetPasswordEmailAction = action(authMethods.sendResetPasswordEmail) -export const verifyEmailAction = action(authMethods.verifyEmail) +export const verifyResetPasswordTokenAction = action(authOperations.verifyResetPasswordToken) +export const resetPasswordAction = action(authOperations.resetPassword) +export const sendResetPasswordEmailAction = action(authOperations.sendResetPasswordEmail) +export const verifyEmailAction = action(authOperations.verifyEmail) diff --git a/src/services/auth/methods.ts b/src/services/auth/operations.ts similarity index 92% rename from src/services/auth/methods.ts rename to src/services/auth/operations.ts index 62a24daa8..50da2c74e 100644 --- a/src/services/auth/methods.ts +++ b/src/services/auth/operations.ts @@ -5,11 +5,11 @@ import { userSchemas } from '@/services/users/schemas' import { sendResetPasswordMail } from '@/services/notifications/email/systemMail/resetPassword' import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' -import { userMethods } from '@/services/users/methods' +import { userOperations } from '@/services/users/operations' import { readJWTPayload } from '@/lib/jwt/jwtReadUnsecure' import { z } from 'zod' -export const authMethods = { +export const authOperations = { verifyEmail: defineOperation({ paramsSchema: z.object({ @@ -29,7 +29,7 @@ export const authMethods = { const iat = new Date(payload.iat * 1000) - const user = await userMethods.read({ + const user = await userOperations.read({ params: { id: userId, }, @@ -92,9 +92,9 @@ export const authMethods = { dataSchema: userSchemas.updatePassword, authorizer: ({ params }) => authAuthers.resetPassword.dynamicFields(params), operation: async ({ params, data }) => { - const userId = await authMethods.verifyResetPasswordToken({ params }) + const userId = await authOperations.verifyResetPasswordToken({ params }) - userMethods.updatePassword({ + userOperations.updatePassword({ params: { id: userId, }, @@ -110,7 +110,7 @@ export const authMethods = { operation: async ({ data }) => { console.log(data) try { - const user = await userMethods.read({ + const user = await userOperations.read({ params: { email: data.email, }, diff --git a/src/services/cabin/actions.ts b/src/services/cabin/actions.ts index 9e9829923..dd2896965 100644 --- a/src/services/cabin/actions.ts +++ b/src/services/cabin/actions.ts @@ -1,32 +1,32 @@ 'use server' -import { cabinReleasePeriodMethods } from './releasePeriod/methods' -import { cabinPricePeriodMethods } from './pricePeriod/methods' -import { cabinBookingMethods } from './booking/methods' -import { cabinProductMethods } from './product/methods' +import { cabinReleasePeriodOperations } from './releasePeriod/operations' +import { cabinPricePeriodOperations } from './pricePeriod/operations' +import { cabinBookingOperations } from './booking/operations' +import { cabinProductOperations } from './product/operations' import { action } from '@/services/action' -export const createReleasePeriodAction = action(cabinReleasePeriodMethods.create) -export const readReleasePeriodsAction = action(cabinReleasePeriodMethods.readMany) -export const updateReleasePeriodAction = action(cabinReleasePeriodMethods.update) -export const destroyReleasePeriodAction = action(cabinReleasePeriodMethods.destroy) +export const createReleasePeriodAction = action(cabinReleasePeriodOperations.create) +export const readReleasePeriodsAction = action(cabinReleasePeriodOperations.readMany) +export const updateReleasePeriodAction = action(cabinReleasePeriodOperations.update) +export const destroyReleasePeriodAction = action(cabinReleasePeriodOperations.destroy) -export const createPricePeriodAction = action(cabinPricePeriodMethods.create) -export const destoryPricePeriodAction = action(cabinPricePeriodMethods.destroy) -export const readPricePeriodsAction = action(cabinPricePeriodMethods.readMany) -export const readPublicPricePeriodsAction = action(cabinPricePeriodMethods.readPublicPeriods) -export const readUnreleasedPricePeriodsAction = action(cabinPricePeriodMethods.readUnreleasedPeriods) +export const createPricePeriodAction = action(cabinPricePeriodOperations.create) +export const destoryPricePeriodAction = action(cabinPricePeriodOperations.destroy) +export const readPricePeriodsAction = action(cabinPricePeriodOperations.readMany) +export const readPublicPricePeriodsAction = action(cabinPricePeriodOperations.readPublicPeriods) +export const readUnreleasedPricePeriodsAction = action(cabinPricePeriodOperations.readUnreleasedPeriods) -export const createCabinBookingUserAttachedAction = action(cabinBookingMethods.createCabinBookingUserAttached) -export const createBedBookingUserAttachedAction = action(cabinBookingMethods.createBedBookingUserAttached) -export const createCabinBookingNoUserAction = action(cabinBookingMethods.createCabinBookingNoUser) -export const createBedBookingNoUserAction = action(cabinBookingMethods.createBedBookingNoUser) -export const readCabinAvailabilityAction = action(cabinBookingMethods.readAvailability) -export const readCabinBookingsAction = action(cabinBookingMethods.readMany) -export const readCabinBookingAction = action(cabinBookingMethods.read) +export const createCabinBookingUserAttachedAction = action(cabinBookingOperations.createCabinBookingUserAttached) +export const createBedBookingUserAttachedAction = action(cabinBookingOperations.createBedBookingUserAttached) +export const createCabinBookingNoUserAction = action(cabinBookingOperations.createCabinBookingNoUser) +export const createBedBookingNoUserAction = action(cabinBookingOperations.createBedBookingNoUser) +export const readCabinAvailabilityAction = action(cabinBookingOperations.readAvailability) +export const readCabinBookingsAction = action(cabinBookingOperations.readMany) +export const readCabinBookingAction = action(cabinBookingOperations.read) -export const readCabinProductsAction = action(cabinProductMethods.readMany) -export const readCabinProductsActiveAction = action(cabinProductMethods.readActive) -export const readCabinProductAction = action(cabinProductMethods.read) -export const createCabinProductAction = action(cabinProductMethods.create) -export const createCabinProductPriceAction = action(cabinProductMethods.createPrice) +export const readCabinProductsAction = action(cabinProductOperations.readMany) +export const readCabinProductsActiveAction = action(cabinProductOperations.readActive) +export const readCabinProductAction = action(cabinProductOperations.read) +export const createCabinProductAction = action(cabinProductOperations.create) +export const createCabinProductPriceAction = action(cabinProductOperations.createPrice) diff --git a/src/services/cabin/booking/methods.ts b/src/services/cabin/booking/operations.ts similarity index 95% rename from src/services/cabin/booking/methods.ts rename to src/services/cabin/booking/operations.ts index ce86a8b8d..36a802122 100644 --- a/src/services/cabin/booking/methods.ts +++ b/src/services/cabin/booking/operations.ts @@ -3,14 +3,14 @@ import { calculateCabinBookingPrice, calculateTotalCabinBookingPrice } from './c import { cabinBookingSchemas } from './schemas' import { cabinBookingAuthers } from './authers' import { cabinBookingFilerSelection, cabinBookingIncluder } from './config' -import { cabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' +import { cabinPricePeriodOperations } from '@/services/cabin/pricePeriod/operations' import { cabinProductPriceIncluder } from '@/services/cabin/product/config' import { defineOperation } from '@/services/serviceOperation' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { ServerError } from '@/services/error' -import { cabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' +import { cabinReleasePeriodOperations } from '@/services/cabin/releasePeriod/operations' import { sendSystemMail } from '@/services/notifications/email/send' -import { notificationMethods } from '@/services/notifications/methods' +import { notificationOperations } from '@/services/notifications/operations' import { z } from 'zod' import { BookingType } from '@prisma/client' import type { CabinProductExtended } from '@/services/cabin/product/config' @@ -58,7 +58,7 @@ const create = defineOperation({ operation: async ({ prisma, params, data }) => { // TODO: Prevent Race conditions - const latestReleaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ + const latestReleaseDate = await cabinReleasePeriodOperations.getCurrentReleasePeriod({ bypassAuth: true, }) @@ -122,7 +122,7 @@ const create = defineOperation({ throw new ServerError('BAD PARAMETERS', 'Sengebookinger må inneholde minst ett produkt.') } - const pricePeriods = await cabinPricePeriodMethods.readMany({ bypassAuth: true }) + const pricePeriods = await cabinPricePeriodOperations.readMany({ bypassAuth: true }) const priceObjects = calculateCabinBookingPrice({ pricePeriods, @@ -184,7 +184,7 @@ const createBookingWithUser = defineOperation({ } }) - await notificationMethods.createSpecial({ + await notificationOperations.createSpecial({ params: { special: 'CABIN_BOOKING_CONFIRMATION', }, @@ -239,7 +239,7 @@ const createBookingNoUser = defineOperation({ } }) -export const cabinBookingMethods = { +export const cabinBookingOperations = { createCabinBookingUserAttached: defineOperation({ paramsSchema: z.object({ userId: z.number(), diff --git a/src/services/cabin/pricePeriod/methods.ts b/src/services/cabin/pricePeriod/operations.ts similarity index 90% rename from src/services/cabin/pricePeriod/methods.ts rename to src/services/cabin/pricePeriod/operations.ts index f75162e09..6770f30e8 100644 --- a/src/services/cabin/pricePeriod/methods.ts +++ b/src/services/cabin/pricePeriod/operations.ts @@ -2,16 +2,16 @@ import 'server-only' import { cabinPricePeriodAuthers } from './authers' import { cabinPricePeriodSchemas } from './schemas' import { defineOperation } from '@/services/serviceOperation' -import { cabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' +import { cabinReleasePeriodOperations } from '@/services/cabin/releasePeriod/operations' import { ServerError } from '@/services/error' import { z } from 'zod' -export const cabinPricePeriodMethods = { +export const cabinPricePeriodOperations = { create: defineOperation({ authorizer: () => cabinPricePeriodAuthers.create.dynamicFields({}), dataSchema: cabinPricePeriodSchemas.createPricePeriod, operation: async ({ prisma, data }) => { - const currentReleaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) + const currentReleaseDate = await cabinReleasePeriodOperations.getCurrentReleasePeriod({ bypassAuth: true }) if (currentReleaseDate && currentReleaseDate.releaseUntil >= data.validFrom) { throw new ServerError( @@ -64,7 +64,7 @@ export const cabinPricePeriodMethods = { id: z.number(), }), operation: async ({ prisma, params }) => { - const currentReleasePeriod = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) + const currentReleasePeriod = await cabinReleasePeriodOperations.getCurrentReleasePeriod({ bypassAuth: true }) const pricePeriod = await prisma.pricePeriod.findUniqueOrThrow({ where: params, @@ -88,7 +88,7 @@ export const cabinPricePeriodMethods = { readPublicPeriods: defineOperation({ authorizer: () => cabinPricePeriodAuthers.readPublicPeriods.dynamicFields({}), operation: async ({ prisma }) => { - const releaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) + const releaseDate = await cabinReleasePeriodOperations.getCurrentReleasePeriod({ bypassAuth: true }) const [currentPeriod, futurePeriods] = await Promise.all([ prisma.pricePeriod.findFirstOrThrow({ @@ -121,7 +121,7 @@ export const cabinPricePeriodMethods = { readUnreleasedPeriods: defineOperation({ authorizer: () => cabinPricePeriodAuthers.read.dynamicFields({}), operation: async ({ prisma }) => { - const releaseDate = await cabinReleasePeriodMethods.getCurrentReleasePeriod({ bypassAuth: true }) + const releaseDate = await cabinReleasePeriodOperations.getCurrentReleasePeriod({ bypassAuth: true }) return prisma.pricePeriod.findMany({ where: { validFrom: { diff --git a/src/services/cabin/product/methods.ts b/src/services/cabin/product/operations.ts similarity index 88% rename from src/services/cabin/product/methods.ts rename to src/services/cabin/product/operations.ts index 398432db1..2c5946d41 100644 --- a/src/services/cabin/product/methods.ts +++ b/src/services/cabin/product/operations.ts @@ -3,13 +3,13 @@ import 'server-only' import { cabinProductAuthers } from './authers' import { cabinProductSchemas } from './schemas' import { cabinProductPriceIncluder } from './config' -import { cabinReleasePeriodMethods } from '@/services/cabin/releasePeriod/methods' +import { cabinReleasePeriodOperations } from '@/services/cabin/releasePeriod/operations' import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' -import { cabinPricePeriodMethods } from '@/services/cabin/pricePeriod/methods' +import { cabinPricePeriodOperations } from '@/services/cabin/pricePeriod/operations' import { z } from 'zod' -export const cabinProductMethods = { +export const cabinProductOperations = { create: defineOperation({ authorizer: () => cabinProductAuthers.create.dynamicFields({}), @@ -32,7 +32,7 @@ export const cabinProductMethods = { id: data.pricePeriodId, } }), - cabinReleasePeriodMethods.getCurrentReleasePeriod({ + cabinReleasePeriodOperations.getCurrentReleasePeriod({ bypassAuth: true, session }) @@ -63,7 +63,7 @@ export const cabinProductMethods = { readActive: defineOperation({ authorizer: () => cabinProductAuthers.read.dynamicFields({}), operation: async ({ prisma }) => { - const pricePeriods = await cabinPricePeriodMethods.readPublicPeriods({ bypassAuth: true }) + const pricePeriods = await cabinPricePeriodOperations.readPublicPeriods({ bypassAuth: true }) return await prisma.cabinProduct.findMany({ where: { diff --git a/src/services/cabin/releasePeriod/methods.ts b/src/services/cabin/releasePeriod/operations.ts similarity index 98% rename from src/services/cabin/releasePeriod/methods.ts rename to src/services/cabin/releasePeriod/operations.ts index 343228e29..ba56fb01e 100644 --- a/src/services/cabin/releasePeriod/methods.ts +++ b/src/services/cabin/releasePeriod/operations.ts @@ -5,7 +5,7 @@ import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' import { z } from 'zod' -export const cabinReleasePeriodMethods = { +export const cabinReleasePeriodOperations = { create: defineOperation({ authorizer: () => cabinReleasePeriodAuthers.createReleasePeriodAuther.dynamicFields({}), diff --git a/src/services/career/companies/actions.ts b/src/services/career/companies/actions.ts index e06fb4b6b..a60517af2 100644 --- a/src/services/career/companies/actions.ts +++ b/src/services/career/companies/actions.ts @@ -1,12 +1,12 @@ 'use server' import { action } from '@/services/action' -import { companyMethods } from '@/services/career/companies/methods' +import { companyOperations } from '@/services/career/companies/operations' -export const createCompanyAction = action(companyMethods.create) +export const createCompanyAction = action(companyOperations.create) -export const destroyCompanyAction = action(companyMethods.destroy) +export const destroyCompanyAction = action(companyOperations.destroy) -export const readCompanyPageAction = action(companyMethods.readPage) +export const readCompanyPageAction = action(companyOperations.readPage) -export const updateComanyAction = action(companyMethods.update) +export const updateComanyAction = action(companyOperations.update) diff --git a/src/services/career/companies/methods.ts b/src/services/career/companies/operations.ts similarity index 98% rename from src/services/career/companies/methods.ts rename to src/services/career/companies/operations.ts index 43eb35ff5..5a550063c 100644 --- a/src/services/career/companies/methods.ts +++ b/src/services/career/companies/operations.ts @@ -9,7 +9,7 @@ import { readPageInputSchemaObject } from '@/lib/paging/schema' import { v4 as uuid } from 'uuid' import { z } from 'zod' -export const companyMethods = { +export const companyOperations = { create: defineOperation({ dataSchema: companySchemas.create, authorizer: () => companyAuthers.create.dynamicFields({}), diff --git a/src/services/career/jobAds/actions.ts b/src/services/career/jobAds/actions.ts index d623c28dc..336929616 100644 --- a/src/services/career/jobAds/actions.ts +++ b/src/services/career/jobAds/actions.ts @@ -1,14 +1,14 @@ 'use server' import { action } from '@/services/action' -import { jobAdMethods } from '@/services/career/jobAds/methods' +import { jobAdOperations } from '@/services/career/jobAds/operations' -export const createJobAdAction = action(jobAdMethods.create) +export const createJobAdAction = action(jobAdOperations.create) -export const destroyJobAdAction = action(jobAdMethods.destroy) +export const destroyJobAdAction = action(jobAdOperations.destroy) -export const readJobAdAction = action(jobAdMethods.read) -export const readActiveJobAdsAction = action(jobAdMethods.readActive) -export const readInactiveJobAdsPageAction = action(jobAdMethods.readInactivePage) +export const readJobAdAction = action(jobAdOperations.read) +export const readActiveJobAdsAction = action(jobAdOperations.readActive) +export const readInactiveJobAdsPageAction = action(jobAdOperations.readInactivePage) -export const updateJobAdAction = action(jobAdMethods.update) +export const updateJobAdAction = action(jobAdOperations.update) diff --git a/src/services/career/jobAds/methods.ts b/src/services/career/jobAds/operations.ts similarity index 99% rename from src/services/career/jobAds/methods.ts rename to src/services/career/jobAds/operations.ts index 3e0a6cfa8..d3ec09205 100644 --- a/src/services/career/jobAds/methods.ts +++ b/src/services/career/jobAds/operations.ts @@ -14,7 +14,7 @@ import { z } from 'zod' import { JobType } from '@prisma/client' import type { ExpandedJobAd, SimpleJobAd } from './Types' -export const jobAdMethods = { +export const jobAdOperations = { create: defineOperation({ dataSchema: jobAdSchemas.create, authorizer: () => jobAdAuthers.create.dynamicFields({}), diff --git a/src/services/dots/actions.ts b/src/services/dots/actions.ts index 1cc90e8bd..d046ce520 100644 --- a/src/services/dots/actions.ts +++ b/src/services/dots/actions.ts @@ -1,10 +1,10 @@ 'use server' import { action } from '@/services/action' -import { dotMethods } from '@/services/dots/methods' +import { dotOperations } from '@/services/dots/operations' -export const createDotAction = action(dotMethods.create) +export const createDotAction = action(dotOperations.create) -export const readDotPageAction = action(dotMethods.readPage) +export const readDotPageAction = action(dotOperations.readPage) -export const readDotWrappersForUserAction = action(dotMethods.readWrappersForUser) +export const readDotWrappersForUserAction = action(dotOperations.readWrappersForUser) diff --git a/src/services/dots/methods.ts b/src/services/dots/operations.ts similarity index 99% rename from src/services/dots/methods.ts rename to src/services/dots/operations.ts index b1ee6a7ce..7998847db 100644 --- a/src/services/dots/methods.ts +++ b/src/services/dots/operations.ts @@ -130,7 +130,7 @@ const readPage = defineOperation({ })) }) -export const dotMethods = { +export const dotOperations = { create, readForUser, readWrappersForUser, diff --git a/src/services/events/actions.ts b/src/services/events/actions.ts index a9b8e0de5..3b8c8d1f4 100644 --- a/src/services/events/actions.ts +++ b/src/services/events/actions.ts @@ -1,14 +1,14 @@ 'use server' import { action } from '@/services/action' -import { eventMethods } from '@/services/events/methods' +import { eventOperations } from '@/services/events/operations' -export const createEventAction = action(eventMethods.create) +export const createEventAction = action(eventOperations.create) -export const destroyEventAction = action(eventMethods.destroy) +export const destroyEventAction = action(eventOperations.destroy) -export const readCurrentEventsAction = action(eventMethods.readManyCurrent) -export const readEventAction = action(eventMethods.read) -export const readArchivedEventsPageAction = action(eventMethods.readManyArchivedPage) +export const readCurrentEventsAction = action(eventOperations.readManyCurrent) +export const readEventAction = action(eventOperations.read) +export const readArchivedEventsPageAction = action(eventOperations.readManyArchivedPage) -export const updateEventAction = action(eventMethods.update) +export const updateEventAction = action(eventOperations.update) diff --git a/src/services/events/methods.ts b/src/services/events/operations.ts similarity index 98% rename from src/services/events/methods.ts rename to src/services/events/operations.ts index 100054e51..c749a6c44 100644 --- a/src/services/events/methods.ts +++ b/src/services/events/operations.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { eventAuthers } from './authers' import { eventSchemas } from './schemas' import { eventFilterSelection } from './config' -import { notificationMethods } from '@/services/notifications/methods' +import { notificationOperations } from '@/services/notifications/operations' import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createCmsImage } from '@/services/cms/images/create' @@ -16,7 +16,7 @@ import { v4 as uuid } from 'uuid' import { z } from 'zod' import type { EventExpanded } from './Types' -export const eventMethods = { +export const eventOperations = { create: defineOperation({ dataSchema: eventSchemas.create, authorizer: () => eventAuthers.create.dynamicFields({}), @@ -79,7 +79,7 @@ export const eventMethods = { })) }) - await notificationMethods.createSpecial({ + await notificationOperations.createSpecial({ params: { special: 'NEW_EVENT', }, diff --git a/src/services/events/registration/actions.ts b/src/services/events/registration/actions.ts index 08218e299..d60f746f3 100644 --- a/src/services/events/registration/actions.ts +++ b/src/services/events/registration/actions.ts @@ -1,11 +1,11 @@ 'use server' import { action } from '@/services/action' -import { eventRegistrationMethods } from '@/services/events/registration/methods' +import { eventRegistrationOperations } from '@/services/events/registration/operations' -export const createEventRegistrationAction = action(eventRegistrationMethods.create) -export const createGuestEventRegistrationAction = action(eventRegistrationMethods.createGuest) -export const readManyEventRegistrationAction = action(eventRegistrationMethods.readMany) -export const eventRegistrationReadManyDetailedAction = action(eventRegistrationMethods.readManyDetailed) -export const eventRegistrationUpdateNotesAction = action(eventRegistrationMethods.updateNotes) -export const eventRegistrationDestroyAction = action(eventRegistrationMethods.destroy) +export const createEventRegistrationAction = action(eventRegistrationOperations.create) +export const createGuestEventRegistrationAction = action(eventRegistrationOperations.createGuest) +export const readManyEventRegistrationAction = action(eventRegistrationOperations.readMany) +export const eventRegistrationReadManyDetailedAction = action(eventRegistrationOperations.readManyDetailed) +export const eventRegistrationUpdateNotesAction = action(eventRegistrationOperations.updateNotes) +export const eventRegistrationDestroyAction = action(eventRegistrationOperations.destroy) diff --git a/src/services/events/registration/methods.ts b/src/services/events/registration/operations.ts similarity index 97% rename from src/services/events/registration/methods.ts rename to src/services/events/registration/operations.ts index 51edbb2d7..b769aef38 100644 --- a/src/services/events/registration/methods.ts +++ b/src/services/events/registration/operations.ts @@ -3,8 +3,8 @@ import { eventRegistrationIncluderDetailed, eventRegistrationSelection, REGISTRA import { eventRegistrationAuthers } from './authers' import { eventRegistrationSchemas } from './schemas' import { Smorekopp } from '@/services/error' -import { imageMethods } from '@/services/images/methods' -import { notificationMethods } from '@/services/notifications/methods' +import { imageOperations } from '@/services/images/operations' +import { notificationOperations } from '@/services/notifications/operations' import { sendSystemMail } from '@/services/notifications/email/send' import { userFilterSelection } from '@/services/users/config' import { defineOperation } from '@/services/serviceOperation' @@ -123,7 +123,7 @@ async function calculateTakeSkip(prisma: Prisma.TransactionClient, params: { } } -export const eventRegistrationMethods = { +export const eventRegistrationOperations = { create: defineOperation({ paramsSchema: z.object({ @@ -205,7 +205,7 @@ export const eventRegistrationMethods = { type: z.nativeEnum(REGISTRATION_READER_TYPE).optional(), }), operation: async ({ prisma, params }): Promise => { - const defaultImage = await imageMethods.readSpecial({ + const defaultImage = await imageOperations.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, }) @@ -372,7 +372,7 @@ export const eventRegistrationMethods = { const message = `Gratulerer! Du har rykket opp fra venteliste på arrangementet ${registration.event.name}.` if (nextInLine.user) { - await notificationMethods.createSpecial({ + await notificationOperations.createSpecial({ params: { special: 'EVENT_WAITINGLIST_PROMOTION', }, diff --git a/src/services/events/tags/actions.ts b/src/services/events/tags/actions.ts index 740d7d285..48427a93c 100644 --- a/src/services/events/tags/actions.ts +++ b/src/services/events/tags/actions.ts @@ -1,14 +1,14 @@ 'use server' import { action } from '@/services/action' -import { eventTagMethods } from '@/services/events/tags/methods' +import { eventTagOperations } from '@/services/events/tags/operations' -export const createEventTagAction = action(eventTagMethods.create) +export const createEventTagAction = action(eventTagOperations.create) -export const destroyEventTagAction = action(eventTagMethods.destroy) +export const destroyEventTagAction = action(eventTagOperations.destroy) -export const readEventTagsAction = action(eventTagMethods.readAll) -export const readSpecialEventTagAction = action(eventTagMethods.readSpecial) -export const readEventTagAction = action(eventTagMethods.read) +export const readEventTagsAction = action(eventTagOperations.readAll) +export const readSpecialEventTagAction = action(eventTagOperations.readSpecial) +export const readEventTagAction = action(eventTagOperations.read) -export const updateEventTagAction = action(eventTagMethods.update) +export const updateEventTagAction = action(eventTagOperations.update) diff --git a/src/services/events/tags/methods.ts b/src/services/events/tags/operations.ts similarity index 99% rename from src/services/events/tags/methods.ts rename to src/services/events/tags/operations.ts index d71f95244..80983da1e 100644 --- a/src/services/events/tags/methods.ts +++ b/src/services/events/tags/operations.ts @@ -9,7 +9,7 @@ import { ServerError } from '@/services/error' import { SpecialEventTags } from '@prisma/client' import { z } from 'zod' -export const eventTagMethods = { +export const eventTagOperations = { read: defineOperation({ paramsSchema: z.object({ id: z.number(), diff --git a/src/services/groups/actions.ts b/src/services/groups/actions.ts index d226b5771..9bb271916 100644 --- a/src/services/groups/actions.ts +++ b/src/services/groups/actions.ts @@ -1,9 +1,9 @@ 'use server' import { action } from '@/services/action' -import { groupMethods } from '@/services/groups/methods' +import { groupOperations } from '@/services/groups/operations' -export const readGroupsAction = action(groupMethods.readGroups) -export const readGroupExpandedAction = action(groupMethods.readGroupExpanded) -export const readGroupsExpandedAction = action(groupMethods.readGroupsExpanded) -export const readGroupsStructuredAction = action(groupMethods.readGroupsStructured) +export const readGroupsAction = action(groupOperations.readGroups) +export const readGroupExpandedAction = action(groupOperations.readGroupExpanded) +export const readGroupsExpandedAction = action(groupOperations.readGroupsExpanded) +export const readGroupsStructuredAction = action(groupOperations.readGroupsStructured) diff --git a/src/services/groups/committees/actions.ts b/src/services/groups/committees/actions.ts index 0ac4436b6..9c74d0cbf 100644 --- a/src/services/groups/committees/actions.ts +++ b/src/services/groups/committees/actions.ts @@ -4,7 +4,7 @@ import { action } from '@/services/action' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createCommittee } from '@/services/groups/committees/create' -import { committeeMethods } from '@/services/groups/committees/methods' +import { committeeOperations } from '@/services/groups/committees/operations' import { updateCommittee } from '@/services/groups/committees/update' import { createCommitteeValidation, updateCommitteeValidation } from '@/services/groups/committees/validation' import type { ExpandedCommittee } from '@/services/groups/committees/Types' @@ -27,11 +27,11 @@ export async function createCommitteeAction( return await safeServerCall(() => createCommittee(parse.data)) } -export const readCommitteesAction = action(committeeMethods.readCommittees) -export const readCommitteeAction = action(committeeMethods.readCommittee) -export const readCommitteeArticleAction = action(committeeMethods.readCommitteArticle) -export const readCommitteeParagraphAction = action(committeeMethods.readCommitteeParagraph) -export const readCommitteeMembersAction = action(committeeMethods.readCommitteeMembers) +export const readCommitteesAction = action(committeeOperations.readCommittees) +export const readCommitteeAction = action(committeeOperations.readCommittee) +export const readCommitteeArticleAction = action(committeeOperations.readCommitteArticle) +export const readCommitteeParagraphAction = action(committeeOperations.readCommitteeParagraph) +export const readCommitteeMembersAction = action(committeeOperations.readCommitteeMembers) export async function updateCommitteeAction( id: number, diff --git a/src/services/groups/committees/create.ts b/src/services/groups/committees/create.ts index 7197151a3..db53d51af 100644 --- a/src/services/groups/committees/create.ts +++ b/src/services/groups/committees/create.ts @@ -4,7 +4,7 @@ import { prismaCall } from '@/services/prismaCall' import { createArticle } from '@/services/cms/articles/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createCmsParagraph } from '@/services/cms/paragraphs/create' -import { imageMethods } from '@/services/images/methods' +import { imageOperations } from '@/services/images/operations' import { GroupType } from '@prisma/client' import type { ExpandedCommittee } from './Types' import type { CreateCommitteeTypes } from './validation' @@ -13,7 +13,7 @@ export async function createCommittee(rawdata: CreateCommitteeTypes['Detailed']) const { name, shortName, logoImageId } = createCommitteeValidation.detailedValidate(rawdata) let defaultLogoImageId: number if (!logoImageId) { - defaultLogoImageId = await imageMethods.readSpecial({ + defaultLogoImageId = await imageOperations.readSpecial({ params: { special: 'DAFAULT_COMMITTEE_LOGO' }, //TODO: pass session }).then(res => res.id) } diff --git a/src/services/groups/committees/methods.ts b/src/services/groups/committees/operations.ts similarity index 94% rename from src/services/groups/committees/methods.ts rename to src/services/groups/committees/operations.ts index f862517d8..755a2713d 100644 --- a/src/services/groups/committees/methods.ts +++ b/src/services/groups/committees/operations.ts @@ -2,11 +2,11 @@ import { committeeAuthers } from './authers' import { committeeExpandedIncluder, committeeLogoIncluder, membershipIncluder } from './config' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { articleRealtionsIncluder } from '@/cms/articles/ConfigVars' -import { imageMethods } from '@/services/images/methods' +import { imageOperations } from '@/services/images/operations' import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' -export const committeeMethods = { +export const committeeOperations = { readCommittees: defineOperation({ authorizer: () => committeeAuthers.read.dynamicFields({}), @@ -22,7 +22,7 @@ export const committeeMethods = { z.object({ shortName: z.string() }) ]), operation: async ({ prisma, params }) => { - const defaultImage = await imageMethods.readSpecial({ + const defaultImage = await imageOperations.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, bypassAuth: true }) @@ -99,7 +99,7 @@ export const committeeMethods = { active: z.boolean().optional(), }), operation: async ({ prisma, params }) => { - const defaultImage = await imageMethods.readSpecial({ + const defaultImage = await imageOperations.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, }) diff --git a/src/services/groups/committees/read.ts b/src/services/groups/committees/read.ts index df6c7b356..7275d472b 100644 --- a/src/services/groups/committees/read.ts +++ b/src/services/groups/committees/read.ts @@ -2,7 +2,7 @@ import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { articleRealtionsIncluder } from '@/services/cms/articles/ConfigVars' -import { imageMethods } from '@/services/images/methods' +import { imageOperations } from '@/services/images/operations' import { userFilterSelection } from '@/services/users/config' import type { ExpandedArticle } from '@/services/cms/articles/Types' import type { CmsParagraph } from '@prisma/client' @@ -90,7 +90,7 @@ export async function readCommitteeParagraph(shortName: string) : Promise res.id) } diff --git a/src/services/groups/interestGroups/actions.ts b/src/services/groups/interestGroups/actions.ts index cbb1177de..b1fd43586 100644 --- a/src/services/groups/interestGroups/actions.ts +++ b/src/services/groups/interestGroups/actions.ts @@ -1,12 +1,12 @@ 'use server' import { action } from '@/services/action' -import { interestGroupMethods } from '@/services/groups/interestGroups/methods' +import { interestGroupOperations } from '@/services/groups/interestGroups/operations' -export const createInterestGroupAction = action(interestGroupMethods.create) +export const createInterestGroupAction = action(interestGroupOperations.create) -export const destroyInterestGroupAction = action(interestGroupMethods.destroy) +export const destroyInterestGroupAction = action(interestGroupOperations.destroy) -export const readInterestGroupsAction = action(interestGroupMethods.readMany) +export const readInterestGroupsAction = action(interestGroupOperations.readMany) -export const updateInterestGroupAction = action(interestGroupMethods.update) +export const updateInterestGroupAction = action(interestGroupOperations.update) diff --git a/src/services/groups/interestGroups/methods.ts b/src/services/groups/interestGroups/operations.ts similarity index 98% rename from src/services/groups/interestGroups/methods.ts rename to src/services/groups/interestGroups/operations.ts index 358282755..f651a9498 100644 --- a/src/services/groups/interestGroups/methods.ts +++ b/src/services/groups/interestGroups/operations.ts @@ -7,7 +7,7 @@ import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' import type { ExpandedInterestGroup } from './Types' -export const interestGroupMethods = { +export const interestGroupOperations = { create: defineOperation({ dataSchema: interestGroupSchemas.create, authorizer: () => interestGroupAuthers.create.dynamicFields({}), diff --git a/src/services/groups/memberships/create.ts b/src/services/groups/memberships/create.ts index bcbf47009..af708e25c 100644 --- a/src/services/groups/memberships/create.ts +++ b/src/services/groups/memberships/create.ts @@ -5,7 +5,7 @@ import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { prisma } from '@/prisma/client' import { invalidateManyUserSessionData, invalidateOneUserSessionData } from '@/services/auth/invalidateSession' -import { groupMethods } from '@/services/groups/methods' +import { groupOperations } from '@/services/groups/operations' import type { ExpandedMembership } from './Types' export async function createMembershipForUser( @@ -18,7 +18,7 @@ export async function createMembershipForUser( throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await groupMethods.readCurrentGroupOrder({ + const order = orderArg ?? await groupOperations.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId, @@ -64,7 +64,7 @@ export async function createMembershipsForGroup( if (!await canEasilyManageMembershipOfGroup(groupId)) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await groupMethods.readCurrentGroupOrder({ + const order = orderArg ?? await groupOperations.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId, @@ -111,7 +111,7 @@ export async function createMembershipsForUser( if (!await canEasilyManageMembershipOfGroups(data.map(group => group.groupId))) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const ordersMap = await groupMethods.readCurrentGroupOrders({ + const ordersMap = await groupOperations.readCurrentGroupOrders({ bypassAuth: true, params: { ids: data.map(group => group.groupId) diff --git a/src/services/groups/memberships/destroy.ts b/src/services/groups/memberships/destroy.ts index 99545a2c4..2863fe01a 100644 --- a/src/services/groups/memberships/destroy.ts +++ b/src/services/groups/memberships/destroy.ts @@ -4,7 +4,7 @@ import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { prisma } from '@/prisma/client' import { invalidateManyUserSessionData, invalidateOneUserSessionData } from '@/services/auth/invalidateSession' -import { groupMethods } from '@/services/groups/methods' +import { groupOperations } from '@/services/groups/operations' import type { ExpandedMembership } from './Types' export async function destoryMembershipOfUser({ @@ -19,7 +19,7 @@ export async function destoryMembershipOfUser({ if (!await canEasilyManageMembershipOfGroup(groupId)) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await groupMethods.readCurrentGroupOrder({ + const order = orderArg ?? await groupOperations.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId @@ -47,7 +47,7 @@ export async function destroyMembershipOfUsers( if (!await canEasilyManageMembershipOfGroup(groupId)) { throw new ServerError('BAD PARAMETERS', 'Denne Gruppetypen kan ikke enkelt opprette medlemskap') } - const order = orderArg ?? await groupMethods.readCurrentGroupOrder({ + const order = orderArg ?? await groupOperations.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId, diff --git a/src/services/groups/memberships/update.ts b/src/services/groups/memberships/update.ts index 943d117a4..7ea06df2b 100644 --- a/src/services/groups/memberships/update.ts +++ b/src/services/groups/memberships/update.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { prismaCall } from '@/services/prismaCall' import { prisma } from '@/prisma/client' import { invalidateOneUserSessionData } from '@/services/auth/invalidateSession' -import { groupMethods } from '@/services/groups/methods' +import { groupOperations } from '@/services/groups/operations' import type { ExpandedMembership } from './Types' export async function updateMembership({ @@ -18,7 +18,7 @@ export async function updateMembership({ active?: boolean }): Promise { const order = (orderArg && typeof orderArg === 'number') ? orderArg : ( - await groupMethods.readCurrentGroupOrder({ + await groupOperations.readCurrentGroupOrder({ bypassAuth: true, params: { id: groupId diff --git a/src/services/groups/methods.ts b/src/services/groups/operations.ts similarity index 98% rename from src/services/groups/methods.ts rename to src/services/groups/operations.ts index ccc187972..0036e2d29 100644 --- a/src/services/groups/methods.ts +++ b/src/services/groups/operations.ts @@ -187,7 +187,7 @@ export function checkGroupValidity< } } -export const groupMethods = { +export const groupOperations = { readGroups: defineOperation({ authorizer: () => groupAuthers.read.dynamicFields({}), operation: async ({ prisma }) => prisma.group.findMany() @@ -295,7 +295,7 @@ export const groupMethods = { }, } satisfies GroupsStructured - const groupExpanded = await groupMethods.readGroupsExpanded({ bypassAuth: true }) + const groupExpanded = await groupOperations.readGroupsExpanded({ bypassAuth: true }) groupExpanded.forEach(group => { groupsStructured[group.groupType].groups.push(group) diff --git a/src/services/images/actions.ts b/src/services/images/actions.ts index 972d10fb2..ae70a6fc7 100644 --- a/src/services/images/actions.ts +++ b/src/services/images/actions.ts @@ -1,24 +1,24 @@ 'use server' import { action } from '@/services/action' -import { imageMethods } from '@/services/images/methods' +import { imageOperations } from '@/services/images/operations' -export const createImageAction = action(imageMethods.create) -export const createImagesAction = action(imageMethods.createMany) +export const createImageAction = action(imageOperations.create) +export const createImagesAction = action(imageOperations.createMany) -export const destroyImageAction = action(imageMethods.destroy) +export const destroyImageAction = action(imageOperations.destroy) /** * Read one image. */ -export const readImageAction = action(imageMethods.read) +export const readImageAction = action(imageOperations.read) /** * Read one page of images. */ -export const readImagesPageAction = action(imageMethods.readPage) +export const readImagesPageAction = action(imageOperations.readPage) /** * Read one special image. */ -export const readSpecialImageAction = action(imageMethods.readSpecial) +export const readSpecialImageAction = action(imageOperations.readSpecial) -export const updateImageAction = action(imageMethods.update) +export const updateImageAction = action(imageOperations.update) diff --git a/src/services/images/collections/read.ts b/src/services/images/collections/read.ts index 5fe5ab2c7..746c18a8d 100644 --- a/src/services/images/collections/read.ts +++ b/src/services/images/collections/read.ts @@ -6,7 +6,7 @@ import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { readSpecialVisibility } from '@/services/visibility/read' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' -import { imageMethods } from '@/services/images/methods' +import { imageOperations } from '@/services/images/operations' import type { SpecialCollection, ImageCollection, Image } from '@prisma/client' import type { ExpandedImageCollection, @@ -68,7 +68,7 @@ export async function readImageCollectionsPage( ...cursorPageingSelection(page) })) - const lensCamera = await imageMethods.readSpecial({ + const lensCamera = await imageOperations.readSpecial({ params: { special: 'DEFAULT_IMAGE_COLLECTION_COVER' }, diff --git a/src/services/images/methods.ts b/src/services/images/operations.ts similarity index 99% rename from src/services/images/methods.ts rename to src/services/images/operations.ts index 415e363e3..ff6067ca0 100644 --- a/src/services/images/methods.ts +++ b/src/services/images/operations.ts @@ -68,7 +68,7 @@ const createSourceless = defineOperation({ } }) -export const imageMethods = { +export const imageOperations = { /** * Creates an image. * The method will resize the image to the correct sizes and save it to the store. @@ -140,7 +140,7 @@ export const imageMethods = { for (const file of data.files) { console.log('file', file) const name = useFileName ? file.name.split('.')[0] : undefined - await imageMethods.create({ + await imageOperations.create({ params: { collectionId }, data: { file, name, alt: file.name.split('.')[0], licenseId: data.licenseId, credit: data.credit }, }) diff --git a/src/services/licenses/actions.ts b/src/services/licenses/actions.ts index 6e607c63f..7723bd2eb 100644 --- a/src/services/licenses/actions.ts +++ b/src/services/licenses/actions.ts @@ -1,12 +1,12 @@ 'use server' import { action } from '@/services/action' -import { licenseMethods } from '@/services/licenses/methods' +import { licenseOperations } from '@/services/licenses/operations' -export const createLicenseAction = action(licenseMethods.create) +export const createLicenseAction = action(licenseOperations.create) -export const destroyLicenseAction = action(licenseMethods.destroy) +export const destroyLicenseAction = action(licenseOperations.destroy) -export const readAllLicensesAction = action(licenseMethods.readAll) +export const readAllLicensesAction = action(licenseOperations.readAll) -export const updateLicenseAction = action(licenseMethods.update) +export const updateLicenseAction = action(licenseOperations.update) diff --git a/src/services/licenses/methods.ts b/src/services/licenses/operations.ts similarity index 98% rename from src/services/licenses/methods.ts rename to src/services/licenses/operations.ts index 419c8ae12..b13de25ee 100644 --- a/src/services/licenses/methods.ts +++ b/src/services/licenses/operations.ts @@ -5,7 +5,7 @@ import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' -export const licenseMethods = { +export const licenseOperations = { create: defineOperation({ authorizer: () => licenseAuthers.create.dynamicFields({}), dataSchema: licenseSchemas.create, diff --git a/src/services/lockers/actions.ts b/src/services/lockers/actions.ts index 430622d56..54c7d081b 100644 --- a/src/services/lockers/actions.ts +++ b/src/services/lockers/actions.ts @@ -1,16 +1,16 @@ 'use server' import { action } from '@/services/action' -import { lockerLocationMethods } from '@/services/lockers/locations/methods' -import { lockerMethods } from '@/services/lockers/methods' -import { lockerReservationMethods } from '@/services/lockers/reservations/methods' +import { lockerLocationOperations } from '@/services/lockers/locations/operations' +import { lockerOperations } from '@/services/lockers/operations' +import { lockerReservationOperations } from '@/services/lockers/reservations/operations' -export const createLockerLocationAction = action(lockerLocationMethods.create) -export const readAllLockerLocationsAction = action(lockerLocationMethods.readAll) +export const createLockerLocationAction = action(lockerLocationOperations.create) +export const readAllLockerLocationsAction = action(lockerLocationOperations.readAll) -export const createLockerAction = action(lockerMethods.create) -export const readLockerAction = action(lockerMethods.read) -export const readLockerPageAction = action(lockerMethods.readPage) +export const createLockerAction = action(lockerOperations.create) +export const readLockerAction = action(lockerOperations.read) +export const readLockerPageAction = action(lockerOperations.readPage) -export const updateLockerReservationAction = action(lockerReservationMethods.update) -export const createLockerReservationAction = action(lockerReservationMethods.create) +export const updateLockerReservationAction = action(lockerReservationOperations.update) +export const createLockerReservationAction = action(lockerReservationOperations.create) diff --git a/src/services/lockers/locations/methods.ts b/src/services/lockers/locations/operations.ts similarity index 96% rename from src/services/lockers/locations/methods.ts rename to src/services/lockers/locations/operations.ts index 7d4bd9246..d438e1732 100644 --- a/src/services/lockers/locations/methods.ts +++ b/src/services/lockers/locations/operations.ts @@ -2,7 +2,7 @@ import { lockerLocationAuthers } from './authers' import { lockersSchemas } from '@/services/lockers/schemas' import { defineOperation } from '@/services/serviceOperation' -export const lockerLocationMethods = { +export const lockerLocationOperations = { /** * Creates a new locker location. * diff --git a/src/services/lockers/methods.ts b/src/services/lockers/operations.ts similarity index 99% rename from src/services/lockers/methods.ts rename to src/services/lockers/operations.ts index 217579dbc..dd6a9628e 100644 --- a/src/services/lockers/methods.ts +++ b/src/services/lockers/operations.ts @@ -32,7 +32,7 @@ export async function updateLockerReservationIfExpired(prisma: Prisma.Transactio locker.LockerReservation = [] } } -export const lockerMethods = { +export const lockerOperations = { /** * Creates a new locker. * diff --git a/src/services/lockers/reservations/methods.ts b/src/services/lockers/reservations/operations.ts similarity index 94% rename from src/services/lockers/reservations/methods.ts rename to src/services/lockers/reservations/operations.ts index a0a8fabc9..e1ccdb467 100644 --- a/src/services/lockers/reservations/methods.ts +++ b/src/services/lockers/reservations/operations.ts @@ -4,10 +4,10 @@ import { lockerReservationAuthers } from './authers' import { lockerReservationSchemas } from './schemas' import { defineOperation } from '@/services/serviceOperation' import { Smorekopp } from '@/services/error' -import { groupMethods } from '@/services/groups/methods' +import { groupOperations } from '@/services/groups/operations' import { z } from 'zod' -export const lockerReservationMethods = { +export const lockerReservationOperations = { /** * Creates a new locker reservation for a given user and locker. * @@ -26,7 +26,7 @@ export const lockerReservationMethods = { // TODO: Use authers for authing in stead of this // Verify that user is in group if (data.groupId) { - const groupUsers = await groupMethods.readUsersOfGroups({ + const groupUsers = await groupOperations.readUsersOfGroups({ bypassAuth: true, params: { groups: [{ groupId: data.groupId, admin: false }] @@ -107,7 +107,7 @@ export const lockerReservationMethods = { // Verify that user is in group if (data.groupId) { - const groupUsers = await groupMethods.readUsersOfGroups({ + const groupUsers = await groupOperations.readUsersOfGroups({ bypassAuth: true, params: { groups: [{ groupId: data.groupId, admin: false }] diff --git a/src/services/news/actions.ts b/src/services/news/actions.ts index 3e4917dbe..71491b255 100644 --- a/src/services/news/actions.ts +++ b/src/services/news/actions.ts @@ -6,7 +6,7 @@ import { destroyNews } from '@/services/news/destroy' import { readNews, readNewsCurrent, readOldNewsPage } from '@/services/news/read' import { updateNews } from '@/services/news/update' import { createNewsArticleValidation, updateNewsArticleValidation } from '@/services/news/validation' -import { notificationMethods } from '@/services/notifications/methods' +import { notificationOperations } from '@/services/notifications/operations' import type { CreateNewsArticleTypes, UpdateNewsArticleTypes } from '@/services/news/validation' import type { ExpandedNewsArticle, NewsCursor, SimpleNewsArticle } from '@/services/news/Types' import type { ReadPageInput } from '@/lib/paging/Types' @@ -67,7 +67,7 @@ export async function publishNewsAction( // eslint-disable-next-line @typescript-eslint/no-unused-vars shouldPublish: boolean ): Promise>> { - notificationMethods.createSpecial({ + notificationOperations.createSpecial({ params: { special: 'NEW_NEWS_ARTICLE', }, diff --git a/src/services/notifications/actions.ts b/src/services/notifications/actions.ts index a1ab9c884..be9111567 100644 --- a/src/services/notifications/actions.ts +++ b/src/services/notifications/actions.ts @@ -1,15 +1,15 @@ 'use server' import { action } from '@/services/action' -import { notificationChannelMethods } from '@/services/notifications/channel/methods' -import { notificationMethods } from '@/services/notifications/methods' -import { notificationSubscriptionMethods } from '@/services/notifications/subscription/methods' +import { notificationChannelOperations } from '@/services/notifications/channel/operations' +import { notificationOperations } from '@/services/notifications/operations' +import { notificationSubscriptionOperations } from '@/services/notifications/subscription/operations' -export const createNotificationChannelAction = action(notificationChannelMethods.create) -export const updateNotificationChannelAction = action(notificationChannelMethods.update) -export const readNotificationChannelsAction = action(notificationChannelMethods.readMany) +export const createNotificationChannelAction = action(notificationChannelOperations.create) +export const updateNotificationChannelAction = action(notificationChannelOperations.update) +export const readNotificationChannelsAction = action(notificationChannelOperations.readMany) -export const createNotificationAction = action(notificationMethods.create) +export const createNotificationAction = action(notificationOperations.create) -export const readNotificationSubscriptionsAction = action(notificationSubscriptionMethods.read) -export const updateNotificationSubscriptionsAction = action(notificationSubscriptionMethods.update) +export const readNotificationSubscriptionsAction = action(notificationSubscriptionOperations.read) +export const updateNotificationSubscriptionsAction = action(notificationSubscriptionOperations.update) diff --git a/src/services/notifications/channel/methods.ts b/src/services/notifications/channel/operations.ts similarity index 98% rename from src/services/notifications/channel/methods.ts rename to src/services/notifications/channel/operations.ts index 324af1d91..c11ae7917 100644 --- a/src/services/notifications/channel/methods.ts +++ b/src/services/notifications/channel/operations.ts @@ -15,7 +15,7 @@ import { ServerError } from '@/services/error' import { z } from 'zod' import type { ExpandedNotificationChannel, NotificationMethodGeneral } from '@/services/notifications/Types' -export const notificationChannelMethods = { +export const notificationChannelOperations = { create: defineOperation({ authorizer: () => notificationChannelAuthers.create.dynamicFields({}), dataSchema: notificationChannelSchemas.create, @@ -156,7 +156,7 @@ export const notificationChannelMethods = { // Not allowed to change the parent of ROOT if (channel.special !== 'ROOT') { - const allChannels = await notificationChannelMethods.readMany({ + const allChannels = await notificationChannelOperations.readMany({ bypassAuth: true, }) diff --git a/src/services/notifications/email/dispatch.tsx b/src/services/notifications/email/dispatch.tsx index 5fb50555c..f0bf3d2af 100644 --- a/src/services/notifications/email/dispatch.tsx +++ b/src/services/notifications/email/dispatch.tsx @@ -2,7 +2,7 @@ import { sendBulkMail } from './send' import { DEFAULT_NOTIFICATION_ALIAS } from './config' import { sendEmailValidation } from './validation' import { DefaultEmailTemplate } from './templates/default' -import { repalceSpecialSymbols } from '@/services/notifications/methods' +import { repalceSpecialSymbols } from '@/services/notifications/operations' import { prismaCall } from '@/services/prismaCall' import { prisma } from '@/prisma/client' import { render } from '@react-email/render' diff --git a/src/services/notifications/email/systemMail/resetPassword.tsx b/src/services/notifications/email/systemMail/resetPassword.tsx index acf1ed47e..b61192be1 100644 --- a/src/services/notifications/email/systemMail/resetPassword.tsx +++ b/src/services/notifications/email/systemMail/resetPassword.tsx @@ -2,7 +2,7 @@ import '@pn-server-only' import { sendSystemMail } from '@/services/notifications/email/send' import { ResetPasswordTemplate } from '@/services/notifications/email/templates/resetPassword' import { generateJWT } from '@/jwt/jwt' -import { userMethods } from '@/services/users/methods' +import { userOperations } from '@/services/users/operations' import { ServerError } from '@/services/error' import { z } from 'zod' @@ -10,7 +10,7 @@ export async function sendResetPasswordMail(email: string) { const emailParsed = z.string().email().parse(email) try { - const user = await userMethods.read({ + const user = await userOperations.read({ params: { email: emailParsed }, bypassAuth: true, }) diff --git a/src/services/notifications/methods.ts b/src/services/notifications/operations.ts similarity index 98% rename from src/services/notifications/methods.ts rename to src/services/notifications/operations.ts index ea7dd044c..37ef398aa 100644 --- a/src/services/notifications/methods.ts +++ b/src/services/notifications/operations.ts @@ -28,7 +28,7 @@ export function repalceSpecialSymbols(text: string, user: UserFiltered) { .replaceAll('%N', `${user.firstname} ${user.lastname}`) } -export const notificationMethods = { +export const notificationOperations = { /** * Creates a notification with the specified data. * @@ -130,7 +130,7 @@ export const notificationMethods = { } }) - return await notificationMethods.create({ + return await notificationOperations.create({ session, bypassAuth: true, data: { diff --git a/src/services/notifications/subscription/methods.ts b/src/services/notifications/subscription/operations.ts similarity index 96% rename from src/services/notifications/subscription/methods.ts rename to src/services/notifications/subscription/operations.ts index 30f2a5653..feadf8da2 100644 --- a/src/services/notifications/subscription/methods.ts +++ b/src/services/notifications/subscription/operations.ts @@ -4,7 +4,7 @@ import { subscriptionSchemas } from './schemas' import { validateMethods } from '@/services/notifications/channel/schemas' import { allNotificationMethodsOff, allNotificationMethodsOn } from '@/services/notifications/config' import { availableNotificationMethodIncluder } from '@/services/notifications/channel/config' -import { notificationChannelMethods } from '@/services/notifications/channel/methods' +import { notificationChannelOperations } from '@/services/notifications/channel/operations' import { defineOperation } from '@/services/serviceOperation' import { ServerOnly } from '@/auth/auther/ServerOnly' import { ServerError } from '@/services/error' @@ -108,7 +108,7 @@ async function createTransactionPart( }) } -export const notificationSubscriptionMethods = { +export const notificationSubscriptionOperations = { read: defineOperation({ paramsSchema: z.object({ userId: z.number(), @@ -129,7 +129,7 @@ export const notificationSubscriptionMethods = { }), opensTransaction: true, operation: async ({ prisma, params, session }) => { - const channels = await notificationChannelMethods.readDefault({ + const channels = await notificationChannelOperations.readDefault({ session, bypassAuth: true, }) diff --git a/src/services/ombul/create.ts b/src/services/ombul/create.ts index 226a22799..032334307 100644 --- a/src/services/ombul/create.ts +++ b/src/services/ombul/create.ts @@ -5,8 +5,8 @@ import { readSpecialImageCollection } from '@/services/images/collections/read' import { createCmsImage } from '@/services/cms/images/create' import { prisma } from '@/prisma/client' import { createFile } from '@/services/store/createFile' -import { imageMethods } from '@/services/images/methods' -import { notificationMethods } from '@/services/notifications/methods' +import { imageOperations } from '@/services/images/operations' +import { notificationOperations } from '@/services/notifications/operations' import type { CreateOmbulTypes } from './validation' import type { Ombul } from '@prisma/client' @@ -43,7 +43,7 @@ export async function createOmbul( // create coverimage const ombulCoverCollection = await readSpecialImageCollection('OMBULCOVERS') - const coverImage = await imageMethods.create({ + const coverImage = await imageOperations.create({ params: { collectionId: ombulCoverCollection.id, }, @@ -70,7 +70,7 @@ export async function createOmbul( } })) - notificationMethods.createSpecial({ + notificationOperations.createSpecial({ params: { special: 'NEW_OMBUL', }, diff --git a/src/services/omegaquotes/create.ts b/src/services/omegaquotes/create.ts index 94465ab45..ae9714d69 100644 --- a/src/services/omegaquotes/create.ts +++ b/src/services/omegaquotes/create.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { createOmegaquotesValidation } from './validation' import { prismaCall } from '@/services/prismaCall' import { prisma } from '@/prisma/client' -import { notificationMethods } from '@/services/notifications/methods' +import { notificationOperations } from '@/services/notifications/operations' import type { CreateOmegaguotesTypes } from './validation' import type { OmegaQuote } from '@prisma/client' @@ -28,7 +28,7 @@ export async function createQuote( } })) - notificationMethods.createSpecial({ + notificationOperations.createSpecial({ params: { special: 'NEW_OMEGAQUOTE', }, diff --git a/src/services/permissions/actions.ts b/src/services/permissions/actions.ts index f7d1a69d0..20fccda78 100644 --- a/src/services/permissions/actions.ts +++ b/src/services/permissions/actions.ts @@ -1,10 +1,10 @@ 'use server' import { action } from '@/services/action' -import { permissionMethods } from '@/services/permissions/methods' +import { permissionOperations } from '@/services/permissions/operations' -export const readPermissionOfGroupAction = action(permissionMethods.readPermissionsOfGroup) -export const readPermissionMatrixAction = action(permissionMethods.readPermissionMatrix) -export const readDefaultPermissionsAction = action(permissionMethods.readDefaultPermissions) -export const updateDefaultPermissionsAction = action(permissionMethods.updateDefaultPermissions) -export const updateGroupPermissionAction = action(permissionMethods.updateGroupPermission) +export const readPermissionOfGroupAction = action(permissionOperations.readPermissionsOfGroup) +export const readPermissionMatrixAction = action(permissionOperations.readPermissionMatrix) +export const readDefaultPermissionsAction = action(permissionOperations.readDefaultPermissions) +export const updateDefaultPermissionsAction = action(permissionOperations.updateDefaultPermissions) +export const updateGroupPermissionAction = action(permissionOperations.updateGroupPermission) diff --git a/src/services/permissions/methods.ts b/src/services/permissions/operations.ts similarity index 97% rename from src/services/permissions/methods.ts rename to src/services/permissions/operations.ts index cc48b8054..cefd0871b 100644 --- a/src/services/permissions/methods.ts +++ b/src/services/permissions/operations.ts @@ -4,12 +4,12 @@ import { defineOperation } from '@/services/serviceOperation' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { invalidateAllUserSessionData, invalidateManyUserSessionData } from '@/services/auth/invalidateSession' import { groupsWithRelationsIncluder } from '@/services/groups/config' -import { checkGroupValidity, inferGroupName } from '@/services/groups/methods' +import { checkGroupValidity, inferGroupName } from '@/services/groups/operations' import { Permission } from '@prisma/client' import { z } from 'zod' -export const permissionMethods = { +export const permissionOperations = { readDefaultPermissions: defineOperation({ authorizer: () => permissionAuthers.readDefaultPermissions.dynamicFields({}), operation: async ({ prisma }) => @@ -23,7 +23,7 @@ export const permissionMethods = { }), operation: async ({ prisma, params }) => { const [defaultPermissions, groupPermissions] = await Promise.all([ - permissionMethods.readDefaultPermissions({}), + permissionOperations.readDefaultPermissions({}), prisma.membership.findMany({ where: { userId: params.userId, diff --git a/src/services/shop/actions.ts b/src/services/shop/actions.ts index dda7d92f6..c87373fa9 100644 --- a/src/services/shop/actions.ts +++ b/src/services/shop/actions.ts @@ -1,19 +1,19 @@ 'use server' import { action } from '@/services/action' -import { productMethods } from '@/services/shop/product/methods' -import { shopMethods } from '@/services/shop/shop/methods' +import { productOperations } from '@/services/shop/product/operations' +import { shopOperations } from '@/services/shop/shop/operations' -export const readProductsAction = action(productMethods.readMany) -export const readProductAction = action(productMethods.read) -export const createProductAction = action(productMethods.create) -export const updateProductAction = action(productMethods.update) +export const readProductsAction = action(productOperations.readMany) +export const readProductAction = action(productOperations.read) +export const createProductAction = action(productOperations.create) +export const updateProductAction = action(productOperations.update) -export const createProductForShopAction = action(productMethods.createForShop) -export const updateProductForShopAction = action(productMethods.updateForShop) +export const createProductForShopAction = action(productOperations.createForShop) +export const updateProductForShopAction = action(productOperations.updateForShop) -export const createShopProductConnectionAction = action(productMethods.createShopConnection) +export const createShopProductConnectionAction = action(productOperations.createShopConnection) -export const readShopsAction = action(shopMethods.readMany) -export const readShopAction = action(shopMethods.read) -export const createShopAction = action(shopMethods.create) +export const readShopsAction = action(shopOperations.readMany) +export const readShopAction = action(shopOperations.read) +export const createShopAction = action(shopOperations.create) diff --git a/src/services/shop/product/methods.ts b/src/services/shop/product/operations.ts similarity index 99% rename from src/services/shop/product/methods.ts rename to src/services/shop/product/operations.ts index 82076ad0a..345b9b9e7 100644 --- a/src/services/shop/product/methods.ts +++ b/src/services/shop/product/operations.ts @@ -6,7 +6,7 @@ import type { ExtendedProduct } from './Types' import { productAuthers } from './authers' import { productSchemas } from './schemas' -export const productMethods = { +export const productOperations = { create: defineOperation({ authorizer: () => productAuthers.create.dynamicFields({}), dataSchema: productSchemas.create, diff --git a/src/services/shop/purchase/methods.ts b/src/services/shop/purchase/operations.ts similarity index 91% rename from src/services/shop/purchase/methods.ts rename to src/services/shop/purchase/operations.ts index ed1f311de..48a4eb65c 100644 --- a/src/services/shop/purchase/methods.ts +++ b/src/services/shop/purchase/operations.ts @@ -3,17 +3,17 @@ import { purchaseAuthers } from './authers' import { purchaseSchemas } from './schemas' import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' -import { userMethods } from '@/services/users/methods' -import { permissionMethods } from '@/services/permissions/methods' +import { userOperations } from '@/services/users/operations' +import { permissionOperations } from '@/services/permissions/operations' import { userFilterSelection } from '@/services/users/config' import { PurchaseMethod } from '@prisma/client' -export const purchaseMethods = { +export const purchaseOperations = { createByStudentCard: defineOperation({ authorizer: async ({ data }) => { let user try { - user = await userMethods.read({ + user = await userOperations.read({ params: { studentCard: data.studentCard, }, @@ -26,7 +26,7 @@ export const purchaseMethods = { throw e } - const permissions = await permissionMethods.readPermissionsOfUser({ + const permissions = await permissionOperations.readPermissionsOfUser({ bypassAuth: true, params: { userId: user.id, diff --git a/src/services/shop/shop/methods.ts b/src/services/shop/shop/operations.ts similarity index 98% rename from src/services/shop/shop/methods.ts rename to src/services/shop/shop/operations.ts index 8c2d466cd..c2bd12408 100644 --- a/src/services/shop/shop/methods.ts +++ b/src/services/shop/shop/operations.ts @@ -5,7 +5,7 @@ import type { ExtendedShop } from './Types' import { shopSchemas } from './schema' import { shopAuthers } from './authers' -export const shopMethods = { +export const shopOperations = { create: defineOperation({ dataSchema: shopSchemas.create, authorizer: () => shopAuthers.create.dynamicFields({}), diff --git a/src/services/users/actions.ts b/src/services/users/actions.ts index 33b4d3b1a..7d84fad00 100644 --- a/src/services/users/actions.ts +++ b/src/services/users/actions.ts @@ -1,22 +1,22 @@ 'use server' import { action } from '@/services/action' -import { groupMethods } from '@/services/groups/methods' -import { userMethods } from '@/services/users/methods' +import { groupOperations } from '@/services/groups/operations' +import { userOperations } from '@/services/users/operations' /** * A action that creates a user by the given data. It will also hash the password * @param rawdata - The user to create * @returns - The created user */ -export const createUserAction = action(userMethods.create) +export const createUserAction = action(userOperations.create) /** * Action to destroy a user by the given id * @param id - The id of the user to destroy * @returns */ -export const destroyUserAction = action(userMethods.destroy) +export const destroyUserAction = action(userOperations.destroy) /** * A action to read a page of users with the given details (filtering) @@ -24,7 +24,7 @@ export const destroyUserAction = action(userMethods.destroy) * name and groups * @returns */ -export const readUserPageAction = action(userMethods.readPage) +export const readUserPageAction = action(userOperations.readPage) /** * Action meant to read the profile of a user. @@ -32,13 +32,13 @@ export const readUserPageAction = action(userMethods.readPage) * @param username - The username of the user to read * @returns - The profile of the user */ -export const readUserProfileAction = action(userMethods.readProfile) +export const readUserProfileAction = action(userOperations.readProfile) -export const readUserAction = action(userMethods.read) +export const readUserAction = action(userOperations.read) -export const readGroupsForPageFilteringAction = action(groupMethods.readGroupsExpanded) +export const readGroupsForPageFilteringAction = action(groupOperations.readGroupsExpanded) -export const updateUserAction = action(userMethods.update) -export const registerNewEmailAction = action(userMethods.registerNewEmail) -export const registerUser = action(userMethods.register) -export const registerStudentCardInQueueAction = action(userMethods.registerStudentCardInQueue) +export const updateUserAction = action(userOperations.update) +export const registerNewEmailAction = action(userOperations.registerNewEmail) +export const registerUser = action(userOperations.register) +export const registerStudentCardInQueueAction = action(userOperations.registerStudentCardInQueue) diff --git a/src/services/users/methods.ts b/src/services/users/operations.ts similarity index 97% rename from src/services/users/methods.ts rename to src/services/users/operations.ts index 976d59ca7..997d32789 100644 --- a/src/services/users/methods.ts +++ b/src/services/users/operations.ts @@ -7,8 +7,8 @@ import { studentCardRegistrationExpiry, userFilterSelection } from './config' -import { imageMethods } from '@/services/images/methods' -import { notificationSubscriptionMethods } from '@/services/notifications/subscription/methods' +import { imageOperations } from '@/services/images/operations' +import { notificationSubscriptionOperations } from '@/services/notifications/subscription/operations' import { readMembershipsOfUser } from '@/services/groups/memberships/read' import { NTNUEmailDomain } from '@/services/mail/mailAddressExternal/ConfigVars' import { sendVerifyEmail } from '@/services/notifications/email/systemMail/verifyEmail' @@ -22,11 +22,11 @@ import { getMembershipFilter } from '@/auth/getMembershipFilter' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { hashAndEncryptPassword } from '@/auth/password' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' -import { permissionMethods } from '@/services/permissions/methods' +import { permissionOperations } from '@/services/permissions/operations' import { z } from 'zod' import type { UserPagingReturn } from './Types' -export const userMethods = { +export const userOperations = { /** * This Method creates an user by invitation, and sends the invitation email. * WARNING: This should not be used to create users registered by Feide. @@ -101,7 +101,7 @@ export const userMethods = { }), authorizer: ({ params }) => userAuthers.readProfile.dynamicFields({ username: params.username }), operation: async ({ prisma, params }) => { - const defaultProfileImage = await imageMethods.readSpecial({ + const defaultProfileImage = await imageOperations.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, }) const user = await prisma.user.findUniqueOrThrow({ @@ -117,7 +117,7 @@ export const userMethods = { })) const memberships = await readMembershipsOfUser(user.id) - const permissions = await permissionMethods.readPermissionsOfUser({ + const permissions = await permissionOperations.readPermissionsOfUser({ bypassAuth: true, params: { userId: user.id @@ -503,7 +503,7 @@ export const userMethods = { ]) try { - await notificationSubscriptionMethods.createDefault({ + await notificationSubscriptionOperations.createDefault({ params: { userId: params.id, }, diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index dc27c0987..f4361b24d 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -4,7 +4,7 @@ import { createActionError, safeServerCall } from '@/services/actionError' import { checkVisibility } from '@/auth/checkVisibility' import { getUser } from '@/auth/getUser' import { groupTypesConfig } from '@/services/groups/config' -import { groupMethods } from '@/services/groups/methods' +import { groupOperations } from '@/services/groups/operations' import { purposeTextsConfig } from '@/services/visibility/ConfigVars' import { readVisibilityCollapsed } from '@/services/visibility/read' import type { ExpandedGroup, GroupsStructured } from '@/services/groups/Types' @@ -21,7 +21,7 @@ export async function readVisibilityForAdminAction(id: number): Promise readVisibilityCollapsed(id)), // TODO: Fix Authing here. The bypass should be false - safeServerCall(() => groupMethods.readGroupsStructured({ bypassAuth: true })) + safeServerCall(() => groupOperations.readGroupsStructured({ bypassAuth: true })) ]) if (!visibilityRes.success || !groupsRes.success) return createActionError('UNKNOWN ERROR', 'noe gikk galt') diff --git a/tests/services/apiKeys.test.ts b/tests/services/apiKeys.test.ts index 09dea2699..fc72abacf 100644 --- a/tests/services/apiKeys.test.ts +++ b/tests/services/apiKeys.test.ts @@ -1,7 +1,7 @@ import { Session } from '@/auth/Session' import { Smorekopp } from '@/services/error' import { prisma } from '@/prisma/client' -import { ApiKeyMethods } from '@/services/api-keys/methods' +import { apiKeyOperations } from '@/services/api-keys/operations' import { afterEach, describe, expect, test } from '@jest/globals' afterEach(async () => { @@ -16,7 +16,7 @@ describe('api keys', () => { user: null, }) - const createdApiKey = await ApiKeyMethods.create({ + const createdApiKey = await apiKeyOperations.create({ data: { name: 'Min api nøkkel', }, @@ -28,7 +28,7 @@ describe('api keys', () => { permissions: [], }) - const readApiKeyResult = await ApiKeyMethods.read({ + const readApiKeyResult = await apiKeyOperations.read({ params: createdApiKey, session, }) @@ -38,7 +38,7 @@ describe('api keys', () => { permissions: [], }) - await ApiKeyMethods.update({ + await apiKeyOperations.update({ params: createdApiKey, data: { permissions: ['APIKEY_ADMIN'], @@ -59,7 +59,7 @@ describe('api keys', () => { // so there should probably be a system in place to run the same test // with different session objects. test('create, read and update api key with unauthenticated user', async () => { - const createdApiKeyPromise = ApiKeyMethods.create({ + const createdApiKeyPromise = apiKeyOperations.create({ data: { name: 'Min api nøkkel', }, @@ -67,14 +67,14 @@ describe('api keys', () => { expect(createdApiKeyPromise).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) expect(await prisma.apiKey.count()).toEqual(0) - const readApiKeyPromise = ApiKeyMethods.read({ + const readApiKeyPromise = apiKeyOperations.read({ params: { id: 1, }, }) expect(readApiKeyPromise).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) - const updateApiKeyPromise = ApiKeyMethods.update({ + const updateApiKeyPromise = apiKeyOperations.update({ params: { id: 1, }, diff --git a/tests/services/jobads.test.ts b/tests/services/jobads.test.ts index b78f86574..090af3ef2 100644 --- a/tests/services/jobads.test.ts +++ b/tests/services/jobads.test.ts @@ -1,7 +1,7 @@ import { Session } from '@/auth/Session' import { Smorekopp } from '@/services/error' import { prisma } from '@/prisma/client' -import { jobAdMethods } from '@/services/career/jobAds/methods' +import { jobAdOperations } from '@/services/career/jobAds/operations' import { afterEach, beforeAll, describe, expect, test } from '@jest/globals' // NOTE: This is file contains a lot of boiler plate which should be refactored to be more reusable. @@ -39,7 +39,7 @@ afterEach(async () => { const jobAds = await prisma.jobAd.findMany() await Promise.all(jobAds.map(jobAd => - jobAdMethods.destroy({ + jobAdOperations.destroy({ params: { id: jobAd.id }, @@ -50,7 +50,7 @@ afterEach(async () => { describe('job ads', () => { test('create with unauthenticated user', async () => { - expect(jobAdMethods.create({ + expect(jobAdOperations.create({ data: CREATE_JOB_AD, session: Session.empty() })).rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) @@ -69,7 +69,7 @@ describe('job ads', () => { user: null, }) - await jobAdMethods.create({ data: CREATE_JOB_AD, session }) + await jobAdOperations.create({ data: CREATE_JOB_AD, session }) const res = await prisma.jobAd.findFirst({}) expect(res).toMatchObject(CREATE_JOB_AD) @@ -77,18 +77,18 @@ describe('job ads', () => { test('(create and then) read with unauthenticated user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await jobAdMethods.create({ + const createRes = await jobAdOperations.create({ data: CREATE_JOB_AD, bypassAuth: true }) - expect(jobAdMethods.read({ params: { idOrName: createRes.id }, session: Session.empty() })) + expect(jobAdOperations.read({ params: { idOrName: createRes.id }, session: Session.empty() })) .rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) }) test('(create and then) read with authorized user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await jobAdMethods.create({ + const createRes = await jobAdOperations.create({ data: CREATE_JOB_AD, bypassAuth: true }) @@ -99,18 +99,18 @@ describe('job ads', () => { user: null, }) - const readRes = await jobAdMethods.read({ params: { idOrName: createRes.id }, session }) + const readRes = await jobAdOperations.read({ params: { idOrName: createRes.id }, session }) expect(readRes).toMatchObject(CREATE_JOB_AD) }) test('update with unauthenticated user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await jobAdMethods.create({ + const createRes = await jobAdOperations.create({ data: CREATE_JOB_AD, bypassAuth: true }) - expect(jobAdMethods.update({ + expect(jobAdOperations.update({ params: { id: createRes.id, }, @@ -124,7 +124,7 @@ describe('job ads', () => { test('update with authorized user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await jobAdMethods.create({ + const createRes = await jobAdOperations.create({ data: CREATE_JOB_AD, bypassAuth: true }) @@ -135,7 +135,7 @@ describe('job ads', () => { user: null, }) - await jobAdMethods.update({ + await jobAdOperations.update({ params: { id: createRes.id, }, @@ -149,12 +149,12 @@ describe('job ads', () => { test('destroy with unauthenticated user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await jobAdMethods.create({ + const createRes = await jobAdOperations.create({ data: CREATE_JOB_AD, bypassAuth: true }) - expect(jobAdMethods.destroy({ params: { id: createRes.id }, session: Session.empty() })) + expect(jobAdOperations.destroy({ params: { id: createRes.id }, session: Session.empty() })) .rejects.toThrow(new Smorekopp('UNAUTHENTICATED')) const count = await prisma.jobAd.count() @@ -163,7 +163,7 @@ describe('job ads', () => { test('destroy with authorized user', async () => { // TODO: To avoid fragile tests, this should be refactored to use a seeded job ad. - const createRes = await jobAdMethods.create({ + const createRes = await jobAdOperations.create({ data: CREATE_JOB_AD, bypassAuth: true }) @@ -174,7 +174,7 @@ describe('job ads', () => { user: null, }) - await jobAdMethods.destroy({ params: { id: createRes.id }, session }) + await jobAdOperations.destroy({ params: { id: createRes.id }, session }) const count = await prisma.jobAd.count() expect(count).toBe(0) From 6c50694dfa05432597b712bf4b44de8cf98b35ca Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sat, 11 Oct 2025 01:23:09 +0200 Subject: [PATCH 20/24] refactor: config -> constants --- src/app/(auth)/register/RegistrationForm.tsx | 2 +- .../NotificationMethodCheckboxes.tsx | 2 +- src/app/_components/Permission/DisplayAllPermissions.tsx | 2 +- src/app/_components/Permission/Permission.tsx | 2 +- src/app/_components/Permission/PermissionCategory.tsx | 2 +- src/app/_components/UI/CheckboxFieldPresent.tsx | 2 +- src/app/admin/(permissions)/group-permissions/page.tsx | 2 +- src/app/admin/admission/[admission]/page.tsx | 2 +- src/app/admin/admission/page.tsx | 2 +- src/app/admin/groups/page.tsx | 2 +- .../admin/notification-channels/addNotificationChannel.tsx | 2 +- src/app/cabin/book/CabinPriceCalculator.tsx | 2 +- src/app/cabin/book/SelectBedProduct.tsx | 2 +- src/app/cabin/book/stateWrapper.tsx | 2 +- src/app/career/jobads/CreateJobAdForm.tsx | 2 +- src/app/career/jobads/JobAd.tsx | 2 +- src/app/career/jobads/[...orderAndName]/EditJobAd.tsx | 2 +- src/app/career/jobads/[...orderAndName]/page.tsx | 2 +- src/app/events/CreateOrUpdateEventForm.tsx | 4 ++-- src/app/events/[order]/[name]/RegistrationsList.tsx | 2 +- src/app/images/collections/[id]/CollectionAdminUpload.tsx | 2 +- .../(user-admin)/notifications/notificationSettings.tsx | 2 +- .../(user-admin)/notifications/subscriptionItem.tsx | 2 +- .../(user-admin)/settings/RegisterStudentCardButton.tsx | 2 +- src/app/users/[username]/page.tsx | 2 +- src/auth/VevenAdapter.ts | 2 +- src/lib/fields/{config.ts => constants.ts} | 0 src/lib/fields/zpn.ts | 2 +- src/prisma/seeder/src/seedNotificationsChannels.ts | 2 +- src/services/admission/{config.ts => constants.ts} | 0 src/services/admission/operations.ts | 2 +- src/services/api-keys/Types.ts | 2 +- src/services/api-keys/{config.ts => constants.ts} | 0 src/services/api-keys/operations.ts | 2 +- src/services/applications/periods/Types.ts | 2 +- .../applications/periods/{config.ts => constants.ts} | 0 src/services/applications/periods/operations.ts | 2 +- src/services/auth/operations.ts | 2 +- src/services/cabin/booking/Types.ts | 2 +- src/services/cabin/booking/cabinPriceCalculator.ts | 2 +- src/services/cabin/booking/{config.ts => constants.ts} | 2 +- src/services/cabin/booking/operations.ts | 6 +++--- src/services/cabin/product/{config.ts => constants.ts} | 0 src/services/cabin/product/operations.ts | 2 +- src/services/career/companies/{config.ts => constants.ts} | 0 src/services/career/companies/operations.ts | 2 +- src/services/career/jobAds/{config.ts => constants.ts} | 0 src/services/career/jobAds/operations.ts | 4 ++-- src/services/dots/{config.ts => constants.ts} | 0 src/services/dots/operations.ts | 2 +- src/services/events/Types.ts | 2 +- src/services/events/{config.ts => constants.ts} | 0 src/services/events/operations.ts | 2 +- src/services/events/registration/Types.ts | 2 +- .../events/registration/{config.ts => constants.ts} | 2 +- src/services/events/registration/operations.ts | 4 ++-- src/services/events/tags/{config.ts => constants.ts} | 0 src/services/events/tags/operations.ts | 2 +- src/services/groups/committees/{config.ts => constants.ts} | 2 +- src/services/groups/committees/operations.ts | 2 +- src/services/groups/committees/read.ts | 2 +- src/services/groups/{config.ts => constants.ts} | 0 src/services/groups/omegaMembershipGroups/update.ts | 2 +- src/services/groups/operations.ts | 4 ++-- src/services/images/{config.ts => constants.ts} | 0 src/services/images/operations.ts | 2 +- src/services/images/schemas.ts | 2 +- src/services/lockers/Types.ts | 2 +- src/services/lockers/locations/{config.ts => constants.ts} | 0 src/services/lockers/operations.ts | 2 +- .../lockers/reservations/{config.ts => constants.ts} | 0 src/services/mail/read.ts | 2 +- src/services/notifications/Types.ts | 4 ++-- .../notifications/channel/{config.ts => constants.ts} | 2 +- src/services/notifications/channel/operations.ts | 6 +++--- src/services/notifications/channel/schemas.ts | 4 ++-- src/services/notifications/{config.ts => constants.ts} | 0 .../notifications/email/{config.ts => constants.ts} | 0 src/services/notifications/email/dispatch.tsx | 2 +- src/services/notifications/email/mailHandler.ts | 2 +- src/services/notifications/notificationMethodOperations.ts | 2 +- src/services/notifications/operations.ts | 6 +++--- src/services/notifications/subscription/Types.ts | 2 +- .../notifications/subscription/{config.ts => constants.ts} | 2 +- src/services/notifications/subscription/operations.ts | 6 +++--- src/services/permissions/Types.ts | 2 +- src/services/permissions/{config.ts => constants.ts} | 0 src/services/permissions/operations.ts | 2 +- src/services/shop/purchase/operations.ts | 2 +- src/services/users/Types.ts | 2 +- src/services/users/{config.ts => constants.ts} | 0 src/services/users/operations.ts | 2 +- src/services/visibility/actions.ts | 2 +- 93 files changed, 89 insertions(+), 89 deletions(-) rename src/lib/fields/{config.ts => constants.ts} (100%) rename src/services/admission/{config.ts => constants.ts} (100%) rename src/services/api-keys/{config.ts => constants.ts} (100%) rename src/services/applications/periods/{config.ts => constants.ts} (100%) rename src/services/cabin/booking/{config.ts => constants.ts} (88%) rename src/services/cabin/product/{config.ts => constants.ts} (100%) rename src/services/career/companies/{config.ts => constants.ts} (100%) rename src/services/career/jobAds/{config.ts => constants.ts} (100%) rename src/services/dots/{config.ts => constants.ts} (100%) rename src/services/events/{config.ts => constants.ts} (100%) rename src/services/events/registration/{config.ts => constants.ts} (89%) rename src/services/events/tags/{config.ts => constants.ts} (100%) rename src/services/groups/committees/{config.ts => constants.ts} (93%) rename src/services/groups/{config.ts => constants.ts} (100%) rename src/services/images/{config.ts => constants.ts} (100%) rename src/services/lockers/locations/{config.ts => constants.ts} (100%) rename src/services/lockers/reservations/{config.ts => constants.ts} (100%) rename src/services/notifications/channel/{config.ts => constants.ts} (95%) rename src/services/notifications/{config.ts => constants.ts} (100%) rename src/services/notifications/email/{config.ts => constants.ts} (100%) rename src/services/notifications/subscription/{config.ts => constants.ts} (95%) rename src/services/permissions/{config.ts => constants.ts} (100%) rename src/services/users/{config.ts => constants.ts} (100%) diff --git a/src/app/(auth)/register/RegistrationForm.tsx b/src/app/(auth)/register/RegistrationForm.tsx index 7206cbefc..76a95d800 100644 --- a/src/app/(auth)/register/RegistrationForm.tsx +++ b/src/app/(auth)/register/RegistrationForm.tsx @@ -4,7 +4,7 @@ import Form from '@/components/Form/Form' import Checkbox from '@/components/UI/Checkbox' import { SelectString } from '@/components/UI/Select' import TextInput from '@/components/UI/TextInput' -import { sexConfig } from '@/services/users/config' +import { sexConfig } from '@/services/users/constants' import { SEX, type User } from '@prisma/client' import { signIn } from 'next-auth/react' import { useSearchParams } from 'next/navigation' diff --git a/src/app/_components/NotificaionMethodSelector/NotificationMethodCheckboxes.tsx b/src/app/_components/NotificaionMethodSelector/NotificationMethodCheckboxes.tsx index f7fb16a0c..b71d10474 100644 --- a/src/app/_components/NotificaionMethodSelector/NotificationMethodCheckboxes.tsx +++ b/src/app/_components/NotificaionMethodSelector/NotificationMethodCheckboxes.tsx @@ -1,6 +1,6 @@ 'use client' import Checkbox from '@/components/UI/Checkbox' -import { notificationMethodsDisplayMap } from '@/services/notifications/config' +import { notificationMethodsDisplayMap } from '@/services/notifications/constants' import { v4 as uuid } from 'uuid' import React, { useState } from 'react' import type { NotificationMethodGeneral, NotificationMethodTypes } from '@/services/notifications/Types' diff --git a/src/app/_components/Permission/DisplayAllPermissions.tsx b/src/app/_components/Permission/DisplayAllPermissions.tsx index 6bfcec162..c9eb819ba 100644 --- a/src/app/_components/Permission/DisplayAllPermissions.tsx +++ b/src/app/_components/Permission/DisplayAllPermissions.tsx @@ -1,5 +1,5 @@ import PermissionCategory from './PermissionCategory' -import { permissionCategories } from '@/services/permissions/config' +import { permissionCategories } from '@/services/permissions/constants' import type { PropTypes as PropTypesCategory } from './PermissionCategory' type PropTypes = Pick diff --git a/src/app/_components/Permission/Permission.tsx b/src/app/_components/Permission/Permission.tsx index 56ea31df4..f9751882d 100644 --- a/src/app/_components/Permission/Permission.tsx +++ b/src/app/_components/Permission/Permission.tsx @@ -1,5 +1,5 @@ import styles from './Permission.module.scss' -import { permissionConfig } from '@/services/permissions/config' +import { permissionConfig } from '@/services/permissions/constants' import type { ReactNode } from 'react' import type { Permission as PermissionT } from '@prisma/client' diff --git a/src/app/_components/Permission/PermissionCategory.tsx b/src/app/_components/Permission/PermissionCategory.tsx index b1f8eac07..71d0cb6d2 100644 --- a/src/app/_components/Permission/PermissionCategory.tsx +++ b/src/app/_components/Permission/PermissionCategory.tsx @@ -1,6 +1,6 @@ import Permission from './Permission' import styles from './PermissionCategory.module.scss' -import { permissionConfig } from '@/services/permissions/config' +import { permissionConfig } from '@/services/permissions/constants' import { Permission as PermissionEnum } from '@prisma/client' import type { PermissionCategory } from '@/services/permissions/Types' import type { ReactNode } from 'react' diff --git a/src/app/_components/UI/CheckboxFieldPresent.tsx b/src/app/_components/UI/CheckboxFieldPresent.tsx index b4bc4d5ff..c792132dc 100644 --- a/src/app/_components/UI/CheckboxFieldPresent.tsx +++ b/src/app/_components/UI/CheckboxFieldPresent.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './CheckboxFieldPresent.module.scss' -import { FIELD_IS_PRESENT_VALUE } from '@/lib/fields/config' +import { FIELD_IS_PRESENT_VALUE } from '@/lib/fields/constants' type PropTypes = { name: string diff --git a/src/app/admin/(permissions)/group-permissions/page.tsx b/src/app/admin/(permissions)/group-permissions/page.tsx index 7e09a0829..cabf08862 100644 --- a/src/app/admin/(permissions)/group-permissions/page.tsx +++ b/src/app/admin/(permissions)/group-permissions/page.tsx @@ -2,7 +2,7 @@ import styles from './page.module.scss' import PermissionCheckbox from './PermissionCheckbox' import { readPermissionMatrixAction } from '@/services/permissions/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' -import { permissionConfig } from '@/services/permissions/config' +import { permissionConfig } from '@/services/permissions/constants' import type { Permission } from '@prisma/client' export default async function PermissionGroups() { diff --git a/src/app/admin/admission/[admission]/page.tsx b/src/app/admin/admission/[admission]/page.tsx index 191c83ea0..7679f5447 100644 --- a/src/app/admin/admission/[admission]/page.tsx +++ b/src/app/admin/admission/[admission]/page.tsx @@ -1,5 +1,5 @@ import RegisterAdmissiontrial from './registration' -import { admissionDisplayNames, allAdmissions } from '@/services/admission/config' +import { admissionDisplayNames, allAdmissions } from '@/services/admission/constants' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { readOmegaJWTPublicKey } from '@/services/omegaid/actions' import { type Admission as AdmissionType } from '@prisma/client' diff --git a/src/app/admin/admission/page.tsx b/src/app/admin/admission/page.tsx index 6e200789c..5a05f2212 100644 --- a/src/app/admin/admission/page.tsx +++ b/src/app/admin/admission/page.tsx @@ -1,7 +1,7 @@ 'use server' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { admissionDisplayNames, allAdmissions } from '@/services/admission/config' +import { admissionDisplayNames, allAdmissions } from '@/services/admission/constants' import Link from 'next/link' import { v4 as uuid } from 'uuid' diff --git a/src/app/admin/groups/page.tsx b/src/app/admin/groups/page.tsx index 08817a796..87cc27990 100644 --- a/src/app/admin/groups/page.tsx +++ b/src/app/admin/groups/page.tsx @@ -1,6 +1,6 @@ import styles from './page.module.scss' import GroupSelector from './GroupSelector' -import { GroupTypeOrdering } from '@/services/groups/config' +import { GroupTypeOrdering } from '@/services/groups/constants' import { readGroupsStructuredAction } from '@/services/groups/actions' import { notFound } from 'next/navigation' diff --git a/src/app/admin/notification-channels/addNotificationChannel.tsx b/src/app/admin/notification-channels/addNotificationChannel.tsx index b19a161c1..d96ebed01 100644 --- a/src/app/admin/notification-channels/addNotificationChannel.tsx +++ b/src/app/admin/notification-channels/addNotificationChannel.tsx @@ -6,7 +6,7 @@ import NotificationMethodSelector from '@/components/NotificaionMethodSelector/N import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' import { bindParams } from '@/services/actionBind' import { createNotificationChannelAction } from '@/services/notifications/actions' -import { allNotificationMethodsOff, allNotificationMethodsOn } from '@/services/notifications/config' +import { allNotificationMethodsOff, allNotificationMethodsOn } from '@/services/notifications/constants' import { useState } from 'react' import { useRouter } from 'next/navigation' import type { ExpandedNotificationChannel, NotificationMethodGeneral } from '@/services/notifications/Types' diff --git a/src/app/cabin/book/CabinPriceCalculator.tsx b/src/app/cabin/book/CabinPriceCalculator.tsx index 391cd1cbe..1cf32e0b2 100644 --- a/src/app/cabin/book/CabinPriceCalculator.tsx +++ b/src/app/cabin/book/CabinPriceCalculator.tsx @@ -1,7 +1,7 @@ import SimpleTable from '@/app/_components/Table/SimpleTable' import { displayPrice } from '@/lib/money/convert' import { calculateCabinBookingPrice, calculateTotalCabinBookingPrice } from '@/services/cabin/booking/cabinPriceCalculator' -import type { CabinProductExtended } from '@/services/cabin/product/config' +import type { CabinProductExtended } from '@/services/cabin/product/constants' import type { CabinPriceCalculatorReturnType } from '@/services/cabin/booking/cabinPriceCalculator' import type { PricePeriod } from '@prisma/client' diff --git a/src/app/cabin/book/SelectBedProduct.tsx b/src/app/cabin/book/SelectBedProduct.tsx index 4b0694b7c..33409b772 100644 --- a/src/app/cabin/book/SelectBedProduct.tsx +++ b/src/app/cabin/book/SelectBedProduct.tsx @@ -1,5 +1,5 @@ import NumberInput from '@/app/_components/UI/NumberInput' -import type { CabinProductExtended } from '@/services/cabin/product/config' +import type { CabinProductExtended } from '@/services/cabin/product/constants' export default function SelectBedProducts({ diff --git a/src/app/cabin/book/stateWrapper.tsx b/src/app/cabin/book/stateWrapper.tsx index 7cb22d688..97c1b47dd 100644 --- a/src/app/cabin/book/stateWrapper.tsx +++ b/src/app/cabin/book/stateWrapper.tsx @@ -17,7 +17,7 @@ import { } from '@/services/cabin/actions' import { getZodDateString } from '@/lib/dates/formatting' import { useMemo, useState } from 'react' -import type { CabinProductExtended } from '@/services/cabin/product/config' +import type { CabinProductExtended } from '@/services/cabin/product/constants' import type { BookingFiltered } from '@/services/cabin/booking/Types' import type { DateRange } from './CabinCalendar' import type { BookingType, PricePeriod } from '@prisma/client' diff --git a/src/app/career/jobads/CreateJobAdForm.tsx b/src/app/career/jobads/CreateJobAdForm.tsx index 379c4fdc4..0c13102bb 100644 --- a/src/app/career/jobads/CreateJobAdForm.tsx +++ b/src/app/career/jobads/CreateJobAdForm.tsx @@ -6,7 +6,7 @@ import { createJobAdAction } from '@/services/career/jobAds/actions' import TextInput from '@/components/UI/TextInput' import Form from '@/components/Form/Form' import { SelectString } from '@/components/UI/Select' -import { jobAdOptions } from '@/services/career/jobAds/config' +import { jobAdOptions } from '@/services/career/jobAds/constants' import DateInput from '@/components/UI/DateInput' import { v4 as uuid } from 'uuid' diff --git a/src/app/career/jobads/JobAd.tsx b/src/app/career/jobads/JobAd.tsx index 3ce7faeb5..522890ded 100644 --- a/src/app/career/jobads/JobAd.tsx +++ b/src/app/career/jobads/JobAd.tsx @@ -1,6 +1,6 @@ import styles from './JobAd.module.scss' import ImageCard from '@/components/ImageCard/ImageCard' -import { jobAdType } from '@/services/career/jobAds/config' +import { jobAdType } from '@/services/career/jobAds/constants' import type { SimpleJobAd } from '@/services/career/jobAds/Types' type PropTypes = { diff --git a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx index b8b4a38f2..e19fe0ec6 100644 --- a/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx +++ b/src/app/career/jobads/[...orderAndName]/EditJobAd.tsx @@ -12,7 +12,7 @@ import { CompanyPagingContext } from '@/contexts/paging/CompanyPaging' import CompanyChooser from '@/app/career/jobads/CompanyChooser' import { bindParams } from '@/services/actionBind' import { destroyJobAdAction, updateJobAdAction } from '@/career/jobAds/actions' -import { jobAdOptions } from '@/services/career/jobAds/config' +import { jobAdOptions } from '@/services/career/jobAds/constants' import { v4 as uuid } from 'uuid' import { useContext, type ReactNode } from 'react' import type { ExpandedJobAd } from '@/career/jobAds/Types' diff --git a/src/app/career/jobads/[...orderAndName]/page.tsx b/src/app/career/jobads/[...orderAndName]/page.tsx index a89a76ac0..759e467e7 100644 --- a/src/app/career/jobads/[...orderAndName]/page.tsx +++ b/src/app/career/jobads/[...orderAndName]/page.tsx @@ -8,7 +8,7 @@ import Company from '@/components/Company/Company' import Date from '@/components/Date/Date' import { Session } from '@/auth/Session' import { readJobAdAction } from '@/services/career/jobAds/actions' -import { jobAdType } from '@/services/career/jobAds/config' +import { jobAdType } from '@/services/career/jobAds/constants' import { notFound } from 'next/navigation' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { diff --git a/src/app/events/CreateOrUpdateEventForm.tsx b/src/app/events/CreateOrUpdateEventForm.tsx index 5a21836d8..019fec0b3 100644 --- a/src/app/events/CreateOrUpdateEventForm.tsx +++ b/src/app/events/CreateOrUpdateEventForm.tsx @@ -9,9 +9,9 @@ import Form from '@/components/Form/Form' import TextInput from '@/components/UI/TextInput' import EventTag from '@/components/Event/EventTag' import { bindParams } from '@/services/actionBind' -import { FIELD_IS_PRESENT_VALUE } from '@/lib/fields/config' +import { FIELD_IS_PRESENT_VALUE } from '@/lib/fields/constants' import { createEventAction, updateEventAction } from '@/services/events/actions' -import { eventCanBeViewdByOptions } from '@/services/events/config' +import { eventCanBeViewdByOptions } from '@/services/events/constants' import { useState } from 'react' import type { Event, EventTag as EventTagT } from '@prisma/client' import type { ChangeEvent } from 'react' diff --git a/src/app/events/[order]/[name]/RegistrationsList.tsx b/src/app/events/[order]/[name]/RegistrationsList.tsx index 680154061..c1a0d463b 100644 --- a/src/app/events/[order]/[name]/RegistrationsList.tsx +++ b/src/app/events/[order]/[name]/RegistrationsList.tsx @@ -12,7 +12,7 @@ import Form from '@/components/Form/Form' import { bindParams } from '@/services/actionBind' import ContactCard from '@/components/User/ContactCard' import { eventRegistrationDestroyAction } from '@/services/events/registration/actions' -import { REGISTRATION_READER_TYPE } from '@/services/events/registration/config' +import { REGISTRATION_READER_TYPE } from '@/services/events/registration/constants' import Link from 'next/link' import { useState } from 'react' import type { EventFiltered } from '@/services/events/Types' diff --git a/src/app/images/collections/[id]/CollectionAdminUpload.tsx b/src/app/images/collections/[id]/CollectionAdminUpload.tsx index 581eaf2bf..dffe09172 100644 --- a/src/app/images/collections/[id]/CollectionAdminUpload.tsx +++ b/src/app/images/collections/[id]/CollectionAdminUpload.tsx @@ -7,7 +7,7 @@ import ProgressBar from '@/components/ProgressBar/ProgressBar' import TextInput from '@/app/_components/UI/TextInput' import LicenseChooser from '@/app/_components/LicenseChooser/LicenseChooser' import { createImagesAction } from '@/services/images/actions' -import { maxImageCountInOneBatch } from '@/services/images/config' +import { maxImageCountInOneBatch } from '@/services/images/constants' import { useCallback, useState } from 'react' import type { FileWithStatus } from '@/components/UI/Dropzone' import type { ActionReturn } from '@/services/actionTypes' diff --git a/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx b/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx index d8343acf8..8efe9ad76 100644 --- a/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx +++ b/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx @@ -6,7 +6,7 @@ import { booleanOperationOnMethods, newAllMethodsOff } from '@/services/notifica import SubmitButton from '@/components/UI/SubmitButton' import { SUCCESS_FEEDBACK_TIME } from '@/components/Form/ConfigVars' import { updateNotificationSubscriptionsAction } from '@/services/notifications/actions' -import { notificationMethodsArray, notificationMethodsDisplayMap } from '@/services/notifications/config' +import { notificationMethodsArray, notificationMethodsDisplayMap } from '@/services/notifications/constants' import { v4 as uuid } from 'uuid' import { useState } from 'react' import type { UserFiltered } from '@/services/users/Types' diff --git a/src/app/users/[username]/(user-admin)/notifications/subscriptionItem.tsx b/src/app/users/[username]/(user-admin)/notifications/subscriptionItem.tsx index b300308c5..d21ee92f9 100644 --- a/src/app/users/[username]/(user-admin)/notifications/subscriptionItem.tsx +++ b/src/app/users/[username]/(user-admin)/notifications/subscriptionItem.tsx @@ -2,7 +2,7 @@ import styles from './subscriptionItem.module.scss' import NotificationMethodCheckboxes from '@/components/NotificaionMethodSelector/NotificationMethodCheckboxes' -import { allNotificationMethodsOn } from '@/services/notifications/config' +import { allNotificationMethodsOn } from '@/services/notifications/constants' import { v4 as uuid } from 'uuid' import React from 'react' import type { NotificationMethodGeneral } from '@/services/notifications/Types' diff --git a/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx b/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx index d6878c5a7..d88518fa9 100644 --- a/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx +++ b/src/app/users/[username]/(user-admin)/settings/RegisterStudentCardButton.tsx @@ -1,7 +1,7 @@ 'use client' import { registerStudentCardInQueueAction } from '@/services/users/actions' import Form from '@/app/_components/Form/Form' -import { studentCardRegistrationExpiry } from '@/services/users/config' +import { studentCardRegistrationExpiry } from '@/services/users/constants' export default function RegisterStudentCardButton({ diff --git a/src/app/users/[username]/page.tsx b/src/app/users/[username]/page.tsx index 41d030987..f7c7a0f1c 100644 --- a/src/app/users/[username]/page.tsx +++ b/src/app/users/[username]/page.tsx @@ -9,7 +9,7 @@ import ProfilePicture from '@/components/User/ProfilePicture' import UserDisplayName from '@/components/User/UserDisplayName' import { readUserProfileAction } from '@/services/users/actions' import { readSpecialImageAction } from '@/services/images/actions' -import { sexConfig } from '@/services/users/config' +import { sexConfig } from '@/services/users/constants' import Link from 'next/link' import { notFound, redirect } from 'next/navigation' import { v4 as uuid } from 'uuid' diff --git a/src/auth/VevenAdapter.ts b/src/auth/VevenAdapter.ts index 2203f28a4..955a6eef9 100644 --- a/src/auth/VevenAdapter.ts +++ b/src/auth/VevenAdapter.ts @@ -3,7 +3,7 @@ import { readJWTPayload } from '@/jwt/jwtReadUnsecure' import { createFeideAccount } from '@/services/auth/feideAccounts/create' import { readUserOrNullOfFeideAccount } from '@/services/auth/feideAccounts/read' import { userOperations } from '@/services/users/operations' -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import type { UserFiltered } from '@/services/users/Types' import type { PrismaClient } from '@prisma/client' import type { Adapter, AdapterUser, AdapterAccount } from 'next-auth/adapters' diff --git a/src/lib/fields/config.ts b/src/lib/fields/constants.ts similarity index 100% rename from src/lib/fields/config.ts rename to src/lib/fields/constants.ts diff --git a/src/lib/fields/zpn.ts b/src/lib/fields/zpn.ts index c49792c96..c9096923c 100644 --- a/src/lib/fields/zpn.ts +++ b/src/lib/fields/zpn.ts @@ -1,4 +1,4 @@ -import { FIELD_IS_PRESENT_VALUE } from './config' +import { FIELD_IS_PRESENT_VALUE } from './constants' import { dateMatchCron } from '@/lib/dates/cron' import { z } from 'zod' import { zfd } from 'zod-form-data' diff --git a/src/prisma/seeder/src/seedNotificationsChannels.ts b/src/prisma/seeder/src/seedNotificationsChannels.ts index 344606379..190d33de0 100644 --- a/src/prisma/seeder/src/seedNotificationsChannels.ts +++ b/src/prisma/seeder/src/seedNotificationsChannels.ts @@ -1,4 +1,4 @@ -import { allNotificationMethodsOn } from '@/services/notifications/config' +import { allNotificationMethodsOn } from '@/services/notifications/constants' import { SpecialNotificationChannel } from '@prisma/client' import type { NotificationMethod, PrismaClient } from '@prisma/client' diff --git a/src/services/admission/config.ts b/src/services/admission/constants.ts similarity index 100% rename from src/services/admission/config.ts rename to src/services/admission/constants.ts diff --git a/src/services/admission/operations.ts b/src/services/admission/operations.ts index 70e08ea7e..2e223d29b 100644 --- a/src/services/admission/operations.ts +++ b/src/services/admission/operations.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { admissionSchemas } from './schemas' import { admissionAuthers } from './authers' -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import { defineOperation } from '@/services/serviceOperation' import { updateUserOmegaMembershipGroup } from '@/services/groups/omegaMembershipGroups/update' import { Admission } from '@prisma/client' diff --git a/src/services/api-keys/Types.ts b/src/services/api-keys/Types.ts index 07c39330c..32d878a71 100644 --- a/src/services/api-keys/Types.ts +++ b/src/services/api-keys/Types.ts @@ -1,4 +1,4 @@ -import type { apiKeyFieldsToExpose } from './config' +import type { apiKeyFieldsToExpose } from './constants' import type { ApiKey } from '@prisma/client' export type ApiKeyFiltered = Pick diff --git a/src/services/api-keys/config.ts b/src/services/api-keys/constants.ts similarity index 100% rename from src/services/api-keys/config.ts rename to src/services/api-keys/constants.ts diff --git a/src/services/api-keys/operations.ts b/src/services/api-keys/operations.ts index 15b4813a9..10f386ed7 100644 --- a/src/services/api-keys/operations.ts +++ b/src/services/api-keys/operations.ts @@ -3,7 +3,7 @@ import { apiKeyAuthers } from './authers' import { apiKeySchemas } from './schemas' import { apiKeyHashAndEncrypt } from './hashEncryptKey' import { encodeApiKey } from './apiKeyEncoder' -import { apiFilterSelection, apiKeyLength } from './config' +import { apiFilterSelection, apiKeyLength } from './constants' import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' import logger from '@/lib/logger' diff --git a/src/services/applications/periods/Types.ts b/src/services/applications/periods/Types.ts index f03f0c86c..36ba710da 100644 --- a/src/services/applications/periods/Types.ts +++ b/src/services/applications/periods/Types.ts @@ -1,4 +1,4 @@ -import type { committeesParticipatingincluder } from './config' +import type { committeesParticipatingincluder } from './constants' import type { Image, Prisma } from '@prisma/client' export type CountdownInfo = { diff --git a/src/services/applications/periods/config.ts b/src/services/applications/periods/constants.ts similarity index 100% rename from src/services/applications/periods/config.ts rename to src/services/applications/periods/constants.ts diff --git a/src/services/applications/periods/operations.ts b/src/services/applications/periods/operations.ts index bb0951a99..d4cb86c90 100644 --- a/src/services/applications/periods/operations.ts +++ b/src/services/applications/periods/operations.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { applicationPeriodAuthers } from './authers' import { applicationPeriodSchemas } from './schemas' -import { committeesParticipatingincluder } from './config' +import { committeesParticipatingincluder } from './constants' import { applicationOperations } from '@/services/applications/operations' import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' diff --git a/src/services/auth/operations.ts b/src/services/auth/operations.ts index 50da2c74e..b07a92d6c 100644 --- a/src/services/auth/operations.ts +++ b/src/services/auth/operations.ts @@ -1,6 +1,6 @@ import { authAuthers } from './authers' import { authSchemas } from './schemas' -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import { userSchemas } from '@/services/users/schemas' import { sendResetPasswordMail } from '@/services/notifications/email/systemMail/resetPassword' import { defineOperation } from '@/services/serviceOperation' diff --git a/src/services/cabin/booking/Types.ts b/src/services/cabin/booking/Types.ts index f391c3604..bf3c45dda 100644 --- a/src/services/cabin/booking/Types.ts +++ b/src/services/cabin/booking/Types.ts @@ -1,4 +1,4 @@ -import type { cabinBookingFieldsToExpose } from './config' +import type { cabinBookingFieldsToExpose } from './constants' import type { Booking } from '@prisma/client' export type BookingFiltered = Pick diff --git a/src/services/cabin/booking/cabinPriceCalculator.ts b/src/services/cabin/booking/cabinPriceCalculator.ts index 8928cea3e..e38d0fc15 100644 --- a/src/services/cabin/booking/cabinPriceCalculator.ts +++ b/src/services/cabin/booking/cabinPriceCalculator.ts @@ -1,5 +1,5 @@ import { dateMatchCron } from '@/lib/dates/cron' -import type { CabinProductExtended, CabinProductPriceExtended } from '@/services/cabin/product/config' +import type { CabinProductExtended, CabinProductPriceExtended } from '@/services/cabin/product/constants' import type { CabinProduct, CabinProductPrice, PricePeriod } from '@prisma/client' function getDateArray(start: Date, end: Date) { diff --git a/src/services/cabin/booking/config.ts b/src/services/cabin/booking/constants.ts similarity index 88% rename from src/services/cabin/booking/config.ts rename to src/services/cabin/booking/constants.ts index d492f4b1e..c805ca080 100644 --- a/src/services/cabin/booking/config.ts +++ b/src/services/cabin/booking/constants.ts @@ -1,5 +1,5 @@ import { createSelection } from '@/services/createSelection' -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import type { Booking } from '@prisma/client' export const cabinBookingFieldsToExpose = ['start', 'end', 'type'] as const satisfies (keyof Booking)[] diff --git a/src/services/cabin/booking/operations.ts b/src/services/cabin/booking/operations.ts index 36a802122..ea75b5484 100644 --- a/src/services/cabin/booking/operations.ts +++ b/src/services/cabin/booking/operations.ts @@ -2,9 +2,9 @@ import 'server-only' import { calculateCabinBookingPrice, calculateTotalCabinBookingPrice } from './cabinPriceCalculator' import { cabinBookingSchemas } from './schemas' import { cabinBookingAuthers } from './authers' -import { cabinBookingFilerSelection, cabinBookingIncluder } from './config' +import { cabinBookingFilerSelection, cabinBookingIncluder } from './constants' import { cabinPricePeriodOperations } from '@/services/cabin/pricePeriod/operations' -import { cabinProductPriceIncluder } from '@/services/cabin/product/config' +import { cabinProductPriceIncluder } from '@/services/cabin/product/constants' import { defineOperation } from '@/services/serviceOperation' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { ServerError } from '@/services/error' @@ -13,7 +13,7 @@ import { sendSystemMail } from '@/services/notifications/email/send' import { notificationOperations } from '@/services/notifications/operations' import { z } from 'zod' import { BookingType } from '@prisma/client' -import type { CabinProductExtended } from '@/services/cabin/product/config' +import type { CabinProductExtended } from '@/services/cabin/product/constants' const mailData = { title: 'Bekreftelse på hyttebooking', diff --git a/src/services/cabin/product/config.ts b/src/services/cabin/product/constants.ts similarity index 100% rename from src/services/cabin/product/config.ts rename to src/services/cabin/product/constants.ts diff --git a/src/services/cabin/product/operations.ts b/src/services/cabin/product/operations.ts index 2c5946d41..241622657 100644 --- a/src/services/cabin/product/operations.ts +++ b/src/services/cabin/product/operations.ts @@ -2,7 +2,7 @@ import 'server-only' import { cabinProductAuthers } from './authers' import { cabinProductSchemas } from './schemas' -import { cabinProductPriceIncluder } from './config' +import { cabinProductPriceIncluder } from './constants' import { cabinReleasePeriodOperations } from '@/services/cabin/releasePeriod/operations' import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' diff --git a/src/services/career/companies/config.ts b/src/services/career/companies/constants.ts similarity index 100% rename from src/services/career/companies/config.ts rename to src/services/career/companies/constants.ts diff --git a/src/services/career/companies/operations.ts b/src/services/career/companies/operations.ts index 5a550063c..50eb52630 100644 --- a/src/services/career/companies/operations.ts +++ b/src/services/career/companies/operations.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { companyAuthers } from './authers' -import { logoIncluder } from './config' +import { logoIncluder } from './constants' import { companySchemas } from './schemas' import { createCmsImage } from '@/services/cms/images/create' import { defineOperation } from '@/services/serviceOperation' diff --git a/src/services/career/jobAds/config.ts b/src/services/career/jobAds/constants.ts similarity index 100% rename from src/services/career/jobAds/config.ts rename to src/services/career/jobAds/constants.ts diff --git a/src/services/career/jobAds/operations.ts b/src/services/career/jobAds/operations.ts index d3ec09205..e3595f5c2 100644 --- a/src/services/career/jobAds/operations.ts +++ b/src/services/career/jobAds/operations.ts @@ -1,8 +1,8 @@ import '@pn-server-only' import { jobAdAuthers } from './authers' import { jobAdSchemas } from './schemas' -import { articleAndCompanyIncluder, simpleArticleAndCompanyIncluder } from './config' -import { logoIncluder } from '@/services/career/companies/config' +import { articleAndCompanyIncluder, simpleArticleAndCompanyIncluder } from './constants' +import { logoIncluder } from '@/services/career/companies/constants' import { defineOperation } from '@/services/serviceOperation' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { createArticle } from '@/services/cms/articles/create' diff --git a/src/services/dots/config.ts b/src/services/dots/constants.ts similarity index 100% rename from src/services/dots/config.ts rename to src/services/dots/constants.ts diff --git a/src/services/dots/operations.ts b/src/services/dots/operations.ts index 7998847db..91dddd561 100644 --- a/src/services/dots/operations.ts +++ b/src/services/dots/operations.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { dotAuthers } from './authers' import { dotSchemas } from './schemas' -import { dotBaseDuration, dotsIncluder } from './config' +import { dotBaseDuration, dotsIncluder } from './constants' import { defineOperation } from '@/services/serviceOperation' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' import { readPageInputSchemaObject } from '@/lib/paging/schema' diff --git a/src/services/events/Types.ts b/src/services/events/Types.ts index 003cfddee..834282f1a 100644 --- a/src/services/events/Types.ts +++ b/src/services/events/Types.ts @@ -1,4 +1,4 @@ -import type { eventFilterSelection } from './config' +import type { eventFilterSelection } from './constants' import type { ExpandedCmsImage } from '@/cms/images/Types' import type { EventTag, Prisma } from '@prisma/client' diff --git a/src/services/events/config.ts b/src/services/events/constants.ts similarity index 100% rename from src/services/events/config.ts rename to src/services/events/constants.ts diff --git a/src/services/events/operations.ts b/src/services/events/operations.ts index c749a6c44..f709820ba 100644 --- a/src/services/events/operations.ts +++ b/src/services/events/operations.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { eventAuthers } from './authers' import { eventSchemas } from './schemas' -import { eventFilterSelection } from './config' +import { eventFilterSelection } from './constants' import { notificationOperations } from '@/services/notifications/operations' import { createCmsParagraph } from '@/services/cms/paragraphs/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' diff --git a/src/services/events/registration/Types.ts b/src/services/events/registration/Types.ts index 8df2e67ca..c63064da2 100644 --- a/src/services/events/registration/Types.ts +++ b/src/services/events/registration/Types.ts @@ -1,4 +1,4 @@ -import type { eventRegistrationIncluderDetailed, eventRegistrationSelection, REGISTRATION_READER_TYPE } from './config' +import type { eventRegistrationIncluderDetailed, eventRegistrationSelection, REGISTRATION_READER_TYPE } from './constants' import type { Image, Prisma } from '@prisma/client' // This type will just make sure that the image is not null diff --git a/src/services/events/registration/config.ts b/src/services/events/registration/constants.ts similarity index 89% rename from src/services/events/registration/config.ts rename to src/services/events/registration/constants.ts index 0a2936807..e86d27fb5 100644 --- a/src/services/events/registration/config.ts +++ b/src/services/events/registration/constants.ts @@ -1,4 +1,4 @@ -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import type { Prisma } from '@prisma/client' export const eventRegistrationSelection = { diff --git a/src/services/events/registration/operations.ts b/src/services/events/registration/operations.ts index b769aef38..bed346469 100644 --- a/src/services/events/registration/operations.ts +++ b/src/services/events/registration/operations.ts @@ -1,12 +1,12 @@ import '@pn-server-only' -import { eventRegistrationIncluderDetailed, eventRegistrationSelection, REGISTRATION_READER_TYPE } from './config' +import { eventRegistrationIncluderDetailed, eventRegistrationSelection, REGISTRATION_READER_TYPE } from './constants' import { eventRegistrationAuthers } from './authers' import { eventRegistrationSchemas } from './schemas' import { Smorekopp } from '@/services/error' import { imageOperations } from '@/services/images/operations' import { notificationOperations } from '@/services/notifications/operations' import { sendSystemMail } from '@/services/notifications/email/send' -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' import type { Prisma } from '@prisma/client' diff --git a/src/services/events/tags/config.ts b/src/services/events/tags/constants.ts similarity index 100% rename from src/services/events/tags/config.ts rename to src/services/events/tags/constants.ts diff --git a/src/services/events/tags/operations.ts b/src/services/events/tags/operations.ts index 80983da1e..8dbf5f2a8 100644 --- a/src/services/events/tags/operations.ts +++ b/src/services/events/tags/operations.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { eventTagAuthers } from './authers' -import { specialEventTags } from './config' +import { specialEventTags } from './constants' import { eventTagSchemas } from './schemas' import { eventAuthers } from '@/services/events/authers' import logger from '@/lib/logger' diff --git a/src/services/groups/committees/config.ts b/src/services/groups/committees/constants.ts similarity index 93% rename from src/services/groups/committees/config.ts rename to src/services/groups/committees/constants.ts index 844f1f3c7..fd224b864 100644 --- a/src/services/groups/committees/config.ts +++ b/src/services/groups/committees/constants.ts @@ -1,4 +1,4 @@ -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import type { Prisma } from '@prisma/client' export const committeeLogoIncluder = { diff --git a/src/services/groups/committees/operations.ts b/src/services/groups/committees/operations.ts index 755a2713d..405c53fe3 100644 --- a/src/services/groups/committees/operations.ts +++ b/src/services/groups/committees/operations.ts @@ -1,5 +1,5 @@ import { committeeAuthers } from './authers' -import { committeeExpandedIncluder, committeeLogoIncluder, membershipIncluder } from './config' +import { committeeExpandedIncluder, committeeLogoIncluder, membershipIncluder } from './constants' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { articleRealtionsIncluder } from '@/cms/articles/ConfigVars' import { imageOperations } from '@/services/images/operations' diff --git a/src/services/groups/committees/read.ts b/src/services/groups/committees/read.ts index 7275d472b..ff799dc7f 100644 --- a/src/services/groups/committees/read.ts +++ b/src/services/groups/committees/read.ts @@ -3,7 +3,7 @@ import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { articleRealtionsIncluder } from '@/services/cms/articles/ConfigVars' import { imageOperations } from '@/services/images/operations' -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import type { ExpandedArticle } from '@/services/cms/articles/Types' import type { CmsParagraph } from '@prisma/client' import type { ExpandedCommittee, ExpandedCommitteeWithCover } from './Types' diff --git a/src/services/groups/config.ts b/src/services/groups/constants.ts similarity index 100% rename from src/services/groups/config.ts rename to src/services/groups/constants.ts diff --git a/src/services/groups/omegaMembershipGroups/update.ts b/src/services/groups/omegaMembershipGroups/update.ts index 728564eda..184d07eb5 100644 --- a/src/services/groups/omegaMembershipGroups/update.ts +++ b/src/services/groups/omegaMembershipGroups/update.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { readOmegaMembershipGroup, readUserOmegaMembershipLevel } from './read' -import { OMEGA_MEMBERSHIP_LEVEL_RANKING } from '@/services/groups/config' +import { OMEGA_MEMBERSHIP_LEVEL_RANKING } from '@/services/groups/constants' import { prisma } from '@/prisma/client' import { prismaCall } from '@/services/prismaCall' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' diff --git a/src/services/groups/operations.ts b/src/services/groups/operations.ts index 0036e2d29..aac34e84b 100644 --- a/src/services/groups/operations.ts +++ b/src/services/groups/operations.ts @@ -1,7 +1,7 @@ import '@pn-server-only' -import { groupsExpandedIncluder, groupTypesConfig, OmegaMembershipLevelConfig, readGroupsOfUserIncluder } from './config' +import { groupsExpandedIncluder, groupTypesConfig, OmegaMembershipLevelConfig, readGroupsOfUserIncluder } from './constants' import { groupAuthers } from './authers' -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' diff --git a/src/services/images/config.ts b/src/services/images/constants.ts similarity index 100% rename from src/services/images/config.ts rename to src/services/images/constants.ts diff --git a/src/services/images/operations.ts b/src/services/images/operations.ts index ff6067ca0..c2ecd0711 100644 --- a/src/services/images/operations.ts +++ b/src/services/images/operations.ts @@ -2,7 +2,7 @@ import '@pn-server-only' import { readSpecialImageCollection } from './collections/read' import { imageAuthers } from './authers' import { imageSchemas } from './schemas' -import { allowedExtensions, avifConvertionOptions, imageSizes } from './config' +import { allowedExtensions, avifConvertionOptions, imageSizes } from './constants' import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' import { createFile } from '@/services/store/createFile' diff --git a/src/services/images/schemas.ts b/src/services/images/schemas.ts index f7fa046b2..69579621a 100644 --- a/src/services/images/schemas.ts +++ b/src/services/images/schemas.ts @@ -1,4 +1,4 @@ -import { allowedExtensions, maxImageCountInOneBatch, maxImageFileSize } from './config' +import { allowedExtensions, maxImageCountInOneBatch, maxImageFileSize } from './constants' import { z } from 'zod' import { zfd } from 'zod-form-data' diff --git a/src/services/lockers/Types.ts b/src/services/lockers/Types.ts index b89f1e8a6..0069548ca 100644 --- a/src/services/lockers/Types.ts +++ b/src/services/lockers/Types.ts @@ -1,4 +1,4 @@ -import type { lockerReservationIncluder } from './reservations/config' +import type { lockerReservationIncluder } from './reservations/constants' import type { Prisma } from '@prisma/client' export type LockerWithReservation = Prisma.LockerGetPayload<{ diff --git a/src/services/lockers/locations/config.ts b/src/services/lockers/locations/constants.ts similarity index 100% rename from src/services/lockers/locations/config.ts rename to src/services/lockers/locations/constants.ts diff --git a/src/services/lockers/operations.ts b/src/services/lockers/operations.ts index dd6a9628e..ba28a8d1e 100644 --- a/src/services/lockers/operations.ts +++ b/src/services/lockers/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { lockerReservationIncluder } from './reservations/config' +import { lockerReservationIncluder } from './reservations/constants' import { lockersSchemas } from './schemas' import { lockerAuthers } from './authers' import { defineOperation } from '@/services/serviceOperation' diff --git a/src/services/lockers/reservations/config.ts b/src/services/lockers/reservations/constants.ts similarity index 100% rename from src/services/lockers/reservations/config.ts rename to src/services/lockers/reservations/constants.ts diff --git a/src/services/mail/read.ts b/src/services/mail/read.ts index 9a8eb1f33..68efce61c 100644 --- a/src/services/mail/read.ts +++ b/src/services/mail/read.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import { prismaCall } from '@/services/prismaCall' import { ServerError } from '@/services/error' import { prisma } from '@/prisma/client' diff --git a/src/services/notifications/Types.ts b/src/services/notifications/Types.ts index a35ae157e..1259db248 100644 --- a/src/services/notifications/Types.ts +++ b/src/services/notifications/Types.ts @@ -1,5 +1,5 @@ -import type { availableNotificationMethodIncluder } from './channel/config' -import type { notificationMethodsArray, notificationMethodTypes } from './config' +import type { availableNotificationMethodIncluder } from './channel/constants' +import type { notificationMethodsArray, notificationMethodTypes } from './constants' import type { Notification, NotificationMethod, Prisma } from '@prisma/client' export type NotificationMethodTypes = typeof notificationMethodTypes[number] diff --git a/src/services/notifications/channel/config.ts b/src/services/notifications/channel/constants.ts similarity index 95% rename from src/services/notifications/channel/config.ts rename to src/services/notifications/channel/constants.ts index 96bb0d3e6..0e5a52098 100644 --- a/src/services/notifications/channel/config.ts +++ b/src/services/notifications/channel/constants.ts @@ -1,4 +1,4 @@ -import { allNotificationMethodsOn } from '@/services/notifications/config' +import { allNotificationMethodsOn } from '@/services/notifications/constants' export const availableNotificationMethodIncluder = { availableMethods: { diff --git a/src/services/notifications/channel/operations.ts b/src/services/notifications/channel/operations.ts index c11ae7917..b4690ff1f 100644 --- a/src/services/notifications/channel/operations.ts +++ b/src/services/notifications/channel/operations.ts @@ -1,16 +1,16 @@ import '@pn-server-only' import { notificationChannelAuthers } from './authers' import { notificationChannelSchemas, validateMethods, validateNewParent } from './schemas' -import { availableNotificationMethodIncluder } from './config' +import { availableNotificationMethodIncluder } from './constants' import { allNotificationMethodsOff, allNotificationMethodsOn, notificationMethodsArray, -} from '@/services/notifications/config' +} from '@/services/notifications/constants' import { notificationMethodSchema } from '@/services/notifications/schemas' import { booleanOperationOnMethods } from '@/services/notifications/notificationMethodOperations' import { defineOperation } from '@/services/serviceOperation' -import { DEFAULT_NOTIFICATION_ALIAS } from '@/services/notifications/email/config' +import { DEFAULT_NOTIFICATION_ALIAS } from '@/services/notifications/email/constants' import { ServerError } from '@/services/error' import { z } from 'zod' import type { ExpandedNotificationChannel, NotificationMethodGeneral } from '@/services/notifications/Types' diff --git a/src/services/notifications/channel/schemas.ts b/src/services/notifications/channel/schemas.ts index 6e745edb5..0ff529606 100644 --- a/src/services/notifications/channel/schemas.ts +++ b/src/services/notifications/channel/schemas.ts @@ -1,5 +1,5 @@ -import { INFINITE_LOOP_PREVENTION_MAX_ITERATIONS } from './config' -import { notificationMethodsArray } from '@/services/notifications/config' +import { INFINITE_LOOP_PREVENTION_MAX_ITERATIONS } from './constants' +import { notificationMethodsArray } from '@/services/notifications/constants' import { SpecialNotificationChannel } from '@prisma/client' import { z } from 'zod' import type { diff --git a/src/services/notifications/config.ts b/src/services/notifications/constants.ts similarity index 100% rename from src/services/notifications/config.ts rename to src/services/notifications/constants.ts diff --git a/src/services/notifications/email/config.ts b/src/services/notifications/email/constants.ts similarity index 100% rename from src/services/notifications/email/config.ts rename to src/services/notifications/email/constants.ts diff --git a/src/services/notifications/email/dispatch.tsx b/src/services/notifications/email/dispatch.tsx index f0bf3d2af..2b899c859 100644 --- a/src/services/notifications/email/dispatch.tsx +++ b/src/services/notifications/email/dispatch.tsx @@ -1,5 +1,5 @@ import { sendBulkMail } from './send' -import { DEFAULT_NOTIFICATION_ALIAS } from './config' +import { DEFAULT_NOTIFICATION_ALIAS } from './constants' import { sendEmailValidation } from './validation' import { DefaultEmailTemplate } from './templates/default' import { repalceSpecialSymbols } from '@/services/notifications/operations' diff --git a/src/services/notifications/email/mailHandler.ts b/src/services/notifications/email/mailHandler.ts index e12cdee52..f064c20ce 100644 --- a/src/services/notifications/email/mailHandler.ts +++ b/src/services/notifications/email/mailHandler.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { TRANSPORT_OPTIONS } from './config' +import { TRANSPORT_OPTIONS } from './constants' import nodemailer from 'nodemailer' import type SMTPPool from 'nodemailer/lib/smtp-pool' import type SMTPTransport from 'nodemailer/lib/smtp-transport' diff --git a/src/services/notifications/notificationMethodOperations.ts b/src/services/notifications/notificationMethodOperations.ts index 57faa8626..2ee611a53 100644 --- a/src/services/notifications/notificationMethodOperations.ts +++ b/src/services/notifications/notificationMethodOperations.ts @@ -1,4 +1,4 @@ -import { allNotificationMethodsOff, allNotificationMethodsOn, notificationMethodsArray } from './config' +import { allNotificationMethodsOff, allNotificationMethodsOn, notificationMethodsArray } from './constants' import type { NotificationMethodGeneral } from './Types' export function newAllMethodsOff() { diff --git a/src/services/notifications/operations.ts b/src/services/notifications/operations.ts index 37ef398aa..5e2499984 100644 --- a/src/services/notifications/operations.ts +++ b/src/services/notifications/operations.ts @@ -2,9 +2,9 @@ import '@pn-server-only' import { dispatchEmailNotifications } from './email/dispatch' import { notificationAuthers } from './authers' import { notificationSchemas } from './schemas' -import { allNotificationMethodsOn, notificationMethodsArray } from './config' -import { availableNotificationMethodIncluder } from './channel/config' -import { userFilterSelection } from '@/services/users/config' +import { allNotificationMethodsOn, notificationMethodsArray } from './constants' +import { availableNotificationMethodIncluder } from './channel/constants' +import { userFilterSelection } from '@/services/users/constants' import { defineOperation } from '@/services/serviceOperation' import { ServerOnly } from '@/auth/auther/ServerOnly' import { z } from 'zod' diff --git a/src/services/notifications/subscription/Types.ts b/src/services/notifications/subscription/Types.ts index c345925ec..0c92d6134 100644 --- a/src/services/notifications/subscription/Types.ts +++ b/src/services/notifications/subscription/Types.ts @@ -1,4 +1,4 @@ -import type { notificationMethodIncluder } from './config' +import type { notificationMethodIncluder } from './constants' import type { Prisma } from '@prisma/client' diff --git a/src/services/notifications/subscription/config.ts b/src/services/notifications/subscription/constants.ts similarity index 95% rename from src/services/notifications/subscription/config.ts rename to src/services/notifications/subscription/constants.ts index eafc7128f..a0e223ef1 100644 --- a/src/services/notifications/subscription/config.ts +++ b/src/services/notifications/subscription/constants.ts @@ -1,4 +1,4 @@ -import { allNotificationMethodsOn } from '@/services/notifications/config' +import { allNotificationMethodsOn } from '@/services/notifications/constants' import type { Prisma } from '@prisma/client' export const notificationMethodIncluder = { diff --git a/src/services/notifications/subscription/operations.ts b/src/services/notifications/subscription/operations.ts index feadf8da2..9ad3b8fbc 100644 --- a/src/services/notifications/subscription/operations.ts +++ b/src/services/notifications/subscription/operations.ts @@ -1,9 +1,9 @@ -import { notificationMethodIncluder } from './config' +import { notificationMethodIncluder } from './constants' import { notificationSubscriptionAuthers } from './authers' import { subscriptionSchemas } from './schemas' import { validateMethods } from '@/services/notifications/channel/schemas' -import { allNotificationMethodsOff, allNotificationMethodsOn } from '@/services/notifications/config' -import { availableNotificationMethodIncluder } from '@/services/notifications/channel/config' +import { allNotificationMethodsOff, allNotificationMethodsOn } from '@/services/notifications/constants' +import { availableNotificationMethodIncluder } from '@/services/notifications/channel/constants' import { notificationChannelOperations } from '@/services/notifications/channel/operations' import { defineOperation } from '@/services/serviceOperation' import { ServerOnly } from '@/auth/auther/ServerOnly' diff --git a/src/services/permissions/Types.ts b/src/services/permissions/Types.ts index 2cd716bde..3e60402d9 100644 --- a/src/services/permissions/Types.ts +++ b/src/services/permissions/Types.ts @@ -1,4 +1,4 @@ -import type { permissionCategories } from './config' +import type { permissionCategories } from './constants' export type PermissionCategory = typeof permissionCategories[number] export type PermissionInfo = { diff --git a/src/services/permissions/config.ts b/src/services/permissions/constants.ts similarity index 100% rename from src/services/permissions/config.ts rename to src/services/permissions/constants.ts diff --git a/src/services/permissions/operations.ts b/src/services/permissions/operations.ts index cefd0871b..766996869 100644 --- a/src/services/permissions/operations.ts +++ b/src/services/permissions/operations.ts @@ -3,7 +3,7 @@ import { permissionAuthers } from './auther' import { defineOperation } from '@/services/serviceOperation' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { invalidateAllUserSessionData, invalidateManyUserSessionData } from '@/services/auth/invalidateSession' -import { groupsWithRelationsIncluder } from '@/services/groups/config' +import { groupsWithRelationsIncluder } from '@/services/groups/constants' import { checkGroupValidity, inferGroupName } from '@/services/groups/operations' import { Permission } from '@prisma/client' import { z } from 'zod' diff --git a/src/services/shop/purchase/operations.ts b/src/services/shop/purchase/operations.ts index 48a4eb65c..dcb7db579 100644 --- a/src/services/shop/purchase/operations.ts +++ b/src/services/shop/purchase/operations.ts @@ -5,7 +5,7 @@ import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' import { userOperations } from '@/services/users/operations' import { permissionOperations } from '@/services/permissions/operations' -import { userFilterSelection } from '@/services/users/config' +import { userFilterSelection } from '@/services/users/constants' import { PurchaseMethod } from '@prisma/client' export const purchaseOperations = { diff --git a/src/services/users/Types.ts b/src/services/users/Types.ts index c8b3cbfef..1eecbd53c 100644 --- a/src/services/users/Types.ts +++ b/src/services/users/Types.ts @@ -1,4 +1,4 @@ -import type { userFieldsToExpose } from './config' +import type { userFieldsToExpose } from './constants' import type { MembershipFiltered } from '@/services/groups/memberships/Types' import type { OmegaMembershipLevel, User, Image, Permission } from '@prisma/client' diff --git a/src/services/users/config.ts b/src/services/users/constants.ts similarity index 100% rename from src/services/users/config.ts rename to src/services/users/constants.ts diff --git a/src/services/users/operations.ts b/src/services/users/operations.ts index 997d32789..40ae367fd 100644 --- a/src/services/users/operations.ts +++ b/src/services/users/operations.ts @@ -6,7 +6,7 @@ import { standardMembershipSelection, studentCardRegistrationExpiry, userFilterSelection -} from './config' +} from './constants' import { imageOperations } from '@/services/images/operations' import { notificationSubscriptionOperations } from '@/services/notifications/subscription/operations' import { readMembershipsOfUser } from '@/services/groups/memberships/read' diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index f4361b24d..7e1eb1aee 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -3,7 +3,7 @@ import { createActionError, safeServerCall } from '@/services/actionError' import { checkVisibility } from '@/auth/checkVisibility' import { getUser } from '@/auth/getUser' -import { groupTypesConfig } from '@/services/groups/config' +import { groupTypesConfig } from '@/services/groups/constants' import { groupOperations } from '@/services/groups/operations' import { purposeTextsConfig } from '@/services/visibility/ConfigVars' import { readVisibilityCollapsed } from '@/services/visibility/read' From 831065cda201ce8362f5e872dd585f61b28d6214 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sat, 11 Oct 2025 01:50:45 +0200 Subject: [PATCH 21/24] refactor: action -> makeAction and remove data guarantee --- .../EditableTextField/EditableTextField.tsx | 8 ++-- src/app/_components/Form/Form.tsx | 10 ++--- .../Form/{ConfigVars.ts => constants.ts} | 0 src/app/_components/Image/ImageUploader.tsx | 2 +- src/app/redirectToErrorPage.ts | 9 +--- .../notifications/notificationSettings.tsx | 2 +- src/auth/getUser.ts | 4 +- src/auth/useUser.ts | 4 +- src/contexts/paging/PagingGenerator.tsx | 8 ++-- src/hooks/useActionCall.ts | 7 ++- src/hooks/useEditing.ts | 2 +- src/{utils => lib}/checkMatrix.ts | 0 src/lib/jwt/jwt.ts | 2 +- src/lib/jwt/parseJWTClient.ts | 2 +- src/services/actionError.ts | 8 ++-- src/services/actionTypes.ts | 30 +++++++------ src/services/admission/actions.ts | 4 +- src/services/api-keys/actions.ts | 12 ++--- src/services/applications/actions.ts | 10 ++--- src/services/applications/periods/actions.ts | 16 +++---- src/services/auth/actions.ts | 10 ++--- src/services/cabin/actions.ts | 44 +++++++++---------- src/services/career/companies/actions.ts | 10 ++--- src/services/career/jobAds/actions.ts | 14 +++--- src/services/cms/links/actions.ts | 4 +- src/services/dots/actions.ts | 8 ++-- src/services/events/actions.ts | 14 +++--- src/services/events/registration/actions.ts | 14 +++--- src/services/events/tags/actions.ts | 14 +++--- src/services/groups/actions.ts | 10 ++--- src/services/groups/committees/actions.ts | 12 ++--- src/services/groups/interestGroups/actions.ts | 10 ++--- src/services/images/actions.ts | 16 +++---- src/services/licenses/actions.ts | 10 ++--- src/services/lockers/actions.ts | 16 +++---- src/services/notifications/actions.ts | 14 +++--- src/services/omegaid/compress.ts | 4 +- src/services/permissions/actions.ts | 12 ++--- src/services/{action.ts => serverAction.ts} | 10 ++--- src/services/shop/actions.ts | 22 +++++----- src/services/users/actions.ts | 22 +++++----- src/services/visibility/Types.ts | 2 +- 42 files changed, 214 insertions(+), 218 deletions(-) rename src/app/_components/Form/{ConfigVars.ts => constants.ts} (100%) rename src/{utils => lib}/checkMatrix.ts (100%) rename src/services/{action.ts => serverAction.ts} (90%) diff --git a/src/app/_components/EditableTextField/EditableTextField.tsx b/src/app/_components/EditableTextField/EditableTextField.tsx index 5f3e488b8..5f57d24db 100644 --- a/src/app/_components/EditableTextField/EditableTextField.tsx +++ b/src/app/_components/EditableTextField/EditableTextField.tsx @@ -8,11 +8,11 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faPencil } from '@fortawesome/free-solid-svg-icons' import type { PropTypes as FormPropTypes } from '@/components/Form/Form' -type PropTypes = { +type PropTypes = { props?: Omit, 'children' | 'contentEditable'> editable: boolean, children: React.ReactNode, - formProps: Omit, 'title' | 'children' | 'submitText'> + formProps: Omit, 'title' | 'children' | 'submitText'> inputName: string, submitButton: { text: string, @@ -28,14 +28,14 @@ type PropTypes = { * @param submitButton - The props to pass to the submit button * @param props - further props to pass to the text element */ -export default function EditableTextField({ +export default function EditableTextField({ editable, children, formProps, submitButton, inputName, ...props -}: PropTypes +}: PropTypes ) { const [value, setValue] = useState('') const [noChange, setNoChange] = useState(true) diff --git a/src/app/_components/Form/Form.tsx b/src/app/_components/Form/Form.tsx index 124ab7f24..aaac3a3d8 100644 --- a/src/app/_components/Form/Form.tsx +++ b/src/app/_components/Form/Form.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './Form.module.scss' -import { SUCCESS_FEEDBACK_TIME } from './ConfigVars' +import { SUCCESS_FEEDBACK_TIME } from './constants' import { PopUpContext } from '@/contexts/PopUp' import SubmitButton from '@/components/UI/SubmitButton' import React, { Children, useContext, useEffect, useState } from 'react' @@ -13,13 +13,13 @@ import type { Action } from '@/services/actionTypes' import type { ErrorMessage } from '@/services/error' type FormType = DetailedHTMLProps, HTMLFormElement> -export type PropTypes = Omit & { +export type PropTypes = Omit & { children?: ReactNode, title?: string, submitText?: string, submitColor?: Colors, confirmation?: Confirmation, - action: Action, + action: Action, successCallback?: (data?: ReturnType) => void, refreshOnSuccess?: boolean, navigateOnSuccess?: string | ((data?: ReturnType) => string | null), @@ -62,7 +62,7 @@ const makeInputArray = (children: ReactNode): Inputs => } }) -export default function Form({ +export default function Form({ children, title, submitText = 'create', @@ -78,7 +78,7 @@ export default function Form({ closePopUpOnSuccess, buttonClassName, ...props -}: PropTypes) { +}: PropTypes) { const [generalErrors, setGeneralErrors] = useState() const [inputs, setInputs] = useState(makeInputArray(children)) const [success, setSuccess] = useState(false) diff --git a/src/app/_components/Form/ConfigVars.ts b/src/app/_components/Form/constants.ts similarity index 100% rename from src/app/_components/Form/ConfigVars.ts rename to src/app/_components/Form/constants.ts diff --git a/src/app/_components/Image/ImageUploader.tsx b/src/app/_components/Image/ImageUploader.tsx index 435eabc73..57dbc0413 100644 --- a/src/app/_components/Image/ImageUploader.tsx +++ b/src/app/_components/Image/ImageUploader.tsx @@ -9,7 +9,7 @@ import type { PropTypes as FormPropTypes } from '@/components/Form/Form' type ResponseType = Awaited>; type T = Pick['data'] -type PropTypes = Omit, 'action' | 'submitText' | 'title'> & { +type PropTypes = Omit, 'action' | 'submitText' | 'title'> & { collectionId: number, } diff --git a/src/app/redirectToErrorPage.ts b/src/app/redirectToErrorPage.ts index e6ee067af..b5c816e3a 100644 --- a/src/app/redirectToErrorPage.ts +++ b/src/app/redirectToErrorPage.ts @@ -24,14 +24,7 @@ export function redirectToErrorPage(code: ErrorCode, message?: string | undefine */ export function unwrapActionReturn< Data, ->(actionReturn: ActionReturn): Data -export function unwrapActionReturn< - Data, ->(actionReturn: ActionReturn): Data | undefined -export function unwrapActionReturn< - Data, - const DataGuarantee extends boolean, ->(actionReturn: ActionReturn): Data | undefined { +>(actionReturn: ActionReturn): Data { if (!actionReturn.success) { redirectToErrorPage(actionReturn.errorCode, actionReturn.error?.length ? actionReturn.error[0].message : undefined) } diff --git a/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx b/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx index 8efe9ad76..43055af17 100644 --- a/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx +++ b/src/app/users/[username]/(user-admin)/notifications/notificationSettings.tsx @@ -4,7 +4,7 @@ import SubscriptionItem from './subscriptionItem' import styles from './notificationSettings.module.scss' import { booleanOperationOnMethods, newAllMethodsOff } from '@/services/notifications/notificationMethodOperations' import SubmitButton from '@/components/UI/SubmitButton' -import { SUCCESS_FEEDBACK_TIME } from '@/components/Form/ConfigVars' +import { SUCCESS_FEEDBACK_TIME } from '@/components/Form/constants' import { updateNotificationSubscriptionsAction } from '@/services/notifications/actions' import { notificationMethodsArray, notificationMethodsDisplayMap } from '@/services/notifications/constants' import { v4 as uuid } from 'uuid' diff --git a/src/auth/getUser.ts b/src/auth/getUser.ts index 3e728c66d..0c94f60e2 100644 --- a/src/auth/getUser.ts +++ b/src/auth/getUser.ts @@ -1,10 +1,10 @@ import '@pn-server-only' import { authOptions } from './authoptions' -import checkMatrix from '@/utils/checkMatrix' +import checkMatrix from '@/lib/checkMatrix' import { permissionOperations } from '@/services/permissions/operations' import { getServerSession } from 'next-auth' import { notFound, redirect } from 'next/navigation' -import type { Matrix } from '@/utils/checkMatrix' +import type { Matrix } from '@/lib/checkMatrix' import type { Permission } from '@prisma/client' import type { MembershipFiltered } from '@/services/groups/memberships/Types' import type { UserFiltered } from '@/services/users/Types' diff --git a/src/auth/useUser.ts b/src/auth/useUser.ts index 130c2254b..9b32694e5 100644 --- a/src/auth/useUser.ts +++ b/src/auth/useUser.ts @@ -1,13 +1,13 @@ 'use client' import { DefaultPermissionsContext } from '@/contexts/DefaultPermissions' -import checkMatrix from '@/utils/checkMatrix' +import checkMatrix from '@/lib/checkMatrix' import { useSession } from 'next-auth/react' import { usePathname, useRouter } from 'next/navigation' import { useContext, useEffect, useState } from 'react' import type { Permission } from '@prisma/client' import type { UserFiltered } from '@/services/users/Types' -import type { Matrix } from '@/utils/checkMatrix' +import type { Matrix } from '@/lib/checkMatrix' import type { MembershipFiltered } from '@/services/groups/memberships/Types' // SessionProvider needs to be exported from a 'use client' file so that it can diff --git a/src/contexts/paging/PagingGenerator.tsx b/src/contexts/paging/PagingGenerator.tsx index 68c094e1d..eb71f58b7 100644 --- a/src/contexts/paging/PagingGenerator.tsx +++ b/src/contexts/paging/PagingGenerator.tsx @@ -29,8 +29,8 @@ export type PropTypes = { serverRenderedData: Data[], } -export type GeneratorPropTypes = { - fetcher: (x: ReadPageInput) => Promise>, +export type GeneratorPropTypes = { + fetcher: (x: ReadPageInput) => Promise>, Context: PagingContextType, getCursorAfterFetch: (data: Data[]) => Cursor | null, } @@ -44,11 +44,11 @@ export type GeneratorPropTypes({ +function generatePagingProvider({ fetcher, Context, getCursorAfterFetch, -}: GeneratorPropTypes +}: GeneratorPropTypes ) { return function PagingProvider( { serverRenderedData, startPage, children, details: givenDetails }: PropTypes diff --git a/src/hooks/useActionCall.ts b/src/hooks/useActionCall.ts index 090974758..63122f29c 100644 --- a/src/hooks/useActionCall.ts +++ b/src/hooks/useActionCall.ts @@ -1,7 +1,7 @@ 'use client' import { createActionError } from '@/services/actionError' import { useState, useEffect } from 'react' -import type { ActionReturn, ActionReturnError } from '@/services/actionTypes' +import type { ActionReturn, ActionError } from '@/services/actionTypes' /** * You sometimes want to call a server action that reads from the client. This hook helps with that. @@ -10,16 +10,15 @@ import type { ActionReturn, ActionReturnError } from '@/services/actionTypes' */ export default function useActionCall< Data, - DataGuarantee extends true >( - action: () => Promise> + action: () => Promise> ) { const [res, setRes] = useState<{ data: Data | null, error: null } | { data: null, - error: ActionReturnError + error: ActionError }>({ data: null, error: null diff --git a/src/hooks/useEditing.ts b/src/hooks/useEditing.ts index ce6e33c37..6a570afa9 100644 --- a/src/hooks/useEditing.ts +++ b/src/hooks/useEditing.ts @@ -5,7 +5,7 @@ import { checkVisibility } from '@/auth/checkVisibility' import { useContext, useEffect, useRef, useState } from 'react' import { v4 as uuid } from 'uuid' import type { Permission } from '@prisma/client' -import type { Matrix } from '@/utils/checkMatrix' +import type { Matrix } from '@/lib/checkMatrix' import type { VisibilityCollapsed, VisibilityLevelType } from '@/services/visibility/Types' /** diff --git a/src/utils/checkMatrix.ts b/src/lib/checkMatrix.ts similarity index 100% rename from src/utils/checkMatrix.ts rename to src/lib/checkMatrix.ts diff --git a/src/lib/jwt/jwt.ts b/src/lib/jwt/jwt.ts index cbcf3187d..057796b4f 100644 --- a/src/lib/jwt/jwt.ts +++ b/src/lib/jwt/jwt.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { readJWTPart } from './jwtReadUnsecure' -import { JWT_ISSUER } from '@/jwt/ConfigVars' +import { JWT_ISSUER } from '@/lib/jwt/ConfigVars' import { ServerError } from '@/services/error' import { JsonWebTokenError, TokenExpiredError, sign, verify } from 'jsonwebtoken' import type jwt from 'jsonwebtoken' diff --git a/src/lib/jwt/parseJWTClient.ts b/src/lib/jwt/parseJWTClient.ts index 2cd64d5b4..6f8d79bc8 100644 --- a/src/lib/jwt/parseJWTClient.ts +++ b/src/lib/jwt/parseJWTClient.ts @@ -2,7 +2,7 @@ import { readJWTPayload } from './jwtReadUnsecure' import { createActionError } from '@/services/actionError' -import { JWT_ISSUER } from '@/jwt/ConfigVars' +import { JWT_ISSUER } from '@/lib/jwt/ConfigVars' import type { OmegaJWTAudience } from '@/jwt/Types' import type { ActionReturn } from '@/services/actionTypes' diff --git a/src/services/actionError.ts b/src/services/actionError.ts index f30e91070..c3d332f05 100644 --- a/src/services/actionError.ts +++ b/src/services/actionError.ts @@ -2,13 +2,13 @@ import { errorCodes, type ErrorCode, type ErrorMessage } from '@/services/error' import { ParseError, Smorekopp } from '@/services/error' import type { AuthStatus } from '@/auth/getUser' import type { SafeParseError } from 'zod' -import type { ActionReturnError, ActionReturn } from './actionTypes' +import type { ActionError, ActionReturn } from './actionTypes' /** * @deprecated With the "new" service method system this should not be called directly. * The action creation utility should handle this internally. */ -export function createActionError(errorCode: ErrorCode | AuthStatus, error?: string | ErrorMessage[]): ActionReturnError { +export function createActionError(errorCode: ErrorCode | AuthStatus, error?: string | ErrorMessage[]): ActionError { if (errorCode === 'AUTHORIZED' || errorCode === 'AUTHORIZED_NO_USER') { return { success: false, @@ -29,7 +29,7 @@ export function createActionError(errorCode: ErrorCode | AuthStatus, error?: str * @deprecated With the "new" service method system this should not be called directly. * The action creation utility should handle this internally. */ -export function createZodActionError(parse: SafeParseError): ActionReturnError { +export function createZodActionError(parse: SafeParseError): ActionError { return { success: false, httpCode: 400, @@ -50,7 +50,7 @@ export async function safeServerCall(call: () => Promise): Promise = ( - ActionReturnError -) | { +/** + * The return type of an action on success. + */ +export type ActionData = { success: true, -} & ( - DataGuarantee extends true ? { - data: ReturnType - } : { - data?: ReturnType - } -) + data: T, +} + +/** + * The return type of an action. Either success with data or error with error info. + */ +export type ActionReturn = ActionData | ActionError -export type Action = (formData: FormData) => ( - Promise> +export type Action = (formData: FormData) => ( + Promise> ) diff --git a/src/services/admission/actions.ts b/src/services/admission/actions.ts index 5da8a9206..0e7f18af7 100644 --- a/src/services/admission/actions.ts +++ b/src/services/admission/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { admissionOperations } from '@/services/admission/operations' -export const createAdmissionTrialAction = action(admissionOperations.createTrial) +export const createAdmissionTrialAction = makeAction(admissionOperations.createTrial) diff --git a/src/services/api-keys/actions.ts b/src/services/api-keys/actions.ts index 2fbe460cc..9bb80c72a 100644 --- a/src/services/api-keys/actions.ts +++ b/src/services/api-keys/actions.ts @@ -1,13 +1,13 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { apiKeyOperations } from '@/services/api-keys/operations' -export const createApiKeyAction = action(apiKeyOperations.create) +export const createApiKeyAction = makeAction(apiKeyOperations.create) -export const destroyApiKeyAction = action(apiKeyOperations.destroy) +export const destroyApiKeyAction = makeAction(apiKeyOperations.destroy) -export const readApiKeysAction = action(apiKeyOperations.readMany) -export const readApiKeyAction = action(apiKeyOperations.read) +export const readApiKeysAction = makeAction(apiKeyOperations.readMany) +export const readApiKeyAction = makeAction(apiKeyOperations.read) -export const updateApiKeyAction = action(apiKeyOperations.update) +export const updateApiKeyAction = makeAction(apiKeyOperations.update) diff --git a/src/services/applications/actions.ts b/src/services/applications/actions.ts index 8dd7e0d1d..0c9cd3932 100644 --- a/src/services/applications/actions.ts +++ b/src/services/applications/actions.ts @@ -1,12 +1,12 @@ 'use server' import { applicationOperations } from './operations' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' -export const createApplicationAction = action(applicationOperations.create) +export const createApplicationAction = makeAction(applicationOperations.create) -export const destroyApplicationAction = action(applicationOperations.destroy) +export const destroyApplicationAction = makeAction(applicationOperations.destroy) -export const readApplicationsForUserAction = action(applicationOperations.readForUser) +export const readApplicationsForUserAction = makeAction(applicationOperations.readForUser) -export const updateApplicationAction = action(applicationOperations.update) +export const updateApplicationAction = makeAction(applicationOperations.update) diff --git a/src/services/applications/periods/actions.ts b/src/services/applications/periods/actions.ts index 2710e64c1..e9003ad4b 100644 --- a/src/services/applications/periods/actions.ts +++ b/src/services/applications/periods/actions.ts @@ -1,15 +1,15 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { applicationPeriodOperations } from '@/services/applications/periods/operations' -export const createApplicationPeriodAction = action(applicationPeriodOperations.create) +export const createApplicationPeriodAction = makeAction(applicationPeriodOperations.create) -export const destroyApplicationPeriodAction = action(applicationPeriodOperations.destroy) -export const removeAllApplicationTextsAction = action(applicationPeriodOperations.removeAllApplicationTexts) +export const destroyApplicationPeriodAction = makeAction(applicationPeriodOperations.destroy) +export const removeAllApplicationTextsAction = makeAction(applicationPeriodOperations.removeAllApplicationTexts) -export const readApplicationPeriodsAction = action(applicationPeriodOperations.readAll) -export const readApplicationPeriodAction = action(applicationPeriodOperations.read) -export const readNumberOfApplicationsAction = action(applicationPeriodOperations.readNumberOfApplications) +export const readApplicationPeriodsAction = makeAction(applicationPeriodOperations.readAll) +export const readApplicationPeriodAction = makeAction(applicationPeriodOperations.read) +export const readNumberOfApplicationsAction = makeAction(applicationPeriodOperations.readNumberOfApplications) -export const updateApplicationPeriodAction = action(applicationPeriodOperations.update) +export const updateApplicationPeriodAction = makeAction(applicationPeriodOperations.update) diff --git a/src/services/auth/actions.ts b/src/services/auth/actions.ts index 5b489325d..a2944f8d1 100644 --- a/src/services/auth/actions.ts +++ b/src/services/auth/actions.ts @@ -1,9 +1,9 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { authOperations } from '@/services/auth/operations' -export const verifyResetPasswordTokenAction = action(authOperations.verifyResetPasswordToken) -export const resetPasswordAction = action(authOperations.resetPassword) -export const sendResetPasswordEmailAction = action(authOperations.sendResetPasswordEmail) -export const verifyEmailAction = action(authOperations.verifyEmail) +export const verifyResetPasswordTokenAction = makeAction(authOperations.verifyResetPasswordToken) +export const resetPasswordAction = makeAction(authOperations.resetPassword) +export const sendResetPasswordEmailAction = makeAction(authOperations.sendResetPasswordEmail) +export const verifyEmailAction = makeAction(authOperations.verifyEmail) diff --git a/src/services/cabin/actions.ts b/src/services/cabin/actions.ts index dd2896965..cbff4f407 100644 --- a/src/services/cabin/actions.ts +++ b/src/services/cabin/actions.ts @@ -4,29 +4,29 @@ import { cabinReleasePeriodOperations } from './releasePeriod/operations' import { cabinPricePeriodOperations } from './pricePeriod/operations' import { cabinBookingOperations } from './booking/operations' import { cabinProductOperations } from './product/operations' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' -export const createReleasePeriodAction = action(cabinReleasePeriodOperations.create) -export const readReleasePeriodsAction = action(cabinReleasePeriodOperations.readMany) -export const updateReleasePeriodAction = action(cabinReleasePeriodOperations.update) -export const destroyReleasePeriodAction = action(cabinReleasePeriodOperations.destroy) +export const createReleasePeriodAction = makeAction(cabinReleasePeriodOperations.create) +export const readReleasePeriodsAction = makeAction(cabinReleasePeriodOperations.readMany) +export const updateReleasePeriodAction = makeAction(cabinReleasePeriodOperations.update) +export const destroyReleasePeriodAction = makeAction(cabinReleasePeriodOperations.destroy) -export const createPricePeriodAction = action(cabinPricePeriodOperations.create) -export const destoryPricePeriodAction = action(cabinPricePeriodOperations.destroy) -export const readPricePeriodsAction = action(cabinPricePeriodOperations.readMany) -export const readPublicPricePeriodsAction = action(cabinPricePeriodOperations.readPublicPeriods) -export const readUnreleasedPricePeriodsAction = action(cabinPricePeriodOperations.readUnreleasedPeriods) +export const createPricePeriodAction = makeAction(cabinPricePeriodOperations.create) +export const destoryPricePeriodAction = makeAction(cabinPricePeriodOperations.destroy) +export const readPricePeriodsAction = makeAction(cabinPricePeriodOperations.readMany) +export const readPublicPricePeriodsAction = makeAction(cabinPricePeriodOperations.readPublicPeriods) +export const readUnreleasedPricePeriodsAction = makeAction(cabinPricePeriodOperations.readUnreleasedPeriods) -export const createCabinBookingUserAttachedAction = action(cabinBookingOperations.createCabinBookingUserAttached) -export const createBedBookingUserAttachedAction = action(cabinBookingOperations.createBedBookingUserAttached) -export const createCabinBookingNoUserAction = action(cabinBookingOperations.createCabinBookingNoUser) -export const createBedBookingNoUserAction = action(cabinBookingOperations.createBedBookingNoUser) -export const readCabinAvailabilityAction = action(cabinBookingOperations.readAvailability) -export const readCabinBookingsAction = action(cabinBookingOperations.readMany) -export const readCabinBookingAction = action(cabinBookingOperations.read) +export const createCabinBookingUserAttachedAction = makeAction(cabinBookingOperations.createCabinBookingUserAttached) +export const createBedBookingUserAttachedAction = makeAction(cabinBookingOperations.createBedBookingUserAttached) +export const createCabinBookingNoUserAction = makeAction(cabinBookingOperations.createCabinBookingNoUser) +export const createBedBookingNoUserAction = makeAction(cabinBookingOperations.createBedBookingNoUser) +export const readCabinAvailabilityAction = makeAction(cabinBookingOperations.readAvailability) +export const readCabinBookingsAction = makeAction(cabinBookingOperations.readMany) +export const readCabinBookingAction = makeAction(cabinBookingOperations.read) -export const readCabinProductsAction = action(cabinProductOperations.readMany) -export const readCabinProductsActiveAction = action(cabinProductOperations.readActive) -export const readCabinProductAction = action(cabinProductOperations.read) -export const createCabinProductAction = action(cabinProductOperations.create) -export const createCabinProductPriceAction = action(cabinProductOperations.createPrice) +export const readCabinProductsAction = makeAction(cabinProductOperations.readMany) +export const readCabinProductsActiveAction = makeAction(cabinProductOperations.readActive) +export const readCabinProductAction = makeAction(cabinProductOperations.read) +export const createCabinProductAction = makeAction(cabinProductOperations.create) +export const createCabinProductPriceAction = makeAction(cabinProductOperations.createPrice) diff --git a/src/services/career/companies/actions.ts b/src/services/career/companies/actions.ts index a60517af2..307bda7ec 100644 --- a/src/services/career/companies/actions.ts +++ b/src/services/career/companies/actions.ts @@ -1,12 +1,12 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { companyOperations } from '@/services/career/companies/operations' -export const createCompanyAction = action(companyOperations.create) +export const createCompanyAction = makeAction(companyOperations.create) -export const destroyCompanyAction = action(companyOperations.destroy) +export const destroyCompanyAction = makeAction(companyOperations.destroy) -export const readCompanyPageAction = action(companyOperations.readPage) +export const readCompanyPageAction = makeAction(companyOperations.readPage) -export const updateComanyAction = action(companyOperations.update) +export const updateComanyAction = makeAction(companyOperations.update) diff --git a/src/services/career/jobAds/actions.ts b/src/services/career/jobAds/actions.ts index 336929616..040ae8daf 100644 --- a/src/services/career/jobAds/actions.ts +++ b/src/services/career/jobAds/actions.ts @@ -1,14 +1,14 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { jobAdOperations } from '@/services/career/jobAds/operations' -export const createJobAdAction = action(jobAdOperations.create) +export const createJobAdAction = makeAction(jobAdOperations.create) -export const destroyJobAdAction = action(jobAdOperations.destroy) +export const destroyJobAdAction = makeAction(jobAdOperations.destroy) -export const readJobAdAction = action(jobAdOperations.read) -export const readActiveJobAdsAction = action(jobAdOperations.readActive) -export const readInactiveJobAdsPageAction = action(jobAdOperations.readInactivePage) +export const readJobAdAction = makeAction(jobAdOperations.read) +export const readActiveJobAdsAction = makeAction(jobAdOperations.readActive) +export const readInactiveJobAdsPageAction = makeAction(jobAdOperations.readInactivePage) -export const updateJobAdAction = action(jobAdOperations.update) +export const updateJobAdAction = makeAction(jobAdOperations.update) diff --git a/src/services/cms/links/actions.ts b/src/services/cms/links/actions.ts index 4dcf21866..163bfe625 100644 --- a/src/services/cms/links/actions.ts +++ b/src/services/cms/links/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { createZodActionError, safeServerCall } from '@/services/actionError' import { createCmsLink } from '@/services/cms/links/create' import { readSpecialCmsLink } from '@/services/cms/links/read' @@ -21,7 +21,7 @@ export async function createCmsLinkAction( return await safeServerCall(() => createCmsLink(data)) } -export const readSpecialCmsLinkAction = action(readSpecialCmsLink) +export const readSpecialCmsLinkAction = makeAction(readSpecialCmsLink) export async function updateCmsLinkAction( id: number, diff --git a/src/services/dots/actions.ts b/src/services/dots/actions.ts index d046ce520..d7a2bfcae 100644 --- a/src/services/dots/actions.ts +++ b/src/services/dots/actions.ts @@ -1,10 +1,10 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { dotOperations } from '@/services/dots/operations' -export const createDotAction = action(dotOperations.create) +export const createDotAction = makeAction(dotOperations.create) -export const readDotPageAction = action(dotOperations.readPage) +export const readDotPageAction = makeAction(dotOperations.readPage) -export const readDotWrappersForUserAction = action(dotOperations.readWrappersForUser) +export const readDotWrappersForUserAction = makeAction(dotOperations.readWrappersForUser) diff --git a/src/services/events/actions.ts b/src/services/events/actions.ts index 3b8c8d1f4..0ecb22161 100644 --- a/src/services/events/actions.ts +++ b/src/services/events/actions.ts @@ -1,14 +1,14 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { eventOperations } from '@/services/events/operations' -export const createEventAction = action(eventOperations.create) +export const createEventAction = makeAction(eventOperations.create) -export const destroyEventAction = action(eventOperations.destroy) +export const destroyEventAction = makeAction(eventOperations.destroy) -export const readCurrentEventsAction = action(eventOperations.readManyCurrent) -export const readEventAction = action(eventOperations.read) -export const readArchivedEventsPageAction = action(eventOperations.readManyArchivedPage) +export const readCurrentEventsAction = makeAction(eventOperations.readManyCurrent) +export const readEventAction = makeAction(eventOperations.read) +export const readArchivedEventsPageAction = makeAction(eventOperations.readManyArchivedPage) -export const updateEventAction = action(eventOperations.update) +export const updateEventAction = makeAction(eventOperations.update) diff --git a/src/services/events/registration/actions.ts b/src/services/events/registration/actions.ts index d60f746f3..108850041 100644 --- a/src/services/events/registration/actions.ts +++ b/src/services/events/registration/actions.ts @@ -1,11 +1,11 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { eventRegistrationOperations } from '@/services/events/registration/operations' -export const createEventRegistrationAction = action(eventRegistrationOperations.create) -export const createGuestEventRegistrationAction = action(eventRegistrationOperations.createGuest) -export const readManyEventRegistrationAction = action(eventRegistrationOperations.readMany) -export const eventRegistrationReadManyDetailedAction = action(eventRegistrationOperations.readManyDetailed) -export const eventRegistrationUpdateNotesAction = action(eventRegistrationOperations.updateNotes) -export const eventRegistrationDestroyAction = action(eventRegistrationOperations.destroy) +export const createEventRegistrationAction = makeAction(eventRegistrationOperations.create) +export const createGuestEventRegistrationAction = makeAction(eventRegistrationOperations.createGuest) +export const readManyEventRegistrationAction = makeAction(eventRegistrationOperations.readMany) +export const eventRegistrationReadManyDetailedAction = makeAction(eventRegistrationOperations.readManyDetailed) +export const eventRegistrationUpdateNotesAction = makeAction(eventRegistrationOperations.updateNotes) +export const eventRegistrationDestroyAction = makeAction(eventRegistrationOperations.destroy) diff --git a/src/services/events/tags/actions.ts b/src/services/events/tags/actions.ts index 48427a93c..76e3bc0f4 100644 --- a/src/services/events/tags/actions.ts +++ b/src/services/events/tags/actions.ts @@ -1,14 +1,14 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { eventTagOperations } from '@/services/events/tags/operations' -export const createEventTagAction = action(eventTagOperations.create) +export const createEventTagAction = makeAction(eventTagOperations.create) -export const destroyEventTagAction = action(eventTagOperations.destroy) +export const destroyEventTagAction = makeAction(eventTagOperations.destroy) -export const readEventTagsAction = action(eventTagOperations.readAll) -export const readSpecialEventTagAction = action(eventTagOperations.readSpecial) -export const readEventTagAction = action(eventTagOperations.read) +export const readEventTagsAction = makeAction(eventTagOperations.readAll) +export const readSpecialEventTagAction = makeAction(eventTagOperations.readSpecial) +export const readEventTagAction = makeAction(eventTagOperations.read) -export const updateEventTagAction = action(eventTagOperations.update) +export const updateEventTagAction = makeAction(eventTagOperations.update) diff --git a/src/services/groups/actions.ts b/src/services/groups/actions.ts index 9bb271916..04b2847fe 100644 --- a/src/services/groups/actions.ts +++ b/src/services/groups/actions.ts @@ -1,9 +1,9 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { groupOperations } from '@/services/groups/operations' -export const readGroupsAction = action(groupOperations.readGroups) -export const readGroupExpandedAction = action(groupOperations.readGroupExpanded) -export const readGroupsExpandedAction = action(groupOperations.readGroupsExpanded) -export const readGroupsStructuredAction = action(groupOperations.readGroupsStructured) +export const readGroupsAction = makeAction(groupOperations.readGroups) +export const readGroupExpandedAction = makeAction(groupOperations.readGroupExpanded) +export const readGroupsExpandedAction = makeAction(groupOperations.readGroupsExpanded) +export const readGroupsStructuredAction = makeAction(groupOperations.readGroupsStructured) diff --git a/src/services/groups/committees/actions.ts b/src/services/groups/committees/actions.ts index 9c74d0cbf..e293b8d52 100644 --- a/src/services/groups/committees/actions.ts +++ b/src/services/groups/committees/actions.ts @@ -1,6 +1,6 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { getUser } from '@/auth/getUser' import { createCommittee } from '@/services/groups/committees/create' @@ -27,11 +27,11 @@ export async function createCommitteeAction( return await safeServerCall(() => createCommittee(parse.data)) } -export const readCommitteesAction = action(committeeOperations.readCommittees) -export const readCommitteeAction = action(committeeOperations.readCommittee) -export const readCommitteeArticleAction = action(committeeOperations.readCommitteArticle) -export const readCommitteeParagraphAction = action(committeeOperations.readCommitteeParagraph) -export const readCommitteeMembersAction = action(committeeOperations.readCommitteeMembers) +export const readCommitteesAction = makeAction(committeeOperations.readCommittees) +export const readCommitteeAction = makeAction(committeeOperations.readCommittee) +export const readCommitteeArticleAction = makeAction(committeeOperations.readCommitteArticle) +export const readCommitteeParagraphAction = makeAction(committeeOperations.readCommitteeParagraph) +export const readCommitteeMembersAction = makeAction(committeeOperations.readCommitteeMembers) export async function updateCommitteeAction( id: number, diff --git a/src/services/groups/interestGroups/actions.ts b/src/services/groups/interestGroups/actions.ts index b1fd43586..3ff7cac45 100644 --- a/src/services/groups/interestGroups/actions.ts +++ b/src/services/groups/interestGroups/actions.ts @@ -1,12 +1,12 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { interestGroupOperations } from '@/services/groups/interestGroups/operations' -export const createInterestGroupAction = action(interestGroupOperations.create) +export const createInterestGroupAction = makeAction(interestGroupOperations.create) -export const destroyInterestGroupAction = action(interestGroupOperations.destroy) +export const destroyInterestGroupAction = makeAction(interestGroupOperations.destroy) -export const readInterestGroupsAction = action(interestGroupOperations.readMany) +export const readInterestGroupsAction = makeAction(interestGroupOperations.readMany) -export const updateInterestGroupAction = action(interestGroupOperations.update) +export const updateInterestGroupAction = makeAction(interestGroupOperations.update) diff --git a/src/services/images/actions.ts b/src/services/images/actions.ts index ae70a6fc7..9d91c2142 100644 --- a/src/services/images/actions.ts +++ b/src/services/images/actions.ts @@ -1,24 +1,24 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { imageOperations } from '@/services/images/operations' -export const createImageAction = action(imageOperations.create) -export const createImagesAction = action(imageOperations.createMany) +export const createImageAction = makeAction(imageOperations.create) +export const createImagesAction = makeAction(imageOperations.createMany) -export const destroyImageAction = action(imageOperations.destroy) +export const destroyImageAction = makeAction(imageOperations.destroy) /** * Read one image. */ -export const readImageAction = action(imageOperations.read) +export const readImageAction = makeAction(imageOperations.read) /** * Read one page of images. */ -export const readImagesPageAction = action(imageOperations.readPage) +export const readImagesPageAction = makeAction(imageOperations.readPage) /** * Read one special image. */ -export const readSpecialImageAction = action(imageOperations.readSpecial) +export const readSpecialImageAction = makeAction(imageOperations.readSpecial) -export const updateImageAction = action(imageOperations.update) +export const updateImageAction = makeAction(imageOperations.update) diff --git a/src/services/licenses/actions.ts b/src/services/licenses/actions.ts index 7723bd2eb..1411255fe 100644 --- a/src/services/licenses/actions.ts +++ b/src/services/licenses/actions.ts @@ -1,12 +1,12 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { licenseOperations } from '@/services/licenses/operations' -export const createLicenseAction = action(licenseOperations.create) +export const createLicenseAction = makeAction(licenseOperations.create) -export const destroyLicenseAction = action(licenseOperations.destroy) +export const destroyLicenseAction = makeAction(licenseOperations.destroy) -export const readAllLicensesAction = action(licenseOperations.readAll) +export const readAllLicensesAction = makeAction(licenseOperations.readAll) -export const updateLicenseAction = action(licenseOperations.update) +export const updateLicenseAction = makeAction(licenseOperations.update) diff --git a/src/services/lockers/actions.ts b/src/services/lockers/actions.ts index 54c7d081b..08f24c201 100644 --- a/src/services/lockers/actions.ts +++ b/src/services/lockers/actions.ts @@ -1,16 +1,16 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { lockerLocationOperations } from '@/services/lockers/locations/operations' import { lockerOperations } from '@/services/lockers/operations' import { lockerReservationOperations } from '@/services/lockers/reservations/operations' -export const createLockerLocationAction = action(lockerLocationOperations.create) -export const readAllLockerLocationsAction = action(lockerLocationOperations.readAll) +export const createLockerLocationAction = makeAction(lockerLocationOperations.create) +export const readAllLockerLocationsAction = makeAction(lockerLocationOperations.readAll) -export const createLockerAction = action(lockerOperations.create) -export const readLockerAction = action(lockerOperations.read) -export const readLockerPageAction = action(lockerOperations.readPage) +export const createLockerAction = makeAction(lockerOperations.create) +export const readLockerAction = makeAction(lockerOperations.read) +export const readLockerPageAction = makeAction(lockerOperations.readPage) -export const updateLockerReservationAction = action(lockerReservationOperations.update) -export const createLockerReservationAction = action(lockerReservationOperations.create) +export const updateLockerReservationAction = makeAction(lockerReservationOperations.update) +export const createLockerReservationAction = makeAction(lockerReservationOperations.create) diff --git a/src/services/notifications/actions.ts b/src/services/notifications/actions.ts index be9111567..f1362690d 100644 --- a/src/services/notifications/actions.ts +++ b/src/services/notifications/actions.ts @@ -1,15 +1,15 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { notificationChannelOperations } from '@/services/notifications/channel/operations' import { notificationOperations } from '@/services/notifications/operations' import { notificationSubscriptionOperations } from '@/services/notifications/subscription/operations' -export const createNotificationChannelAction = action(notificationChannelOperations.create) -export const updateNotificationChannelAction = action(notificationChannelOperations.update) -export const readNotificationChannelsAction = action(notificationChannelOperations.readMany) +export const createNotificationChannelAction = makeAction(notificationChannelOperations.create) +export const updateNotificationChannelAction = makeAction(notificationChannelOperations.update) +export const readNotificationChannelsAction = makeAction(notificationChannelOperations.readMany) -export const createNotificationAction = action(notificationOperations.create) +export const createNotificationAction = makeAction(notificationOperations.create) -export const readNotificationSubscriptionsAction = action(notificationSubscriptionOperations.read) -export const updateNotificationSubscriptionsAction = action(notificationSubscriptionOperations.update) +export const readNotificationSubscriptionsAction = makeAction(notificationSubscriptionOperations.read) +export const updateNotificationSubscriptionsAction = makeAction(notificationSubscriptionOperations.update) diff --git a/src/services/omegaid/compress.ts b/src/services/omegaid/compress.ts index ac45b1394..7b1e14878 100644 --- a/src/services/omegaid/compress.ts +++ b/src/services/omegaid/compress.ts @@ -1,5 +1,5 @@ import { JWT_ISSUER } from '@/lib/jwt/ConfigVars' -import type { ActionReturn, ActionReturnError } from '@/services/actionTypes' +import type { ActionReturn, ActionError } from '@/services/actionTypes' import type { OmegaIdJWT } from '@/services/omegaid/Types' /** @@ -81,7 +81,7 @@ export function decompressOmegaId(rawdata: string): ActionReturn { const headerJSONString = JSON.stringify(header) const headerB64String = encodeBase64Url(headerJSONString) - const errorReturn: ActionReturnError = { + const errorReturn: ActionError = { success: false, errorCode: 'JWT INVALID', httpCode: 400, diff --git a/src/services/permissions/actions.ts b/src/services/permissions/actions.ts index 20fccda78..5ede64e3d 100644 --- a/src/services/permissions/actions.ts +++ b/src/services/permissions/actions.ts @@ -1,10 +1,10 @@ 'use server' -import { action } from '@/services/action' +import { makeAction } from '@/services/serverAction' import { permissionOperations } from '@/services/permissions/operations' -export const readPermissionOfGroupAction = action(permissionOperations.readPermissionsOfGroup) -export const readPermissionMatrixAction = action(permissionOperations.readPermissionMatrix) -export const readDefaultPermissionsAction = action(permissionOperations.readDefaultPermissions) -export const updateDefaultPermissionsAction = action(permissionOperations.updateDefaultPermissions) -export const updateGroupPermissionAction = action(permissionOperations.updateGroupPermission) +export const readPermissionOfGroupAction = makeAction(permissionOperations.readPermissionsOfGroup) +export const readPermissionMatrixAction = makeAction(permissionOperations.readPermissionMatrix) +export const readDefaultPermissionsAction = makeAction(permissionOperations.readDefaultPermissions) +export const updateDefaultPermissionsAction = makeAction(permissionOperations.updateDefaultPermissions) +export const updateGroupPermissionAction = makeAction(permissionOperations.updateGroupPermission) diff --git a/src/services/action.ts b/src/services/serverAction.ts similarity index 90% rename from src/services/action.ts rename to src/services/serverAction.ts index 76bb67609..f3707cfc4 100644 --- a/src/services/action.ts +++ b/src/services/serverAction.ts @@ -5,20 +5,20 @@ import type { ActionReturn } from './actionTypes' import type { ServiceOperation } from '@/services/serviceOperation' import type { z } from 'zod' -export function action( +export function makeAction( serviceMethod: ServiceOperation ): () => Promise> -export function action( +export function makeAction( serviceMethod: ServiceOperation ): (params: z.input) => Promise> -export function action( +export function makeAction( serviceMethod: ServiceOperation ): (data: z.input | FormData) => Promise> // This function is overloaded to allow for different combinations of parameters and data. -export function action( +export function makeAction( serviceMethod: ServiceOperation ): (params: z.input, data: z.input | FormData) => Promise> @@ -28,7 +28,7 @@ export function action From 673ed6771710dd99fc6d5ed4f3effa3a04b6e7a7 Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sat, 11 Oct 2025 02:16:48 +0200 Subject: [PATCH 22/24] refactor: auther -> auth --- src/app/_components/Company/Company.tsx | 6 ++-- src/app/cabin/book/page.tsx | 6 ++-- src/app/events/archive/page.tsx | 8 +++--- src/app/events/page.tsx | 8 +++--- src/app/interest-groups/InterestGroup.tsx | 6 ++-- src/app/interest-groups/page.tsx | 4 +-- .../(user-admin)/getProfileForAdmin.ts | 4 +-- src/app/users/[username]/page.tsx | 4 +-- .../admission/{authers.ts => auth.ts} | 2 +- src/services/admission/operations.ts | 6 ++-- src/services/api-keys/{authers.ts => auth.ts} | 2 +- src/services/api-keys/operations.ts | 16 +++++------ .../applications/{authers.ts => auth.ts} | 2 +- src/services/applications/operations.ts | 10 +++---- .../periods/{authers.ts => auth.ts} | 2 +- .../applications/periods/operations.ts | 16 +++++------ src/services/auth/{authers.ts => auth.ts} | 3 +- src/services/auth/operations.ts | 10 +++---- .../cabin/booking/{authers.ts => auth.ts} | 2 +- src/services/cabin/booking/operations.ts | 16 +++++------ .../cabin/pricePeriod/{authers.ts => auth.ts} | 2 +- src/services/cabin/pricePeriod/operations.ts | 14 +++++----- .../cabin/product/{authers.ts => auth.ts} | 2 +- src/services/cabin/product/operations.ts | 12 ++++---- .../releasePeriod/{authers.ts => auth.ts} | 2 +- .../cabin/releasePeriod/operations.ts | 12 ++++---- .../career/companies/{authers.ts => auth.ts} | 2 +- src/services/career/companies/operations.ts | 10 +++---- .../career/jobAds/{authers.ts => auth.ts} | 2 +- src/services/career/jobAds/operations.ts | 14 +++++----- src/services/cms/links/auth.ts | 3 ++ src/services/cms/links/authers.ts | 3 -- src/services/cms/links/read.ts | 4 +-- src/services/dots/{authers.ts => auth.ts} | 2 +- src/services/dots/operations.ts | 10 +++---- src/services/events/{authers.ts => auth.ts} | 2 +- src/services/events/operations.ts | 14 +++++----- .../registration/{authers.ts => auth.ts} | 2 +- .../events/registration/operations.ts | 14 +++++----- .../events/tags/{authers.ts => auth.ts} | 2 +- src/services/events/tags/operations.ts | 16 +++++------ src/services/groups/{authers.ts => auth.ts} | 2 +- .../groups/committees/{authers.ts => auth.ts} | 2 +- src/services/groups/committees/operations.ts | 12 ++++---- .../interestGroups/{authers.ts => auth.ts} | 2 +- .../groups/interestGroups/operations.ts | 12 ++++---- src/services/groups/operations.ts | 10 +++---- src/services/images/{authers.ts => auth.ts} | 2 +- src/services/images/operations.ts | 18 ++++++------ src/services/licenses/{authers.ts => auth.ts} | 2 +- src/services/licenses/operations.ts | 10 +++---- src/services/lockers/{authers.ts => auth.ts} | 2 +- .../lockers/locations/{authers.ts => auth.ts} | 2 +- src/services/lockers/locations/operations.ts | 6 ++-- src/services/lockers/operations.ts | 8 +++--- .../reservations/{authers.ts => auth.ts} | 2 +- .../lockers/reservations/operations.ts | 8 +++--- .../notifications/{authers.ts => auth.ts} | 2 +- .../channel/{authers.ts => auth.ts} | 2 +- .../notifications/channel/operations.ts | 12 ++++---- src/services/notifications/operations.ts | 4 +-- .../subscription/{authers.ts => auth.ts} | 2 +- .../notifications/subscription/operations.ts | 6 ++-- .../permissions/{auther.ts => auth.ts} | 2 +- src/services/permissions/operations.ts | 12 ++++---- .../shop/product/{authers.ts => auth.ts} | 2 +- src/services/shop/product/operations.ts | 18 ++++++------ .../shop/purchase/{authers.ts => auth.ts} | 2 +- src/services/shop/purchase/operations.ts | 4 +-- .../shop/shop/{authers.ts => auth.ts} | 2 +- src/services/shop/shop/operations.ts | 8 +++--- src/services/users/{authers.ts => auth.ts} | 2 +- src/services/users/operations.ts | 28 +++++++++---------- 73 files changed, 243 insertions(+), 242 deletions(-) rename src/services/admission/{authers.ts => auth.ts} (90%) rename src/services/api-keys/{authers.ts => auth.ts} (91%) rename src/services/applications/{authers.ts => auth.ts} (92%) rename src/services/applications/periods/{authers.ts => auth.ts} (94%) rename src/services/auth/{authers.ts => auth.ts} (86%) rename src/services/cabin/booking/{authers.ts => auth.ts} (96%) rename src/services/cabin/pricePeriod/{authers.ts => auth.ts} (89%) rename src/services/cabin/product/{authers.ts => auth.ts} (90%) rename src/services/cabin/releasePeriod/{authers.ts => auth.ts} (88%) rename src/services/career/companies/{authers.ts => auth.ts} (92%) rename src/services/career/jobAds/{authers.ts => auth.ts} (94%) create mode 100644 src/services/cms/links/auth.ts delete mode 100644 src/services/cms/links/authers.ts rename src/services/dots/{authers.ts => auth.ts} (96%) rename src/services/events/{authers.ts => auth.ts} (94%) rename src/services/events/registration/{authers.ts => auth.ts} (95%) rename src/services/events/tags/{authers.ts => auth.ts} (93%) rename src/services/groups/{authers.ts => auth.ts} (82%) rename src/services/groups/committees/{authers.ts => auth.ts} (81%) rename src/services/groups/interestGroups/{authers.ts => auth.ts} (93%) rename src/services/images/{authers.ts => auth.ts} (94%) rename src/services/licenses/{authers.ts => auth.ts} (92%) rename src/services/lockers/{authers.ts => auth.ts} (90%) rename src/services/lockers/locations/{authers.ts => auth.ts} (86%) rename src/services/lockers/reservations/{authers.ts => auth.ts} (87%) rename src/services/notifications/{authers.ts => auth.ts} (87%) rename src/services/notifications/channel/{authers.ts => auth.ts} (91%) rename src/services/notifications/subscription/{authers.ts => auth.ts} (85%) rename src/services/permissions/{auther.ts => auth.ts} (94%) rename src/services/shop/product/{authers.ts => auth.ts} (92%) rename src/services/shop/purchase/{authers.ts => auth.ts} (91%) rename src/services/shop/shop/{authers.ts => auth.ts} (88%) rename src/services/users/{authers.ts => auth.ts} (98%) diff --git a/src/app/_components/Company/Company.tsx b/src/app/_components/Company/Company.tsx index 16545de74..37a84ba1d 100644 --- a/src/app/_components/Company/Company.tsx +++ b/src/app/_components/Company/Company.tsx @@ -6,7 +6,7 @@ import CmsImage from '@/cms/CmsImage/CmsImage' import CmsImageClient from '@/cms/CmsImage/CmsImageClient' import Form from '@/components/Form/Form' import { bindParams } from '@/services/actionBind' -import { companyAuthers } from '@/services/career/companies/authers' +import { companyAuth } from '@/services/career/companies/auth' import { destroyCompanyAction, updateComanyAction } from '@/services/career/companies/actions' import type { CompanyExpanded } from '@/services/career/companies/Types' import type { SessionMaybeUser } from '@/auth/Session' @@ -38,8 +38,8 @@ export default function Company({ logoWidth = 300, squareLogo = true, }: PropTypes) { - const canUpdate = companyAuthers.update.dynamicFields({}).auth(session) - const canDestroy = companyAuthers.destroy.dynamicFields({}).auth(session) + const canUpdate = companyAuth.update.dynamicFields({}).auth(session) + const canDestroy = companyAuth.destroy.dynamicFields({}).auth(session) return (
    {asClient ? diff --git a/src/app/cabin/book/page.tsx b/src/app/cabin/book/page.tsx index 972b7912d..dcefa49dc 100644 --- a/src/app/cabin/book/page.tsx +++ b/src/app/cabin/book/page.tsx @@ -10,7 +10,7 @@ import { } from '@/services/cabin/actions' import { displayDate } from '@/lib/dates/displayDate' import { Session } from '@/auth/Session' -import { cabinBookingAuthers } from '@/services/cabin/booking/authers' +import { cabinBookingAuth } from '@/services/cabin/booking/auth' import type { ReleasePeriod } from '@prisma/client' function findCurrentReleasePeriod(releasePeriods: ReleasePeriod[]) { @@ -41,8 +41,8 @@ export default async function CabinBooking() { const pricePeriods = unwrapActionReturn(await readPublicPricePeriodsAction()) const cabinProducts = unwrapActionReturn(await readCabinProductsActiveAction()) const session = await Session.fromNextAuth() - const canBookCabin = cabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}).auth(session) - const canBookBed = cabinBookingAuthers.createBedBookingNoUser.dynamicFields({}).auth(session) + const canBookCabin = cabinBookingAuth.createCabinBookingNoUser.dynamicFields({}).auth(session) + const canBookBed = cabinBookingAuth.createBedBookingNoUser.dynamicFields({}).auth(session) return Failed to load interest groups
    //TODO: Change to unwrap const interestGroups = interestGroupsRes.data - const canCreate = interestGroupAuthers.create.dynamicFields({}).auth(session) + const canCreate = interestGroupAuth.create.dynamicFields({}).auth(session) return ( admissionAuthers.readTrial.dynamicFields({}), + authorizer: () => admissionAuth.readTrial.dynamicFields({}), paramsSchema: z.object({ userId: z.number(), }), @@ -21,7 +21,7 @@ export const admissionOperations = { }) }), createTrial: defineOperation({ - authorizer: () => admissionAuthers.createTrial.dynamicFields({}), + authorizer: () => admissionAuth.createTrial.dynamicFields({}), paramsSchema: z.object({ admission: z.nativeEnum(Admission), }), diff --git a/src/services/api-keys/authers.ts b/src/services/api-keys/auth.ts similarity index 91% rename from src/services/api-keys/authers.ts rename to src/services/api-keys/auth.ts index d9231cd2d..ccf82ffb7 100644 --- a/src/services/api-keys/authers.ts +++ b/src/services/api-keys/auth.ts @@ -2,7 +2,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' const baseAuther = RequirePermission.staticFields({ permission: 'APIKEY_ADMIN' }) -export const apiKeyAuthers = { +export const apiKeyAuth = { create: baseAuther, read: baseAuther, readMany: baseAuther, diff --git a/src/services/api-keys/operations.ts b/src/services/api-keys/operations.ts index 10f386ed7..ddf61b5a0 100644 --- a/src/services/api-keys/operations.ts +++ b/src/services/api-keys/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { apiKeyAuthers } from './authers' +import { apiKeyAuth } from './auth' import { apiKeySchemas } from './schemas' import { apiKeyHashAndEncrypt } from './hashEncryptKey' import { encodeApiKey } from './apiKeyEncoder' @@ -18,7 +18,7 @@ import type { ApiKeyFiltered, ApiKeyFilteredWithKey } from './Types' * Note: This operaiton is only used internally. */ const updateIfExpired = defineOperation({ - authorizer: () => apiKeyAuthers.updateIfExpired.dynamicFields({}), + authorizer: () => apiKeyAuth.updateIfExpired.dynamicFields({}), paramsSchema: z.object({ id: z.number(), expiresAt: z.date().nullable(), @@ -45,7 +45,7 @@ const updateIfExpired = defineOperation({ export const apiKeyOperations = { create: defineOperation({ - authorizer: () => apiKeyAuthers.create.dynamicFields({}), + authorizer: () => apiKeyAuth.create.dynamicFields({}), dataSchema: apiKeySchemas.create, operation: async ({ prisma, data }): Promise => { const NODE_ENV = process.env.NODE_ENV @@ -66,7 +66,7 @@ export const apiKeyOperations = { } }), read: defineOperation({ - authorizer: () => apiKeyAuthers.read.dynamicFields({}), + authorizer: () => apiKeyAuth.read.dynamicFields({}), paramsSchema: z.union([z.object({ id: z.number() }), z.object({ name: z.string() })]), operation: async ({ prisma, params }): Promise => { const apiKey = await prisma.apiKey.findUnique({ @@ -88,7 +88,7 @@ export const apiKeyOperations = { } }), readMany: defineOperation({ - authorizer: () => apiKeyAuthers.readMany.dynamicFields({}), + authorizer: () => apiKeyAuth.readMany.dynamicFields({}), operation: async ({ prisma }): Promise => { const apiKeys = await prisma.apiKey.findMany({ select: apiFilterSelection, @@ -108,7 +108,7 @@ export const apiKeyOperations = { } }), readWithHash: defineOperation({ - authorizer: () => apiKeyAuthers.readWithHash.dynamicFields({}), + authorizer: () => apiKeyAuth.readWithHash.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -134,7 +134,7 @@ export const apiKeyOperations = { } }), update: defineOperation({ - authorizer: () => apiKeyAuthers.update.dynamicFields({}), + authorizer: () => apiKeyAuth.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -152,7 +152,7 @@ export const apiKeyOperations = { }, }), destroy: defineOperation({ - authorizer: () => apiKeyAuthers.destroy.dynamicFields({}), + authorizer: () => apiKeyAuth.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/applications/authers.ts b/src/services/applications/auth.ts similarity index 92% rename from src/services/applications/authers.ts rename to src/services/applications/auth.ts index 235bb4956..94d1c947b 100644 --- a/src/services/applications/authers.ts +++ b/src/services/applications/auth.ts @@ -1,6 +1,6 @@ import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' -export const applicationAuthers = { +export const applicationAuth = { readForUser: RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }), create: RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }), update: RequireUserIdOrPermission.staticFields({ permission: 'APPLICATION_ADMIN' }), diff --git a/src/services/applications/operations.ts b/src/services/applications/operations.ts index a60b5a537..3213fd9b0 100644 --- a/src/services/applications/operations.ts +++ b/src/services/applications/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { applicationAuthers } from './authers' +import { applicationAuth } from './auth' import { applicationSchemas } from './schemas' import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' @@ -11,7 +11,7 @@ export const applicationOperations = { userId: z.number(), periodId: z.number() }), - authorizer: ({ params }) => applicationAuthers.readForUser.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => applicationAuth.readForUser.dynamicFields({ userId: params.userId }), operation: async ({ prisma, params }) => prisma.application.findMany({ where: { userId: params.userId, @@ -26,7 +26,7 @@ export const applicationOperations = { userId: z.number(), commiteeParticipationId: z.number() }), - authorizer: ({ params }) => applicationAuthers.create.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => applicationAuth.create.dynamicFields({ userId: params.userId }), operation: async ({ prisma, data, params }) => { const commiteeParticipation = await prisma.committeeParticipationInApplicationPeriod.findUniqueOrThrow({ where: { @@ -85,7 +85,7 @@ export const applicationOperations = { commiteeParticipationId: z.number() }), opensTransaction: true, - authorizer: ({ params }) => applicationAuthers.update.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => applicationAuth.update.dynamicFields({ userId: params.userId }), operation: async ({ prisma, data, params }) => { const application = await prisma.application.findUniqueOrThrow({ where: { @@ -199,7 +199,7 @@ export const applicationOperations = { userId: z.number(), commiteeParticipationId: z.number() }), - authorizer: ({ params }) => applicationAuthers.destroy.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => applicationAuth.destroy.dynamicFields({ userId: params.userId }), opensTransaction: true, operation: async ({ prisma, params }) => { prisma.$transaction(async (tx) => { diff --git a/src/services/applications/periods/authers.ts b/src/services/applications/periods/auth.ts similarity index 94% rename from src/services/applications/periods/authers.ts rename to src/services/applications/periods/auth.ts index 6f8483f02..dabdf974d 100644 --- a/src/services/applications/periods/authers.ts +++ b/src/services/applications/periods/auth.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const applicationPeriodAuthers = { +export const applicationPeriodAuth = { readAll: RequirePermission.staticFields({ permission: 'APPLICATION_WRITE' }), read: RequirePermission.staticFields({ permission: 'APPLICATION_WRITE' }), readNumberOfApplications: RequirePermission.staticFields({ permission: 'APPLICATION_WRITE' }), diff --git a/src/services/applications/periods/operations.ts b/src/services/applications/periods/operations.ts index d4cb86c90..c0c6a1b99 100644 --- a/src/services/applications/periods/operations.ts +++ b/src/services/applications/periods/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { applicationPeriodAuthers } from './authers' +import { applicationPeriodAuth } from './auth' import { applicationPeriodSchemas } from './schemas' import { committeesParticipatingincluder } from './constants' import { applicationOperations } from '@/services/applications/operations' @@ -9,12 +9,12 @@ import { z } from 'zod' export const applicationPeriodOperations = { readAll: defineOperation({ - authorizer: () => applicationPeriodAuthers.readAll.dynamicFields({}), + authorizer: () => applicationPeriodAuth.readAll.dynamicFields({}), operation: async ({ prisma }) => prisma.applicationPeriod.findMany() }), read: defineOperation({ - authorizer: () => applicationPeriodAuthers.read.dynamicFields({}), + authorizer: () => applicationPeriodAuth.read.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), @@ -25,7 +25,7 @@ export const applicationPeriodOperations = { }), create: defineOperation({ - authorizer: () => applicationPeriodAuthers.create.dynamicFields({}), + authorizer: () => applicationPeriodAuth.create.dynamicFields({}), dataSchema: applicationPeriodSchemas.create, operation: async ({ prisma, data }) => { await prisma.applicationPeriod.create({ @@ -44,7 +44,7 @@ export const applicationPeriodOperations = { }), update: defineOperation({ - authorizer: () => applicationPeriodAuthers.update.dynamicFields({}), + authorizer: () => applicationPeriodAuth.update.dynamicFields({}), dataSchema: applicationPeriodSchemas.update, paramsSchema: z.object({ name: z.string() @@ -126,7 +126,7 @@ export const applicationPeriodOperations = { paramsSchema: z.object({ name: z.string() }), - authorizer: () => applicationPeriodAuthers.removeAllApplicationTexts.dynamicFields({}), + authorizer: () => applicationPeriodAuth.removeAllApplicationTexts.dynamicFields({}), operation: async ({ prisma, params, session }) => { const period = await applicationPeriodOperations.read({ params: { name: params.name }, @@ -149,7 +149,7 @@ export const applicationPeriodOperations = { }), destroy: defineOperation({ - authorizer: () => applicationPeriodAuthers.destroy.dynamicFields({}), + authorizer: () => applicationPeriodAuth.destroy.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), @@ -161,7 +161,7 @@ export const applicationPeriodOperations = { }), readNumberOfApplications: defineOperation({ - authorizer: () => applicationPeriodAuthers.readNumberOfApplications.dynamicFields({}), + authorizer: () => applicationPeriodAuth.readNumberOfApplications.dynamicFields({}), paramsSchema: z.object({ name: z.string() }), diff --git a/src/services/auth/authers.ts b/src/services/auth/auth.ts similarity index 86% rename from src/services/auth/authers.ts rename to src/services/auth/auth.ts index b91bbaff0..aeea9db52 100644 --- a/src/services/auth/authers.ts +++ b/src/services/auth/auth.ts @@ -1,7 +1,8 @@ import { RequireJWT } from '@/auth/auther/RequireJWT' import { RequireNothing } from '@/auth/auther/RequireNothing' -export const authAuthers = { +// TODO: A better name lol +export const authAuth = { verifyEmail: RequireJWT.staticFields({ audience: 'verifyemail' }), resetPassword: RequireJWT.staticFields({ audience: 'resetpassword' }), sendResetPasswordEmail: RequireNothing.staticFields({}), diff --git a/src/services/auth/operations.ts b/src/services/auth/operations.ts index b07a92d6c..3b274bdea 100644 --- a/src/services/auth/operations.ts +++ b/src/services/auth/operations.ts @@ -1,4 +1,4 @@ -import { authAuthers } from './authers' +import { authAuth } from './auth' import { authSchemas } from './schemas' import { userFilterSelection } from '@/services/users/constants' import { userSchemas } from '@/services/users/schemas' @@ -15,7 +15,7 @@ export const authOperations = { paramsSchema: z.object({ token: z.string(), }), - authorizer: ({ params }) => authAuthers.verifyEmail.dynamicFields(params), + authorizer: ({ params }) => authAuth.verifyEmail.dynamicFields(params), operation: async ({ prisma, params }) => { // INFO: Safe to parse unsafe since the auther has verified the token. const payload = readJWTPayload(params.token) @@ -57,7 +57,7 @@ export const authOperations = { paramsSchema: z.object({ token: z.string() }), - authorizer: ({ params }) => authAuthers.resetPassword.dynamicFields(params), + authorizer: ({ params }) => authAuth.resetPassword.dynamicFields(params), operation: async ({ prisma, params }) => { // INFO: Safe to parse unsafe since the auther has verified the token. const payload = readJWTPayload(params.token) @@ -90,7 +90,7 @@ export const authOperations = { token: z.string() }), dataSchema: userSchemas.updatePassword, - authorizer: ({ params }) => authAuthers.resetPassword.dynamicFields(params), + authorizer: ({ params }) => authAuth.resetPassword.dynamicFields(params), operation: async ({ params, data }) => { const userId = await authOperations.verifyResetPasswordToken({ params }) @@ -106,7 +106,7 @@ export const authOperations = { sendResetPasswordEmail: defineOperation({ dataSchema: authSchemas.sendResetPasswordEmail, - authorizer: () => authAuthers.sendResetPasswordEmail.dynamicFields({}), + authorizer: () => authAuth.sendResetPasswordEmail.dynamicFields({}), operation: async ({ data }) => { console.log(data) try { diff --git a/src/services/cabin/booking/authers.ts b/src/services/cabin/booking/auth.ts similarity index 96% rename from src/services/cabin/booking/authers.ts rename to src/services/cabin/booking/auth.ts index 7d6184366..1b89907c0 100644 --- a/src/services/cabin/booking/authers.ts +++ b/src/services/cabin/booking/auth.ts @@ -1,7 +1,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import { RequirePermissionAndUserId } from '@/auth/auther/RequirePermissionAndUserId' -export const cabinBookingAuthers = { +export const cabinBookingAuth = { createCabinBookingUserAttached: RequirePermissionAndUserId.staticFields({ permission: 'CABIN_BOOKING_CABIN_CREATE' }), diff --git a/src/services/cabin/booking/operations.ts b/src/services/cabin/booking/operations.ts index ea75b5484..d48ec1fac 100644 --- a/src/services/cabin/booking/operations.ts +++ b/src/services/cabin/booking/operations.ts @@ -1,7 +1,7 @@ import 'server-only' import { calculateCabinBookingPrice, calculateTotalCabinBookingPrice } from './cabinPriceCalculator' import { cabinBookingSchemas } from './schemas' -import { cabinBookingAuthers } from './authers' +import { cabinBookingAuth } from './auth' import { cabinBookingFilerSelection, cabinBookingIncluder } from './constants' import { cabinPricePeriodOperations } from '@/services/cabin/pricePeriod/operations' import { cabinProductPriceIncluder } from '@/services/cabin/product/constants' @@ -245,7 +245,7 @@ export const cabinBookingOperations = { userId: z.number(), bookingProducts: bookingProductParams, }), - authorizer: ({ params }) => cabinBookingAuthers.createCabinBookingUserAttached.dynamicFields({ + authorizer: ({ params }) => cabinBookingAuth.createCabinBookingUserAttached.dynamicFields({ userId: params.userId, }), dataSchema: cabinBookingSchemas.createBookingUserAttached, @@ -266,7 +266,7 @@ export const cabinBookingOperations = { userId: z.number(), bookingProducts: bookingProductParams, }), - authorizer: ({ params }) => cabinBookingAuthers.createBedBookingUserAttached.dynamicFields({ + authorizer: ({ params }) => cabinBookingAuth.createBedBookingUserAttached.dynamicFields({ userId: params.userId, }), dataSchema: cabinBookingSchemas.createBookingUserAttached, @@ -286,7 +286,7 @@ export const cabinBookingOperations = { paramsSchema: z.object({ bookingProducts: bookingProductParams, }), - authorizer: () => cabinBookingAuthers.createCabinBookingNoUser.dynamicFields({}), + authorizer: () => cabinBookingAuth.createCabinBookingNoUser.dynamicFields({}), dataSchema: cabinBookingSchemas.createBookingNoUser, operation: async ({ params, data }) => createBookingNoUser({ params: { @@ -302,7 +302,7 @@ export const cabinBookingOperations = { paramsSchema: z.object({ bookingProducts: bookingProductParams, }), - authorizer: () => cabinBookingAuthers.createBedBookingNoUser.dynamicFields({}), + authorizer: () => cabinBookingAuth.createBedBookingNoUser.dynamicFields({}), dataSchema: cabinBookingSchemas.createBookingNoUser, operation: async ({ params, data }) => createBookingNoUser({ params: { @@ -315,7 +315,7 @@ export const cabinBookingOperations = { }), readAvailability: defineOperation({ - authorizer: () => cabinBookingAuthers.readAvailability.dynamicFields({}), + authorizer: () => cabinBookingAuth.readAvailability.dynamicFields({}), operation: async ({ prisma }) => { const results = await prisma.booking.findMany({ select: cabinBookingFilerSelection, @@ -343,7 +343,7 @@ export const cabinBookingOperations = { }), readMany: defineOperation({ - authorizer: () => cabinBookingAuthers.readMany.dynamicFields({}), + authorizer: () => cabinBookingAuth.readMany.dynamicFields({}), operation: ({ prisma }) => prisma.booking.findMany({ orderBy: { start: 'asc', @@ -353,7 +353,7 @@ export const cabinBookingOperations = { }), read: defineOperation({ - authorizer: () => cabinBookingAuthers.read.dynamicFields({}), + authorizer: () => cabinBookingAuth.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/cabin/pricePeriod/authers.ts b/src/services/cabin/pricePeriod/auth.ts similarity index 89% rename from src/services/cabin/pricePeriod/authers.ts rename to src/services/cabin/pricePeriod/auth.ts index 1a13e37e4..e35733873 100644 --- a/src/services/cabin/pricePeriod/authers.ts +++ b/src/services/cabin/pricePeriod/auth.ts @@ -2,7 +2,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' const baseAuther = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) -export const cabinPricePeriodAuthers = { +export const cabinPricePeriodAuth = { create: baseAuther, read: baseAuther, readPublicPeriods: RequirePermission.staticFields({ permission: 'CABIN_CALENDAR_READ' }), diff --git a/src/services/cabin/pricePeriod/operations.ts b/src/services/cabin/pricePeriod/operations.ts index 6770f30e8..50f58226f 100644 --- a/src/services/cabin/pricePeriod/operations.ts +++ b/src/services/cabin/pricePeriod/operations.ts @@ -1,5 +1,5 @@ import 'server-only' -import { cabinPricePeriodAuthers } from './authers' +import { cabinPricePeriodAuth } from './auth' import { cabinPricePeriodSchemas } from './schemas' import { defineOperation } from '@/services/serviceOperation' import { cabinReleasePeriodOperations } from '@/services/cabin/releasePeriod/operations' @@ -8,7 +8,7 @@ import { z } from 'zod' export const cabinPricePeriodOperations = { create: defineOperation({ - authorizer: () => cabinPricePeriodAuthers.create.dynamicFields({}), + authorizer: () => cabinPricePeriodAuth.create.dynamicFields({}), dataSchema: cabinPricePeriodSchemas.createPricePeriod, operation: async ({ prisma, data }) => { const currentReleaseDate = await cabinReleasePeriodOperations.getCurrentReleasePeriod({ bypassAuth: true }) @@ -59,7 +59,7 @@ export const cabinPricePeriodOperations = { }), destroy: defineOperation({ - authorizer: () => cabinPricePeriodAuthers.destroy.dynamicFields({}), + authorizer: () => cabinPricePeriodAuth.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -81,12 +81,12 @@ export const cabinPricePeriodOperations = { }), readMany: defineOperation({ - authorizer: () => cabinPricePeriodAuthers.read.dynamicFields({}), + authorizer: () => cabinPricePeriodAuth.read.dynamicFields({}), operation: async ({ prisma }) => prisma.pricePeriod.findMany() }), readPublicPeriods: defineOperation({ - authorizer: () => cabinPricePeriodAuthers.readPublicPeriods.dynamicFields({}), + authorizer: () => cabinPricePeriodAuth.readPublicPeriods.dynamicFields({}), operation: async ({ prisma }) => { const releaseDate = await cabinReleasePeriodOperations.getCurrentReleasePeriod({ bypassAuth: true }) @@ -119,7 +119,7 @@ export const cabinPricePeriodOperations = { }), readUnreleasedPeriods: defineOperation({ - authorizer: () => cabinPricePeriodAuthers.read.dynamicFields({}), + authorizer: () => cabinPricePeriodAuth.read.dynamicFields({}), operation: async ({ prisma }) => { const releaseDate = await cabinReleasePeriodOperations.getCurrentReleasePeriod({ bypassAuth: true }) return prisma.pricePeriod.findMany({ @@ -133,7 +133,7 @@ export const cabinPricePeriodOperations = { }), update: defineOperation({ - authorizer: () => cabinPricePeriodAuthers.update.dynamicFields({}), + authorizer: () => cabinPricePeriodAuth.update.dynamicFields({}), dataSchema: cabinPricePeriodSchemas.updatePricePeriod, paramsSchema: z.object({ pricePeriodId: z.number(), diff --git a/src/services/cabin/product/authers.ts b/src/services/cabin/product/auth.ts similarity index 90% rename from src/services/cabin/product/authers.ts rename to src/services/cabin/product/auth.ts index eb9f6594a..cf24e9975 100644 --- a/src/services/cabin/product/authers.ts +++ b/src/services/cabin/product/auth.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const cabinProductAuthers = { +export const cabinProductAuth = { read: RequirePermission.staticFields({ permission: 'CABIN_CALENDAR_READ' }), diff --git a/src/services/cabin/product/operations.ts b/src/services/cabin/product/operations.ts index 241622657..9861309db 100644 --- a/src/services/cabin/product/operations.ts +++ b/src/services/cabin/product/operations.ts @@ -1,6 +1,6 @@ import 'server-only' -import { cabinProductAuthers } from './authers' +import { cabinProductAuth } from './auth' import { cabinProductSchemas } from './schemas' import { cabinProductPriceIncluder } from './constants' import { cabinReleasePeriodOperations } from '@/services/cabin/releasePeriod/operations' @@ -12,7 +12,7 @@ import { z } from 'zod' export const cabinProductOperations = { create: defineOperation({ - authorizer: () => cabinProductAuthers.create.dynamicFields({}), + authorizer: () => cabinProductAuth.create.dynamicFields({}), dataSchema: cabinProductSchemas.createProduct, operation: ({ prisma, data }) => prisma.cabinProduct.create({ data, @@ -20,7 +20,7 @@ export const cabinProductOperations = { }), createPrice: defineOperation({ - authorizer: () => cabinProductAuthers.createPrice.dynamicFields({}), + authorizer: () => cabinProductAuth.createPrice.dynamicFields({}), paramsSchema: z.object({ cabinProductId: z.number(), }), @@ -54,14 +54,14 @@ export const cabinProductOperations = { }), readMany: defineOperation({ - authorizer: () => cabinProductAuthers.read.dynamicFields({}), + authorizer: () => cabinProductAuth.read.dynamicFields({}), operation: ({ prisma }) => prisma.cabinProduct.findMany({ include: cabinProductPriceIncluder, }), }), readActive: defineOperation({ - authorizer: () => cabinProductAuthers.read.dynamicFields({}), + authorizer: () => cabinProductAuth.read.dynamicFields({}), operation: async ({ prisma }) => { const pricePeriods = await cabinPricePeriodOperations.readPublicPeriods({ bypassAuth: true }) @@ -81,7 +81,7 @@ export const cabinProductOperations = { }), read: defineOperation({ - authorizer: () => cabinProductAuthers.read.dynamicFields({}), + authorizer: () => cabinProductAuth.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/cabin/releasePeriod/authers.ts b/src/services/cabin/releasePeriod/auth.ts similarity index 88% rename from src/services/cabin/releasePeriod/authers.ts rename to src/services/cabin/releasePeriod/auth.ts index a0c6a6113..898ce4d5e 100644 --- a/src/services/cabin/releasePeriod/authers.ts +++ b/src/services/cabin/releasePeriod/auth.ts @@ -2,7 +2,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' const baseAuther = RequirePermission.staticFields({ permission: 'CABIN_ADMIN' }) -export const cabinReleasePeriodAuthers = { +export const cabinReleasePeriodAuth = { createReleasePeriodAuther: baseAuther, readReleasePeriodAuther: baseAuther, updateReleasePeriodAuther: baseAuther, diff --git a/src/services/cabin/releasePeriod/operations.ts b/src/services/cabin/releasePeriod/operations.ts index ba56fb01e..e2ac3572c 100644 --- a/src/services/cabin/releasePeriod/operations.ts +++ b/src/services/cabin/releasePeriod/operations.ts @@ -1,5 +1,5 @@ import 'server-only' -import { cabinReleasePeriodAuthers } from './authers' +import { cabinReleasePeriodAuth } from './auth' import { cabinReleasePeriodSchemas } from './schemas' import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' @@ -8,7 +8,7 @@ import { z } from 'zod' export const cabinReleasePeriodOperations = { create: defineOperation({ - authorizer: () => cabinReleasePeriodAuthers.createReleasePeriodAuther.dynamicFields({}), + authorizer: () => cabinReleasePeriodAuth.createReleasePeriodAuther.dynamicFields({}), dataSchema: cabinReleasePeriodSchemas.createReleasePeriod, operation: async ({ prisma, data }) => { const latestReleasePeriod = await prisma.releasePeriod.findFirst({ @@ -32,7 +32,7 @@ export const cabinReleasePeriodOperations = { }), destroy: defineOperation({ - authorizer: () => cabinReleasePeriodAuthers.deleteReleasePeriodAuther.dynamicFields({}), + authorizer: () => cabinReleasePeriodAuth.deleteReleasePeriodAuther.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -52,7 +52,7 @@ export const cabinReleasePeriodOperations = { }), readMany: defineOperation({ - authorizer: () => cabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), + authorizer: () => cabinReleasePeriodAuth.readReleasePeriodAuther.dynamicFields({}), operation: async ({ prisma }) => prisma.releasePeriod.findMany({ orderBy: { releaseUntil: 'desc', @@ -61,7 +61,7 @@ export const cabinReleasePeriodOperations = { }), getCurrentReleasePeriod: defineOperation({ - authorizer: () => cabinReleasePeriodAuthers.readReleasePeriodAuther.dynamicFields({}), + authorizer: () => cabinReleasePeriodAuth.readReleasePeriodAuther.dynamicFields({}), operation: async ({ prisma }) => prisma.releasePeriod.findFirst({ where: { releaseTime: { @@ -76,7 +76,7 @@ export const cabinReleasePeriodOperations = { }), update: defineOperation({ - authorizer: () => cabinReleasePeriodAuthers.updateReleasePeriodAuther.dynamicFields({}), + authorizer: () => cabinReleasePeriodAuth.updateReleasePeriodAuther.dynamicFields({}), dataSchema: cabinReleasePeriodSchemas.updateReleasePeriod, operation: async ({ prisma, data }) => prisma.releasePeriod.update({ where: { diff --git a/src/services/career/companies/authers.ts b/src/services/career/companies/auth.ts similarity index 92% rename from src/services/career/companies/authers.ts rename to src/services/career/companies/auth.ts index e7ff1ec72..5fe8b7a68 100644 --- a/src/services/career/companies/authers.ts +++ b/src/services/career/companies/auth.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const companyAuthers = { +export const companyAuth = { create: RequirePermission.staticFields({ permission: 'COMPANY_ADMIN' }), readPage: RequirePermission.staticFields({ permission: 'COMPANY_READ' }), update: RequirePermission.staticFields({ permission: 'COMPANY_ADMIN' }), diff --git a/src/services/career/companies/operations.ts b/src/services/career/companies/operations.ts index 50eb52630..18f7b62b8 100644 --- a/src/services/career/companies/operations.ts +++ b/src/services/career/companies/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { companyAuthers } from './authers' +import { companyAuth } from './auth' import { logoIncluder } from './constants' import { companySchemas } from './schemas' import { createCmsImage } from '@/services/cms/images/create' @@ -12,7 +12,7 @@ import { z } from 'zod' export const companyOperations = { create: defineOperation({ dataSchema: companySchemas.create, - authorizer: () => companyAuthers.create.dynamicFields({}), + authorizer: () => companyAuth.create.dynamicFields({}), operation: async ({ prisma, data }) => { //TODO: tranaction when createCmsImage is service method. const logo = await createCmsImage({ name: uuid() }) @@ -34,7 +34,7 @@ export const companyOperations = { name: z.string().optional(), }), ), - authorizer: () => companyAuthers.readPage.dynamicFields({}), + authorizer: () => companyAuth.readPage.dynamicFields({}), operation: async ({ prisma, params }) => await prisma.company.findMany({ ...cursorPageingSelection(params.paging.page), where: { @@ -51,7 +51,7 @@ export const companyOperations = { id: z.number(), }), dataSchema: companySchemas.update, - authorizer: () => companyAuthers.update.dynamicFields({}), + authorizer: () => companyAuth.update.dynamicFields({}), operation: async ({ prisma, params: { id }, data }) => { await prisma.company.update({ where: { id }, @@ -63,7 +63,7 @@ export const companyOperations = { paramsSchema: z.object({ id: z.number() }), - authorizer: () => companyAuthers.destroy.dynamicFields({}), + authorizer: () => companyAuth.destroy.dynamicFields({}), operation: async ({ prisma, params: { id } }) => { await prisma.company.delete({ where: { diff --git a/src/services/career/jobAds/authers.ts b/src/services/career/jobAds/auth.ts similarity index 94% rename from src/services/career/jobAds/authers.ts rename to src/services/career/jobAds/auth.ts index fa4639326..86b6543aa 100644 --- a/src/services/career/jobAds/authers.ts +++ b/src/services/career/jobAds/auth.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const jobAdAuthers = { +export const jobAdAuth = { create: RequirePermission.staticFields({ permission: 'JOBAD_CREATE' }), read: RequirePermission.staticFields({ permission: 'JOBAD_READ' }), readActive: RequirePermission.staticFields({ permission: 'JOBAD_READ' }), diff --git a/src/services/career/jobAds/operations.ts b/src/services/career/jobAds/operations.ts index e3595f5c2..52b99b342 100644 --- a/src/services/career/jobAds/operations.ts +++ b/src/services/career/jobAds/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { jobAdAuthers } from './authers' +import { jobAdAuth } from './auth' import { jobAdSchemas } from './schemas' import { articleAndCompanyIncluder, simpleArticleAndCompanyIncluder } from './constants' import { logoIncluder } from '@/services/career/companies/constants' @@ -17,7 +17,7 @@ import type { ExpandedJobAd, SimpleJobAd } from './Types' export const jobAdOperations = { create: defineOperation({ dataSchema: jobAdSchemas.create, - authorizer: () => jobAdAuthers.create.dynamicFields({}), + authorizer: () => jobAdAuth.create.dynamicFields({}), operation: async ({ prisma, data: { articleName, companyId, ...data } }) => { const article = await createArticle({ name: articleName }) @@ -58,7 +58,7 @@ export const jobAdOperations = { }), ]), }), - authorizer: () => jobAdAuthers.read.dynamicFields({}), + authorizer: () => jobAdAuth.read.dynamicFields({}), operation: async ({ prisma, params: { idOrName } }): Promise => { const jobAd = await prisma.jobAd.findUnique({ where: typeof idOrName === 'number' ? { @@ -85,7 +85,7 @@ export const jobAdOperations = { * @returns SimpleJobAd[] - all jobAds with coverImage */ readActive: defineOperation({ - authorizer: () => jobAdAuthers.readActive.dynamicFields({}), + authorizer: () => jobAdAuth.readActive.dynamicFields({}), operation: async ({ prisma }): Promise => { const jobAds = await prisma.jobAd.findMany({ orderBy: { @@ -120,7 +120,7 @@ export const jobAdOperations = { type: z.nativeEnum(JobType).nullable(), }), ), - authorizer: () => jobAdAuthers.readInactivePage.dynamicFields({}), + authorizer: () => jobAdAuth.readInactivePage.dynamicFields({}), operation: async ({ prisma, params }): Promise => { const jobAds = await prisma.jobAd.findMany({ ...cursorPageingSelection(params.paging.page), @@ -154,7 +154,7 @@ export const jobAdOperations = { id: z.number(), }), dataSchema: jobAdSchemas.update, - authorizer: () => jobAdAuthers.update.dynamicFields({}), + authorizer: () => jobAdAuth.update.dynamicFields({}), operation: async ({ prisma, params: { id }, data }) => await prisma.jobAd.update({ where: { id }, data, @@ -164,7 +164,7 @@ export const jobAdOperations = { paramsSchema: z.object({ id: z.number(), }), - authorizer: () => jobAdAuthers.destroy.dynamicFields({}), + authorizer: () => jobAdAuth.destroy.dynamicFields({}), operation: async ({ prisma, params: { id } }) => { const jobAd = await prisma.jobAd.delete({ where: { id }, diff --git a/src/services/cms/links/auth.ts b/src/services/cms/links/auth.ts new file mode 100644 index 000000000..7da372fc7 --- /dev/null +++ b/src/services/cms/links/auth.ts @@ -0,0 +1,3 @@ +import { RequireNothing } from '@/auth/auther/RequireNothing' + +export const readSpecialCmsLinkAuth = RequireNothing.staticFields({}) diff --git a/src/services/cms/links/authers.ts b/src/services/cms/links/authers.ts deleted file mode 100644 index 692502bf7..000000000 --- a/src/services/cms/links/authers.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { RequireNothing } from '@/auth/auther/RequireNothing' - -export const readSpecialCmsLinkAuther = RequireNothing.staticFields({}) diff --git a/src/services/cms/links/read.ts b/src/services/cms/links/read.ts index 70ba09c49..0219e0edd 100644 --- a/src/services/cms/links/read.ts +++ b/src/services/cms/links/read.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { readSpecialCmsLinkAuther } from './authers' +import { readSpecialCmsLinkAuth } from './auth' import logger from '@/lib/logger' import { defineOperation } from '@/services/serviceOperation' import { SpecialCmsLink } from '@prisma/client' @@ -9,7 +9,7 @@ export const readSpecialCmsLink = defineOperation({ paramsSchema: z.object({ special: z.nativeEnum(SpecialCmsLink), }), - authorizer: () => readSpecialCmsLinkAuther.dynamicFields({}), + authorizer: () => readSpecialCmsLinkAuth.dynamicFields({}), operation: async ({ prisma, params: { special } }) => { const cmsLink = await prisma.cmsLink.findUnique({ where: { special } diff --git a/src/services/dots/authers.ts b/src/services/dots/auth.ts similarity index 96% rename from src/services/dots/authers.ts rename to src/services/dots/auth.ts index f0e2bc333..386421be0 100644 --- a/src/services/dots/authers.ts +++ b/src/services/dots/auth.ts @@ -2,7 +2,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import { RequirePermissionAndUserId } from '@/auth/auther/RequirePermissionAndUserId' import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' -export const dotAuthers = { +export const dotAuth = { create: RequirePermissionAndUserId.staticFields({ permission: 'DOTS_ADMIN' }), update: RequirePermission.staticFields({ permission: 'DOTS_ADMIN' }), destroy: RequirePermission.staticFields({ permission: 'DOTS_ADMIN' }), diff --git a/src/services/dots/operations.ts b/src/services/dots/operations.ts index 91dddd561..32a7a5652 100644 --- a/src/services/dots/operations.ts +++ b/src/services/dots/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { dotAuthers } from './authers' +import { dotAuth } from './auth' import { dotSchemas } from './schemas' import { dotBaseDuration, dotsIncluder } from './constants' import { defineOperation } from '@/services/serviceOperation' @@ -13,7 +13,7 @@ import { z } from 'zod' * @returns All dots for the user in ascending order of expiration. i.e the dot that expires first will be first in the list */ const readForUser = defineOperation({ - authorizer: ({ params }) => dotAuthers.readForUser.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => dotAuth.readForUser.dynamicFields({ userId: params.userId }), paramsSchema: z.object({ userId: z.number(), onlyActive: z.boolean(), @@ -35,7 +35,7 @@ const readForUser = defineOperation({ const create = defineOperation({ dataSchema: dotSchemas.create, - authorizer: ({ data }) => dotAuthers.create.dynamicFields({ userId: data.userId }), + authorizer: ({ data }) => dotAuth.create.dynamicFields({ userId: data.userId }), paramsSchema: z.object({ accuserId: z.number(), }), @@ -71,7 +71,7 @@ const create = defineOperation({ }) const readWrappersForUser = defineOperation({ - authorizer: ({ params }) => dotAuthers.readWrapperForUser.dynamicFields({ userId: params.userId }), + authorizer: ({ params }) => dotAuth.readWrapperForUser.dynamicFields({ userId: params.userId }), paramsSchema: z.object({ userId: z.number(), }), @@ -95,7 +95,7 @@ const readWrappersForUser = defineOperation({ }) const readPage = defineOperation({ - authorizer: () => dotAuthers.readPage.dynamicFields({}), + authorizer: () => dotAuth.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), z.object({ diff --git a/src/services/events/authers.ts b/src/services/events/auth.ts similarity index 94% rename from src/services/events/authers.ts rename to src/services/events/auth.ts index 5e7b503fb..7f705b74e 100644 --- a/src/services/events/authers.ts +++ b/src/services/events/auth.ts @@ -1,7 +1,7 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequirePermission } from '@/auth/auther/RequirePermission' -export const eventAuthers = { +export const eventAuth = { create: RequirePermission.staticFields({ permission: 'EVENT_CREATE' }), // TODO: Replace below with proper authers read: RequireNothing.staticFields({}), diff --git a/src/services/events/operations.ts b/src/services/events/operations.ts index f709820ba..5715b975a 100644 --- a/src/services/events/operations.ts +++ b/src/services/events/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { eventAuthers } from './authers' +import { eventAuth } from './auth' import { eventSchemas } from './schemas' import { eventFilterSelection } from './constants' import { notificationOperations } from '@/services/notifications/operations' @@ -19,7 +19,7 @@ import type { EventExpanded } from './Types' export const eventOperations = { create: defineOperation({ dataSchema: eventSchemas.create, - authorizer: () => eventAuthers.create.dynamicFields({}), + authorizer: () => eventAuth.create.dynamicFields({}), operation: async ({ prisma, data, session }) => { const cmsParagraph = await createCmsParagraph({ name: uuid() }) const cmsImage = await createCmsImage({ name: uuid() }) @@ -97,7 +97,7 @@ export const eventOperations = { order: z.number(), name: z.string(), }), - authorizer: () => eventAuthers.read.dynamicFields({}), + authorizer: () => eventAuth.read.dynamicFields({}), operation: async ({ prisma, params, session }) => { const event = await prisma.event.findUniqueOrThrow({ where: { @@ -159,7 +159,7 @@ export const eventOperations = { paramsSchema: z.object({ tags: z.array(z.string()).nullable(), }), - authorizer: () => eventAuthers.readManyCurrent.dynamicFields({}), + authorizer: () => eventAuth.readManyCurrent.dynamicFields({}), operation: async ({ prisma, params }): Promise => { const events = await prisma.event.findMany({ select: { @@ -201,7 +201,7 @@ export const eventOperations = { tags: z.array(z.string()).nullable(), }), ), // Converted from ReadPageInput - authorizer: () => eventAuthers.readManyArchivedPage.dynamicFields({}), + authorizer: () => eventAuth.readManyArchivedPage.dynamicFields({}), operation: async ({ prisma, params }): Promise => { const events = await prisma.event.findMany({ ...cursorPageingSelection(params.paging.page), @@ -242,7 +242,7 @@ export const eventOperations = { id: z.number(), }), dataSchema: eventSchemas.update, - authorizer: () => eventAuthers.update.dynamicFields({}), + authorizer: () => eventAuth.update.dynamicFields({}), operation: async ({ prisma, params, data: { tagIds, ...data } }) => { const event = await prisma.event.findUniqueOrThrow({ where: { id: params.id } @@ -292,7 +292,7 @@ export const eventOperations = { paramsSchema: z.object({ id: z.number() }), - authorizer: () => eventAuthers.destroy.dynamicFields({}), + authorizer: () => eventAuth.destroy.dynamicFields({}), operation: async ({ prisma, params }) => { await prisma.event.delete({ where: { diff --git a/src/services/events/registration/authers.ts b/src/services/events/registration/auth.ts similarity index 95% rename from src/services/events/registration/authers.ts rename to src/services/events/registration/auth.ts index 5bfa27c7c..9001b5872 100644 --- a/src/services/events/registration/authers.ts +++ b/src/services/events/registration/auth.ts @@ -3,7 +3,7 @@ import { RequirePermissionAndUser } from '@/auth/auther/RequirePermissionAndUser import { RequireUser } from '@/auth/auther/RequireUser' import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' -export const eventRegistrationAuthers = { +export const eventRegistrationAuth = { // TODO: Fix authing create: RequireUserIdOrPermission.staticFields({ permission: 'EVENT_REGISTRATION_CREATE' }), createGuest: RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }), diff --git a/src/services/events/registration/operations.ts b/src/services/events/registration/operations.ts index bed346469..b9edcba4b 100644 --- a/src/services/events/registration/operations.ts +++ b/src/services/events/registration/operations.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { eventRegistrationIncluderDetailed, eventRegistrationSelection, REGISTRATION_READER_TYPE } from './constants' -import { eventRegistrationAuthers } from './authers' +import { eventRegistrationAuth } from './auth' import { eventRegistrationSchemas } from './schemas' import { Smorekopp } from '@/services/error' import { imageOperations } from '@/services/images/operations' @@ -130,7 +130,7 @@ export const eventRegistrationOperations = { userId: z.number().min(0), eventId: z.number().min(0), }), - authorizer: ({ params }) => eventRegistrationAuthers.create.dynamicFields({ + authorizer: ({ params }) => eventRegistrationAuth.create.dynamicFields({ userId: params.userId, }), opensTransaction: true, @@ -163,7 +163,7 @@ export const eventRegistrationOperations = { }), createGuest: defineOperation({ - authorizer: () => eventRegistrationAuthers.createGuest.dynamicFields({}), + authorizer: () => eventRegistrationAuth.createGuest.dynamicFields({}), paramsSchema: z.object({ eventId: z.number(), }), @@ -197,7 +197,7 @@ export const eventRegistrationOperations = { }), readMany: defineOperation({ - authorizer: () => eventRegistrationAuthers.readMany.dynamicFields({}), + authorizer: () => eventRegistrationAuth.readMany.dynamicFields({}), paramsSchema: z.object({ eventId: z.number().min(0), skip: z.number().optional(), @@ -231,7 +231,7 @@ export const eventRegistrationOperations = { }), readManyDetailed: defineOperation({ - authorizer: () => eventRegistrationAuthers.readManyDetailed.dynamicFields({}), + authorizer: () => eventRegistrationAuth.readManyDetailed.dynamicFields({}), paramsSchema: z.object({ eventId: z.number().min(0), skip: z.number().optional(), @@ -256,7 +256,7 @@ export const eventRegistrationOperations = { }), updateNotes: defineOperation({ - authorizer: () => eventRegistrationAuthers.updateRegistrationNotes.dynamicFields({}), + authorizer: () => eventRegistrationAuth.updateRegistrationNotes.dynamicFields({}), paramsSchema: z.object({ registrationId: z.number().min(0), }), @@ -292,7 +292,7 @@ export const eventRegistrationOperations = { }), destroy: defineOperation({ - authorizer: () => eventRegistrationAuthers.destroy.dynamicFields({}), + authorizer: () => eventRegistrationAuth.destroy.dynamicFields({}), paramsSchema: z.object({ registrationId: z.number().min(0), }), diff --git a/src/services/events/tags/authers.ts b/src/services/events/tags/auth.ts similarity index 93% rename from src/services/events/tags/authers.ts rename to src/services/events/tags/auth.ts index 32d666be2..ef6bbeaed 100644 --- a/src/services/events/tags/authers.ts +++ b/src/services/events/tags/auth.ts @@ -1,7 +1,7 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequirePermission } from '@/auth/auther/RequirePermission' -export const eventTagAuthers = { +export const eventTagAuth = { create: RequirePermission.staticFields({ permission: 'EVENT_ADMIN' }), readSpecial: RequireNothing.staticFields({}), read: RequireNothing.staticFields({}), diff --git a/src/services/events/tags/operations.ts b/src/services/events/tags/operations.ts index 8dbf5f2a8..582fdf6f8 100644 --- a/src/services/events/tags/operations.ts +++ b/src/services/events/tags/operations.ts @@ -1,8 +1,8 @@ import '@pn-server-only' -import { eventTagAuthers } from './authers' +import { eventTagAuth } from './auth' import { specialEventTags } from './constants' import { eventTagSchemas } from './schemas' -import { eventAuthers } from '@/services/events/authers' +import { eventAuth } from '@/services/events/auth' import logger from '@/lib/logger' import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' @@ -14,7 +14,7 @@ export const eventTagOperations = { paramsSchema: z.object({ id: z.number(), }), - authorizer: () => eventTagAuthers.read.dynamicFields({}), + authorizer: () => eventTagAuth.read.dynamicFields({}), operation: async ({ prisma, params: { id } }) => await prisma.eventTag.findUniqueOrThrow({ where: { id @@ -25,7 +25,7 @@ export const eventTagOperations = { paramsSchema: z.object({ special: z.nativeEnum(SpecialEventTags), }), - authorizer: () => eventTagAuthers.readSpecial.dynamicFields({}), + authorizer: () => eventTagAuth.readSpecial.dynamicFields({}), operation: async ({ prisma, params: { special } }) => { const tag = await prisma.eventTag.findUnique({ where: { @@ -45,12 +45,12 @@ export const eventTagOperations = { } }), readAll: defineOperation({ - authorizer: () => eventTagAuthers.readAll.dynamicFields({}), + authorizer: () => eventTagAuth.readAll.dynamicFields({}), operation: async ({ prisma }) => await prisma.eventTag.findMany() }), create: defineOperation({ dataSchema: eventTagSchemas.create, - authorizer: () => eventTagAuthers.create.dynamicFields({}), + authorizer: () => eventTagAuth.create.dynamicFields({}), operation: async ({ prisma, data: { color, ...data } }) => { const colorR = parseInt(color.slice(1, 3), 16) const colorG = parseInt(color.slice(3, 5), 16) @@ -70,7 +70,7 @@ export const eventTagOperations = { id: z.number(), }), dataSchema: eventTagSchemas.update, - authorizer: () => eventAuthers.update.dynamicFields({}), + authorizer: () => eventAuth.update.dynamicFields({}), operation: async ({ prisma, params: { id }, data: { color, ...data } }) => { const colorR = color ? parseInt(color.slice(1, 3), 16) : undefined const colorG = color ? parseInt(color.slice(3, 5), 16) : undefined @@ -92,7 +92,7 @@ export const eventTagOperations = { paramsSchema: z.object({ id: z.number(), }), - authorizer: () => eventAuthers.destroy.dynamicFields({}), + authorizer: () => eventAuth.destroy.dynamicFields({}), operation: async ({ prisma, params }) => { const tag = await prisma.eventTag.findUniqueOrThrow({ where: { id: params.id } diff --git a/src/services/groups/authers.ts b/src/services/groups/auth.ts similarity index 82% rename from src/services/groups/authers.ts rename to src/services/groups/auth.ts index 0dddbedf8..ec5781366 100644 --- a/src/services/groups/authers.ts +++ b/src/services/groups/auth.ts @@ -1,5 +1,5 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const groupAuthers = { +export const groupAuth = { read: RequirePermission.staticFields({ permission: 'GROUP_READ' }), } diff --git a/src/services/groups/committees/authers.ts b/src/services/groups/committees/auth.ts similarity index 81% rename from src/services/groups/committees/authers.ts rename to src/services/groups/committees/auth.ts index 8d07f05de..79566f8bf 100644 --- a/src/services/groups/committees/authers.ts +++ b/src/services/groups/committees/auth.ts @@ -1,5 +1,5 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const committeeAuthers = { +export const committeeAuth = { read: RequirePermission.staticFields({ permission: 'COMMITTEE_READ' }), } diff --git a/src/services/groups/committees/operations.ts b/src/services/groups/committees/operations.ts index 405c53fe3..2816f70ac 100644 --- a/src/services/groups/committees/operations.ts +++ b/src/services/groups/committees/operations.ts @@ -1,4 +1,4 @@ -import { committeeAuthers } from './authers' +import { committeeAuth } from './auth' import { committeeExpandedIncluder, committeeLogoIncluder, membershipIncluder } from './constants' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { articleRealtionsIncluder } from '@/cms/articles/ConfigVars' @@ -9,14 +9,14 @@ import { z } from 'zod' export const committeeOperations = { readCommittees: defineOperation({ - authorizer: () => committeeAuthers.read.dynamicFields({}), + authorizer: () => committeeAuth.read.dynamicFields({}), operation: async ({ prisma }) => prisma.committee.findMany({ include: committeeLogoIncluder, }) }), readCommittee: defineOperation({ - authorizer: () => committeeAuthers.read.dynamicFields({}), + authorizer: () => committeeAuth.read.dynamicFields({}), paramsSchema: z.union([ z.object({ id: z.number() }), z.object({ shortName: z.string() }) @@ -50,7 +50,7 @@ export const committeeOperations = { }), readCommitteArticle: defineOperation({ - authorizer: () => committeeAuthers.read.dynamicFields({}), + authorizer: () => committeeAuth.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), }), @@ -80,7 +80,7 @@ export const committeeOperations = { }), readCommitteeParagraph: defineOperation({ - authorizer: () => committeeAuthers.read.dynamicFields({}), + authorizer: () => committeeAuth.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), }), @@ -93,7 +93,7 @@ export const committeeOperations = { }), readCommitteeMembers: defineOperation({ - authorizer: () => committeeAuthers.read.dynamicFields({}), + authorizer: () => committeeAuth.read.dynamicFields({}), paramsSchema: z.object({ shortName: z.string(), active: z.boolean().optional(), diff --git a/src/services/groups/interestGroups/authers.ts b/src/services/groups/interestGroups/auth.ts similarity index 93% rename from src/services/groups/interestGroups/authers.ts rename to src/services/groups/interestGroups/auth.ts index c8d01f33f..b61dd6cf7 100644 --- a/src/services/groups/interestGroups/authers.ts +++ b/src/services/groups/interestGroups/auth.ts @@ -1,7 +1,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import { RequirePermissionOrGroupAdmin } from '@/auth/auther/RequirePermissionOrGroupAdmin' -export const interestGroupAuthers = { +export const interestGroupAuth = { create: RequirePermission.staticFields({ permission: 'INTEREST_GROUP_ADMIN' }), read: RequirePermission.staticFields({ permission: 'INTEREST_GROUP_READ' }), readMany: RequirePermission.staticFields({ permission: 'INTEREST_GROUP_READ' }), diff --git a/src/services/groups/interestGroups/operations.ts b/src/services/groups/interestGroups/operations.ts index f651a9498..74fe42e28 100644 --- a/src/services/groups/interestGroups/operations.ts +++ b/src/services/groups/interestGroups/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { interestGroupAuthers } from './authers' +import { interestGroupAuth } from './auth' import { interestGroupSchemas } from './schemas' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { articleSectionsRealtionsIncluder } from '@/services/cms/articleSections/ConfigVars' @@ -10,7 +10,7 @@ import type { ExpandedInterestGroup } from './Types' export const interestGroupOperations = { create: defineOperation({ dataSchema: interestGroupSchemas.create, - authorizer: () => interestGroupAuthers.create.dynamicFields({}), + authorizer: () => interestGroupAuth.create.dynamicFields({}), operation: async ({ prisma, data }) => { const { order } = await readCurrentOmegaOrder() @@ -36,7 +36,7 @@ export const interestGroupOperations = { }), readMany: defineOperation({ - authorizer: () => interestGroupAuthers.readMany.dynamicFields({}), + authorizer: () => interestGroupAuth.readMany.dynamicFields({}), operation: async ({ prisma }): Promise => prisma.interestGroup.findMany({ include: { articleSection: { @@ -55,7 +55,7 @@ export const interestGroupOperations = { id: z.number().optional(), shortName: z.string().optional(), }), - authorizer: () => interestGroupAuthers.read.dynamicFields({}), + authorizer: () => interestGroupAuth.read.dynamicFields({}), operation: async ({ prisma, params: { id, shortName } }) => await prisma.interestGroup.findUniqueOrThrow({ where: { id, @@ -80,7 +80,7 @@ export const interestGroupOperations = { select: { groupId: true }, }) - return interestGroupAuthers.update.dynamicFields({ + return interestGroupAuth.update.dynamicFields({ groupId, }) }, @@ -94,7 +94,7 @@ export const interestGroupOperations = { paramsSchema: z.object({ id: z.number(), }), - authorizer: () => interestGroupAuthers.destroy.dynamicFields({}), + authorizer: () => interestGroupAuth.destroy.dynamicFields({}), opensTransaction: true, operation: async ({ prisma, params: { id } }) => { await prisma.$transaction(async tx => { diff --git a/src/services/groups/operations.ts b/src/services/groups/operations.ts index aac34e84b..08cbbcee7 100644 --- a/src/services/groups/operations.ts +++ b/src/services/groups/operations.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { groupsExpandedIncluder, groupTypesConfig, OmegaMembershipLevelConfig, readGroupsOfUserIncluder } from './constants' -import { groupAuthers } from './authers' +import { groupAuth } from './auth' import { userFilterSelection } from '@/services/users/constants' import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' @@ -189,7 +189,7 @@ export function checkGroupValidity< export const groupOperations = { readGroups: defineOperation({ - authorizer: () => groupAuthers.read.dynamicFields({}), + authorizer: () => groupAuth.read.dynamicFields({}), operation: async ({ prisma }) => prisma.group.findMany() }), @@ -239,7 +239,7 @@ export const groupOperations = { }), readGroupExpanded: defineOperation({ - authorizer: () => groupAuthers.read.dynamicFields({}), + authorizer: () => groupAuth.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -255,7 +255,7 @@ export const groupOperations = { }), readGroupsExpanded: defineOperation({ - authorizer: () => groupAuthers.read.dynamicFields({}), + authorizer: () => groupAuth.read.dynamicFields({}), operation: async ({ prisma }) => { const groups = (await prisma.group.findMany({ include: groupsExpandedIncluder, @@ -266,7 +266,7 @@ export const groupOperations = { }), readGroupsStructured: defineOperation({ - authorizer: () => groupAuthers.read.dynamicFields({}), + authorizer: () => groupAuth.read.dynamicFields({}), operation: async () => { const groupsStructured: GroupsStructured = { CLASS: { diff --git a/src/services/images/authers.ts b/src/services/images/auth.ts similarity index 94% rename from src/services/images/authers.ts rename to src/services/images/auth.ts index 6dcea3636..5f4a7cf2d 100644 --- a/src/services/images/authers.ts +++ b/src/services/images/auth.ts @@ -1,7 +1,7 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' //TODO: Implement proper authers -export const imageAuthers = { +export const imageAuth = { create: RequireNothing.staticFields({}), createMany: RequireNothing.staticFields({}), createSourcelessImage: RequireNothing.staticFields({}), diff --git a/src/services/images/operations.ts b/src/services/images/operations.ts index c2ecd0711..ff0563a56 100644 --- a/src/services/images/operations.ts +++ b/src/services/images/operations.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { readSpecialImageCollection } from './collections/read' -import { imageAuthers } from './authers' +import { imageAuth } from './auth' import { imageSchemas } from './schemas' import { allowedExtensions, avifConvertionOptions, imageSizes } from './constants' import { defineOperation } from '@/services/serviceOperation' @@ -37,7 +37,7 @@ async function createOneInStore(file: File, allowedExt: string[], size: number) * @param config - the config for the image (special) */ const createSourceless = defineOperation({ - authorizer: () => imageAuthers.createSourcelessImage.dynamicFields({}), + authorizer: () => imageAuth.createSourcelessImage.dynamicFields({}), paramsSchema: z.object({ name: z.string(), special: z.nativeEnum(SpecialImage), @@ -77,7 +77,7 @@ export const imageOperations = { * @param collectionId - The id of the collection to add the image to */ create: defineOperation({ - authorizer: () => imageAuthers.create.dynamicFields({}), + authorizer: () => imageAuth.create.dynamicFields({}), paramsSchema: z.object({ collectionId: z.number(), }), @@ -126,7 +126,7 @@ export const imageOperations = { * The method will resize the images to the correct sizes and save them to the store. */ createMany: defineOperation({ - authorizer: () => imageAuthers.createMany.dynamicFields({}), + authorizer: () => imageAuth.createMany.dynamicFields({}), paramsSchema: z.object({ useFileName: z.boolean(), collectionId: z.number(), @@ -152,7 +152,7 @@ export const imageOperations = { * Reads an image by id. */ read: defineOperation({ - authorizer: () => imageAuthers.read.dynamicFields({}), + authorizer: () => imageAuth.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -172,7 +172,7 @@ export const imageOperations = { * Reads a page of images in a collection by collectionId. */ readPage: defineOperation({ - authorizer: () => imageAuthers.readPage.dynamicFields({}), + authorizer: () => imageAuth.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), z.object({ @@ -198,7 +198,7 @@ export const imageOperations = { * In the case that the special image does not exist (bad state) a "bad" image will be created. */ readSpecial: defineOperation({ - authorizer: () => imageAuthers.readSpecial.dynamicFields({}), + authorizer: () => imageAuth.readSpecial.dynamicFields({}), paramsSchema: z.object({ special: z.nativeEnum(SpecialImage) }), @@ -222,7 +222,7 @@ export const imageOperations = { * Update a image by id and data. Also can give the image a new license by data.licenseId. */ update: defineOperation({ - authorizer: () => imageAuthers.update.dynamicFields({}), + authorizer: () => imageAuth.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -244,7 +244,7 @@ export const imageOperations = { }), destroy: defineOperation({ - authorizer: () => imageAuthers.destroy.dynamicFields({}), + authorizer: () => imageAuth.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/licenses/authers.ts b/src/services/licenses/auth.ts similarity index 92% rename from src/services/licenses/authers.ts rename to src/services/licenses/auth.ts index ce2890d70..9f81be925 100644 --- a/src/services/licenses/authers.ts +++ b/src/services/licenses/auth.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const licenseAuthers = { +export const licenseAuth = { create: RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }), read: RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }), update: RequirePermission.staticFields({ permission: 'LICENSE_ADMIN' }), diff --git a/src/services/licenses/operations.ts b/src/services/licenses/operations.ts index b13de25ee..77dbc300c 100644 --- a/src/services/licenses/operations.ts +++ b/src/services/licenses/operations.ts @@ -1,27 +1,27 @@ import '@pn-server-only' import { licenseSchemas } from './schemas' -import { licenseAuthers } from './authers' +import { licenseAuth } from './auth' import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' import { z } from 'zod' export const licenseOperations = { create: defineOperation({ - authorizer: () => licenseAuthers.create.dynamicFields({}), + authorizer: () => licenseAuth.create.dynamicFields({}), dataSchema: licenseSchemas.create, operation: async ({ prisma, data }) => await prisma.license.create({ data, }), }), readAll: defineOperation({ - authorizer: () => licenseAuthers.destroy.dynamicFields({}), + authorizer: () => licenseAuth.destroy.dynamicFields({}), operation: async ({ prisma }) => await prisma.license.findMany() }), destroy: defineOperation({ paramsSchema: z.object({ id: z.number(), }), - authorizer: () => licenseAuthers.destroy.dynamicFields({}), + authorizer: () => licenseAuth.destroy.dynamicFields({}), operation: async ({ prisma, params }) => { const { name: licenseName } = await prisma.license.findUniqueOrThrow({ where: { id: params.id }, @@ -49,7 +49,7 @@ export const licenseOperations = { id: z.number(), }), dataSchema: licenseSchemas.update, - authorizer: () => licenseAuthers.update.dynamicFields({}), + authorizer: () => licenseAuth.update.dynamicFields({}), operation: async ({ prisma, params, data }) => { await prisma.license.update({ where: { diff --git a/src/services/lockers/authers.ts b/src/services/lockers/auth.ts similarity index 90% rename from src/services/lockers/authers.ts rename to src/services/lockers/auth.ts index cc4ebe32e..e37160731 100644 --- a/src/services/lockers/authers.ts +++ b/src/services/lockers/auth.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const lockerAuthers = { +export const lockerAuth = { create: RequirePermission.staticFields({ permission: 'LOCKER_ADMIN' }), read: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), readPage: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), diff --git a/src/services/lockers/locations/authers.ts b/src/services/lockers/locations/auth.ts similarity index 86% rename from src/services/lockers/locations/authers.ts rename to src/services/lockers/locations/auth.ts index c10d0bd2a..360773e0d 100644 --- a/src/services/lockers/locations/authers.ts +++ b/src/services/lockers/locations/auth.ts @@ -1,7 +1,7 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequirePermission } from '@/auth/auther/RequirePermission' -export const lockerLocationAuthers = { +export const lockerLocationAuth = { create: RequirePermission.staticFields({ permission: 'LOCKER_ADMIN' }), readAll: RequireNothing.staticFields({}), } diff --git a/src/services/lockers/locations/operations.ts b/src/services/lockers/locations/operations.ts index d438e1732..ddd637b3e 100644 --- a/src/services/lockers/locations/operations.ts +++ b/src/services/lockers/locations/operations.ts @@ -1,4 +1,4 @@ -import { lockerLocationAuthers } from './authers' +import { lockerLocationAuth } from './auth' import { lockersSchemas } from '@/services/lockers/schemas' import { defineOperation } from '@/services/serviceOperation' @@ -11,7 +11,7 @@ export const lockerLocationOperations = { * @returns The newly created locker location object. */ create: defineOperation({ - authorizer: () => lockerLocationAuthers.create.dynamicFields({}), + authorizer: () => lockerLocationAuth.create.dynamicFields({}), dataSchema: lockersSchemas.createLocation, operation: async ({ prisma, data }) => prisma.lockerLocation.create({ data: { @@ -27,7 +27,7 @@ export const lockerLocationOperations = { * @returns All locker location objects. */ readAll: defineOperation({ - authorizer: () => lockerLocationAuthers.readAll.dynamicFields({}), + authorizer: () => lockerLocationAuth.readAll.dynamicFields({}), operation: async ({ prisma }) => prisma.lockerLocation.findMany() }), } diff --git a/src/services/lockers/operations.ts b/src/services/lockers/operations.ts index ba28a8d1e..9a3a838c9 100644 --- a/src/services/lockers/operations.ts +++ b/src/services/lockers/operations.ts @@ -1,7 +1,7 @@ import '@pn-server-only' import { lockerReservationIncluder } from './reservations/constants' import { lockersSchemas } from './schemas' -import { lockerAuthers } from './authers' +import { lockerAuth } from './auth' import { defineOperation } from '@/services/serviceOperation' import { ServerError } from '@/services/error' import { readPageInputSchemaObject } from '@/lib/paging/schema' @@ -41,7 +41,7 @@ export const lockerOperations = { * @returns The newly created locker object. */ create: defineOperation({ - authorizer: () => lockerAuthers.create.dynamicFields({}), + authorizer: () => lockerAuth.create.dynamicFields({}), dataSchema: lockersSchemas.create, operation: async ({ prisma, data }) => { console.log(data) @@ -59,7 +59,7 @@ export const lockerOperations = { * @returns The locker object. */ read: defineOperation({ - authorizer: () => lockerAuthers.read.dynamicFields({}), + authorizer: () => lockerAuth.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -85,7 +85,7 @@ export const lockerOperations = { * @returns A list of locker objects. */ readPage: defineOperation({ - authorizer: () => lockerAuthers.readPage.dynamicFields({}), + authorizer: () => lockerAuth.readPage.dynamicFields({}), paramsSchema: readPageInputSchemaObject( z.number(), z.object({ diff --git a/src/services/lockers/reservations/authers.ts b/src/services/lockers/reservations/auth.ts similarity index 87% rename from src/services/lockers/reservations/authers.ts rename to src/services/lockers/reservations/auth.ts index 2a0861774..b1617e547 100644 --- a/src/services/lockers/reservations/authers.ts +++ b/src/services/lockers/reservations/auth.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const lockerReservationAuthers = { +export const lockerReservationAuth = { create: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), read: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), update: RequirePermission.staticFields({ permission: 'LOCKER_USE' }), diff --git a/src/services/lockers/reservations/operations.ts b/src/services/lockers/reservations/operations.ts index e1ccdb467..b6cc28723 100644 --- a/src/services/lockers/reservations/operations.ts +++ b/src/services/lockers/reservations/operations.ts @@ -1,6 +1,6 @@ import '@pn-server-only' -import { lockerReservationAuthers } from './authers' +import { lockerReservationAuth } from './auth' import { lockerReservationSchemas } from './schemas' import { defineOperation } from '@/services/serviceOperation' import { Smorekopp } from '@/services/error' @@ -17,7 +17,7 @@ export const lockerReservationOperations = { * @returns The newly created reservation object. */ create: defineOperation({ - authorizer: () => lockerReservationAuthers.create.dynamicFields({}), + authorizer: () => lockerReservationAuth.create.dynamicFields({}), paramsSchema: z.object({ lockerId: z.number(), }), @@ -64,7 +64,7 @@ export const lockerReservationOperations = { * @returns The updated reservation object. */ read: defineOperation({ - authorizer: () => lockerReservationAuthers.read.dynamicFields({}), + authorizer: () => lockerReservationAuth.read.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), @@ -84,7 +84,7 @@ export const lockerReservationOperations = { * @returns The updated reservation object. */ update: defineOperation({ - authorizer: () => lockerReservationAuthers.update.dynamicFields({}), + authorizer: () => lockerReservationAuth.update.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/notifications/authers.ts b/src/services/notifications/auth.ts similarity index 87% rename from src/services/notifications/authers.ts rename to src/services/notifications/auth.ts index 9f4459501..641137b1e 100644 --- a/src/services/notifications/authers.ts +++ b/src/services/notifications/auth.ts @@ -1,7 +1,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import '@pn-server-only' -export const notificationAuthers = { +export const notificationAuth = { create: RequirePermission.staticFields({ permission: 'NOTIFICATION_CREATE' }), sendMail: RequirePermission.staticFields({ permission: 'MAIL_SEND' }), } diff --git a/src/services/notifications/channel/authers.ts b/src/services/notifications/channel/auth.ts similarity index 91% rename from src/services/notifications/channel/authers.ts rename to src/services/notifications/channel/auth.ts index f9ab00947..821826a3f 100644 --- a/src/services/notifications/channel/authers.ts +++ b/src/services/notifications/channel/auth.ts @@ -1,7 +1,7 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' import '@pn-server-only' -export const notificationChannelAuthers = { +export const notificationChannelAuth = { create: RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_CREATE' }), read: RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_READ' }), update: RequirePermission.staticFields({ permission: 'NOTIFICATION_CHANNEL_UPDATE' }), diff --git a/src/services/notifications/channel/operations.ts b/src/services/notifications/channel/operations.ts index b4690ff1f..e10638ce3 100644 --- a/src/services/notifications/channel/operations.ts +++ b/src/services/notifications/channel/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { notificationChannelAuthers } from './authers' +import { notificationChannelAuth } from './auth' import { notificationChannelSchemas, validateMethods, validateNewParent } from './schemas' import { availableNotificationMethodIncluder } from './constants' import { @@ -17,7 +17,7 @@ import type { ExpandedNotificationChannel, NotificationMethodGeneral } from '@/s export const notificationChannelOperations = { create: defineOperation({ - authorizer: () => notificationChannelAuthers.create.dynamicFields({}), + authorizer: () => notificationChannelAuth.create.dynamicFields({}), dataSchema: notificationChannelSchemas.create, opensTransaction: true, paramsSchema: z.object({ @@ -105,14 +105,14 @@ export const notificationChannelOperations = { }), readMany: defineOperation({ - authorizer: () => notificationChannelAuthers.read.dynamicFields({}), + authorizer: () => notificationChannelAuth.read.dynamicFields({}), operation: async ({ prisma }) => await prisma.notificationChannel.findMany({ include: availableNotificationMethodIncluder, }) }), readDefault: defineOperation({ - authorizer: () => notificationChannelAuthers.read.dynamicFields({}), + authorizer: () => notificationChannelAuth.read.dynamicFields({}), operation: async ({ prisma }) => await prisma.notificationChannel.findMany({ where: { defaultMethods: { @@ -126,7 +126,7 @@ export const notificationChannelOperations = { }), update: defineOperation({ - authorizer: () => notificationChannelAuthers.update.dynamicFields({}), + authorizer: () => notificationChannelAuth.update.dynamicFields({}), dataSchema: notificationChannelSchemas.update, paramsSchema: z.object({ id: z.number(), @@ -219,7 +219,7 @@ export const notificationChannelOperations = { // It doesn't seem that this function is used yet. -Theodor destroy: defineOperation({ - authorizer: () => notificationChannelAuthers.destroy.dynamicFields({}), + authorizer: () => notificationChannelAuth.destroy.dynamicFields({}), paramsSchema: z.object({ id: z.number(), }), diff --git a/src/services/notifications/operations.ts b/src/services/notifications/operations.ts index 5e2499984..3e4460986 100644 --- a/src/services/notifications/operations.ts +++ b/src/services/notifications/operations.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { dispatchEmailNotifications } from './email/dispatch' -import { notificationAuthers } from './authers' +import { notificationAuth } from './auth' import { notificationSchemas } from './schemas' import { allNotificationMethodsOn, notificationMethodsArray } from './constants' import { availableNotificationMethodIncluder } from './channel/constants' @@ -36,7 +36,7 @@ export const notificationOperations = { * @returns A promise that resolves with an object containing the dispatched notification and the number of recipients. */ create: defineOperation({ - authorizer: () => notificationAuthers.create.dynamicFields({}), + authorizer: () => notificationAuth.create.dynamicFields({}), dataSchema: notificationSchemas.create, operation: async ({ prisma, data }): Promise => { // This prevent notifications from beeing sent during seeding diff --git a/src/services/notifications/subscription/authers.ts b/src/services/notifications/subscription/auth.ts similarity index 85% rename from src/services/notifications/subscription/authers.ts rename to src/services/notifications/subscription/auth.ts index 9e400742e..5616998a9 100644 --- a/src/services/notifications/subscription/authers.ts +++ b/src/services/notifications/subscription/auth.ts @@ -1,6 +1,6 @@ import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' -export const notificationSubscriptionAuthers = { +export const notificationSubscriptionAuth = { read: RequireUserIdOrPermission.staticFields({ permission: 'NOTIFICATION_SUBSCRIPTION_READ' }), update: RequireUserIdOrPermission.staticFields({ permission: 'NOTIFICATION_SUBSCRIPTION_UPDATE' }), } diff --git a/src/services/notifications/subscription/operations.ts b/src/services/notifications/subscription/operations.ts index 9ad3b8fbc..213582e74 100644 --- a/src/services/notifications/subscription/operations.ts +++ b/src/services/notifications/subscription/operations.ts @@ -1,5 +1,5 @@ import { notificationMethodIncluder } from './constants' -import { notificationSubscriptionAuthers } from './authers' +import { notificationSubscriptionAuth } from './auth' import { subscriptionSchemas } from './schemas' import { validateMethods } from '@/services/notifications/channel/schemas' import { allNotificationMethodsOff, allNotificationMethodsOn } from '@/services/notifications/constants' @@ -113,7 +113,7 @@ export const notificationSubscriptionOperations = { paramsSchema: z.object({ userId: z.number(), }), - authorizer: ({ params }) => notificationSubscriptionAuthers.read.dynamicFields(params), + authorizer: ({ params }) => notificationSubscriptionAuth.read.dynamicFields(params), operation: async ({ prisma, params }) => await prisma.notificationSubscription.findMany({ where: { userId: params.userId, @@ -158,7 +158,7 @@ export const notificationSubscriptionOperations = { update: defineOperation({ - authorizer: ({ params }) => notificationSubscriptionAuthers.update.dynamicFields(params), + authorizer: ({ params }) => notificationSubscriptionAuth.update.dynamicFields(params), paramsSchema: z.object({ userId: z.number(), }), diff --git a/src/services/permissions/auther.ts b/src/services/permissions/auth.ts similarity index 94% rename from src/services/permissions/auther.ts rename to src/services/permissions/auth.ts index 796ad3904..2714a93ed 100644 --- a/src/services/permissions/auther.ts +++ b/src/services/permissions/auth.ts @@ -2,7 +2,7 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequirePermission } from '@/auth/auther/RequirePermission' -export const permissionAuthers = { +export const permissionsAuth = { readGroupPermissions: RequirePermission.staticFields({ permission: 'PERMISSION_GROUP_READ' }), readPermissionMatrix: RequirePermission.staticFields({ permission: 'PERMISSION_GROUP_READ' }), updateGroupPermission: RequirePermission.staticFields({ permission: 'PERMISSION_GROUP_ADMIN' }), diff --git a/src/services/permissions/operations.ts b/src/services/permissions/operations.ts index 766996869..b2f65921f 100644 --- a/src/services/permissions/operations.ts +++ b/src/services/permissions/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { permissionAuthers } from './auther' +import { permissionsAuth } from './auth' import { defineOperation } from '@/services/serviceOperation' import { ServerOnlyAuther } from '@/auth/auther/RequireServer' import { invalidateAllUserSessionData, invalidateManyUserSessionData } from '@/services/auth/invalidateSession' @@ -11,7 +11,7 @@ import { z } from 'zod' export const permissionOperations = { readDefaultPermissions: defineOperation({ - authorizer: () => permissionAuthers.readDefaultPermissions.dynamicFields({}), + authorizer: () => permissionsAuth.readDefaultPermissions.dynamicFields({}), operation: async ({ prisma }) => (await prisma.defaultPermission.findMany()).map(perm => perm.permission) }), @@ -50,7 +50,7 @@ export const permissionOperations = { }), readPermissionsOfGroup: defineOperation({ - authorizer: () => permissionAuthers.readGroupPermissions.dynamicFields({}), + authorizer: () => permissionsAuth.readGroupPermissions.dynamicFields({}), paramsSchema: z.object({ groupId: z.number() }), @@ -62,7 +62,7 @@ export const permissionOperations = { }), readPermissionMatrix: defineOperation({ - authorizer: () => permissionAuthers.readPermissionMatrix.dynamicFields({}), + authorizer: () => permissionsAuth.readPermissionMatrix.dynamicFields({}), operation: async ({ prisma }) => { const groupsPermission = await prisma.group.findMany({ include: { @@ -80,7 +80,7 @@ export const permissionOperations = { }), updateDefaultPermissions: defineOperation({ - authorizer: () => permissionAuthers.updateDefaultPermissions.dynamicFields({}), + authorizer: () => permissionsAuth.updateDefaultPermissions.dynamicFields({}), dataSchema: z.object({ permissions: z.nativeEnum(Permission).array(), }), @@ -108,7 +108,7 @@ export const permissionOperations = { }), updateGroupPermission: defineOperation({ - authorizer: () => permissionAuthers.updateGroupPermission.dynamicFields({}), + authorizer: () => permissionsAuth.updateGroupPermission.dynamicFields({}), paramsSchema: z.object({ groupId: z.number(), permission: z.nativeEnum(Permission), diff --git a/src/services/shop/product/authers.ts b/src/services/shop/product/auth.ts similarity index 92% rename from src/services/shop/product/authers.ts rename to src/services/shop/product/auth.ts index 3751d9189..9dde385b5 100644 --- a/src/services/shop/product/authers.ts +++ b/src/services/shop/product/auth.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const productAuthers = { +export const productAuth = { read: RequirePermission.staticFields({ permission: 'PRODUCT_READ' }), create: RequirePermission.staticFields({ permission: 'PRODUCT_ADMIN' }), update: RequirePermission.staticFields({ permission: 'PRODUCT_ADMIN' }), diff --git a/src/services/shop/product/operations.ts b/src/services/shop/product/operations.ts index 345b9b9e7..c8338fdcd 100644 --- a/src/services/shop/product/operations.ts +++ b/src/services/shop/product/operations.ts @@ -3,12 +3,12 @@ import '@pn-server-only' import { ServerError } from '@/services/error' import { z } from 'zod' import type { ExtendedProduct } from './Types' -import { productAuthers } from './authers' +import { productAuth } from './auth' import { productSchemas } from './schemas' export const productOperations = { create: defineOperation({ - authorizer: () => productAuthers.create.dynamicFields({}), + authorizer: () => productAuth.create.dynamicFields({}), dataSchema: productSchemas.create, operation: async ({ prisma, data }) => prisma.product.create({ data: { @@ -20,7 +20,7 @@ export const productOperations = { }), createForShop: defineOperation({ - authorizer: () => productAuthers.create.dynamicFields({}), + authorizer: () => productAuth.create.dynamicFields({}), paramsSchema: z.object({ shopId: z.number(), }), @@ -45,7 +45,7 @@ export const productOperations = { }), createShopConnection: defineOperation({ - authorizer: () => productAuthers.createShopConnection.dynamicFields({}), + authorizer: () => productAuth.createShopConnection.dynamicFields({}), dataSchema: productSchemas.createShopConnection, operation: async ({ prisma, data }) => prisma.shopProduct.create({ data: { @@ -65,12 +65,12 @@ export const productOperations = { }), readMany: defineOperation({ - authorizer: () => productAuthers.read.dynamicFields({}), + authorizer: () => productAuth.read.dynamicFields({}), operation: async ({ prisma }) => await prisma.product.findMany() }), read: defineOperation({ - authorizer: () => productAuthers.read.dynamicFields({}), + authorizer: () => productAuth.read.dynamicFields({}), paramsSchema: z.object({ productId: z.number(), }), @@ -89,7 +89,7 @@ export const productOperations = { }), readByBarCode: defineOperation({ - authorizer: () => productAuthers.read.dynamicFields({}), + authorizer: () => productAuth.read.dynamicFields({}), dataSchema: productSchemas.readByBarCode, operation: async ({ prisma, data }): Promise => { if (!data.barcode) { @@ -131,7 +131,7 @@ export const productOperations = { }), update: defineOperation({ - authorizer: () => productAuthers.update.dynamicFields({}), + authorizer: () => productAuth.update.dynamicFields({}), dataSchema: productSchemas.update, operation: async ({ prisma, data }) => prisma.product.update({ where: { @@ -146,7 +146,7 @@ export const productOperations = { }), updateForShop: defineOperation({ - authorizer: () => productAuthers.update.dynamicFields({}), + authorizer: () => productAuth.update.dynamicFields({}), dataSchema: productSchemas.updateForShop, paramsSchema: z.object({ shopId: z.number(), diff --git a/src/services/shop/purchase/authers.ts b/src/services/shop/purchase/auth.ts similarity index 91% rename from src/services/shop/purchase/authers.ts rename to src/services/shop/purchase/auth.ts index 3f49f2565..8b24f0563 100644 --- a/src/services/shop/purchase/authers.ts +++ b/src/services/shop/purchase/auth.ts @@ -1,7 +1,7 @@ import { RequirePermissionAndDynamicPermission } from '@/auth/auther/RequirePermissionAndDynamicPermission' -export const purchaseAuthers = { +export const purchaseAuth = { createByStudentCard: RequirePermissionAndDynamicPermission.staticFields({ permission: 'PURCHASE_CREATE_ONBEHALF', dynamicPermission: 'PURCHASE_CREATE', diff --git a/src/services/shop/purchase/operations.ts b/src/services/shop/purchase/operations.ts index dcb7db579..d8d5c5ba1 100644 --- a/src/services/shop/purchase/operations.ts +++ b/src/services/shop/purchase/operations.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { purchaseAuthers } from './authers' +import { purchaseAuth } from './auth' import { purchaseSchemas } from './schemas' import { ServerError } from '@/services/error' import { defineOperation } from '@/services/serviceOperation' @@ -33,7 +33,7 @@ export const purchaseOperations = { }, }) - return purchaseAuthers.createByStudentCard.dynamicFields({ + return purchaseAuth.createByStudentCard.dynamicFields({ permissions, }) }, diff --git a/src/services/shop/shop/authers.ts b/src/services/shop/shop/auth.ts similarity index 88% rename from src/services/shop/shop/authers.ts rename to src/services/shop/shop/auth.ts index 8df1d9ff4..a20eb8750 100644 --- a/src/services/shop/shop/authers.ts +++ b/src/services/shop/shop/auth.ts @@ -1,6 +1,6 @@ import { RequirePermission } from '@/auth/auther/RequirePermission' -export const shopAuthers = { +export const shopAuth = { read: RequirePermission.staticFields({ permission: 'SHOP_READ' }), create: RequirePermission.staticFields({ permission: 'SHOP_ADMIN' }), } diff --git a/src/services/shop/shop/operations.ts b/src/services/shop/shop/operations.ts index c2bd12408..ff063cb81 100644 --- a/src/services/shop/shop/operations.ts +++ b/src/services/shop/shop/operations.ts @@ -3,24 +3,24 @@ import '@pn-server-only' import { z } from 'zod' import type { ExtendedShop } from './Types' import { shopSchemas } from './schema' -import { shopAuthers } from './authers' +import { shopAuth } from './auth' export const shopOperations = { create: defineOperation({ dataSchema: shopSchemas.create, - authorizer: () => shopAuthers.create.dynamicFields({}), + authorizer: () => shopAuth.create.dynamicFields({}), operation: async ({ prisma, data }) => prisma.shop.create({ data }) }), readMany: defineOperation({ - authorizer: () => shopAuthers.read.dynamicFields({}), + authorizer: () => shopAuth.read.dynamicFields({}), operation: ({ prisma }) => prisma.shop.findMany(), }), read: defineOperation({ - authorizer: () => shopAuthers.read.dynamicFields({}), + authorizer: () => shopAuth.read.dynamicFields({}), paramsSchema: z.object({ shopId: z.number(), }), diff --git a/src/services/users/authers.ts b/src/services/users/auth.ts similarity index 98% rename from src/services/users/authers.ts rename to src/services/users/auth.ts index 1adfdd3e0..6ca87888c 100644 --- a/src/services/users/authers.ts +++ b/src/services/users/auth.ts @@ -4,7 +4,7 @@ import { RequireUserId } from '@/auth/auther/RequireUserId' import { RequireUserIdOrPermission } from '@/auth/auther/RequireUserIdOrPermission' import { RequireUsernameOrPermission } from '@/auth/auther/RequireUsernameOrPermission' -export const userAuthers = { +export const userAuth = { readProfile: RequireUsernameOrPermission.staticFields({ permission: 'USERS_READ' }), read: RequireUserFieldOrPermission.staticFields({ permission: 'USERS_READ' }), readOrNull: RequireUserFieldOrPermission.staticFields({ permission: 'USERS_READ' }), diff --git a/src/services/users/operations.ts b/src/services/users/operations.ts index 40ae367fd..9c8a3aba3 100644 --- a/src/services/users/operations.ts +++ b/src/services/users/operations.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { userSchemas } from './schemas' -import { userAuthers } from './authers' +import { userAuth } from './auth' import { maxNumberOfGroupsInFilter, standardMembershipSelection, @@ -33,7 +33,7 @@ export const userOperations = { */ create: defineOperation({ dataSchema: userSchemas.create, - authorizer: () => userAuthers.create.dynamicFields({}), + authorizer: () => userAuth.create.dynamicFields({}), operation: async ({ prisma, data }) => { const omegaMembership = await readOmegaMembershipGroup('EXTERNAL') const omegaOrder = await readCurrentOmegaOrder() @@ -68,7 +68,7 @@ export const userOperations = { email: z.string().optional(), studentCard: z.string().optional(), }), - authorizer: ({ params }) => userAuthers.read.dynamicFields(params), + authorizer: ({ params }) => userAuth.read.dynamicFields(params), operation: async ({ prisma, params }) => await prisma.user.findUniqueOrThrow({ where: { id: params.id, @@ -85,7 +85,7 @@ export const userOperations = { email: z.string().optional(), studentCard: z.string().optional(), }), - authorizer: ({ params }) => userAuthers.read.dynamicFields(params), + authorizer: ({ params }) => userAuth.read.dynamicFields(params), operation: async ({ prisma, params }) => await prisma.user.findUnique({ where: { id: params.id, // This is a bit wierd, but now ts is satisfied. @@ -99,7 +99,7 @@ export const userOperations = { paramsSchema: z.object({ username: z.string(), }), - authorizer: ({ params }) => userAuthers.readProfile.dynamicFields({ username: params.username }), + authorizer: ({ params }) => userAuth.readProfile.dynamicFields({ username: params.username }), operation: async ({ prisma, params }) => { const defaultProfileImage = await imageOperations.readSpecial({ params: { special: 'DEFAULT_PROFILE_IMAGE' }, @@ -146,7 +146,7 @@ export const userOperations = { }).nullable().optional() }) ), - authorizer: () => userAuthers.readPage.dynamicFields({}), + authorizer: () => userAuth.readPage.dynamicFields({}), operation: async ({ prisma, params }): Promise => { const { page, details } = params.paging const words = details.partOfName.split(' ') @@ -256,7 +256,7 @@ export const userOperations = { }), connectStudentCard: defineOperation({ - authorizer: () => userAuthers.connectStudentCard.dynamicFields({}), + authorizer: () => userAuth.connectStudentCard.dynamicFields({}), dataSchema: userSchemas.connectStudentCard, opensTransaction: true, operation: async ({ prisma, data }) => { @@ -305,7 +305,7 @@ export const userOperations = { paramsSchema: z.object({ userId: z.number(), }), - authorizer: ({ params }) => userAuthers.registerStudentCardInQueue.dynamicFields(params), + authorizer: ({ params }) => userAuth.registerStudentCardInQueue.dynamicFields(params), operation: async (args) => { const expiry = (new Date()).getTime() + studentCardRegistrationExpiry * 60 * 1000 await args.prisma.registerStudentCardQueue.upsert({ @@ -330,7 +330,7 @@ export const userOperations = { update: defineOperation({ paramsSchema: z.union([z.object({ id: z.number() }), z.object({ username: z.string() })]), dataSchema: userSchemas.update, - authorizer: () => userAuthers.update.dynamicFields({}), + authorizer: () => userAuth.update.dynamicFields({}), operation: async ({ prisma: prisma_, params, data }) => prisma_.user.update({ where: params, data @@ -343,7 +343,7 @@ export const userOperations = { id: z.number(), }), dataSchema: userSchemas.updatePassword, - authorizer: ({ params }) => userAuthers.updatePassword.dynamicFields({ userId: params.id }), + authorizer: ({ params }) => userAuth.updatePassword.dynamicFields({ userId: params.id }), operation: async ({ prisma, data, params }) => { const passwordHash = await hashAndEncryptPassword(data.password) @@ -364,7 +364,7 @@ export const userOperations = { paramsSchema: z.object({ id: z.number(), }), - authorizer: ({ params }) => userAuthers.registerNewEmail.dynamicFields({ userId: params.id }), + authorizer: ({ params }) => userAuth.registerNewEmail.dynamicFields({ userId: params.id }), dataSchema: userSchemas.registerNewEmail, operation: async ({ prisma, params, data }) => { const storedUser = await prisma.user.findUniqueOrThrow({ @@ -429,7 +429,7 @@ export const userOperations = { id: z.number(), }), dataSchema: userSchemas.register, - authorizer: ({ params }) => userAuthers.register.dynamicFields({ userId: params.id }), + authorizer: ({ params }) => userAuth.register.dynamicFields({ userId: params.id }), opensTransaction: true, operation: async ({ prisma, data, params }) => { const { sex, password, mobile, allergies } = data @@ -531,7 +531,7 @@ export const userOperations = { }), readUserWithBalance: defineOperation({ - authorizer: ({ params }) => userAuthers.read.dynamicFields({ + authorizer: ({ params }) => userAuth.read.dynamicFields({ username: params.username || '', }), paramsSchema: z.object({ @@ -563,7 +563,7 @@ export const userOperations = { paramsSchema: z.object({ id: z.number(), }), - authorizer: () => userAuthers.destroy.dynamicFields({}), + authorizer: () => userAuth.destroy.dynamicFields({}), operation: async ({ prisma, params }) => { await prisma.user.delete({ where: { From 1b36107b69dd4aaaf86c2bd03d2a4808df8d0dea Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sat, 11 Oct 2025 02:25:55 +0200 Subject: [PATCH 23/24] refactor: reorganize auth folder --- src/app/(auth)/register-email/page.tsx | 2 +- src/app/(auth)/register/page.tsx | 2 +- src/app/(auth)/verify-email/page.tsx | 2 +- src/app/(home)/page.tsx | 2 +- src/app/_components/Company/Company.tsx | 2 +- src/app/_components/Company/CompanyList.tsx | 2 +- src/app/_components/Company/CompanyListRenderer.tsx | 2 +- src/app/_components/OmegaId/identification/OmegaIdElement.tsx | 2 +- src/app/admin/dots/CreateDotForm.tsx | 2 +- src/app/admin/mail/[filter]/[id]/(editComponents)/group.tsx | 2 +- .../[filter]/[id]/(editComponents)/mailAddressExternal.tsx | 2 +- .../admin/mail/[filter]/[id]/(editComponents)/mailAlias.tsx | 2 +- .../admin/mail/[filter]/[id]/(editComponents)/mailingList.tsx | 2 +- src/app/admin/mail/[filter]/[id]/(editComponents)/user.tsx | 2 +- src/app/admin/mail/[filter]/[id]/MailFlow.tsx | 2 +- src/app/admin/mail/page.tsx | 2 +- src/app/admin/send-mail/page.tsx | 2 +- src/app/admin/stateOfOmega/page.tsx | 2 +- src/app/admin/study-programmes/page.tsx | 2 +- src/app/api/apiHandler.ts | 4 ++-- src/app/api/auth/[...nextauth]/route.ts | 2 +- src/app/applications/[periodName]/page.tsx | 2 +- src/app/cabin/book/page.tsx | 2 +- src/app/cabin/book/stateWrapper.tsx | 2 +- src/app/career/companies/page.tsx | 2 +- src/app/career/jobads/[...orderAndName]/page.tsx | 2 +- src/app/career/page.tsx | 2 +- src/app/education/schools/page.tsx | 2 +- src/app/events/archive/page.tsx | 2 +- src/app/events/page.tsx | 2 +- src/app/images/page.tsx | 2 +- src/app/interest-groups/InterestGroup.tsx | 2 +- src/app/interest-groups/page.tsx | 2 +- src/app/layout.tsx | 4 ++-- src/app/lockers/[id]/page.tsx | 2 +- src/app/lockers/page.tsx | 2 +- src/app/ombul/[...yearAndName]/page.tsx | 2 +- src/app/ombul/page.tsx | 2 +- src/app/omegaquotes/page.tsx | 2 +- src/app/users/[username]/(user-admin)/getProfileForAdmin.ts | 2 +- src/app/users/[username]/(user-admin)/layout.tsx | 2 +- src/app/users/[username]/page.tsx | 2 +- src/auth/auther/AuthResult.ts | 2 +- src/auth/auther/Auther.ts | 2 +- src/auth/{ => nextAuth}/VevenAdapter.ts | 0 src/auth/{authoptions.ts => nextAuth/authOptions.ts} | 2 +- src/auth/{password.ts => passwordHash.ts} | 0 src/auth/{ => session}/Session.ts | 2 +- src/auth/{ => session}/getUser.ts | 2 +- src/auth/{ => session}/useUser.ts | 0 src/hooks/useEditing.ts | 2 +- src/prisma/seeder/src/development/seedDevUsers.ts | 2 +- src/services/actionError.ts | 2 +- src/services/education/schools/actions.ts | 2 +- src/services/error.ts | 2 +- src/services/groups/committees/actions.ts | 2 +- src/services/groups/memberships/actions.ts | 2 +- src/services/groups/studyProgrammes/actions.ts | 2 +- src/services/images/collections/actions.ts | 2 +- src/services/mail/actions.ts | 2 +- src/services/mail/alias/actions.ts | 2 +- src/services/mail/list/actions.ts | 2 +- src/services/mail/mailAddressExternal/actions.ts | 2 +- src/services/ombul/actions.ts | 2 +- src/services/omegaOrder/actions.ts | 2 +- src/services/omegaid/actions.ts | 2 +- src/services/omegaquotes/actions.ts | 2 +- src/services/screens/actions.ts | 2 +- src/services/screens/pages/actions.ts | 2 +- src/services/sendmail/actions.ts | 2 +- src/services/serverAction.ts | 2 +- src/services/serviceOperation.ts | 4 ++-- src/services/users/operations.ts | 2 +- src/services/visibility/actions.ts | 2 +- tests/services/apiKeys.test.ts | 2 +- tests/services/jobads.test.ts | 2 +- tests/services/service-method.test.ts | 2 +- 77 files changed, 77 insertions(+), 77 deletions(-) rename src/auth/{ => nextAuth}/VevenAdapter.ts (100%) rename src/auth/{authoptions.ts => nextAuth/authOptions.ts} (99%) rename src/auth/{password.ts => passwordHash.ts} (100%) rename src/auth/{ => session}/Session.ts (98%) rename src/auth/{ => session}/getUser.ts (98%) rename src/auth/{ => session}/useUser.ts (100%) diff --git a/src/app/(auth)/register-email/page.tsx b/src/app/(auth)/register-email/page.tsx index 9ec1224d9..f40a425cb 100644 --- a/src/app/(auth)/register-email/page.tsx +++ b/src/app/(auth)/register-email/page.tsx @@ -1,5 +1,5 @@ import EmailRegistrationForm from './EmailregistrationForm' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { readUserAction } from '@/services/users/actions' import { notFound, redirect } from 'next/navigation' diff --git a/src/app/(auth)/register/page.tsx b/src/app/(auth)/register/page.tsx index 3fb3aa197..86a22ad9b 100644 --- a/src/app/(auth)/register/page.tsx +++ b/src/app/(auth)/register/page.tsx @@ -1,5 +1,5 @@ import RegistrationForm from './RegistrationForm' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { QueryParams } from '@/lib/query-params/queryParams' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { readUserAction } from '@/services/users/actions' diff --git a/src/app/(auth)/verify-email/page.tsx b/src/app/(auth)/verify-email/page.tsx index 9ede27b8d..7a0e6fd8a 100644 --- a/src/app/(auth)/verify-email/page.tsx +++ b/src/app/(auth)/verify-email/page.tsx @@ -1,5 +1,5 @@ import { EmailVerifiedWrapper } from './EmailVerifiedWrapper' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { QueryParams } from '@/lib/query-params/queryParams' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import { verifyEmailAction } from '@/services/auth/actions' diff --git a/src/app/(home)/page.tsx b/src/app/(home)/page.tsx index aacbe81db..9f794f4bb 100644 --- a/src/app/(home)/page.tsx +++ b/src/app/(home)/page.tsx @@ -1,6 +1,6 @@ import LoggedInLandingPage from './LoggedIn' import LoggedOutLandingPage from './LoggedOut' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' export default async function Home() { const { user } = await Session.fromNextAuth() diff --git a/src/app/_components/Company/Company.tsx b/src/app/_components/Company/Company.tsx index 37a84ba1d..c17c7da34 100644 --- a/src/app/_components/Company/Company.tsx +++ b/src/app/_components/Company/Company.tsx @@ -9,7 +9,7 @@ import { bindParams } from '@/services/actionBind' import { companyAuth } from '@/services/career/companies/auth' import { destroyCompanyAction, updateComanyAction } from '@/services/career/companies/actions' import type { CompanyExpanded } from '@/services/career/companies/Types' -import type { SessionMaybeUser } from '@/auth/Session' +import type { SessionMaybeUser } from '@/auth/session/Session' type PropTypes = { company: CompanyExpanded, diff --git a/src/app/_components/Company/CompanyList.tsx b/src/app/_components/Company/CompanyList.tsx index e4fb604e8..58d47bac4 100644 --- a/src/app/_components/Company/CompanyList.tsx +++ b/src/app/_components/Company/CompanyList.tsx @@ -3,7 +3,7 @@ import { companyListRenderer } from './CompanyListRenderer' import styles from './CompanyList.module.scss' import { CompanyPagingContext } from '@/contexts/paging/CompanyPaging' import EndlessScroll from '@/components/PagingWrappers/EndlessScroll' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import type { ReactNode } from 'react' type PropTypes = { diff --git a/src/app/_components/Company/CompanyListRenderer.tsx b/src/app/_components/Company/CompanyListRenderer.tsx index 6ad8e939b..cd882a15d 100644 --- a/src/app/_components/Company/CompanyListRenderer.tsx +++ b/src/app/_components/Company/CompanyListRenderer.tsx @@ -1,5 +1,5 @@ import Company from './Company' -import type { SessionMaybeUser } from '@/auth/Session' +import type { SessionMaybeUser } from '@/auth/session/Session' import type { CompanyExpanded } from '@/services/career/companies/Types' /** diff --git a/src/app/_components/OmegaId/identification/OmegaIdElement.tsx b/src/app/_components/OmegaId/identification/OmegaIdElement.tsx index c052eb76d..e5a72ef1e 100644 --- a/src/app/_components/OmegaId/identification/OmegaIdElement.tsx +++ b/src/app/_components/OmegaId/identification/OmegaIdElement.tsx @@ -1,6 +1,6 @@ 'use client' import styles from './OmegaIdElement.module.scss' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import { generateOmegaIdAction } from '@/services/omegaid/actions' import { readJWTPayload } from '@/jwt/jwtReadUnsecure' import { compressOmegaId } from '@/services/omegaid/compress' diff --git a/src/app/admin/dots/CreateDotForm.tsx b/src/app/admin/dots/CreateDotForm.tsx index 086b3ef9b..e6384d27f 100644 --- a/src/app/admin/dots/CreateDotForm.tsx +++ b/src/app/admin/dots/CreateDotForm.tsx @@ -6,7 +6,7 @@ import PopUp from '@/components/PopUp/PopUp' import NumberInput from '@/components/UI/NumberInput' import TextInput from '@/components/UI/TextInput' import UserList from '@/components/User/UserList/UserList' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import { PopUpContext } from '@/contexts/PopUp' import { UserSelectionContext } from '@/contexts/UserSelection' import { useContext } from 'react' diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/group.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/group.tsx index e660e6b82..6a94390f3 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/group.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/group.tsx @@ -2,7 +2,7 @@ import Form from '@/components/Form/Form' import { SelectNumber } from '@/components/UI/Select' import { createMailingListGroupRelationAction } from '@/services/mail/actions' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import type { MailFlowObject } from '@/services/mail/Types' import type { MailingList } from '@prisma/client' diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAddressExternal.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAddressExternal.tsx index ced0f30af..eb19f5d3d 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAddressExternal.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAddressExternal.tsx @@ -4,7 +4,7 @@ import TextInput from '@/components/UI/TextInput' import Form from '@/components/Form/Form' import { SelectNumber } from '@/components/UI/Select' import { createMailingListExternalRelationAction } from '@/services/mail/actions' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import { updateMailAddressExternalAction, destroyMailAddressExternalAction diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAlias.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAlias.tsx index b347b1d32..dc2ee95b6 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAlias.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailAlias.tsx @@ -4,7 +4,7 @@ import TextInput from '@/components/UI/TextInput' import Form from '@/components/Form/Form' import { SelectNumber } from '@/components/UI/Select' import { createAliasMailingListRelationAction } from '@/services/mail/actions' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import { updateMailAliasAction, destroyMailAliasAction } from '@/services/mail/alias/actions' import { useRouter } from 'next/navigation' import type { MailFlowObject } from '@/services/mail/Types' diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailingList.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailingList.tsx index f04ceebfa..fc35fd995 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/mailingList.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/mailingList.tsx @@ -9,7 +9,7 @@ import { createMailingListGroupRelationAction, createMailingListUserRelationAction } from '@/services/mail/actions' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import { updateMailingListAction, destroyMailingListAction } from '@/services/mail/list/actions' import { useRouter } from 'next/navigation' import type { MailAddressExternal, MailAlias } from '@prisma/client' diff --git a/src/app/admin/mail/[filter]/[id]/(editComponents)/user.tsx b/src/app/admin/mail/[filter]/[id]/(editComponents)/user.tsx index f2458a9c5..36e5f246e 100644 --- a/src/app/admin/mail/[filter]/[id]/(editComponents)/user.tsx +++ b/src/app/admin/mail/[filter]/[id]/(editComponents)/user.tsx @@ -3,7 +3,7 @@ import Form from '@/components/Form/Form' import { SelectNumber } from '@/components/UI/Select' import { createMailingListUserRelationAction } from '@/services/mail/actions' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import type { MailFlowObject } from '@/services/mail/Types' import type { MailingList } from '@prisma/client' diff --git a/src/app/admin/mail/[filter]/[id]/MailFlow.tsx b/src/app/admin/mail/[filter]/[id]/MailFlow.tsx index f79b680c1..8e1123dc0 100644 --- a/src/app/admin/mail/[filter]/[id]/MailFlow.tsx +++ b/src/app/admin/mail/[filter]/[id]/MailFlow.tsx @@ -2,7 +2,7 @@ import MailList from './mailList' import styles from './MailFlow.module.scss' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import { destroyAliasMailingListRelationAction, destroyMailingListExternalRelationAction, diff --git a/src/app/admin/mail/page.tsx b/src/app/admin/mail/page.tsx index a50c58024..6c273c744 100644 --- a/src/app/admin/mail/page.tsx +++ b/src/app/admin/mail/page.tsx @@ -5,7 +5,7 @@ import CreateMailAlias from './createMailAliasForm' import CreateMailingList from './createMailingListForm' import CreateMailaddressExternal from './createMailaddressExternalForm' import MailListView from './mailListView' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { readMailAliases } from '@/services/mail/alias/read' import { readMailingLists } from '@/services/mail/list/read' diff --git a/src/app/admin/send-mail/page.tsx b/src/app/admin/send-mail/page.tsx index c1d7f4794..a705e3e09 100644 --- a/src/app/admin/send-mail/page.tsx +++ b/src/app/admin/send-mail/page.tsx @@ -1,6 +1,6 @@ import MailForm from './mailForm' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { notFound } from 'next/navigation' export default async function SendMail() { diff --git a/src/app/admin/stateOfOmega/page.tsx b/src/app/admin/stateOfOmega/page.tsx index 9076b7e4f..52c783475 100644 --- a/src/app/admin/stateOfOmega/page.tsx +++ b/src/app/admin/stateOfOmega/page.tsx @@ -1,6 +1,6 @@ import styles from './page.module.scss' import CreateOrder from './CreateOrder' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { readCurrentOmegaOrderAction } from '@/services/omegaOrder/actions' import { notFound } from 'next/navigation' diff --git a/src/app/admin/study-programmes/page.tsx b/src/app/admin/study-programmes/page.tsx index 9f8aa416b..7e7f21715 100644 --- a/src/app/admin/study-programmes/page.tsx +++ b/src/app/admin/study-programmes/page.tsx @@ -6,7 +6,7 @@ import styles from './page.module.scss' import { readStudyProgrammesAction } from '@/services/groups/studyProgrammes/actions' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' export default async function StudyProgrammes() { diff --git a/src/app/api/apiHandler.ts b/src/app/api/apiHandler.ts index 845767689..33834d4ed 100644 --- a/src/app/api/apiHandler.ts +++ b/src/app/api/apiHandler.ts @@ -1,9 +1,9 @@ import '@pn-server-only' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { getHttpErrorCode, ServerError, Smorekopp } from '@/services/error' import type { ServiceOperation } from '@/services/serviceOperation' import type { ErrorCode, ErrorMessage } from '@/services/error' -import type { SessionNoUser } from '@/auth/Session' +import type { SessionNoUser } from '@/auth/session/Session' import type { z } from 'zod' type APIHandler< diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index 34db9c6c1..34a9f8546 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -1,4 +1,4 @@ -import { authOptions } from '@/auth/authoptions' +import { authOptions } from '@/auth/nextAuth/authOptions' import NextAuth from 'next-auth' const handler = NextAuth(authOptions) diff --git a/src/app/applications/[periodName]/page.tsx b/src/app/applications/[periodName]/page.tsx index 7385de545..2fa5dd980 100644 --- a/src/app/applications/[periodName]/page.tsx +++ b/src/app/applications/[periodName]/page.tsx @@ -7,7 +7,7 @@ import CountDown from '@/components/countDown/CountDown' import BackdropImage from '@/components/BackdropImage/BackdropImage' import CmsParagraph from '@/components/Cms/CmsParagraph/CmsParagraph' import PopUp from '@/components/PopUp/PopUp' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import Textarea from '@/components/UI/Textarea' import Form from '@/components/Form/Form' import { SettingsHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' diff --git a/src/app/cabin/book/page.tsx b/src/app/cabin/book/page.tsx index dcefa49dc..e9c115055 100644 --- a/src/app/cabin/book/page.tsx +++ b/src/app/cabin/book/page.tsx @@ -9,7 +9,7 @@ import { readReleasePeriodsAction } from '@/services/cabin/actions' import { displayDate } from '@/lib/dates/displayDate' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { cabinBookingAuth } from '@/services/cabin/booking/auth' import type { ReleasePeriod } from '@prisma/client' diff --git a/src/app/cabin/book/stateWrapper.tsx b/src/app/cabin/book/stateWrapper.tsx index 97c1b47dd..7bf942b95 100644 --- a/src/app/cabin/book/stateWrapper.tsx +++ b/src/app/cabin/book/stateWrapper.tsx @@ -8,7 +8,7 @@ import Form from '@/app/_components/Form/Form' import TextInput from '@/app/_components/UI/TextInput' import NumberInput from '@/app/_components/UI/NumberInput' import Checkbox from '@/app/_components/UI/Checkbox' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import { createBedBookingNoUserAction, createBedBookingUserAttachedAction, diff --git a/src/app/career/companies/page.tsx b/src/app/career/companies/page.tsx index c6b073eaf..bff7c50ab 100644 --- a/src/app/career/companies/page.tsx +++ b/src/app/career/companies/page.tsx @@ -8,7 +8,7 @@ import CompanyList from '@/components/Company/CompanyList' import { companyListRenderer } from '@/components/Company/CompanyListRenderer' import { QueryParams } from '@/lib/query-params/queryParams' import CompanyListFilter from '@/app/_components/Company/CompanyListFilter' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import type { SearchParamsServerSide } from '@/lib/query-params/Types' import type { PageSizeCompany } from '@/contexts/paging/CompanyPaging' diff --git a/src/app/career/jobads/[...orderAndName]/page.tsx b/src/app/career/jobads/[...orderAndName]/page.tsx index 759e467e7..802194f17 100644 --- a/src/app/career/jobads/[...orderAndName]/page.tsx +++ b/src/app/career/jobads/[...orderAndName]/page.tsx @@ -6,7 +6,7 @@ import CompanySelectionProvider from '@/contexts/CompanySelection' import CompanyPagingProvider from '@/contexts/paging/CompanyPaging' import Company from '@/components/Company/Company' import Date from '@/components/Date/Date' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { readJobAdAction } from '@/services/career/jobAds/actions' import { jobAdType } from '@/services/career/jobAds/constants' import { notFound } from 'next/navigation' diff --git a/src/app/career/page.tsx b/src/app/career/page.tsx index d01cee89f..f1f382f26 100644 --- a/src/app/career/page.tsx +++ b/src/app/career/page.tsx @@ -1,7 +1,7 @@ import styles from './page.module.scss' import SpecialCmsParagraph from '@/components/Cms/CmsParagraph/SpecialCmsParagraph' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import Image from '@/components/Image/Image' import CmsLink from '@/components/Cms/CmsLink/CmsLink' import { QueryParams } from '@/lib/query-params/queryParams' diff --git a/src/app/education/schools/page.tsx b/src/app/education/schools/page.tsx index a9551388f..98c17d70a 100644 --- a/src/app/education/schools/page.tsx +++ b/src/app/education/schools/page.tsx @@ -1,6 +1,6 @@ import styles from './page.module.scss' import { readSchoolsPageAction } from '@/services/education/schools/actions' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import PageWrapper from '@/components/PageWrapper/PageWrapper' import SchoolPagingProvider from '@/contexts/paging/SchoolPaging' import SchoolList from '@/components/School/SchoolList' diff --git a/src/app/events/archive/page.tsx b/src/app/events/archive/page.tsx index beba57d3b..10ed908b6 100644 --- a/src/app/events/archive/page.tsx +++ b/src/app/events/archive/page.tsx @@ -5,7 +5,7 @@ import EventsLandingLayout from '@/app/events/EventsLandingLayout' import EventArchivePagingProvider from '@/contexts/paging/EventArchivePaging' import { QueryParams } from '@/lib/query-params/queryParams' import { eventTagAuth } from '@/services/events/tags/auth' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { faArrowLeft } from '@fortawesome/free-solid-svg-icons' import type { SearchParamsServerSide } from '@/lib/query-params/Types' diff --git a/src/app/events/page.tsx b/src/app/events/page.tsx index c13c0be7d..429c98a59 100644 --- a/src/app/events/page.tsx +++ b/src/app/events/page.tsx @@ -8,7 +8,7 @@ import EventCard from '@/components/Event/EventCard' import { readEventTagsAction } from '@/services/events/tags/actions' import { eventTagAuth } from '@/services/events/tags/auth' import { QueryParams } from '@/lib/query-params/queryParams' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { faArchive } from '@fortawesome/free-solid-svg-icons' import type { SearchParamsServerSide } from '@/lib/query-params/Types' diff --git a/src/app/images/page.tsx b/src/app/images/page.tsx index 8a217443c..deabb2dee 100644 --- a/src/app/images/page.tsx +++ b/src/app/images/page.tsx @@ -3,7 +3,7 @@ import MakeNewCollection from './MakeNewCollection' import ImageCollectionList from '@/components/Image/Collection/ImageCollectionList' import ImageCollectionPagingProvider from '@/contexts/paging/ImageCollectionPaging' import CollectionCard from '@/components/Image/Collection/CollectionCard' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { readImageCollectionsPageAction } from '@/services/images/collections/actions' import type { PageSizeImageCollection } from '@/contexts/paging/ImageCollectionPaging' diff --git a/src/app/interest-groups/InterestGroup.tsx b/src/app/interest-groups/InterestGroup.tsx index 97b14711c..4807f597c 100644 --- a/src/app/interest-groups/InterestGroup.tsx +++ b/src/app/interest-groups/InterestGroup.tsx @@ -5,7 +5,7 @@ import ArticleSection from '@/components/Cms/ArticleSection/ArticleSection' import { SettingsHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import { updateInterestGroupAction, destroyInterestGroupAction } from '@/services/groups/interestGroups/actions' import { interestGroupAuth } from '@/services/groups/interestGroups/auth' -import type { SessionMaybeUser } from '@/auth/Session' +import type { SessionMaybeUser } from '@/auth/session/Session' import type { ExpandedInterestGroup } from '@/services/groups/interestGroups/Types' type PropTypes = { diff --git a/src/app/interest-groups/page.tsx b/src/app/interest-groups/page.tsx index ecf21816f..76726d238 100644 --- a/src/app/interest-groups/page.tsx +++ b/src/app/interest-groups/page.tsx @@ -3,7 +3,7 @@ import InterestGroup from './InterestGroup' import SpecialCmsParagraph from '@/cms/CmsParagraph/SpecialCmsParagraph' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { interestGroupAuth } from '@/services/groups/interestGroups/auth' import { readInterestGroupsAction } from '@/services/groups/interestGroups/actions' diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 61bff1f51..5f1119372 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,9 +1,9 @@ import styles from './layout.module.scss' -import { SessionProvider } from '@/auth/useUser' +import { SessionProvider } from '@/auth/session/useUser' import MobileNavBar from '@/components/NavBar/MobileNavBar' import NavBar from '@/components/NavBar/NavBar' import Footer from '@/components/Footer/Footer' -import { authOptions } from '@/auth/authoptions' +import { authOptions } from '@/auth/nextAuth/authOptions' import EditModeProvider from '@/contexts/EditMode' import PopUpProvider from '@/contexts/PopUp' import DefaultPermissionsProvider from '@/contexts/DefaultPermissions' diff --git a/src/app/lockers/[id]/page.tsx b/src/app/lockers/[id]/page.tsx index f4c48c1f9..60bfc9e2f 100644 --- a/src/app/lockers/[id]/page.tsx +++ b/src/app/lockers/[id]/page.tsx @@ -4,7 +4,7 @@ import CreateLockerReservationForm from './CreateLockerReservationForm' import UpdateLockerReservationForm from './UpdateLockerReservationForm' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { readLockerAction } from '@/services/lockers/actions' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { checkGroupValidity, groupOperations, inferGroupName } from '@/services/groups/operations' diff --git a/src/app/lockers/page.tsx b/src/app/lockers/page.tsx index dcf2c05a1..bcba0f3fa 100644 --- a/src/app/lockers/page.tsx +++ b/src/app/lockers/page.tsx @@ -2,7 +2,7 @@ import LockerIdForm from './LockerIdForm' import LockerList from './LockerList' import QRButton from './QRButton' import PageWrapper from '@/components/PageWrapper/PageWrapper' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import LockerPagingProvider from '@/contexts/paging/LockerPaging' export default async function Lockers() { diff --git a/src/app/ombul/[...yearAndName]/page.tsx b/src/app/ombul/[...yearAndName]/page.tsx index 04001baf4..cce4be720 100644 --- a/src/app/ombul/[...yearAndName]/page.tsx +++ b/src/app/ombul/[...yearAndName]/page.tsx @@ -5,7 +5,7 @@ import { readOmbulAction, updateOmbulAction } from '@/services/ombul/actions' import PdfDocument from '@/components/PdfDocument/PdfDocument' import SlideInOnView from '@/components/SlideInOnView/SlideInOnView' import EditableTextField from '@/components/EditableTextField/EditableTextField' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import CmsImage from '@/components/Cms/CmsImage/CmsImage' import Link from 'next/link' import { notFound } from 'next/navigation' diff --git a/src/app/ombul/page.tsx b/src/app/ombul/page.tsx index 375812ebd..08740c79b 100644 --- a/src/app/ombul/page.tsx +++ b/src/app/ombul/page.tsx @@ -4,7 +4,7 @@ import OmbulCover from './OmbulCover' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { AddHeaderItemPopUp } from '@/components/HeaderItems/HeaderItemPopUp' import { readLatestOmbulAction, readOmbulsAction } from '@/services/ombul/actions' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import type { ExpandedOmbul } from '@/services/ombul/Types' export default async function Ombuls() { diff --git a/src/app/omegaquotes/page.tsx b/src/app/omegaquotes/page.tsx index 5a84c859a..510a4919a 100644 --- a/src/app/omegaquotes/page.tsx +++ b/src/app/omegaquotes/page.tsx @@ -4,7 +4,7 @@ import CreateOmegaquoteForm from './CreateOmegaquoteForm' import OmegaquotePagingProvider from '@/contexts/paging/OmegaquotesPaging' import PageWrapper from '@/components/PageWrapper/PageWrapper' import { readQuotesPageAction } from '@/services/omegaquotes/actions' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { notFound } from 'next/navigation' import { v4 as uuid } from 'uuid' import type { PageSizeOmegaquote } from '@/contexts/paging/OmegaquotesPaging' diff --git a/src/app/users/[username]/(user-admin)/getProfileForAdmin.ts b/src/app/users/[username]/(user-admin)/getProfileForAdmin.ts index 502cb775c..8c83b1809 100644 --- a/src/app/users/[username]/(user-admin)/getProfileForAdmin.ts +++ b/src/app/users/[username]/(user-admin)/getProfileForAdmin.ts @@ -1,5 +1,5 @@ import { readUserProfileAction } from '@/services/users/actions' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { userAuth } from '@/services/users/auth' import { notFound, redirect } from 'next/navigation' diff --git a/src/app/users/[username]/(user-admin)/layout.tsx b/src/app/users/[username]/(user-admin)/layout.tsx index 1c4aec771..c75a08f0d 100644 --- a/src/app/users/[username]/(user-admin)/layout.tsx +++ b/src/app/users/[username]/(user-admin)/layout.tsx @@ -1,6 +1,6 @@ import styles from './layout.module.scss' import Nav from './Nav' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { readUserProfileAction } from '@/services/users/actions' import { unwrapActionReturn } from '@/app/redirectToErrorPage' import PageWrapper from '@/components/PageWrapper/PageWrapper' diff --git a/src/app/users/[username]/page.tsx b/src/app/users/[username]/page.tsx index af71c5494..3142568d9 100644 --- a/src/app/users/[username]/page.tsx +++ b/src/app/users/[username]/page.tsx @@ -3,7 +3,7 @@ import BorderButton from '@/components/UI/BorderButton' import { readCommitteesFromGroupIds } from '@/services/groups/committees/read' import OmegaId from '@/components/OmegaId/identification/OmegaId' import PopUp from '@/components/PopUp/PopUp' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { userAuth } from '@/services/users/auth' import ProfilePicture from '@/components/User/ProfilePicture' import UserDisplayName from '@/components/User/UserDisplayName' diff --git a/src/auth/auther/AuthResult.ts b/src/auth/auther/AuthResult.ts index a714b3346..4cbab879e 100644 --- a/src/auth/auther/AuthResult.ts +++ b/src/auth/auther/AuthResult.ts @@ -1,6 +1,6 @@ import { redirectToErrorPage } from '@/app/redirectToErrorPage' import { redirect } from 'next/navigation' -import type { SessionType, UserGuaranteeOption } from '@/auth/Session' +import type { SessionType, UserGuaranteeOption } from '@/auth/session/Session' export type AuthStatus = 'AUTHORIZED' | 'UNAUTHORIZED' | 'AUTHORIZED_NO_USER' | 'UNAUTHENTICATED' diff --git a/src/auth/auther/Auther.ts b/src/auth/auther/Auther.ts index c8da07a60..b2e18d47b 100644 --- a/src/auth/auther/Auther.ts +++ b/src/auth/auther/Auther.ts @@ -1,5 +1,5 @@ import { AuthResult } from './AuthResult' -import type { SessionMaybeUser, SessionUser } from '@/auth/Session' +import type { SessionMaybeUser, SessionUser } from '@/auth/session/Session' export type UserRequieredOutOpt = 'USER_NOT_REQUIERED_FOR_AUTHORIZED' | 'USER_REQUIERED_FOR_AUTHORIZED' diff --git a/src/auth/VevenAdapter.ts b/src/auth/nextAuth/VevenAdapter.ts similarity index 100% rename from src/auth/VevenAdapter.ts rename to src/auth/nextAuth/VevenAdapter.ts diff --git a/src/auth/authoptions.ts b/src/auth/nextAuth/authOptions.ts similarity index 99% rename from src/auth/authoptions.ts rename to src/auth/nextAuth/authOptions.ts index 17cd9b560..3cd7779dc 100644 --- a/src/auth/authoptions.ts +++ b/src/auth/nextAuth/authOptions.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import VevenAdapter from './VevenAdapter' -import { decryptAndComparePassword } from './password' +import { decryptAndComparePassword } from '../passwordHash' import FeideProvider from '@/lib/feide/FeideProvider' import { updateUserStudyProgrammes } from '@/lib/feide/userRoutines' import { prisma } from '@/prisma/client' diff --git a/src/auth/password.ts b/src/auth/passwordHash.ts similarity index 100% rename from src/auth/password.ts rename to src/auth/passwordHash.ts diff --git a/src/auth/Session.ts b/src/auth/session/Session.ts similarity index 98% rename from src/auth/Session.ts rename to src/auth/session/Session.ts index a666e1a28..528615da5 100644 --- a/src/auth/Session.ts +++ b/src/auth/session/Session.ts @@ -1,4 +1,4 @@ -import { authOptions } from './authoptions' +import { authOptions } from '../nextAuth/authOptions' import { apiKeyOperations } from '@/services/api-keys/operations' import { apiKeyDecryptAndCompare } from '@/services/api-keys/hashEncryptKey' import { decodeApiKey } from '@/services/api-keys/apiKeyEncoder' diff --git a/src/auth/getUser.ts b/src/auth/session/getUser.ts similarity index 98% rename from src/auth/getUser.ts rename to src/auth/session/getUser.ts index 0c94f60e2..a541eac04 100644 --- a/src/auth/getUser.ts +++ b/src/auth/session/getUser.ts @@ -1,5 +1,5 @@ import '@pn-server-only' -import { authOptions } from './authoptions' +import { authOptions } from '../nextAuth/authOptions' import checkMatrix from '@/lib/checkMatrix' import { permissionOperations } from '@/services/permissions/operations' import { getServerSession } from 'next-auth' diff --git a/src/auth/useUser.ts b/src/auth/session/useUser.ts similarity index 100% rename from src/auth/useUser.ts rename to src/auth/session/useUser.ts diff --git a/src/hooks/useEditing.ts b/src/hooks/useEditing.ts index 6a570afa9..e1c5a4680 100644 --- a/src/hooks/useEditing.ts +++ b/src/hooks/useEditing.ts @@ -1,5 +1,5 @@ 'use client' -import { useUser } from '@/auth/useUser' +import { useUser } from '@/auth/session/useUser' import { EditModeContext } from '@/contexts/EditMode' import { checkVisibility } from '@/auth/checkVisibility' import { useContext, useEffect, useRef, useState } from 'react' diff --git a/src/prisma/seeder/src/development/seedDevUsers.ts b/src/prisma/seeder/src/development/seedDevUsers.ts index 1772dcd60..f992f175a 100644 --- a/src/prisma/seeder/src/development/seedDevUsers.ts +++ b/src/prisma/seeder/src/development/seedDevUsers.ts @@ -1,4 +1,4 @@ -import { hashAndEncryptPassword } from '@/auth/password' +import { hashAndEncryptPassword } from '@/auth/passwordHash' import { v4 as uuid } from 'uuid' import type { PrismaClient } from '@prisma/client' diff --git a/src/services/actionError.ts b/src/services/actionError.ts index c3d332f05..1b4ac9ff1 100644 --- a/src/services/actionError.ts +++ b/src/services/actionError.ts @@ -1,6 +1,6 @@ import { errorCodes, type ErrorCode, type ErrorMessage } from '@/services/error' import { ParseError, Smorekopp } from '@/services/error' -import type { AuthStatus } from '@/auth/getUser' +import type { AuthStatus } from '@/auth/session/getUser' import type { SafeParseError } from 'zod' import type { ActionError, ActionReturn } from './actionTypes' diff --git a/src/services/education/schools/actions.ts b/src/services/education/schools/actions.ts index a664d5d2d..65c543f9f 100644 --- a/src/services/education/schools/actions.ts +++ b/src/services/education/schools/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createSchoolValidation, updateSchoolValidation } from '@/education/schools/validation' import { createSchool } from '@/services/education/schools/create' import { destroySchool } from '@/services/education/schools/destroy' diff --git a/src/services/error.ts b/src/services/error.ts index 85158e89d..9181a7973 100644 --- a/src/services/error.ts +++ b/src/services/error.ts @@ -1,5 +1,5 @@ import type { SafeParseError } from 'zod' -import type { AuthStatus } from '@/auth/getUser' +import type { AuthStatus } from '@/auth/session/getUser' export const errorCodes = [ { diff --git a/src/services/groups/committees/actions.ts b/src/services/groups/committees/actions.ts index e293b8d52..57921643e 100644 --- a/src/services/groups/committees/actions.ts +++ b/src/services/groups/committees/actions.ts @@ -2,7 +2,7 @@ import { makeAction } from '@/services/serverAction' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createCommittee } from '@/services/groups/committees/create' import { committeeOperations } from '@/services/groups/committees/operations' import { updateCommittee } from '@/services/groups/committees/update' diff --git a/src/services/groups/memberships/actions.ts b/src/services/groups/memberships/actions.ts index 402ab7257..906d19ab7 100644 --- a/src/services/groups/memberships/actions.ts +++ b/src/services/groups/memberships/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createMembershipsForGroup } from '@/services/groups/memberships/create' import { destoryMembershipOfUser } from '@/services/groups/memberships/destroy' import { updateMembership } from '@/services/groups/memberships/update' diff --git a/src/services/groups/studyProgrammes/actions.ts b/src/services/groups/studyProgrammes/actions.ts index 3c7200e6e..f4363d6b1 100644 --- a/src/services/groups/studyProgrammes/actions.ts +++ b/src/services/groups/studyProgrammes/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createStudyProgramme } from '@/services/groups/studyProgrammes/create' import { readStudyProgrammes } from '@/services/groups/studyProgrammes/read' import { updateStudyProgramme } from '@/services/groups/studyProgrammes/update' diff --git a/src/services/images/collections/actions.ts b/src/services/images/collections/actions.ts index 675bdf4d6..4470c5d82 100644 --- a/src/services/images/collections/actions.ts +++ b/src/services/images/collections/actions.ts @@ -2,7 +2,7 @@ import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { checkVisibility } from '@/auth/checkVisibility' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { getVisibilityFilter } from '@/auth/getVisibilityFilter' import { createImageCollection } from '@/services/images/collections/create' import { destroyImageCollection } from '@/services/images/collections/destroy' diff --git a/src/services/mail/actions.ts b/src/services/mail/actions.ts index e0fe0cfc6..09d07a864 100644 --- a/src/services/mail/actions.ts +++ b/src/services/mail/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { readMailAliases } from '@/services/mail/alias/read' import { createAliasMailingListRelation, diff --git a/src/services/mail/alias/actions.ts b/src/services/mail/alias/actions.ts index 7748c5cde..a06cc7ff5 100644 --- a/src/services/mail/alias/actions.ts +++ b/src/services/mail/alias/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createMailAlias } from '@/services/mail/alias/create' import { destroyMailAlias } from '@/services/mail/alias/destroy' import { readMailAliases } from '@/services/mail/alias/read' diff --git a/src/services/mail/list/actions.ts b/src/services/mail/list/actions.ts index 31c93a489..3a142809a 100644 --- a/src/services/mail/list/actions.ts +++ b/src/services/mail/list/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createMailingList } from '@/services/mail/list/create' import { destroyMailingList } from '@/services/mail/list/destroy' import { updateMailingList } from '@/services/mail/list/update' diff --git a/src/services/mail/mailAddressExternal/actions.ts b/src/services/mail/mailAddressExternal/actions.ts index 4723a0e90..6a56c49dd 100644 --- a/src/services/mail/mailAddressExternal/actions.ts +++ b/src/services/mail/mailAddressExternal/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createMailAddressExternal } from '@/services/mail/mailAddressExternal/create' import { destroyMailAddressExternal } from '@/services/mail/mailAddressExternal/destroy' import { updateMailAddressExternal } from '@/services/mail/mailAddressExternal/update' diff --git a/src/services/ombul/actions.ts b/src/services/ombul/actions.ts index 3474e9028..6445db440 100644 --- a/src/services/ombul/actions.ts +++ b/src/services/ombul/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createOmbul } from '@/services/ombul/create' import { destroyOmbul } from '@/services/ombul/destroy' import { readLatestOmbul, readOmbul, readOmbuls } from '@/services/ombul/read' diff --git a/src/services/omegaOrder/actions.ts b/src/services/omegaOrder/actions.ts index e32756c53..6bf55f39c 100644 --- a/src/services/omegaOrder/actions.ts +++ b/src/services/omegaOrder/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createOmegaOrder } from '@/services/omegaOrder/create' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import type { ActionReturn } from '@/services/actionTypes' diff --git a/src/services/omegaid/actions.ts b/src/services/omegaid/actions.ts index 7ecabb75a..e104af06f 100644 --- a/src/services/omegaid/actions.ts +++ b/src/services/omegaid/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { ServerError } from '@/services/error' import { generateOmegaId } from '@/services/omegaid/generate' import type { ActionReturn } from '@/services/actionTypes' diff --git a/src/services/omegaquotes/actions.ts b/src/services/omegaquotes/actions.ts index a4bbffbd0..d9bce2920 100644 --- a/src/services/omegaquotes/actions.ts +++ b/src/services/omegaquotes/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createQuote } from '@/services/omegaquotes/create' import { readQuotesPage } from '@/services/omegaquotes/read' import { createOmegaquotesValidation } from '@/services/omegaquotes/validation' diff --git a/src/services/screens/actions.ts b/src/services/screens/actions.ts index 81fa5fef3..72ee87010 100644 --- a/src/services/screens/actions.ts +++ b/src/services/screens/actions.ts @@ -2,7 +2,7 @@ import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' import { RequirePermission } from '@/auth/auther/RequirePermission' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { createScreen } from '@/services/screens/create' import { destroyScreen } from '@/services/screens/destroy' import { readScreen, readScreens } from '@/services/screens/read' diff --git a/src/services/screens/pages/actions.ts b/src/services/screens/pages/actions.ts index 37cfdeae4..034973168 100644 --- a/src/services/screens/pages/actions.ts +++ b/src/services/screens/pages/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { createPage } from '@/services/screens/pages/create' import { destroyPage } from '@/services/screens/pages/destroy' import { readPage, readPages } from '@/services/screens/pages/read' diff --git a/src/services/sendmail/actions.ts b/src/services/sendmail/actions.ts index 492b79307..27bc12211 100644 --- a/src/services/sendmail/actions.ts +++ b/src/services/sendmail/actions.ts @@ -1,7 +1,7 @@ 'use server' import { createActionError, createZodActionError, safeServerCall } from '@/services/actionError' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { sendMail as transportSendMail } from '@/services/notifications/email/send' import { sendEmailValidation } from '@/services/notifications/email/validation' import type { ActionReturn } from '@/services/actionTypes' diff --git a/src/services/serverAction.ts b/src/services/serverAction.ts index f3707cfc4..9e80e02f7 100644 --- a/src/services/serverAction.ts +++ b/src/services/serverAction.ts @@ -1,6 +1,6 @@ import '@pn-server-only' import { safeServerCall } from './actionError' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import type { ActionReturn } from './actionTypes' import type { ServiceOperation } from '@/services/serviceOperation' import type { z } from 'zod' diff --git a/src/services/serviceOperation.ts b/src/services/serviceOperation.ts index bf75379d7..f6e735f21 100644 --- a/src/services/serviceOperation.ts +++ b/src/services/serviceOperation.ts @@ -2,12 +2,12 @@ import '@pn-server-only' import { ParseError, Smorekopp } from './error' import { prismaErrorWrapper } from './prismaCall' import { prisma as globalPrisma } from '@/prisma/client' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { zfd } from 'zod-form-data' import { AsyncLocalStorage } from 'async_hooks' import type { z } from 'zod' import type { Prisma, PrismaClient } from '@prisma/client' -import type { SessionMaybeUser } from '@/auth/Session' +import type { SessionMaybeUser } from '@/auth/session/Session' import type { AutherResult } from '@/auth/auther/Auther' /** diff --git a/src/services/users/operations.ts b/src/services/users/operations.ts index 9c8a3aba3..5966d3b42 100644 --- a/src/services/users/operations.ts +++ b/src/services/users/operations.ts @@ -20,7 +20,7 @@ import { readPageInputSchemaObject } from '@/lib/paging/schema' import { ServerError } from '@/services/error' import { getMembershipFilter } from '@/auth/getMembershipFilter' import { cursorPageingSelection } from '@/lib/paging/cursorPageingSelection' -import { hashAndEncryptPassword } from '@/auth/password' +import { hashAndEncryptPassword } from '@/auth/passwordHash' import { readCurrentOmegaOrder } from '@/services/omegaOrder/read' import { permissionOperations } from '@/services/permissions/operations' import { z } from 'zod' diff --git a/src/services/visibility/actions.ts b/src/services/visibility/actions.ts index 7e1eb1aee..f5e3800c7 100644 --- a/src/services/visibility/actions.ts +++ b/src/services/visibility/actions.ts @@ -2,7 +2,7 @@ import { createActionError, safeServerCall } from '@/services/actionError' import { checkVisibility } from '@/auth/checkVisibility' -import { getUser } from '@/auth/getUser' +import { getUser } from '@/auth/session/getUser' import { groupTypesConfig } from '@/services/groups/constants' import { groupOperations } from '@/services/groups/operations' import { purposeTextsConfig } from '@/services/visibility/ConfigVars' diff --git a/tests/services/apiKeys.test.ts b/tests/services/apiKeys.test.ts index fc72abacf..8385e1737 100644 --- a/tests/services/apiKeys.test.ts +++ b/tests/services/apiKeys.test.ts @@ -1,4 +1,4 @@ -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { Smorekopp } from '@/services/error' import { prisma } from '@/prisma/client' import { apiKeyOperations } from '@/services/api-keys/operations' diff --git a/tests/services/jobads.test.ts b/tests/services/jobads.test.ts index 090af3ef2..929a3c87b 100644 --- a/tests/services/jobads.test.ts +++ b/tests/services/jobads.test.ts @@ -1,4 +1,4 @@ -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { Smorekopp } from '@/services/error' import { prisma } from '@/prisma/client' import { jobAdOperations } from '@/services/career/jobAds/operations' diff --git a/tests/services/service-method.test.ts b/tests/services/service-method.test.ts index dfcc0e1b4..d7a0651ae 100644 --- a/tests/services/service-method.test.ts +++ b/tests/services/service-method.test.ts @@ -1,6 +1,6 @@ import { RequireNothing } from '@/auth/auther/RequireNothing' import { RequireServerOnly } from '@/auth/auther/ServerOnly' -import { Session } from '@/auth/Session' +import { Session } from '@/auth/session/Session' import { defineOperation } from '@/services/serviceOperation' import { prisma as globalPrisma } from '@/prisma/client' import { describe, expect, test } from '@jest/globals' From 05164b483f74d882b6110ec7e19d4f4ba6fdc80f Mon Sep 17 00:00:00 2001 From: Paulius Juzenas Date: Sat, 11 Oct 2025 09:06:07 +0200 Subject: [PATCH 24/24] refactor: rename service method holdouts --- src/app/api/apiHandler.ts | 8 +++--- src/app/api/shop/getAll/route.ts | 2 +- src/app/api/shop/product/barcode/route.ts | 2 +- .../purchase/createByStudentCard/route.ts | 2 +- src/app/api/users/connectStudentCard/route.ts | 2 +- src/app/api/users/get/[username]/route.ts | 4 +-- .../getWithBalance/[studentCard]/route.ts | 2 +- src/app/api/users/route.ts | 2 +- src/services/actionError.ts | 4 +-- src/services/career/companies/operations.ts | 2 +- src/services/groups/committees/read.ts | 2 +- src/services/serverAction.ts | 26 +++++++++---------- .../{jobads.test.ts => jobAds.test.ts} | 0 ...ethod.test.ts => serviceOperationstest.ts} | 6 ++--- 14 files changed, 32 insertions(+), 32 deletions(-) rename tests/services/{jobads.test.ts => jobAds.test.ts} (100%) rename tests/services/{service-method.test.ts => serviceOperationstest.ts} (94%) diff --git a/src/app/api/apiHandler.ts b/src/app/api/apiHandler.ts index 33834d4ed..b34403dfb 100644 --- a/src/app/api/apiHandler.ts +++ b/src/app/api/apiHandler.ts @@ -12,7 +12,7 @@ type APIHandler< ParamsSchema extends z.ZodTypeAny | undefined = undefined, DataSchema extends z.ZodTypeAny | undefined = undefined, > = { - serviceMethod: ServiceOperation, + serviceOperation: ServiceOperation, } & (ParamsSchema extends undefined ? { params?: undefined, } : { @@ -41,13 +41,13 @@ export function apiHandler< Return, ParamsSchema extends z.ZodTypeAny | undefined = undefined, DataSchema extends z.ZodTypeAny | undefined = undefined, ->({ serviceMethod, params }: APIHandler) { +>({ serviceOperation, params }: APIHandler) { // TODO: I think I will rewrite this to be easier to read return async (req: Request, { params: rawParams }: { params: Promise }) => await apiHandlerGeneric(req, async session => { let data - if (serviceMethod.dataSchema) { + if (serviceOperation.dataSchema) { try { data = await req.json() } catch (error) { @@ -58,7 +58,7 @@ export function apiHandler< } } - return serviceMethod<'UNCHECKED'>({ + return serviceOperation<'UNCHECKED'>({ params: params ? params(await rawParams) : undefined, data, session, diff --git a/src/app/api/shop/getAll/route.ts b/src/app/api/shop/getAll/route.ts index 34fe2420b..a525df2b4 100644 --- a/src/app/api/shop/getAll/route.ts +++ b/src/app/api/shop/getAll/route.ts @@ -2,5 +2,5 @@ import { apiHandler } from '@/app/api/apiHandler' import { shopOperations } from '@/services/shop/shop/operations' export const GET = apiHandler({ - serviceMethod: shopOperations.readMany, + serviceOperation: shopOperations.readMany, }) diff --git a/src/app/api/shop/product/barcode/route.ts b/src/app/api/shop/product/barcode/route.ts index c09295c9b..468ef56fc 100644 --- a/src/app/api/shop/product/barcode/route.ts +++ b/src/app/api/shop/product/barcode/route.ts @@ -2,5 +2,5 @@ import { apiHandler } from '@/app/api/apiHandler' import { productOperations } from '@/services/shop/product/operations' export const POST = apiHandler({ - serviceMethod: productOperations.readByBarCode, + serviceOperation: productOperations.readByBarCode, }) diff --git a/src/app/api/shop/purchase/createByStudentCard/route.ts b/src/app/api/shop/purchase/createByStudentCard/route.ts index f6de3e734..c2dfd7e47 100644 --- a/src/app/api/shop/purchase/createByStudentCard/route.ts +++ b/src/app/api/shop/purchase/createByStudentCard/route.ts @@ -2,5 +2,5 @@ import { apiHandler } from '@/app/api/apiHandler' import { purchaseOperations } from '@/services/shop/purchase/operations' export const POST = apiHandler({ - serviceMethod: purchaseOperations.createByStudentCard, + serviceOperation: purchaseOperations.createByStudentCard, }) diff --git a/src/app/api/users/connectStudentCard/route.ts b/src/app/api/users/connectStudentCard/route.ts index 7b90bc918..6ce1703b6 100644 --- a/src/app/api/users/connectStudentCard/route.ts +++ b/src/app/api/users/connectStudentCard/route.ts @@ -3,5 +3,5 @@ import { userOperations } from '@/services/users/operations' export const POST = apiHandler({ - serviceMethod: userOperations.connectStudentCard + serviceOperation: userOperations.connectStudentCard }) diff --git a/src/app/api/users/get/[username]/route.ts b/src/app/api/users/get/[username]/route.ts index c8bc2faae..957fc7773 100644 --- a/src/app/api/users/get/[username]/route.ts +++ b/src/app/api/users/get/[username]/route.ts @@ -2,11 +2,11 @@ import { apiHandler } from '@/api/apiHandler' import { userOperations } from '@/services/users/operations' export const GET = apiHandler({ - serviceMethod: userOperations.readProfile, + serviceOperation: userOperations.readProfile, params: (rawparams: {username: string}) => ({ username: rawparams.username }) }) export const PATCH = apiHandler({ - serviceMethod: userOperations.update, + serviceOperation: userOperations.update, params: (rawparams: { username: string }) => ({ username: rawparams.username }) }) diff --git a/src/app/api/users/getWithBalance/[studentCard]/route.ts b/src/app/api/users/getWithBalance/[studentCard]/route.ts index 718ec5343..bf389c275 100644 --- a/src/app/api/users/getWithBalance/[studentCard]/route.ts +++ b/src/app/api/users/getWithBalance/[studentCard]/route.ts @@ -5,5 +5,5 @@ export const GET = apiHandler({ params: (rawparams: { studentCard: string }) => ({ studentCard: rawparams.studentCard, }), - serviceMethod: userOperations.readUserWithBalance, + serviceOperation: userOperations.readUserWithBalance, }) diff --git a/src/app/api/users/route.ts b/src/app/api/users/route.ts index 768857257..a68ca7400 100644 --- a/src/app/api/users/route.ts +++ b/src/app/api/users/route.ts @@ -3,5 +3,5 @@ import { apiHandler } from '@/api/apiHandler' import { userOperations } from '@/services/users/operations' export const POST = apiHandler({ - serviceMethod: userOperations.create + serviceOperation: userOperations.create }) diff --git a/src/services/actionError.ts b/src/services/actionError.ts index 1b4ac9ff1..d8bc22767 100644 --- a/src/services/actionError.ts +++ b/src/services/actionError.ts @@ -5,7 +5,7 @@ import type { SafeParseError } from 'zod' import type { ActionError, ActionReturn } from './actionTypes' /** - * @deprecated With the "new" service method system this should not be called directly. + * @deprecated With the "new" service operation system this should not be called directly. * The action creation utility should handle this internally. */ export function createActionError(errorCode: ErrorCode | AuthStatus, error?: string | ErrorMessage[]): ActionError { @@ -26,7 +26,7 @@ export function createActionError(errorCode: ErrorCode | AuthStatus, error?: str } /** - * @deprecated With the "new" service method system this should not be called directly. + * @deprecated With the "new" service operation system this should not be called directly. * The action creation utility should handle this internally. */ export function createZodActionError(parse: SafeParseError): ActionError { diff --git a/src/services/career/companies/operations.ts b/src/services/career/companies/operations.ts index 18f7b62b8..0446e614c 100644 --- a/src/services/career/companies/operations.ts +++ b/src/services/career/companies/operations.ts @@ -14,7 +14,7 @@ export const companyOperations = { dataSchema: companySchemas.create, authorizer: () => companyAuth.create.dynamicFields({}), operation: async ({ prisma, data }) => { - //TODO: tranaction when createCmsImage is service method. + //TODO: tranaction when createCmsImage is service operation. const logo = await createCmsImage({ name: uuid() }) return await prisma.company.create({ data: { diff --git a/src/services/groups/committees/read.ts b/src/services/groups/committees/read.ts index ff799dc7f..7aa5b9cbc 100644 --- a/src/services/groups/committees/read.ts +++ b/src/services/groups/committees/read.ts @@ -88,7 +88,7 @@ export async function readCommitteeParagraph(shortName: string) : Promise( - serviceMethod: ServiceOperation + serviceOperation: ServiceOperation ): () => Promise> export function makeAction( - serviceMethod: ServiceOperation + serviceOperation: ServiceOperation ): (params: z.input) => Promise> export function makeAction( - serviceMethod: ServiceOperation + serviceOperation: ServiceOperation ): (data: z.input | FormData) => Promise> // This function is overloaded to allow for different combinations of parameters and data. export function makeAction( - serviceMethod: ServiceOperation + serviceOperation: ServiceOperation ): (params: z.input, data: z.input | FormData) => Promise> /** - * Turn a service method into suitable function for an action. + * Turn a service operation into suitable function for an action. * - * @param serviceMethod - The service method to create an action for. - * @returns - A function that takes in data (which may be FormData) and/or/nor parameters and calls the service method. + * @param serviceOperation - The service operation to create an action for. + * @returns - A function that takes in data (which may be FormData) and/or/nor parameters and calls the service operation. */ export function makeAction< Return, ParamsSchema extends z.ZodTypeAny | undefined = undefined, DataSchema extends z.ZodTypeAny | undefined = undefined, >( - serviceMethod: ServiceOperation + serviceOperation: ServiceOperation ) { // Letting the arguments to the actual function be unknown is safer as anything can be passed to it form the client. - // The action and service method will validate the parameter and data before it is used. + // The action and service operation will validate the parameter and data before it is used. // // For convenience this function is given a return type that is more specific. The return type is a function that - // has arguments witch match the underlying service method. This makes programming easier as Intellisense can + // has arguments witch match the underlying service operation. This makes programming easier as Intellisense can // help and errors are caught at compile time. const actionUnsafe = async (params?: unknown, data?: unknown) => { const session = await Session.fromNextAuth() @@ -50,15 +50,15 @@ export function makeAction< data = undefined } - return safeServerCall(() => serviceMethod<'UNCHECKED'>({ + return safeServerCall(() => serviceOperation<'UNCHECKED'>({ params, data, session, })) } - // If the service method has a params schema, we require the params to be passed to the action. - if (serviceMethod.paramsSchema) { + // If the service operation has a params schema, we require the params to be passed to the action. + if (serviceOperation.paramsSchema) { return actionUnsafe } diff --git a/tests/services/jobads.test.ts b/tests/services/jobAds.test.ts similarity index 100% rename from tests/services/jobads.test.ts rename to tests/services/jobAds.test.ts diff --git a/tests/services/service-method.test.ts b/tests/services/serviceOperationstest.ts similarity index 94% rename from tests/services/service-method.test.ts rename to tests/services/serviceOperationstest.ts index d7a0651ae..85fb6c5d3 100644 --- a/tests/services/service-method.test.ts +++ b/tests/services/serviceOperationstest.ts @@ -6,7 +6,7 @@ import { prisma as globalPrisma } from '@/prisma/client' import { describe, expect, test } from '@jest/globals' import { z } from 'zod' -describe('service method', () => { +describe('service operation', () => { describe('simple', () => { const addPositiveOnly = defineOperation({ authorizer: ({ data: { a, b } }) => { @@ -57,13 +57,13 @@ describe('service method', () => { }) describe('nested', () => { - // Simple service method that just returns its own context + // Simple service operation that just returns its own context const inner = defineOperation({ authorizer: () => RequireNothing.staticFields({}).dynamicFields({}), operation: async (context) => context, }) - // Outer service method that calls the inner one and returns its context + // Outer service operation that calls the inner one and returns its context const outer = defineOperation({ authorizer: () => RequireNothing.staticFields({}).dynamicFields({}), operation: async () => await inner({}),
    - {PermissionConfig[permission as Permission].name} + {permissionConfig[permission as Permission].name}
    Kanal - {NotificationConfig.methodsDisplayMap[method]} + {notificationMethodsDisplayMap[method]}