180 lines
4.8 KiB
TypeScript
180 lines
4.8 KiB
TypeScript
// services/propertyService.ts
|
|
// Handle property listing creation, updates, queries, and validation
|
|
import { eq, sql } from "drizzle-orm";
|
|
import { db } from "../db/db.ts";
|
|
import { leases, properties } from "../db/schema.ts";
|
|
import { Property } from "../db/interfaces.ts";
|
|
import {
|
|
addE2EProperty,
|
|
getE2EAllProperties,
|
|
getE2ELeasesByOwner,
|
|
getE2ELeasesByTenant,
|
|
getE2EPropertiesByOwner,
|
|
getE2EPropertyById,
|
|
isE2EEnabled,
|
|
} from "./e2eFixtures.ts";
|
|
|
|
export async function getProperties(ownerId: string) {
|
|
if (isE2EEnabled()) {
|
|
const leasesByOwner = getE2ELeasesByOwner(ownerId);
|
|
return getE2EPropertiesByOwner(ownerId).map((property) => ({
|
|
...property,
|
|
lease_count: leasesByOwner.filter((lease) =>
|
|
lease.property_id === property.id
|
|
).length,
|
|
}));
|
|
}
|
|
return await db
|
|
.select({
|
|
id: properties.id,
|
|
title: properties.title,
|
|
description: properties.description,
|
|
address_1: properties.address_1,
|
|
address_2: properties.address_2,
|
|
city: properties.city,
|
|
state: properties.state,
|
|
zip: properties.zip,
|
|
country: properties.country,
|
|
bedrooms: properties.bedrooms,
|
|
bathrooms: properties.bathrooms,
|
|
square_footage: properties.square_footage,
|
|
lot_size: properties.lot_size,
|
|
year_built: properties.year_built,
|
|
price: properties.price,
|
|
property_type: properties.property_type,
|
|
listing_status: properties.listing_status,
|
|
image_url: properties.image_url,
|
|
created_on: properties.created_on,
|
|
updated_on: properties.updated_on,
|
|
owner_id: properties.owner_id,
|
|
lease_count: sql`COUNT(${leases.id})::int`,
|
|
})
|
|
.from(properties)
|
|
.leftJoin(leases, eq(leases.property_id, properties.id))
|
|
.where(eq(properties.owner_id, ownerId))
|
|
.groupBy(properties.id);
|
|
}
|
|
|
|
export async function createProperty(property: Property) {
|
|
if (isE2EEnabled()) {
|
|
return [addE2EProperty(property.owner_id || "", property)];
|
|
}
|
|
return await db.insert(properties).values(property).returning();
|
|
}
|
|
|
|
export async function updateProperty(id: string, property: Partial<Property>) {
|
|
return await db.update(properties).set(property).where(eq(properties.id, id))
|
|
.returning();
|
|
}
|
|
|
|
export async function deleteProperty(id: string) {
|
|
return await db.delete(properties).where(eq(properties.id, id));
|
|
}
|
|
|
|
export async function getLeases(propertyId: string) {
|
|
return await db.select().from(leases).where(
|
|
eq(leases.property_id, propertyId),
|
|
);
|
|
}
|
|
|
|
export async function getLease(id: string) {
|
|
return await db.select().from(leases).where(eq(leases.id, id));
|
|
}
|
|
|
|
export async function createLease(
|
|
property_id: string,
|
|
tenant_id: string,
|
|
owner_id: string,
|
|
title: string,
|
|
rent: number,
|
|
start_date: number,
|
|
end_date: number,
|
|
) {
|
|
const now = Date.now();
|
|
return await db.insert(leases).values({
|
|
id: crypto.randomUUID(),
|
|
property_id,
|
|
tenant_id,
|
|
owner_id,
|
|
title,
|
|
rent,
|
|
start_date,
|
|
end_date,
|
|
created_on: now,
|
|
updated_on: now,
|
|
}).returning();
|
|
}
|
|
|
|
export async function updateLease(
|
|
id: string,
|
|
property_id: string,
|
|
tenant_id: string,
|
|
owner_id: string,
|
|
title: string,
|
|
rent: number,
|
|
start_date: number,
|
|
end_date: number,
|
|
) {
|
|
return await db.update(leases).set({
|
|
property_id,
|
|
tenant_id,
|
|
rent,
|
|
start_date,
|
|
end_date,
|
|
updated_on: Date.now(),
|
|
}).where(eq(leases.id, id)).returning();
|
|
}
|
|
|
|
export async function deleteLease(id: string) {
|
|
return await db.delete(leases).where(eq(leases.id, id));
|
|
}
|
|
|
|
export async function getLeasesByOwner(ownerId: string) {
|
|
if (isE2EEnabled()) {
|
|
return getE2ELeasesByOwner(ownerId);
|
|
}
|
|
return await db.select().from(leases).where(eq(leases.owner_id, ownerId));
|
|
}
|
|
|
|
export async function getLeasesByTenant(tenantId: string) {
|
|
if (isE2EEnabled()) {
|
|
return getE2ELeasesByTenant(tenantId);
|
|
}
|
|
return await db.select().from(leases).where(eq(leases.tenant_id, tenantId));
|
|
}
|
|
|
|
export async function getProperty(id: string) {
|
|
if (isE2EEnabled()) {
|
|
const property = getE2EPropertyById(id);
|
|
return property ? [property] : [];
|
|
}
|
|
return await db.select().from(properties).where(eq(properties.id, id));
|
|
}
|
|
|
|
// Get property by ID (alias for compatibility)
|
|
export async function getPropertyById(id: string) {
|
|
const result = await getProperty(id);
|
|
return result[0] || null;
|
|
}
|
|
|
|
export async function getPropertiesByOwner(ownerId: string) {
|
|
if (isE2EEnabled()) {
|
|
return getE2EPropertiesByOwner(ownerId);
|
|
}
|
|
return await db.select().from(properties).where(
|
|
eq(properties.owner_id, ownerId),
|
|
);
|
|
}
|
|
|
|
// Get properties by user (alias for compatibility)
|
|
export async function getPropertiesByUser(userId: string) {
|
|
return await getPropertiesByOwner(userId);
|
|
}
|
|
|
|
export async function getAllProperties() {
|
|
if (isE2EEnabled()) {
|
|
return getE2EAllProperties();
|
|
}
|
|
return await db.select().from(properties);
|
|
}
|