So I want to make an app where a user can create a 'Household' where they can invite other members of their family to have a shared database where they can store items in their pantry/kitchen.
The family members would have their emails added to an invite list, and upon their first log in, their email would be checked to see if it is on an invite list, and if it is, given the option to join the Household, and if not, the ability to create their own household.
When creating a new household, I would like to have the user supply a name for their household, their name and email (from next-auth session), and optionally a list of emails to send invites to.
I am using nextjs, prisma and trpc, all of which I am fairly new with, and I am wondering if the schema I have come up with is feasible, and what info I should add into a trpc procedure to take in the User info (from session data) and household name from the front end form.
Here is my prisma schema:
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
founder Boolean?
household Household? @relation(fields: [householdId], references: [householdId])
householdId String?
onInviteList Boolean? @default(false)
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
model Household {
name String
householdId String @id @default(cuid())
members User[]
invitedList Invite[]
storageAreas StorageArea[]
}
model Invite {
email String @unique
isVerified Boolean?
Household Household? @relation(fields: [householdId], references: [householdId])
householdId String?
}
EDIT
This is how I was attempting to create the household:
My household.ts router:
export const householdRouter = createTRPCRouter({
create: protectedProcedure
.input(
z.object({
name: z.string(),
members: z.object({ name: z.string(), email: z.string() }),
})
)
.mutation(({ ctx, input }) => {
return ctx.prisma.household.create({
data: {
name: input.name,
members: input.members
},
});
}),
});
and on the front end
// for storing the sessionData to pass to backend
const [householdFounder, setHouseholdFounder] = useState<HouseholdFounder>({
name: "",
email: "",
});
useEffect(() => {
status === "authenticated" &&
setHouseholdFounder({
name: sessionData.user.name,
email: sessionData.user.email,
});
}, [status, sessionData]);
// and here's the input for receiving the household name and the trpc call to the backend
<input
type="text"
onChange={(e) => setHouseholdName(e.currentTarget.value)}
value={householdName ?? ""}
/>
<button
onClick={(e) => {
newHousehold.mutate({
name: householdName ?? "",
members: householdFounder,
});
setHouseholdName("");
}}
>
Create New Household
</button>
This throws a type error in the router when taking in the input.members:
Type '{ email: string; name: string; }' is not assignable to type 'UserUncheckedCreateNestedManyWithoutHouseholdInput | UserCreateNestedManyWithoutHouseholdInput | undefined'.ts(2322)
Thank you for an insight you can shed on this for me, I've been trying all day to get a household created with the proper info sent.