diff --git a/apps/backend/src/modules/organizations/organizations.service.ts b/apps/backend/src/modules/organizations/organizations.service.ts index f9209b94..fed950a6 100644 --- a/apps/backend/src/modules/organizations/organizations.service.ts +++ b/apps/backend/src/modules/organizations/organizations.service.ts @@ -1,3 +1,4 @@ +import { taskEither as TE } from 'fp-ts'; import { pipe } from 'fp-ts/function'; import { inject, injectable } from 'tsyringe'; @@ -7,8 +8,6 @@ import type { SdkUpdateOrganizationInputT, } from '@llm/sdk'; -import { tapTaskEitherTE } from '@llm/commons'; - import type { WithAuthFirewall } from '../auth'; import type { TableRowWithId } from '../database'; @@ -29,12 +28,12 @@ export class OrganizationsService implements WithAuthFirewall pipe( this.repo.create({ value }), - tapTaskEitherTE(({ id }) => this.esIndexRepo.findAndIndexDocumentById(id)), + TE.tap(({ id }) => this.esIndexRepo.findAndIndexDocumentById(id)), ); update = ({ id, ...value }: SdkUpdateOrganizationInputT & TableRowWithId) => pipe( this.repo.update({ id, value }), - tapTaskEitherTE(() => this.esIndexRepo.findAndIndexDocumentById(id)), + TE.tap(() => this.esIndexRepo.findAndIndexDocumentById(id)), ); asUser = (jwt: SdkJwtTokenT) => new OrganizationsFirewall(jwt, this); diff --git a/apps/backend/src/modules/users/users.boot.ts b/apps/backend/src/modules/users/users.boot.ts index 46916723..d345f1f9 100644 --- a/apps/backend/src/modules/users/users.boot.ts +++ b/apps/backend/src/modules/users/users.boot.ts @@ -38,7 +38,7 @@ export class UsersBootService { }, }); }), - TE.bindW('result', ({ dto }) => this.usersService.createIfNotExists(dto)), + TE.bindW('result', ({ dto }) => this.usersService.createIfNotExists({ value: dto })), tapTaskEither(({ dto, result }) => { if (result.created) { this.logger.info('Created root user!', { diff --git a/apps/backend/src/modules/users/users.repo.ts b/apps/backend/src/modules/users/users.repo.ts index d9f9c2b7..15a25ed3 100644 --- a/apps/backend/src/modules/users/users.repo.ts +++ b/apps/backend/src/modules/users/users.repo.ts @@ -53,7 +53,7 @@ export class UsersRepo extends createProtectedDatabaseRepo('users') { TE.map(() => refreshToken), ); - create = ({ forwardTransaction, ...user }: TransactionalAttrs) => { + create = ({ forwardTransaction, value }: TransactionalAttrs<{ value: SdkCreateUserInputT; }>) => { const transaction = tryReuseOrCreateTransaction({ db: this.db, forwardTransaction, @@ -63,42 +63,52 @@ export class UsersRepo extends createProtectedDatabaseRepo('users') { this.baseRepo.create({ forwardTransaction: trx, value: { - email: user.email, - active: user.active, - role: user.role, + email: value.email, + active: value.active, + role: value.role, }, }), TE.tap(({ id }) => pipe( this.authRepo.upsertUserAuthMethods({ forwardTransaction: trx, user: { id }, - email: user.auth.email, - password: user.auth.password, + email: value.auth.email, + password: value.auth.password, }), )), )); }; - createIfNotExists = ({ forwardTransaction, ...user }: TransactionalAttrs) => pipe( - this.baseRepo.findOne({ + createIfNotExists = ({ forwardTransaction, value }: TransactionalAttrs<{ value: SdkCreateUserInputT; }>) => { + const transaction = tryReuseOrCreateTransaction({ + db: this.db, forwardTransaction, - select: ['id'], - where: [ - ['email', '=', user.email], - ], - }), - TE.map(result => ({ - ...result, - created: false, - })), - catchTaskEitherTagError('DatabaseRecordNotExists')(() => pipe( - this.create(user), + }); + + return transaction(trx => pipe( + this.baseRepo.findOne({ + forwardTransaction: trx, + select: ['id'], + where: [ + ['email', '=', value.email], + ], + }), TE.map(result => ({ ...result, - created: true, + created: false, })), - )), - ); + catchTaskEitherTagError('DatabaseRecordNotExists')(() => pipe( + this.create({ + value, + forwardTransaction: trx, + }), + TE.map(result => ({ + ...result, + created: true, + })), + )), + )); + }; findWithRelationsByIds = ({ forwardTransaction, ids }: TransactionalAttrs<{ ids: TableId[]; }>) => { const transaction = tryReuseTransactionOrSkip({ db: this.db, forwardTransaction }); diff --git a/apps/backend/src/modules/users/users.service.ts b/apps/backend/src/modules/users/users.service.ts index 0b10e714..f6bcae68 100644 --- a/apps/backend/src/modules/users/users.service.ts +++ b/apps/backend/src/modules/users/users.service.ts @@ -1,14 +1,23 @@ +import { taskEither as TE } from 'fp-ts'; +import { flow } from 'fp-ts/function'; import { inject, injectable } from 'tsyringe'; +import { UsersEsIndexRepo } from './elasticsearch/users-es-index.repo'; import { UsersRepo } from './users.repo'; @injectable() export class UsersService { constructor( @inject(UsersRepo) private readonly usersRepo: UsersRepo, + @inject(UsersEsIndexRepo) private readonly usersEsIndexRepo: UsersEsIndexRepo, ) {} - create = this.usersRepo.create; - - createIfNotExists = this.usersRepo.createIfNotExists; + createIfNotExists = flow( + this.usersRepo.createIfNotExists, + TE.tap(({ id, created }) => + created + ? this.usersEsIndexRepo.findAndIndexDocumentById(id) + : TE.right(undefined), + ), + ); }