diff --git a/src/app/db/schema/relations.ts b/src/app/db/schema/relations.ts new file mode 100644 index 00000000..6640da27 --- /dev/null +++ b/src/app/db/schema/relations.ts @@ -0,0 +1,102 @@ +// This script contains ALL relations for the database, used by drizzle-orm + +import { relations } from "drizzle-orm"; +import { property, propertyTargets } from "./property"; +import { + plan, + planRecommendations, + recommendation, + recommendationMaterials, +} from "./recommendations"; +import { material } from "./materials"; +import { portfolio, portfolioUsers } from "./portfolio"; +import { user } from "./users"; + +// Define the other side of the one to many relation between a property and its recomendations +export const recommendationsRelations = relations( + recommendation, + ({ one, many }) => ({ + property: one(property, { + fields: [recommendation.propertyId], + references: [property.id], + }), + recommendationMaterials: many(recommendationMaterials), + }) +); + +// We construct a relationship between a recommendation and recommendationMaterials +// On recommendationMaterial will map to a single recommendation + +// Define the relationships for the material table +export const materialRelations = relations(material, ({ many }) => ({ + recommendationMaterials: many(recommendationMaterials), +})); + +// Define the relationships for the recommendationMaterials table +export const recommendationMaterialsRelations = relations( + recommendationMaterials, + ({ one }) => ({ + recommendation: one(recommendation, { + fields: [recommendationMaterials.recommendationId], + references: [recommendation.id], + }), + material: one(material, { + fields: [recommendationMaterials.materialId], + references: [material.id], + }), + }) +); + +// create a one to many relation to map a plan to the details in the underlying recommendation +// create a many to many map from a plan to a recommendation +// A recommendation can be in multiple plans and therefore we have a many to many relationship between +// plan and recommendations. This relationship is facilitated by the planRecommdnations table + +export const planRelations = relations(plan, ({ many }) => ({ + planRecommendations: many(planRecommendations), +})); + +export const planRecommendationsRelations = relations( + planRecommendations, + ({ one }) => ({ + plan: one(plan, { + fields: [planRecommendations.planId], + references: [plan.id], + }), + recommendation: one(recommendation, { + fields: [planRecommendations.recommendationId], + references: [recommendation.id], + }), + }) +); + +// one to one relationship between property and propertyTargets, and also to the recommendations table +export const propertyRelations = relations(property, ({ one, many }) => ({ + target: one(propertyTargets, { + fields: [property.id], + references: [propertyTargets.propertyId], + }), + recommendations: many(recommendation), +})); + +// We have a many to many relationship between users and portfolios +// One user can have many portfolios, and one portfolio can have many users +// We use the Dizzle relational queries pattern to facilitate this + +// Define relation from users to portfolios +export const usersToPortfolioRelations = relations(user, ({ many }) => ({ + portfolios: many(portfolio), +})); + +// Define relation from portfolios to users +export const portfolioToUsersRelations = relations(portfolio, ({ many }) => ({ + users: many(user), +})); + +// Define relation from portfolioUsers to portfolios (we can have many users to a portfolio) +export const portfolioUsersToPortfolioRelations = relations( + portfolioUsers, + ({ many }) => ({ + portfolio: many(portfolio), + }) +);