Conditional unique contstraint in prisma/postgres schema? Is it possible? - postgresql

I am trying to implement an AuthProvider model for our prisma schema, using postgres as the provider. You can see the start of my work here:
model AuthProvider {
id String #id #default(cuid())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
type AuthProviderType
externalUserId String? #unique
email String #unique // this should not be unique if the userId is the same among two AuthProviders
emailVerified Boolean? #default(false)
password String? // Hashed password
user User #relation(fields: [userId], references: [id])
userId String
##map("auth_providers")
}
A user can have many authentication providers, such as email + password, google, twitter. They can sign in with whatever they choose once they have connected it
Now here comes the tricky part:
what I want to accomplish is to make it so an AuthProviders email is unique, but ONLY if the userId of that AuthProvider is different.
So a user should be able to have several AuthProviders with the same email, but if one user tries to connect an authprovider with an email that another user already has connected (on any of their authproviders), then it should fail via unique constraint.
would this be achieveable just using unique constraints/indexes in the schema?

Related

Why can't I query certain fields in Prisma?

I need to be able to access certain fields of a Prisma model, but they always come back undefined even though I can see that the data exists in Prisma Studio.
Here is my model for Goods in schema.prisma:
model Good {
id String #id #default(cuid())
title String
completed Boolean #default(false)
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
user User #relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
userId String
}
Each Good has an id, title, etc. in addition to a user. However, when I log a Good to the console, it seems I can only access the title and id of the item. All the other expected fields are not present, and come back as undefined when I try to access them (i.e. console.log(good.user). Here's the output of console.log({good}):
{id: 'clcxxla0g0008ts5qjk248fzk', title: 'Title of good'}
What I need is to be able to query the user or userId for each Good, but I can't find a way to do this.
For more info, here is what what Prisma Studio data looks like:

What should I use as validation tool using NestJS and MongoDB?

Let's say, I am creating application using NestJS. I use MongoDB as a database and mongoose as ODM. So, NestJS has it's own way to validate data - ValidationPipe's. On the other side, there is mongoose built-in ways to validate data that being pushed into DB.
The question is - can I use only NestJS validation or do I need also second-check my data using mongoose validation tools?
Personally, I can't see why should I use additional layer of validation if I already have NestJS validation. But maybe there is best-practice or something?
Each database validates input data and emits an error if found. However, you must take into account your schema file. For instance, if you are using Prisma(It doesn't actually matter) and you have a User model like below
model User {
id String #id #default(auto()) #map("_id") #db.ObjectId
email String #unique
password String
name String
image String?
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
##map("user")
}
As you can see there is only one optional property "image". Whether you pass a value for image property or not, the database will insert the data as a row. On the other hand, the properties without "?" mark at the end of the type, will not be stored if you don't pass them and emit an error.
Therefore, if you modeled schema according to your business logic, you don't need to validate twice but only add an exception handling like the one below.
const user = await this.usersService.findOne('id...')
.catch((e) => new NotFoundException({ message: 'No user found.' }))

Use a field's generated value as another field's default value in prisma?

I have this User model in prisma (postgres), I want to use the same value cuid() generates for id in username. How do I achieve that?
model User {
id String #id #default(cuid())
username String? #unique
}
I know I can just regenerate cuid() for a different value, it would still work for what I am working on, but I want user's id and username to be same by default.

Is there a way to set up MongoDB ttl indexes using prisma

I am trying to make a Hotel website backend that allows users to reserve rooms using GraphQL and prisma. I want to make sure that the reservation will be cancelled after the check-in time if no one has checked in. To do this I wanted to set up a ttl index that will delete the reservation.
If there is any alternative way of doing this you can help me.
take a look on this : https://www.prisma.io/docs/concepts/components/prisma-schema/indexes
model Post {
id Int #id
title String #db.VarChar(255)
content String #db.Text
##fulltext([title, content])
}

After I run "npm run migrate", model is go away

I created model like this
model Comment {
id Int #id #default(autoincrement())
createdAt DateTime #default(now())
updatedAt DateTime #updatedAt
user User #relation(fields: [userId],references: [id])
photo Photo #relation(fields: [photoId],references: [id])
comment String
userId Int
photoId Int
}
After I run npm run migrate, the Comment Model is gone away... what should I do..?
Now, I see an error.
Error validating field photo in model Comment: The relation field photo on Model Comment is missing an opposite relation field on the model Photo. Either run prisma format or add it manually.