mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
broke out script to define relations to avoid conflicts and circular imports
This commit is contained in:
parent
138153f876
commit
59e47cb02c
7 changed files with 41 additions and 106 deletions
|
|
@ -5,6 +5,7 @@ import * as portfolioSchema from "@/app/db/schema/portfolio";
|
|||
import * as propertySchema from "@/app/db/schema/property";
|
||||
import * as recommendationSchema from "@/app/db/schema/recommendations";
|
||||
import * as materialSchema from "@/app/db/schema/materials";
|
||||
import * as Relations from "@/app/db/schema/relations";
|
||||
|
||||
export const pool = new Pool({
|
||||
host: process.env.DB_HOST,
|
||||
|
|
@ -21,6 +22,7 @@ const schema = {
|
|||
...propertySchema,
|
||||
...recommendationSchema,
|
||||
...materialSchema,
|
||||
...Relations,
|
||||
};
|
||||
|
||||
export const db = drizzle(pool, {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { InferModel } from "drizzle-orm";
|
||||
import {
|
||||
bigserial,
|
||||
text,
|
||||
|
|
@ -86,3 +87,5 @@ export const material = pgTable("material", {
|
|||
cost: json("cost").$type<number[]>(),
|
||||
notes: text("notes"),
|
||||
});
|
||||
|
||||
export type Material = InferModel<typeof material, "select">;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
bigint,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { user } from "./users";
|
||||
import { InferModel, relations } from "drizzle-orm";
|
||||
import { InferModel } from "drizzle-orm";
|
||||
|
||||
export const PortfolioStatus: [string, ...string[]] = [
|
||||
"scoping",
|
||||
|
|
@ -70,15 +70,6 @@ export const portfolio = pgTable("portfolio", {
|
|||
.notNull(),
|
||||
});
|
||||
|
||||
// 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),
|
||||
}));
|
||||
|
||||
export const portfolioUsers = pgTable("portfolioUsers", {
|
||||
id: bigserial("id", { mode: "bigint" }).primaryKey(),
|
||||
// Define the foreign key constraints using references from Drizzle, from user_id to the users table
|
||||
|
|
@ -104,19 +95,6 @@ export const portfolioUsers = pgTable("portfolioUsers", {
|
|||
.notNull(),
|
||||
});
|
||||
|
||||
// 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),
|
||||
})
|
||||
);
|
||||
|
||||
export type Portfolio = InferModel<typeof portfolio, "select">;
|
||||
export type NewPortfolio = InferModel<typeof portfolio, "insert">;
|
||||
export type PortfolioUsers = InferModel<typeof portfolioUsers, "select">;
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ import {
|
|||
bigint,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { portfolio, PortfolioStatus } from "./portfolio";
|
||||
import { recommendation } from "./recommendations";
|
||||
import { InferModel, relations } from "drizzle-orm";
|
||||
import { InferModel } from "drizzle-orm";
|
||||
|
||||
// This is a placeholder for the property schema
|
||||
export interface PropertyMeta {
|
||||
|
|
@ -184,26 +183,6 @@ export const propertyTargets = pgTable("property_targets", {
|
|||
heatDemand: text("heat_demand"),
|
||||
});
|
||||
|
||||
// one to one relationship between property and propertyTargets
|
||||
export const propertyRelations = relations(property, ({ one, many }) => ({
|
||||
target: one(propertyTargets, {
|
||||
fields: [property.id],
|
||||
references: [propertyTargets.propertyId],
|
||||
}),
|
||||
recommendations: many(recommendation),
|
||||
}));
|
||||
|
||||
// Define the other side of the one to many relation between a property and its recomendations
|
||||
export const recommendationsRelations = relations(
|
||||
recommendation,
|
||||
({ one }) => ({
|
||||
author: one(property, {
|
||||
fields: [recommendation.propertyId],
|
||||
references: [property.id],
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
// TODO: We'll need a property details buildings materials for verisk data?
|
||||
|
||||
export type Property = InferModel<typeof property, "select">;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import {
|
|||
bigint,
|
||||
pgEnum,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { material } from "./materials";
|
||||
import { InferModel, relations } from "drizzle-orm";
|
||||
import { Material, material } from "./materials";
|
||||
import { InferModel } from "drizzle-orm";
|
||||
|
||||
export const recommendation = pgTable("recommendation", {
|
||||
id: bigserial("id", { mode: "bigint" }).primaryKey(),
|
||||
|
|
@ -81,66 +81,16 @@ export const planRecommendations = pgTable("plan_recommendations", {
|
|||
.references(() => recommendation.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],
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
// We construct a relationship between a recommendation and recommendationMaterials
|
||||
// On recommendationMaterial will map to a single recommendation
|
||||
|
||||
// Define the relationships for the recommendation table
|
||||
export const recommendationRelations = relations(
|
||||
recommendation,
|
||||
({ many }) => ({
|
||||
recommendationMaterials: many(recommendationMaterials),
|
||||
})
|
||||
);
|
||||
|
||||
// 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],
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
export type Plan = InferModel<typeof plan, "select">;
|
||||
export type Recommendation = InferModel<typeof recommendation, "select">;
|
||||
export type PlanRecommendations = InferModel<
|
||||
typeof planRecommendations,
|
||||
"select"
|
||||
>;
|
||||
export type RecommendationMaterial = InferModel<
|
||||
typeof recommendationMaterials,
|
||||
"select"
|
||||
>;
|
||||
|
||||
// We allow recommendation types to be a string however we'll set up a typing for it here to control
|
||||
// the types we expect
|
||||
|
|
@ -166,3 +116,25 @@ export interface PortfolioPlanRecommendation {
|
|||
materialType: string;
|
||||
numberOfProperties: number;
|
||||
}
|
||||
|
||||
export interface RecommendationMaterialToMaterial extends Material {
|
||||
material: Material;
|
||||
}
|
||||
|
||||
export interface RecommendationWithMaterials {
|
||||
id: string;
|
||||
type: RecommendationType;
|
||||
description: string;
|
||||
estimatedCost: number;
|
||||
startingUValue: number;
|
||||
newUValue: number;
|
||||
sapPoints: number;
|
||||
heatDemand: number;
|
||||
co2EquivalentSavings: number;
|
||||
energySavings: number;
|
||||
energyCostSavings: number;
|
||||
propertyValuationIncrease: number;
|
||||
rentalYieldIncrease: number;
|
||||
totalWorkHours: number;
|
||||
recommendationMaterials: RecommendationMaterialToMaterial[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,16 +24,16 @@ import { useState } from "react";
|
|||
import { DataTablePagination } from "./propertyTablePagination";
|
||||
import React from "react";
|
||||
import { Input } from "@/app/shadcn_components/ui/input";
|
||||
import { PropertyWithTarget } from "@/app/db/schema/property";
|
||||
import { PropertyWithRelations } from "@/app/db/schema/property";
|
||||
|
||||
interface DataTableProps<TData, TValue> {
|
||||
columns: ColumnDef<PropertyWithTarget>[];
|
||||
data: PropertyWithTarget[];
|
||||
columns: ColumnDef<PropertyWithRelations>[];
|
||||
data: PropertyWithRelations[];
|
||||
}
|
||||
|
||||
function fetchData(offset: number) {
|
||||
// Because this is a client component, this will be handled with react query
|
||||
let properties: PropertyWithTarget[] = [];
|
||||
let properties: PropertyWithRelations[] = [];
|
||||
// TODO: implement this
|
||||
return properties;
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ export default function DataTable<TData, TValue>({
|
|||
columns,
|
||||
}: DataTableProps<TData, TValue>) {
|
||||
const [sorting, setSorting] = useState<SortingState>([]);
|
||||
const [tableData, setTableData] = useState<PropertyWithTarget[]>(data);
|
||||
const [tableData, setTableData] = useState<PropertyWithRelations[]>(data);
|
||||
const [offset, setOffset] = useState(0);
|
||||
const [currentPageIndex, setCurrentPageIndex] = useState(0);
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import {
|
|||
recommendation,
|
||||
UnnestedRecommendation,
|
||||
PortfolioPlanRecommendation,
|
||||
RecommendationWithMaterials,
|
||||
} from "./../../db/schema/recommendations";
|
||||
import { and, eq, inArray } from "drizzle-orm";
|
||||
import { db } from "@/app/db/db";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue