integratedhub/services/propertyMediaService.ts
2026-01-20 09:02:26 -06:00

174 lines
4.7 KiB
TypeScript

// services/propertyMediaService.ts
// Handle property photos, videos, and document uploads
import { and, eq } from "drizzle-orm";
import { db } from "../db/db.ts";
import { property_media } from "../db/schema.ts";
import {
addE2EPropertyMedia,
deleteE2EAllMediaForProperty,
deleteE2EPropertyMedia,
getE2EMediaByProperty,
getE2EMediaByPropertyAndType,
getE2EMediaCountByProperty,
getE2EPrimaryPhoto,
isE2EEnabled,
updateE2EMultipleMediaOrders,
updateE2EPropertyMediaOrder,
} from "./e2eFixtures.ts";
export interface PropertyMedia {
id: string;
property_id: string;
media_type: string | null; // 'photo', 'video', 'document'
file_url: string | null;
file_name: string | null;
display_order: number | null;
created_on: number;
}
// Create new media entry
export async function createPropertyMedia(
property_id: string,
media_type: string,
file_url: string,
file_name: string,
display_order: number = 0,
) {
if (isE2EEnabled()) {
return [addE2EPropertyMedia(
property_id,
media_type,
file_url,
file_name,
display_order,
)];
}
const now = Date.now();
return await db.insert(property_media)
.values({
id: crypto.randomUUID(),
property_id,
media_type,
file_url,
file_name,
display_order,
created_on: now,
})
.returning();
}
// Get all media for a property
export async function getMediaByProperty(property_id: string) {
if (isE2EEnabled()) {
return getE2EMediaByProperty(property_id);
}
return await db.select()
.from(property_media)
.where(eq(property_media.property_id, property_id))
.orderBy(property_media.display_order);
}
// Get media by type for a property
export async function getMediaByPropertyAndType(
property_id: string,
media_type: string,
) {
if (isE2EEnabled()) {
return getE2EMediaByPropertyAndType(property_id, media_type);
}
return await db.select()
.from(property_media)
.where(and(
eq(property_media.property_id, property_id),
eq(property_media.media_type, media_type),
))
.orderBy(property_media.display_order);
}
// Get photos only for a property
export async function getPhotosByProperty(property_id: string) {
return await getMediaByPropertyAndType(property_id, "photo");
}
// Get documents only for a property
export async function getDocumentsByProperty(property_id: string) {
return await getMediaByPropertyAndType(property_id, "document");
}
// Update media display order
export async function updateMediaOrder(id: string, display_order: number) {
if (isE2EEnabled()) {
return updateE2EPropertyMediaOrder(id, display_order);
}
return await db.update(property_media)
.set({ display_order })
.where(eq(property_media.id, id))
.returning();
}
// Update multiple media orders (for drag-drop reordering)
export async function updateMultipleMediaOrders(
updates: { id: string; display_order: number }[],
) {
if (isE2EEnabled()) {
return updateE2EMultipleMediaOrders(updates);
}
const promises = updates.map((update) =>
db.update(property_media)
.set({ display_order: update.display_order })
.where(eq(property_media.id, update.id))
.returning()
);
return await Promise.all(promises);
}
// Delete media
export async function deletePropertyMedia(id: string) {
if (isE2EEnabled()) {
return deleteE2EPropertyMedia(id);
}
return await db.delete(property_media)
.where(eq(property_media.id, id))
.returning();
}
// Delete all media for a property
export async function deleteAllMediaForProperty(property_id: string) {
if (isE2EEnabled()) {
return deleteE2EAllMediaForProperty(property_id);
}
return await db.delete(property_media)
.where(eq(property_media.property_id, property_id))
.returning();
}
// Get media count by property
export async function getMediaCountByProperty(property_id: string) {
if (isE2EEnabled()) {
return getE2EMediaCountByProperty(property_id);
}
const media = await getMediaByProperty(property_id);
return {
total: media.length,
photos: media.filter((m) => m.media_type === "photo").length,
videos: media.filter((m) => m.media_type === "video").length,
documents: media.filter((m) => m.media_type === "document").length,
};
}
// Get primary photo for a property (first photo by display order)
export async function getPrimaryPhoto(property_id: string) {
if (isE2EEnabled()) {
return getE2EPrimaryPhoto(property_id);
}
const photos = await getPhotosByProperty(property_id);
return photos[0] || null;
}
// Get property media by property (alias for compatibility)
export async function getPropertyMediaByProperty(property_id: string) {
return await getMediaByProperty(property_id);
}