geo coding, user service, listing for business

This commit is contained in:
2024-03-10 20:59:23 +01:00
parent 06f349d1c3
commit 6ad40b6dca
59 changed files with 120466 additions and 687 deletions

View File

@@ -1,7 +0,0 @@
/// <reference types="multer" />
import { FileService } from '../file/file.service.js';
export declare class AccountController {
private fileService;
constructor(fileService: FileService);
uploadFile(file: Express.Multer.File, id: string): void;
}

View File

@@ -1,2 +0,0 @@
export declare class AccountService {
}

View File

@@ -1,6 +0,0 @@
import { AppService } from './app.service.js';
export declare class AppController {
private readonly appService;
constructor(appService: AppService);
getHello(): string;
}

View File

@@ -1,2 +0,0 @@
export declare class AppModule {
}

View File

@@ -1,3 +0,0 @@
export declare class AppService {
getHello(): string;
}

View File

@@ -1,66 +0,0 @@
[
{
"id":"1",
"userId":"1",
"listingsCategory": "business",
"title": "Industrial Service Company In Corpus Christi For Sale - 1954",
"summary": ["Asking price: $5,500,000","Sales revenue: $1,200,000","Net profit: $650,000"],
"description": ["This company services a wide variety of industries. Asking price includes Business and the Real Estate and is approx 30,000 sq ft with room for expansion including approx 5 acres. Absentee run business."],
"type": "2",
"location": "Texas",
"price":5500000,
"salesRevenue":1200000,
"cashFlow":650000,
"brokerLicencing":"TREC Broker #516788",
"established":1954,
"realEstateIncluded":true
},
{
"id":"2",
"userId":"1",
"listingsCategory": "business",
"title": "Coastal Bend Manufacturing Business Plastic Injection For Sale - 1950",
"summary": ["Asking price: $165,000","Sales revenue: Undisclosed","Net profit: Undisclosed"],
"description": [""],
"type": "12",
"location": "Texas",
"price":165000,
"salesRevenue":null,
"cashFlow":null,
"brokerLicencing":"TREC Broker #516788",
"established":1950,
"realEstateIncluded":false
},
{
"id":"3",
"userId":"1",
"listingsCategory": "business",
"title": "Corner Property On Everhart South-side Corpus Christi For Sale - 1944",
"summary": ["Asking price: $830,000","Sales revenue: Undisclosed","Net profit: Undisclosed"],
"description": [""],
"type": "3",
"location": "Texas",
"price":830000,
"salesRevenue":null,
"cashFlow":null,
"brokerLicencing":"TREC Broker #516788",
"established":1944,
"realEstateIncluded":false
},
{
"id":"4",
"userId":"1",
"listingsCategory": "business",
"title": "Corpus Christi Dessert Business For Sale - 1941",
"summary": ["Asking price: $124,900","Sales revenue: $225,000","Net profit: $50,000"],
"description": [""],
"type": "13",
"location": "Texas",
"price":830000,
"salesRevenue":225000,
"cashFlow":50000,
"brokerLicencing":"TREC Broker #516788",
"established":1941,
"realEstateIncluded":false
}
]

View File

@@ -1,14 +0,0 @@
[{
"id":"1",
"userId":"e0811669-c7eb-4e5e-a699-e8334d5c5b01",
"level":"Business Broker",
"start":"2024-02-12T21:54:20.603Z",
"modified":"2024-02-12T21:54:20.603Z",
"end":"9999-02-12T21:54:20.603Z",
"status":"active",
"invoices":[{
"date":"2024-02-12T21:54:20.603Z",
"id":"C991853B99",
"price":0
}]
}]

View File

@@ -1,8 +0,0 @@
/// <reference types="multer" />
export declare class FileService {
private subscriptions;
constructor();
private loadSubscriptions;
getSubscriptions(): any;
storeFile(file: Express.Multer.File, id: string): Promise<void>;
}

View File

@@ -1,13 +0,0 @@
import { ListingsService } from './listings.service.js';
import { Logger } from 'winston';
export declare class ListingsController {
private readonly listingsService;
private readonly logger;
constructor(listingsService: ListingsService, logger: Logger);
findAll(): any;
findById(id: string): any;
find(criteria: any): any;
updateById(id: string, listing: any): void;
create(listing: any): void;
deleteById(id: string): void;
}

