BugFixing

This commit is contained in:
Andreas Knuth 2025-03-13 16:59:50 +01:00
parent 097a6cb360
commit cfddabbfe0
7 changed files with 89 additions and 59 deletions

View File

@ -103,8 +103,8 @@ export class BusinessListingService {
whereConditions.push(and(ilike(schema.users.firstname, `%${firstname}%`), ilike(schema.users.lastname, `%${lastname}%`))); whereConditions.push(and(ilike(schema.users.firstname, `%${firstname}%`), ilike(schema.users.lastname, `%${lastname}%`)));
} }
} }
if (!user?.roles?.includes('ADMIN')) { if (user?.role !== 'admin') {
whereConditions.push(or(eq(businesses.email, user?.username), ne(businesses.draft, true))); whereConditions.push(or(eq(businesses.email, user?.email), ne(businesses.draft, true)));
} }
whereConditions.push(and(eq(schema.users.customerType, 'professional'), eq(schema.users.customerSubType, 'broker'))); whereConditions.push(and(eq(schema.users.customerType, 'professional'), eq(schema.users.customerSubType, 'broker')));
return whereConditions; return whereConditions;
@ -186,8 +186,8 @@ export class BusinessListingService {
async findBusinessesById(id: string, user: JwtUser): Promise<BusinessListing> { async findBusinessesById(id: string, user: JwtUser): Promise<BusinessListing> {
const conditions = []; const conditions = [];
if (!user?.roles?.includes('ADMIN')) { if (user?.role !== 'admin') {
conditions.push(or(eq(businesses.email, user?.username), ne(businesses.draft, true))); conditions.push(or(eq(businesses.email, user?.email), ne(businesses.draft, true)));
} }
conditions.push(sql`${businesses.id} = ${id}`); conditions.push(sql`${businesses.id} = ${id}`);
const result = await this.conn const result = await this.conn
@ -204,7 +204,7 @@ export class BusinessListingService {
async findBusinessesByEmail(email: string, user: JwtUser): Promise<BusinessListing[]> { async findBusinessesByEmail(email: string, user: JwtUser): Promise<BusinessListing[]> {
const conditions = []; const conditions = [];
conditions.push(eq(businesses.email, email)); conditions.push(eq(businesses.email, email));
if (email !== user?.username && (!user?.roles?.includes('ADMIN'))) { if (email !== user?.email && user?.role !== 'admin') {
conditions.push(ne(businesses.draft, true)); conditions.push(ne(businesses.draft, true));
} }
const listings = (await this.conn const listings = (await this.conn
@ -219,7 +219,7 @@ export class BusinessListingService {
const userFavorites = await this.conn const userFavorites = await this.conn
.select() .select()
.from(businesses) .from(businesses)
.where(arrayContains(businesses.favoritesForUser, [user.username])); .where(arrayContains(businesses.favoritesForUser, [user.email]));
return userFavorites; return userFavorites;
} }
// #### CREATE ######################################## // #### CREATE ########################################
@ -276,7 +276,7 @@ export class BusinessListingService {
await this.conn await this.conn
.update(businesses) .update(businesses)
.set({ .set({
favoritesForUser: sql`array_remove(${businesses.favoritesForUser}, ${user.username})`, favoritesForUser: sql`array_remove(${businesses.favoritesForUser}, ${user.email})`,
}) })
.where(sql`${businesses.id} = ${id}`); .where(sql`${businesses.id} = ${id}`);
} }

View File

@ -49,8 +49,8 @@ export class CommercialPropertyService {
if (criteria.title) { if (criteria.title) {
whereConditions.push(or(ilike(schema.commercials.title, `%${criteria.title}%`), ilike(schema.commercials.description, `%${criteria.title}%`))); whereConditions.push(or(ilike(schema.commercials.title, `%${criteria.title}%`), ilike(schema.commercials.description, `%${criteria.title}%`)));
} }
if (!user?.roles?.includes('ADMIN')) { if (user?.role !== 'admin') {
whereConditions.push(or(eq(commercials.email, user?.username), ne(commercials.draft, true))); whereConditions.push(or(eq(commercials.email, user?.email), ne(commercials.draft, true)));
} }
// whereConditions.push(and(eq(schema.users.customerType, 'professional'))); // whereConditions.push(and(eq(schema.users.customerType, 'professional')));
return whereConditions; return whereConditions;
@ -113,8 +113,8 @@ export class CommercialPropertyService {
// #### Find by ID ######################################## // #### Find by ID ########################################
async findCommercialPropertiesById(id: string, user: JwtUser): Promise<CommercialPropertyListing> { async findCommercialPropertiesById(id: string, user: JwtUser): Promise<CommercialPropertyListing> {
const conditions = []; const conditions = [];
if (!user?.roles?.includes('ADMIN')) { if (user?.role !== 'admin') {
conditions.push(or(eq(commercials.email, user?.username), ne(commercials.draft, true))); conditions.push(or(eq(commercials.email, user?.email), ne(commercials.draft, true)));
} }
conditions.push(sql`${commercials.id} = ${id}`); conditions.push(sql`${commercials.id} = ${id}`);
const result = await this.conn const result = await this.conn
@ -132,7 +132,7 @@ export class CommercialPropertyService {
async findCommercialPropertiesByEmail(email: string, user: JwtUser): Promise<CommercialPropertyListing[]> { async findCommercialPropertiesByEmail(email: string, user: JwtUser): Promise<CommercialPropertyListing[]> {
const conditions = []; const conditions = [];
conditions.push(eq(commercials.email, email)); conditions.push(eq(commercials.email, email));
if (email !== user?.username && (!user?.roles?.includes('ADMIN'))) { if (email !== user?.email && user?.role !== 'admin') {
conditions.push(ne(commercials.draft, true)); conditions.push(ne(commercials.draft, true));
} }
const listings = (await this.conn const listings = (await this.conn
@ -146,7 +146,7 @@ export class CommercialPropertyService {
const userFavorites = await this.conn const userFavorites = await this.conn
.select() .select()
.from(commercials) .from(commercials)
.where(arrayContains(commercials.favoritesForUser, [user.username])); .where(arrayContains(commercials.favoritesForUser, [user.email]));
return userFavorites; return userFavorites;
} }
// #### Find by imagePath ######################################## // #### Find by imagePath ########################################
@ -233,7 +233,7 @@ export class CommercialPropertyService {
await this.conn await this.conn
.update(commercials) .update(commercials)
.set({ .set({
favoritesForUser: sql`array_remove(${commercials.favoritesForUser}, ${user.username})`, favoritesForUser: sql`array_remove(${commercials.favoritesForUser}, ${user.email})`,
}) })
.where(sql`${commercials.id} = ${id}`); .where(sql`${commercials.id} = ${id}`);
} }

View File

@ -258,35 +258,59 @@ export type AreasServed = z.infer<typeof AreasServedSchema>;
export type LicensedIn = z.infer<typeof LicensedInSchema>; export type LicensedIn = z.infer<typeof LicensedInSchema>;
export type User = z.infer<typeof UserSchema>; export type User = z.infer<typeof UserSchema>;
export const BusinessListingSchema = z.object({ export const BusinessListingSchema = z
id: z.string().uuid().optional().nullable(), .object({
email: z.string().email(), id: z.string().uuid().optional().nullable(),
type: z.string().refine(val => TypeEnum.safeParse(val).success, { email: z.string().email(),
message: 'Invalid type. Must be one of: ' + TypeEnum.options.join(', '), type: z.string().refine(val => TypeEnum.safeParse(val).success, {
}), message: 'Invalid type. Must be one of: ' + TypeEnum.options.join(', '),
title: z.string().min(10), }),
description: z.string().min(10), title: z.string().min(10),
location: GeoSchema, description: z.string().min(10),
price: z.number().positive().max(1000000000), location: GeoSchema,
favoritesForUser: z.array(z.string()), price: z.number().positive(),
draft: z.boolean(), favoritesForUser: z.array(z.string()),
listingsCategory: ListingsCategoryEnum, draft: z.boolean(),
realEstateIncluded: z.boolean().optional().nullable(), listingsCategory: ListingsCategoryEnum,
leasedLocation: z.boolean().optional().nullable(), realEstateIncluded: z.boolean().optional().nullable(),
franchiseResale: z.boolean().optional().nullable(), leasedLocation: z.boolean().optional().nullable(),
salesRevenue: z.number().positive().max(100000000), franchiseResale: z.boolean().optional().nullable(),
cashFlow: z.number().positive().max(100000000), salesRevenue: z.number().positive().nullable(),
supportAndTraining: z.string().min(5), cashFlow: z.number().positive().max(100000000),
employees: z.number().int().positive().max(100000).optional().nullable(), supportAndTraining: z.string().min(5),
established: z.number().int().min(1800).max(2030).optional().nullable(), employees: z.number().int().positive().max(100000).optional().nullable(),
internalListingNumber: z.number().int().positive().optional().nullable(), established: z.number().int().min(1800).max(2030).optional().nullable(),
reasonForSale: z.string().min(5).optional().nullable(), internalListingNumber: z.number().int().positive().optional().nullable(),
brokerLicencing: z.string().optional().nullable(), reasonForSale: z.string().min(5).optional().nullable(),
internals: z.string().min(5).optional().nullable(), brokerLicencing: z.string().optional().nullable(),
imageName: z.string().optional().nullable(), internals: z.string().min(5).optional().nullable(),
created: z.date(), imageName: z.string().optional().nullable(),
updated: z.date(), created: z.date(),
}); updated: z.date(),
})
.superRefine((data, ctx) => {
if (data.price && data.price > 1000000000) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Price must less than or equal $1,000,000,000',
path: ['price'],
});
}
if (data.salesRevenue && data.salesRevenue > 100000000) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'SalesRevenue must less than or equal $100,000,000',
path: ['salesRevenue'],
});
}
if (data.cashFlow && data.cashFlow > 100000000) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'CashFlow must less than or equal $100,000,000',
path: ['cashFlow'],
});
}
});
export type BusinessListing = z.infer<typeof BusinessListingSchema>; export type BusinessListing = z.infer<typeof BusinessListingSchema>;
export const CommercialPropertyListingSchema = z export const CommercialPropertyListingSchema = z
@ -300,7 +324,7 @@ export const CommercialPropertyListingSchema = z
title: z.string().min(10), title: z.string().min(10),
description: z.string().min(10), description: z.string().min(10),
location: GeoSchema, location: GeoSchema,
price: z.number().positive().max(1000000000), price: z.number().positive(),
favoritesForUser: z.array(z.string()), favoritesForUser: z.array(z.string()),
listingsCategory: ListingsCategoryEnum, listingsCategory: ListingsCategoryEnum,
draft: z.boolean(), draft: z.boolean(),
@ -309,7 +333,15 @@ export const CommercialPropertyListingSchema = z
created: z.date(), created: z.date(),
updated: z.date(), updated: z.date(),
}) })
.strict(); .superRefine((data, ctx) => {
if (data.price && data.price > 1000000000) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Price must less than or equal $1,000,000,000',
path: ['price'],
});
}
});
export type CommercialPropertyListing = z.infer<typeof CommercialPropertyListingSchema>; export type CommercialPropertyListing = z.infer<typeof CommercialPropertyListingSchema>;

