Create Residents table #78

Merged
BenjaminPalko merged 4 commits from 36-create-residents into master 2025-02-07 16:30:12 -05:00
7 changed files with 50 additions and 18 deletions

View file

@ -2,3 +2,4 @@
package-lock.json package-lock.json
pnpm-lock.yaml pnpm-lock.yaml
yarn.lock yarn.lock
*.md

View file

@ -1,12 +1,16 @@
# Hestia # Hestia
Hestia is an early stage project <!--toc:start-->
- [Hestia](#hestia)
- [Setup](#setup) - [Setup](#setup)
- [Developing](#developing) - [Developing](#developing)
- [Modifying Database Schema](#modifying-database-schema) - [Modifying Database Schema](#modifying-database-schema)
- [Building](#building) - [Building](#building)
- [Stack](#stack) - [Stack](#stack) - [Frontend](#frontend) - [Backend](#backend) - [Tools](#tools)
<!--toc:end-->
Hestia is an early stage project
## Setup ## Setup

View file

@ -9,7 +9,7 @@
"@inlang/paraglide-sveltekit": "^0.15.0", "@inlang/paraglide-sveltekit": "^0.15.0",
"@pothos/core": "^4.3.0", "@pothos/core": "^4.3.0",
"@pothos/plugin-prisma": "^4.4.0", "@pothos/plugin-prisma": "^4.4.0",
"@prisma/client": "6.0.1", "@prisma/client": "^6.3.1",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"clerk-sveltekit": "https://pkg.pr.new/wobsoriano/clerk-sveltekit@ca15d4e", "clerk-sveltekit": "https://pkg.pr.new/wobsoriano/clerk-sveltekit@ca15d4e",
"clsx": "^2.1.1", "clsx": "^2.1.1",
@ -52,7 +52,7 @@
"prettier": "^3.3.2", "prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.6", "prettier-plugin-svelte": "^3.2.6",
"prettier-plugin-tailwindcss": "^0.6.5", "prettier-plugin-tailwindcss": "^0.6.5",
"prisma": "6.0.1", "prisma": "^6.3.1",
"storybook": "^8.5.0", "storybook": "^8.5.0",
"svelte": "^5.0.0", "svelte": "^5.0.0",
"svelte-check": "^4.0.0", "svelte-check": "^4.0.0",
@ -309,19 +309,19 @@
"@pothos/plugin-prisma": ["@pothos/plugin-prisma@4.4.0", "", { "dependencies": { "@prisma/generator-helper": "^6.0.0" }, "peerDependencies": { "@pothos/core": "*", "@prisma/client": "*", "graphql": ">=16.6.0", "typescript": ">=4.7.2" }, "bin": { "prisma-pothos-types": "bin/generator.js" } }, "sha512-TlXJ8QVOihpPbJGGHwOv2MUFv61xHU2xgGyTVp7KWNLQ6hzP9RH3nSQY7H1pNLOYR5wK+RyREJcaswVNwtxuqw=="], "@pothos/plugin-prisma": ["@pothos/plugin-prisma@4.4.0", "", { "dependencies": { "@prisma/generator-helper": "^6.0.0" }, "peerDependencies": { "@pothos/core": "*", "@prisma/client": "*", "graphql": ">=16.6.0", "typescript": ">=4.7.2" }, "bin": { "prisma-pothos-types": "bin/generator.js" } }, "sha512-TlXJ8QVOihpPbJGGHwOv2MUFv61xHU2xgGyTVp7KWNLQ6hzP9RH3nSQY7H1pNLOYR5wK+RyREJcaswVNwtxuqw=="],
"@prisma/client": ["@prisma/client@6.0.1", "", { "peerDependencies": { "prisma": "*" }, "optionalPeers": ["prisma"] }, "sha512-60w7kL6bUxz7M6Gs/V+OWMhwy94FshpngVmOY05TmGD0Lhk+Ac0ZgtjlL6Wll9TD4G03t4Sq1wZekNVy+Xdlbg=="], "@prisma/client": ["@prisma/client@6.3.1", "", { "peerDependencies": { "prisma": "*", "typescript": ">=5.1.0" }, "optionalPeers": ["prisma", "typescript"] }, "sha512-ARAJaPs+eBkemdky/XU3cvGRl+mIPHCN2lCXsl5Vlb0E2gV+R6IN7aCI8CisRGszEZondwIsW9Iz8EJkTdykyA=="],
"@prisma/debug": ["@prisma/debug@6.0.1", "", {}, "sha512-jQylgSOf7ibTVxqBacnAlVGvek6fQxJIYCQOeX2KexsfypNzXjJQSS2o5s+Mjj2Np93iSOQUaw6TvPj8syhG4w=="], "@prisma/debug": ["@prisma/debug@6.3.1", "", {}, "sha512-RrEBkd+HLZx+ydfmYT0jUj7wjLiS95wfTOSQ+8FQbvb6vHh5AeKfEPt/XUQ5+Buljj8hltEfOslEW57/wQIVeA=="],
"@prisma/engines": ["@prisma/engines@6.0.1", "", { "dependencies": { "@prisma/debug": "6.0.1", "@prisma/engines-version": "5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e", "@prisma/fetch-engine": "6.0.1", "@prisma/get-platform": "6.0.1" } }, "sha512-4hxzI+YQIR2uuDyVsDooFZGu5AtixbvM2psp+iayDZ4hRrAHo/YwgA17N23UWq7G6gRu18NvuNMb48qjP3DPQw=="], "@prisma/engines": ["@prisma/engines@6.3.1", "", { "dependencies": { "@prisma/debug": "6.3.1", "@prisma/engines-version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0", "@prisma/fetch-engine": "6.3.1", "@prisma/get-platform": "6.3.1" } }, "sha512-sXdqEVLyGAJ5/iUoG/Ea5AdHMN71m6PzMBWRQnLmhhOejzqAaEr8rUd623ql6OJpED4s/U4vIn4dg1qkF7vGag=="],
"@prisma/engines-version": ["@prisma/engines-version@5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e", "", {}, "sha512-JmIds0Q2/vsOmnuTJYxY4LE+sajqjYKhLtdOT6y4imojqv5d/aeVEfbBGC74t8Be1uSp0OP8lxIj2OqoKbLsfQ=="], "@prisma/engines-version": ["@prisma/engines-version@6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0", "", {}, "sha512-R/ZcMuaWZT2UBmgX3Ko6PAV3f8//ZzsjRIG1eKqp3f2rqEqVtCv+mtzuH2rBPUC9ujJ5kCb9wwpxeyCkLcHVyA=="],
"@prisma/fetch-engine": ["@prisma/fetch-engine@6.0.1", "", { "dependencies": { "@prisma/debug": "6.0.1", "@prisma/engines-version": "5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e", "@prisma/get-platform": "6.0.1" } }, "sha512-T36bWFVGeGYYSyYOj9d+O9G3sBC+pAyMC+jc45iSL63/Haq1GrYjQPgPMxrEj9m739taXrupoysRedQ+VyvM/Q=="], "@prisma/fetch-engine": ["@prisma/fetch-engine@6.3.1", "", { "dependencies": { "@prisma/debug": "6.3.1", "@prisma/engines-version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0", "@prisma/get-platform": "6.3.1" } }, "sha512-HOf/0umOgt+/S2xtZze+FHKoxpVg4YpVxROr6g2YG09VsI3Ipyb+rGvD6QGbCqkq5NTWAAZoOGNL+oy7t+IhaQ=="],
"@prisma/generator-helper": ["@prisma/generator-helper@6.2.1", "", { "dependencies": { "@prisma/debug": "6.2.1" } }, "sha512-7Ws8DCXGan7hhaFMERXYdmhsudvSzEsrTttJEC7ubZJidvyimS12m3xpM+dLTt+NAShJ7Op7PgF+Mal2jf6xfg=="], "@prisma/generator-helper": ["@prisma/generator-helper@6.2.1", "", { "dependencies": { "@prisma/debug": "6.2.1" } }, "sha512-7Ws8DCXGan7hhaFMERXYdmhsudvSzEsrTttJEC7ubZJidvyimS12m3xpM+dLTt+NAShJ7Op7PgF+Mal2jf6xfg=="],
"@prisma/get-platform": ["@prisma/get-platform@6.0.1", "", { "dependencies": { "@prisma/debug": "6.0.1" } }, "sha512-zspC9vlxAqx4E6epMPMLLBMED2VD8axDe8sPnquZ8GOsn6tiacWK0oxrGK4UAHYzYUVuMVUApJbdXB2dFpLhvg=="], "@prisma/get-platform": ["@prisma/get-platform@6.3.1", "", { "dependencies": { "@prisma/debug": "6.3.1" } }, "sha512-AYLq6Hk9xG73JdLWJ3Ip9Wg/vlP7xPvftGBalsPzKDOHr/ImhwJ09eS8xC2vNT12DlzGxhfk8BkL0ve2OriNhQ=="],
"@repeaterjs/repeater": ["@repeaterjs/repeater@3.0.6", "", {}, "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA=="], "@repeaterjs/repeater": ["@repeaterjs/repeater@3.0.6", "", {}, "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA=="],
@ -1249,7 +1249,7 @@
"pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], "pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="],
"prisma": ["prisma@6.0.1", "", { "dependencies": { "@prisma/engines": "6.0.1" }, "optionalDependencies": { "fsevents": "2.3.3" }, "bin": { "prisma": "build/index.js" } }, "sha512-CaMNFHkf+DDq8zq3X/JJsQ4Koy7dyWwwtOKibkT/Am9j/tDxcfbg7+lB1Dzhx18G/+RQCMgjPYB61bhRqteNBQ=="], "prisma": ["prisma@6.3.1", "", { "dependencies": { "@prisma/engines": "6.3.1" }, "optionalDependencies": { "fsevents": "2.3.3" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-JKCZWvBC3enxk51tY4TWzS4b5iRt4sSU1uHn2I183giZTvonXaQonzVtjLzpOHE7qu9MxY510kAtFGJwryKe3Q=="],
"process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="], "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],

View file

@ -57,7 +57,7 @@
"prettier": "^3.3.2", "prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.6", "prettier-plugin-svelte": "^3.2.6",
"prettier-plugin-tailwindcss": "^0.6.5", "prettier-plugin-tailwindcss": "^0.6.5",
"prisma": "6.0.1", "prisma": "6.3.1",
"storybook": "^8.5.0", "storybook": "^8.5.0",
"svelte": "^5.0.0", "svelte": "^5.0.0",
"svelte-check": "^4.0.0", "svelte-check": "^4.0.0",
@ -73,7 +73,7 @@
"@inlang/paraglide-sveltekit": "^0.15.0", "@inlang/paraglide-sveltekit": "^0.15.0",
"@pothos/core": "^4.3.0", "@pothos/core": "^4.3.0",
"@pothos/plugin-prisma": "^4.4.0", "@pothos/plugin-prisma": "^4.4.0",
"@prisma/client": "6.0.1", "@prisma/client": "6.3.1",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"clerk-sveltekit": "https://pkg.pr.new/wobsoriano/clerk-sveltekit@ca15d4e", "clerk-sveltekit": "https://pkg.pr.new/wobsoriano/clerk-sveltekit@ca15d4e",
"clsx": "^2.1.1", "clsx": "^2.1.1",

View file

@ -0,0 +1,14 @@
-- CreateTable
CREATE TABLE "Resident" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"phoneNumber" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Resident_pkey" PRIMARY KEY ("id")
);
-- AddForeignKey
ALTER TABLE "Resident" ADD CONSTRAINT "Resident_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
piopi commented 2025-02-06 13:50:05 -05:00 (Migrated from github.com)
Review

Feel like it should be ON DELETE CASACADE but maybe it is prisma generating this

Feel like it should be ON DELETE CASACADE but maybe it is prisma generating this
BenjaminPalko commented 2025-02-06 22:04:53 -05:00 (Migrated from github.com)
Review

Cascade needs to be explicitly specified, I could see the desire to add that, but I can also see how it might be dangerous. If a tenant is accidentally deleted then it would cascade to all related tables and nuke a tenant completely, whereas with RESTRICT it would prevent this. Child tables would need to be removed FIRST before the parent, this would be a more explicit operation that would be less likely to be run on accident.

Thanks for coming to my Ted talk

Cascade needs to be explicitly specified, I could see the desire to add that, but I can also see how it might be dangerous. If a tenant is accidentally deleted then it would cascade to all related tables and nuke a tenant completely, whereas with RESTRICT it would prevent this. Child tables would need to be removed FIRST before the parent, this would be a more explicit operation that would be less likely to be run on accident. Thanks for coming to my Ted talk
piopi commented 2025-02-07 16:46:34 -05:00 (Migrated from github.com)
Review

If a tenant is deleted it means they want their data out of the platform. Not making it cascade delete just makes it harder to fully delete a tenant data. ( You could protect the data with an appropriate backup policy and db roles)

Cascade delete helps a lot when you setup your integration test and you delete your test tenant after each test, it makes the clean up of the test much easier.

If a tenant is deleted it means they want their data out of the platform. Not making it cascade delete just makes it harder to fully delete a tenant data. ( You could protect the data with an appropriate backup policy and db roles) Cascade delete helps a lot when you setup your integration test and you delete your test tenant after each test, it makes the clean up of the test much easier.

View file

@ -1,3 +1,3 @@
# Please do not edit this file manually # Please do not edit this file manually
# It should be added in your version-control system (i.e. Git) # It should be added in your version-control system (e.g., Git)
provider = "postgresql" provider = "postgresql"

View file

@ -31,11 +31,24 @@ model User {
@@unique([clerkId, tenantId]) @@unique([clerkId, tenantId])
} }
model Resident {
id String @id @default(uuid())
DanMihailescu commented 2025-02-07 10:11:32 -05:00 (Migrated from github.com)
Review

It should be marked as unique to ensure no duplicate residents

It should be marked as unique to ensure no duplicate residents
BenjaminPalko commented 2025-02-07 15:43:56 -05:00 (Migrated from github.com)
Review

@id is unique

@id is unique
tenant Tenant @relation(fields: [tenantId], references: [id])
tenantId String
name String
phoneNumber String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
piopi commented 2025-02-04 08:51:39 -05:00 (Migrated from github.com)
Review

Missing the tenantId

Missing the tenantId
BenjaminPalko commented 2025-02-05 15:42:56 -05:00 (Migrated from github.com)
Review

Fix, thanks!

Fix, thanks!
}
model Tenant { model Tenant {
id String @id @default(uuid()) id String @id @default(uuid())
clerkOrganizationId String @unique clerkOrganizationId String @unique
users User[] users User[]
residents Resident[]
tenantConfig TenantConfig? tenantConfig TenantConfig?
name String name String