Merge pull request #156 from Hestia-Homes/new-reporting

Added indexing for plans and plan recommendations
This commit is contained in:
KhalimCK 2026-01-05 21:37:00 +08:00 committed by GitHub
commit 6788d4dffa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 5029 additions and 65 deletions

View file

@ -18,5 +18,5 @@ export default {
ssl: isProduction
? true // strict SSL for prod
: { rejectUnauthorized: false }, // allow self-signed in dev/preview
}
},
} satisfies Config;

View file

@ -0,0 +1,2 @@
CREATE INDEX CONCURRENTLY "idx_plan_portfolio_scenario" ON "plan" USING btree ("portfolio_id","scenario_id");--> statement-breakpoint
CREATE INDEX CONCURRENTLY "idx_plan_recommendations_plan_id" ON "plan_recommendations" USING btree ("plan_id");

File diff suppressed because it is too large Load diff

View file

@ -988,6 +988,13 @@
"when": 1766389269465,
"tag": "0140_keen_dreaming_celestial",
"breakpoints": true
},
{
"idx": 141,
"version": "7",
"when": 1767619224711,
"tag": "0141_amazing_harry_osborn",
"breakpoints": true
}
]
}

View file

@ -93,83 +93,96 @@ export type PlanTypeEnum =
| "extraction_eco";
export const planTypeEnum = pgEnum("plan_type", PlanType);
export const plan = pgTable("plan", {
id: bigserial("id", { mode: "bigint" }).primaryKey(),
name: text("name"),
export const plan = pgTable(
"plan",
{
id: bigserial("id", { mode: "bigint" }).primaryKey(),
name: text("name"),
portfolioId: bigint("portfolio_id", { mode: "bigint" })
.notNull()
.references(() => portfolio.id),
portfolioId: bigint("portfolio_id", { mode: "bigint" })
.notNull()
.references(() => portfolio.id),
propertyId: bigint("property_id", { mode: "bigint" })
.notNull()
.references(() => property.id),
propertyId: bigint("property_id", { mode: "bigint" })
.notNull()
.references(() => property.id),
scenarioId: bigint("scenario_id", { mode: "bigint" }).references(
() => scenario.id
),
scenarioId: bigint("scenario_id", { mode: "bigint" }).references(
() => scenario.id
),
createdAt: timestamp("created_at").notNull().defaultNow(),
isDefault: boolean("is_default").notNull(),
createdAt: timestamp("created_at").notNull().defaultNow(),
isDefault: boolean("is_default").notNull(),
// ─────────────────────────────────────────────────────────
// Valuation metrics (existing)
// ─────────────────────────────────────────────────────────
valuationIncreaseLowerBound: real("valuation_increase_lower_bound"),
valuationIncreaseUpperBound: real("valuation_increase_upper_bound"),
valuationIncreaseAverage: real("valuation_increase_average"),
// ─────────────────────────────────────────────────────────
// Valuation metrics (existing)
// ─────────────────────────────────────────────────────────
valuationIncreaseLowerBound: real("valuation_increase_lower_bound"),
valuationIncreaseUpperBound: real("valuation_increase_upper_bound"),
valuationIncreaseAverage: real("valuation_increase_average"),
// ─────────────────────────────────────────────────────────
// NEW — SAP / EPC
// ─────────────────────────────────────────────────────────
postSapPoints: real("post_sap_points"),
postEpcRating: epcEnum("post_epc_rating"),
// ─────────────────────────────────────────────────────────
// NEW — SAP / EPC
// ─────────────────────────────────────────────────────────
postSapPoints: real("post_sap_points"),
postEpcRating: epcEnum("post_epc_rating"),
// ─────────────────────────────────────────────────────────
// NEW — Carbon emissions (tonnes CO₂e/yr)
// ─────────────────────────────────────────────────────────
postCo2Emissions: real("post_co2_emissions"),
co2Savings: real("co2_savings"), // baseline - post
// ─────────────────────────────────────────────────────────
// NEW — Carbon emissions (tonnes CO₂e/yr)
// ─────────────────────────────────────────────────────────
postCo2Emissions: real("post_co2_emissions"),
co2Savings: real("co2_savings"), // baseline - post
// ─────────────────────────────────────────────────────────
// NEW — Energy bills
// ─────────────────────────────────────────────────────────
postEnergyBill: real("post_energy_bill"),
energyBillSavings: real("energy_bill_savings"),
// ─────────────────────────────────────────────────────────
// NEW — Energy bills
// ─────────────────────────────────────────────────────────
postEnergyBill: real("post_energy_bill"),
energyBillSavings: real("energy_bill_savings"),
// ─────────────────────────────────────────────────────────
// NEW — Energy consumption (kWh/year)
// ─────────────────────────────────────────────────────────
postEnergyConsumption: real("post_energy_consumption"),
energyConsumptionSavings: real("energy_consumption_savings"),
// ─────────────────────────────────────────────────────────
// NEW — Energy consumption (kWh/year)
// ─────────────────────────────────────────────────────────
postEnergyConsumption: real("post_energy_consumption"),
energyConsumptionSavings: real("energy_consumption_savings"),
// ─────────────────────────────────────────────────────────
// NEW — Valuation
// ─────────────────────────────────────────────────────────
valuationPostRetrofit: real("valuation_post_retrofit"),
valuationIncrease: real("valuation_increase"),
// ─────────────────────────────────────────────────────────
// NEW — Valuation
// ─────────────────────────────────────────────────────────
valuationPostRetrofit: real("valuation_post_retrofit"),
valuationIncrease: real("valuation_increase"),
// Plan costing data
costOfWorks: real("cost_of_works"),
contingencyCost: real("contingency_cost"),
// Plan costing data
costOfWorks: real("cost_of_works"),
contingencyCost: real("contingency_cost"),
// ─────────────────────────────────────────────────────────
// Plan type stays as-is
// ─────────────────────────────────────────────────────────
planType: planTypeEnum("plan_type"),
});
// ─────────────────────────────────────────────────────────
// Plan type stays as-is
// ─────────────────────────────────────────────────────────
planType: planTypeEnum("plan_type"),
},
(table) => [
index("idx_plan_portfolio_scenario").on(
table.portfolioId,
table.scenarioId
),
]
);
export const planRecommendations = pgTable("plan_recommendations", {
id: bigserial("id", { mode: "bigint" }).primaryKey(),
planId: bigint("plan_id", { mode: "bigint" })
.notNull()
.references(() => plan.id),
recommendationId: bigint("recommendation_id", {
mode: "bigint",
})
.notNull()
.references(() => recommendation.id),
});
export const planRecommendations = pgTable(
"plan_recommendations",
{
id: bigserial("id", { mode: "bigint" }).primaryKey(),
planId: bigint("plan_id", { mode: "bigint" })
.notNull()
.references(() => plan.id),
recommendationId: bigint("recommendation_id", {
mode: "bigint",
})
.notNull()
.references(() => recommendation.id),
},
(table) => [index("idx_plan_recommendations_plan_id").on(table.planId)]
);
export const HousingType: [string, ...string[]] = ["Private", "Social"];