diff --git a/app/models/enum.ts b/app/models/enum.ts index 3379a37..2ad5a98 100644 --- a/app/models/enum.ts +++ b/app/models/enum.ts @@ -3,3 +3,13 @@ export const ROLES = { AUTHOR: 'AUTHOR', MEMBER: 'MEMBER', } + +export const SUBSCRIPTION_STATUS = { + INACTIVE: 'INACTIVE', + ACTIVE: 'ACTIVE', +} + +export const TRANSACTION_STATUS = { + SUBMITTED: 'SUBMITTED', + VERIFIED: 'VERIFIED', +} diff --git a/prisma/migrations/20211225043237_add_transaction_table/migration.sql b/prisma/migrations/20211225043237_add_transaction_table/migration.sql new file mode 100644 index 0000000..ed42acb --- /dev/null +++ b/prisma/migrations/20211225043237_add_transaction_table/migration.sql @@ -0,0 +1,15 @@ +-- CreateTable +CREATE TABLE "Transaction" ( + "id" TEXT NOT NULL PRIMARY KEY, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + "userId" TEXT NOT NULL, + "subscriptionId" TEXT NOT NULL, + "bankName" TEXT NOT NULL, + "bankAccountNumber" TEXT NOT NULL, + "bankAccountName" TEXT NOT NULL, + "amount" INTEGER NOT NULL, + "status" TEXT NOT NULL, + CONSTRAINT "Transaction_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "Transaction_subscriptionId_fkey" FOREIGN KEY ("subscriptionId") REFERENCES "Subscription" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 72cb7de..be684a8 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -19,17 +19,19 @@ model User { role String courses Course[] subscriptions Subscription[] + Transaction Transaction[] } model Subscription { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - userId String - courseId String - status String - course Course @relation(fields: [courseId], references: [id], onDelete: Cascade) - user User @relation(fields: [userId], references: [id], onDelete: Cascade) + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + userId String + courseId String + status String + course Course @relation(fields: [courseId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + Transaction Transaction[] } model Course { @@ -45,3 +47,18 @@ model Course { author User @relation(fields: [authorId], references: [id], onDelete: Cascade) subscriptions Subscription[] } + +model Transaction { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + userId String + subscriptionId String + bankName String + bankAccountNumber String + bankAccountName String + amount Int + status String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade) +} diff --git a/prisma/seed.ts b/prisma/seed.ts index 49727f7..63cb118 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -1,16 +1,102 @@ import { PrismaClient } from '@prisma/client' -import { ROLES } from '../app/models/enum' +import { + ROLES, + SUBSCRIPTION_STATUS, + TRANSACTION_STATUS, +} from '../app/models/enum' const prisma = new PrismaClient() async function main() { - await Promise.all( - getUsers().map((user) => - prisma.user.create({ - data: user, + // update or insert user with admin role + await prisma.user.upsert({ + where: { email: 'me@zain.dev' }, + update: {}, + create: { + email: 'me@zainf.dev', + name: 'Zain', + phoneNumber: '+6512345678', + role: ROLES.ADMIN, + }, + }) + + // update or insert user with author role + const author = await prisma.user.upsert({ + where: { email: 'vika@rbagi.id' }, + update: {}, + create: { + email: 'vika@rbagi.id', + name: 'Vika', + role: ROLES.AUTHOR, + }, + }) + + // update or insert user with member role + const member = await prisma.user.upsert({ + where: { email: 'pk@zainf.dev' }, + update: {}, + create: { + email: 'pk@zainf.dev', + name: 'Pejuang Kode', + role: ROLES.MEMBER, + }, + }) + + // create courses + const courses = await Promise.all( + getCourse().map((course) => + prisma.course.create({ + data: { + authorId: author.id, + ...course, + }, }) ) ) + + // create subscription + const subscription1 = await prisma.subscription.create({ + data: { + userId: member.id, + courseId: courses[0].id, + status: SUBSCRIPTION_STATUS.ACTIVE, + }, + }) + + // create subscription + const subscription2 = await prisma.subscription.create({ + data: { + userId: member.id, + courseId: courses[1].id, + status: SUBSCRIPTION_STATUS.ACTIVE, + }, + }) + + // create transaction with status SUBMITTED + await prisma.transaction.create({ + data: { + userId: member.id, + subscriptionId: subscription1.id, + bankName: 'Bank Mandiri', + bankAccountName: 'Pejuang Kode', + bankAccountNumber: '123456789', + amount: 25000, + status: TRANSACTION_STATUS.SUBMITTED, + }, + }) + + // create transaction with status VERIFIED + await prisma.transaction.create({ + data: { + userId: member.id, + subscriptionId: subscription2.id, + bankName: 'Bank Mandiri', + bankAccountName: 'Pejuang Kode', + bankAccountNumber: '123456789', + amount: 50000, + status: TRANSACTION_STATUS.VERIFIED, + }, + }) } main() @@ -22,23 +108,31 @@ main() await prisma.$disconnect() }) -function getUsers() { +function getCourse() { return [ { - email: 'me@zainf.dev', - name: 'Zain', - phoneNumber: '+6512345678', - role: ROLES.ADMIN, + name: 'Menumbuhkan Minat Baca Anak', + description: + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.", + price: 25000, + image: 'https://picsum.photos/id/1073/1200/800', + category: 'Parenting', }, { - email: 'vika@rbagi.id', - name: 'Vika', - role: ROLES.AUTHOR, + name: 'Mengelola Konflik dalam Keluarga', + description: + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.", + price: 50000, + image: 'https://picsum.photos/id/146/1200/800', + category: 'Parenting', }, { - email: 'pk@zainf.dev', - name: 'Pejuang Kode', - role: ROLES.MEMBER, + name: 'Menumbuhkan Rasa Percaya Diri Sejak Dini', + description: + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.", + price: 100000, + image: 'https://picsum.photos/id/1001/1200/800', + category: 'Parenting', }, ] }