Split blogs and other modules into child sitemaps.

Move blogs, portfolios, videos, instructions, and workshops out of sitemap-main into dedicated files like products, and allow saving migrated Farsi category color labels without wiping store-item links.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-26 19:02:38 +03:30
co-authored by Cursor
parent 5850c90d84
commit 730407ec3a
14 changed files with 839 additions and 113 deletions
+7 -2
View File
@@ -262,9 +262,14 @@ All routes are prefixed with `/api/v1`.
| POST | `/auth/verify-otp` | Verify OTP (marks cell verified; no tokens) |
| POST | `/auth/handoff/consume` | One-time SSO ticket → tokens (customer → business dashboard) |
| GET | `/tenants/:host` | Resolve business from domain (`specialProductsSource`, `enabledModules`, `homeCharts`, `ePayment`) |
| GET | `/tenants/:host/sitemap.xml` | Sitemap **index** → main + products child sitemaps |
| GET | `/tenants/:host/sitemap-main.xml` | Static pages + `/products/category/{id}/{faSlug}` + blogs/portfolios |
| GET | `/tenants/:host/sitemap.xml` | Sitemap **index** → main + dynamic child sitemaps |
| GET | `/tenants/:host/sitemap-main.xml` | Static pages + `/products/category/{id}/{faSlug}` |
| GET | `/tenants/:host/sitemap-products.xml` | Published products `/products/{id}/{faSlug}` |
| GET | `/tenants/:host/sitemap-blogs.xml` | Published blogs `/blog/{id}/{slug}` |
| GET | `/tenants/:host/sitemap-portfolios.xml` | Published portfolios `/portfolios/{id}/{slug}` |
| GET | `/tenants/:host/sitemap-videos.xml` | Published videos `/videos/{slug}` |
| GET | `/tenants/:host/sitemap-instructions.xml` | Published instructions `/instructions/{slug}` |
| GET | `/tenants/:host/sitemap-workshops.xml` | Published workshops `/workshops/{slug}` |
| GET | `/tenants/:host/robots.txt` | robots.txt pointing to apex `/sitemap.xml` |
| GET | `/tenants/:host/categories/by-id/:categoryId` | Public category by id (for category landing pages) |
| GET | `/tenants/:host/categories/by-slug/:slug` | Public category by CMS slug |
+7 -2
View File
@@ -138,9 +138,14 @@ Minimal example:
- When linking from lists/cards, use the same `{id}/{slug}` shape for details (slugify Farsi title: spaces → `-`, keep Persian letters). Category links use `/products/category/{id}/{nameFaSlug}`.
- Omit `templates` in `sitemap-config.json` unless this site uses non-default paths.
- **Sitemap files (proxied by nginx — do not ship local copies):**
- `/sitemap.xml` — sitemap **index**
- `/sitemap-main.xml` — static pages + categories + blogs + portfolios
- `/sitemap.xml` — sitemap **index** (lists child sitemaps for enabled modules)
- `/sitemap-main.xml` — static pages + product categories
- `/sitemap-products.xml` — published products (when products module is enabled)
- `/sitemap-blogs.xml` — published blogs (when blog module is enabled)
- `/sitemap-portfolios.xml` — published portfolios (when portfolio module is enabled)
- `/sitemap-videos.xml` — published videos (when videos module is enabled)
- `/sitemap-instructions.xml` — published instructions (when instructions module is enabled)
- `/sitemap-workshops.xml` — published workshops (when workshops module is enabled)
- `/robots.txt` — points at `/sitemap.xml`
### On-page SEO (every public page)
+127 -2
View File
@@ -201,7 +201,7 @@
"SEO"
],
"summary": "XML sitemap for search engines",
"description": "Sitemap **index** for this tenant. Points to `/sitemap-main.xml` (static pages, product categories, blogs, portfolios) and `/sitemap-products.xml` (published products when the products module is enabled). Category paths: `/products/category/{id}/{nameFaSlug}`. Product paths: `/products/{id}/{nameFaSlug}`. Proxied from `https://{domain}/sitemap.xml`. Cached in Redis; refreshed after CMS writes and manifest sync.",
"description": "Sitemap **index** for this tenant. Points to `/sitemap-main.xml` (static pages + product categories) plus module child sitemaps when enabled: `/sitemap-products.xml`, `/sitemap-blogs.xml`, `/sitemap-portfolios.xml`, `/sitemap-videos.xml`, `/sitemap-instructions.xml`, `/sitemap-workshops.xml`. Proxied from `https://{domain}/sitemap.xml`. Cached in Redis; refreshed after CMS writes and manifest sync.",
"parameters": [
{
"$ref": "#/components/parameters/domain"
@@ -237,7 +237,7 @@
"tags": [
"SEO"
],
"summary": "Main sitemap urlset (static + categories + blogs + portfolios)",
"summary": "Main sitemap urlset (static pages + product categories)",
"parameters": [
{
"$ref": "#/components/parameters/domain"
@@ -282,6 +282,131 @@
}
}
},
"/tenants/{domain}/sitemap-blogs.xml": {
"get": {
"tags": [
"SEO"
],
"summary": "Blogs-only sitemap urlset",
"parameters": [
{
"$ref": "#/components/parameters/domain"
}
],
"responses": {
"200": {
"description": "Sitemap XML (urlset) of published blogs",
"content": {
"application/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/tenants/{domain}/sitemap-portfolios.xml": {
"get": {
"tags": [
"SEO"
],
"summary": "Portfolios-only sitemap urlset",
"parameters": [
{
"$ref": "#/components/parameters/domain"
}
],
"responses": {
"200": {
"description": "Sitemap XML (urlset) of published portfolios",
"content": {
"application/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/tenants/{domain}/sitemap-videos.xml": {
"get": {
"tags": [
"SEO"
],
"summary": "Videos-only sitemap urlset",
"parameters": [
{
"$ref": "#/components/parameters/domain"
}
],
"responses": {
"200": {
"description": "Sitemap XML (urlset) of published videos",
"content": {
"application/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/tenants/{domain}/sitemap-instructions.xml": {
"get": {
"tags": [
"SEO"
],
"summary": "Instructions-only sitemap urlset",
"parameters": [
{
"$ref": "#/components/parameters/domain"
}
],
"responses": {
"200": {
"description": "Sitemap XML (urlset) of published instructions",
"content": {
"application/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/tenants/{domain}/sitemap-workshops.xml": {
"get": {
"tags": [
"SEO"
],
"summary": "Workshops-only sitemap urlset",
"parameters": [
{
"$ref": "#/components/parameters/domain"
}
],
"responses": {
"200": {
"description": "Sitemap XML (urlset) of published workshops",
"content": {
"application/xml": {
"schema": {
"type": "string"
}
}
}
}
}
}
},
"/tenants/{domain}/robots.txt": {
"get": {
"tags": [