View File

@@ -1,13 +0,0 @@
import { BusinessListing, InvestmentsListing, ListingCriteria, ProfessionalsBrokersListing } from '../models/main.model.js';
import { RedisService } from '../redis/redis.service.js';
import { Logger } from 'winston';
export declare class ListingsService {
private redisService;
private readonly logger;
constructor(redisService: RedisService, logger: Logger);
setListing(value: BusinessListing | ProfessionalsBrokersListing | InvestmentsListing, id?: string): Promise<void>;
getListingById(id: string): Promise<any>;
deleteListing(id: string): void;
getAllListings(start?: number, end?: number): Promise<any>;
find(criteria: ListingCriteria): Promise<any>;
}

View File

@@ -1,7 +0,0 @@
import { MailService } from './mail.service.js';
import { MailInfo } from '../models/server.model.js';
export declare class MailController {
private mailService;
constructor(mailService: MailService);
sendEMail(id: string, mailInfo: MailInfo): any;
}

View File

@@ -1,2 +0,0 @@
export declare class MailModule {
}

View File

@@ -1,9 +0,0 @@
import { MailerService } from '@nestjs-modules/mailer';
import { AuthService } from '../auth/auth.service.js';
import { MailInfo } from '../models/server.model.js';
export declare class MailService {
private mailerService;
private authService;
constructor(mailerService: MailerService, authService: AuthService);
sendInquiry(userId: string, mailInfo: MailInfo): Promise<void>;
}

View File

@@ -1,5 +0,0 @@
<p>Hey {{ name }},</p>
<p>You got an inquiry a</p>
<p>
{{inquiry}}
</p>

View File

@@ -1 +0,0 @@
export {};

View File

@@ -1,126 +0,0 @@
export interface KeyValue {
name: string;
value: string;
}
export interface KeyValueStyle {
name: string;
value: string;
icon: string;
bgColorClass: string;
textColorClass: string;
}
export type SelectOption<T = number> = {
value: T;
label: string;
};
export interface Listing {
id: string;
userId: string;
title: string;
description: Array<string>;
location: string;
favoritesForUser: Array<string>;
hideImage?: boolean;
created: Date;
updated: Date;
}
export interface BusinessListing extends Listing {
listingsCategory: 'business';
summary: Array<string>;
type: string;
price?: number;
realEstateIncluded?: boolean;
salesRevenue?: number;
cashFlow?: number;
netProfit?: number;
inventory?: string;
employees?: number;
established?: number;
reasonForSale?: string;
brokerLicencing?: string;
internals?: string;
}
export interface ProfessionalsBrokersListing extends Listing {
listingsCategory: 'professionals_brokers';
summary: string;
address?: string;
email?: string;
website?: string;
category?: 'Professionals' | 'Broker';
}
export interface InvestmentsListing extends Listing {
listingsCategory: 'investment';
email?: string;
website?: string;
phoneNumber?: string;
}
export type ListingType = BusinessListing | ProfessionalsBrokersListing | InvestmentsListing;
export interface ListingCriteria {
type: string;
location: string;
minPrice: string;
maxPrice: string;
realEstateChecked: boolean;
listingsCategory: 'business' | 'professionals_brokers' | 'investment';
category: 'professional|broker';
}
export interface User {
id: string;
username: string;
firstname: string;
lastname: string;
email: string;
}
export interface Subscription {
id: string;
userId: string;
level: string;
start: Date;
modified: Date;
end: Date;
status: string;
invoices: Array<Invoice>;
}
export interface Invoice {
id: string;
date: Date;
price: number;
}
export interface JwtToken {
exp: number;
iat: number;
auth_time: number;
jti: string;
iss: string;
aud: string;
sub: string;
typ: string;
azp: string;
nonce: string;
session_state: string;
acr: string;
realm_access: Realmaccess;
resource_access: Resourceaccess;
scope: string;
sid: string;
email_verified: boolean;
name: string;
preferred_username: string;
given_name: string;
family_name: string;
email: string;
user_id: string;
}
interface Resourceaccess {
account: Realmaccess;
}
interface Realmaccess {
roles: string[];
}
export interface PageEvent {
first: number;
rows: number;
page: number;
pageCount: number;
}
export {};

View File

