Skip to content

Commit

Permalink
feat: add prisma migration
Browse files Browse the repository at this point in the history
  • Loading branch information
joannechen1223 committed Mar 6, 2024
1 parent 4c1dd00 commit 65be335
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 6 deletions.
33 changes: 33 additions & 0 deletions apps/recnet-api/buildspec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
version: 0.2

phases:
install:
runtime-versions:
nodejs: 18
commands:
- npm i -g pnpm
- pnpm i --frozen-lockfile
pre_build:
commands:
- pnpm nx clean recnet-api
- pnpm nx prisma:generate recnet-api
build:
commands:
- pnpm nx build recnet-api
post_build:
commands:
- rm -rf node_modules
- mv package.json package.json.bak
- mv pnpm-lock.yaml pnpm-lock.yaml.bak
- mv dist/apps/recnet-api/package.json package.json
- mv dist/apps/recnet-api/pnpm-lock.yaml pnpm-lock.yaml
- pnpm install --prod --frozen-lockfile
- pnpx prisma generate --schema=apps/recnet-api/prisma/schema.prisma
- cp -R apps/recnet-api/prisma/ dist/apps/recnet-api/prisma
artifacts:
files:
- "dist/apps/recnet-api/**/*"
- "node_modules/**/*"
- "package.json"
- "Procfile"
enable-symlinks: yes
102 changes: 102 additions & 0 deletions apps/recnet-api/prisma/migrations/20240306035932_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
-- CreateEnum
CREATE TYPE "Provider" AS ENUM ('FACEBOOK', 'GOOGLE');

-- CreateEnum
CREATE TYPE "Role" AS ENUM ('ADMIN', 'USER');

-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"provider" "Provider" NOT NULL,
"providerId" VARCHAR(128) NOT NULL,
"email" VARCHAR(128) NOT NULL,
"handle" VARCHAR(32) NOT NULL,
"displayName" VARCHAR(32) NOT NULL,
"inviteCode" VARCHAR(64),
"photoUrl" VARCHAR(256) NOT NULL,
"affiliation" VARCHAR(32),
"bio" TEXT,
"lastLoginAt" TIMESTAMP(3) NOT NULL,
"role" "Role" NOT NULL DEFAULT 'USER',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "FollowingRecord" (
"userId" TEXT NOT NULL,
"followerId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL,

CONSTRAINT "FollowingRecord_pkey" PRIMARY KEY ("userId","followerId")
);

-- CreateTable
CREATE TABLE "Recommendation" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"articleId" TEXT NOT NULL,
"description" TEXT NOT NULL,
"cutoff" TIMESTAMP(3) NOT NULL,
"createAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updateAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "Recommendation_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Article" (
"id" TEXT NOT NULL,
"doi" VARCHAR(32),
"title" VARCHAR(256) NOT NULL,
"author" VARCHAR(256) NOT NULL,
"link" VARCHAR(256) NOT NULL,
"year" SMALLINT NOT NULL,
"month" SMALLINT,
"isVerified" BOOLEAN NOT NULL DEFAULT false,
"createAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updateAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,

CONSTRAINT "Article_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "InviteCode" (
"id" SERIAL NOT NULL,
"code" VARCHAR(64) NOT NULL,
"ownerId" VARCHAR(32) NOT NULL,
"issuedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"usedById" VARCHAR(32),
"usedAt" TIMESTAMP(3),

CONSTRAINT "InviteCode_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

-- CreateIndex
CREATE UNIQUE INDEX "User_handle_key" ON "User"("handle");

-- CreateIndex
CREATE UNIQUE INDEX "InviteCode_usedById_key" ON "InviteCode"("usedById");

