for a use-case that allows an actor to perform an account creation.
As such I have created these methods on User
async createUser({ email, username, password }: Pick<UserObject, 'password' | 'email' | 'username'>) {
return await this.#dbAccessor.createNewUser({ email, username, password });
}
//and...
checkEmailExists(email: string): boolean;
checkUsernameExists(username: string): boolean;
On the Use-Case Layer, after the hurdles of checking with utilities such as pwhashing and validation, I make use check conditions with checkEmailExists and checkUsernameExists, then if passes, I'll finally run createUser.
However, my question is, what if those email/username checks is already stale by time it begins to insert? To prevent that, would I have to migrate these check logic into the db query ? And if that's so, wouldn't it mean my logic is leaking out of Application logic/Enterprise logic layers into these adapters?
is a method such as 'checkAndInsertNewUser' more suitable in this scenario, and implement so in the database layer?
It is generally not recommended to "merge" business logic with the database layer. What if you want to or need to replace the whole database layer in some point of time? What about testing business logic (decision making) independent from database? Even if your business logic involves querying the database the actual decision making (what to check and how) should be separate from database. What might be useful or even necessary in your case are transactions to make the query of the DB and the creation/insertion of a new item atomic.