@@ -1,129 +0,0 @@
export interface KeyValue {
name: string;
value: string;
}
export interface KeyValueStyle {
name: string;
value: string;
icon:string;
bgColorClass:string;
textColorClass:string;
}
export type SelectOption<T = number> = {
value: T;
label: string;
};
export interface Listing {
id: string;
userId: string;
title: string;
description: Array<string>;
location: string;//enum
favoritesForUser:Array<string>;
hideImage?:boolean;
created:Date;
updated:Date;
}
export interface BusinessListing extends Listing {
listingsCategory: 'business'; //enum
summary: Array<string>;
type: string; //enum
price?: number;
realEstateIncluded?: boolean;
salesRevenue?: number;
cashFlow?: number;
netProfit?: number;
inventory?: string;
employees?: number;
established?: number;
reasonForSale?: string;
brokerLicencing?: string;
internals?: string;
}
export interface ProfessionalsBrokersListing extends Listing {
listingsCategory: 'professionals_brokers'; //enum
summary: string;
address?: string;
email?: string;
website?: string;
category?: 'Professionals' | 'Broker';
}
export interface InvestmentsListing extends Listing {
listingsCategory: 'investment'; //enum
email?: string;
website?: string;
phoneNumber?: string;
}
export type ListingType =
| BusinessListing
| ProfessionalsBrokersListing
| InvestmentsListing;
export interface ListingCriteria {
type:string,
location:string,
minPrice:string,
maxPrice:string,
realEstateChecked:boolean,
listingsCategory:'business'|'professionals_brokers'|'investment',
category:'professional|broker'
}
export interface User {
id: string;
username: string;
firstname: string;
lastname: string;
email: string;
}
export interface Subscription {
id: string;
userId:string
level: string;
start: Date;
modified: Date;
end: Date;
status: string;
invoices: Array<Invoice>;
}
export interface Invoice {
id: string,
date: Date,
price: number
}
export interface JwtToken {
exp: number;
iat: number;
auth_time: number;
jti: string;
iss: string;
aud: string;
sub: string;
typ: string;
azp: string;
nonce: string;
session_state: string;
acr: string;
realm_access: Realmaccess;
resource_access: Resourceaccess;
scope: string;
sid: string;
email_verified: boolean;
name: string;
preferred_username: string;
given_name: string;
family_name: string;
email: string;
user_id: string;
}
interface Resourceaccess {
account: Realmaccess;
}
interface Realmaccess {
roles: string[];
}
export interface PageEvent {
first: number;
rows: number;
page: number;
pageCount: number;
}

View File

@@ -1,11 +0,0 @@
export interface MailInfo {
sender: Sender;
userId: string;
}
export interface Sender {
name: string;
email: string;
phoneNumber: string;
state: string;
comments: string;
}

View File

@@ -1,5 +0,0 @@
import { RedisService } from './redis.service.js';
export declare class RedisController {
private redisService;
constructor(redisService: RedisService);
}

View File

@@ -1,2 +0,0 @@
export declare class RedisModule {
}

View File

@@ -1,11 +0,0 @@
export declare const LISTINGS = "LISTINGS";
export declare const SUBSCRIPTIONS = "SUBSCRIPTIONS";
export declare const USERS = "USERS";
export declare class RedisService {
private redis;
setJson(id: string, value: any): Promise<void>;
delete(id: string): Promise<void>;
getJson(id: string, prefix: string): Promise<any>;
getId(prefix: 'LISTINGS' | 'SUBSCRIPTIONS' | 'USERS'): Promise<string>;
search(prefix: 'LISTINGS' | 'SUBSCRIPTIONS' | 'USERS', clause: string): Promise<any>;
}

View File

@@ -1,6 +0,0 @@
import { SelectOptionsService } from './select-options.service.js';
export declare class SelectOptionsController {
private selectOptionsService;
constructor(selectOptionsService: SelectOptionsService);
getSelectOption(): any;
}

View File

@@ -1,10 +0,0 @@
import { KeyValue, KeyValueStyle } from '../models/main.model.js';
export declare class SelectOptionsService {
constructor();
typesOfBusiness: Array<KeyValueStyle>;
prices: Array<KeyValue>;
listingCategories: Array<KeyValue>;
categories: Array<KeyValueStyle>;
private usStates;
locations: Array<any>;
}

