.ts
TypeScript
(application/typescript)
// 1st-party
import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
// generated via script[generate:prisma]
import {
  OrganizationKind,
  OrganizationRole,
  ResourceVisibility,
  User,
} from "@prisma/client";
// app
import type { AuthServiceCreateUserDTO, AuthServiceDeps } from "./types";

const makeCreateUser: ServiceMethodFactory<
  AuthServiceDeps,
  [AuthServiceCreateUserDTO],
  Promise<User>
> = ({ cryptoService, request }) => {
  // create a user with a personal organization
  return async ({ emailAddress, username, password }) => {
    const user = await request.prisma.user.create({
      data: {
        email: emailAddress,
        username: username,
        hashedPassword: cryptoService.computeHash(password),
      },
    });

    try {
      await request.prisma.organization.create({
        data: {
          kind: OrganizationKind.PERSONAL,
          slug: username,
          visibility: ResourceVisibility.PRIVATE,
          owner: {
            connect: {
              id: user.id,
            },
          },
          memberships: {
            create: {
              role: OrganizationRole.OWNER,
              user: {
                connect: {
                  id: user.id,
                },
              },
            },
          },
        },
      });
    } catch (err) {
      const error = err as Error;
      console.error(
        `Could not create User's personal's Organization. Error: ${error.message}`
      );
      return user;
    }

    return user;
  };
};

export default makeCreateUser;