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:
Alireza Hassani
2026-08-26 10:13:06 +03:30
co-authored by Cursor
parent 6cd0b009ef
commit 92601ae729
39 changed files with 1013 additions and 198 deletions
+13 -5
View File
@@ -14,6 +14,7 @@ import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { RequireBusinessPermission } from '../auth/decorators/require-business-permission.decorator';
import { BusinessPermissionGuard } from '../auth/guards/business-permission.guard';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { WebsiteAnalyticsService } from '../website-analytics/website-analytics.service';
import { VideosService } from './videos.service';
import {
CreateVideoCommentDto,
@@ -92,11 +93,16 @@ export class VideosController {
@Controller('tenants/:host/videos')
export class PublicVideosController {
constructor(private readonly service: VideosService) {}
constructor(
private readonly service: VideosService,
private readonly analytics: WebsiteAnalyticsService,
) {}
@Get()
list(@Param('host') host: string, @Query() query: ListPublicVideosDto) {
return this.service.listPublic(host, query);
async list(@Param('host') host: string, @Query() query: ListPublicVideosDto) {
const result = await this.service.listPublic(host, query);
this.analytics.trackPublicPage(host, 'video_list');
return result;
}
@Get(':videoId/comments')
@@ -114,7 +120,9 @@ export class PublicVideosController {
}
@Get(':slug')
getBySlug(@Param('host') host: string, @Param('slug') slug: string) {
return this.service.getPublicBySlug(host, slug);
async getBySlug(@Param('host') host: string, @Param('slug') slug: string) {
const result = await this.service.getPublicBySlug(host, slug);
this.analytics.trackPublicPage(host, 'video_detail', result.video.id);
return result;
}
}
+2 -1
View File
@@ -2,11 +2,12 @@ import { Module } from '@nestjs/common';
import { AuthModule } from '../auth/auth.module';
import { BusinessSettingsModule } from '../business-settings/business-settings.module';
import { TenantModule } from '../tenant/tenant.module';
import { WebsiteAnalyticsModule } from '../website-analytics/website-analytics.module';
import { PublicVideosController, VideosController } from './videos.controller';
import { VideosService } from './videos.service';
@Module({
imports: [AuthModule, BusinessSettingsModule, TenantModule],
imports: [AuthModule, BusinessSettingsModule, TenantModule, WebsiteAnalyticsModule],
controllers: [VideosController, PublicVideosController],
providers: [VideosService],
})