diff --git a/bizmatch-server/.gitignore b/bizmatch-server/.gitignore index 0b86619..563139f 100644 --- a/bizmatch-server/.gitignore +++ b/bizmatch-server/.gitignore @@ -56,4 +56,7 @@ pids report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json pictures -pictures_base \ No newline at end of file +pictures_base + +src/*.js +bun.lockb diff --git a/bizmatch-server/.vscode/launch.json b/bizmatch-server/.vscode/launch.json index c094940..6b473fd 100644 --- a/bizmatch-server/.vscode/launch.json +++ b/bizmatch-server/.vscode/launch.json @@ -27,6 +27,17 @@ "smartStep": true, "internalConsoleOptions": "openOnSessionStart" }, + { + "type": "node", + "request": "launch", + "name": "Launch TypeScript file", + "runtimeArgs": ["-r", "ts-node/register", "-r", "tsconfig-paths/register"], + "args": ["${workspaceFolder}/src/drizzle/import.ts"], + "cwd": "${workspaceFolder}", + "protocol": "inspector", + "outFiles": ["${workspaceFolder}/**/*.js"], + "skipFiles": ["/**", "${workspaceFolder}/node_modules/**/*.js"] + }, { "type": "node", "request": "launch", diff --git a/bizmatch-server/drizzle.config.ts b/bizmatch-server/drizzle.config.ts index 1fbe407..46b9f86 100644 --- a/bizmatch-server/drizzle.config.ts +++ b/bizmatch-server/drizzle.config.ts @@ -1,11 +1,12 @@ -import { defineConfig } from 'drizzle-kit' +import { defineConfig } from 'drizzle-kit'; export default defineConfig({ - schema: "./src/drizzle/schema.ts", - out: "./src/drizzle/migrations", - driver: 'pg', - dbCredentials: { - connectionString: process.env.DATABASE_URL, - }, - verbose: true, - strict: true, -}) \ No newline at end of file + schema: './src/drizzle/schema.ts', + out: './src/drizzle/migrations', + dialect: 'postgresql', + // driver: 'pg', + dbCredentials: { + url: process.env.DATABASE_URL, + }, + verbose: true, + strict: true, +}); diff --git a/bizmatch-server/package.json b/bizmatch-server/package.json index ecdb4b5..9a1ce67 100644 --- a/bizmatch-server/package.json +++ b/bizmatch-server/package.json @@ -19,7 +19,7 @@ "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", "test:e2e": "jest --config ./test/jest-e2e.json", - "generate": "drizzle-kit generate:pg", + "generate": "drizzle-kit generate", "drop": "drizzle-kit drop", "migrate": "tsx src/drizzle/migrate.ts", "import": "tsx src/drizzle/import.ts", @@ -40,7 +40,7 @@ "fs-extra": "^11.2.0", "handlebars": "^4.7.8", "jwks-rsa": "^3.1.0", - "ky": "^1.2.0", + "ky": "^1.4.0", "nest-winston": "^1.9.4", "nodemailer": "^6.9.10", "nodemailer-smtp-transport": "^2.7.4", @@ -90,7 +90,7 @@ "supertest": "^6.3.3", "ts-jest": "^29.1.0", "ts-loader": "^9.4.3", - "ts-node": "^10.9.1", + "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", "typescript": "^5.1.3" }, diff --git a/bizmatch-server/src/app.module.ts b/bizmatch-server/src/app.module.ts index 6cb91c2..054cf48 100644 --- a/bizmatch-server/src/app.module.ts +++ b/bizmatch-server/src/app.module.ts @@ -4,8 +4,6 @@ import { PassportModule } from '@nestjs/passport'; import * as dotenv from 'dotenv'; import fs from 'fs-extra'; import { WinstonModule, utilities as nestWinstonModuleUtilities } from 'nest-winston'; -import path from 'path'; -import { fileURLToPath } from 'url'; import * as winston from 'winston'; import { AppController } from './app.controller.js'; import { AppService } from './app.service.js'; @@ -18,8 +16,8 @@ import { MailModule } from './mail/mail.module.js'; import { RequestDurationMiddleware } from './request-duration/request-duration.middleware.js'; import { SelectOptionsModule } from './select-options/select-options.module.js'; import { UserModule } from './user/user.module.js'; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); +// const __filename = fileURLToPath(import.meta.url); +// const __dirname = path.dirname(__filename); function loadEnvFiles() { // Load the .env file diff --git a/bizmatch-server/src/auth/auth.module.ts b/bizmatch-server/src/auth/auth.module.ts index f1a8f81..0d88910 100644 --- a/bizmatch-server/src/auth/auth.module.ts +++ b/bizmatch-server/src/auth/auth.module.ts @@ -1,12 +1,9 @@ import { Module } from '@nestjs/common'; import { PassportModule } from '@nestjs/passport'; -import path from 'path'; -import { fileURLToPath } from 'url'; import { JwtStrategy } from '../jwt.strategy.js'; import { AuthController } from './auth.controller.js'; import { AuthService } from './auth.service.js'; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); + @Module({ imports: [PassportModule], providers: [AuthService, JwtStrategy], diff --git a/bizmatch-server/src/auth/auth.service.ts b/bizmatch-server/src/auth/auth.service.ts index 57be19b..822d432 100644 --- a/bizmatch-server/src/auth/auth.service.ts +++ b/bizmatch-server/src/auth/auth.service.ts @@ -1,11 +1,9 @@ import { Injectable } from '@nestjs/common'; -// import got from 'got'; import ky from 'ky'; import urlcat from 'urlcat'; @Injectable() export class AuthService { - public async getAccessToken() { const form = new FormData(); form.append('grant_type', 'password'); @@ -19,13 +17,15 @@ export class AuthService { params.append('password', process.env.password); const URL = `${process.env.host}${process.env.tokenURL}`; - const response = await ky.post(URL, { - body: params.toString(), - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization':'Basic YWRtaW4tY2xpOnE0RmJnazFkd0NaelFQZmt5VzhhM3NnckV5UHZlRUY3' - }, - }).json(); + const response = await ky + .post(URL, { + body: params.toString(), + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: 'Basic YWRtaW4tY2xpOnE0RmJnazFkd0NaelFQZmt5VzhhM3NnckV5UHZlRUY3', + }, + }) + .json(); return (response).access_token; } catch (error) { if (error.name === 'HTTPError') { @@ -37,71 +37,83 @@ export class AuthService { } } - public async getUsers(){ + public async getUsers() { const token = await this.getAccessToken(); const URL = `${process.env.host}${process.env.usersURL}`; - const response = await ky.get(URL, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization':`Bearer ${token}` - }, - }).json(); - return response + const response = await ky + .get(URL, { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: `Bearer ${token}`, + }, + }) + .json(); + return response; } - public async getUser(userid:string){ + public async getUser(userid: string) { const token = await this.getAccessToken(); - const URL = urlcat(process.env.host,process.env.userURL,{userid}) - const response = await ky.get(URL, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization':`Bearer ${token}` - }, - }).json(); - return response + const URL = urlcat(process.env.host, process.env.userURL, { userid }); + const response = await ky + .get(URL, { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: `Bearer ${token}`, + }, + }) + .json(); + return response; } - public async getGroups(){ + public async getGroups() { const token = await this.getAccessToken(); const URL = `${process.env.host}${process.env.groupsURL}`; - const response = await ky.get(URL, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization':`Bearer ${token}` - }, - }).json(); - return response + const response = await ky + .get(URL, { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: `Bearer ${token}`, + }, + }) + .json(); + return response; } - public async getGroupsForUser(userid:string){ + public async getGroupsForUser(userid: string) { const token = await this.getAccessToken(); - const URL = urlcat(process.env.host,process.env.userGroupsURL,{userid}) - const response = await ky.get(URL, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization':`Bearer ${token}` - }, - }).json(); - return response + const URL = urlcat(process.env.host, process.env.userGroupsURL, { userid }); + const response = await ky + .get(URL, { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: `Bearer ${token}`, + }, + }) + .json(); + return response; } - public async getLastLogin(userid:string){ + public async getLastLogin(userid: string) { const token = await this.getAccessToken(); - const URL = urlcat(process.env.host,process.env.lastLoginURL,{userid}) - const response = await ky.get(URL, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization':`Bearer ${token}` - }, - }).json(); - return response + const URL = urlcat(process.env.host, process.env.lastLoginURL, { userid }); + const response = await ky + .get(URL, { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: `Bearer ${token}`, + }, + }) + .json(); + return response; } - public async addUser2Group(userid:string,groupid:string){ + public async addUser2Group(userid: string, groupid: string) { const token = await this.getAccessToken(); - const URL = urlcat(process.env.host,process.env.addUser2GroupURL,{userid,groupid}) - const response = await ky.put(URL, { - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization':`Bearer ${token}` - }, - }).json(); - return response + const URL = urlcat(process.env.host, process.env.addUser2GroupURL, { userid, groupid }); + const response = await ky + .put(URL, { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: `Bearer ${token}`, + }, + }) + .json(); + return response; } } diff --git a/bizmatch-server/src/drizzle/import.ts b/bizmatch-server/src/drizzle/import.ts index f1c8b05..ae259a8 100644 --- a/bizmatch-server/src/drizzle/import.ts +++ b/bizmatch-server/src/drizzle/import.ts @@ -1,15 +1,30 @@ import 'dotenv/config'; import { drizzle } from 'drizzle-orm/node-postgres'; -import { existsSync, readFileSync, readdirSync, statSync, unlinkSync } from 'fs'; +import { existsSync, readdirSync, readFileSync, statSync, unlinkSync } from 'fs'; import fs from 'fs-extra'; import OpenAI from 'openai'; import { join } from 'path'; import pkg from 'pg'; import { rimraf } from 'rimraf'; import sharp from 'sharp'; -import { BusinessListing, CommercialPropertyListing, User, UserData } from 'src/models/db.model.js'; -import { emailToDirName } from 'src/models/main.model.js'; +import { BusinessListing, CommercialPropertyListing, User, UserData } from '../models/db.model.js'; +import { emailToDirName, KeyValueStyle } from '../models/main.model.js'; import * as schema from './schema.js'; +const typesOfBusiness: Array = [ + { name: 'Automotive', value: '1', icon: 'fa-solid fa-car', textColorClass: 'text-green-400' }, + { name: 'Industrial Services', value: '2', icon: 'fa-solid fa-industry', textColorClass: 'text-yellow-400' }, + { name: 'Real Estate', value: '3', icon: 'fa-solid fa-building', textColorClass: 'text-blue-400' }, + { name: 'Uncategorized', value: '4', icon: 'fa-solid fa-question', textColorClass: 'text-cyan-400' }, + { name: 'Retail', value: '5', icon: 'fa-solid fa-money-bill-wave', textColorClass: 'text-pink-400' }, + { name: 'Oilfield SVE and MFG.', value: '6', icon: 'fa-solid fa-oil-well', textColorClass: 'text-indigo-400' }, + { name: 'Service', value: '7', icon: 'fa-solid fa-umbrella', textColorClass: 'text-teal-400' }, + { name: 'Advertising', value: '8', icon: 'fa-solid fa-rectangle-ad', textColorClass: 'text-orange-400' }, + { name: 'Agriculture', value: '9', icon: 'fa-solid fa-wheat-awn', textColorClass: 'text-sky-400' }, + { name: 'Franchise', value: '10', icon: 'fa-solid fa-star', textColorClass: 'text-purple-400' }, + { name: 'Professional', value: '11', icon: 'fa-solid fa-user-gear', textColorClass: 'text-gray-400' }, + { name: 'Manufacturing', value: '12', icon: 'fa-solid fa-industry', textColorClass: 'text-red-400' }, + { name: 'Food and Restaurant', value: '13', icon: 'fa-solid fa-utensils', textColorClass: 'text-amber-700' }, +]; const { Pool } = pkg; const openai = new OpenAI({ @@ -88,11 +103,11 @@ for (const userData of usersData) { const data = readFileSync(`./pictures_base/logo/${i}.jpg`); await storeCompanyLogo(data, emailToDirName(u[0].email)); } + //Business Listings filePath = `./data/businesses.json`; data = readFileSync(filePath, 'utf8'); const businessJsonData = JSON.parse(data) as BusinessListing[]; // Erwartet ein Array von Objekten - for (const business of businessJsonData) { delete business.id; business.created = new Date(business.created); @@ -100,7 +115,28 @@ for (const business of businessJsonData) { const user = getRandomItem(generatedUserData); business.userId = user.insertedId; business.imageName = emailToDirName(user.email); - await db.insert(schema.businesses).values(business); + const embeddingText = JSON.stringify({ + type: typesOfBusiness.find(b => b.value === String(business.type))?.name, + title: business.title, + description: business.description, + city: business.city, + state: business.state, + price: business.price, + realEstateIncluded: business.realEstateIncluded, + leasedLocation: business.leasedLocation, + franchiseResale: business.franchiseResale, + salesRevenue: business.salesRevenue, + cashFlow: business.cashFlow, + supportAndTraining: business.supportAndTraining, + employees: business.employees, + established: business.established, + reasonForSale: business.reasonForSale, + }); + const embedding = await createEmbedding(embeddingText); + await db.insert(schema.businesses).values({ + ...business, + embedding: embedding, + }); } //Corporate Listings filePath = `./data/commercials.json`; @@ -131,7 +167,7 @@ await client.end(); async function createEmbedding(text: string): Promise { const response = await openai.embeddings.create({ - model: 'text-embedding-ada-002', + model: 'text-embedding-3-small', input: text, }); return response.data[0].embedding; diff --git a/bizmatch-server/src/drizzle/migrate.ts b/bizmatch-server/src/drizzle/migrate.ts index c008ec3..f114bec 100644 --- a/bizmatch-server/src/drizzle/migrate.ts +++ b/bizmatch-server/src/drizzle/migrate.ts @@ -1,13 +1,12 @@ import 'dotenv/config'; import { drizzle } from 'drizzle-orm/node-postgres'; import pkg from 'pg'; -const { Pool } = pkg; import * as schema from './schema.js'; -import { migrate } from 'drizzle-orm/node-postgres/migrator'; -const connectionString = process.env.DATABASE_URL -const pool = new Pool({connectionString}) +const { Pool } = pkg; +const connectionString = process.env.DATABASE_URL; +const pool = new Pool({ connectionString }); const db = drizzle(pool, { schema }); // This will run migrations on the database, skipping the ones already applied -await migrate(db, { migrationsFolder: './src/drizzle/migrations' }); +//await migrate(db, { migrationsFolder: './src/drizzle/migrations' }); // Don't forget to close the connection, otherwise the script will hang -await pool.end(); \ No newline at end of file +//await pool.end(); diff --git a/bizmatch-server/src/drizzle/migrations/0001_eager_sandman.sql b/bizmatch-server/src/drizzle/migrations/0001_eager_sandman.sql new file mode 100644 index 0000000..ebab33a --- /dev/null +++ b/bizmatch-server/src/drizzle/migrations/0001_eager_sandman.sql @@ -0,0 +1 @@ +ALTER TABLE "businesses" ADD COLUMN "embedding" vector(1536); \ No newline at end of file diff --git a/bizmatch-server/src/drizzle/migrations/meta/0000_snapshot.json b/bizmatch-server/src/drizzle/migrations/meta/0000_snapshot.json index 6305d03..c7c464b 100644 --- a/bizmatch-server/src/drizzle/migrations/meta/0000_snapshot.json +++ b/bizmatch-server/src/drizzle/migrations/meta/0000_snapshot.json @@ -1,10 +1,8 @@ { - "id": "f8241dfe-8f15-4656-aeb5-c9ef0ad65f28", - "prevId": "00000000-0000-0000-0000-000000000000", - "version": "5", - "dialect": "pg", + "version": "7", + "dialect": "postgresql", "tables": { - "businesses": { + "public.businesses": { "name": "businesses", "schema": "", "columns": { @@ -183,21 +181,21 @@ "businesses_userId_users_id_fk": { "name": "businesses_userId_users_id_fk", "tableFrom": "businesses", - "tableTo": "users", "columnsFrom": [ "userId" ], + "tableTo": "users", "columnsTo": [ "id" ], - "onDelete": "no action", - "onUpdate": "no action" + "onUpdate": "no action", + "onDelete": "no action" } }, "compositePrimaryKeys": {}, "uniqueConstraints": {} }, - "commercials": { + "public.commercials": { "name": "commercials", "schema": "", "columns": { @@ -352,21 +350,21 @@ "commercials_userId_users_id_fk": { "name": "commercials_userId_users_id_fk", "tableFrom": "commercials", - "tableTo": "users", "columnsFrom": [ "userId" ], + "tableTo": "users", "columnsTo": [ "id" ], - "onDelete": "no action", - "onUpdate": "no action" + "onUpdate": "no action", + "onDelete": "no action" } }, "compositePrimaryKeys": {}, "uniqueConstraints": {} }, - "users": { + "public.users": { "name": "users", "schema": "", "columns": { @@ -499,36 +497,41 @@ } }, "enums": { - "customerSubType": { + "public.customerSubType": { "name": "customerSubType", - "values": { - "broker": "broker", - "cpa": "cpa", - "attorney": "attorney", - "titleCompany": "titleCompany", - "surveyor": "surveyor", - "appraiser": "appraiser" - } + "schema": "public", + "values": [ + "broker", + "cpa", + "attorney", + "titleCompany", + "surveyor", + "appraiser" + ] }, - "customerType": { + "public.customerType": { "name": "customerType", - "values": { - "buyer": "buyer", - "professional": "professional" - } + "schema": "public", + "values": [ + "buyer", + "professional" + ] }, - "gender": { + "public.gender": { "name": "gender", - "values": { - "male": "male", - "female": "female" - } + "schema": "public", + "values": [ + "male", + "female" + ] } }, "schemas": {}, "_meta": { - "columns": {}, "schemas": {}, - "tables": {} - } + "tables": {}, + "columns": {} + }, + "id": "f8241dfe-8f15-4656-aeb5-c9ef0ad65f28", + "prevId": "00000000-0000-0000-0000-000000000000" } \ No newline at end of file diff --git a/bizmatch-server/src/drizzle/migrations/meta/0001_snapshot.json b/bizmatch-server/src/drizzle/migrations/meta/0001_snapshot.json new file mode 100644 index 0000000..d7d5f1f --- /dev/null +++ b/bizmatch-server/src/drizzle/migrations/meta/0001_snapshot.json @@ -0,0 +1,547 @@ +{ + "id": "aac13d99-fd8d-44f9-bfb0-f00cef85809d", + "prevId": "f8241dfe-8f15-4656-aeb5-c9ef0ad65f28", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.businesses": { + "name": "businesses", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "char(2)", + "primaryKey": false, + "notNull": false + }, + "price": { + "name": "price", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "favoritesForUser": { + "name": "favoritesForUser", + "type": "varchar(30)[]", + "primaryKey": false, + "notNull": false + }, + "draft": { + "name": "draft", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "listingsCategory": { + "name": "listingsCategory", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "realEstateIncluded": { + "name": "realEstateIncluded", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "leasedLocation": { + "name": "leasedLocation", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "franchiseResale": { + "name": "franchiseResale", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "salesRevenue": { + "name": "salesRevenue", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "cashFlow": { + "name": "cashFlow", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "supportAndTraining": { + "name": "supportAndTraining", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "employees": { + "name": "employees", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "established": { + "name": "established", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "internalListingNumber": { + "name": "internalListingNumber", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reasonForSale": { + "name": "reasonForSale", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "brokerLicencing": { + "name": "brokerLicencing", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "internals": { + "name": "internals", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "imagePath": { + "name": "imagePath", + "type": "varchar(200)", + "primaryKey": false, + "notNull": false + }, + "created": { + "name": "created", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated": { + "name": "updated", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "visits": { + "name": "visits", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lastVisit": { + "name": "lastVisit", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "embedding": { + "name": "embedding", + "type": "vector(1536)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "businesses_userId_users_id_fk": { + "name": "businesses_userId_users_id_fk", + "tableFrom": "businesses", + "tableTo": "users", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.commercials": { + "name": "commercials", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "serial_id": { + "name": "serial_id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "city": { + "name": "city", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "char(2)", + "primaryKey": false, + "notNull": false + }, + "price": { + "name": "price", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "favoritesForUser": { + "name": "favoritesForUser", + "type": "varchar(30)[]", + "primaryKey": false, + "notNull": false + }, + "listingsCategory": { + "name": "listingsCategory", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "hideImage": { + "name": "hideImage", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "draft": { + "name": "draft", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "zipCode": { + "name": "zipCode", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "county": { + "name": "county", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "website": { + "name": "website", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "phoneNumber": { + "name": "phoneNumber", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "imageOrder": { + "name": "imageOrder", + "type": "varchar(200)[]", + "primaryKey": false, + "notNull": false + }, + "imagePath": { + "name": "imagePath", + "type": "varchar(200)", + "primaryKey": false, + "notNull": false + }, + "created": { + "name": "created", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated": { + "name": "updated", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "visits": { + "name": "visits", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lastVisit": { + "name": "lastVisit", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "commercials_userId_users_id_fk": { + "name": "commercials_userId_users_id_fk", + "tableFrom": "commercials", + "tableTo": "users", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "firstname": { + "name": "firstname", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "lastname": { + "name": "lastname", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "phoneNumber": { + "name": "phoneNumber", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "companyName": { + "name": "companyName", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "companyOverview": { + "name": "companyOverview", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "companyWebsite": { + "name": "companyWebsite", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "companyLocation": { + "name": "companyLocation", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "offeredServices": { + "name": "offeredServices", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "areasServed": { + "name": "areasServed", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hasProfile": { + "name": "hasProfile", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "hasCompanyLogo": { + "name": "hasCompanyLogo", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "licensedIn": { + "name": "licensedIn", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "gender": { + "name": "gender", + "type": "gender", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "customerType": { + "name": "customerType", + "type": "customerType", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "customerSubType": { + "name": "customerSubType", + "type": "customerSubType", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "created": { + "name": "created", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated": { + "name": "updated", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.customerSubType": { + "name": "customerSubType", + "schema": "public", + "values": [ + "broker", + "cpa", + "attorney", + "titleCompany", + "surveyor", + "appraiser" + ] + }, + "public.customerType": { + "name": "customerType", + "schema": "public", + "values": [ + "buyer", + "professional" + ] + }, + "public.gender": { + "name": "gender", + "schema": "public", + "values": [ + "male", + "female" + ] + } + }, + "schemas": {}, + "sequences": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/bizmatch-server/src/drizzle/migrations/meta/_journal.json b/bizmatch-server/src/drizzle/migrations/meta/_journal.json index 0afd75c..f591828 100644 --- a/bizmatch-server/src/drizzle/migrations/meta/_journal.json +++ b/bizmatch-server/src/drizzle/migrations/meta/_journal.json @@ -8,6 +8,13 @@ "when": 1717933164279, "tag": "0000_known_havok", "breakpoints": true + }, + { + "idx": 1, + "version": "7", + "when": 1720777203223, + "tag": "0001_eager_sandman", + "breakpoints": true } ] } \ No newline at end of file diff --git a/bizmatch-server/src/drizzle/schema.ts b/bizmatch-server/src/drizzle/schema.ts index 7958f2d..ec51884 100644 --- a/bizmatch-server/src/drizzle/schema.ts +++ b/bizmatch-server/src/drizzle/schema.ts @@ -1,5 +1,5 @@ import { boolean, char, doublePrecision, integer, jsonb, pgEnum, pgTable, serial, text, timestamp, uuid, varchar, vector } from 'drizzle-orm/pg-core'; -import { AreasServed, LicensedIn } from 'src/models/db.model'; +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', 'professional']); diff --git a/bizmatch-server/src/listings/commercial-property-listings.controller.ts b/bizmatch-server/src/listings/commercial-property-listings.controller.ts index 23e5666..7054a5b 100644 --- a/bizmatch-server/src/listings/commercial-property-listings.controller.ts +++ b/bizmatch-server/src/listings/commercial-property-listings.controller.ts @@ -1,10 +1,10 @@ import { Body, Controller, Delete, Get, Inject, Param, Post, Put, Request, UseGuards } from '@nestjs/common'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; -import { CommercialPropertyListing } from 'src/models/db.model.js'; import { Logger } from 'winston'; import { commercials } from '../drizzle/schema.js'; import { FileService } from '../file/file.service.js'; import { OptionalJwtAuthGuard } from '../jwt-auth/optional-jwt-auth.guard.js'; +import { CommercialPropertyListing } from '../models/db.model'; import { JwtUser, ListingCriteria } from '../models/main.model.js'; import { ListingsService } from './listings.service.js'; diff --git a/bizmatch-server/src/listings/listings.service.ts b/bizmatch-server/src/listings/listings.service.ts index 70e3ac7..6456262 100644 --- a/bizmatch-server/src/listings/listings.service.ts +++ b/bizmatch-server/src/listings/listings.service.ts @@ -2,11 +2,11 @@ import { Inject, Injectable } from '@nestjs/common'; import { and, eq, gte, ilike, lte, ne, or, sql } from 'drizzle-orm'; import { NodePgDatabase } from 'drizzle-orm/node-postgres'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; -import { BusinessListing, CommercialPropertyListing } from 'src/models/db.model.js'; import { Logger } from 'winston'; import * as schema from '../drizzle/schema.js'; import { PG_CONNECTION, businesses, commercials } from '../drizzle/schema.js'; import { FileService } from '../file/file.service.js'; +import { BusinessListing, CommercialPropertyListing } from '../models/db.model'; import { JwtUser, ListingCriteria, emailToDirName } from '../models/main.model.js'; @Injectable() diff --git a/bizmatch-server/src/mail/mail.controller.ts b/bizmatch-server/src/mail/mail.controller.ts index 54e08b7..256a6c9 100644 --- a/bizmatch-server/src/mail/mail.controller.ts +++ b/bizmatch-server/src/mail/mail.controller.ts @@ -1,5 +1,5 @@ import { Body, Controller, Post } from '@nestjs/common'; -import { ErrorResponse, MailInfo } from 'src/models/main.model.js'; +import { ErrorResponse, MailInfo } from '../models/main.model'; import { MailService } from './mail.service.js'; @Controller('mail') diff --git a/bizmatch-server/src/main.ts b/bizmatch-server/src/main.ts index bd873a8..255db8c 100644 --- a/bizmatch-server/src/main.ts +++ b/bizmatch-server/src/main.ts @@ -1,10 +1,7 @@ import { NestFactory } from '@nestjs/core'; import express from 'express'; -import path from 'path'; -import { fileURLToPath } from 'url'; import { AppModule } from './app.module.js'; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); + async function bootstrap() { const server = express(); const app = await NestFactory.create(AppModule); diff --git a/bizmatch-server/src/models/server.model.ts b/bizmatch-server/src/models/server.model.ts index 3bfbf67..98d2bfe 100644 --- a/bizmatch-server/src/models/server.model.ts +++ b/bizmatch-server/src/models/server.model.ts @@ -1,4 +1,3 @@ -import { Entity } from "redis-om"; export interface Geo { id: number; name: string; diff --git a/bizmatch-server/src/user/user.controller.ts b/bizmatch-server/src/user/user.controller.ts index 6b5bf11..d792193 100644 --- a/bizmatch-server/src/user/user.controller.ts +++ b/bizmatch-server/src/user/user.controller.ts @@ -1,8 +1,8 @@ import { Body, Controller, Get, Inject, Param, Post, Query } from '@nestjs/common'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; -import { User } from 'src/models/db.model.js'; import { Logger } from 'winston'; import { FileService } from '../file/file.service.js'; +import { User } from '../models/db.model'; import { Subscription } from '../models/main.model.js'; import { UserService } from './user.service.js';