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

const getUserOrganizations: ServiceMethodFactory<
  UsersServiceDeps,
  [string, undefined | boolean],
  Promise<Organization[]>
> = ({ request }) => {
  return async (userId, personalOnly = false) => {
    const userOrgs = await request.prisma.organization.findMany({
      where: {
        AND: [
          personalOnly === true && {
            kind: OrganizationKind.PERSONAL,
          },
          {
            OR: [
              {
                ownerId: userId,
              },
              {
                memberships: {
                  some: {
                    userId,
                  },
                },
              },
            ],
          },
        ].filter(
          (
            x
          ): x is
            | { kind: "PERSONAL"; OR?: undefined }
            | {
                OR: (
                  | { ownerId: string; memberships?: undefined }
                  | {
                      memberships: { some: { userId: string } };
                      ownerId?: undefined;
                    }
                )[];
                kind?: undefined;
              } => x != null && x !== false
        ),
      },
      orderBy: {
        kind: "asc", // private first then company
      },
    });

    return userOrgs;
  };
};

export default getUserOrganizations;