View File

@@ -1,6 +0,0 @@
import { FileService } from '../file/file.service.js';
export declare class SubscriptionsController {
private readonly fileService;
constructor(fileService: FileService);
findAll(): any;
}

View File

@@ -1 +0,0 @@
export declare function convertStringToNullUndefined(value: any): any;

View File

@@ -30,7 +30,6 @@
"@nestjs/platform-express": "^10.0.0",
"@nestjs/serve-static": "^4.0.1",
"handlebars": "^4.7.8",
"ioredis": "^5.3.2",
"ky": "^1.2.0",
"nest-winston": "^1.9.4",
"nodemailer": "^6.9.10",
@@ -39,6 +38,8 @@
"passport-google-oauth20": "^2.0.0",
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"redis": "^4.6.13",
"redis-om": "^0.4.3",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1",
"urlcat": "^3.1.0",

View File

@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { AccountController } from './account.controller.js';
import { AccountService } from './account.service.js';
import { FileService } from '../file/file.service.js';
@Module({
controllers: [AccountController],
providers: [AccountService,FileService]
})
export class AccountModule {}

View File

@@ -20,11 +20,16 @@ import { utilities as nestWinstonModuleUtilities, WinstonModule } from 'nest-win
import * as winston from 'winston';
import { MailModule } from './mail/mail.module.js';
import { AuthModule } from './auth/auth.module.js';
import { GeoModule } from './geo/geo.module.js';
import { UserModule } from './user/user.module.js';
import { ListingsModule } from './listings/listings.module.js';
import { AccountModule } from './account/account.module.js';
import { SelectOptionsModule } from './select-options/select-options.module.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@Module({
imports: [ConfigModule.forRoot(), RedisModule, MailModule, AuthModule,
imports: [ConfigModule.forRoot(), MailModule, AuthModule,
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'), // `public` ist das Verzeichnis, wo Ihre statischen Dateien liegen
}),
@@ -43,9 +48,15 @@ const __dirname = path.dirname(__filename);
// other transports...
],
// other options
})
}),
GeoModule,
UserModule,
ListingsModule,
AccountModule,
SelectOptionsModule,
RedisModule
],
controllers: [AppController, ListingsController, SelectOptionsController, SubscriptionsController, AccountController],
providers: [AppService, FileService, SelectOptionsService, ListingsService, AccountService],
controllers: [AppController, SubscriptionsController],
providers: [AppService, FileService],
})
export class AppModule {}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
import { Controller, Get, Param } from '@nestjs/common';
import { GeoService } from './geo.service.js';
@Controller('geo')
export class GeoController {
constructor(private geoService:GeoService){}
@Get(':prefix')
findByPrefix(@Param('prefix') prefix:string): any {
return this.geoService.findCitiesStartingWith(prefix);
}
@Get(':prefix/:state')
findByPrefixAndState(@Param('prefix') prefix:string,@Param('state') state:string): any {
return this.geoService.findCitiesStartingWith(prefix,state);
}
}

View File

@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { GeoController } from './geo.controller.js';
import { GeoService } from './geo.service.js';
@Module({
controllers: [GeoController],
providers: [GeoService]
})
export class GeoModule {}

View File

@@ -0,0 +1,40 @@
import { Injectable } from '@nestjs/common';
import { readFileSync } from 'fs';
import path, { join } from 'path';
import { City, Geo, State } from 'src/models/server.model.js';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@Injectable()
export class GeoService {
geo:Geo;
constructor() {
this.loadGeo();
}
private loadGeo(): void {
const filePath = join(__dirname,'..', 'assets', 'geo.json');
const rawData = readFileSync(filePath, 'utf8');
this.geo = JSON.parse(rawData);
}
findCitiesStartingWith( prefix: string, state?:string): { city: string; state: string; state_code: string }[] {
const result: { city: string; state: string; state_code: string }[] = [];
this.geo.states.forEach((state: State) => {
state.cities.forEach((city: City) => {
if (city.name.toLowerCase().startsWith(prefix.toLowerCase())) {
result.push({
city: city.name,
state: state.name,
state_code: state.state_code
});
}
});
});
return state ? result.filter(e=>e.state_code.toLowerCase()===state.toLowerCase()) :result;
}
}

View File

