diff --git a/public/images/Alexandra-Road-Park.webp b/public/images/Alexandra-Road-Park.webp
new file mode 100644
index 0000000..e45af6c
Binary files /dev/null and b/public/images/Alexandra-Road-Park.webp differ
diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts
index e12c3ab..1975e6f 100644
--- a/src/app/api/auth/[...nextauth]/route.ts
+++ b/src/app/api/auth/[...nextauth]/route.ts
@@ -147,14 +147,24 @@ export const AuthOptions: NextAuthOptions = {
/**
* Persist dbId in the JWT so it’s available in sessions
*/
- async jwt({ token, user }) {
- if (user?.dbId) {
- token.dbId = user.dbId;
+ async jwt({ token, user: userFromLogin }) {
+ // Initial sign-in: attach DB fields
+ if (userFromLogin) {
+ const existing = await db.query.user.findFirst({
+ where: eq(users.email, userFromLogin.email!),
+ });
+ if (existing) {
+ token.onboarded = existing.onboarded;
+ }
+ } else if (token.email) {
+ // On subsequent calls, keep token synced from DB
+ const existing = await db.query.user.findFirst({
+ where: eq(users.email, token.email),
+ });
+ if (existing) {
+ token.onboarded = existing.onboarded;
+ }
}
-
- // Fetch onboarding status from user
- if (user?.onboarded !== undefined) token.onboarded = user.onboarded;
-
return token;
},
diff --git a/src/app/api/user/onboarded/route.ts b/src/app/api/user/onboarded/route.ts
new file mode 100644
index 0000000..eaed750
--- /dev/null
+++ b/src/app/api/user/onboarded/route.ts
@@ -0,0 +1,57 @@
+import { NextRequest, NextResponse } from "next/server";
+import { z } from "zod";
+import { db } from "@/app/db/db";
+import { user } from "@/app/db/schema/users";
+import { eq } from "drizzle-orm";
+import { getServerSession } from "next-auth";
+import { AuthOptions } from "@/app/api/auth/[...nextauth]/route";
+
+const OnboardedSchema = z.object({
+ onboarded: z.boolean(),
+});
+
+export async function PATCH(req: NextRequest) {
+ try {
+ const session = await getServerSession(AuthOptions);
+ if (!session?.user?.email) {
+ return new NextResponse(JSON.stringify({ msg: "Unauthenticated" }), {
+ status: 401,
+ });
+ }
+
+ const body = await req.json();
+ const { onboarded } = OnboardedSchema.parse(body);
+
+ const existingUser = await db.query.user.findFirst({
+ where: eq(user.email, session.user.email),
+ });
+ if (!existingUser) {
+ return new NextResponse(JSON.stringify({ msg: "User not found" }), {
+ status: 404,
+ });
+ }
+
+ await db
+ .update(user)
+ .set({ onboarded, updatedAt: new Date() })
+ .where(eq(user.id, existingUser.id));
+
+ return new NextResponse(
+ JSON.stringify({ msg: "User marked as onboarded" }),
+ { status: 200 }
+ );
+ } catch (err) {
+ console.error("Error updating onboarded flag:", err);
+ if (err instanceof z.ZodError) {
+ return new NextResponse(
+ JSON.stringify({ msg: "Invalid input", errors: err.flatten() }),
+ {
+ status: 400,
+ }
+ );
+ }
+ return new NextResponse(JSON.stringify({ msg: "Server error" }), {
+ status: 500,
+ });
+ }
+}
diff --git a/src/app/api/user/profile/route.ts b/src/app/api/user/profile/route.ts
new file mode 100644
index 0000000..218426b
--- /dev/null
+++ b/src/app/api/user/profile/route.ts
@@ -0,0 +1,143 @@
+import { NextRequest, NextResponse } from "next/server";
+import { z } from "zod";
+import { db } from "@/app/db/db";
+import { userProfiles, user } from "@/app/db/schema/users";
+import { eq } from "drizzle-orm";
+import { getServerSession } from "next-auth";
+import { AuthOptions } from "@/app/api/auth/[...nextauth]/route";
+
+const UserProfileSchema = z.object({
+ firstName: z.string().min(1),
+ lastName: z.string().min(1),
+ userType: z.enum([
+ "private_landlord",
+ "private_tenant",
+ "social_landlord",
+ "social_tenant",
+ "homeowner",
+ "other",
+ ]),
+ propertyCount: z
+ .enum([
+ "1",
+ "2–5",
+ "6–20",
+ "21+",
+ "1–50",
+ "51–100",
+ "101–300",
+ "301–1000",
+ "1000+",
+ ])
+ .optional(),
+ goals: z
+ .array(
+ z.enum([
+ "access_funding",
+ "net_zero",
+ "improve_condition",
+ "save_money",
+ "other",
+ ])
+ )
+ .min(1),
+ referralSource: z.enum([
+ "search",
+ "social_media",
+ "NRLA",
+ "partner",
+ "word_of_mouth",
+ "other",
+ ]),
+ nrlaMembershipId: z.string().optional(),
+ marketingOptIn: z.boolean().optional(),
+ acceptedPrivacy: z.boolean().refine((v) => v === true, {
+ message: "You must accept our privacy policy to continue",
+ }),
+});
+
+export async function POST(req: NextRequest) {
+ try {
+ const session = await getServerSession(AuthOptions);
+ if (!session?.user?.email) {
+ return new NextResponse(JSON.stringify({ msg: "Unauthenticated" }), {
+ status: 401,
+ });
+ }
+
+ const body = await req.json();
+ const parsed = UserProfileSchema.parse(body);
+
+ // 1️⃣ Get user from DB
+ const existingUser = await db.query.user.findFirst({
+ where: eq(user.email, session.user.email),
+ });
+ if (!existingUser) {
+ return new NextResponse(JSON.stringify({ msg: "User not found" }), {
+ status: 404,
+ });
+ }
+
+ // 2️⃣ Check if profile already exists
+ const existingProfile = await db.query.userProfiles.findFirst({
+ where: eq(userProfiles.userId, existingUser.id),
+ });
+
+ // Timestamps for policy and marketing
+ const now = new Date();
+ const acceptedPrivacyAt = parsed.acceptedPrivacy ? now : null;
+ const marketingOptInAt = parsed.marketingOptIn ? now : null;
+
+ if (existingProfile) {
+ await db
+ .update(userProfiles)
+ .set({
+ firstName: parsed.firstName,
+ lastName: parsed.lastName,
+ userType: parsed.userType,
+ propertyCount: parsed.propertyCount,
+ goals: parsed.goals,
+ referralSource: parsed.referralSource,
+ nrlaMembershipId: parsed.nrlaMembershipId,
+ marketingOptIn: parsed.marketingOptIn ?? false,
+ acceptedPrivacy: parsed.acceptedPrivacy,
+ acceptedPrivacyAt,
+ marketingOptInAt,
+ updatedAt: now,
+ })
+ .where(eq(userProfiles.userId, existingUser.id));
+ } else {
+ await db.insert(userProfiles).values({
+ userId: existingUser.id,
+ firstName: parsed.firstName,
+ lastName: parsed.lastName,
+ userType: parsed.userType,
+ propertyCount: parsed.propertyCount,
+ goals: parsed.goals,
+ referralSource: parsed.referralSource,
+ nrlaMembershipId: parsed.nrlaMembershipId,
+ marketingOptIn: parsed.marketingOptIn ?? false,
+ acceptedPrivacy: parsed.acceptedPrivacy,
+ acceptedPrivacyAt,
+ marketingOptInAt,
+ });
+ }
+
+ return new NextResponse(JSON.stringify({ msg: "Profile saved" }), {
+ status: 200,
+ });
+ } catch (err) {
+ console.error("Error saving user profile:", err);
+ if (err instanceof z.ZodError) {
+ return new NextResponse(
+ JSON.stringify({ msg: "Invalid input", errors: err.flatten() }),
+ {
+ status: 400,
+ }
+ );
+ }
+ return new NextResponse(JSON.stringify({ msg: "Server error" }), {
+ status: 500,
+ });
+ }
+}
diff --git a/src/app/db/db.ts b/src/app/db/db.ts
index 8798282..fc9d118 100644
--- a/src/app/db/db.ts
+++ b/src/app/db/db.ts
@@ -9,6 +9,7 @@ import * as solarSchema from "@/app/db/schema/solar";
import * as EnergyAssessmentsSchema from "@/app/db/schema/energy_assessments";
import * as FundingSchema from "@/app/db/schema/funding";
import * as Relations from "@/app/db/schema/relations";
+import * as Users from "@/app/db/schema/users";
export const pool = new Pool({
host: process.env.DB_HOST,
@@ -29,6 +30,7 @@ const schema = {
...Relations,
...EnergyAssessmentsSchema,
...FundingSchema,
+ ...Users,
};
export const db = drizzle(pool, {
diff --git a/src/app/db/migrations/0118_lazy_gabe_jones.sql b/src/app/db/migrations/0118_lazy_gabe_jones.sql
new file mode 100644
index 0000000..6da1cba
--- /dev/null
+++ b/src/app/db/migrations/0118_lazy_gabe_jones.sql
@@ -0,0 +1,22 @@
+CREATE TYPE "public"."user_profiles_property_count" AS ENUM('1', '2–5', '6–20', '21+', '1–50', '51–100', '101–300', '301–1000', '1000+');--> statement-breakpoint
+CREATE TYPE "public"."user_profiles_referral_source" AS ENUM('search', 'social_media', 'NRLA', 'partner', 'word_of_mouth', 'other');--> statement-breakpoint
+CREATE TYPE "public"."user_profiles_user_type" AS ENUM('private_landlord', 'private_tenant', 'social_landlord', 'social_tenant', 'homeowner', 'other');--> statement-breakpoint
+CREATE TABLE "user_profiles" (
+ "id" bigserial PRIMARY KEY NOT NULL,
+ "user_id" bigint NOT NULL,
+ "user_type" "user_profiles_user_type" NOT NULL,
+ "property_count" "user_profiles_property_count",
+ "goals" json,
+ "referral_source" "user_profiles_referral_source",
+ "nrla_membership_id" varchar(255),
+ "accepted_privacy" boolean DEFAULT false NOT NULL,
+ "accepted_privacy_at" timestamp (6) with time zone,
+ "marketing_opt_in" boolean DEFAULT false,
+ "marketing_opt_in_at" timestamp (6) with time zone,
+ "first_name" text,
+ "last_name" text,
+ "created_at" timestamp (6) with time zone DEFAULT now() NOT NULL,
+ "updated_at" timestamp (6) with time zone DEFAULT now() NOT NULL
+);
+--> statement-breakpoint
+ALTER TABLE "user_profiles" ADD CONSTRAINT "user_profiles_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
\ No newline at end of file
diff --git a/src/app/db/migrations/meta/0118_snapshot.json b/src/app/db/migrations/meta/0118_snapshot.json
new file mode 100644
index 0000000..36e7ad4
--- /dev/null
+++ b/src/app/db/migrations/meta/0118_snapshot.json
@@ -0,0 +1,3750 @@
+{
+ "id": "63ef9be0-1df9-444e-b384-5c5f353f88da",
+ "prevId": "a327a64c-a85a-408a-b460-8e53f65963d6",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.energy_assessments": {
+ "name": "energy_assessments",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "uprn": {
+ "name": "uprn",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "uprn_source": {
+ "name": "uprn_source",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "property_type": {
+ "name": "property_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "building_reference_number": {
+ "name": "building_reference_number",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "current_energy_efficiency": {
+ "name": "current_energy_efficiency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "current_energy_rating": {
+ "name": "current_energy_rating",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "address1": {
+ "name": "address1",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "address2": {
+ "name": "address2",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "address3": {
+ "name": "address3",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "posttown": {
+ "name": "posttown",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "postcode": {
+ "name": "postcode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "address": {
+ "name": "address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "county": {
+ "name": "county",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "constituency": {
+ "name": "constituency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "constituency_label": {
+ "name": "constituency_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "low_energy_fixed_light_count": {
+ "name": "low_energy_fixed_light_count",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "construction_age_band": {
+ "name": "construction_age_band",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mainheat_energy_eff": {
+ "name": "mainheat_energy_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "windows_env_eff": {
+ "name": "windows_env_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lighting_energy_eff": {
+ "name": "lighting_energy_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "environment_impact_potential": {
+ "name": "environment_impact_potential",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mainheatcont_description": {
+ "name": "mainheatcont_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sheating_energy_eff": {
+ "name": "sheating_energy_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "local_authority": {
+ "name": "local_authority",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "local_authority_label": {
+ "name": "local_authority_label",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "fixed_lighting_outlets_count": {
+ "name": "fixed_lighting_outlets_count",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "energy_tariff": {
+ "name": "energy_tariff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mechanical_ventilation": {
+ "name": "mechanical_ventilation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "solar_water_heating_flag": {
+ "name": "solar_water_heating_flag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "co2_emissions_potential": {
+ "name": "co2_emissions_potential",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "number_heated_rooms": {
+ "name": "number_heated_rooms",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "floor_description": {
+ "name": "floor_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "energy_consumption_potential": {
+ "name": "energy_consumption_potential",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "built_form": {
+ "name": "built_form",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "number_open_fireplaces": {
+ "name": "number_open_fireplaces",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "windows_description": {
+ "name": "windows_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "glazed_area": {
+ "name": "glazed_area",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "inspection_date": {
+ "name": "inspection_date",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mains_gas_flag": {
+ "name": "mains_gas_flag",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "co2_emiss_curr_per_floor_area": {
+ "name": "co2_emiss_curr_per_floor_area",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "heat_loss_corridor": {
+ "name": "heat_loss_corridor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "unheated_corridor_length": {
+ "name": "unheated_corridor_length",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "flat_storey_count": {
+ "name": "flat_storey_count",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "roof_energy_eff": {
+ "name": "roof_energy_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "total_floor_area": {
+ "name": "total_floor_area",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "environment_impact_current": {
+ "name": "environment_impact_current",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "roof_description": {
+ "name": "roof_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "floor_energy_eff": {
+ "name": "floor_energy_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "number_habitable_rooms": {
+ "name": "number_habitable_rooms",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hot_water_env_eff": {
+ "name": "hot_water_env_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mainheatc_energy_eff": {
+ "name": "mainheatc_energy_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "main_fuel": {
+ "name": "main_fuel",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lighting_env_eff": {
+ "name": "lighting_env_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "windows_energy_eff": {
+ "name": "windows_energy_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "floor_env_eff": {
+ "name": "floor_env_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sheating_env_eff": {
+ "name": "sheating_env_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lighting_description": {
+ "name": "lighting_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "roof_env_eff": {
+ "name": "roof_env_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "walls_energy_eff": {
+ "name": "walls_energy_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "photo_supply": {
+ "name": "photo_supply",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lighting_cost_potential": {
+ "name": "lighting_cost_potential",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mainheat_env_eff": {
+ "name": "mainheat_env_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "multi_glaze_proportion": {
+ "name": "multi_glaze_proportion",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "main_heating_controls": {
+ "name": "main_heating_controls",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "flat_top_storey": {
+ "name": "flat_top_storey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "secondheat_description": {
+ "name": "secondheat_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "walls_env_eff": {
+ "name": "walls_env_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "transaction_type": {
+ "name": "transaction_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "extension_count": {
+ "name": "extension_count",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mainheatc_env_eff": {
+ "name": "mainheatc_env_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lmk_key": {
+ "name": "lmk_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "wind_turbine_count": {
+ "name": "wind_turbine_count",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "tenure": {
+ "name": "tenure",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "floor_level": {
+ "name": "floor_level",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "potential_energy_efficiency": {
+ "name": "potential_energy_efficiency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "potential_energy_rating": {
+ "name": "potential_energy_rating",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hot_water_energy_eff": {
+ "name": "hot_water_energy_eff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "low_energy_lighting": {
+ "name": "low_energy_lighting",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "walls_description": {
+ "name": "walls_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hotwater_description": {
+ "name": "hotwater_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "co2_emissions_current": {
+ "name": "co2_emissions_current",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "heating_cost_current": {
+ "name": "heating_cost_current",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "heating_cost_potential": {
+ "name": "heating_cost_potential",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hot_water_cost_current": {
+ "name": "hot_water_cost_current",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "hot_water_cost_potential": {
+ "name": "hot_water_cost_potential",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lighting_cost_current": {
+ "name": "lighting_cost_current",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "energy_consumption_current": {
+ "name": "energy_consumption_current",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lodgement_date": {
+ "name": "lodgement_date",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lodgement_datetime": {
+ "name": "lodgement_datetime",
+ "type": "timestamp (6)",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "mainheat_description": {
+ "name": "mainheat_description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "floor_height": {
+ "name": "floor_height",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "glazed_type": {
+ "name": "glazed_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "file_location": {
+ "name": "file_location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "surveyor_name": {
+ "name": "surveyor_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "surveyor_company": {
+ "name": "surveyor_company",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "space_heating_kwh": {
+ "name": "space_heating_kwh",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "water_heating_kwh": {
+ "name": "water_heating_kwh",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "number_of_doors": {
+ "name": "number_of_doors",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "number_of_insulated_doors": {
+ "name": "number_of_insulated_doors",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "number_of_floors": {
+ "name": "number_of_floors",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "insulation_wall_area": {
+ "name": "insulation_wall_area",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "heat_loss_perimeter": {
+ "name": "heat_loss_perimeter",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "party_wall_length": {
+ "name": "party_wall_length",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "perimeter": {
+ "name": "perimeter",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rooms_with_bath_and_or_shower": {
+ "name": "rooms_with_bath_and_or_shower",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rooms_with_mixer_shower_no_bath": {
+ "name": "rooms_with_mixer_shower_no_bath",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "room_with_bath_and_mixer_shower": {
+ "name": "room_with_bath_and_mixer_shower",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "percent_draftproofed": {
+ "name": "percent_draftproofed",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "has_hot_water_cylinder": {
+ "name": "has_hot_water_cylinder",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cylinder_insulation_type": {
+ "name": "cylinder_insulation_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cylinder_insulation_thickness": {
+ "name": "cylinder_insulation_thickness",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cylinder_thermostat": {
+ "name": "cylinder_thermostat",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "main_dwelling_ground_floor_area": {
+ "name": "main_dwelling_ground_floor_area",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number_of_windows": {
+ "name": "number_of_windows",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "windows_area": {
+ "name": "windows_area",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.energy_assessment_documents": {
+ "name": "energy_assessment_documents",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "uprn": {
+ "name": "uprn",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "energy_assessment_id": {
+ "name": "energy_assessment_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_type": {
+ "name": "document_type",
+ "type": "document_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "document_location": {
+ "name": "document_location",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "uploaded_at": {
+ "name": "uploaded_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "scenario_id": {
+ "name": "scenario_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "energy_assessment_documents_energy_assessment_id_energy_assessments_id_fk": {
+ "name": "energy_assessment_documents_energy_assessment_id_energy_assessments_id_fk",
+ "tableFrom": "energy_assessment_documents",
+ "tableTo": "energy_assessments",
+ "columnsFrom": [
+ "energy_assessment_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "energy_assessment_documents_scenario_id_energy_assessment_scenarios_id_fk": {
+ "name": "energy_assessment_documents_scenario_id_energy_assessment_scenarios_id_fk",
+ "tableFrom": "energy_assessment_documents",
+ "tableTo": "energy_assessment_scenarios",
+ "columnsFrom": [
+ "scenario_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.energy_assessment_scenarios": {
+ "name": "energy_assessment_scenarios",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "scenario_name": {
+ "name": "scenario_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "energy_assessment_id": {
+ "name": "energy_assessment_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "energy_assessment_scenarios_energy_assessment_id_energy_assessments_id_fk": {
+ "name": "energy_assessment_scenarios_energy_assessment_id_energy_assessments_id_fk",
+ "tableFrom": "energy_assessment_scenarios",
+ "tableTo": "energy_assessments",
+ "columnsFrom": [
+ "energy_assessment_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.funding_package": {
+ "name": "funding_package",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "plan_id": {
+ "name": "plan_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scheme": {
+ "name": "scheme",
+ "type": "scheme",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "project_funding": {
+ "name": "project_funding",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_uplift": {
+ "name": "total_uplift",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "full_project_score": {
+ "name": "full_project_score",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "partial_project_score": {
+ "name": "partial_project_score",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uplift_project_score": {
+ "name": "uplift_project_score",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "funding_package_plan_id_plan_id_fk": {
+ "name": "funding_package_plan_id_plan_id_fk",
+ "tableFrom": "funding_package",
+ "tableTo": "plan",
+ "columnsFrom": [
+ "plan_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.funding_package_measures": {
+ "name": "funding_package_measures",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "funding_package_id": {
+ "name": "funding_package_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "measure": {
+ "name": "measure",
+ "type": "type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "material_id": {
+ "name": "material_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "innovation_uplift": {
+ "name": "innovation_uplift",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "partial_project_score": {
+ "name": "partial_project_score",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "uplift_project_score": {
+ "name": "uplift_project_score",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "funding_package_measures_funding_package_id_funding_package_id_fk": {
+ "name": "funding_package_measures_funding_package_id_funding_package_id_fk",
+ "tableFrom": "funding_package_measures",
+ "tableTo": "funding_package",
+ "columnsFrom": [
+ "funding_package_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "funding_package_measures_material_id_material_id_fk": {
+ "name": "funding_package_measures_material_id_material_id_fk",
+ "tableFrom": "funding_package_measures",
+ "tableTo": "material",
+ "columnsFrom": [
+ "material_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.material": {
+ "name": "material",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "depth": {
+ "name": "depth",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "depth_unit": {
+ "name": "depth_unit",
+ "type": "depth_unit",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_unit": {
+ "name": "cost_unit",
+ "type": "cost_unit",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "r_value_per_mm": {
+ "name": "r_value_per_mm",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "r_value_unit": {
+ "name": "r_value_unit",
+ "type": "r_value_unit",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "thermal_conductivity": {
+ "name": "thermal_conductivity",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "thermal_conductivity_unit": {
+ "name": "thermal_conductivity_unit",
+ "type": "thermal_conductivity_unit",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "link": {
+ "name": "link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "is_active": {
+ "name": "is_active",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": true
+ },
+ "prime_material_cost": {
+ "name": "prime_material_cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "material_cost": {
+ "name": "material_cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labour_cost": {
+ "name": "labour_cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labour_hours_per_unit": {
+ "name": "labour_hours_per_unit",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "plant_cost": {
+ "name": "plant_cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_cost": {
+ "name": "total_cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost": {
+ "name": "cost",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_installer_quote": {
+ "name": "is_installer_quote",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "innovation_rate": {
+ "name": "innovation_rate",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 0
+ },
+ "size": {
+ "name": "size",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "size_unit": {
+ "name": "size_unit",
+ "type": "size_unit",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "includes_scaffolding": {
+ "name": "includes_scaffolding",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "includes_battery": {
+ "name": "includes_battery",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "battery_size": {
+ "name": "battery_size",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.portfolio": {
+ "name": "portfolio",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "budget": {
+ "name": "budget",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "goal": {
+ "name": "goal",
+ "type": "goal",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost": {
+ "name": "cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number_of_properties": {
+ "name": "number_of_properties",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "co2_equivalent_savings": {
+ "name": "co2_equivalent_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_savings": {
+ "name": "energy_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_cost_savings": {
+ "name": "energy_cost_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "property_valuation_increase": {
+ "name": "property_valuation_increase",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rental_yield_increase": {
+ "name": "rental_yield_increase",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_work_hours": {
+ "name": "total_work_hours",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labour_days": {
+ "name": "labour_days",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "epc_breakdown_pre_retrofit": {
+ "name": "epc_breakdown_pre_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "epc_breakdown_post_retrofit": {
+ "name": "epc_breakdown_post_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "n_units_to_retrofit": {
+ "name": "n_units_to_retrofit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "co2_per_unit_pre_retrofit": {
+ "name": "co2_per_unit_pre_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "co2_per_unit_post_retrofit": {
+ "name": "co2_per_unit_post_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_bill_per_unit_pre_retrofit": {
+ "name": "energy_bill_per_unit_pre_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_bill_per_unit_post_retrofit": {
+ "name": "energy_bill_per_unit_post_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_consumption_per_unit_pre_retrofit": {
+ "name": "energy_consumption_per_unit_pre_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_consumption_per_unit_post_retrofit": {
+ "name": "energy_consumption_per_unit_post_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "valuation_improvement_per_unit": {
+ "name": "valuation_improvement_per_unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_per_unit": {
+ "name": "cost_per_unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_per_co2_saved": {
+ "name": "cost_per_co2_saved",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_per_sap_point": {
+ "name": "cost_per_sap_point",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "valuation_return_on_investment": {
+ "name": "valuation_return_on_investment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.portfolioUsers": {
+ "name": "portfolioUsers",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "portfolio_id": {
+ "name": "portfolio_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "role": {
+ "name": "role",
+ "type": "role",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "portfolioUsers_user_id_user_id_fk": {
+ "name": "portfolioUsers_user_id_user_id_fk",
+ "tableFrom": "portfolioUsers",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "portfolioUsers_portfolio_id_portfolio_id_fk": {
+ "name": "portfolioUsers_portfolio_id_portfolio_id_fk",
+ "tableFrom": "portfolioUsers",
+ "tableTo": "portfolio",
+ "columnsFrom": [
+ "portfolio_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.non_intrusive_survey": {
+ "name": "non_intrusive_survey",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "uprn": {
+ "name": "uprn",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "survey_date": {
+ "name": "survey_date",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "surveyor": {
+ "name": "surveyor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.non_intrusive_survey_notes": {
+ "name": "non_intrusive_survey_notes",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "survey_id": {
+ "name": "survey_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "note": {
+ "name": "note",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "non_intrusive_survey_notes_survey_id_non_intrusive_survey_id_fk": {
+ "name": "non_intrusive_survey_notes_survey_id_non_intrusive_survey_id_fk",
+ "tableFrom": "non_intrusive_survey_notes",
+ "tableTo": "non_intrusive_survey",
+ "columnsFrom": [
+ "survey_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.property": {
+ "name": "property",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "portfolio_id": {
+ "name": "portfolio_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "creation_status": {
+ "name": "creation_status",
+ "type": "creation_status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "uprn": {
+ "name": "uprn",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "building_reference_number": {
+ "name": "building_reference_number",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "address": {
+ "name": "address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "postcode": {
+ "name": "postcode",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "has_pre_condition_report": {
+ "name": "has_pre_condition_report",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "has_recommendations": {
+ "name": "has_recommendations",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "property_type": {
+ "name": "property_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "built_form": {
+ "name": "built_form",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "local_authority": {
+ "name": "local_authority",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "constituency": {
+ "name": "constituency",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number_of_rooms": {
+ "name": "number_of_rooms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "year_built": {
+ "name": "year_built",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tenure": {
+ "name": "tenure",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "current_epc_rating": {
+ "name": "current_epc_rating",
+ "type": "epc",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "current_sap_points": {
+ "name": "current_sap_points",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "current_valuation": {
+ "name": "current_valuation",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "property_portfolio_id_portfolio_id_fk": {
+ "name": "property_portfolio_id_portfolio_id_fk",
+ "tableFrom": "property",
+ "tableTo": "portfolio",
+ "columnsFrom": [
+ "portfolio_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.property_details_epc": {
+ "name": "property_details_epc",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "property_id": {
+ "name": "property_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "portfolio_id": {
+ "name": "portfolio_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "full_address": {
+ "name": "full_address",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_floor_area": {
+ "name": "total_floor_area",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "walls": {
+ "name": "walls",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "walls_rating": {
+ "name": "walls_rating",
+ "type": "smallint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "roof": {
+ "name": "roof",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "roof_rating": {
+ "name": "roof_rating",
+ "type": "smallint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "floor": {
+ "name": "floor",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "floor_rating": {
+ "name": "floor_rating",
+ "type": "smallint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "windows": {
+ "name": "windows",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "windows_rating": {
+ "name": "windows_rating",
+ "type": "smallint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heating": {
+ "name": "heating",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heating_rating": {
+ "name": "heating_rating",
+ "type": "smallint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heating_controls": {
+ "name": "heating_controls",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heating_controls_rating": {
+ "name": "heating_controls_rating",
+ "type": "smallint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hot_water": {
+ "name": "hot_water",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hot_water_rating": {
+ "name": "hot_water_rating",
+ "type": "smallint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lighting": {
+ "name": "lighting",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lighting_rating": {
+ "name": "lighting_rating",
+ "type": "smallint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mainfuel": {
+ "name": "mainfuel",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ventilation": {
+ "name": "ventilation",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "solar_pv": {
+ "name": "solar_pv",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "solar_hot_water": {
+ "name": "solar_hot_water",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "wind_turbine": {
+ "name": "wind_turbine",
+ "type": "smallint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "floor_height": {
+ "name": "floor_height",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number_heated_rooms": {
+ "name": "number_heated_rooms",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heat_loss_corridor": {
+ "name": "heat_loss_corridor",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "unheated_corridor_length": {
+ "name": "unheated_corridor_length",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number_of_open_fireplaces": {
+ "name": "number_of_open_fireplaces",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number_of_extensions": {
+ "name": "number_of_extensions",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number_of_storeys": {
+ "name": "number_of_storeys",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "mains_gas": {
+ "name": "mains_gas",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_tariff": {
+ "name": "energy_tariff",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "primary_energy_consumption": {
+ "name": "primary_energy_consumption",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "co2_emissions": {
+ "name": "co2_emissions",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "current_energy_demand": {
+ "name": "current_energy_demand",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "current_energy_demand_heating_hotwater": {
+ "name": "current_energy_demand_heating_hotwater",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "estimated": {
+ "name": "estimated",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "heating_cost_current": {
+ "name": "heating_cost_current",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "hot_water_cost_current": {
+ "name": "hot_water_cost_current",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lighting_cost_current": {
+ "name": "lighting_cost_current",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "appliances_cost_current": {
+ "name": "appliances_cost_current",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gas_standing_charge": {
+ "name": "gas_standing_charge",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "electricity_standing_charge": {
+ "name": "electricity_standing_charge",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "property_details_epc_property_id_property_id_fk": {
+ "name": "property_details_epc_property_id_property_id_fk",
+ "tableFrom": "property_details_epc",
+ "tableTo": "property",
+ "columnsFrom": [
+ "property_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "property_details_epc_portfolio_id_portfolio_id_fk": {
+ "name": "property_details_epc_portfolio_id_portfolio_id_fk",
+ "tableFrom": "property_details_epc",
+ "tableTo": "portfolio",
+ "columnsFrom": [
+ "portfolio_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.property_details_meter": {
+ "name": "property_details_meter",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "uprn": {
+ "name": "uprn",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_supplier": {
+ "name": "energy_supplier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "gas_supplier": {
+ "name": "gas_supplier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "meter_reading_total": {
+ "name": "meter_reading_total",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "meter_reading_electricity": {
+ "name": "meter_reading_electricity",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "meter_reading_gas": {
+ "name": "meter_reading_gas",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.property_details_spatial": {
+ "name": "property_details_spatial",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "uprn": {
+ "name": "uprn",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "x_coordinate": {
+ "name": "x_coordinate",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "y_coordinate": {
+ "name": "y_coordinate",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "latitude": {
+ "name": "latitude",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "longitude": {
+ "name": "longitude",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "conservation_status": {
+ "name": "conservation_status",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_listed_building": {
+ "name": "is_listed_building",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_heritage_building": {
+ "name": "is_heritage_building",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.property_targets": {
+ "name": "property_targets",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "property_id": {
+ "name": "property_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "portfolio_id": {
+ "name": "portfolio_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "epc": {
+ "name": "epc",
+ "type": "epc",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heat_demand": {
+ "name": "heat_demand",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "property_targets_property_id_property_id_fk": {
+ "name": "property_targets_property_id_property_id_fk",
+ "tableFrom": "property_targets",
+ "tableTo": "property",
+ "columnsFrom": [
+ "property_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "property_targets_portfolio_id_portfolio_id_fk": {
+ "name": "property_targets_portfolio_id_portfolio_id_fk",
+ "tableFrom": "property_targets",
+ "tableTo": "portfolio",
+ "columnsFrom": [
+ "portfolio_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plan": {
+ "name": "plan",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "portfolio_id": {
+ "name": "portfolio_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "property_id": {
+ "name": "property_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scenario_id": {
+ "name": "scenario_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "valuation_increase_lower_bound": {
+ "name": "valuation_increase_lower_bound",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "valuation_increase_upper_bound": {
+ "name": "valuation_increase_upper_bound",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "valuation_increase_average": {
+ "name": "valuation_increase_average",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "plan_portfolio_id_portfolio_id_fk": {
+ "name": "plan_portfolio_id_portfolio_id_fk",
+ "tableFrom": "plan",
+ "tableTo": "portfolio",
+ "columnsFrom": [
+ "portfolio_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "plan_property_id_property_id_fk": {
+ "name": "plan_property_id_property_id_fk",
+ "tableFrom": "plan",
+ "tableTo": "property",
+ "columnsFrom": [
+ "property_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "plan_scenario_id_scenario_id_fk": {
+ "name": "plan_scenario_id_scenario_id_fk",
+ "tableFrom": "plan",
+ "tableTo": "scenario",
+ "columnsFrom": [
+ "scenario_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.plan_recommendations": {
+ "name": "plan_recommendations",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "plan_id": {
+ "name": "plan_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "recommendation_id": {
+ "name": "recommendation_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "plan_recommendations_plan_id_plan_id_fk": {
+ "name": "plan_recommendations_plan_id_plan_id_fk",
+ "tableFrom": "plan_recommendations",
+ "tableTo": "plan",
+ "columnsFrom": [
+ "plan_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "plan_recommendations_recommendation_id_recommendation_id_fk": {
+ "name": "plan_recommendations_recommendation_id_recommendation_id_fk",
+ "tableFrom": "plan_recommendations",
+ "tableTo": "recommendation",
+ "columnsFrom": [
+ "recommendation_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.recommendation": {
+ "name": "recommendation",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "property_id": {
+ "name": "property_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "measure_type": {
+ "name": "measure_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "estimated_cost": {
+ "name": "estimated_cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contingency_cost": {
+ "name": "contingency_cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "default": {
+ "name": "default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "starting_u_value": {
+ "name": "starting_u_value",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "new_u_value": {
+ "name": "new_u_value",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sap_points": {
+ "name": "sap_points",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "heat_demand": {
+ "name": "heat_demand",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "kwh_savings": {
+ "name": "kwh_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "co2_equivalent_savings": {
+ "name": "co2_equivalent_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_savings": {
+ "name": "energy_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_cost_savings": {
+ "name": "energy_cost_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "property_valuation_increase": {
+ "name": "property_valuation_increase",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rental_yield_increase": {
+ "name": "rental_yield_increase",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_work_hours": {
+ "name": "total_work_hours",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labour_days": {
+ "name": "labour_days",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "already_installed": {
+ "name": "already_installed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "recommendation_property_id_property_id_fk": {
+ "name": "recommendation_property_id_property_id_fk",
+ "tableFrom": "recommendation",
+ "tableTo": "property",
+ "columnsFrom": [
+ "property_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.recommendation_materials": {
+ "name": "recommendation_materials",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "recommendation_id": {
+ "name": "recommendation_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "material_id": {
+ "name": "material_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "depth": {
+ "name": "depth",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quantity": {
+ "name": "quantity",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "quantity_unit": {
+ "name": "quantity_unit",
+ "type": "unit_quantity",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "estimated_cost": {
+ "name": "estimated_cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "recommendation_materials_recommendation_id_recommendation_id_fk": {
+ "name": "recommendation_materials_recommendation_id_recommendation_id_fk",
+ "tableFrom": "recommendation_materials",
+ "tableTo": "recommendation",
+ "columnsFrom": [
+ "recommendation_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ },
+ "recommendation_materials_material_id_material_id_fk": {
+ "name": "recommendation_materials_material_id_material_id_fk",
+ "tableFrom": "recommendation_materials",
+ "tableTo": "material",
+ "columnsFrom": [
+ "material_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.scenario": {
+ "name": "scenario",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "budget": {
+ "name": "budget",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "portfolio_id": {
+ "name": "portfolio_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "housing_type": {
+ "name": "housing_type",
+ "type": "housing_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "goal": {
+ "name": "goal",
+ "type": "goal",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "goal_value": {
+ "name": "goal_value",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "ashp_cop": {
+ "name": "ashp_cop",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false,
+ "default": 2.8
+ },
+ "trigger_file_path": {
+ "name": "trigger_file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "already_installed_file_path": {
+ "name": "already_installed_file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "patches_file_path": {
+ "name": "patches_file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "non_invasive_recommendations_file_path": {
+ "name": "non_invasive_recommendations_file_path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exclusions": {
+ "name": "exclusions",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "multi_plan": {
+ "name": "multi_plan",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "cost": {
+ "name": "cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "contingency": {
+ "name": "contingency",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "funding": {
+ "name": "funding",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_work_hours": {
+ "name": "total_work_hours",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_savings": {
+ "name": "energy_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "co2_equivalent_savings": {
+ "name": "co2_equivalent_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_cost_savings": {
+ "name": "energy_cost_savings",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "property_valuation_increase": {
+ "name": "property_valuation_increase",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "labour_days": {
+ "name": "labour_days",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "epc_breakdown_pre_retrofit": {
+ "name": "epc_breakdown_pre_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "epc_breakdown_post_retrofit": {
+ "name": "epc_breakdown_post_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "number_of_properties": {
+ "name": "number_of_properties",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "n_units_to_retrofit": {
+ "name": "n_units_to_retrofit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "co2_per_unit_pre_retrofit": {
+ "name": "co2_per_unit_pre_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "co2_per_unit_post_retrofit": {
+ "name": "co2_per_unit_post_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_bill_per_unit_pre_retrofit": {
+ "name": "energy_bill_per_unit_pre_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_bill_per_unit_post_retrofit": {
+ "name": "energy_bill_per_unit_post_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_consumption_per_unit_pre_retrofit": {
+ "name": "energy_consumption_per_unit_pre_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "energy_consumption_per_unit_post_retrofit": {
+ "name": "energy_consumption_per_unit_post_retrofit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "valuation_improvement_per_unit": {
+ "name": "valuation_improvement_per_unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_per_unit": {
+ "name": "cost_per_unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_per_co2_saved": {
+ "name": "cost_per_co2_saved",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost_per_sap_point": {
+ "name": "cost_per_sap_point",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "valuation_return_on_investment": {
+ "name": "valuation_return_on_investment",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "scenario_portfolio_id_portfolio_id_fk": {
+ "name": "scenario_portfolio_id_portfolio_id_fk",
+ "tableFrom": "scenario",
+ "tableTo": "portfolio",
+ "columnsFrom": [
+ "portfolio_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.solar": {
+ "name": "solar",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "longitude": {
+ "name": "longitude",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "latitude": {
+ "name": "latitude",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "uprn": {
+ "name": "uprn",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "google_api_response": {
+ "name": "google_api_response",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.solar_scenario": {
+ "name": "solar_scenario",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "solar_id": {
+ "name": "solar_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "scenario_type": {
+ "name": "scenario_type",
+ "type": "scenario_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "number_panels": {
+ "name": "number_panels",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "array_kwhp": {
+ "name": "array_kwhp",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lifetime_dc_kwh": {
+ "name": "lifetime_dc_kwh",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "yearly_dc_kwh": {
+ "name": "yearly_dc_kwh",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "lifetime_ac_kwh": {
+ "name": "lifetime_ac_kwh",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "yearly_ac_kwh": {
+ "name": "yearly_ac_kwh",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "cost": {
+ "name": "cost",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expected_payback_years": {
+ "name": "expected_payback_years",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "panelled_roof_area": {
+ "name": "panelled_roof_area",
+ "type": "real",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "is_default": {
+ "name": "is_default",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "solar_scenario_solar_id_solar_id_fk": {
+ "name": "solar_scenario_solar_id_solar_id_fk",
+ "tableFrom": "solar_scenario",
+ "tableTo": "solar",
+ "columnsFrom": [
+ "solar_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.account": {
+ "name": "account",
+ "schema": "",
+ "columns": {
+ "userId": {
+ "name": "userId",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "type": {
+ "name": "type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "provider": {
+ "name": "provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "providerAccountId": {
+ "name": "providerAccountId",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "refresh_token": {
+ "name": "refresh_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "access_token": {
+ "name": "access_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "token_type": {
+ "name": "token_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "scope": {
+ "name": "scope",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "id_token": {
+ "name": "id_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "session_state": {
+ "name": "session_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "account_userId_user_id_fk": {
+ "name": "account_userId_user_id_fk",
+ "tableFrom": "account",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "account_provider_providerAccountId_pk": {
+ "name": "account_provider_providerAccountId_pk",
+ "columns": [
+ "provider",
+ "providerAccountId"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.session": {
+ "name": "session",
+ "schema": "",
+ "columns": {
+ "sessionToken": {
+ "name": "sessionToken",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "userId": {
+ "name": "userId",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "session_userId_user_id_fk": {
+ "name": "session_userId_user_id_fk",
+ "tableFrom": "session",
+ "tableTo": "user",
+ "columnsFrom": [
+ "userId"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "firstName": {
+ "name": "firstName",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "emailVerified": {
+ "name": "emailVerified",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "oauth_id": {
+ "name": "oauth_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "oauth_provider": {
+ "name": "oauth_provider",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "onboarded": {
+ "name": "onboarded",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "last_login": {
+ "name": "last_login",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "email"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user_profiles": {
+ "name": "user_profiles",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_type": {
+ "name": "user_type",
+ "type": "user_profiles_user_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "property_count": {
+ "name": "property_count",
+ "type": "user_profiles_property_count",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "goals": {
+ "name": "goals",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "referral_source": {
+ "name": "referral_source",
+ "type": "user_profiles_referral_source",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "nrla_membership_id": {
+ "name": "nrla_membership_id",
+ "type": "varchar(255)",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "accepted_privacy": {
+ "name": "accepted_privacy",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "accepted_privacy_at": {
+ "name": "accepted_privacy_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "marketing_opt_in": {
+ "name": "marketing_opt_in",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "marketing_opt_in_at": {
+ "name": "marketing_opt_in_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "first_name": {
+ "name": "first_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "last_name": {
+ "name": "last_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp (6) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "user_profiles_user_id_user_id_fk": {
+ "name": "user_profiles_user_id_user_id_fk",
+ "tableFrom": "user_profiles",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.verificationToken": {
+ "name": "verificationToken",
+ "schema": "",
+ "columns": {
+ "identifier": {
+ "name": "identifier",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires": {
+ "name": "expires",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {
+ "verificationToken_identifier_token_pk": {
+ "name": "verificationToken_identifier_token_pk",
+ "columns": [
+ "identifier",
+ "token"
+ ]
+ }
+ },
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {
+ "public.document_type": {
+ "name": "document_type",
+ "schema": "public",
+ "values": [
+ "EPR",
+ "Condition Report",
+ "Evidence Report",
+ "Summary Information",
+ "Floor Plan",
+ "Scenario Draft EPC",
+ "Scenario Site Notes"
+ ]
+ },
+ "public.scheme": {
+ "name": "scheme",
+ "schema": "public",
+ "values": [
+ "eco4",
+ "gbis",
+ "whlg",
+ "none"
+ ]
+ },
+ "public.cost_unit": {
+ "name": "cost_unit",
+ "schema": "public",
+ "values": [
+ "gbp_sq_meter",
+ "gbp_per_unit",
+ "gbp_per_m2",
+ "gbp_per_m"
+ ]
+ },
+ "public.depth_unit": {
+ "name": "depth_unit",
+ "schema": "public",
+ "values": [
+ "mm"
+ ]
+ },
+ "public.type": {
+ "name": "type",
+ "schema": "public",
+ "values": [
+ "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",
+ "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_glazing",
+ "trickle_vent",
+ "door_undercut",
+ "solar_pv",
+ "solar_battery",
+ "scaffolding",
+ "high_heat_retention_storage_heaters",
+ "air_source_heat_pump",
+ "roomstat_programmer_trvs",
+ "time_temperature_zone_control",
+ "sealing_fireplace"
+ ]
+ },
+ "public.r_value_unit": {
+ "name": "r_value_unit",
+ "schema": "public",
+ "values": [
+ "square_meter_kelvin_per_watt"
+ ]
+ },
+ "public.size_unit": {
+ "name": "size_unit",
+ "schema": "public",
+ "values": [
+ "kWp",
+ "kW",
+ "watt",
+ "storey"
+ ]
+ },
+ "public.thermal_conductivity_unit": {
+ "name": "thermal_conductivity_unit",
+ "schema": "public",
+ "values": [
+ "watt_per_meter_kelvin"
+ ]
+ },
+ "public.goal": {
+ "name": "goal",
+ "schema": "public",
+ "values": [
+ "Valuation Improvement",
+ "Increasing EPC",
+ "Reducing CO2 emissions",
+ "Energy Savings",
+ "None"
+ ]
+ },
+ "public.role": {
+ "name": "role",
+ "schema": "public",
+ "values": [
+ "creator",
+ "admin",
+ "read",
+ "write"
+ ]
+ },
+ "public.status": {
+ "name": "status",
+ "schema": "public",
+ "values": [
+ "scoping",
+ "survey",
+ "assessment",
+ "tendering",
+ "project underway",
+ "completion; status: on track",
+ "completion; status: delayed",
+ "completion; status: at risk",
+ "completion; status: completed",
+ "needs review"
+ ]
+ },
+ "public.epc": {
+ "name": "epc",
+ "schema": "public",
+ "values": [
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G"
+ ]
+ },
+ "public.creation_status": {
+ "name": "creation_status",
+ "schema": "public",
+ "values": [
+ "LOADING",
+ "READY",
+ "ERROR"
+ ]
+ },
+ "public.housing_type": {
+ "name": "housing_type",
+ "schema": "public",
+ "values": [
+ "Private",
+ "Social"
+ ]
+ },
+ "public.unit_quantity": {
+ "name": "unit_quantity",
+ "schema": "public",
+ "values": [
+ "m2",
+ "part",
+ "kwp"
+ ]
+ },
+ "public.scenario_type": {
+ "name": "scenario_type",
+ "schema": "public",
+ "values": [
+ "unit",
+ "building"
+ ]
+ },
+ "public.user_profiles_property_count": {
+ "name": "user_profiles_property_count",
+ "schema": "public",
+ "values": [
+ "1",
+ "2–5",
+ "6–20",
+ "21+",
+ "1–50",
+ "51–100",
+ "101–300",
+ "301–1000",
+ "1000+"
+ ]
+ },
+ "public.user_profiles_referral_source": {
+ "name": "user_profiles_referral_source",
+ "schema": "public",
+ "values": [
+ "search",
+ "social_media",
+ "NRLA",
+ "partner",
+ "word_of_mouth",
+ "other"
+ ]
+ },
+ "public.user_profiles_user_type": {
+ "name": "user_profiles_user_type",
+ "schema": "public",
+ "values": [
+ "private_landlord",
+ "private_tenant",
+ "social_landlord",
+ "social_tenant",
+ "homeowner",
+ "other"
+ ]
+ }
+ },
+ "schemas": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "views": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/src/app/db/migrations/meta/_journal.json b/src/app/db/migrations/meta/_journal.json
index c44a331..6226eee 100644
--- a/src/app/db/migrations/meta/_journal.json
+++ b/src/app/db/migrations/meta/_journal.json
@@ -827,6 +827,13 @@
"when": 1760191704756,
"tag": "0117_colossal_bastion",
"breakpoints": true
+ },
+ {
+ "idx": 118,
+ "version": "7",
+ "when": 1760552402393,
+ "tag": "0118_lazy_gabe_jones",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/src/app/db/schema/users.ts b/src/app/db/schema/users.ts
index 0232d77..b2597ba 100644
--- a/src/app/db/schema/users.ts
+++ b/src/app/db/schema/users.ts
@@ -119,10 +119,15 @@ export const Goal: [string, ...string[]] = [
"other",
];
-export const userTypeEnum = pgEnum("user_type", UserType);
-export const propertyCountEnum = pgEnum("property_count", PropertyCount);
-export const referralSourceEnum = pgEnum("referral_source", ReferralSource);
-export const goalEnum = pgEnum("goal", Goal);
+export const userTypeEnum = pgEnum("user_profiles_user_type", UserType);
+export const propertyCountEnum = pgEnum(
+ "user_profiles_property_count",
+ PropertyCount
+);
+export const referralSourceEnum = pgEnum(
+ "user_profiles_referral_source",
+ ReferralSource
+);
// ----------------------------
// MAIN TABLE
diff --git a/src/app/email_templates/magic_link.ts b/src/app/email_templates/magic_link.ts
new file mode 100644
index 0000000..1786733
--- /dev/null
+++ b/src/app/email_templates/magic_link.ts
@@ -0,0 +1,7 @@
+// Contains the email template for user sign in via magic links. A user will be asked to
+// click a verification email to sign in to the app, should they choose to sign in with magic
+// links
+
+export async function MagicLinksEmail() {
+ return null;
+}
diff --git a/src/app/onboarding/OnboardUserHook.ts b/src/app/onboarding/OnboardUserHook.ts
new file mode 100644
index 0000000..f5fa845
--- /dev/null
+++ b/src/app/onboarding/OnboardUserHook.ts
@@ -0,0 +1,45 @@
+import { useMutation } from "@tanstack/react-query";
+import { useRouter } from "next/navigation";
+import { useSession } from "next-auth/react";
+
+interface OnboardData {
+ firstName: string;
+ lastName: string;
+ userType: string;
+ propertyCount?: string;
+ goals: string[];
+ referralSource: string;
+ nrlaMembershipId?: string;
+ marketingOptIn?: boolean;
+}
+
+export function useOnboardUser() {
+ const router = useRouter();
+ const { update } = useSession();
+
+ return useMutation({
+ mutationFn: async (data: OnboardData) => {
+ // 1️) Create user profile
+ const res1 = await fetch("/api/user/profile", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify(data),
+ });
+ if (!res1.ok) throw new Error("Failed to create user profile");
+
+ // 2️) Mark user as onboarded
+ const res2 = await fetch("/api/user/onboarded", {
+ method: "PATCH",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ onboarded: true }),
+ });
+ if (!res2.ok) throw new Error("Failed to update onboarding status");
+ },
+ onSuccess: async () => {
+ // 3️) Redirect once both requests succeed
+ // Refresh the token with the next-auth session update
+ await update();
+ router.push("/home");
+ },
+ });
+}
diff --git a/src/app/onboarding/page.tsx b/src/app/onboarding/page.tsx
index c36c289..85fc170 100644
--- a/src/app/onboarding/page.tsx
+++ b/src/app/onboarding/page.tsx
@@ -15,6 +15,7 @@ import {
SelectItem,
} from "@/app/shadcn_components/ui/select";
import { Fragment } from "react";
+import { useOnboardUser } from "./OnboardUserHook";
const referralLabels: Record
- By telling us a bit about yourself, we'll know how to best
- support your journey.
+ {`By telling us a bit about yourself, we'll know how to best support your journey.`}