Add backend-generated sitemap with website manifest sync and nginx SEO proxy support.

Stores synced route config from /meshkee/sitemap-config.json, serves sitemap.xml and robots.txt per tenant, and invalidates cache on CMS writes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-22 15:15:32 +03:30
co-authored by Cursor
parent c7d5204b49
commit 2e8d7c1cfd
27 changed files with 1167 additions and 3 deletions
+2 -1
View File
@@ -1,12 +1,13 @@
import { Module } from '@nestjs/common';
import { AuthModule } from '../auth/auth.module';
import { BusinessSettingsModule } from '../business-settings/business-settings.module';
import { SitemapModule } from '../sitemap/sitemap.module';
import { TenantModule } from '../tenant/tenant.module';
import { BlogsController, PublicBlogsController } from './blogs.controller';
import { BlogsService } from './blogs.service';
@Module({
imports: [AuthModule, BusinessSettingsModule, TenantModule],
imports: [AuthModule, BusinessSettingsModule, SitemapModule, TenantModule],
controllers: [BlogsController, PublicBlogsController],
providers: [BlogsService],
})
+8
View File
@@ -13,6 +13,7 @@ import { AuthUser } from '../auth/auth.types';
import { PermissionsService } from '../auth/permissions.service';
import { BusinessSettingsService } from '../business-settings/business-settings.service';
import { PrismaService } from '../prisma/prisma.service';
import { SitemapService } from '../sitemap/sitemap.service';
import { TenantService } from '../tenant/tenant.service';
import {
CreateBlogCommentDto,
@@ -58,6 +59,7 @@ export class BlogsService {
private readonly permissions: PermissionsService,
private readonly tenant: TenantService,
private readonly businessSettings: BusinessSettingsService,
private readonly sitemap: SitemapService,
) {}
async list(businessIdRaw: string, query: ListBlogsDto, actor: AuthUser) {
@@ -155,6 +157,8 @@ export class BlogsService {
return blog;
});
await this.sitemap.invalidateForBusiness(businessId);
return {
message: 'Blog post created successfully',
blog: await this.serializeBlog(created),
@@ -275,6 +279,8 @@ export class BlogsService {
return blog;
});
await this.sitemap.invalidateForBusiness(businessId);
return {
message: 'Blog post updated successfully',
blog: await this.serializeBlog(updated),
@@ -312,6 +318,8 @@ export class BlogsService {
this.prisma.blogs.delete({ where: { id: blogId } }),
]);
await this.sitemap.invalidateForBusiness(businessId);
return { message: 'Blog post deleted successfully' };
}