commiting missing files

This commit is contained in:
Khalim Conn-Kowlessar 2023-07-11 21:14:36 +01:00
parent 293738f89d
commit c7edac7fb6
5 changed files with 493 additions and 0 deletions

View file

@ -0,0 +1,17 @@
import { eq } from "drizzle-orm";
import { portfolio, portfolioUsers } from "@/app/db/schema/portfolio";
import { NextRequest, NextResponse } from "next/server";
import { db } from "@/app/db/db";
export async function GET(request: NextRequest) {
// Get all portfolios for a user - use a relation
console.log(request);
// const portfolios = await db
// .select()
// .from(portfolioUsers)
// .where(eq(portfolioUsers.userId, 1));
//
const portfolios: String[] = [];
return NextResponse.json(portfolios);
}

View file

@ -0,0 +1,56 @@
DO $$ BEGIN
CREATE TYPE "goal" AS ENUM('Valuation Improvement', 'Increasing EPC', 'Reducing CO2 emissions', 'Energy Savings', 'None');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
CREATE TYPE "role" AS ENUM('creator', 'admin', 'read', 'write');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
CREATE TYPE "status" AS ENUM('scoping', 'assessment', 'tendering', 'project underway', 'completion; status: on track', 'completion; status: delayed', 'completion; status: at risk', 'completion; status: completed', 'needs review');
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "portfolio" (
"id" serial PRIMARY KEY NOT NULL,
"name" text NOT NULL,
"budget" real,
"status" "status" NOT NULL,
"goal" "goal" NOT NULL,
"cost" real,
"number_of_properties" integer,
"co2_equivalent_savings" real,
"energy_savings" real,
"energy_cost_savings" real,
"property_valuation_increase" real,
"rental_yield_increase" real,
"total_work_hours" real,
"created_at" timestamp (6) with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp (6) with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "portfolioUsers" (
"id" serial PRIMARY KEY NOT NULL,
"user_id" integer NOT NULL,
"portfolio_id" integer NOT NULL,
"role" "role" NOT NULL,
"created_at" timestamp (6) with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp (6) with time zone DEFAULT now() NOT NULL
);
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "portfolioUsers" ADD CONSTRAINT "portfolioUsers_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "portfolioUsers" ADD CONSTRAINT "portfolioUsers_portfolio_id_portfolio_id_fk" FOREIGN KEY ("portfolio_id") REFERENCES "portfolio"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

View file

@ -0,0 +1,277 @@
{
"version": "5",
"dialect": "pg",
"id": "e43a69c5-c8ed-4de7-8915-0f0a23455bf1",
"prevId": "4347e9a7-f388-4bac-8860-a482db2a5c8b",
"tables": {
"portfolio": {
"name": "portfolio",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"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",
"primaryKey": false,
"notNull": true
},
"goal": {
"name": "goal",
"type": "goal",
"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
},
"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": {}
},
"portfolioUsers": {
"name": "portfolioUsers",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"portfolio_id": {
"name": "portfolio_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"role": {
"name": "role",
"type": "role",
"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": {}
},
"user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"firstName": {
"name": "firstName",
"type": "text",
"primaryKey": false,
"notNull": false
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"oauth_id": {
"name": "oauth_id",
"type": "text",
"primaryKey": false,
"notNull": false
},
"oauth_provider": {
"name": "oauth_provider",
"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": {},
"compositePrimaryKeys": {}
}
},
"enums": {
"goal": {
"name": "goal",
"values": {
"Valuation Improvement": "Valuation Improvement",
"Increasing EPC": "Increasing EPC",
"Reducing CO2 emissions": "Reducing CO2 emissions",
"Energy Savings": "Energy Savings",
"None": "None"
}
},
"role": {
"name": "role",
"values": {
"creator": "creator",
"admin": "admin",
"read": "read",
"write": "write"
}
},
"status": {
"name": "status",
"values": {
"scoping": "scoping",
"assessment": "assessment",
"tendering": "tendering",
"project underway": "project underway",
"completion; status: on track": "completion; status: on track",
"completion; status: delayed": "completion; status: delayed",
"completion; status: at risk": "completion; status: at risk",
"completion; status: completed": "completion; status: completed",
"needs review": "needs review"
}
}
},
"schemas": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
}
}

View file

