From 1317381aea366ad4e070267262c7f90d4d3df5ab Mon Sep 17 00:00:00 2001 From: Gabriele Granello Date: Mon, 26 Aug 2024 10:22:52 +0200 Subject: [PATCH 1/4] fix data types and set perform the calculations in the API --- app/api/route.ts | 4 ++- app/components/ui/CalculatorInput.tsx | 3 +-- app/data/rentRepo.ts | 36 ++++++++++++++++----------- app/models/Household.ts | 5 ++-- app/models/tenure/SocialRent.ts | 11 ++------ app/models/testClasses.ts | 10 ++++---- 6 files changed, 35 insertions(+), 34 deletions(-) diff --git a/app/api/route.ts b/app/api/route.ts index 5b800be..5c93709 100644 --- a/app/api/route.ts +++ b/app/api/route.ts @@ -2,6 +2,7 @@ import { NextResponse } from "next/server"; import { api, apiSchema } from "../schemas/apiSchema"; import { calculationSchema } from "../schemas/calculationSchema"; import * as calculationService from "../services/calculationService"; +import calculateFairhold from "@/app/models/testClasses"; export async function POST(req: Request) { try { @@ -14,7 +15,8 @@ export async function POST(req: Request) { input = data; } const householdData = await calculationService.getHouseholdData(input); - return NextResponse.json(householdData); + const processedData = calculateFairhold(householdData); + return NextResponse.json(processedData); } catch (err) { console.log("ERROR: API - ", (err as Error).message); const response = { error: (err as Error).message }; diff --git a/app/components/ui/CalculatorInput.tsx b/app/components/ui/CalculatorInput.tsx index eb4bf8f..178e923 100644 --- a/app/components/ui/CalculatorInput.tsx +++ b/app/components/ui/CalculatorInput.tsx @@ -49,8 +49,7 @@ const CalculatorInput = () => { body: JSON.stringify(data), // pass the form data to the API }); - const jsonData = await response.json(); - const processedData = calculateFairhold(jsonData); + const processedData = await response.json(); // saved processedData & switch to dashboard view setData(processedData); diff --git a/app/data/rentRepo.ts b/app/data/rentRepo.ts index 8c93db5..314d152 100644 --- a/app/data/rentRepo.ts +++ b/app/data/rentRepo.ts @@ -1,24 +1,30 @@ import prisma from "./db"; -const getRentByITL3 = async (itl3: string): Promise => { - try { - const result = await prisma.rent.aggregate({ - where: { - itl3: { equals: itl3 }, - }, - _avg: { - monthlyMeanRent: true, - }, - }); +const getRentByITL3 = async (itl3: string): Promise => { + try { + const result = await prisma.rent.aggregate({ + where: { + itl3: { equals: itl3 }, + }, + _avg: { + monthlyMeanRent: true, + }, + }); - const monthlyMeanRent = result._avg.monthlyMeanRent; + const monthlyMeanRent = result._avg.monthlyMeanRent; - return monthlyMeanRent; - } catch (error) { - throw new Error(`Data error: Unable to find monthlyMeanRent for itl3 ${itl3}`); + if (monthlyMeanRent === null) { + throw new Error(`No monthlyMeanRent found for itl3 ${itl3}`); } + + return monthlyMeanRent; + } catch (error) { + throw new Error( + `Data error: Unable to find monthlyMeanRent for itl3 ${itl3}` + ); + } }; export const rentRepo = { - getRentByITL3, + getRentByITL3, }; diff --git a/app/models/Household.ts b/app/models/Household.ts index dd07e53..3cfab41 100644 --- a/app/models/Household.ts +++ b/app/models/Household.ts @@ -4,8 +4,9 @@ import { FairholdLandPurchase } from "./tenure/FairholdLandPurchase"; import { FairholdLandRent } from "./tenure/FairholdLandRent"; import { Fairhold } from "./Fairhold"; import { Property } from "./Property"; -import { SocialRent, SocialRentAdjustments } from "./tenure/SocialRent"; +import { SocialRent } from "./tenure/SocialRent"; import { ForecastParameters } from "./ForecastParameters"; +import { socialRentAdjustmentTypes } from "../data/socialRentAdjustmentsRepo"; const HOUSE_MULTIPLIER = 2.4; @@ -15,7 +16,7 @@ type ConstructorParams = Pick< > & { averageRentYearly: number; socialRentAverageEarning: number; - socialRentAdjustments: SocialRentAdjustments; + socialRentAdjustments: socialRentAdjustmentTypes; housePriceIndex: number; }; diff --git a/app/models/tenure/SocialRent.ts b/app/models/tenure/SocialRent.ts index 11325d1..1bf2d57 100644 --- a/app/models/tenure/SocialRent.ts +++ b/app/models/tenure/SocialRent.ts @@ -1,22 +1,15 @@ import { WEEKS_PER_MONTH } from "../constants"; import { BED_WEIGHTS_AND_CAPS, NATIONAL_AVERAGES } from "../constants"; +import { socialRentAdjustmentTypes } from "../../data/socialRentAdjustmentsRepo"; interface SocialRentParams { numberOfBedrooms: number; socialRentAverageEarning: number; - socialRentAdjustments: SocialRentAdjustments; + socialRentAdjustments: socialRentAdjustmentTypes; housePriceIndex: number; landToTotalRatio: number; } -export type SocialRentAdjustments = { - year: string; - inflation: number; - // TODO: Is this optional or required? - additional?: number; - total: number; -}[]; - export class SocialRent { socialRentAverageEarning: number; /** adjustment factors that take into account the increase of living cost */ diff --git a/app/models/testClasses.ts b/app/models/testClasses.ts index eedbb93..25939f2 100644 --- a/app/models/testClasses.ts +++ b/app/models/testClasses.ts @@ -1,24 +1,24 @@ +import { ValidPostcode } from "../schemas/apiSchema"; import { DEFAULT_FORECAST_PARAMETERS } from "./ForecastParameters"; import { Household } from "./Household"; import { HouseType, Property } from "./Property"; import { MONTHS_PER_YEAR } from "./constants"; -import { SocialRentAdjustments } from "./tenure/SocialRent"; +import { socialRentAdjustmentTypes } from "../data/socialRentAdjustmentsRepo"; // TODO: Share type with backend export interface ResponseData { - postcode: string; + postcode: ValidPostcode; houseType: HouseType; houseBedrooms: number; buildPrice: number; houseAge: number; houseSize: number; - newBuildPricePerMetre: number; averagePrice: number; itl3: string; gdhi: number; averageRentMonthly: number; socialRentAverageEarning: number; - socialRentAdjustments: SocialRentAdjustments; + socialRentAdjustments: socialRentAdjustmentTypes; hpi: number; gasBillYearly: number; } @@ -33,7 +33,7 @@ function calculateFairhold(responseData: ResponseData) { // define the property object const property = new Property({ - postcode: responseData.postcode, + postcode: responseData.postcode.postcode, houseType: responseData.houseType, numberOfBedrooms: responseData.houseBedrooms, age: responseData.houseAge, From 33b8167e404bc6b296d01d3d46842f881be391d0 Mon Sep 17 00:00:00 2001 From: Gabriele Granello Date: Mon, 26 Aug 2024 10:23:39 +0200 Subject: [PATCH 2/4] fix lint error --- app/components/ui/CalculatorInput.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/components/ui/CalculatorInput.tsx b/app/components/ui/CalculatorInput.tsx index 178e923..7a22bc7 100644 --- a/app/components/ui/CalculatorInput.tsx +++ b/app/components/ui/CalculatorInput.tsx @@ -3,7 +3,6 @@ import React, { useState } from "react"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; -import calculateFairhold from "@/app/models/testClasses"; import { Household } from "@/app/models/Household"; import Dashboard from "./Dashboard"; import { From dde813873f27d118cd7f49ebc4c643c923015f09 Mon Sep 17 00:00:00 2001 From: Gabriele Granello Date: Mon, 26 Aug 2024 11:12:35 +0200 Subject: [PATCH 3/4] socialRentAdjustment types --- app/data/socialRentAdjustmentsRepo.ts | 61 +++++++++++++++++---------- app/models/tenure/SocialRent.test.ts | 5 ++- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/app/data/socialRentAdjustmentsRepo.ts b/app/data/socialRentAdjustmentsRepo.ts index ad9a7a8..ec40542 100644 --- a/app/data/socialRentAdjustmentsRepo.ts +++ b/app/data/socialRentAdjustmentsRepo.ts @@ -2,36 +2,51 @@ import prisma from "./db"; export type socialRentAdjustmentTypes = { year: string; - inflation: string; - additional: string; - total: string; + inflation: number; + additional: number; + total: number; }[]; -const getSocialRentAdjustments = async (): Promise => { +const getSocialRentAdjustments = + async (): Promise => { try { - const result = await prisma.socialRentAdjustments.findMany({ - select: { - year: true, - inflation: true, - additional: true, - total: true, - } - }); + const result = await prisma.socialRentAdjustments.findMany({ + select: { + year: true, + inflation: true, + additional: true, + total: true, + }, + }); - const socialRentAdjustments: socialRentAdjustmentTypes = result.map(item => ({ - year: item.year || '', - inflation: item.inflation?.toString() || '', - additional: item.additional?.toString() || '', - total: item.total?.toString() || '', - })); + const socialRentAdjustments: socialRentAdjustmentTypes = result.map( + (item) => { + if ( + item.year === null || + item.inflation === null || + item.additional === null || + item.total === null + ) { + throw new Error( + `Data error: Found null values in socialRentAdjustments` + ); + } + return { + year: item.year, + inflation: item.inflation, + additional: item.additional, + total: item.total, + }; + } + ); - return socialRentAdjustments; - + // Return the array after validation + return socialRentAdjustments; } catch (error) { - throw new Error(`Data error: Unable to find socialRentAdjustments`); + throw new Error(`Data error: unable to find socialRentAdjustments`); } -}; + }; export const socialRentAdjustmentsRepo = { - getSocialRentAdjustments, + getSocialRentAdjustments, }; diff --git a/app/models/tenure/SocialRent.test.ts b/app/models/tenure/SocialRent.test.ts index ec11122..4884a49 100644 --- a/app/models/tenure/SocialRent.test.ts +++ b/app/models/tenure/SocialRent.test.ts @@ -1,9 +1,10 @@ -import { SocialRent, SocialRentAdjustments } from "./SocialRent"; +import { SocialRent } from "./SocialRent"; +import { socialRentAdjustmentTypes } from "../../data/socialRentAdjustmentsRepo"; let tenureSocialRent: SocialRent; beforeEach(() => { - const socialRentAdjustments: SocialRentAdjustments = [ + const socialRentAdjustments: socialRentAdjustmentTypes = [ { inflation: 3.3, total: 4.3, From 3c624f782556a0c398284fad2d0f8ecfa940dca9 Mon Sep 17 00:00:00 2001 From: Gabriele Granello Date: Mon, 26 Aug 2024 11:27:33 +0200 Subject: [PATCH 4/4] fix socialRentAdjustments missing data --- app/models/Household.test.ts | 165 +++++++++++++++++++++++++++++------ 1 file changed, 140 insertions(+), 25 deletions(-) diff --git a/app/models/Household.test.ts b/app/models/Household.test.ts index 3f9e986..5e7db2b 100644 --- a/app/models/Household.test.ts +++ b/app/models/Household.test.ts @@ -1,34 +1,149 @@ import { DEFAULT_FORECAST_PARAMETERS } from "./ForecastParameters"; import { Household } from "./Household"; import { Property } from "./Property"; -import { SocialRentAdjustments } from "./tenure/SocialRent"; +import { socialRentAdjustmentTypes } from "../data/socialRentAdjustmentsRepo"; let property: Property; let household: Household; -const socialRentAdjustments: SocialRentAdjustments = [ - { inflation: 3.3, total: 4.3, year: "2001-02" }, - { inflation: 1.7, total: 2.2, year: "2002-03" }, - { inflation: 1.7, total: 2.2, year: "2003-04" }, - { inflation: 2.8, total: 3.3, year: "2004-05" }, - { inflation: 3.1, total: 3.6, year: "2005-06" }, - { inflation: 2.7, total: 3.2, year: "2006-07" }, - { inflation: 3.6, total: 4.1, year: "2007-08" }, - { inflation: 3.9, total: 4.4, year: "2008-09" }, - { inflation: 5.0, total: 5.5, year: "2009-10" }, - { inflation: -1.4, total: -0.9, year: "2010-11" }, - { inflation: 4.6, total: 5.1, year: "2011-12" }, - { inflation: 5.6, total: 6.1, year: "2012-13" }, - { inflation: 2.6, total: 3.1, year: "2013-14" }, - { inflation: 3.2, total: 3.7, year: "2014-15" }, - { inflation: 1.2, total: 2.2, year: "2015-16" }, - { inflation: NaN, total: -1.0, year: "2016-17" }, - { inflation: NaN, total: -1.0, year: "2017-18" }, - { inflation: NaN, total: -1.0, year: "2018-19" }, - { inflation: NaN, total: -1.0, year: "2019-20" }, - { inflation: 1.7, total: 2.7, year: "2020-21" }, - { inflation: 0.5, total: 1.5, year: "2021-22" }, - { inflation: 3.1, total: 4.1, year: "2022-23" }, - { inflation: 10.1, total: 11.1, year: "2023-24" }, +const socialRentAdjustments: socialRentAdjustmentTypes = [ + { + inflation: 3.3, + total: 4.3, + year: "2001-02", + additional: 0, + }, + { + inflation: 1.7, + total: 2.2, + year: "2002-03", + additional: 0, + }, + { + inflation: 1.7, + total: 2.2, + year: "2003-04", + additional: 0, + }, + { + inflation: 2.8, + total: 3.3, + year: "2004-05", + additional: 0, + }, + { + inflation: 3.1, + total: 3.6, + year: "2005-06", + additional: 0, + }, + { + inflation: 2.7, + total: 3.2, + year: "2006-07", + additional: 0, + }, + { + inflation: 3.6, + total: 4.1, + year: "2007-08", + additional: 0, + }, + { + inflation: 3.9, + total: 4.4, + year: "2008-09", + additional: 0, + }, + { + inflation: 5.0, + total: 5.5, + year: "2009-10", + additional: 0, + }, + { + inflation: -1.4, + total: -0.9, + year: "2010-11", + additional: 0, + }, + { + inflation: 4.6, + total: 5.1, + year: "2011-12", + additional: 0, + }, + { + inflation: 5.6, + total: 6.1, + year: "2012-13", + additional: 0, + }, + { + inflation: 2.6, + total: 3.1, + year: "2013-14", + additional: 0, + }, + { + inflation: 3.2, + total: 3.7, + year: "2014-15", + additional: 0, + }, + { + inflation: 1.2, + total: 2.2, + year: "2015-16", + additional: 0, + }, + { + inflation: NaN, + total: -1.0, + year: "2016-17", + additional: 0, + }, + { + inflation: NaN, + total: -1.0, + year: "2017-18", + additional: 0, + }, + { + inflation: NaN, + total: -1.0, + year: "2018-19", + additional: 0, + }, + { + inflation: NaN, + total: -1.0, + year: "2019-20", + additional: 0, + }, + { + inflation: 1.7, + total: 2.7, + year: "2020-21", + additional: 0, + }, + { + inflation: 0.5, + total: 1.5, + year: "2021-22", + additional: 0, + }, + { + inflation: 3.1, + total: 4.1, + year: "2022-23", + additional: 0, + }, + { + inflation: 10.1, + total: 11.1, + year: "2023-24", + additional: 0, + }, ]; beforeEach(() => {