bizmatch-project/bizmatch-server/src/drizzle/schema.ts

150 lines
7.5 KiB
TypeScript

import { sql } from 'drizzle-orm';
import { boolean, doublePrecision, index, integer, jsonb, pgEnum, pgTable, serial, text, timestamp, uuid, varchar } from 'drizzle-orm/pg-core';
import { AreasServed, LicensedIn } from '../models/db.model';
export const PG_CONNECTION = 'PG_CONNECTION';
export const genderEnum = pgEnum('gender', ['male', 'female']);
export const customerTypeEnum = pgEnum('customerType', ['buyer', 'seller', 'professional']);
export const customerSubTypeEnum = pgEnum('customerSubType', ['broker', 'cpa', 'attorney', 'titleCompany', 'surveyor', 'appraiser']);
export const listingsCategoryEnum = pgEnum('listingsCategory', ['commercialProperty', 'business']);
export const subscriptionTypeEnum = pgEnum('subscriptionType', ['free', 'professional', 'broker']);
export const users = pgTable(
'users',
{
id: uuid('id').primaryKey().defaultRandom().notNull(),
firstname: varchar('firstname', { length: 255 }).notNull(),
lastname: varchar('lastname', { length: 255 }).notNull(),
email: varchar('email', { length: 255 }).notNull().unique(),
phoneNumber: varchar('phoneNumber', { length: 255 }),
description: text('description'),
companyName: varchar('companyName', { length: 255 }),
companyOverview: text('companyOverview'),
companyWebsite: varchar('companyWebsite', { length: 255 }),
offeredServices: text('offeredServices'),
areasServed: jsonb('areasServed').$type<AreasServed[]>(),
hasProfile: boolean('hasProfile'),
hasCompanyLogo: boolean('hasCompanyLogo'),
licensedIn: jsonb('licensedIn').$type<LicensedIn[]>(),
gender: genderEnum('gender'),
customerType: customerTypeEnum('customerType'),
customerSubType: customerSubTypeEnum('customerSubType'),
created: timestamp('created'),
updated: timestamp('updated'),
subscriptionId: text('subscriptionId'),
subscriptionPlan: subscriptionTypeEnum('subscriptionPlan'),
location: jsonb('location'),
// city: varchar('city', { length: 255 }),
// state: char('state', { length: 2 }),
// latitude: doublePrecision('latitude'),
// longitude: doublePrecision('longitude'),
},
table => ({
locationUserCityStateIdx: index('idx_user_location_city_state').on(
sql`((${table.location}->>'name')::varchar), ((${table.location}->>'state')::varchar), ((${table.location}->>'latitude')::float), ((${table.location}->>'longitude')::float)`,
),
}),
);
export const businesses = pgTable(
'businesses',
{
id: uuid('id').primaryKey().defaultRandom().notNull(),
email: varchar('email', { length: 255 }).references(() => users.email),
type: varchar('type', { length: 255 }),
title: varchar('title', { length: 255 }),
description: text('description'),
price: doublePrecision('price'),
favoritesForUser: varchar('favoritesForUser', { length: 30 }).array(),
draft: boolean('draft'),
listingsCategory: listingsCategoryEnum('listingsCategory'), //varchar('listingsCategory', { length: 255 }),
realEstateIncluded: boolean('realEstateIncluded'),
leasedLocation: boolean('leasedLocation'),
franchiseResale: boolean('franchiseResale'),
salesRevenue: doublePrecision('salesRevenue'),
cashFlow: doublePrecision('cashFlow'),
supportAndTraining: text('supportAndTraining'),
employees: integer('employees'),
established: integer('established'),
internalListingNumber: integer('internalListingNumber'),
reasonForSale: varchar('reasonForSale', { length: 255 }),
brokerLicencing: varchar('brokerLicencing', { length: 255 }),
internals: text('internals'),
imageName: varchar('imageName', { length: 200 }),
created: timestamp('created'),
updated: timestamp('updated'),
location: jsonb('location'),
// city: varchar('city', { length: 255 }),
// state: char('state', { length: 2 }),
// zipCode: integer('zipCode'),
// county: varchar('county', { length: 255 }),
// street: varchar('street', { length: 255 }),
// housenumber: varchar('housenumber', { length: 10 }),
// latitude: doublePrecision('latitude'),
// longitude: doublePrecision('longitude'),
},
table => ({
locationBusinessCityStateIdx: index('idx_business_location_city_state').on(
sql`((${table.location}->>'name')::varchar), ((${table.location}->>'state')::varchar), ((${table.location}->>'latitude')::float), ((${table.location}->>'longitude')::float)`,
),
}),
);
export const commercials = pgTable(
'commercials',
{
id: uuid('id').primaryKey().defaultRandom().notNull(),
serialId: serial('serialId'),
email: varchar('email', { length: 255 }).references(() => users.email),
type: varchar('type', { length: 255 }),
title: varchar('title', { length: 255 }),
description: text('description'),
price: doublePrecision('price'),
favoritesForUser: varchar('favoritesForUser', { length: 30 }).array(),
listingsCategory: listingsCategoryEnum('listingsCategory'), //listingsCategory: varchar('listingsCategory', { length: 255 }),
draft: boolean('draft'),
imageOrder: varchar('imageOrder', { length: 200 }).array(),
imagePath: varchar('imagePath', { length: 200 }),
created: timestamp('created'),
updated: timestamp('updated'),
location: jsonb('location'),
// city: varchar('city', { length: 255 }),
// state: char('state', { length: 2 }),
// zipCode: integer('zipCode'),
// county: varchar('county', { length: 255 }),
// street: varchar('street', { length: 255 }),
// housenumber: varchar('housenumber', { length: 10 }),
// latitude: doublePrecision('latitude'),
// longitude: doublePrecision('longitude'),
},
table => ({
locationCommercialsCityStateIdx: index('idx_commercials_location_city_state').on(
sql`((${table.location}->>'name')::varchar), ((${table.location}->>'state')::varchar), ((${table.location}->>'latitude')::float), ((${table.location}->>'longitude')::float)`,
),
}),
);
// export const geo = pgTable('geo', {
// id: uuid('id').primaryKey().defaultRandom().notNull(),
// country: varchar('country', { length: 255 }).default('us'),
// state: char('state', { length: 2 }),
// city: varchar('city', { length: 255 }),
// zipCode: integer('zipCode'),
// county: varchar('county', { length: 255 }),
// street: varchar('street', { length: 255 }),
// housenumber: varchar('housenumber', { length: 10 }),
// latitude: doublePrecision('latitude'),
// longitude: doublePrecision('longitude'),
// });
export const listingEvents = pgTable('listing_events', {
id: uuid('id').primaryKey().defaultRandom().notNull(),
listingId: uuid('listing_id'), // Assuming listings are referenced by UUID, adjust as necessary
userId: uuid('user_id'), // Nullable, if user is logged in, otherwise null
eventType: varchar('event_type', { length: 50 }), // 'view', 'print', 'email', 'facebook', 'x', 'linkedin', 'contact'
eventTimestamp: timestamp('event_timestamp').defaultNow(),
userIp: varchar('user_ip', { length: 45 }), // Optional if you choose to track IP in frontend or backend
userAgent: varchar('user_agent', { length: 255 }), // Store User-Agent as string
locationCountry: varchar('location_country', { length: 100 }), // Country from IP
locationCity: varchar('location_city', { length: 100 }), // City from IP
locationLat: varchar('location_lat', { length: 20 }), // Latitude from IP, stored as varchar
locationLng: varchar('location_lng', { length: 20 }), // Longitude from IP, stored as varchar
referrer: varchar('referrer', { length: 255 }), // Referrer URL if applicable
additionalData: jsonb('additional_data'), // JSON for any other optional data (like email, social shares etc.)
});