Add page-view analytics, product counters, SSL expiry, and business renewal.
Auto-count storefront page views with 6-month event retention and lifetime counters, track product visit/cart/sale stats, persist SSL cert expiry with daily probes, and support owner titles plus annual contract renewal. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
6cd0b009ef
commit
92601ae729
@@ -59,6 +59,7 @@ type BusinessRow = {
|
||||
about: string | null;
|
||||
slug: string;
|
||||
createdAt: Date;
|
||||
annualRenewalAt: Date | null;
|
||||
isActive: boolean;
|
||||
oldBusinessId: bigint | null;
|
||||
domainId: bigint | null;
|
||||
@@ -142,6 +143,7 @@ export class BusinessAdminService {
|
||||
b.about AS "about",
|
||||
b.slug AS "slug",
|
||||
b.created_at AS "createdAt",
|
||||
b.annual_renewal_at AS "annualRenewalAt",
|
||||
b.is_active AS "isActive",
|
||||
b.old_business_id AS "oldBusinessId",
|
||||
dom.id AS "domainId",
|
||||
@@ -372,6 +374,9 @@ export class BusinessAdminService {
|
||||
nameFa: dto.nameFa.trim(),
|
||||
about: dto.about?.trim() ?? null,
|
||||
slug,
|
||||
annualRenewalAt: dto.annualRenewalAt
|
||||
? new Date(dto.annualRenewalAt)
|
||||
: null,
|
||||
oldBusinessId:
|
||||
dto.oldBusinessId !== undefined ? BigInt(dto.oldBusinessId) : undefined,
|
||||
settings: toPrismaJson({
|
||||
@@ -455,6 +460,14 @@ export class BusinessAdminService {
|
||||
dto.oldBusinessId === null ? null : BigInt(dto.oldBusinessId),
|
||||
}
|
||||
: {}),
|
||||
...(dto.annualRenewalAt !== undefined
|
||||
? {
|
||||
annualRenewalAt:
|
||||
dto.annualRenewalAt === null
|
||||
? null
|
||||
: new Date(dto.annualRenewalAt),
|
||||
}
|
||||
: {}),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1075,6 +1088,7 @@ export class BusinessAdminService {
|
||||
tx: Prisma.TransactionClient,
|
||||
dto: Pick<
|
||||
CreateBusinessDto,
|
||||
| 'ownerTitleId'
|
||||
| 'ownerFirstName'
|
||||
| 'ownerLastName'
|
||||
| 'ownerFirstNameEn'
|
||||
@@ -1087,26 +1101,45 @@ export class BusinessAdminService {
|
||||
where: { cellNumber: dto.ownerCellNumber },
|
||||
});
|
||||
|
||||
let titleId: bigint | null | undefined = undefined;
|
||||
if (dto.ownerTitleId !== undefined) {
|
||||
const title = await tx.userTitle.findFirst({
|
||||
where: { id: BigInt(dto.ownerTitleId), isActive: true },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!title) {
|
||||
throw new BadRequestException('Owner title not found');
|
||||
}
|
||||
titleId = title.id;
|
||||
}
|
||||
|
||||
const passwordHash = await bcrypt.hash(dto.ownerPassword, 10);
|
||||
const nameData = {
|
||||
...(titleId !== undefined ? { titleId } : {}),
|
||||
firstName: dto.ownerFirstName.trim(),
|
||||
lastName: dto.ownerLastName.trim(),
|
||||
firstNameEn: dto.ownerFirstNameEn.trim(),
|
||||
lastNameEn: dto.ownerLastNameEn.trim(),
|
||||
passwordHash,
|
||||
};
|
||||
|
||||
// Users can own multiple businesses. If the cell number already exists,
|
||||
// leave that user unchanged and only attach the new business as owner.
|
||||
// refresh name + password from the create form, then attach as owner.
|
||||
if (existing) {
|
||||
if (!existing.isActive) {
|
||||
throw new BadRequestException('Owner user is inactive');
|
||||
}
|
||||
return existing;
|
||||
return tx.user.update({
|
||||
where: { id: existing.id },
|
||||
data: nameData,
|
||||
});
|
||||
}
|
||||
|
||||
const passwordHash = await bcrypt.hash(dto.ownerPassword, 10);
|
||||
|
||||
return tx.user.create({
|
||||
data: {
|
||||
cellNumber: dto.ownerCellNumber,
|
||||
passwordHash,
|
||||
firstName: dto.ownerFirstName.trim(),
|
||||
lastName: dto.ownerLastName.trim(),
|
||||
firstNameEn: dto.ownerFirstNameEn.trim(),
|
||||
lastNameEn: dto.ownerLastNameEn.trim(),
|
||||
cellVerifiedAt: new Date(),
|
||||
...nameData,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1176,6 +1209,7 @@ export class BusinessAdminService {
|
||||
slug: string;
|
||||
isActive: boolean;
|
||||
oldBusinessId: bigint | null;
|
||||
annualRenewalAt: Date | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
categoryAssignments: {
|
||||
@@ -1217,6 +1251,7 @@ export class BusinessAdminService {
|
||||
isActive: business.isActive,
|
||||
oldBusinessId:
|
||||
business.oldBusinessId != null ? business.oldBusinessId.toString() : null,
|
||||
annualRenewalAt: business.annualRenewalAt,
|
||||
createdAt: business.createdAt,
|
||||
updatedAt: business.updatedAt,
|
||||
categories: business.categoryAssignments.map((a) => ({
|
||||
|
||||
Reference in New Issue
Block a user