-- AddForeignKey
ALTER TABLE "FollowingRecord" ADD CONSTRAINT "FollowingRecord_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "FollowingRecord" ADD CONSTRAINT "FollowingRecord_followerId_fkey" FOREIGN KEY ("followerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Recommendation" ADD CONSTRAINT "Recommendation_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Recommendation" ADD CONSTRAINT "Recommendation_articleId_fkey" FOREIGN KEY ("articleId") REFERENCES "Article"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "InviteCode" ADD CONSTRAINT "InviteCode_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "InviteCode" ADD CONSTRAINT "InviteCode_usedById_fkey" FOREIGN KEY ("usedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
3 changes: 3 additions & 0 deletions apps/recnet-api/prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
58 changes: 57 additions & 1 deletion apps/recnet-api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,67 @@ model User {
handle String @db.VarChar(32) @unique
displayName String @db.VarChar(32)
inviteCode String? @db.VarChar(64)
photoUrl String @db.VarChar(128)
photoUrl String @db.VarChar(256)
affiliation String? @db.VarChar(32)
bio String?
lastLoginAt DateTime
role Role @default(USER) // Enum type
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
following FollowingRecord[] @relation("Following")
followers FollowingRecord[] @relation("Follower")
recommendations Recommendation[]
inviteCodeOwner InviteCode[] @relation("InviteCodeOwner")
inviteCodeUsed InviteCode? @relation("InviteCodeUsedBy")
}

model FollowingRecord {
userId String
followerId String
createdAt DateTime
@@id([userId, followerId])
user User @relation("Following", fields: [userId], references: [id])
follower User @relation("Follower", fields: [followerId], references: [id])
}

model Recommendation {
id String @id @default(uuid())
userId String
articleId String
description String
cutoff DateTime
createAt DateTime @default(now())
updateAt DateTime @default(now()) @updatedAt
user User @relation(fields: [userId], references: [id]) // User who made the recommendation
article Article @relation(fields: [articleId], references: [id]) // Article being recommended
}

model Article {
id String @id
doi String? @db.VarChar(32)
title String @db.VarChar(256)
author String @db.VarChar(256)
link String @db.VarChar(256)
year Int @db.SmallInt
month Int? @db.SmallInt
isVerified Boolean @default(false)
createAt DateTime @default(now())
updateAt DateTime @default(now()) @updatedAt
recommendations Recommendation[]
}

model InviteCode {
id Int @id @default(autoincrement())
code String @db.VarChar(64)
ownerId String @db.VarChar(32)
issuedAt DateTime @default(now())
usedById String? @db.VarChar(32) @unique
usedAt DateTime?
owner User @relation("InviteCodeOwner", fields: [ownerId], references: [id])
usedBy User? @relation("InviteCodeUsedBy", fields: [usedById], references: [id])
}
29 changes: 24 additions & 5 deletions apps/recnet-api/src/database/prisma/prisma.connection.provider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { execSync } from "child_process";

import { Injectable, OnModuleInit } from "@nestjs/common";
import { PrismaClient } from "@prisma/client";

Expand All @@ -14,22 +16,39 @@ export class PrismaConnectionProvider
extends PrismaClient
implements OnModuleInit
{
// prisma url
private prismaUrl: string;

constructor() {
const connectionUrl = `postgresql://${postgresConfig.username}:${encodeURIComponent(
postgresConfig.password
)}@${postgresConfig.host}:${postgresConfig.port}/${
postgresConfig.database
}?schema=recnet`;

super({
datasources: {
db: {
url: `postgresql://${postgresConfig.username}:${encodeURIComponent(
postgresConfig.password
)}@${postgresConfig.host}:${postgresConfig.port}/${
postgresConfig.database
}?schema=recnet&pool_timeout=60`,
url: `${connectionUrl}&pool_timeout=60`,
},
},
});

this.prismaUrl = connectionUrl;
}

async onModuleInit() {
await this.$connect();

const prismaSchema =
process.env.PRISMA_SCHEMA || "dist/apps/recnet-api/prisma/schema.prisma";

if (process.env.DB_MIGRATE === "true") {
execSync(
`export PRISMA_DATABASE_URL=${this.prismaUrl} && pnpx prisma migrate deploy --schema=${prismaSchema}`,
{ stdio: "inherit" }
);
}
}
}

Expand Down

0 comments on commit 65be335

Please sign in to comment.