@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { ListingsController } from './listings.controller.js';
import { ListingsService } from './listings.service.js';
@Module({
controllers: [ListingsController],
providers: [ListingsService]
})
export class ListingsModule {}

View File

@@ -5,55 +5,51 @@ import {
ListingCriteria,
ProfessionalsBrokersListing,
} from '../models/main.model.js';
import { LISTINGS, RedisService } from '../redis/redis.service.js';
import { convertStringToNullUndefined } from '../utils.js';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
@Injectable()
export class ListingsService {
// private readonly logger = new Logger(ListingsService.name);
constructor(private redisService: RedisService,@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {}
constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {}
async setListing(
value: BusinessListing | ProfessionalsBrokersListing | InvestmentsListing,
id?: string,
) {
if (!id) {
id = await this.redisService.getId(LISTINGS);
value.id = id;
this.logger.info(`No ID - creating new one:${id}`)
} else {
this.logger.info(`ID available:${id}`)
}
this.redisService.setJson(id, value);
// if (!id) {
// id = await this.redisService.getId(LISTINGS);
// value.id = id;
// this.logger.info(`No ID - creating new one:${id}`)
// } else {
// this.logger.info(`ID available:${id}`)
// }
//this.redisService.setJson(id, value);
}
async getListingById(id: string) {
return await this.redisService.getJson(id, LISTINGS);
//return await this.redisService.getJson(id, LISTINGS);
}
deleteListing(id: string){
this.redisService.delete(id);
//this.redisService.delete(id);
this.logger.info(`delete listing with ID:${id}`)
}
async getAllListings(start?: number, end?: number) {
const searchResult = await this.redisService.search(LISTINGS, '*');
const listings = searchResult.slice(1).reduce((acc, item, index, array) => {
// Jedes zweite Element (beginnend mit dem ersten) ist ein JSON-String des Listings
if (index % 2 === 1) {
try {
const listing = JSON.parse(item[1]); // Parsen des JSON-Strings
acc.push(listing);
} catch (error) {
console.error('Fehler beim Parsen des JSON-Strings: ', error);
}
}
return acc;
}, []);
return listings;
// const searchResult = await this.redisService.search(LISTINGS, '*');
// const listings = searchResult.slice(1).reduce((acc, item, index, array) => {
// if (index % 2 === 1) {
// try {
// const listing = JSON.parse(item[1]);
// acc.push(listing);
// } catch (error) {
// console.error('Fehler beim Parsen des JSON-Strings: ', error);
// }
// }
// return acc;
// }, []);
// return listings;
return [];
}
//criteria.type,criteria.location,criteria.minPrice,criteria.maxPrice,criteria.realEstateChecked,criteria.listingsCategory
//async find(type:string,location:string,minPrice:string,maxPrice:string,realEstateChecked:boolean,listingsCategory:string): Promise<any> {
async find(criteria:ListingCriteria): Promise<any> {
let listings = await this.getAllListings();
listings=listings.filter(l=>l.listingsCategory===criteria.listingsCategory);

View File

@@ -14,12 +14,16 @@ const __dirname = path.dirname(__filename);
// transport: 'smtps://user@example.com:topsecret@smtp.example.com',
// or
transport: {
host: 'smtp.gmail.com',
secure: true,
host: 'email-smtp.us-east-2.amazonaws.com',
secure: false,
port:587,
// auth: {
// user: 'andreas.knuth@gmail.com',
// pass: 'ksnh xjae dqbv xana',
// },
auth: {
user: 'andreas.knuth@gmail.com',
pass: 'ksnh xjae dqbv xana',
user: 'AKIAU6GDWVAQ2QNFLNWN',
pass: 'BDE9nZv/ARbpotim1mIOir52WgIbpSi9cv1oJoH8oEf7',
},
},
defaults: {

View File

@@ -1,11 +1,80 @@
import { Entity } from "redis-om";
import { UserBase } from "./main.model.js";
export interface MailInfo {
sender:Sender;
userId:string;
}
sender: Sender;
userId: string;
}
export interface Sender {
name:string;
email:string;
phoneNumber:string;
state:string;
comments:string;
name: string;
email: string;
phoneNumber: string;
state: string;
comments: string;
}
export interface Geo {
id: number;
name: string;
iso3: string;
iso2: string;
numeric_code: string;
phone_code: string;
capital: string;
currency: string;
currency_name: string;
currency_symbol: string;
tld: string;
native: string;
region: string;
region_id: string;
subregion: string;
subregion_id: string;
nationality: string;
timezones: Timezone[];
translations: Translations;
latitude: string;
longitude: string;
emoji: string;
emojiU: string;
states: State[];
}
export interface State {
id: number;
name: string;
state_code: string;
latitude: string;
longitude: string;
type: string;
cities: City[];
}
export interface City {
id: number;
name: string;
latitude: string;
longitude: string;
}
export interface Translations {
kr: string;
'pt-BR': string;
pt: string;
nl: string;
hr: string;
fa: string;
de: string;
es: string;
fr: string;
ja: string;
it: string;
cn: string;
tr: string;
}
export interface Timezone {
zoneName: string;
gmtOffset: number;
gmtOffsetName: string;
abbreviation: string;
tzName: string;
}
export interface UserEntity extends UserBase, Entity {
licensedIn?: string[];
}

View File

@@ -6,13 +6,4 @@ import { RedisService } from './redis.service.js';
export class RedisController {
constructor(private redisService:RedisService){}
// @Get(':id')
// getById(@Param('id') id:string){
// return this.redisService.getListingById(id);
// }
// @Post(':id')
// updateById(@Body() listing: any){
// this.redisService.setListing(listing);
// }
}

View File

@@ -2,15 +2,30 @@
import { Module } from '@nestjs/common';
@Module({
providers: [RedisService],
exports: [RedisService],
controllers: [RedisController],
providers: [
{
provide: 'REDIS_OPTIONS',
useValue: {
url: 'redis://localhost:6379'
}
},
{
inject: ['REDIS_OPTIONS'],
provide: 'REDIS_CLIENT',
useFactory: async (options: { url: string }) => {
const client = createClient(options);
await client.connect();
return client;
}
}],
exports:['REDIS_CLIENT']
})
export class RedisModule {}
export const REDIS_CLIENT = "REDIS_CLIENT";
// redis.service.ts
import { Injectable } from '@nestjs/common';
import { RedisService } from './redis.service.js';
import { RedisController } from './redis.controller.js';
import { createClient } from 'redis';

View File

@@ -1,48 +1,50 @@
// redis.service.ts
import { Injectable } from '@nestjs/common';
import { Redis } from 'ioredis';
import { BusinessListing, InvestmentsListing,ProfessionalsBrokersListing } from '../models/main.model.js';
import fs from 'fs-extra';
import { createClient } from 'redis';
export const LISTINGS = 'LISTINGS';
export const SUBSCRIPTIONS = 'SUBSCRIPTIONS';
export const USERS = 'USERS'
export const redis = createClient({ url: 'redis://localhost:6379' })
@Injectable()
export class RedisService {
// private redis = new Redis(); // Verbindungsparameter nach Bedarf anpassen
private redis = new Redis({
port: 6379, // Der TLS-Port von Redis
host: '2.56.188.138',
password: 'bizmatchRedis:5600Wuppertal11', // ACL Benutzername und Passwort
//private redis = new Redis(); // Verbindungsparameter nach Bedarf anpassen
// private redis = new Redis({
// port: 6379, // Der TLS-Port von Redis
//host: '2.56.188.138',
// host: '127.0.0.1',
//password: 'bizmatchRedis:5600Wuppertal11', // ACL Benutzername und Passwort
// tls: {
// key: fs.readFileSync('/home/aknuth/ssl/private/redis.key'),
// cert: fs.readFileSync('/home/aknuth/ssl/certs/redis.crt')
// }
});
// });
// ######################################
// general methods
// ######################################
async setJson(id: string, value: any): Promise<void> {
await this.redis.call("JSON.SET", `${LISTINGS}:${id}`, "$", JSON.stringify(value));
}
async delete(id: string): Promise<void> {
await this.redis.del(`${LISTINGS}:${id}`);
}
async getJson(id: string, prefix:string): Promise<any> {
const result:string = await this.redis.call("JSON.GET", `${prefix}:${id}`) as string;
return JSON.parse(result);
}
// async setJson(id: string, value: any): Promise<void> {
// await this.redis.call("JSON.SET", `${LISTINGS}:${id}`, "$", JSON.stringify(value));
// }
// async delete(id: string): Promise<void> {
// await this.redis.del(`${LISTINGS}:${id}`);
// }
// async getJson(id: string, prefix:string): Promise<any> {
// const result:string = await this.redis.call("JSON.GET", `${prefix}:${id}`) as string;
// return JSON.parse(result);
// }
async getId(prefix:'LISTINGS'|'SUBSCRIPTIONS'|'USERS'):Promise<string>{
const counter = await this.redis.call("INCR",`${prefix}_ID_COUNTER`) as number;
return counter.toString().padStart(15, '0')
}
// async getId(prefix:'LISTINGS'|'SUBSCRIPTIONS'|'USERS'):Promise<string>{
// const counter = await this.redis.call("INCR",`${prefix}_ID_COUNTER`) as number;
// return counter.toString().padStart(15, '0')
// }
async search(prefix:'LISTINGS'|'SUBSCRIPTIONS'|'USERS',clause:string):Promise<any>{
const result = await this.redis.call(`FT.SEARCH`, `${prefix}_INDEX`, `${clause}`, 'LIMIT', 0, 200);
return result;
}
// async search(prefix:'LISTINGS'|'SUBSCRIPTIONS'|'USERS',clause:string):Promise<any>{
// const result = await this.redis.call(`FT.SEARCH`, `${prefix}_INDEX`, `${clause}`, 'LIMIT', 0, 200);
// return result;
// }
}

View File

@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { SelectOptionsController } from './select-options.controller.js';
import { SelectOptionsService } from './select-options.service.js';
@Module({
controllers: [SelectOptionsController],
providers: [SelectOptionsService]
})
export class SelectOptionsModule {}

View File

@@ -0,0 +1,28 @@
import { Body, Controller, Get, Inject, Param, Post, Put } from '@nestjs/common';
import { UserService } from './user.service.js';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { UserEntity } from 'src/models/server.model.js';
@Controller('user')
export class UserController {
constructor(private userService:UserService,@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger){}
@Get(':id')
findById(@Param('id') id:string): any {
return this.userService.getUserById(id);
}
@Post()
save(@Body() user: any):Promise<UserEntity>{
this.logger.info(`User persisted: `);
return this.userService.saveUser(user);
}
// @Put()
// update(@Body() user: any):Promise<UserEntity>{
// this.logger.info(`update User`);
// return this.userService.saveUser(user);
// }
}

View File

@@ -0,0 +1,12 @@
import { Module } from '@nestjs/common';
import { UserController } from './user.controller.js';
import { UserService } from './user.service.js';
import { RedisModule } from '../redis/redis.module.js';
@Module({
imports: [RedisModule],
controllers: [UserController],
providers: [UserService]
})
export class UserModule {
}

View File

@@ -0,0 +1,46 @@
import { Get, Inject, Injectable, Param } from '@nestjs/common';
import { createClient } from 'redis';
import { Entity, Repository, Schema } from 'redis-om';
import { User } from '../models/main.model.js';
import { REDIS_CLIENT } from '../redis/redis.module.js';
import { UserEntity } from '../models/server.model.js';
// export const redis = createClient({ url: 'redis://localhost:6379' })
@Injectable()
export class UserService {
userRepository:Repository;
userSchema = new Schema('user',{
// id: string;
firstname: { type: 'string' },
lastname: { type: 'string' },
email: { type: 'string' },
phoneNumber: { type: 'string' },
companyOverview:{ type: 'string' },
companyWebsite:{ type: 'string' },
companyLocation:{ type: 'string' },
offeredServices:{ type: 'string' },
areasServed:{ type: 'string' },
names:{ type: 'string[]', path:'$.licensedIn.name' },
values:{ type: 'string[]', path:'$.licensedIn.value' }
}, {
dataStructure: 'JSON'
})
constructor(@Inject(REDIS_CLIENT) private readonly client: any){
// const redis = createClient({ url: 'redis://localhost:6379' })
this.userRepository = new Repository(this.userSchema, client)
}
async getUserById( id:string){
return await this.userRepository.fetch(id);
}
async saveUser(user:any):Promise<UserEntity>{
return await this.userRepository.save(user.id,user) as UserEntity
}
// createUser(){
// }
// updateById(id:string){
// }
}