@ -0,0 +1,122 @@
import {
serial,
text,
timestamp,
pgTable,
real,
pgEnum,
integer,
} from "drizzle-orm/pg-core";
import { user } from "./users";
import { InferModel, relations } from "drizzle-orm";
export const PortfolioStatus: [string, ...string[]] = [
"scoping",
"assessment",
"tendering",
"project underway",
"completion; status: on track",
"completion; status: delayed",
"completion; status: at risk",
"completion; status: completed",
"needs review",
];
export const PortfolioGoal: [string, ...string[]] = [
"Valuation Improvement",
"Increasing EPC",
"Reducing CO2 emissions",
"Energy Savings",
"None",
];
export const PortfolioRole: [string, ...string[]] = [
"creator",
"admin",
"read",
"write",
];
export const statusEnum = pgEnum("status", PortfolioStatus);
export const goalEnum = pgEnum("goal", PortfolioGoal);
export const roleEnum = pgEnum("role", PortfolioRole);
export const portfolio = pgTable("portfolio", {
id: serial("id").primaryKey(),
name: text("name").notNull(),
budget: real("budget"),
status: statusEnum("status").notNull(),
goal: goalEnum("goal").notNull(),
cost: real("cost"),
numberOfProperties: integer("number_of_properties"),
co2EquivalentSavings: real("co2_equivalent_savings"), // Unit is always tonnes so we don't need to store unit
energySavings: real("energy_savings"), // Unit is always kWh so we don't need to store unit
energyCostSavings: real("energy_cost_savings"), // Unit is always £ so we don't need to store unit for the moment
propertyValuationIncrease: real("property_valuation_increase"), // Unit is always £ so we don't need to store unit for the moment
rentalYieldIncrease: real("rental_yield_increase"), // Unit is always £ so we don't need to store unit for the moment
totalWorkHours: real("total_work_hours"),
createdAt: timestamp("created_at", {
precision: 6,
withTimezone: true,
})
.defaultNow()
.notNull(),
updatedAt: timestamp("updated_at", {
precision: 6,
withTimezone: true,
})
.defaultNow()
.notNull(),
});
// We have a many to many relationship between users and portfolios
// One user can have many portfolios, and one portfolio can have many users
// We use the Dizzle relational queries pattern to facilitate this
// Define relation from users to portfolios
export const usersToPortfolioRelations = relations(user, ({ many }) => ({
portfolios: many(portfolio),
}));
export const portfolioUsers = pgTable("portfolioUsers", {
id: serial("id").primaryKey(),
// Define the foreign key constraints using references from Drizzle, from user_id to the users table
userId: integer("user_id")
.notNull()
.references(() => user.id),
// Define the foreign key constraints using references from Drizzle, from portfolio_id to the portfolios table
portfolioId: integer("portfolio_id")
.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(),
});
// Define relation from portfolios to users
export const portfolioToUsersRelations = relations(portfolio, ({ many }) => ({
users: many(user),
}));
// Define relation from portfolioUsers to portfolios (we can have many users to a portfolio)
export const portfolioUsersToPortfolioRelations = relations(
portfolioUsers,
({ many }) => ({
portfolio: many(portfolio),
})
);
export type Portfolio = InferModel<typeof portfolio, "select">;
export type NewPortfolio = InferModel<typeof portfolio, "insert">;
export type PortfolioUsers = InferModel<typeof portfolioUsers, "select">;
export type NewPortfolioUsers = InferModel<typeof portfolioUsers, "insert">;

21
src/app/home/utils.ts Normal file
View file

@ -0,0 +1,21 @@
import { portfolioUsers, PortfolioUsers } from "./../db/schema/portfolio";
import { eq } from "drizzle-orm";
import { user } from "@/app/db/schema/users";
import { db } from "@/app/db/db";
import { NextRequest, NextResponse } from "next/server";
import { portfolio } from "@/app/db/schema/portfolio";
import type { Portfolio } from "@/app/db/schema/portfolio";
export default async function getPortfolios(
userId: number
): Promise<Portfolio[]> {
const userPortfolios = await db
.select()
.from(portfolio)
.leftJoin(portfolioUsers, eq(portfolio.id, portfolioUsers.portfolioId))
.where(eq(portfolioUsers.userId, userId));
const portfolios = userPortfolios.map((data) => data.portfolio);
return portfolios;
}