106 lines
4.5 KiB
TypeScript

import * as repository from "@apihub24/repository";
import { Inject, Injectable } from "@nestjs/common";
import { IAccount } from "../contracts/models/account";
import { IGroup } from "../contracts/models/group";
@Injectable()
export class AccountService {
constructor(
@Inject("@apihub24/account_repository")
private readonly accountRepository: repository.IRepository<IAccount>,
@Inject("@apihub24/group_repository")
private readonly groupRepository: repository.IRepository<IGroup>
) {}
/**
* This asynchronous method retrieves accounts that match a given filter.
* @param filter A function that takes an `IAccount` object and returns a boolean. It serves as the condition for selecting accounts.
* @returns A Promise that resolves to an array of `IAccount` objects that satisfy the filter condition.
*/
async getBy(filter: (account: IAccount) => boolean): Promise<IAccount[]> {
return await this.accountRepository.getBy(filter);
}
/**
* This asynchronous method saves a single `IAccount` object. It uses the `accountRepository` to persist the account. If the save operation fails, it logs a warning and returns null.
* @param account The `IAccount` object to be saved.
* @returns A Promise that resolves to the saved `IAccount` object, or `null` if the save operation fails.
*/
async save(account: IAccount): Promise<IAccount | null> {
try {
const accounts = await this.accountRepository.save([account]);
return accounts?.length ? accounts[0] : null;
} catch (err) {
console.warn(err);
return null;
}
}
/**
* This asynchronous method deletes accounts based on a provided filter.
* @param filter A function that takes an `IAccount` object and returns a boolean. It specifies which accounts to delete.
* @returns A Promise that resolves to `true` if the deletion is successful, and `false` otherwise.
*/
async delete(filter: (account: IAccount) => boolean): Promise<boolean> {
return await this.accountRepository.deleteBy(filter);
}
/**
* This asynchronous method adds a specific account to a group. It first finds both the account and the group using their IDs. If they are found, it adds the group to the account's groups array and saves the updated account.
* @param accountId The unique identifier of the account.
* @param groupId The unique identifier of the group to which the account should be added.
* @returns A Promise that resolves to the updated `IAccount` object.
* @throws An error if the account or the group cannot be found, or if the updated account cannot be saved.
*/
async addAccountToGroup(
accountId: string,
groupId: string
): Promise<IAccount> {
const [account, group] = await this.getAccountAndGroup(accountId, groupId);
account.groups = account.groups.filter((x) => x.id !== groupId);
account.groups.push(group);
const accountsSaved = await this.accountRepository.save([account]);
if (!accountsSaved.length) {
throw new Error(`account ${account.accountName} can not be saved`);
}
return accountsSaved[0];
}
/**
* This asynchronous method removes a specific account from a group. It first finds the account and group, then filters the group out of the account's groups array before saving the updated account.
* @param accountId The unique identifier of the account.
* @param groupId The unique identifier of the group to be removed.
* @returns A Promise that resolves to the updated `IAccount` object.
* @throws An error if the account or the group cannot be found, or if the updated account cannot be saved.
*/
async removeAccountFromGroup(
accountId: string,
groupId: string
): Promise<IAccount> {
const [account] = await this.getAccountAndGroup(accountId, groupId);
account.groups = account.groups.filter((x) => x.id !== groupId);
const accountsSaved = await this.accountRepository.save([account]);
if (!accountsSaved.length) {
throw new Error(`account ${account.accountName} can not be saved`);
}
return accountsSaved[0];
}
private async getAccountAndGroup(
accountId: string,
groupId: string
): Promise<[IAccount, IGroup]> {
const accounts = await this.accountRepository.getBy(
(x) => x.id === accountId
);
if (!accounts.length) {
throw new Error(`account with id ${accountId} not found`);
}
const groups = await this.groupRepository.getBy((x) => x.id === groupId);
if (!groups.length) {
throw new Error(`group with id ${groupId} not found`);
}
return [accounts[0], groups[0]];
}
}