assessment-model/src/app/db/schema/materials.ts
2025-11-29 07:59:37 +00:00

130 lines
3.7 KiB
TypeScript

import { InferModel } from "drizzle-orm";
import {
bigserial,
text,
timestamp,
pgTable,
real,
pgEnum,
json,
boolean,
} from "drizzle-orm/pg-core";
export const MaterialType: [string, ...string[]] = [
"suspended_floor_insulation",
"solid_floor_insulation",
"external_wall_insulation",
"internal_wall_insulation",
"cavity_wall_insulation",
"mechanical_ventilation",
"loft_insulation",
"exposed_floor_insulation",
"flat_roof_insulation",
"room_roof_insulation",
"cavity_wall_extraction",
// Non insulation tasks
"iwi_wall_demolition",
"iwi_vapour_barrier",
"iwi_redecoration",
"suspended_floor_demolition",
"suspended_floor_redecoration",
"suspended_floor_vapour_barrier",
"solid_floor_demolition",
"solid_floor_preparation",
"solid_floor_vapour_barrier",
"solid_floor_redecoration",
"ewi_wall_demolition",
"ewi_wall_preparation",
"ewi_wall_redecoration",
"low_energy_lighting_installation",
"flat_roof_preparation",
"flat_roof_vapour_barrier",
"flat_roof_waterproofing",
// Windows
"windows_glazing",
"secondary_glazing",
"double_glazing",
// vents
"trickle_vent",
"door_undercut",
// solar
"solar_pv",
"solar_battery",
// scaffolding
"scaffolding",
// heating systems
"high_heat_retention_storage_heaters",
"air_source_heat_pump",
// Upgrade an exiting heating system
"boiler_upgrade",
// heating controls
"roomstat_programmer_trvs",
"time_temperature_zone_control",
// other
"sealing_fireplace",
];
export const materialTypeEnum = pgEnum("type", MaterialType);
export const DepthUnit: [string, ...string[]] = ["mm"];
export const depthUnitEnum = pgEnum("depth_unit", DepthUnit);
export const SizeUnit: [string, ...string[]] = ["kWp", "kW", "watt", "storey"];
export const sizeUnitEnum = pgEnum("size_unit", SizeUnit);
export const CostUnit: [string, ...string[]] = [
"gbp_sq_meter",
"gbp_per_unit",
"gbp_per_m2",
"gbp_per_m",
];
export const costUnitEnum = pgEnum("cost_unit", CostUnit);
export const RValueUnit: [string, ...string[]] = [
"square_meter_kelvin_per_watt",
];
export const rValueUnitEnum = pgEnum("r_value_unit", RValueUnit);
export const ThermalConductivityUnit: [string, ...string[]] = [
"watt_per_meter_kelvin",
];
export const thermalConductivityUnitEnum = pgEnum(
"thermal_conductivity_unit",
ThermalConductivityUnit
);
export const material = pgTable("material", {
id: bigserial("id", { mode: "bigint" }).primaryKey(),
type: materialTypeEnum("type").notNull(),
description: text("description").notNull(),
depth: json("depth").$type<number[]>(),
depth_unit: depthUnitEnum("depth_unit"),
costUnit: costUnitEnum("cost_unit"),
rValuePerMm: real("r_value_per_mm"),
rValueUnit: rValueUnitEnum("r_value_unit"),
thermalConductivity: real("thermal_conductivity"),
thermalConductivityUnit: thermalConductivityUnitEnum(
"thermal_conductivity_unit"
),
link: text("link"),
createdAt: timestamp("created_at").notNull().defaultNow(),
isActive: boolean("is_active").notNull().default(true),
prime_material_cost: real("prime_material_cost"),
material_cost: real("material_cost"),
labour_cost: real("labour_cost"),
labour_hours_per_unit: real("labour_hours_per_unit"),
plant_cost: real("plant_cost"),
total_cost: real("total_cost"),
cost: json("cost").$type<number[]>(),
notes: text("notes"),
isInstallerQuote: boolean("is_installer_quote").default(false),
innovationRate: real("innovation_rate").default(0),
size: real("size"),
// Can be null
sizeUnit: sizeUnitEnum("size_unit"),
includesScaffolding: boolean("includes_scaffolding").default(false),
includesBattery: boolean("includes_battery").default(false),
batterySize: real("battery_size"),
});
export type Material = InferModel<typeof material, "select">;