mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
adding already installed table
This commit is contained in:
parent
3979ae9575
commit
8a08e98340
9 changed files with 15775 additions and 17 deletions
19
src/app/db/migrations/0145_brave_power_pack.sql
Normal file
19
src/app/db/migrations/0145_brave_power_pack.sql
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
CREATE TYPE "public"."measure_type" AS ENUM('air_source_heat_pump', 'boiler_upgrade', 'high_heat_retention_storage_heaters', 'secondary_heating', 'roomstat_programmer_trvs', 'time_temperature_zone_control', 'cylinder_thermostat', 'cavity_wall_insulation', 'extension_cavity_wall_insulation', 'external_wall_insulation', 'internal_wall_insulation', 'loft_insulation', 'flat_roof_insulation', 'room_roof_insulation', 'solid_floor_insulation', 'suspended_floor_insulation', 'double_glazing', 'secondary_glazing', 'draught_proofing', 'mechanical_ventilation', 'low_energy_lighting', 'solar_pv', 'hot_water_tank_insulation', 'sealing_open_fireplace');--> statement-breakpoint
|
||||
CREATE TABLE "installed_measure" (
|
||||
"id" bigserial PRIMARY KEY NOT NULL,
|
||||
"uprn" text NOT NULL,
|
||||
"measure_type" "measure_type" NOT NULL,
|
||||
"installed_at" timestamp DEFAULT now(),
|
||||
"sap_points" real,
|
||||
"carbon_savings" real,
|
||||
"kwh_savings" real,
|
||||
"bill_savings" real,
|
||||
"heat_demand_savings" real,
|
||||
"source" text,
|
||||
"is_active" boolean DEFAULT true NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE INDEX "idx_installed_measure_uprn" ON "installed_measure" USING btree ("uprn");--> statement-breakpoint
|
||||
CREATE INDEX "idx_installed_measure_uprn_active" ON "installed_measure" USING btree ("uprn") WHERE "installed_measure"."is_active" = true;--> statement-breakpoint
|
||||
CREATE INDEX "idx_installed_measure_measure_type" ON "installed_measure" USING btree ("measure_type");--> statement-breakpoint
|
||||
CREATE INDEX "idx_installed_measure_uprn_measure" ON "installed_measure" USING btree ("uprn","measure_type") WHERE "installed_measure"."is_active" = true;
|
||||
3
src/app/db/migrations/0146_tiny_george_stacy.sql
Normal file
3
src/app/db/migrations/0146_tiny_george_stacy.sql
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE "property" ADD COLUMN "installed_measures_sap_point_adjustment" real;--> statement-breakpoint
|
||||
ALTER TABLE "property" ADD COLUMN "is_sap_points_adjusted_for_installed_measures" boolean DEFAULT false;--> statement-breakpoint
|
||||
ALTER TABLE "property" ADD COLUMN "original_sap_points" real;
|
||||
2
src/app/db/migrations/0147_confused_killer_shrike.sql
Normal file
2
src/app/db/migrations/0147_confused_killer_shrike.sql
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE "property_installed_measures" DISABLE ROW LEVEL SECURITY;--> statement-breakpoint
|
||||
DROP TABLE "property_installed_measures" CASCADE;--> statement-breakpoint
|
||||
5215
src/app/db/migrations/meta/0145_snapshot.json
Normal file
5215
src/app/db/migrations/meta/0145_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
5234
src/app/db/migrations/meta/0146_snapshot.json
Normal file
5234
src/app/db/migrations/meta/0146_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
5188
src/app/db/migrations/meta/0147_snapshot.json
Normal file
5188
src/app/db/migrations/meta/0147_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1016,6 +1016,27 @@
|
|||
"when": 1767704869539,
|
||||
"tag": "0144_lovely_moira_mactaggert",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 145,
|
||||
"version": "7",
|
||||
"when": 1767810791075,
|
||||
"tag": "0145_brave_power_pack",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 146,
|
||||
"version": "7",
|
||||
"when": 1767812381964,
|
||||
"tag": "0146_tiny_george_stacy",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 147,
|
||||
"version": "7",
|
||||
"when": 1767814056667,
|
||||
"tag": "0147_confused_killer_shrike",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -132,6 +132,17 @@ export const property = pgTable(
|
|||
currentEpcRating: epcEnum("current_epc_rating"),
|
||||
currentSapPoints: real("current_sap_points"),
|
||||
currentValuation: real("current_valuation"),
|
||||
|
||||
// When we have already installed measures, we will adjust the SAP points to reflect this. We keep a record of
|
||||
// 1) The number of points we've adjusted by
|
||||
// 2) a flag to indicate whether the SAP points have been adjusted, for easily filtering
|
||||
installedMeasuresSapPointAdjustment: real(
|
||||
"installed_measures_sap_point_adjustment"
|
||||
),
|
||||
isSapPointsAdjustedForInstalledMeasures: boolean(
|
||||
"is_sap_points_adjusted_for_installed_measures"
|
||||
).default(false),
|
||||
originalSapPoints: real("original_sap_points"),
|
||||
},
|
||||
(table) => [
|
||||
uniqueIndex("uq_property_portfolio_uprn")
|
||||
|
|
@ -283,23 +294,6 @@ export const nonIntrusiveSurveyNotes = pgTable("non_intrusive_survey_notes", {
|
|||
note: text("note").notNull(),
|
||||
});
|
||||
|
||||
// This model is a record of the measures that have already been installed for a property
|
||||
// This is considered as supplementary daa and stored against the UPRN
|
||||
// RecommendationType is the
|
||||
export const propertyInstalledMeasures = pgTable(
|
||||
"property_installed_measures",
|
||||
{
|
||||
id: bigserial("id", { mode: "bigint" }).primaryKey(),
|
||||
uprn: bigint("uprn", { mode: "bigint" }).notNull(),
|
||||
// The material types define the list of measures we should expect
|
||||
measureType: materialTypeEnum("measure_type").notNull(),
|
||||
// Record of when this measure was inserted into the db
|
||||
createdAt: timestamp("created_at").notNull().defaultNow(),
|
||||
// Record of when this measure was actually installed
|
||||
installedAt: timestamp("installed_at").notNull().defaultNow(),
|
||||
}
|
||||
);
|
||||
|
||||
export type Property = InferModel<typeof property, "select">;
|
||||
export type PropertyDetailsEpc = InferModel<
|
||||
typeof propertyDetailsEpc,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,50 @@ import { Material, material } from "./materials";
|
|||
import { InferModel, sql } from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
|
||||
// For recommendations, measure types was initially defined as a string but we should convert this to an enum in the future
|
||||
|
||||
export const measureTypeEnum = pgEnum("measure_type", [
|
||||
// Heating systems
|
||||
"air_source_heat_pump",
|
||||
"boiler_upgrade",
|
||||
"high_heat_retention_storage_heaters",
|
||||
"secondary_heating",
|
||||
|
||||
// Heating controls
|
||||
"roomstat_programmer_trvs",
|
||||
"time_temperature_zone_control",
|
||||
"cylinder_thermostat",
|
||||
|
||||
// Insulation
|
||||
"cavity_wall_insulation",
|
||||
"extension_cavity_wall_insulation",
|
||||
"external_wall_insulation",
|
||||
"internal_wall_insulation",
|
||||
"loft_insulation",
|
||||
"flat_roof_insulation",
|
||||
"room_roof_insulation",
|
||||
"solid_floor_insulation",
|
||||
"suspended_floor_insulation",
|
||||
|
||||
// Windows & doors
|
||||
"double_glazing",
|
||||
"secondary_glazing",
|
||||
"draught_proofing",
|
||||
|
||||
// Ventilation
|
||||
"mechanical_ventilation",
|
||||
|
||||
// Lighting
|
||||
"low_energy_lighting",
|
||||
|
||||
// Renewables
|
||||
"solar_pv",
|
||||
|
||||
// Other fabric / hot water
|
||||
"hot_water_tank_insulation",
|
||||
"sealing_open_fireplace",
|
||||
]);
|
||||
|
||||
export const recommendation = pgTable(
|
||||
"recommendation",
|
||||
{
|
||||
|
|
@ -266,6 +310,44 @@ export const scenario = pgTable("scenario", {
|
|||
valuationReturnOnInvestment: text("valuation_return_on_investment"),
|
||||
});
|
||||
|
||||
export const installedMeasure = pgTable(
|
||||
"installed_measure",
|
||||
{
|
||||
id: bigserial("id", { mode: "bigint" }).primaryKey(),
|
||||
|
||||
uprn: bigint("uprn", { mode: "bigint" }).notNull(),
|
||||
|
||||
measureType: measureTypeEnum("measure_type").notNull(),
|
||||
installedAt: timestamp("installed_at").defaultNow(),
|
||||
|
||||
// Impacts
|
||||
sapPoints: real("sap_points"),
|
||||
carbonSavings: real("carbon_savings"), // tonnes CO₂e / yr
|
||||
kwhSavings: real("kwh_savings"), // kWh / yr
|
||||
billSavings: real("bill_savings"), // £ / yr
|
||||
heatDemandSavings: real("heat_demand_savings"),
|
||||
|
||||
//
|
||||
source: text("source"), // e.g. "EPC", "Survey", "Installer"
|
||||
|
||||
// Soft delete / supersession
|
||||
isActive: boolean("is_active").notNull().default(true),
|
||||
},
|
||||
(table) => [
|
||||
index("idx_installed_measure_uprn").on(table.uprn),
|
||||
|
||||
index("idx_installed_measure_uprn_active")
|
||||
.on(table.uprn)
|
||||
.where(sql`${table.isActive} = true`),
|
||||
|
||||
index("idx_installed_measure_measure_type").on(table.measureType),
|
||||
|
||||
index("idx_installed_measure_uprn_measure")
|
||||
.on(table.uprn, table.measureType)
|
||||
.where(sql`${table.isActive} = true`),
|
||||
]
|
||||
);
|
||||
|
||||
export type Plan = InferModel<typeof plan, "select">;
|
||||
export type Recommendation = InferModel<typeof recommendation, "select">;
|
||||
export type PlanRecommendations = InferModel<
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue