Init roles, permissions and resources repository
This commit is contained in:
parent
a468f3db68
commit
258205ef49
|
@ -0,0 +1,14 @@
|
|||
import { useCheckPermissionsMutation } from "../_queries/mutations"
|
||||
|
||||
export const useCheckPermissionsHandler = () => {
|
||||
const { mutateAsync: checkPermissions, isPending } = useCheckPermissionsMutation()
|
||||
|
||||
const handleCheckPermissions = async (userId: string, action: string, resource: string) => {
|
||||
return await checkPermissions({ userId, action, resource })
|
||||
}
|
||||
|
||||
return {
|
||||
handleCheckPermissions,
|
||||
isPending,
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { useMutation } from "@tanstack/react-query"
|
||||
import { sendMagicLink, sendPasswordRecovery, signInPasswordless, signInWithPassword, signOut, verifyOtp } from "../action"
|
||||
import { checkPermissions, sendMagicLink, sendPasswordRecovery, signInPasswordless, signInWithPassword, signOut, verifyOtp } from "../action"
|
||||
|
||||
export const useSignInPasswordlessMutation = () => {
|
||||
return useMutation({
|
||||
|
@ -42,3 +42,10 @@ export const useVerifyOtpMutation = () => {
|
|||
mutationFn: async (formData: FormData) => await verifyOtp(formData),
|
||||
})
|
||||
}
|
||||
|
||||
export const useCheckPermissionsMutation = () => {
|
||||
return useMutation({
|
||||
mutationKey: ["checkPermissions"],
|
||||
mutationFn: async ({ userId, action, resource }: { userId: string; action: string; resource: string }) => await checkPermissions(userId, action, resource),
|
||||
})
|
||||
}
|
|
@ -227,3 +227,26 @@ export async function sendPasswordRecovery(email: string) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function checkPermissions(userId: string, action: string, resource: string) {
|
||||
const instrumentationService = getInjection("IInstrumentationService")
|
||||
return await instrumentationService.instrumentServerAction("checkPermissions", {
|
||||
recordResponse: true
|
||||
}, async () => {
|
||||
try {
|
||||
const checkPermissionsController = getInjection("ICheckPermissionsController")
|
||||
return await checkPermissionsController({ userId, action, resource })
|
||||
} catch (err) {
|
||||
if (err instanceof InputParseError) {
|
||||
return { error: err.message }
|
||||
}
|
||||
|
||||
const crashReporterService = getInjection("ICrashReporterService")
|
||||
crashReporterService.report(err)
|
||||
|
||||
return {
|
||||
error: "An error occurred during permissions check. Please try again later.",
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
|
@ -5,6 +5,9 @@ import { createAuthenticationModule } from './modules/authentication.module';
|
|||
import { createMonitoringModule } from './modules/monitoring.module';
|
||||
import { createTransactionManagerModule } from './modules/database.modul';
|
||||
import { createUsersModule } from './modules/users.module';
|
||||
import { createRolesModule } from './modules/roles.module';
|
||||
import { createPermissionsModule } from './modules/permissions.module';
|
||||
import { createResourcesModule } from './modules/resources.module';
|
||||
|
||||
const ApplicationContainer = createContainer();
|
||||
|
||||
|
@ -12,6 +15,9 @@ ApplicationContainer.load(Symbol('MonitoringModule'), createMonitoringModule());
|
|||
ApplicationContainer.load(Symbol('TransactionManagerModule'), createTransactionManagerModule());
|
||||
ApplicationContainer.load(Symbol('AuthenticationModule'), createAuthenticationModule());
|
||||
ApplicationContainer.load(Symbol('UsersModule'), createUsersModule());
|
||||
ApplicationContainer.load(Symbol('RolesModule'), createRolesModule());
|
||||
ApplicationContainer.load(Symbol('PermissionsModule'), createPermissionsModule());
|
||||
ApplicationContainer.load(Symbol('ResourcesModule'), createResourcesModule());
|
||||
|
||||
export function getInjection<K extends keyof typeof DI_SYMBOLS>(
|
||||
symbol: K
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
import { createModule } from '@evyweb/ioctopus';
|
||||
|
||||
import { DI_SYMBOLS } from '@/di/types';
|
||||
import { createPermissionUseCase } from '@/src/application/use-cases/permissions/create-permissions.use-case';
|
||||
import { getAllPermissionsUseCase } from '@/src/application/use-cases/permissions/get-all-permissions';
|
||||
import { getPermissionByIdUseCase } from '@/src/application/use-cases/permissions/get-permissions-by-id.use-case';
|
||||
import { getPermissionByRoleUseCase } from '@/src/application/use-cases/permissions/get-permissions-by-role.use-case';
|
||||
import { updatePermissionUseCase } from '@/src/application/use-cases/permissions/update-permissions.use-case';
|
||||
import { deletePermissionUseCase } from '@/src/application/use-cases/permissions/delete-permissions.use-case';
|
||||
import { createPermissionController } from '@/src/interface-adapters/controllers/permissions/create-permission.controller';
|
||||
import { getAllPermissionsController } from '@/src/interface-adapters/controllers/permissions/get-all-permission.controller';
|
||||
import { getPermissionByIdController } from '@/src/interface-adapters/controllers/permissions/get-permission-by-id.controller';
|
||||
import { getPermissionByRoleController } from '@/src/interface-adapters/controllers/permissions/get-permission-by-role.controller';
|
||||
import { updatePermissionController } from '@/src/interface-adapters/controllers/permissions/update-permission.controller';
|
||||
import { deletePermissionController } from '@/src/interface-adapters/controllers/permissions/delete-permission.controller';
|
||||
|
||||
export function createPermissionsModule() {
|
||||
const permissionsModule = createModule();
|
||||
|
||||
// Use Cases
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.ICreatePermissionUseCase)
|
||||
.toHigherOrderFunction(createPermissionUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IPermissionsRepository,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IGetAllPermissionsUseCase)
|
||||
.toHigherOrderFunction(getAllPermissionsUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IPermissionsRepository,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IGetPermissionByIdUseCase)
|
||||
.toHigherOrderFunction(getPermissionByIdUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IPermissionsRepository,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IGetPermissionByRoleUseCase)
|
||||
.toHigherOrderFunction(getPermissionByRoleUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IPermissionsRepository,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IUpdatePermissionUseCase)
|
||||
.toHigherOrderFunction(updatePermissionUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IPermissionsRepository,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IDeletePermissionUseCase)
|
||||
.toHigherOrderFunction(deletePermissionUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IPermissionsRepository,
|
||||
]);
|
||||
|
||||
// Controllers
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.ICreatePermissionController)
|
||||
.toHigherOrderFunction(createPermissionController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.ICreatePermissionUseCase,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IGetAllPermissionsController)
|
||||
.toHigherOrderFunction(getAllPermissionsController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IGetAllPermissionsUseCase,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IGetPermissionByIdController)
|
||||
.toHigherOrderFunction(getPermissionByIdController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IGetPermissionByIdUseCase,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IGetPermissionByRoleController)
|
||||
.toHigherOrderFunction(getPermissionByRoleController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IGetPermissionByRoleUseCase,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IUpdatePermissionController)
|
||||
.toHigherOrderFunction(updatePermissionController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IUpdatePermissionUseCase,
|
||||
]);
|
||||
|
||||
permissionsModule
|
||||
.bind(DI_SYMBOLS.IDeletePermissionController)
|
||||
.toHigherOrderFunction(deletePermissionController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IDeletePermissionUseCase,
|
||||
]);
|
||||
|
||||
return permissionsModule;
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
import { createModule } from '@evyweb/ioctopus';
|
||||
|
||||
import { DI_SYMBOLS } from '@/di/types';
|
||||
import { createResourceUseCase } from '@/src/application/use-cases/resources/create-resources.use-case';
|
||||
import { getResourceByIdUseCase } from '@/src/application/use-cases/resources/get-resource-by-id.use-case';
|
||||
import { getResourcesByTypeUseCase } from '@/src/application/use-cases/resources/get-resources-by-type.use-case';
|
||||
import { updateResourceUseCase } from '@/src/application/use-cases/resources/update-resource.use-case';
|
||||
import { deleteResourceUseCase } from '@/src/application/use-cases/resources/delete-resource.use-case';
|
||||
import { createResourceController } from '@/src/interface-adapters/controllers/resources/create-resource.controller';
|
||||
import { getResourceByIdController } from '@/src/interface-adapters/controllers/resources/get-resource-by-id.controller';
|
||||
import { getResourcesByTypeController } from '@/src/interface-adapters/controllers/resources/get-resources-by-type.controller';
|
||||
import { updateResourceController } from '@/src/interface-adapters/controllers/resources/update-resource.controller';
|
||||
import { deleteResourceController } from '@/src/interface-adapters/controllers/resources/delete-resource.controller';
|
||||
|
||||
export function createResourcesModule() {
|
||||
const resourcesModule = createModule();
|
||||
|
||||
// Use Cases
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.ICreateResourceUseCase)
|
||||
.toHigherOrderFunction(createResourceUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IResourcesRepository,
|
||||
]);
|
||||
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.IGetResourceByIdUseCase)
|
||||
.toHigherOrderFunction(getResourceByIdUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IResourcesRepository,
|
||||
]);
|
||||
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.IGetResourcesByTypeUseCase)
|
||||
.toHigherOrderFunction(getResourcesByTypeUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IResourcesRepository,
|
||||
]);
|
||||
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.IUpdateResourceUseCase)
|
||||
.toHigherOrderFunction(updateResourceUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IResourcesRepository,
|
||||
]);
|
||||
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.IDeleteResourceUseCase)
|
||||
.toHigherOrderFunction(deleteResourceUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IResourcesRepository,
|
||||
]);
|
||||
|
||||
// Controllers
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.ICreateResourceController)
|
||||
.toHigherOrderFunction(createResourceController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.ICreateResourceUseCase,
|
||||
]);
|
||||
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.IGetResourceByIdController)
|
||||
.toHigherOrderFunction(getResourceByIdController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IGetResourceByIdUseCase,
|
||||
]);
|
||||
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.IGetResourcesByTypeController)
|
||||
.toHigherOrderFunction(getResourcesByTypeController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IGetResourcesByTypeUseCase,
|
||||
]);
|
||||
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.IUpdateResourceController)
|
||||
.toHigherOrderFunction(updateResourceController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IUpdateResourceUseCase,
|
||||
]);
|
||||
|
||||
resourcesModule
|
||||
.bind(DI_SYMBOLS.IDeleteResourceController)
|
||||
.toHigherOrderFunction(deleteResourceController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IDeleteResourceUseCase,
|
||||
]);
|
||||
|
||||
return resourcesModule;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
import { createModule } from '@evyweb/ioctopus';
|
||||
|
||||
import { DI_SYMBOLS } from '@/di/types';
|
||||
import { createRoleUseCase } from '@/src/application/use-cases/roles/create-role.use-case';
|
||||
import { getRoleByIdUseCase } from '@/src/application/use-cases/roles/get-role-by-id.use-case';
|
||||
import { updateRoleUseCase } from '@/src/application/use-cases/roles/update-role.use-case';
|
||||
import { deleteRoleUseCase } from '@/src/application/use-cases/roles/delete-role.use-case';
|
||||
import { createRoleController } from '@/src/interface-adapters/controllers/roles/create-role.controller';
|
||||
import { getRoleByIdController } from '@/src/interface-adapters/controllers/roles/get-role-by-id.controller';
|
||||
import { updateRoleController } from '@/src/interface-adapters/controllers/roles/update-role.controller';
|
||||
import { deleteRoleController } from '@/src/interface-adapters/controllers/roles/delete-role.controller';
|
||||
|
||||
export function createRolesModule() {
|
||||
const rolesModule = createModule();
|
||||
|
||||
// Use Cases
|
||||
rolesModule
|
||||
.bind(DI_SYMBOLS.ICreateRoleUseCase)
|
||||
.toHigherOrderFunction(createRoleUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IRolesRepository,
|
||||
]);
|
||||
|
||||
rolesModule
|
||||
.bind(DI_SYMBOLS.IGetRoleByIdUseCase)
|
||||
.toHigherOrderFunction(getRoleByIdUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IRolesRepository,
|
||||
]);
|
||||
|
||||
rolesModule
|
||||
.bind(DI_SYMBOLS.IUpdateRoleUseCase)
|
||||
.toHigherOrderFunction(updateRoleUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IRolesRepository,
|
||||
]);
|
||||
|
||||
rolesModule
|
||||
.bind(DI_SYMBOLS.IDeleteRoleUseCase)
|
||||
.toHigherOrderFunction(deleteRoleUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IRolesRepository,
|
||||
]);
|
||||
|
||||
// Controllers
|
||||
rolesModule
|
||||
.bind(DI_SYMBOLS.ICreateRoleController)
|
||||
.toHigherOrderFunction(createRoleController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.ICreateRoleUseCase,
|
||||
]);
|
||||
|
||||
rolesModule
|
||||
.bind(DI_SYMBOLS.IGetRoleByIdController)
|
||||
.toHigherOrderFunction(getRoleByIdController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IGetRoleByIdUseCase,
|
||||
]);
|
||||
|
||||
rolesModule
|
||||
.bind(DI_SYMBOLS.IUpdateRoleController)
|
||||
.toHigherOrderFunction(updateRoleController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IUpdateRoleUseCase,
|
||||
]);
|
||||
|
||||
rolesModule
|
||||
.bind(DI_SYMBOLS.IDeleteRoleController)
|
||||
.toHigherOrderFunction(deleteRoleController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IDeleteRoleUseCase,
|
||||
]);
|
||||
|
||||
return rolesModule;
|
||||
}
|
|
@ -90,7 +90,7 @@ export function createUsersModule() {
|
|||
]);
|
||||
|
||||
usersModule
|
||||
.bind(DI_SYMBOLS.IGetUserByUserNameUseCase)
|
||||
.bind(DI_SYMBOLS.IGetUserByUsernameUseCase)
|
||||
.toHigherOrderFunction(getUserByUsernameUseCase, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IUsersRepository
|
||||
|
@ -180,7 +180,7 @@ export function createUsersModule() {
|
|||
.bind(DI_SYMBOLS.IGetUserByUsernameController)
|
||||
.toHigherOrderFunction(getUserByUsernameController, [
|
||||
DI_SYMBOLS.IInstrumentationService,
|
||||
DI_SYMBOLS.IGetUserByUserNameUseCase
|
||||
DI_SYMBOLS.IGetUserByUsernameUseCase
|
||||
]);
|
||||
|
||||
usersModule
|
||||
|
|
|
@ -40,8 +40,46 @@ import { ISendPasswordRecoveryController } from '@/src/interface-adapters/contro
|
|||
import { IUploadAvatarController } from '@/src/interface-adapters/controllers/users/upload-avatar.controller';
|
||||
import { IUploadAvatarUseCase } from '@/src/application/use-cases/users/upload-avatar.use-case';
|
||||
import { ISignInWithPasswordController } from '@/src/interface-adapters/controllers/auth/sign-in-with-password.controller';
|
||||
import { IRolesRepository } from '@/src/application/repositories/roles.repository.interface';
|
||||
import { IPermissionsRepository } from '@/src/application/repositories/permissions.repository.interface';
|
||||
import { IResourcesRepository } from '@/src/application/repositories/resources.repository.interface';
|
||||
import { ICreateRoleUseCase } from '@/src/application/use-cases/roles/create-role.use-case';
|
||||
import { IGetRoleByIdUseCase } from '@/src/application/use-cases/roles/get-role-by-id.use-case';
|
||||
import { IUpdateRoleUseCase } from '@/src/application/use-cases/roles/update-role.use-case';
|
||||
import { IDeleteRoleUseCase } from '@/src/application/use-cases/roles/delete-role.use-case';
|
||||
import { ICreatePermissionUseCase } from '@/src/application/use-cases/permissions/create-permissions.use-case';
|
||||
import { IGetAllPermissionsUseCase } from '@/src/application/use-cases/permissions/get-all-permissions';
|
||||
import { IGetPermissionByIdUseCase } from '@/src/application/use-cases/permissions/get-permissions-by-id.use-case';
|
||||
import { IGetPermissionByRoleUseCase } from '@/src/application/use-cases/permissions/get-permissions-by-role.use-case';
|
||||
import { IGetPermissionByRoleAndResourceController } from '@/src/interface-adapters/controllers/permissions/get-permission-by-role-and-resource.controller';
|
||||
import { IGetPermissionByRoleAndResourcesUseCase } from '@/src/application/use-cases/permissions/get-permissions-by-role-and-resources.use-case';
|
||||
import { IUpdatePermissionUseCase } from '@/src/application/use-cases/permissions/update-permissions.use-case';
|
||||
import { IDeletePermissionUseCase } from '@/src/application/use-cases/permissions/delete-permissions.use-case';
|
||||
import { ICreateResourceUseCase } from '@/src/application/use-cases/resources/create-resources.use-case';
|
||||
import { IGetResourceByIdUseCase } from '@/src/application/use-cases/resources/get-resource-by-id.use-case';
|
||||
import { IGetResourcesByTypeUseCase } from '@/src/application/use-cases/resources/get-resources-by-type.use-case';
|
||||
import { IUpdateResourceUseCase } from '@/src/application/use-cases/resources/update-resource.use-case';
|
||||
import { IDeleteResourceUseCase } from '@/src/application/use-cases/resources/delete-resource.use-case';
|
||||
import { ICheckPermissionsController } from '@/src/interface-adapters/controllers/auth/check-permissions.controller';
|
||||
import { ICreateRoleController } from '@/src/interface-adapters/controllers/roles/create-role.controller';
|
||||
import { IGetRoleByIdController } from '@/src/interface-adapters/controllers/roles/get-role-by-id.controller';
|
||||
import { IUpdateRoleController } from '@/src/interface-adapters/controllers/roles/update-role.controller';
|
||||
import { IDeleteRoleController } from '@/src/interface-adapters/controllers/roles/delete-role.controller';
|
||||
import { ICreatePermissionController } from '@/src/interface-adapters/controllers/permissions/create-permission.controller';
|
||||
import { IGetAllPermissionsController } from '@/src/interface-adapters/controllers/permissions/get-all-permission.controller';
|
||||
import { IGetPermissionByIdController } from '@/src/interface-adapters/controllers/permissions/get-permission-by-id.controller';
|
||||
import { IGetPermissionByRoleController } from '@/src/interface-adapters/controllers/permissions/get-permission-by-role.controller';
|
||||
import { IUpdatePermissionController } from '@/src/interface-adapters/controllers/permissions/update-permission.controller';
|
||||
import { IDeletePermissionController } from '@/src/interface-adapters/controllers/permissions/delete-permission.controller';
|
||||
import { IGetResourceByIdController } from '@/src/interface-adapters/controllers/resources/get-resource-by-id.controller';
|
||||
import { IGetResourcesByTypeController } from '@/src/interface-adapters/controllers/resources/get-resources-by-type.controller';
|
||||
import { IDeleteResourceController } from '@/src/interface-adapters/controllers/resources/delete-resource.controller';
|
||||
import { IUpdateResourceController } from '@/src/interface-adapters/controllers/resources/update-resource.controller';
|
||||
import { ICreateResourceController } from '@/src/interface-adapters/controllers/resources/create-resource.controller';
|
||||
import { ICheckPermissionsUseCase } from '@/src/application/use-cases/auth/check-permissions.use-case';
|
||||
|
||||
export const DI_SYMBOLS = {
|
||||
// Pastikan DI_SYMBOLS memiliki tipe yang sesuai dengan DI_RETURN_TYPES
|
||||
export const DI_SYMBOLS: { [K in keyof DI_RETURN_TYPES]: symbol } = {
|
||||
// Services
|
||||
IAuthenticationService: Symbol.for('IAuthenticationService'),
|
||||
ITransactionManagerService: Symbol.for('ITransactionManagerService'),
|
||||
|
@ -50,37 +88,69 @@ export const DI_SYMBOLS = {
|
|||
|
||||
// Repositories
|
||||
IUsersRepository: Symbol.for('IUsersRepository'),
|
||||
IRolesRepository: Symbol.for('IRolesRepository'),
|
||||
IPermissionsRepository: Symbol.for('IPermissionsRepository'),
|
||||
IResourcesRepository: Symbol.for('IResourcesRepository'),
|
||||
|
||||
// Use Cases
|
||||
|
||||
// Auth Use Cases
|
||||
ISignInPasswordlessUseCase: Symbol.for('ISignInPasswordlessUseCase'),
|
||||
ISignInWithPasswordUseCase: Symbol.for('ISignInWithPasswordUseCase'),
|
||||
ISignUpUseCase: Symbol.for('ISignUpUseCase'),
|
||||
IVerifyOtpUseCase: Symbol.for('IVerifyOtpUseCase'),
|
||||
ISignOutUseCase: Symbol.for('ISignOutUseCase'),
|
||||
ISendMagicLinkUseCase: Symbol.for('ISendMagicLinkUseCase'),
|
||||
ISendPasswordRecoveryUseCase: Symbol.for('ISendPasswordRecoveryUseCase'),
|
||||
ICheckPermissionsUseCase: Symbol.for('ICheckPermissionsUseCase'),
|
||||
|
||||
// User Use Cases
|
||||
IBanUserUseCase: Symbol.for('IBanUserUseCase'),
|
||||
IUnbanUserUseCase: Symbol.for('IUnbanUserUseCase'),
|
||||
IGetCurrentUserUseCase: Symbol.for('IGetCurrentUserUseCase'),
|
||||
IGetUsersUseCase: Symbol.for('IGetUsersUseCase'),
|
||||
IGetUserByIdUseCase: Symbol.for('IGetUserByIdUseCase'),
|
||||
IGetUserByEmailUseCase: Symbol.for('IGetUserByEmailUseCase'),
|
||||
IGetUserByUserNameUseCase: Symbol.for('IGetUserByUserNameUseCase'),
|
||||
IGetUserByUsernameUseCase: Symbol.for('IGetUserByUsernameUseCase'),
|
||||
IInviteUserUseCase: Symbol.for('IInviteUserUseCase'),
|
||||
ICreateUserUseCase: Symbol.for('ICreateUserUseCase'),
|
||||
IUpdateUserUseCase: Symbol.for('IUpdateUserUseCase'),
|
||||
IDeleteUserUseCase: Symbol.for('IDeleteUserUseCase'),
|
||||
IUploadAvatarUseCase: Symbol.for('IUploadAvatarUseCase'),
|
||||
|
||||
// Role Use Cases
|
||||
ICreateRoleUseCase: Symbol.for('ICreateRoleUseCase'),
|
||||
IGetRoleByIdUseCase: Symbol.for('IGetRoleByIdUseCase'),
|
||||
IUpdateRoleUseCase: Symbol.for('IUpdateRoleUseCase'),
|
||||
IDeleteRoleUseCase: Symbol.for('IDeleteRoleUseCase'),
|
||||
|
||||
// Permission Use Cases
|
||||
ICreatePermissionUseCase: Symbol.for('ICreatePermissionUseCase'),
|
||||
IGetAllPermissionsUseCase: Symbol.for('IGetAllPermissionsUseCase'),
|
||||
IGetPermissionByIdUseCase: Symbol.for('IGetPermissionByIdUseCase'),
|
||||
IGetPermissionByRoleUseCase: Symbol.for('IGetPermissionByRoleUseCase'),
|
||||
IGetPermissionByRoleAndResourcesUseCase: Symbol.for('IGetPermissionByRoleAndResourcesUseCase'),
|
||||
IUpdatePermissionUseCase: Symbol.for('IUpdatePermissionUseCase'),
|
||||
IDeletePermissionUseCase: Symbol.for('IDeletePermissionUseCase'),
|
||||
|
||||
// Resource Use Cases
|
||||
ICreateResourceUseCase: Symbol.for('ICreateResourceUseCase'),
|
||||
IGetResourceByIdUseCase: Symbol.for('IGetResourceByIdUseCase'),
|
||||
IGetResourcesByTypeUseCase: Symbol.for('IGetResourcesByTypeUseCase'),
|
||||
IUpdateResourceUseCase: Symbol.for('IUpdateResourceUseCase'),
|
||||
IDeleteResourceUseCase: Symbol.for('IDeleteResourceUseCase'),
|
||||
|
||||
// Controllers
|
||||
|
||||
// Auth Controllers
|
||||
ISignInPasswordlessController: Symbol.for('ISignInPasswordlessController'),
|
||||
ISignInWithPasswordController: Symbol.for('ISignInWithPasswordController'),
|
||||
ISignOutController: Symbol.for('ISignOutController'),
|
||||
IVerifyOtpController: Symbol.for('IVerifyOtpController'),
|
||||
ISendMagicLinkController: Symbol.for('ISendMagicLinkController'),
|
||||
ISendPasswordRecoveryController: Symbol.for('ISendPasswordRecoveryController'),
|
||||
ICheckPermissionsController: Symbol.for('ICheckPermissionsController'),
|
||||
|
||||
// User Controllers
|
||||
IBanUserController: Symbol.for('IBanUserController'),
|
||||
IUnbanUserController: Symbol.for('IUnbanUserController'),
|
||||
IGetCurrentUserController: Symbol.for('IGetCurrentUserController'),
|
||||
|
@ -93,6 +163,28 @@ export const DI_SYMBOLS = {
|
|||
IUpdateUserController: Symbol.for('IUpdateUserController'),
|
||||
IDeleteUserController: Symbol.for('IDeleteUserController'),
|
||||
IUploadAvatarController: Symbol.for('IUploadAvatarController'),
|
||||
|
||||
// Role Controllers
|
||||
ICreateRoleController: Symbol.for('ICreateRoleController'),
|
||||
IGetRoleByIdController: Symbol.for('IGetRoleByIdController'),
|
||||
IUpdateRoleController: Symbol.for('IUpdateRoleController'),
|
||||
IDeleteRoleController: Symbol.for('IDeleteRoleController'),
|
||||
|
||||
// Permission Controllers
|
||||
ICreatePermissionController: Symbol.for('ICreatePermissionController'),
|
||||
IGetAllPermissionsController: Symbol.for('IGetAllPermissionsController'),
|
||||
IGetPermissionByIdController: Symbol.for('IGetPermissionByIdController'),
|
||||
IGetPermissionByRoleController: Symbol.for('IGetPermissionByRoleController'),
|
||||
IGetPermissionByRoleAndResourceController: Symbol.for('IGetPermissionByRoleAndResourceController'),
|
||||
IUpdatePermissionController: Symbol.for('IUpdatePermissionController'),
|
||||
IDeletePermissionController: Symbol.for('IDeletePermissionController'),
|
||||
|
||||
// Resource Controllers
|
||||
ICreateResourceController: Symbol.for('ICreateResourceController'),
|
||||
IGetResourceByIdController: Symbol.for('IGetResourceByIdController'),
|
||||
IGetResourcesByTypeController: Symbol.for('IGetResourcesByTypeController'),
|
||||
IUpdateResourceController: Symbol.for('IUpdateResourceController'),
|
||||
IDeleteResourceController: Symbol.for('IDeleteResourceController'),
|
||||
};
|
||||
|
||||
export interface DI_RETURN_TYPES {
|
||||
|
@ -104,36 +196,69 @@ export interface DI_RETURN_TYPES {
|
|||
|
||||
// Repositories
|
||||
IUsersRepository: IUsersRepository;
|
||||
IRolesRepository: IRolesRepository;
|
||||
IPermissionsRepository: IPermissionsRepository;
|
||||
IResourcesRepository: IResourcesRepository;
|
||||
|
||||
// Use Cases
|
||||
|
||||
// Auth Use Cases
|
||||
ISignInPasswordlessUseCase: ISignInPasswordlessUseCase;
|
||||
ISignUpUseCase: ISignUpUseCase;
|
||||
IVerifyOtpUseCase: IVerifyOtpUseCase;
|
||||
ISignOutUseCase: ISignOutUseCase;
|
||||
ISendMagicLinkUseCase: ISendMagicLinkUseCase;
|
||||
ISendPasswordRecoveryUseCase: ISendPasswordRecoveryUseCase;
|
||||
ICheckPermissionsUseCase: ICheckPermissionsUseCase;
|
||||
|
||||
// User Use Cases
|
||||
IBanUserUseCase: IBanUserUseCase;
|
||||
IUnbanUserUseCase: IUnbanUserUseCase;
|
||||
IGetCurrentUserUseCase: IGetCurrentUserUseCase;
|
||||
IGetUsersUseCase: IGetUsersUseCase;
|
||||
IGetUserByIdUseCase: IGetUserByIdUseCase;
|
||||
IGetUserByEmailUseCase: IGetUserByEmailUseCase;
|
||||
IGetUserByUserNameUseCase: IGetUserByUsernameUseCase;
|
||||
IGetUserByUsernameUseCase: IGetUserByUsernameUseCase;
|
||||
IInviteUserUseCase: IInviteUserUseCase;
|
||||
ICreateUserUseCase: ICreateUserUseCase;
|
||||
IUpdateUserUseCase: IUpdateUserUseCase;
|
||||
IDeleteUserUseCase: IDeleteUserUseCase;
|
||||
IUploadAvatarUseCase: IUploadAvatarUseCase;
|
||||
|
||||
// Role Use Cases
|
||||
ICreateRoleUseCase: ICreateRoleUseCase;
|
||||
IGetRoleByIdUseCase: IGetRoleByIdUseCase;
|
||||
IUpdateRoleUseCase: IUpdateRoleUseCase;
|
||||
IDeleteRoleUseCase: IDeleteRoleUseCase;
|
||||
|
||||
// Permission Use Cases
|
||||
ICreatePermissionUseCase: ICreatePermissionUseCase;
|
||||
IGetAllPermissionsUseCase: IGetAllPermissionsUseCase;
|
||||
IGetPermissionByIdUseCase: IGetPermissionByIdUseCase;
|
||||
IGetPermissionByRoleUseCase: IGetPermissionByRoleUseCase;
|
||||
IGetPermissionByRoleAndResourcesUseCase: IGetPermissionByRoleAndResourcesUseCase;
|
||||
IUpdatePermissionUseCase: IUpdatePermissionUseCase;
|
||||
IDeletePermissionUseCase: IDeletePermissionUseCase;
|
||||
|
||||
// Resource Use Cases
|
||||
ICreateResourceUseCase: ICreateResourceUseCase;
|
||||
IGetResourceByIdUseCase: IGetResourceByIdUseCase;
|
||||
IGetResourcesByTypeUseCase: IGetResourcesByTypeUseCase;
|
||||
IUpdateResourceUseCase: IUpdateResourceUseCase;
|
||||
IDeleteResourceUseCase: IDeleteResourceUseCase;
|
||||
|
||||
// Controllers
|
||||
|
||||
// Auth Controllers
|
||||
ISignInPasswordlessController: ISignInPasswordlessController;
|
||||
ISignInWithPasswordController: ISignInWithPasswordController;
|
||||
IVerifyOtpController: IVerifyOtpController;
|
||||
ISignOutController: ISignOutController;
|
||||
ISendMagicLinkController: ISendMagicLinkController;
|
||||
ISendPasswordRecoveryController: ISendPasswordRecoveryController;
|
||||
ICheckPermissionsController: ICheckPermissionsController;
|
||||
|
||||
// User Controllers
|
||||
IBanUserController: IBanUserController;
|
||||
IUnbanUserController: IUnbanUserController;
|
||||
IGetCurrentUserController: IGetCurrentUserController;
|
||||
|
@ -147,4 +272,26 @@ export interface DI_RETURN_TYPES {
|
|||
IDeleteUserController: IDeleteUserController;
|
||||
IUploadAvatarController: IUploadAvatarController;
|
||||
|
||||
// Role Controllers
|
||||
ICreateRoleController: ICreateRoleController;
|
||||
IGetRoleByIdController: IGetRoleByIdController;
|
||||
IUpdateRoleController: IUpdateRoleController;
|
||||
IDeleteRoleController: IDeleteRoleController;
|
||||
|
||||
// Permission Controllers
|
||||
ICreatePermissionController: ICreatePermissionController;
|
||||
IGetAllPermissionsController: IGetAllPermissionsController;
|
||||
IGetPermissionByIdController: IGetPermissionByIdController;
|
||||
IGetPermissionByRoleController: IGetPermissionByRoleController;
|
||||
IGetPermissionByRoleAndResourceController: IGetPermissionByRoleAndResourceController;
|
||||
IUpdatePermissionController: IUpdatePermissionController;
|
||||
IDeletePermissionController: IDeletePermissionController;
|
||||
|
||||
// Resource Controllers
|
||||
ICreateResourceController: ICreateResourceController;
|
||||
IGetResourceByIdController: IGetResourceByIdController;
|
||||
IGetResourcesByTypeController: IGetResourcesByTypeController;
|
||||
IUpdateResourceController: IUpdateResourceController;
|
||||
IDeleteResourceController: IDeleteResourceController;
|
||||
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
"db:seed": "npx prisma db seed"
|
||||
},
|
||||
"prisma": {
|
||||
"seed": "ts-node prisma/seed.ts"
|
||||
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@evyweb/ioctopus": "^1.2.0",
|
||||
|
|
|
@ -183,6 +183,7 @@ model roles {
|
|||
model resources {
|
||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||
name String @unique @db.VarChar(255)
|
||||
type String?
|
||||
description String?
|
||||
instance_role String?
|
||||
relations String?
|
||||
|
@ -195,8 +196,8 @@ model resources {
|
|||
model permissions {
|
||||
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
|
||||
action String
|
||||
resource_id String
|
||||
role_id String
|
||||
resource_id String @db.Uuid
|
||||
role_id String @db.Uuid
|
||||
resource resources @relation(fields: [resource_id], references: [id])
|
||||
role roles @relation(fields: [role_id], references: [id])
|
||||
created_at DateTime @default(now()) @db.Timestamptz(6)
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log('Starting seeding...');
|
||||
|
||||
// Create roles
|
||||
const adminRole = await prisma.roles.upsert({
|
||||
where: { name: 'admin' },
|
||||
update: {},
|
||||
create: {
|
||||
|
||||
name: 'admin',
|
||||
description: 'Administrator with full access to all features',
|
||||
},
|
||||
});
|
||||
|
||||
const viewerRole = await prisma.roles.upsert({
|
||||
where: { name: 'viewer' },
|
||||
update: {},
|
||||
create: {
|
||||
|
||||
name: 'viewer',
|
||||
description: 'Read-only access to data',
|
||||
},
|
||||
});
|
||||
|
||||
const staffRole = await prisma.roles.upsert({
|
||||
where: { name: 'staff' },
|
||||
update: {},
|
||||
create: {
|
||||
|
||||
name: 'staff',
|
||||
description: 'Staff with limited administrative access',
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Roles created:', { adminRole, viewerRole, staffRole });
|
||||
|
||||
// Create resources based on Prisma schema models
|
||||
const resources = [
|
||||
{
|
||||
name: 'cities',
|
||||
description: 'City data management',
|
||||
attributes: {
|
||||
fields: ['id', 'name', 'code', 'geographic_id', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'contact_messages',
|
||||
description: 'Contact message management',
|
||||
attributes: {
|
||||
fields: ['id', 'name', 'email', 'phone', 'message_type', 'message_type_label', 'message', 'status', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'crime_cases',
|
||||
description: 'Crime case management',
|
||||
attributes: {
|
||||
fields: ['id', 'crime_id', 'crime_category_id', 'date', 'time', 'location', 'latitude', 'longitude', 'description', 'victim_count', 'status', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'crime_categories',
|
||||
description: 'Crime category management',
|
||||
attributes: {
|
||||
fields: ['id', 'name', 'description', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'crimes',
|
||||
description: 'Crime data management',
|
||||
attributes: {
|
||||
fields: ['id', 'district_id', 'city_id', 'year', 'number_of_crime', 'rate', 'heat_map', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'demographics',
|
||||
description: 'Demographic data management',
|
||||
attributes: {
|
||||
fields: ['id', 'district_id', 'city_id', 'province_id', 'year', 'population', 'population_density', 'poverty_rate', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'districts',
|
||||
description: 'District data management',
|
||||
attributes: {
|
||||
fields: ['id', 'city_id', 'name', 'code', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'geographics',
|
||||
description: 'Geographic data management',
|
||||
attributes: {
|
||||
fields: ['id', 'district_id', 'latitude', 'longitude', 'land_area', 'polygon', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'profiles',
|
||||
description: 'User profile management',
|
||||
attributes: {
|
||||
fields: ['id', 'user_id', 'avatar', 'username', 'first_name', 'last_name', 'bio', 'address', 'birth_date']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'users',
|
||||
description: 'User account management',
|
||||
attributes: {
|
||||
fields: ['id', 'roles_id', 'email', 'phone', 'encrypted_password', 'invited_at', 'confirmed_at', 'email_confirmed_at', 'recovery_sent_at', 'last_sign_in_at', 'app_metadata', 'user_metadata', 'created_at', 'updated_at', 'banned_until', 'is_anonymous']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'roles',
|
||||
description: 'Role management',
|
||||
attributes: {
|
||||
fields: ['id', 'name', 'description', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'resources',
|
||||
description: 'Resource management',
|
||||
attributes: {
|
||||
fields: ['id', 'name', 'description', 'instance_role', 'relations', 'attributes', 'created_at', 'updated_at']
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'permissions',
|
||||
description: 'Permission management',
|
||||
attributes: {
|
||||
fields: ['id', 'action', 'resource_id', 'role_id', 'created_at', 'updated_at']
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// Create resources in the database
|
||||
for (const resource of resources) {
|
||||
const createdResource = await prisma.resources.upsert({
|
||||
where: { name: resource.name },
|
||||
update: {},
|
||||
create: {
|
||||
name: resource.name,
|
||||
description: resource.description,
|
||||
attributes: resource.attributes
|
||||
},
|
||||
});
|
||||
console.log(`Resource ${resource.name} created/updated with ID: ${createdResource.id}`);
|
||||
}
|
||||
|
||||
// Set up basic permissions for each role
|
||||
const allResources = await prisma.resources.findMany();
|
||||
|
||||
// Admin permissions - full access to all resources
|
||||
for (const resource of allResources) {
|
||||
await createPermissions(adminRole.id, resource.id, ['create', 'read', 'update', 'delete']);
|
||||
}
|
||||
|
||||
// Viewer permissions - read-only access to all resources
|
||||
for (const resource of allResources) {
|
||||
await createPermissions(viewerRole.id, resource.id, ['read']);
|
||||
}
|
||||
|
||||
// Staff permissions - mixed permissions based on resource
|
||||
for (const resource of allResources) {
|
||||
if (['roles', 'permissions', 'resources', 'users'].includes(resource.name)) {
|
||||
// Staff can only read roles, permissions, resources and users
|
||||
await createPermissions(staffRole.id, resource.id, ['read']);
|
||||
} else {
|
||||
// Staff can create, read, update but not delete other resources
|
||||
await createPermissions(staffRole.id, resource.id, ['create', 'read', 'update']);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Seeding completed!');
|
||||
}
|
||||
|
||||
async function createPermissions(roleId: string, resourceId: string, actions: string[]) {
|
||||
for (const action of actions) {
|
||||
await prisma.permissions.createMany({
|
||||
data: {
|
||||
action: action,
|
||||
resource_id: resourceId,
|
||||
role_id: roleId,
|
||||
},
|
||||
skipDuplicates: true // Skip if the permission already exists
|
||||
}).catch((error) => {
|
||||
console.error(`Error creating permission for role ${roleId} on resource ${resourceId}:`, error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
main()
|
||||
.then(async () => {
|
||||
await prisma.$disconnect();
|
||||
})
|
||||
.catch(async (e) => {
|
||||
console.error(e);
|
||||
await prisma.$disconnect();
|
||||
process.exit(1);
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
import { ICreatePermissionSchema } from "@/src/entities/models/permissions/create-permission.model";
|
||||
import { IPermissionsSchema } from "@/src/entities/models/permissions/permissions.model";
|
||||
import { IUpdatePermissionSchema } from "@/src/entities/models/permissions/update-permission.model";
|
||||
import { permissions } from "@prisma/client";
|
||||
|
||||
export interface IPermissionsRepository {
|
||||
create(data: ICreatePermissionSchema): Promise<IPermissionsSchema>;
|
||||
getById(id: string): Promise<IPermissionsSchema | null>;
|
||||
getByRoleAndResource(roleId: string, resourceId: string): Promise<IPermissionsSchema[]>;
|
||||
getByRole(role: string): Promise<IPermissionsSchema[]>;
|
||||
getAll(): Promise<IPermissionsSchema[]>;
|
||||
update(id: string, data: IUpdatePermissionSchema): Promise<IPermissionsSchema>;
|
||||
delete(id: string): Promise<IPermissionsSchema>;
|
||||
checkPermission(role: string, action: string, resource: string): Promise<boolean>;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { ICreateResourceSchema } from "@/src/entities/models/resources/create-resources.model";
|
||||
import { IResourcesSchema } from "@/src/entities/models/resources/resources.model";
|
||||
import { IUpdateResourceSchema } from "@/src/entities/models/resources/update-resources.model";
|
||||
import { resources } from "@prisma/client";
|
||||
|
||||
export interface IResourcesRepository {
|
||||
create(data: ICreateResourceSchema): Promise<IResourcesSchema>;
|
||||
getById(id: string): Promise<IResourcesSchema | null>;
|
||||
getByName(name: string): Promise<IResourcesSchema | null>;
|
||||
getByType(type: string): Promise<IResourcesSchema[] | null>;
|
||||
getAll(): Promise<IResourcesSchema[]>;
|
||||
update(id: string, data: IUpdateResourceSchema): Promise<IResourcesSchema>;
|
||||
delete(id: string): Promise<IResourcesSchema>;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { ICreateRoleSchema } from "@/src/entities/models/roles/create-roles.model";
|
||||
import { IRolesSchema } from "@/src/entities/models/roles/roles.model";
|
||||
import { IUpdateRoleSchema } from "@/src/entities/models/roles/update-roles.model";
|
||||
import { roles } from "@prisma/client";
|
||||
|
||||
export interface IRolesRepository {
|
||||
create(data: ICreateRoleSchema): Promise<IRolesSchema>;
|
||||
getById(id: string): Promise<IRolesSchema | null>;
|
||||
getByName(name: string): Promise<IRolesSchema | null>;
|
||||
getAll(): Promise<IRolesSchema[]>;
|
||||
update(id: string, data: IUpdateRoleSchema): Promise<IRolesSchema>;
|
||||
delete(id: string): Promise<IRolesSchema>;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { createAdminClient } from "@/app/_utils/supabase/admin";
|
||||
import { createClient } from "@/app/_utils/supabase/client";
|
||||
import { IUserSchema, UserResponse } from "@/src/entities/models/users/users.model";
|
||||
import { IUserSchema, IUserSupabaseSchema, UserResponse } from "@/src/entities/models/users/users.model";
|
||||
import { ITransaction } from "@/src/entities/models/transaction.interface";
|
||||
import { ICreateUserSchema } from "@/src/entities/models/users/create-user.model";
|
||||
import { ICredentialUpdateUserSchema, IUpdateUserSchema } from "@/src/entities/models/users/update-user.model";
|
||||
|
@ -16,8 +16,8 @@ export interface IUsersRepository {
|
|||
getUserById(credential: ICredentialGetUserByIdSchema): Promise<IUserSchema | undefined>;
|
||||
getUserByUsername(credential: ICredentialGetUserByUsernameSchema): Promise<IUserSchema | undefined>;
|
||||
getUserByEmail(credential: ICredentialGetUserByEmailSchema): Promise<IUserSchema | undefined>;
|
||||
createUser(input: ICreateUserSchema, tx?: ITransaction): Promise<IUserSchema>;
|
||||
inviteUser(credential: ICredentialsInviteUserSchema, tx?: ITransaction): Promise<IUserSchema>;
|
||||
createUser(input: ICreateUserSchema, tx?: ITransaction): Promise<IUserSupabaseSchema>;
|
||||
inviteUser(credential: ICredentialsInviteUserSchema, tx?: ITransaction): Promise<IUserSupabaseSchema>;
|
||||
updateUser(credential: ICredentialUpdateUserSchema, input: Partial<IUpdateUserSchema>, tx?: ITransaction): Promise<IUserSchema>;
|
||||
deleteUser(credential: ICredentialsDeleteUserSchema, tx?: ITransaction): Promise<IUserSchema>;
|
||||
banUser(credential: ICredentialsBanUserSchema, input: IBanUserSchema, tx?: ITransaction): Promise<IUserSchema>;
|
||||
|
|
|
@ -17,4 +17,5 @@ export interface IAuthenticationService {
|
|||
sendMagicLink(credentials: ISendMagicLinkSchema): Promise<void>
|
||||
sendPasswordRecovery(credentials: ISendPasswordRecoverySchema): Promise<void>
|
||||
verifyOtp(credentials: IVerifyOtpSchema): Promise<void>
|
||||
checkPermission(userId: string, action: string, resource: string): Promise<boolean>;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
import { IAuthenticationService } from "../../services/authentication.service.interface";
|
||||
import { IUsersRepository } from "../../repositories/users.repository.interface";
|
||||
|
||||
export type ICheckPermissionsUseCase = ReturnType<typeof checkPermissionsUseCase>;
|
||||
|
||||
export const checkPermissionsUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
authenticationService: IAuthenticationService,
|
||||
) => async (userId: string, action: string, resource: string): Promise<boolean> => {
|
||||
return await instrumentationService.startSpan({ name: "Check Permission Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const permission = await authenticationService.checkPermission(userId, action, resource);
|
||||
|
||||
if (!permission) {
|
||||
throw new NotFoundError("Permission not found");
|
||||
}
|
||||
|
||||
return permission;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
import { ICreatePermissionSchema } from "@/src/entities/models/permissions/create-permission.model"
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface"
|
||||
import { IPermissionsRepository } from "../../repositories/permissions.repository.interface"
|
||||
import { permissions } from "@prisma/client"
|
||||
import { AlreadyExistsError } from "@/src/entities/errors/common"
|
||||
import { IPermissionsSchema } from "@/src/entities/models/permissions/permissions.model"
|
||||
|
||||
export type ICreatePermissionUseCase = ReturnType<typeof createPermissionUseCase>
|
||||
|
||||
export const createPermissionUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
permissionsRepository: IPermissionsRepository,
|
||||
) => async (input: ICreatePermissionSchema): Promise<IPermissionsSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Create Permission Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const existingPermission = await permissionsRepository.getByRoleAndResource(input.role_id, input.resource_id)
|
||||
|
||||
if (existingPermission) {
|
||||
throw new AlreadyExistsError("Permission already exists")
|
||||
}
|
||||
|
||||
const permission = await permissionsRepository.create(input)
|
||||
|
||||
return permission
|
||||
}
|
||||
)
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import { IPermissionsSchema } from "@/src/entities/models/permissions/permissions.model";
|
||||
import { IPermissionsRepository } from "../../repositories/permissions.repository.interface";
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
import { IDeletePermissionsSchema } from "@/src/entities/models/permissions/delete-permissions.model";
|
||||
|
||||
export type IDeletePermissionUseCase = ReturnType<typeof deletePermissionUseCase>;
|
||||
|
||||
export const deletePermissionUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
permissionsRepository: IPermissionsRepository,
|
||||
) => async (input: IDeletePermissionsSchema): Promise<IPermissionsSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Delete Permissions Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const permissions = await permissionsRepository.getById(input.id);
|
||||
|
||||
if (!permissions) {
|
||||
throw new NotFoundError("Permissions not found");
|
||||
}
|
||||
|
||||
const deletedPermissions = await permissionsRepository.delete(input.id);
|
||||
|
||||
return deletedPermissions;
|
||||
}
|
||||
);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import { IPermissionsSchema } from "@/src/entities/models/permissions/permissions.model";
|
||||
import { IPermissionsRepository } from "../../repositories/permissions.repository.interface";
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
|
||||
|
||||
export type IGetAllPermissionsUseCase = ReturnType<typeof getAllPermissionsUseCase>;
|
||||
|
||||
export const getAllPermissionsUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
permissionsRepository: IPermissionsRepository,
|
||||
) => async (): Promise<IPermissionsSchema[]> => {
|
||||
return await instrumentationService.startSpan({ name: "Get All Permissions Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const permissions = await permissionsRepository.getAll()
|
||||
|
||||
return permissions
|
||||
}
|
||||
)
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { IPermissionsSchema } from "@/src/entities/models/permissions/permissions.model";
|
||||
import { IPermissionsRepository } from "../../repositories/permissions.repository.interface";
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
export type IGetPermissionByIdUseCase = ReturnType<typeof getPermissionByIdUseCase>;
|
||||
|
||||
export const getPermissionByIdUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
permissionsRepository: IPermissionsRepository,
|
||||
) => async (id: string): Promise<IPermissionsSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Get Permissions By Id Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const permissions = await permissionsRepository.getById(id)
|
||||
|
||||
if (!permissions) {
|
||||
throw new NotFoundError("Permissions not found")
|
||||
}
|
||||
|
||||
return permissions
|
||||
}
|
||||
)
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { IPermissionsSchema } from "@/src/entities/models/permissions/permissions.model";
|
||||
import { IPermissionsRepository } from "../../repositories/permissions.repository.interface";
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
export type IGetPermissionByRoleAndResourcesUseCase = ReturnType<typeof getPermissionByRoleAndResourcesUseCase>;
|
||||
|
||||
export const getPermissionByRoleAndResourcesUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
permissionsRepository: IPermissionsRepository,
|
||||
) => async (roleId: string, resourceId: string): Promise<IPermissionsSchema[]> => {
|
||||
return await instrumentationService.startSpan({ name: "Get Permissions By Role And Resources Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const permissions = await permissionsRepository.getByRoleAndResource(roleId, resourceId)
|
||||
|
||||
if (!permissions) {
|
||||
throw new NotFoundError("Permissions not found")
|
||||
}
|
||||
|
||||
return permissions
|
||||
}
|
||||
)
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
import { IPermissionsSchema } from "@/src/entities/models/permissions/permissions.model";
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IPermissionsRepository } from "../../repositories/permissions.repository.interface";
|
||||
|
||||
export type IGetPermissionByRoleUseCase = ReturnType<typeof getPermissionByRoleUseCase>;
|
||||
|
||||
export const getPermissionByRoleUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
permissionsRepository: IPermissionsRepository,
|
||||
) => async (roleId: string): Promise<IPermissionsSchema[]> => {
|
||||
return await instrumentationService.startSpan({ name: "Get Permissions By Role Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const permissions = await permissionsRepository.getByRole(roleId)
|
||||
|
||||
if (!permissions) {
|
||||
throw new NotFoundError("Permissions not found")
|
||||
}
|
||||
|
||||
return permissions
|
||||
}
|
||||
)
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import { IUpdatePermissionSchema } from "@/src/entities/models/permissions/update-permission.model";
|
||||
import { IPermissionsRepository } from "../../repositories/permissions.repository.interface";
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IPermissionsSchema } from "@/src/entities/models/permissions/permissions.model";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
|
||||
export type IUpdatePermissionUseCase = ReturnType<typeof updatePermissionUseCase>;
|
||||
|
||||
export const updatePermissionUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
permissionsRepository: IPermissionsRepository,
|
||||
) => async (id: string, input: IUpdatePermissionSchema): Promise<IPermissionsSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Update Permission Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const permission = await permissionsRepository.getById(id)
|
||||
|
||||
if (!permission) {
|
||||
throw new NotFoundError("Permission not found")
|
||||
}
|
||||
|
||||
const updatedPermission = await permissionsRepository.update(id, input)
|
||||
|
||||
return updatedPermission
|
||||
}
|
||||
)
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import { ICreateResourceSchema } from "@/src/entities/models/resources/create-resources.model";
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IResourcesRepository } from "../../repositories/resources.repository.interface";
|
||||
import { IResourcesSchema } from "@/src/entities/models/resources/resources.model";
|
||||
import { AlreadyExistsError } from "@/src/entities/errors/common";
|
||||
|
||||
export type ICreateResourceUseCase = ReturnType<typeof createResourceUseCase>;
|
||||
|
||||
export const createResourceUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
resourcesRepository: IResourcesRepository,
|
||||
) => async (input: ICreateResourceSchema): Promise<IResourcesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Create Resource Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const existingResource = await resourcesRepository.getByName(input.name);
|
||||
|
||||
if (existingResource) {
|
||||
throw new AlreadyExistsError("Resource already exists");
|
||||
}
|
||||
|
||||
const resource = await resourcesRepository.create(input);
|
||||
|
||||
return resource;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IResourcesRepository } from "../../repositories/resources.repository.interface";
|
||||
import { IResourcesSchema } from "@/src/entities/models/resources/resources.model";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
export type IDeleteResourceUseCase = ReturnType<typeof deleteResourceUseCase>;
|
||||
|
||||
export const deleteResourceUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
resourcesRepository: IResourcesRepository,
|
||||
) => async (id: string): Promise<IResourcesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Delete Resource Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const existingResource = await resourcesRepository.getById(id);
|
||||
|
||||
if (!existingResource) {
|
||||
throw new NotFoundError("Resource not found");
|
||||
}
|
||||
|
||||
const deletedResource = await resourcesRepository.delete(id);
|
||||
|
||||
return deletedResource;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IResourcesRepository } from "../../repositories/resources.repository.interface";
|
||||
import { IResourcesSchema } from "@/src/entities/models/resources/resources.model";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
export type IGetResourceByIdUseCase = ReturnType<typeof getResourceByIdUseCase>;
|
||||
|
||||
export const getResourceByIdUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
resourcesRepository: IResourcesRepository,
|
||||
) => async (id: string): Promise<IResourcesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Get Resource By ID Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const resource = await resourcesRepository.getById(id);
|
||||
|
||||
if (!resource) {
|
||||
throw new NotFoundError("Resource not found");
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IResourcesRepository } from "../../repositories/resources.repository.interface";
|
||||
import { IResourcesSchema } from "@/src/entities/models/resources/resources.model";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
export type IGetResourceByNameUseCase = ReturnType<typeof getResourceByNameUseCase>;
|
||||
|
||||
export const getResourceByNameUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
resourcesRepository: IResourcesRepository,
|
||||
) => async (name: string): Promise<IResourcesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Get Resource By Name Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const resource = await resourcesRepository.getByName(name);
|
||||
|
||||
if (!resource) {
|
||||
throw new NotFoundError("Resource not found");
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IResourcesRepository } from "../../repositories/resources.repository.interface";
|
||||
import { IResourcesSchema } from "@/src/entities/models/resources/resources.model";
|
||||
|
||||
export type IGetResourcesByTypeUseCase = ReturnType<typeof getResourcesByTypeUseCase>;
|
||||
|
||||
export const getResourcesByTypeUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
resourcesRepository: IResourcesRepository,
|
||||
) => async (type: string): Promise<IResourcesSchema[]> => {
|
||||
return await instrumentationService.startSpan({ name: "Get Resources By Type Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const resources = await resourcesRepository.getByType(type);
|
||||
|
||||
return resources || [];
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
import { IUpdateResourceSchema } from "@/src/entities/models/resources/update-resources.model";
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IResourcesRepository } from "../../repositories/resources.repository.interface";
|
||||
import { IResourcesSchema } from "@/src/entities/models/resources/resources.model";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
export type IUpdateResourceUseCase = ReturnType<typeof updateResourceUseCase>;
|
||||
|
||||
export const updateResourceUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
resourcesRepository: IResourcesRepository,
|
||||
) => async (id: string, data: IUpdateResourceSchema): Promise<IResourcesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Update Resource Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const existingResource = await resourcesRepository.getById(id);
|
||||
|
||||
if (!existingResource) {
|
||||
throw new NotFoundError("Resource not found");
|
||||
}
|
||||
|
||||
const updatedResource = await resourcesRepository.update(id, data);
|
||||
|
||||
return updatedResource;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IRolesRepository } from "../../repositories/roles.repository.interface";
|
||||
import { IRolesSchema } from "@/src/entities/models/roles/roles.model";
|
||||
import { AlreadyExistsError } from "@/src/entities/errors/common";
|
||||
import { ICreateRoleSchema } from "@/src/entities/models/roles/create-roles.model";
|
||||
|
||||
export type ICreateRoleUseCase = ReturnType<typeof createRoleUseCase>;
|
||||
|
||||
export const createRoleUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
rolesRepository: IRolesRepository,
|
||||
) => async (input: ICreateRoleSchema): Promise<IRolesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Create Role Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const existingRole = await rolesRepository.getByName(input.name);
|
||||
|
||||
if (existingRole) {
|
||||
throw new AlreadyExistsError("Role already exists");
|
||||
}
|
||||
|
||||
const role = await rolesRepository.create(input);
|
||||
|
||||
return role;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IRolesRepository } from "../../repositories/roles.repository.interface";
|
||||
import { IRolesSchema } from "@/src/entities/models/roles/roles.model";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
export type IDeleteRoleUseCase = ReturnType<typeof deleteRoleUseCase>;
|
||||
|
||||
export const deleteRoleUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
rolesRepository: IRolesRepository,
|
||||
) => async (id: string): Promise<IRolesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Delete Role Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const existingRole = await rolesRepository.getById(id);
|
||||
|
||||
if (!existingRole) {
|
||||
throw new NotFoundError("Role not found");
|
||||
}
|
||||
|
||||
const deletedRole = await rolesRepository.delete(id);
|
||||
|
||||
return deletedRole;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IRolesRepository } from "../../repositories/roles.repository.interface";
|
||||
import { IRolesSchema } from "@/src/entities/models/roles/roles.model";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
export type IGetRoleByIdUseCase = ReturnType<typeof getRoleByIdUseCase>;
|
||||
|
||||
export const getRoleByIdUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
rolesRepository: IRolesRepository,
|
||||
) => async (id: string): Promise<IRolesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Get Role By ID Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const role = await rolesRepository.getById(id);
|
||||
|
||||
if (!role) {
|
||||
throw new NotFoundError("Role not found");
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IRolesRepository } from "../../repositories/roles.repository.interface";
|
||||
import { IRolesSchema } from "@/src/entities/models/roles/roles.model";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
|
||||
export type IGetRoleByNameUseCase = ReturnType<typeof getRoleByNameUseCase>;
|
||||
|
||||
export const getRoleByNameUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
rolesRepository: IRolesRepository,
|
||||
) => async (name: string): Promise<IRolesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Get Role By Name Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const role = await rolesRepository.getByName(name);
|
||||
|
||||
if (!role) {
|
||||
throw new NotFoundError("Role not found");
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
import { IInstrumentationService } from "../../services/instrumentation.service.interface";
|
||||
import { IRolesRepository } from "../../repositories/roles.repository.interface";
|
||||
import { IRolesSchema } from "@/src/entities/models/roles/roles.model";
|
||||
import { NotFoundError } from "@/src/entities/errors/common";
|
||||
import { IUpdateRoleSchema } from "@/src/entities/models/roles/update-roles.model";
|
||||
|
||||
export type IUpdateRoleUseCase = ReturnType<typeof updateRoleUseCase>;
|
||||
|
||||
export const updateRoleUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
rolesRepository: IRolesRepository,
|
||||
) => async (id: string, data: IUpdateRoleSchema): Promise<IRolesSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "Update Role Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
const existingRole = await rolesRepository.getById(id);
|
||||
|
||||
if (!existingRole) {
|
||||
throw new NotFoundError("Role not found");
|
||||
}
|
||||
|
||||
const updatedRole = await rolesRepository.update(id, data);
|
||||
|
||||
return updatedRole;
|
||||
}
|
||||
);
|
||||
};
|
|
@ -2,7 +2,7 @@ import { AuthenticationError } from "@/src/entities/errors/auth"
|
|||
import { IUsersRepository } from "../../repositories/users.repository.interface"
|
||||
import { IAuthenticationService } from "../../services/authentication.service.interface"
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface"
|
||||
import { IUserSchema } from "@/src/entities/models/users/users.model"
|
||||
import { IUserSchema, IUserSupabaseSchema } from "@/src/entities/models/users/users.model"
|
||||
import { InputParseError } from "@/src/entities/errors/common"
|
||||
import { ICreateUserSchema } from "@/src/entities/models/users/create-user.model"
|
||||
|
||||
|
@ -12,7 +12,7 @@ export type ICreateUserUseCase = ReturnType<typeof createUserUseCase>
|
|||
export const createUserUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
usersRepository: IUsersRepository,
|
||||
) => async (input: ICreateUserSchema): Promise<IUserSchema> => {
|
||||
) => async (input: ICreateUserSchema): Promise<IUserSupabaseSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "createUser Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AuthenticationError } from "@/src/entities/errors/auth"
|
|||
import { IUsersRepository } from "../../repositories/users.repository.interface"
|
||||
import { IAuthenticationService } from "../../services/authentication.service.interface"
|
||||
import { IInstrumentationService } from "../../services/instrumentation.service.interface"
|
||||
import { IUserSchema } from "@/src/entities/models/users/users.model"
|
||||
import { IUserSchema, IUserSupabaseSchema } from "@/src/entities/models/users/users.model"
|
||||
import { ICredentialsInviteUserSchema } from "@/src/entities/models/users/invite-user.model"
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@ export type IInviteUserUseCase = ReturnType<typeof inviteUserUseCase>
|
|||
export const inviteUserUseCase = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
usersRepository: IUsersRepository,
|
||||
) => async (credential: ICredentialsInviteUserSchema): Promise<IUserSchema> => {
|
||||
) => async (credential: ICredentialsInviteUserSchema): Promise<IUserSupabaseSchema> => {
|
||||
return await instrumentationService.startSpan({ name: "inviteUser Use Case", op: "function" },
|
||||
async () => {
|
||||
|
||||
|
|
|
@ -18,6 +18,12 @@ export class InputParseError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
export class AlreadyExistsError extends Error {
|
||||
constructor(message: string, options?: ErrorOptions) {
|
||||
super(message, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class ServerActionError extends Error {
|
||||
code: string;
|
||||
|
|
|
@ -5,7 +5,7 @@ export const SessionSchema = z.object({
|
|||
user: UserSchema.pick({
|
||||
id: true,
|
||||
email: true,
|
||||
role: true,
|
||||
roles_id: true,
|
||||
}),
|
||||
expiresAt: z.number().optional(),
|
||||
});
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export interface CreatePermissionDto {
|
||||
action: string;
|
||||
resource_id: string;
|
||||
role_id: string;
|
||||
}
|
||||
|
||||
export const CreatePermissionSchema = z.object({
|
||||
action: z.string().min(1, { message: "Action is required" }),
|
||||
resource_id: z.string().min(1, { message: "Resource ID is required" }),
|
||||
role_id: z.string().min(1, { message: "Role ID is required" }),
|
||||
})
|
||||
|
||||
export type ICreatePermissionSchema = z.infer<typeof CreatePermissionSchema>;
|
||||
|
||||
export const defaultICreatePermissionSchemaValues: ICreatePermissionSchema = {
|
||||
action: "",
|
||||
resource_id: "",
|
||||
role_id: "",
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export const DeletePermissionsSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
})
|
||||
|
||||
export type IDeletePermissionsSchema = z.infer<typeof DeletePermissionsSchema>
|
||||
|
||||
export const defaultIDeletePermissionsSchemaValues: IDeletePermissionsSchema = {
|
||||
id: "",
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import { z } from "zod";
|
||||
|
||||
type permissions = {
|
||||
id: string;
|
||||
action: string;
|
||||
role_id: string;
|
||||
resource_id: string;
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
export const PermissionsSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
action: z.string().min(1).max(255),
|
||||
role_id: z.string().uuid(),
|
||||
resource_id: z.string().uuid(),
|
||||
created_at: z.date(),
|
||||
updated_at: z.date()
|
||||
})
|
||||
|
||||
export type IPermissionsSchema = z.infer<typeof PermissionsSchema>;
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export const UpdatePermissionSchema = z.object({
|
||||
action: z.string().min(1, { message: "Action is required" }),
|
||||
resource_id: z.string().min(1, { message: "Resource ID is required" }),
|
||||
role_id: z.string().min(1, { message: "Role ID is required" }),
|
||||
})
|
||||
|
||||
export type IUpdatePermissionSchema = z.infer<typeof UpdatePermissionSchema>;
|
||||
|
||||
export const defaultIUpdatePermissionSchemaValues: IUpdatePermissionSchema = {
|
||||
action: "",
|
||||
resource_id: "",
|
||||
role_id: "",
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export interface CreateResourceDto {
|
||||
name: string;
|
||||
type?: string;
|
||||
description?: string;
|
||||
instance_role?: string;
|
||||
relations?: string;
|
||||
attributes?: Record<string, any>;
|
||||
}
|
||||
|
||||
export const CreateResourceSchema = z.object({
|
||||
name: z.string().min(1, { message: "Name is required" }),
|
||||
type: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
instance_role: z.string().optional(),
|
||||
relations: z.string().optional(),
|
||||
attributes: z.record(z.any()).optional(),
|
||||
})
|
||||
|
||||
export type ICreateResourceSchema = z.infer<typeof CreateResourceSchema>;
|
||||
|
||||
export const defaultICreateResourceSchemaValues: ICreateResourceSchema = {
|
||||
name: "",
|
||||
type: undefined,
|
||||
description: undefined,
|
||||
instance_role: undefined,
|
||||
relations: undefined,
|
||||
attributes: {},
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import { JsonValue } from "@prisma/client/runtime/library";
|
||||
import { z } from "zod";
|
||||
|
||||
type resources = {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string | null;
|
||||
description: string | null;
|
||||
instance_role: string | null;
|
||||
relations: string | null;
|
||||
attributes: JsonValue | null;
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
export const ResourcesSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
name: z.string().min(1).max(255),
|
||||
type: z.string().nullable(),
|
||||
description: z.string().nullable(),
|
||||
instance_role: z.string().nullable(),
|
||||
relations: z.string().nullable(),
|
||||
attributes: z.any().nullable(),
|
||||
created_at: z.date(),
|
||||
updated_at: z.date(),
|
||||
})
|
||||
|
||||
export type IResourcesSchema = z.infer<typeof ResourcesSchema>;
|
|
@ -0,0 +1,30 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export interface UpdateResourceDto {
|
||||
name?: string;
|
||||
type?: string;
|
||||
description?: string;
|
||||
instance_role?: string;
|
||||
relations?: string;
|
||||
attributes?: Record<string, any>;
|
||||
}
|
||||
|
||||
export const UpdateResourceSchema = z.object({
|
||||
name: z.string().optional(),
|
||||
type: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
instance_role: z.string().optional(),
|
||||
relations: z.string().optional(),
|
||||
attributes: z.record(z.any()).optional(),
|
||||
})
|
||||
|
||||
export type IUpdateResourceSchema = z.infer<typeof UpdateResourceSchema>;
|
||||
|
||||
export const defaultIUpdateResourceSchemaValues: IUpdateResourceSchema = {
|
||||
name: undefined,
|
||||
type: undefined,
|
||||
description: undefined,
|
||||
instance_role: undefined,
|
||||
relations: undefined,
|
||||
attributes: {},
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export interface CreateRoleDto {
|
||||
name: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export const CreateRoleSchema = z.object({
|
||||
name: z.string().min(1, { message: "Name is required" }),
|
||||
description: z.string().optional(),
|
||||
})
|
||||
|
||||
export type ICreateRoleSchema = z.infer<typeof CreateRoleSchema>;
|
||||
|
||||
export const defaultICreateRoleSchemaValues: ICreateRoleSchema = {
|
||||
name: "",
|
||||
description: undefined,
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export const RoleSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
description: z.string().nullable().optional(),
|
||||
created_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
updated_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
})
|
||||
|
||||
export type IRolesSchema = z.infer<typeof RoleSchema>;
|
|
@ -0,0 +1,18 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export interface UpdateRoleDto {
|
||||
name?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export const UpdateRoleSchema = z.object({
|
||||
name: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
})
|
||||
|
||||
export type IUpdateRoleSchema = z.infer<typeof UpdateRoleSchema>;
|
||||
|
||||
export const defaultIUpdateRoleSchemaValues: IUpdateRoleSchema = {
|
||||
name: undefined,
|
||||
description: undefined,
|
||||
}
|
|
@ -4,7 +4,7 @@ export const UpdateUserSchema = z.object({
|
|||
email: z.string().email().optional(),
|
||||
email_confirmed_at: z.boolean().optional(),
|
||||
encrypted_password: z.string().optional(),
|
||||
role: z.enum(["user", "staff", "admin"]).optional(),
|
||||
roles_id: z.string().optional(), // Sesuai dengan model di Prisma
|
||||
phone: z.string().optional(),
|
||||
phone_confirmed_at: z.boolean().optional(),
|
||||
invited_at: z.union([z.string(), z.date()]).optional(),
|
||||
|
@ -34,7 +34,7 @@ export const defaultValueUpdateUserSchema: IUpdateUserSchema = {
|
|||
email: undefined,
|
||||
email_confirmed_at: undefined,
|
||||
encrypted_password: undefined,
|
||||
role: "user",
|
||||
roles_id: undefined,
|
||||
phone: undefined,
|
||||
phone_confirmed_at: undefined,
|
||||
invited_at: undefined,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { z } from "zod";
|
||||
|
||||
import { AuthError } from "@supabase/supabase-js";
|
||||
import { RoleSchema } from "../roles/roles.model";
|
||||
|
||||
const timestampSchema = z.union([z.string(), z.date()]).nullable();
|
||||
|
||||
|
@ -37,7 +38,7 @@ const timestampSchema = z.union([z.string(), z.date()]).nullable();
|
|||
|
||||
export const UserSchema = z.object({
|
||||
id: z.string(),
|
||||
role: z.string().optional(),
|
||||
roles_id: z.string().optional(), // Sesuaikan dengan field di Prisma
|
||||
email: z.string().email().optional(),
|
||||
email_confirmed_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
encrypted_password: z.string().nullable().optional(),
|
||||
|
@ -64,10 +65,39 @@ export const UserSchema = z.object({
|
|||
})
|
||||
.nullable()
|
||||
.optional(),
|
||||
role: RoleSchema.optional(),
|
||||
});
|
||||
|
||||
export type IUserSchema = z.infer<typeof UserSchema>;
|
||||
|
||||
export const UserSupabaseSchema = z.object({
|
||||
id: z.string(),
|
||||
app_metadata: z.any().optional(),
|
||||
user_metadata: z.any().optional(),
|
||||
aud: z.string(),
|
||||
confirmation_sent_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
recovery_sent_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
email_change_sent_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
new_email: z.string().nullable().optional(),
|
||||
new_phone: z.string().nullable().optional(),
|
||||
invited_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
action_link: z.string().nullable().optional(),
|
||||
email: z.string().email().nullable().optional(),
|
||||
phone: z.string().nullable().optional(),
|
||||
created_at: z.union([z.string(), z.date()]),
|
||||
confirmed_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
email_confirmed_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
phone_confirmed_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
last_sign_in_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
role: z.string().nullable().optional(),
|
||||
updated_at: z.union([z.string(), z.date()]).nullable().optional(),
|
||||
identities: z.array(z.any()).nullable().optional(),
|
||||
is_anonymous: z.boolean().optional(),
|
||||
factors: z.array(z.any()).nullable().optional(),
|
||||
})
|
||||
|
||||
export type IUserSupabaseSchema = z.infer<typeof UserSupabaseSchema>;
|
||||
|
||||
export const ProfileSchema = z.object({
|
||||
id: z.string(),
|
||||
user_id: z.string(),
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
import db from '@/prisma/db';
|
||||
import { IPermissionsRepository } from '@/src/application/repositories/permissions.repository.interface';
|
||||
import { ICrashReporterService } from '@/src/application/services/crash-reporter.service.interface';
|
||||
import { IInstrumentationService } from '@/src/application/services/instrumentation.service.interface';
|
||||
import { ICreatePermissionSchema } from '@/src/entities/models/permissions/create-permission.model';
|
||||
import { IPermissionsSchema } from '@/src/entities/models/permissions/permissions.model';
|
||||
import { IUpdatePermissionSchema } from '@/src/entities/models/permissions/update-permission.model';
|
||||
import { PrismaClient, permissions } from '@prisma/client';
|
||||
|
||||
export class PermissionsRepository implements IPermissionsRepository {
|
||||
constructor(
|
||||
private readonly instrumentationService: IInstrumentationService,
|
||||
private readonly crashReporterService: ICrashReporterService,
|
||||
) { }
|
||||
|
||||
async create(data: ICreatePermissionSchema): Promise<IPermissionsSchema> {
|
||||
return db.permissions.create({
|
||||
data: {
|
||||
action: data.action,
|
||||
resource_id: data.resource_id,
|
||||
role_id: data.role_id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getById(id: string): Promise<permissions | null> {
|
||||
return db.permissions.findUnique({
|
||||
where: { id }
|
||||
});
|
||||
}
|
||||
|
||||
async getByRoleAndResource(roleId: string, resourceId: string): Promise<IPermissionsSchema[]> {
|
||||
return db.permissions.findMany({
|
||||
where: {
|
||||
role_id: roleId,
|
||||
resource_id: resourceId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getByRole(roleId: string): Promise<IPermissionsSchema[]> {
|
||||
return db.permissions.findMany({
|
||||
where: {
|
||||
role_id: roleId
|
||||
},
|
||||
include: {
|
||||
resource: true
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getAll(): Promise<IPermissionsSchema[]> {
|
||||
return db.permissions.findMany();
|
||||
}
|
||||
|
||||
async update(id: string, data: IUpdatePermissionSchema): Promise<IPermissionsSchema> {
|
||||
return db.permissions.update({
|
||||
where: { id },
|
||||
data: {
|
||||
action: data.action
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<IPermissionsSchema> {
|
||||
return db.permissions.delete({
|
||||
where: { id }
|
||||
});
|
||||
}
|
||||
|
||||
async checkPermission(role: string, action: string, resource: string): Promise<boolean> {
|
||||
const result = await db.permissions.findFirst({
|
||||
where: {
|
||||
role: {
|
||||
name: role
|
||||
},
|
||||
action: action,
|
||||
resource: {
|
||||
name: resource
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return !!result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
import db from "@/prisma/db";
|
||||
import { IResourcesRepository } from "@/src/application/repositories/resources.repository.interface";
|
||||
import { ICrashReporterService } from "@/src/application/services/crash-reporter.service.interface";
|
||||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { ICreateResourceSchema } from "@/src/entities/models/resources/create-resources.model";
|
||||
import { IResourcesSchema } from "@/src/entities/models/resources/resources.model";
|
||||
import { resources } from "@prisma/client";
|
||||
|
||||
export class ResourcesRepository implements IResourcesRepository {
|
||||
constructor(
|
||||
private readonly instrumentationService: IInstrumentationService,
|
||||
private readonly crashReporterService: ICrashReporterService,
|
||||
) { }
|
||||
|
||||
async getById(id: string): Promise<IResourcesSchema | null> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Find Resource By ID", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.resources.findUnique({
|
||||
where: { id }
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async getByName(name: string): Promise<IResourcesSchema | null> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Find Resource By Name", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.resources.findUnique({
|
||||
where: { name }
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async getByType(type: string): Promise<IResourcesSchema[] | null> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Find Resources By Type", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.resources.findMany({
|
||||
where: { type }
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async getAll(): Promise<IResourcesSchema[]> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Find All Resources", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.resources.findMany();
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async create(data: ICreateResourceSchema): Promise<IResourcesSchema> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Create Resource", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.resources.create({
|
||||
data: {
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
type: data.type,
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async update(id: string, data: ICreateResourceSchema): Promise<IResourcesSchema> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Update Resource", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.resources.update({
|
||||
where: { id },
|
||||
data: {
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
type: data.type,
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<IResourcesSchema> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Delete Resource", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.resources.delete({
|
||||
where: { id }
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
import db from "@/prisma/db";
|
||||
import { IRolesRepository } from "@/src/application/repositories/roles.repository.interface";
|
||||
import { ICrashReporterService } from "@/src/application/services/crash-reporter.service.interface";
|
||||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { ICreateRoleSchema } from "@/src/entities/models/roles/create-roles.model";
|
||||
import { IRolesSchema } from "@/src/entities/models/roles/roles.model";
|
||||
import { roles } from "@prisma/client";
|
||||
|
||||
export class RolesRepository implements IRolesRepository {
|
||||
constructor(
|
||||
private readonly instrumentationService: IInstrumentationService,
|
||||
private readonly crashReporterService: ICrashReporterService,
|
||||
) { }
|
||||
|
||||
async getById(id: string): Promise<IRolesSchema | null> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Find Role By ID", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.roles.findUnique({
|
||||
where: { id }
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async getByName(name: string): Promise<IRolesSchema | null> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Find Role By Name", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.roles.findUnique({
|
||||
where: { name }
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async getAll(): Promise<IRolesSchema[]> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Find All Roles", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.roles.findMany();
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async create(data: ICreateRoleSchema): Promise<IRolesSchema> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Create Role", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.roles.create({
|
||||
data: {
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async update(id: string, data: ICreateRoleSchema): Promise<IRolesSchema> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Update Role", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.roles.update({
|
||||
where: { id },
|
||||
data: {
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<IRolesSchema> {
|
||||
return this.instrumentationService.startSpan(
|
||||
{ name: "Delete Role", op: "function", attributes: {} },
|
||||
async () => {
|
||||
try {
|
||||
return await db.roles.delete({
|
||||
where: { id }
|
||||
});
|
||||
} catch (error) {
|
||||
this.crashReporterService.report(error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ import { ICrashReporterService } from "@/src/application/services/crash-reporter
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { createAdminClient } from "@/app/_utils/supabase/admin";
|
||||
import { createClient as createServerClient } from "@/app/_utils/supabase/server";
|
||||
import { IUserSchema } from "@/src/entities/models/users/users.model";
|
||||
import { IUserSchema, IUserSupabaseSchema } from "@/src/entities/models/users/users.model";
|
||||
import { ITransaction } from "@/src/entities/models/transaction.interface";
|
||||
import db from "@/prisma/db";
|
||||
import { DatabaseOperationError, NotFoundError } from "@/src/entities/errors/common";
|
||||
|
@ -15,6 +15,7 @@ import { ICredentialsDeleteUserSchema } from "@/src/entities/models/users/delete
|
|||
import { IBanUserSchema, ICredentialsBanUserSchema } from "@/src/entities/models/users/ban-user.model";
|
||||
import { ICredentialsUnbanUserSchema } from "@/src/entities/models/users/unban-user.model";
|
||||
import { ICreateUserSchema } from "@/src/entities/models/users/create-user.model";
|
||||
import { User } from "@supabase/supabase-js";
|
||||
|
||||
export class UsersRepository implements IUsersRepository {
|
||||
constructor(
|
||||
|
@ -33,6 +34,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
const query = db.users.findMany({
|
||||
include: {
|
||||
profile: true,
|
||||
role: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -69,6 +71,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
},
|
||||
include: {
|
||||
profile: true,
|
||||
role: true,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -88,7 +91,6 @@ export class UsersRepository implements IUsersRepository {
|
|||
|
||||
return {
|
||||
...user,
|
||||
id: credential.id,
|
||||
};
|
||||
} catch (err) {
|
||||
this.crashReporterService.report(err);
|
||||
|
@ -110,6 +112,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
},
|
||||
include: {
|
||||
profile: true,
|
||||
role: true,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -149,6 +152,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
},
|
||||
include: {
|
||||
profile: true,
|
||||
role: true,
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -207,6 +211,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
},
|
||||
include: {
|
||||
profile: true,
|
||||
role: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -215,11 +220,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
}
|
||||
|
||||
return {
|
||||
...user,
|
||||
profile: {
|
||||
user_id: userDetail.id,
|
||||
...userDetail.profile,
|
||||
},
|
||||
...userDetail
|
||||
};
|
||||
} catch (err) {
|
||||
this.crashReporterService.report(err);
|
||||
|
@ -228,7 +229,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
})
|
||||
}
|
||||
|
||||
async createUser(input: ICreateUserSchema, tx?: ITransaction): Promise<IUserSchema> {
|
||||
async createUser(input: ICreateUserSchema, tx?: ITransaction): Promise<IUserSupabaseSchema> {
|
||||
return await this.instrumentationService.startSpan({
|
||||
name: "UsersRepository > createUser",
|
||||
}, async () => {
|
||||
|
@ -241,10 +242,11 @@ export class UsersRepository implements IUsersRepository {
|
|||
const query = supabase.auth.admin.createUser({
|
||||
email: input.email,
|
||||
password: input.password,
|
||||
email_confirm: true,
|
||||
email_confirm: input.email_confirm ?? true,
|
||||
phone: input.phone,
|
||||
})
|
||||
|
||||
const { data: { user } } = await this.instrumentationService.startSpan({
|
||||
const { data: { user }, error } = await this.instrumentationService.startSpan({
|
||||
name: "UsersRepository > createUser > supabase.auth.admin.createUser",
|
||||
op: "db:query",
|
||||
attributes: { "system": "supabase.auth" },
|
||||
|
@ -254,7 +256,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
}
|
||||
)
|
||||
|
||||
if (!user) {
|
||||
if (error || !user) {
|
||||
throw new DatabaseOperationError("Failed to create user");
|
||||
}
|
||||
|
||||
|
@ -267,7 +269,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
})
|
||||
}
|
||||
|
||||
async inviteUser(credential: ICredentialsInviteUserSchema, tx?: ITransaction): Promise<IUserSchema> {
|
||||
async inviteUser(credential: ICredentialsInviteUserSchema, tx?: ITransaction): Promise<IUserSupabaseSchema> {
|
||||
return await this.instrumentationService.startSpan({
|
||||
name: "UsersRepository > inviteUser",
|
||||
}, async () => {
|
||||
|
@ -335,6 +337,7 @@ export class UsersRepository implements IUsersRepository {
|
|||
id: credential.id,
|
||||
},
|
||||
include: {
|
||||
role: true,
|
||||
profile: true,
|
||||
},
|
||||
})
|
||||
|
@ -357,8 +360,12 @@ export class UsersRepository implements IUsersRepository {
|
|||
where: {
|
||||
id: credential.id,
|
||||
},
|
||||
include: {
|
||||
profile: true,
|
||||
role: true,
|
||||
},
|
||||
data: {
|
||||
role: input.role || user.role,
|
||||
roles_id: input.roles_id || user.roles_id,
|
||||
invited_at: input.invited_at || user.invited_at,
|
||||
confirmed_at: input.confirmed_at || user.confirmed_at,
|
||||
last_sign_in_at: input.last_sign_in_at || user.last_sign_in_at,
|
||||
|
@ -377,9 +384,6 @@ export class UsersRepository implements IUsersRepository {
|
|||
},
|
||||
},
|
||||
},
|
||||
include: {
|
||||
profile: true,
|
||||
},
|
||||
})
|
||||
|
||||
const updatedUser = await this.instrumentationService.startSpan({
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { createAdminClient } from "@/app/_utils/supabase/admin";
|
||||
import { createClient } from "@/app/_utils/supabase/server";
|
||||
import db from "@/prisma/db";
|
||||
import { IPermissionsRepository } from "@/src/application/repositories/permissions.repository.interface";
|
||||
import { IUsersRepository } from "@/src/application/repositories/users.repository.interface";
|
||||
import { IAuthenticationService } from "@/src/application/services/authentication.service.interface";
|
||||
import { ICrashReporterService } from "@/src/application/services/crash-reporter.service.interface";
|
||||
|
@ -19,6 +20,7 @@ export class AuthenticationService implements IAuthenticationService {
|
|||
private readonly usersRepository: IUsersRepository,
|
||||
private readonly instrumentationService: IInstrumentationService,
|
||||
private readonly crashReporterService: ICrashReporterService,
|
||||
private readonly permissionRepository: IPermissionsRepository,
|
||||
private readonly supabaseAdmin = createAdminClient(),
|
||||
private readonly supabaseServer = createClient()
|
||||
) { }
|
||||
|
@ -274,4 +276,30 @@ export class AuthenticationService implements IAuthenticationService {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
async checkPermission(userId: string, action: string, resource: string): Promise<boolean> {
|
||||
return await this.instrumentationService.startSpan({
|
||||
name: "checkPermission Use Case",
|
||||
}, async () => {
|
||||
try {
|
||||
|
||||
const user = await db.users.findUnique({
|
||||
where: { id: userId },
|
||||
include: { role: true }
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const role = user.role.name;
|
||||
|
||||
return await this.permissionRepository.checkPermission(role, action, resource);
|
||||
|
||||
} catch (err) {
|
||||
this.crashReporterService.report(err)
|
||||
throw err
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { ICheckPermissionsUseCase } from "@/src/application/use-cases/auth/check-permissions.use-case";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
import { z } from "zod";
|
||||
|
||||
|
||||
const checkPermissionInputSchema = z.object({
|
||||
userId: z.string().uuid("Please enter a valid user ID"),
|
||||
action: z.string().nonempty("Please enter an action"),
|
||||
resource: z.string().nonempty("Please enter a resource"),
|
||||
})
|
||||
|
||||
export type ICheckPermissionsController = ReturnType<typeof checkPermissionsController>
|
||||
|
||||
export const checkPermissionsController =
|
||||
(
|
||||
instrumentationService: IInstrumentationService,
|
||||
checkPermissionUseCase: ICheckPermissionsUseCase
|
||||
) =>
|
||||
async (input: Partial<z.infer<typeof checkPermissionInputSchema>>) => {
|
||||
return await instrumentationService.startSpan({ name: "checkPermission Controller" },
|
||||
async () => {
|
||||
const { data, error: inputParseError } = checkPermissionInputSchema.safeParse(input)
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError })
|
||||
}
|
||||
|
||||
return await checkPermissionUseCase(
|
||||
data.userId,
|
||||
data.action,
|
||||
data.resource
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { ICreatePermissionUseCase } from "@/src/application/use-cases/permissions/create-permissions.use-case";
|
||||
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
import { CreatePermissionSchema } from "@/src/entities/models/permissions/create-permission.model";
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
action: z.string().min(1, { message: "Action is required" }),
|
||||
resource_id: z.string().min(1, { message: "Resource ID is required" }),
|
||||
role_id: z.string().min(1, { message: "Role ID is required" }),
|
||||
})
|
||||
|
||||
export type ICreatePermissionController = ReturnType<typeof createPermissionController>;
|
||||
|
||||
export const createPermissionController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
createPermissionUseCase: ICreatePermissionUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (input: Partial<z.infer<typeof inputSchema>>) => {
|
||||
return await instrumentationService.startSpan({ name: "Create Permission Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to create a permission");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError('Invalid data', { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await createPermissionUseCase(data);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IDeletePermissionUseCase } from "@/src/application/use-cases/permissions/delete-permissions.use-case";
|
||||
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
|
||||
export type IDeletePermissionController = ReturnType<typeof deletePermissionController>;
|
||||
|
||||
export const deletePermissionController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
deletePermissionUseCase: IDeletePermissionUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (id: string) => {
|
||||
return await instrumentationService.startSpan({ name: "Delete Permission Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to delete a permission");
|
||||
}
|
||||
|
||||
return await deletePermissionUseCase({ id });
|
||||
});
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IGetAllPermissionsUseCase } from "@/src/application/use-cases/permissions/get-all-permissions";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
|
||||
|
||||
export type IGetAllPermissionsController = ReturnType<typeof getAllPermissionsController>;
|
||||
|
||||
export const getAllPermissionsController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
getAllPermissionsUseCase: IGetAllPermissionsUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async () => {
|
||||
return await instrumentationService.startSpan({ name: "getAllPermissions Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to fetch permissions");
|
||||
}
|
||||
|
||||
return await getAllPermissionsUseCase();
|
||||
});
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IGetPermissionByIdUseCase } from "@/src/application/use-cases/permissions/get-permissions-by-id.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
id: z.string().min(1, { message: "Permission ID is required" }),
|
||||
});
|
||||
|
||||
export type IGetPermissionByIdController = ReturnType<typeof getPermissionByIdController>;
|
||||
|
||||
export const getPermissionByIdController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
getPermissionByIdUseCase: IGetPermissionByIdUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (input: z.infer<typeof inputSchema>) => {
|
||||
return await instrumentationService.startSpan({ name: "Get Permission By Id Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to view a permission");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await getPermissionByIdUseCase(data.id);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IGetPermissionByRoleAndResourcesUseCase } from "@/src/application/use-cases/permissions/get-permissions-by-role-and-resources.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
roleId: z.string(),
|
||||
resourceId: z.string(),
|
||||
})
|
||||
|
||||
export type IGetPermissionByRoleAndResourceController = ReturnType<typeof getPermissionByRoleAndResourceController>;
|
||||
|
||||
export const getPermissionByRoleAndResourceController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
getPermissionByRoleAndResourceUseCase: IGetPermissionByRoleAndResourcesUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (input: z.infer<typeof inputSchema>) => {
|
||||
return await instrumentationService.startSpan({ name: "Get Permissions Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to view permissions");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await getPermissionByRoleAndResourceUseCase(data.roleId, data.resourceId);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IGetPermissionByRoleUseCase } from "@/src/application/use-cases/permissions/get-permissions-by-role.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
|
||||
|
||||
export type IGetPermissionByRoleController = ReturnType<typeof getPermissionByRoleController>;
|
||||
|
||||
export const getPermissionByRoleController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
getPermissionByRoleUseCase: IGetPermissionByRoleUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (roleId: string) => {
|
||||
return await instrumentationService.startSpan({ name: "Get Permission By Role Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to fetch permissions");
|
||||
}
|
||||
|
||||
return await getPermissionByRoleUseCase(roleId);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,37 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IUpdatePermissionUseCase } from "@/src/application/use-cases/permissions/update-permissions.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
import { UpdatePermissionSchema } from "@/src/entities/models/permissions/update-permission.model";
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
action: z.string().min(1, { message: "Action is required" }),
|
||||
resource_id: z.string().min(1, { message: "Resource ID is required" }),
|
||||
role_id: z.string().min(1, { message: "Role ID is required" }),
|
||||
});
|
||||
|
||||
export type IUpdatePermissionController = ReturnType<typeof updatePermissionController>;
|
||||
|
||||
export const updatePermissionController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
updatePermissionUseCase: IUpdatePermissionUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (id: string, input: Partial<z.infer<typeof inputSchema>>) => {
|
||||
return await instrumentationService.startSpan({ name: "Update Permission Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to update a permission");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await updatePermissionUseCase(id, data);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { ICreateResourceUseCase } from "@/src/application/use-cases/resources/create-resources.use-case";
|
||||
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
name: z.string().min(1, { message: "Resource name is required" }),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export type ICreateResourceController = ReturnType<typeof createResourceController>;
|
||||
|
||||
export const createResourceController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
createResourceUseCase: ICreateResourceUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (input: Partial<z.infer<typeof inputSchema>>) => {
|
||||
return await instrumentationService.startSpan({ name: "createResource Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to create a resource");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await createResourceUseCase(data);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IDeleteResourceUseCase } from "@/src/application/use-cases/resources/delete-resource.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
|
||||
export type IDeleteResourceController = ReturnType<typeof deleteResourceController>;
|
||||
|
||||
export const deleteResourceController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
deleteResourceUseCase: IDeleteResourceUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (id: string) => {
|
||||
return await instrumentationService.startSpan({ name: "deleteResource Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to delete a resource");
|
||||
}
|
||||
|
||||
return await deleteResourceUseCase(id);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IGetResourceByIdUseCase } from "@/src/application/use-cases/resources/get-resource-by-id.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
id: z.string().min(1, { message: "Resource ID is required" }),
|
||||
});
|
||||
|
||||
export type IGetResourceByIdController = ReturnType<typeof getResourceByIdController>;
|
||||
|
||||
export const getResourceByIdController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
getResourceById: IGetResourceByIdUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (input: z.infer<typeof inputSchema>) => {
|
||||
return await instrumentationService.startSpan({ name: "getResourceById Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to fetch a resource");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await getResourceById(data.id);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IGetResourcesByTypeUseCase } from "@/src/application/use-cases/resources/get-resources-by-type.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
type: z.string().nonempty("Type is required"),
|
||||
})
|
||||
|
||||
export type IGetResourcesByTypeController = ReturnType<typeof getResourcesByTypeController>;
|
||||
|
||||
export const getResourcesByTypeController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
getResourcesByTypeUseCase: IGetResourcesByTypeUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (input: z.infer<typeof inputSchema>) => {
|
||||
return await instrumentationService.startSpan({ name: "getResourcesByType Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to fetch resources");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new Error("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await getResourcesByTypeUseCase(data.type);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IUpdateResourceUseCase } from "@/src/application/use-cases/resources/update-resource.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
name: z.string().min(1, { message: "Resource name is required" }),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export type IUpdateResourceController = ReturnType<typeof updateResourceController>;
|
||||
|
||||
export const updateResourceController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
updateResourceUseCase: IUpdateResourceUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (id: string, input: Partial<z.infer<typeof inputSchema>>) => {
|
||||
return await instrumentationService.startSpan({ name: "updateResource Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to update a resource");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await updateResourceUseCase(id, data);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { ICreateRoleUseCase } from "@/src/application/use-cases/roles/create-role.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
name: z.string().min(1, { message: "Role name is required" }),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export type ICreateRoleController = ReturnType<typeof createRoleController>;
|
||||
|
||||
export const createRoleController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
createRoleUseCase: ICreateRoleUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (input: Partial<z.infer<typeof inputSchema>>) => {
|
||||
return await instrumentationService.startSpan({ name: "createRole Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to create a role");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await createRoleUseCase(data);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IDeleteRoleUseCase } from "@/src/application/use-cases/roles/delete-role.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
|
||||
export type IDeleteRoleController = ReturnType<typeof deleteRoleController>;
|
||||
|
||||
export const deleteRoleController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
deleteRoleUseCase: IDeleteRoleUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (id: string) => {
|
||||
return await instrumentationService.startSpan({ name: "deleteRole Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to delete a role");
|
||||
}
|
||||
|
||||
return await deleteRoleUseCase(id);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IGetRoleByIdUseCase } from "@/src/application/use-cases/roles/get-role-by-id.use-case";
|
||||
|
||||
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
id: z.string()
|
||||
})
|
||||
|
||||
export type IGetRoleByIdController = ReturnType<typeof getRoleByIdController>;
|
||||
|
||||
export const getRoleByIdController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
getRoleById: IGetRoleByIdUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (input: Partial<z.infer<typeof inputSchema>>) => {
|
||||
return await instrumentationService.startSpan({ name: "getRole Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to fetch a role");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await getRoleById(data.id);
|
||||
});
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
import { IInstrumentationService } from "@/src/application/services/instrumentation.service.interface";
|
||||
import { IUpdateRoleUseCase } from "@/src/application/use-cases/roles/update-role.use-case";
|
||||
import { IGetCurrentUserUseCase } from "@/src/application/use-cases/users/get-current-user.use-case";
|
||||
import { UnauthenticatedError } from "@/src/entities/errors/auth";
|
||||
import { InputParseError } from "@/src/entities/errors/common";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
const inputSchema = z.object({
|
||||
name: z.string().min(1, { message: "Role name is required" }),
|
||||
description: z.string().optional(),
|
||||
});
|
||||
|
||||
export type IUpdateRoleController = ReturnType<typeof updateRoleController>;
|
||||
|
||||
export const updateRoleController = (
|
||||
instrumentationService: IInstrumentationService,
|
||||
updateRoleUseCase: IUpdateRoleUseCase,
|
||||
getCurrentUserUseCase: IGetCurrentUserUseCase
|
||||
) => async (id: string, input: Partial<z.infer<typeof inputSchema>>) => {
|
||||
return await instrumentationService.startSpan({ name: "updateRole Controller" }, async () => {
|
||||
const session = await getCurrentUserUseCase();
|
||||
|
||||
if (!session) {
|
||||
throw new UnauthenticatedError("Must be logged in to update a role");
|
||||
}
|
||||
|
||||
const { data, error: inputParseError } = inputSchema.safeParse(input);
|
||||
|
||||
if (inputParseError) {
|
||||
throw new InputParseError("Invalid data", { cause: inputParseError });
|
||||
}
|
||||
|
||||
return await updateRoleUseCase(id, data);
|
||||
});
|
||||
};
|
Loading…
Reference in New Issue