View File

@ -123,11 +123,9 @@ export interface KeycloakUser {
attributes?: Attributes; attributes?: Attributes;
} }
export interface JwtUser { export interface JwtUser {
userId: string; email: string;
username: string; role: string;
firstname: string; uid: string;
lastname: string;
roles: string[];
} }
interface Attributes { interface Attributes {
[key: string]: any; [key: string]: any;

View File

@ -54,7 +54,7 @@ export class UserService {
} }
//never show user which denied //never show user which denied
whereConditions.push(eq(schema.users.showInDirectory, true)) whereConditions.push(eq(schema.users.showInDirectory, true));
return whereConditions; return whereConditions;
} }
@ -110,7 +110,7 @@ export class UserService {
.from(schema.users) .from(schema.users)
.where(sql`email = ${email}`)) as User[]; .where(sql`email = ${email}`)) as User[];
if (users.length === 0) { if (users.length === 0) {
const user: User = { id: undefined, customerType: 'professional', ...createDefaultUser(email, jwtuser.firstname ? jwtuser.firstname : '', jwtuser.lastname ? jwtuser.lastname : '', null) }; const user: User = { id: undefined, customerType: 'professional', ...createDefaultUser(email, '', '', null) };
const u = await this.saveUser(user, false); const u = await this.saveUser(user, false);
return u; return u;
} else { } else {

View File

@ -83,10 +83,10 @@
<li> <li>
<a routerLink="/myListings" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">My Listings</a> <a routerLink="/myListings" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">My Listings</a>
</li> </li>
}
<li> <li>
<a routerLink="/myFavorites" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">My Favorites</a> <a routerLink="/myFavorites" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">My Favorites</a>
</li> </li>
}
<li> <li>
<a routerLink="/emailUs" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">EMail Us</a> <a routerLink="/emailUs" (click)="closeDropdown()" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white">EMail Us</a>
</li> </li>

