Skip to content
This repository has been archived by the owner on Jun 30, 2021. It is now read-only.

Commit

Permalink
feat(server): add members mutation & query
Browse files Browse the repository at this point in the history
  • Loading branch information
MichelineMedhat committed Feb 6, 2021
1 parent e0a12d0 commit 58b3396
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-- CreateEnum
CREATE TYPE "Role" AS ENUM ('OWNER', 'MANAGER', 'WAITER');

-- CreateTable
CREATE TABLE "Tenant" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"domain_name" TEXT NOT NULL,
"hotline" TEXT NOT NULL,

PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "TenantUser" (
"role" "Role" NOT NULL DEFAULT E'OWNER',
"userId" INTEGER NOT NULL,
"tenantId" INTEGER NOT NULL,

PRIMARY KEY ("userId","tenantId")
);

-- CreateIndex
CREATE UNIQUE INDEX "Tenant.domain_name_unique" ON "Tenant"("domain_name");

-- AddForeignKey
ALTER TABLE "TenantUser" ADD FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "TenantUser" ADD FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
37 changes: 31 additions & 6 deletions packages/server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,37 @@ generator typegraphql {
}

model User {
id Int @id @default(autoincrement())
name String
phone String @unique
email String @unique
id Int @id @default(autoincrement())
name String
phone String @unique
email String @unique
TenantUser TenantUser[]
/// @TypeGraphQL.omit(output: true)
password String
password String
/// @TypeGraphQL.omit(output: true)
createdAt DateTime @default(now())
createdAt DateTime @default(now())
}

model Tenant {
id Int @id @default(autoincrement())
name String
domain_name String @unique
hotline String
TenantUser TenantUser[]
}

model TenantUser {
role Role @default(OWNER)
User User @relation(fields: [userId], references: [id])
userId Int
Tenant Tenant @relation(fields: [tenantId], references: [id])
tenantId Int
@@id([userId, tenantId])
}

enum Role {
OWNER
MANAGER
WAITER
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ObjectType } from "type-graphql";
import { IError } from "../../common/errors/IError";

@ObjectType({ implements: IError })
export class NonExistingMemberError implements IError {
message: string = "member doesn't exist";
}
13 changes: 13 additions & 0 deletions packages/server/src/graphql/member/inputs/MemberInput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Field, InputType, Int } from "type-graphql";
import { IsNotEmpty } from "class-validator";

@InputType()
export class MemberInput {
@IsNotEmpty({ message: "required field" })
@Field()
userId: number;

@IsNotEmpty({ message: "required field" })
@Field()
tenantId: number;
}
62 changes: 62 additions & 0 deletions packages/server/src/graphql/member/resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Arg, Ctx, Mutation, Query, Resolver } from "type-graphql";
import { Context } from "../../context";
import { MemberInput } from "./inputs/memberInput";
import { UpdateMemberResult } from "./results/UpdateMemberResult";
import { DeleteMemberResult } from "./results/DeleteMemberResult";
import { validate } from "class-validator";
import { FieldsValidationError } from "../common/errors/FieldsValidationError";
import { NonExistingMemberError } from "./errors/NonExistingMemberError";
import { TenantUser } from "../../generated/typegraphql-prisma/models/TenantUser";
import { Role } from "../../generated/typegraphql-prisma/enums/Role";

@Resolver()
class MemberResolver {
@Query(() => [TenantUser], { nullable: true })
async getMembers(@Ctx() ctx: Context): Promise<TenantUser[] | null> {
return await ctx.prisma.tenantUser.findMany({
include: {
User: true,
Tenant: true,
},
});
}

@Mutation(() => DeleteMemberResult)
async deleteMember(
@Arg("input", () => MemberInput) input: MemberInput,
@Ctx() ctx: Context
): Promise<typeof DeleteMemberResult> {
const errors = await validate(input);
if (errors.length > 0) return FieldsValidationError.from(errors);

await ctx.prisma.tenantUser.delete({
where: {
userId_tenantId: input,
},
});
}

@Mutation(() => UpdateMemberResult)
async updateMember(
@Arg("input") input: MemberInput,
@Arg("role", () => Role) role: Role,
@Ctx() ctx: Context
): Promise<typeof UpdateMemberResult> {
const errors = await validate(input);
if (errors.length > 0) return FieldsValidationError.from(errors);

try {
const updateMember = await ctx.prisma.tenantUser.update({
where: {
userId_tenantId: input,
},
data: {
role: role,
},
});
return Object.assign(new TenantUser(), updateMember);
} catch (err) {
return new NonExistingMemberError();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { createUnionType } from "type-graphql";
import { FieldsValidationError } from "../../common/errors/FieldsValidationError";

export const DeleteMemberResult = createUnionType({
name: "DeleteMemberResult",
types: () => [FieldsValidationError] as const,
});
10 changes: 10 additions & 0 deletions packages/server/src/graphql/member/results/UpdateMemberResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createUnionType } from "type-graphql";
import { TenantUser } from "../../../generated/typegraphql-prisma/models/TenantUser";
import { FieldsValidationError } from "../../common/errors/FieldsValidationError";
import { NonExistingMemberError } from "../errors/NonExistingMemberError";

export const UpdateMemberResult = createUnionType({
name: "UpdateMemberResult",
types: () =>
[TenantUser, FieldsValidationError, NonExistingMemberError] as const,
});

0 comments on commit 58b3396

Please sign in to comment.