Merged conflicting migrations

This commit is contained in:
Khalim Conn-Kowlessar 2026-03-23 12:23:45 +00:00
commit b664f10fec
6 changed files with 178 additions and 307 deletions

8
.claude/settings.json Normal file
View file

@ -0,0 +1,8 @@
{
"permissions": {
"deny": [
"Bash(npx drizzle-kit generate)",
"Bash(npx drizzle-kit push)"
]
}
}

View file

@ -48,9 +48,7 @@
"postcode_search_postcode_unique": {
"name": "postcode_search_postcode_unique",
"nullsNotDistinct": false,
"columns": [
"postcode"
]
"columns": ["postcode"]
}
},
"policies": {},
@ -123,12 +121,8 @@
"name": "aspect_condition_element_id_element_id_fk",
"tableFrom": "aspect_condition",
"tableTo": "element",
"columnsFrom": [
"element_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["element_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -175,12 +169,8 @@
"name": "element_survey_id_property_condition_survey_id_fk",
"tableFrom": "element",
"tableTo": "property_condition_survey",
"columnsFrom": [
"survey_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["survey_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -448,12 +438,8 @@
"name": "property_status_tracker_property_id_property_id_fk",
"tableFrom": "property_status_tracker",
"tableTo": "property",
"columnsFrom": [
"property_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["property_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
},
@ -461,12 +447,8 @@
"name": "property_status_tracker_portfolio_id_portfolio_id_fk",
"tableFrom": "property_status_tracker",
"tableTo": "portfolio",
"columnsFrom": [
"portfolio_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["portfolio_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
}
@ -1241,12 +1223,8 @@
"name": "energy_assessment_documents_energy_assessment_id_energy_assessments_id_fk",
"tableFrom": "energy_assessment_documents",
"tableTo": "energy_assessments",
"columnsFrom": [
"energy_assessment_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["energy_assessment_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@ -1254,12 +1232,8 @@
"name": "energy_assessment_documents_scenario_id_energy_assessment_scenarios_id_fk",
"tableFrom": "energy_assessment_documents",
"tableTo": "energy_assessment_scenarios",
"columnsFrom": [
"scenario_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["scenario_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -1299,12 +1273,8 @@
"name": "energy_assessment_scenarios_energy_assessment_id_energy_assessments_id_fk",
"tableFrom": "energy_assessment_scenarios",
"tableTo": "energy_assessments",
"columnsFrom": [
"energy_assessment_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["energy_assessment_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -1429,12 +1399,8 @@
"name": "files_from_surveyor_portfolio_id_portfolio_id_fk",
"tableFrom": "files_from_surveyor",
"tableTo": "portfolio",
"columnsFrom": [
"portfolio_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["portfolio_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@ -1442,12 +1408,8 @@
"name": "files_from_surveyor_property_id_property_id_fk",
"tableFrom": "files_from_surveyor",
"tableTo": "property",
"columnsFrom": [
"property_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["property_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -1525,12 +1487,8 @@
"name": "funding_package_plan_id_plan_id_fk",
"tableFrom": "funding_package",
"tableTo": "plan",
"columnsFrom": [
"plan_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["plan_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -1595,12 +1553,8 @@
"name": "funding_package_measures_funding_package_id_funding_package_id_fk",
"tableFrom": "funding_package_measures",
"tableTo": "funding_package",
"columnsFrom": [
"funding_package_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["funding_package_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@ -1608,12 +1562,8 @@
"name": "funding_package_measures_material_id_material_id_fk",
"tableFrom": "funding_package_measures",
"tableTo": "material",
"columnsFrom": [
"material_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["material_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -1749,12 +1699,8 @@
"name": "inspections_property_id_property_id_fk",
"tableFrom": "inspections",
"tableTo": "property",
"columnsFrom": [
"property_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["property_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -2205,12 +2151,8 @@
"name": "portfolioUsers_user_id_user_id_fk",
"tableFrom": "portfolioUsers",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["user_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@ -2218,12 +2160,8 @@
"name": "portfolioUsers_portfolio_id_portfolio_id_fk",
"tableFrom": "portfolioUsers",
"tableTo": "portfolio",
"columnsFrom": [
"portfolio_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["portfolio_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -2306,12 +2244,8 @@
"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"
],
"columnsFrom": ["survey_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -2531,12 +2465,8 @@
"name": "property_portfolio_id_portfolio_id_fk",
"tableFrom": "property",
"tableTo": "portfolio",
"columnsFrom": [
"portfolio_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["portfolio_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -2963,12 +2893,8 @@
"name": "property_details_epc_property_id_property_id_fk",
"tableFrom": "property_details_epc",
"tableTo": "property",
"columnsFrom": [
"property_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["property_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@ -2976,12 +2902,8 @@
"name": "property_details_epc_portfolio_id_portfolio_id_fk",
"tableFrom": "property_details_epc",
"tableTo": "portfolio",
"columnsFrom": [
"portfolio_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["portfolio_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -3179,12 +3101,8 @@
"name": "property_targets_property_id_property_id_fk",
"tableFrom": "property_targets",
"tableTo": "property",
"columnsFrom": [
"property_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["property_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@ -3192,12 +3110,8 @@
"name": "property_targets_portfolio_id_portfolio_id_fk",
"tableFrom": "property_targets",
"tableTo": "portfolio",
"columnsFrom": [
"portfolio_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["portfolio_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -3566,12 +3480,8 @@
"name": "plan_portfolio_id_portfolio_id_fk",
"tableFrom": "plan",
"tableTo": "portfolio",
"columnsFrom": [
"portfolio_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["portfolio_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@ -3579,12 +3489,8 @@
"name": "plan_property_id_property_id_fk",
"tableFrom": "plan",
"tableTo": "property",
"columnsFrom": [
"property_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["property_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@ -3592,12 +3498,8 @@
"name": "plan_scenario_id_scenario_id_fk",
"tableFrom": "plan",
"tableTo": "scenario",
"columnsFrom": [
"scenario_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["scenario_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -3674,12 +3576,8 @@
"name": "plan_recommendations_plan_id_plan_id_fk",
"tableFrom": "plan_recommendations",
"tableTo": "plan",
"columnsFrom": [
"plan_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["plan_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
},
@ -3687,12 +3585,8 @@
"name": "plan_recommendations_recommendation_id_recommendation_id_fk",
"tableFrom": "plan_recommendations",
"tableTo": "recommendation",
"columnsFrom": [
"recommendation_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["recommendation_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -3902,12 +3796,8 @@
"name": "recommendation_property_id_property_id_fk",
"tableFrom": "recommendation",
"tableTo": "property",
"columnsFrom": [
"property_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["property_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -3995,12 +3885,8 @@
"name": "recommendation_materials_recommendation_id_recommendation_id_fk",
"tableFrom": "recommendation_materials",
"tableTo": "recommendation",
"columnsFrom": [
"recommendation_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["recommendation_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
},
@ -4008,12 +3894,8 @@
"name": "recommendation_materials_material_id_material_id_fk",
"tableFrom": "recommendation_materials",
"tableTo": "material",
"columnsFrom": [
"material_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["material_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -4279,12 +4161,8 @@
"name": "scenario_portfolio_id_portfolio_id_fk",
"tableFrom": "scenario",
"tableTo": "portfolio",
"columnsFrom": [
"portfolio_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["portfolio_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -4442,12 +4320,8 @@
"name": "solar_scenario_solar_id_solar_id_fk",
"tableFrom": "solar_scenario",
"tableTo": "solar",
"columnsFrom": [
"solar_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["solar_id"],
"columnsTo": ["id"],
"onDelete": "no action",
"onUpdate": "no action"
}
@ -4526,12 +4400,8 @@
"name": "sub_task_task_id_tasks_id_fk",
"tableFrom": "sub_task",
"tableTo": "tasks",
"columnsFrom": [
"task_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["task_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
}
@ -4690,12 +4560,8 @@
"name": "account_userId_user_id_fk",
"tableFrom": "account",
"tableTo": "user",
"columnsFrom": [
"userId"
],
"columnsTo": [
"id"
],
"columnsFrom": ["userId"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
}
@ -4703,10 +4569,7 @@
"compositePrimaryKeys": {
"account_provider_providerAccountId_pk": {
"name": "account_provider_providerAccountId_pk",
"columns": [
"provider",
"providerAccountId"
]
"columns": ["provider", "providerAccountId"]
}
},
"uniqueConstraints": {},
@ -4743,12 +4606,8 @@
"name": "session_userId_user_id_fk",
"tableFrom": "session",
"tableTo": "user",
"columnsFrom": [
"userId"
],
"columnsTo": [
"id"
],
"columnsFrom": ["userId"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
}
@ -4840,9 +4699,7 @@
"user_email_unique": {
"name": "user_email_unique",
"nullsNotDistinct": false,
"columns": [
"email"
]
"columns": ["email"]
}
},
"policies": {},
@ -4957,12 +4814,8 @@
"name": "user_profiles_user_id_user_id_fk",
"tableFrom": "user_profiles",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"columnsFrom": ["user_id"],
"columnsTo": ["id"],
"onDelete": "cascade",
"onUpdate": "no action"
}
@ -5001,10 +4854,7 @@
"compositePrimaryKeys": {
"verificationToken_identifier_token_pk": {
"name": "verificationToken_identifier_token_pk",
"columns": [
"identifier",
"token"
]
"columns": ["identifier", "token"]
}
},
"uniqueConstraints": {},
@ -5298,12 +5148,7 @@
"public.scheme": {
"name": "scheme",
"schema": "public",
"values": [
"eco4",
"gbis",
"whlg",
"none"
]
"values": ["eco4", "gbis", "whlg", "none"]
},
"public.inspection_archetype_2": {
"name": "inspection_archetype_2",
@ -5320,22 +5165,12 @@
"public.inspection_archetype": {
"name": "inspection_archetype",
"schema": "public",
"values": [
"Bungalow",
"Flat",
"Maisonette",
"House",
"non-domestic"
]
"values": ["Bungalow", "Flat", "Maisonette", "House", "non-domestic"]
},
"public.inspection_borescoped": {
"name": "inspection_borescoped",
"schema": "public",
"values": [
"yes",
"no",
"refused"
]
"values": ["yes", "no", "refused"]
},
"public.inspections_access_issues": {
"name": "inspections_access_issues",
@ -5417,11 +5252,7 @@
"public.inspections_tile_hung": {
"name": "inspections_tile_hung",
"schema": "public",
"values": [
"yes",
"no",
"first floor flats are tile hung"
]
"values": ["yes", "no", "first floor flats are tile hung"]
},
"public.inspections_wall_construction": {
"name": "inspections_wall_construction",
@ -5457,19 +5288,12 @@
"public.cost_unit": {
"name": "cost_unit",
"schema": "public",
"values": [
"gbp_sq_meter",
"gbp_per_unit",
"gbp_per_m2",
"gbp_per_m"
]
"values": ["gbp_sq_meter", "gbp_per_unit", "gbp_per_m2", "gbp_per_m"]
},
"public.depth_unit": {
"name": "depth_unit",
"schema": "public",
"values": [
"mm"
]
"values": ["mm"]
},
"public.type": {
"name": "type",
@ -5522,26 +5346,17 @@
"public.r_value_unit": {
"name": "r_value_unit",
"schema": "public",
"values": [
"square_meter_kelvin_per_watt"
]
"values": ["square_meter_kelvin_per_watt"]
},
"public.size_unit": {
"name": "size_unit",
"schema": "public",
"values": [
"kWp",
"kW",
"watt",
"storey"
]
"values": ["kWp", "kW", "watt", "storey"]
},
"public.thermal_conductivity_unit": {
"name": "thermal_conductivity_unit",
"schema": "public",
"values": [
"watt_per_meter_kelvin"
]
"values": ["watt_per_meter_kelvin"]
},
"public.goal": {
"name": "goal",
@ -5557,12 +5372,7 @@
"public.role": {
"name": "role",
"schema": "public",
"values": [
"creator",
"admin",
"read",
"write"
]
"values": ["creator", "admin", "read", "write"]
},
"public.status": {
"name": "status",
@ -5583,32 +5393,17 @@
"public.epc": {
"name": "epc",
"schema": "public",
"values": [
"A",
"B",
"C",
"D",
"E",
"F",
"G"
]
"values": ["A", "B", "C", "D", "E", "F", "G"]
},
"public.creation_status": {
"name": "creation_status",
"schema": "public",
"values": [
"LOADING",
"READY",
"ERROR"
]
"values": ["LOADING", "READY", "ERROR"]
},
"public.housing_type": {
"name": "housing_type",
"schema": "public",
"values": [
"Private",
"Social"
]
"values": ["Private", "Social"]
},
"public.measure_type": {
"name": "measure_type",
@ -5654,26 +5449,17 @@
"public.unit_quantity": {
"name": "unit_quantity",
"schema": "public",
"values": [
"m2",
"part",
"kwp"
]
"values": ["m2", "part", "kwp"]
},
"public.scenario_type": {
"name": "scenario_type",
"schema": "public",
"values": [
"unit",
"building"
]
"values": ["unit", "building"]
},
"public.source": {
"name": "source",
"schema": "public",
"values": [
"portfolio_id"
]
"values": ["portfolio_id"]
},
"public.user_profiles_property_count": {
"name": "user_profiles_property_count",
@ -5725,4 +5511,4 @@
"schemas": {},
"tables": {}
}
}
}

View file

@ -1102,4 +1102,4 @@
"breakpoints": true
}
]
}
}

View file

@ -0,0 +1,17 @@
import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
import { InferModel } from "drizzle-orm";
export const organisation = pgTable("organisation", {
id: uuid("id").defaultRandom().primaryKey(),
createdAt: timestamp("created_at", { precision: 6, withTimezone: true })
.defaultNow()
.notNull(),
updatedAt: timestamp("updated_at", { precision: 6, withTimezone: true })
.defaultNow()
.notNull(),
hubspotCompanyId: text("hubspot_company_id"),
companyName: text("company_name"),
});
export type Organisation = InferModel<typeof organisation, "select">;
export type NewOrganisation = InferModel<typeof organisation, "insert">;

59
src/app/db/schema/team.ts Normal file
View file

@ -0,0 +1,59 @@
import { pgTable, text, timestamp, uuid, bigint } from "drizzle-orm/pg-core";
import { InferModel } from "drizzle-orm";
import { organisation } from "./organisation";
import { user } from "./users";
import { portfolio, roleEnum } from "./portfolio";
export const team = pgTable("team", {
id: uuid("id").defaultRandom().primaryKey(),
teamName: text("team_name").notNull(),
orgId: uuid("org_id").notNull().references(() => organisation.id),
createdAt: timestamp("created_at", { precision: 6, withTimezone: true })
.defaultNow()
.notNull(),
updatedAt: timestamp("updated_at", { precision: 6, withTimezone: true })
.defaultNow()
.notNull(),
});
export const teamMembers = pgTable("team_members", {
id: uuid("id").defaultRandom().primaryKey(),
userId: bigint("user_id", { mode: "bigint" })
.notNull()
.references(() => user.id),
teamId: uuid("team_id").notNull().references(() => team.id),
createdAt: timestamp("created_at", { precision: 6, withTimezone: true })
.defaultNow()
.notNull(),
updatedAt: timestamp("updated_at", { precision: 6, withTimezone: true })
.defaultNow()
.notNull(),
});
export const teamPortfolioPermissions = pgTable("team_portfolio_permissions", {
id: uuid("id").defaultRandom().primaryKey(),
teamId: uuid("team_id").notNull().references(() => team.id),
portfolioId: bigint("portfolio_id", { mode: "bigint" })
.notNull()
.references(() => portfolio.id),
role: roleEnum("role").notNull(),
createdAt: timestamp("created_at", { precision: 6, withTimezone: true })
.defaultNow()
.notNull(),
updatedAt: timestamp("updated_at", { precision: 6, withTimezone: true })
.defaultNow()
.notNull(),
});
export type Team = InferModel<typeof team, "select">;
export type NewTeam = InferModel<typeof team, "insert">;
export type TeamMembers = InferModel<typeof teamMembers, "select">;
export type NewTeamMembers = InferModel<typeof teamMembers, "insert">;
export type TeamPortfolioPermissions = InferModel<
typeof teamPortfolioPermissions,
"select"
>;
export type NewTeamPortfolioPermissions = InferModel<
typeof teamPortfolioPermissions,
"insert"
>;

View file

@ -60,6 +60,7 @@ const STAGE_ID_MAP: Record<string, string> = {
"2769407184": "Queries", //[Ops] Talk to client, Needs Heating Upgrade (Pre EPR C)
"2702650617": "AFTER_ASSESSMENT", //[Design] Ready for Design
"2473886962": "AFTER_ASSESSMENT", //[Design] Design in progress
"1668803774": "AFTER_ASSESSMENT", //[Ops] post-ERF / completed coordination stage
};
// -----------------------------------------------------------------------
@ -94,7 +95,7 @@ function resolveAfterAssessmentStage(
// Maps dealstage ID + coordinationStatus + designStatus -> DisplayStage
// -----------------------------------------------------------------------
export function resolveDisplayStage(deal: HubspotDeal): DisplayStage {
const raw = STAGE_ID_MAP[deal.dealstage ?? ""] ?? "Unknown Stage";
const raw = STAGE_ID_MAP[deal.dealstage ?? ""] ?? "AFTER_ASSESSMENT";
if (raw === "AFTER_ASSESSMENT") {
return resolveAfterAssessmentStage(