View File

@ -149,9 +149,9 @@ export class DetailsBusinessListingComponent extends BaseDetailsComponent {
const result = [ const result = [
{ label: 'Category', value: this.selectOptions.getBusiness(this.listing.type) }, { label: 'Category', value: this.selectOptions.getBusiness(this.listing.type) },
{ label: 'Located in', value: `${this.listing.location.name ? this.listing.location.name : this.listing.location.county}, ${this.selectOptions.getState(this.listing.location.state)}` }, { label: 'Located in', value: `${this.listing.location.name ? this.listing.location.name : this.listing.location.county}, ${this.selectOptions.getState(this.listing.location.state)}` },
{ label: 'Asking Price', value: `$${this.listing.price?.toLocaleString()}` }, { label: 'Asking Price', value: `${this.listing.price ? `$${this.listing.price.toLocaleString()}` : ''}` },
{ label: 'Sales revenue', value: `$${this.listing.salesRevenue?.toLocaleString()}` }, { label: 'Sales revenue', value: `${this.listing.salesRevenue ? `$${this.listing.salesRevenue.toLocaleString()}` : ''}` },
{ label: 'Cash flow', value: `$${this.listing.cashFlow?.toLocaleString()}` }, { label: 'Cash flow', value: `${this.listing.cashFlow ? `$${this.listing.cashFlow.toLocaleString()}` : ''}` },
{ label: 'Type of Real Estate', value: typeOfRealEstate }, { label: 'Type of Real Estate', value: typeOfRealEstate },
{ label: 'Employees', value: this.listing.employees }, { label: 'Employees', value: this.listing.employees },
{ label: 'Established since', value: this.listing.established }, { label: 'Established since', value: this.listing.established },