Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike out prisma talking directly to Postgres DB #1115

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ yarn-debug.log*
yarn-error.log*

# local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

.vercel
.idea
.idea
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@heroicons/react": "^1.0.4",
"@mdx-js/mdx": "^2.0.0-next.9",
"@mdx-js/react": "^1.6.22",
"@prisma/client": "^3.14.0",
"@reach/alert-dialog": "^0.16.2",
"@reach/dialog": "^0.16.0",
"@reach/listbox": "^0.16.1",
Expand Down Expand Up @@ -112,6 +113,7 @@
"nextjs-sitemap-generator": "^1.3.1",
"pluralize": "^8.0.0",
"prism-react-renderer": "^1.2.1",
"prisma": "^3.14.0",
"qs": "^6.10.1",
"query-string": "^7.0.1",
"react": "^17.0.2",
Expand Down
46 changes: 46 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model roles {
id Int @id @default(autoincrement())
name String? @db.VarChar(255)
resource_id Int?
resource_type String? @db.VarChar(255)
created_at DateTime? @db.Timestamp(6)
updated_at DateTime? @db.Timestamp(6)
users_roles users_roles[] @ignore

@@index([name], map: "index_roles_on_name")
@@index([name, resource_type, resource_id], map: "index_roles_on_name_and_resource_type_and_resource_id")
}

model users {
id Int @id @default(autoincrement())
email String @unique(map: "index_users_on_email") @default("") @db.VarChar(255)
created_at DateTime? @db.Timestamp(6)
updated_at DateTime? @db.Timestamp(6)
first_name String? @db.VarChar(255)
last_name String? @db.VarChar(255)
users_roles users_roles[] @ignore

@@index([id], map: "index_users_on_lower_email_id")
}

/// The underlying table does not contain a valid unique identifier and can therefore currently not be handled by the Prisma Client.
model users_roles {
user_id Int
role_id Int
roles roles @relation(fields: [role_id], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "fk_rails_eb7b4658f8")
users users @relation(fields: [user_id], references: [id], onDelete: NoAction, onUpdate: NoAction, map: "fk_rails_4a41696df6")

@@index([role_id], map: "index_users_roles_on_role_id")
@@index([user_id], map: "index_users_roles_on_user_id")
@@index([user_id, role_id], map: "index_users_roles_on_user_id_and_role_id")
@@ignore
}
59 changes: 46 additions & 13 deletions src/pages/api/users/check-pro-status.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import axios from 'axios'

import {NextApiRequest, NextApiResponse} from 'next'
import emailIsValid from 'utils/email-is-valid'
import {isEmpty} from 'lodash'

import {Prisma, PrismaClient} from '@prisma/client'

if (!process.env.EGGHEAD_SUPPORT_BOT_TOKEN) {
throw new Error('no egghead support+bot token found')
}
Expand All @@ -13,19 +13,52 @@ const checkProStatus = async (req: NextApiRequest, res: NextApiResponse) => {
if (!emailIsValid(email)) {
res.status(400).end()
} else {
const userUrl = `${process.env.NEXT_PUBLIC_AUTH_DOMAIN}/api/v1/users/${email}?by_email=true`
const prisma = new PrismaClient()

// Unfortunately, cannot do this at the moment until we have un-ignored
// the `users_roles` model in `prisma/schema.prisma`. Be cause it doesn't
// have a primary key, the Prisma Client isn't able to handle it.
//
// const getUser: object | null = await prisma.users.findMany({
// where: {
// email: email,
// },
// select: {
// email: true,
// first_name: true,
// users_roles: {
Comment on lines +18 to +29
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the sake of this PoC, I bailed on the standard query syntax and did a raw SQL query below. This only happened here because the users_roles table had to be ignored as a model in schema.prisma because it doesn't have a unique primary key. There are some ways we could work around that, but I didn't want to get into those weeds.

Otherwise, we get really nice auto-generated TypeScript types for all of this.

// select: {
// role_id: true,
// roles: {
// where: {
// name: 'pro',
// },
// select: {
// name: true,
// },
// },
// },
// },
// },
// })

const eggheadUser = await axios
.get(userUrl, {
headers: {
Authorization: `Bearer ${process.env.EGGHEAD_SUPPORT_BOT_TOKEN}`,
},
})
.then(({data}) => data)
const result: Array<object> = await prisma.$queryRaw(
Prisma.sql`
select users.email, roles.name
from users
join users_roles
on users.id = users_roles.user_id
join roles
on roles.id = users_roles.role_id
where users.email = ${email}
and (roles.name = 'pro' or
roles.name = 'instructor')
`,
)

const hasProAccess =
!isEmpty(eggheadUser) &&
(eggheadUser.is_pro || eggheadUser.is_instructor)
// if a user has at least one of the roles: `pro` or `instructor`, then
// they are considered to have pro access.
const hasProAccess = !isEmpty(result)

res.status(200).json({hasProAccess})
}
Expand Down
24 changes: 24 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3607,6 +3607,23 @@
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.2.tgz#adea7b6953cbb34651766b0548468e743c6a2353"
integrity sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==

"@prisma/client@^3.14.0":
version "3.14.0"
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-3.14.0.tgz#bb90405c012fcca11f4647d91153ed4c58f3bd48"
integrity sha512-atb41UpgTR1MCst0VIbiHTMw8lmXnwUvE1KyUCAkq08+wJyjRE78Due+nSf+7uwqQn+fBFYVmoojtinhlLOSaA==
dependencies:
"@prisma/engines-version" "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a"

"@prisma/engines-version@3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a":
version "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a"
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a.tgz#4edae57cf6527f35e22cebe75e49214fc0e99ac9"
integrity sha512-D+yHzq4a2r2Rrd0ZOW/mTZbgDIkUkD8ofKgusEI1xPiZz60Daks+UM7Me2ty5FzH3p/TgyhBpRrfIHx+ha20RQ==

"@prisma/engines@3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a":
version "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a"
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a.tgz#7fa11bc26a51d450185c816cc0ab8cac673fb4bf"
integrity sha512-LwZvI3FY6f43xFjQNRuE10JM5R8vJzFTSmbV9X0Wuhv9kscLkjRlZt0BEoiHmO+2HA3B3xxbMfB5du7ZoSFXGg==

"@reach/alert-dialog@^0.16.2":
version "0.16.2"
resolved "https://registry.yarnpkg.com/@reach/alert-dialog/-/alert-dialog-0.16.2.tgz#624ddef82f3689b6fea9a19687d9cc664767e745"
Expand Down Expand Up @@ -18033,6 +18050,13 @@ prism-react-renderer@^1.2.1:
resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.2.1.tgz#392460acf63540960e5e3caa699d851264e99b89"
integrity sha512-w23ch4f75V1Tnz8DajsYKvY5lF7H1+WvzvLUcF0paFxkTHSp42RS0H5CttdN2Q8RR3DRGZ9v5xD/h3n8C8kGmg==

prisma@^3.14.0:
version "3.14.0"
resolved "https://registry.yarnpkg.com/prisma/-/prisma-3.14.0.tgz#dd67ece37d7b5373e9fd9588971de0024b49be81"
integrity sha512-l9MOgNCn/paDE+i1K2fp9NZ+Du4trzPTJsGkaQHVBufTGqzoYHuNk8JfzXuIn0Gte6/ZjyKj652Jq/Lc1tp2yw==
dependencies:
"@prisma/engines" "3.14.0-36.2b0c12756921c891fec4f68d9444e18c7d5d4a6a"

prismjs@^1.21.0, prismjs@~1.23.0:
version "1.23.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33"
Expand Down