upd
This commit is contained in:
+61
-39
@@ -1,43 +1,65 @@
|
||||
// import { db } from "./src/db/index";
|
||||
// import { IUnit } from "./src/types/IUnit";
|
||||
// import { unitsTable } from "./src/db/schema/units";
|
||||
// import got from "got";
|
||||
import { db } from "./src/db/index";
|
||||
import { IUnit } from "./src/types/IUnit";
|
||||
import { unitsTable } from "./src/db/schema/units";
|
||||
import got from "got";
|
||||
// import { and, eq, exists } from "drizzle-orm";
|
||||
|
||||
// const { units } = await got
|
||||
// .get(
|
||||
// "https://irth-test-ii-16348121.dev.odoo.com/3d-fields/1?token=f82a4708-9a4d-491a-9424-1580b7173ba6"
|
||||
// )
|
||||
// .json<{ units: IUnit[] }>();
|
||||
const { units: unitsOfMarasiDrive } = await got
|
||||
.get(
|
||||
"https://irth-test-ii-16348121.dev.odoo.com/3d-fields/1?token=f82a4708-9a4d-491a-9424-1580b7173ba6"
|
||||
)
|
||||
.json<{ units: IUnit[] }>();
|
||||
|
||||
// for (const {
|
||||
// no_of_bathrooms,
|
||||
// floor,
|
||||
// no_of_parking_space,
|
||||
// project,
|
||||
// sales_price,
|
||||
// square_ft,
|
||||
// state,
|
||||
// suits_area,
|
||||
// unit_no,
|
||||
// unit_type,
|
||||
// unit_view,
|
||||
// } of units) {
|
||||
// type Unit = typeof unitsTable.$inferInsert;
|
||||
const { units: unitsOfDubaiMarina } = await got
|
||||
.get(
|
||||
"https://irth-test-ii-16348121.dev.odoo.com/3d-fields/7?token=f82a4708-9a4d-491a-9424-1580b7173ba6"
|
||||
)
|
||||
.json<{ units: IUnit[] }>();
|
||||
|
||||
// const unit: Unit = {
|
||||
// unitNo: unit_no,
|
||||
// number: +unit_no.slice(2),
|
||||
// project,
|
||||
// floor: +floor,
|
||||
// noOfBathrooms: no_of_bathrooms,
|
||||
// noOfParkingSpace: no_of_parking_space,
|
||||
// salesPrice: sales_price,
|
||||
// state: state as Unit["state"],
|
||||
// unitType: unit_type as Unit["unitType"],
|
||||
// unitView: unit_view as Unit["unitView"],
|
||||
// suitsArea: suits_area.toString(),
|
||||
// squareFt: square_ft.toString(),
|
||||
// };
|
||||
for (const {
|
||||
no_of_bathrooms,
|
||||
floor,
|
||||
no_of_parking_space,
|
||||
project,
|
||||
sales_price,
|
||||
square_ft,
|
||||
state,
|
||||
suits_area,
|
||||
unit_no,
|
||||
unit_type,
|
||||
unit_view,
|
||||
balcony_area,
|
||||
} of unitsOfMarasiDrive.concat(unitsOfDubaiMarina)) {
|
||||
type Unit = typeof unitsTable.$inferInsert;
|
||||
|
||||
// await db.insert(unitsTable).values(unit);
|
||||
// }
|
||||
const parts = unit_no.split("-");
|
||||
|
||||
const unit: Unit = {
|
||||
unitNo: unit_no,
|
||||
number:
|
||||
parts.length === 1
|
||||
? +parts[0]
|
||||
: !Number.isNaN(+parts[0])
|
||||
? +parts[0]
|
||||
: +parts[1],
|
||||
project,
|
||||
floor: +floor,
|
||||
noOfBathrooms: no_of_bathrooms,
|
||||
noOfParkingSpace: no_of_parking_space,
|
||||
salesPrice: sales_price,
|
||||
state: state as Unit["state"],
|
||||
unitType: unit_type ? (unit_type as Unit["unitType"]) : null,
|
||||
unitView: unit_view ? (unit_view as Unit["unitView"]) : null,
|
||||
suitsArea: suits_area,
|
||||
squareFt: square_ft,
|
||||
balconyArea: balcony_area,
|
||||
};
|
||||
|
||||
await db
|
||||
.insert(unitsTable)
|
||||
.values(unit)
|
||||
.onConflictDoUpdate({
|
||||
target: [unitsTable.project, unitsTable.unitNo],
|
||||
set: unit,
|
||||
});
|
||||
}
|
||||
|
||||
+308
-5
@@ -2,16 +2,63 @@ import Elysia, { error, t } from "elysia";
|
||||
import { unitsTable } from "../db/schema";
|
||||
import { createSelectSchema } from "drizzle-typebox";
|
||||
import { db } from "../db";
|
||||
import { eq, and } from "drizzle-orm";
|
||||
import {
|
||||
and,
|
||||
asc,
|
||||
between,
|
||||
count,
|
||||
desc,
|
||||
eq,
|
||||
inArray,
|
||||
max,
|
||||
min,
|
||||
} from "drizzle-orm";
|
||||
|
||||
export const getUnitSchema = createSelectSchema(unitsTable);
|
||||
|
||||
export const unitsController = new Elysia({ prefix: "/units" }).get(
|
||||
export const unitsController = new Elysia({ prefix: "/units" })
|
||||
.get(
|
||||
"/",
|
||||
async ({ query: { project } }) => {
|
||||
async ({
|
||||
query: {
|
||||
project,
|
||||
unitTypes,
|
||||
cost,
|
||||
floor,
|
||||
area,
|
||||
view,
|
||||
order,
|
||||
offset,
|
||||
limit,
|
||||
},
|
||||
}) => {
|
||||
try {
|
||||
return await db.query.unitsTable.findMany({
|
||||
where: and(project ? eq(unitsTable.project, project) : undefined),
|
||||
where: and(
|
||||
project ? eq(unitsTable.project, project) : undefined,
|
||||
unitTypes ? inArray(unitsTable.unitType, unitTypes) : undefined,
|
||||
cost ? between(unitsTable.salesPrice, cost[0], cost[1]) : undefined,
|
||||
floor ? between(unitsTable.floor, floor[0], floor[1]) : undefined,
|
||||
area ? between(unitsTable.squareFt, area[0], area[1]) : undefined,
|
||||
view ? eq(unitsTable.unitView, view) : undefined
|
||||
),
|
||||
orderBy: order
|
||||
? [
|
||||
order[1] === "asc"
|
||||
? asc(
|
||||
unitsTable[
|
||||
order[0] === "cost" ? "salesPrice" : "squareFt"
|
||||
]
|
||||
)
|
||||
: desc(
|
||||
unitsTable[
|
||||
order[0] === "cost" ? "salesPrice" : "squareFt"
|
||||
]
|
||||
),
|
||||
]
|
||||
: undefined,
|
||||
offset,
|
||||
limit,
|
||||
});
|
||||
} catch (err) {
|
||||
console.log((err as Error).message);
|
||||
@@ -19,6 +66,262 @@ export const unitsController = new Elysia({ prefix: "/units" }).get(
|
||||
}
|
||||
},
|
||||
{
|
||||
query: t.Partial(t.Object({ project: t.String() })),
|
||||
query: t.Partial(
|
||||
t.Object({
|
||||
project: t.String(),
|
||||
unitTypes: t.Array(
|
||||
t.Union([
|
||||
t.Literal("Studio Squared"),
|
||||
t.Literal("1 BR Squared"),
|
||||
t.Literal("Studio Flex"),
|
||||
t.Literal("2 BR Squared"),
|
||||
t.Literal("Studio2"),
|
||||
t.Literal("One Bedroom2"),
|
||||
t.Literal("One Bedroom Loft"),
|
||||
t.Literal("Two Bedroom Loft"),
|
||||
])
|
||||
),
|
||||
cost: t.Tuple([t.Number(), t.Number()]),
|
||||
floor: t.Tuple([t.Number(), t.Number()]),
|
||||
area: t.Tuple([t.Number(), t.Number()]),
|
||||
view: t.Union([
|
||||
t.Literal("Canal / Amenities"),
|
||||
t.Literal("Corner-Canal / Amenities"),
|
||||
t.Literal("Corner-Canal View"),
|
||||
t.Literal("Business Bay"),
|
||||
t.Literal("Park Facing"),
|
||||
t.Literal("Corner-Park Facing"),
|
||||
t.Literal("Partial Park"),
|
||||
t.Literal("BK/DT / Amenities"),
|
||||
t.Literal("Corner-BK/DT / Amenities"),
|
||||
t.Literal("Corner-Canal / BK/DT View"),
|
||||
t.Literal("Marina View"),
|
||||
t.Literal("Partial Marina View"),
|
||||
t.Literal("Partial Marina, Partial City View"),
|
||||
t.Literal("City view"),
|
||||
t.Literal("Marina View, Sea View"),
|
||||
t.Literal("Partial Marina View, Partial Sea View"),
|
||||
]),
|
||||
order: t.Tuple([
|
||||
t.Union([t.Literal("cost"), t.Literal("sqft")]),
|
||||
t.Union([t.Literal("asc"), t.Literal("desc")]),
|
||||
]),
|
||||
offset: t.Number({ default: 0 }),
|
||||
limit: t.Number({ default: 16 }),
|
||||
})
|
||||
),
|
||||
}
|
||||
)
|
||||
.get(
|
||||
"/count",
|
||||
async ({ query: { project, unitTypes, cost, floor, area, view } }) => {
|
||||
try {
|
||||
return (
|
||||
await db
|
||||
.select({ count: count() })
|
||||
.from(unitsTable)
|
||||
.where(
|
||||
and(
|
||||
project ? eq(unitsTable.project, project) : undefined,
|
||||
unitTypes ? inArray(unitsTable.unitType, unitTypes) : undefined,
|
||||
cost
|
||||
? between(unitsTable.salesPrice, cost[0], cost[1])
|
||||
: undefined,
|
||||
floor
|
||||
? between(unitsTable.floor, floor[0], floor[1])
|
||||
: undefined,
|
||||
area
|
||||
? between(unitsTable.squareFt, area[0], area[1])
|
||||
: undefined,
|
||||
view ? eq(unitsTable.unitView, view) : undefined
|
||||
)
|
||||
)
|
||||
)[0].count;
|
||||
} catch (err) {
|
||||
console.log((err as Error).message);
|
||||
return error(500, "Internal server error");
|
||||
}
|
||||
},
|
||||
{
|
||||
query: t.Partial(
|
||||
t.Object({
|
||||
project: t.String(),
|
||||
unitTypes: t.Array(
|
||||
t.Union([
|
||||
t.Literal("Studio Squared"),
|
||||
t.Literal("1 BR Squared"),
|
||||
t.Literal("Studio Flex"),
|
||||
t.Literal("2 BR Squared"),
|
||||
t.Literal("Studio2"),
|
||||
t.Literal("One Bedroom2"),
|
||||
t.Literal("One Bedroom Loft"),
|
||||
t.Literal("Two Bedroom Loft"),
|
||||
])
|
||||
),
|
||||
cost: t.Tuple([t.Number(), t.Number()]),
|
||||
floor: t.Tuple([t.Number(), t.Number()]),
|
||||
area: t.Tuple([t.Number(), t.Number()]),
|
||||
view: t.Union([
|
||||
t.Literal("Canal / Amenities"),
|
||||
t.Literal("Corner-Canal / Amenities"),
|
||||
t.Literal("Corner-Canal View"),
|
||||
t.Literal("Business Bay"),
|
||||
t.Literal("Park Facing"),
|
||||
t.Literal("Corner-Park Facing"),
|
||||
t.Literal("Partial Park"),
|
||||
t.Literal("BK/DT / Amenities"),
|
||||
t.Literal("Corner-BK/DT / Amenities"),
|
||||
t.Literal("Corner-Canal / BK/DT View"),
|
||||
t.Literal("Marina View"),
|
||||
t.Literal("Partial Marina View"),
|
||||
t.Literal("Partial Marina, Partial City View"),
|
||||
t.Literal("City view"),
|
||||
t.Literal("Marina View, Sea View"),
|
||||
t.Literal("Partial Marina View, Partial Sea View"),
|
||||
]),
|
||||
})
|
||||
),
|
||||
}
|
||||
)
|
||||
.get(
|
||||
"/filters/:filterName",
|
||||
async ({
|
||||
query: { project, view, unitTypes, cost, floor, area },
|
||||
params: { filterName },
|
||||
}) => {
|
||||
try {
|
||||
const filters = and(
|
||||
project ? eq(unitsTable.project, project) : undefined,
|
||||
unitTypes && filterName !== "unitTypes"
|
||||
? inArray(unitsTable.unitType, unitTypes)
|
||||
: undefined,
|
||||
view && filterName !== "views"
|
||||
? eq(unitsTable.unitView, view)
|
||||
: undefined,
|
||||
cost && filterName !== "cost"
|
||||
? between(unitsTable.salesPrice, cost[0], cost[1])
|
||||
: undefined,
|
||||
floor && filterName !== "floor"
|
||||
? between(unitsTable.floor, floor[0], floor[1])
|
||||
: undefined,
|
||||
area && filterName !== "area"
|
||||
? between(unitsTable.squareFt, area[0], area[1])
|
||||
: undefined
|
||||
);
|
||||
|
||||
if (filterName === "unitTypes")
|
||||
return (
|
||||
await db
|
||||
.selectDistinctOn([unitsTable.unitType], {
|
||||
unitType: unitsTable.unitType,
|
||||
})
|
||||
.from(unitsTable)
|
||||
.where(filters)
|
||||
)
|
||||
.map((unit) => unit.unitType)
|
||||
.filter(Boolean);
|
||||
else if (filterName === "views")
|
||||
return (
|
||||
await db
|
||||
.selectDistinctOn([unitsTable.unitView], {
|
||||
unitView: unitsTable.unitView,
|
||||
})
|
||||
.from(unitsTable)
|
||||
.where(filters)
|
||||
)
|
||||
.map((unit) => unit.unitView)
|
||||
.filter(Boolean);
|
||||
else if (filterName === "cost")
|
||||
return (
|
||||
await db
|
||||
.select({
|
||||
min: min(unitsTable.salesPrice),
|
||||
max: max(unitsTable.salesPrice),
|
||||
})
|
||||
.from(unitsTable)
|
||||
.where(filters)
|
||||
)[0];
|
||||
else if (filterName === "area")
|
||||
return (
|
||||
await db
|
||||
.select({
|
||||
min: min(unitsTable.squareFt),
|
||||
max: max(unitsTable.squareFt),
|
||||
})
|
||||
.from(unitsTable)
|
||||
.where(filters)
|
||||
)[0];
|
||||
return (
|
||||
await db
|
||||
.select({
|
||||
min: min(unitsTable.floor),
|
||||
max: max(unitsTable.floor),
|
||||
})
|
||||
.from(unitsTable)
|
||||
.where(filters)
|
||||
)[0];
|
||||
} catch (err) {
|
||||
console.log((err as Error).message);
|
||||
return error(500, "Internal server error");
|
||||
}
|
||||
},
|
||||
{
|
||||
response: {
|
||||
200: t.Union([
|
||||
t.Array(t.String()),
|
||||
t.Object({
|
||||
min: t.Number(),
|
||||
max: t.Number(),
|
||||
}),
|
||||
]),
|
||||
500: t.ObjectString({}),
|
||||
},
|
||||
params: t.Object({
|
||||
filterName: t.Union([
|
||||
t.Literal("unitTypes"),
|
||||
t.Literal("views"),
|
||||
t.Literal("cost"),
|
||||
t.Literal("area"),
|
||||
t.Literal("floor"),
|
||||
]),
|
||||
}),
|
||||
query: t.Partial(
|
||||
t.Object({
|
||||
project: t.String(),
|
||||
unitTypes: t.Array(
|
||||
t.Union([
|
||||
t.Literal("Studio Squared"),
|
||||
t.Literal("1 BR Squared"),
|
||||
t.Literal("Studio Flex"),
|
||||
t.Literal("2 BR Squared"),
|
||||
t.Literal("Studio2"),
|
||||
t.Literal("One Bedroom2"),
|
||||
t.Literal("One Bedroom Loft"),
|
||||
t.Literal("Two Bedroom Loft"),
|
||||
])
|
||||
),
|
||||
cost: t.Tuple([t.Number(), t.Number()]),
|
||||
floor: t.Tuple([t.Number(), t.Number()]),
|
||||
area: t.Tuple([t.Number(), t.Number()]),
|
||||
view: t.Union([
|
||||
t.Literal("Canal / Amenities"),
|
||||
t.Literal("Corner-Canal / Amenities"),
|
||||
t.Literal("Corner-Canal View"),
|
||||
t.Literal("Business Bay"),
|
||||
t.Literal("Park Facing"),
|
||||
t.Literal("Corner-Park Facing"),
|
||||
t.Literal("Partial Park"),
|
||||
t.Literal("BK/DT / Amenities"),
|
||||
t.Literal("Corner-BK/DT / Amenities"),
|
||||
t.Literal("Corner-Canal / BK/DT View"),
|
||||
t.Literal("Marina View"),
|
||||
t.Literal("Partial Marina View"),
|
||||
t.Literal("Partial Marina, Partial City View"),
|
||||
t.Literal("City view"),
|
||||
t.Literal("Marina View, Sea View"),
|
||||
t.Literal("Partial Marina View, Partial Sea View"),
|
||||
]),
|
||||
})
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
+32
-9
@@ -1,15 +1,29 @@
|
||||
import { integer, pgTable, uuid, varchar, decimal } from "drizzle-orm/pg-core";
|
||||
import { primaryKey } from "drizzle-orm/pg-core";
|
||||
import { unique } from "drizzle-orm/pg-core";
|
||||
import { doublePrecision } from "drizzle-orm/pg-core";
|
||||
import { integer, pgTable, uuid, varchar } from "drizzle-orm/pg-core";
|
||||
|
||||
export const unitsTable = pgTable("units", {
|
||||
export const unitsTable = pgTable(
|
||||
"units",
|
||||
{
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
unitNo: varchar("unit_no", { length: 10 }).notNull(),
|
||||
number: integer("number").notNull(),
|
||||
number: integer("number"),
|
||||
project: varchar("project", { length: 256 }).notNull(),
|
||||
floor: integer("floor").notNull(),
|
||||
unitType: varchar("unit_type", {
|
||||
length: 256,
|
||||
enum: ["Studio Squared", "1 BR Squared", "Studio Flex", "2 BR Squared"],
|
||||
}).notNull(),
|
||||
enum: [
|
||||
"Studio Squared",
|
||||
"1 BR Squared",
|
||||
"Studio Flex",
|
||||
"2 BR Squared",
|
||||
"One Bedroom2",
|
||||
"Studio2",
|
||||
"One Bedroom Loft",
|
||||
"Two Bedroom Loft",
|
||||
],
|
||||
}),
|
||||
noOfBathrooms: integer("no_of_bathrooms").notNull(),
|
||||
unitView: varchar("unit_view", {
|
||||
length: 256,
|
||||
@@ -24,14 +38,23 @@ export const unitsTable = pgTable("units", {
|
||||
"BK/DT / Amenities",
|
||||
"Corner-BK/DT / Amenities",
|
||||
"Corner-Canal / BK/DT View",
|
||||
"Marina View",
|
||||
"Partial Marina View",
|
||||
"Partial Marina, Partial City View",
|
||||
"City view",
|
||||
"Marina View, Sea View",
|
||||
"Partial Marina View, Partial Sea View",
|
||||
],
|
||||
}).notNull(),
|
||||
suitsArea: decimal("suits_area", { mode: "number" }).notNull(),
|
||||
squareFt: decimal("square_ft", { mode: "number" }).notNull(),
|
||||
}),
|
||||
suitsArea: doublePrecision("suits_area").notNull(),
|
||||
squareFt: doublePrecision("square_ft").notNull(),
|
||||
noOfParkingSpace: integer("no_of_parking_space").notNull(),
|
||||
salesPrice: integer("sales_price").notNull(),
|
||||
state: varchar("state", {
|
||||
length: 256,
|
||||
enum: ["reserved", "sold_spa", "available", "sold_registered"],
|
||||
}).notNull(),
|
||||
});
|
||||
balconyArea: doublePrecision("balcony_area").notNull(),
|
||||
},
|
||||
(t) => [unique().on(t.project, t.unitNo)]
|
||||
);
|
||||
|
||||
+5
-1
@@ -1,7 +1,11 @@
|
||||
import { Elysia } from "elysia";
|
||||
import { unitsController } from "./controllers/units";
|
||||
import { cors } from "@elysiajs/cors";
|
||||
|
||||
const app = new Elysia().use(unitsController).listen(3000);
|
||||
const app = new Elysia()
|
||||
.use(cors({ origin: "*" }))
|
||||
.use(unitsController)
|
||||
.listen(3000);
|
||||
|
||||
console.log(
|
||||
`🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port}`
|
||||
|
||||
+3
-2
@@ -2,12 +2,13 @@ export interface IUnit {
|
||||
unit_no: string;
|
||||
project: string;
|
||||
floor: string;
|
||||
unit_type: string;
|
||||
unit_type: string | false;
|
||||
unit_view: string | false;
|
||||
no_of_bathrooms: number;
|
||||
unit_view: string;
|
||||
suits_area: number;
|
||||
square_ft: number;
|
||||
no_of_parking_space: number;
|
||||
sales_price: number;
|
||||
state: string;
|
||||
balcony_area: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user