2026-07-03 01:31:24 +04:00
{
"schemaVersion" : "1.0.0" ,
"generatedAt" : "2026-07-03T00:00:00Z" ,
"tenant" : {
"id" : "tenant-default-001" ,
"slug" : "default" ,
"code" : "DEFAULT" ,
"host" : "default.local" ,
2026-07-05 00:51:29 +04:00
"name" : "Marketplace" ,
"websiteBaseUrl" : "https://marketplace.local" ,
"builderBaseUrl" : "https://builder.marketplace.local" ,
"backofficeBaseUrl" : "https://backoffice.marketplace.local" ,
2026-07-03 01:31:24 +04:00
"defaultLocale" : "ru" ,
"supportedLocales" : [ "ru" , "en" , "hy" ] ,
"defaultCurrency" : "RUB" ,
"supportedCurrencies" : [ "RUB" , "USD" , "EUR" , "AMD" ] ,
feat: close stub-page gaps - profile login/logout, admin Reports/Settings, Help/Docs links
Sprint A: storefront header profile control (login/logout only, no menu),
wired to existing customer Telegram auth (AuthService).
Sprint B: backoffice/reports page, reuses AdminAnalyticsFacade (Sales,
Top Products, Marketplace Health cards + CSV export).
Sprint C: backoffice/settings page, admin UI density preference
(comfortable/compact), localStorage-persisted, applied to app-table
across all admin list pages.
Sprint D: admin bottom-nav Help -> mailto using existing supportEmail,
Documentation -> external link via new TenantConfig.documentationUrl.
AdminNavLink gains externalHref for non-routerLink nav entries.
Docs: docs/GLOBAL-SPRINT-PLAN.md tracks the full sprint breakdown.
docs/COMING-SOON-AUDIT.md removed, folded into docs/KNOWN-ISSUES.md.
docs/BACKEND.md updated with the new documentationUrl bootstrap field.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 17:48:50 +04:00
"timezone" : "Europe/Moscow" ,
"documentationUrl" : "https://docs.marketplace.local"
2026-07-03 01:31:24 +04:00
} ,
"branding" : {
2026-07-05 00:51:29 +04:00
"brandName" : "Marketplace" ,
"legalName" : "Marketplace LLC" ,
"slogan" : "Digital commerce marketplace" ,
"logoUrl" : "/icons/icon-192x192.png" ,
"logoCompactUrl" : "/icons/icon-192x192.png" ,
2026-07-03 01:31:24 +04:00
"faviconUrl" : "/favicon.ico" ,
2026-07-05 00:51:29 +04:00
"appIconUrl" : "/icons/icon-192x192.png" ,
"supportEmail" : "support@marketplace.local" ,
2026-07-03 01:31:24 +04:00
"supportPhone" : "+7-900-000-00-00"
} ,
"theme" : {
"themeId" : "default-light" ,
"mode" : "light" ,
"palette" : {
"primary" : "#497671" ,
"secondary" : "#a1b4b5" ,
"accent" : "#a7ceca" ,
"success" : "#10b981" ,
"warning" : "#f59e0b" ,
"danger" : "#ef4444" ,
"info" : "#3b82f6" ,
"textPrimary" : "#1e3c38" ,
"textSecondary" : "#667a77" ,
"backgroundPrimary" : "#ffffff" ,
"backgroundSecondary" : "#f5f5f5" ,
"border" : "#d3dad9"
} ,
"typography" : {
"primaryFontFamily" : "DM Sans, sans-serif" ,
"headingFontFamily" : "DM Sans, sans-serif" ,
"baseFontSize" : 16
} ,
"spacing" : {
"unit" : 4 ,
"scale" : [ 0 , 4 , 8 , 12 , 16 , 24 , 32 , 48 ]
} ,
"borderRadiusScale" : {
"sm" : "8px" ,
"md" : "12px" ,
"lg" : "16px" ,
"xl" : "22px"
} ,
"shadows" : {
"sm" : "0 2px 8px rgba(0,0,0,0.1)" ,
"md" : "0 4px 12px rgba(0,0,0,0.15)" ,
"lg" : "0 12px 32px rgba(73,118,113,0.2)"
} ,
"iconSet" : "default"
} ,
"company" : {
2026-07-05 00:51:29 +04:00
"companyName" : "Marketplace LLC" ,
2026-07-03 01:31:24 +04:00
"registrationNumber" : "1027700000000" ,
"taxId" : "7700000000" ,
"address" : {
"country" : "Russia" ,
"region" : "Moscow" ,
"city" : "Moscow" ,
"street" : "Tverskaya 1" ,
"postalCode" : "125009"
} ,
"contacts" : {
2026-07-05 00:51:29 +04:00
"email" : "support@marketplace.local" ,
2026-07-03 01:31:24 +04:00
"phone" : "+7-900-000-00-00" ,
2026-07-05 00:51:29 +04:00
"telegram" : "@marketplace_support" ,
"website" : "https://marketplace.local"
2026-07-03 01:31:24 +04:00
}
} ,
"featureFlags" : {
"wishlist" : true ,
"compare" : true ,
"reviews" : true ,
"blog" : false ,
"chat" : false ,
"analytics" : true ,
"notifications" : true ,
"coupons" : true ,
"loyalty" : false ,
"giftCards" : false ,
"invoices" : true
} ,
"apiEndpoints" : {
"bootstrap" : {
"path" : "/bootstrap" ,
"method" : "GET" ,
"timeoutMs" : 10000
} ,
"website" : { } ,
"builder" : { } ,
"backoffice" : { }
} ,
"localization" : {
"defaultLocale" : "ru" ,
"supportedLocales" : [ "ru" , "en" , "hy" ] ,
"currencyByLocale" : {
"ru" : "RUB" ,
"en" : "USD" ,
"hy" : "AMD"
} ,
"dictionaries" : [
{
"locale" : "ru" ,
"dictionaryUrl" : "/assets/i18n/ru.json" ,
"version" : "1.0.0"
} ,
{
"locale" : "en" ,
"dictionaryUrl" : "/assets/i18n/en.json" ,
"version" : "1.0.0"
} ,
{
"locale" : "hy" ,
"dictionaryUrl" : "/assets/i18n/hy.json" ,
"version" : "1.0.0"
}
]
} ,
"seo" : {
"default" : {
2026-07-05 00:51:29 +04:00
"title" : "Marketplace" ,
"description" : "Digital commerce marketplace" ,
2026-07-03 01:31:24 +04:00
"robots" : "index,follow"
} ,
"byPageKey" : {
"home" : {
2026-07-05 00:51:29 +04:00
"title" : "Marketplace - Home" ,
"description" : "Digital commerce marketplace" ,
"canonicalUrl" : "https://marketplace.local/" ,
2026-07-03 01:31:24 +04:00
"robots" : "index,follow"
}
}
} ,
"permissions" : {
"definitions" : [
{
"key" : "builder.pages.edit" ,
"description" : "Edit pages in builder"
} ,
{
"key" : "backoffice.products.read" ,
"description" : "Read products in backoffice"
}
] ,
"roles" : [
{
"role" : "builder_admin" ,
"permissions" : [ "builder.pages.edit" ]
} ,
{
"role" : "backoffice_manager" ,
"permissions" : [ "backoffice.products.read" ]
}
]
} ,
2026-07-05 04:17:31 +04:00
"layout" : {
"type" : "default"
} ,
2026-07-03 01:31:24 +04:00
"navigation" : {
"header" : [
{
"id" : "nav-home" ,
"labelKey" : "nav.home" ,
"route" : "/" ,
"icon" : "home" ,
"order" : 1
} ,
{
"id" : "nav-search" ,
"labelKey" : "nav.search" ,
"route" : "/search" ,
"icon" : "search" ,
"order" : 2
} ,
{
"id" : "nav-cart" ,
"labelKey" : "nav.cart" ,
"route" : "/cart" ,
"icon" : "cart" ,
"order" : 3
}
] ,
"footer" : [
{
"id" : "footer-about" ,
"labelKey" : "nav.about" ,
2026-07-24 09:46:51 +04:00
"route" : "/about-us" ,
2026-07-03 01:31:24 +04:00
"order" : 1
} ,
{
"id" : "footer-contacts" ,
"labelKey" : "nav.contacts" ,
"route" : "/contacts" ,
"order" : 2
} ,
{
"id" : "footer-privacy" ,
"labelKey" : "nav.privacy" ,
"route" : "/privacy-policy" ,
"order" : 3
}
]
} ,
2026-07-05 04:17:31 +04:00
"footer" : {
"paymentIcons" : [
{
"src" : "/assets/images/mir-logo.svg" ,
"alt" : "MIR" ,
"width" : 40 ,
"height" : 28
} ,
{
"src" : "/assets/images/visa-logo.svg" ,
"alt" : "Visa" ,
"width" : 40 ,
"height" : 28
} ,
{
"src" : "/assets/images/mastercard-logo.svg" ,
"alt" : "Mastercard" ,
"width" : 40 ,
"height" : 28
}
] ,
"copyrightText" : {
"ru" : "© 2026 Marketplace. В с е права защищены." ,
"en" : "© 2026 Marketplace. All rights reserved." ,
"hy" : "© 2026 Marketplace. Բոլոր իրավունքները պաշտպանված են:"
} ,
"legalPageKeys" : [ "about-us" , "privacy-policy" , "terms-of-service" ]
} ,
2026-07-09 00:55:50 +04:00
"catalog" : {
"layout" : "grid" ,
"navigationMode" : "default" ,
"defaultSort" : "relevance" ,
"availableSorts" : [ "relevance" , "latest" , "price_asc" , "price_desc" , "rating" , "popular" , "discount" ] ,
"enabledFilters" : [ "price" , "availability" , "rating" , "brand" , "category" , "subcategory" , "discount" , "new" , "color" , "size" , "attributes" ] ,
"showBreadcrumbs" : true ,
"showCategoryBanner" : true ,
"showSubcategoryChips" : true ,
"showRatings" : true ,
"showDiscounts" : true ,
"showAvailability" : true ,
"suggestionsEnabled" : true ,
"searchHistoryEnabled" : true
} ,
2026-07-09 00:45:36 +04:00
"productPage" : {
"rating" : {
"enabled" : true
} ,
"reviews" : {
"enabled" : true ,
"pageSize" : 5 ,
"showSummary" : true
} ,
"questions" : {
"enabled" : true ,
"pageSize" : 5
} ,
"tabs" : {
"enabled" : true ,
"items" : [ "description" , "specifications" , "reviews" , "questions" , "delivery" , "warranty" ]
} ,
"relatedProducts" : {
"enabled" : true
}
} ,
2026-07-09 01:13:54 +04:00
"userExperience" : {
"wishlist" : {
"enabled" : true ,
"headerBadgeEnabled" : true
} ,
"compare" : {
"enabled" : true ,
"maxItems" : 4 ,
"hideIdenticalDefault" : false ,
"highlightDifferencesDefault" : true
} ,
"recentlyViewed" : {
"enabled" : true ,
"maxItems" : 12 ,
"widgetEnabled" : true
} ,
"share" : {
"enabled" : true
} ,
"continueBrowsing" : {
"enabled" : true
} ,
"savedSearches" : {
"enabled" : true ,
"maxItems" : 10
}
} ,
2026-07-05 04:17:31 +04:00
"widgetRegistry" : {
"manifestUrl" : "/assets/mock/bootstrap/widget-manifest.json"
} ,
"staticPages" : {
"about-us" : {
"route" : "/about-us" ,
"title" : {
"ru" : "О компании" ,
"en" : "About Us" ,
"hy" : "Մեր մասին"
} ,
fix(storefront): home carousel overflow, static-page content, compare colour swatch
- product-carousel-widget: implicit CSS grid track had no min-width:0,
so the flex scroller's intrinsic content width (fixed 220px product
cards) overflowed the grid item and pushed body width to ~2187px on
a 1440px viewport, squeezing the entire homepage into a ~340px column.
Added min-width:0 to the track and scroller (standard grid/flex
overflow fix).
- bootstrap.json mock fixture: about-us/privacy-policy/terms-of-service
static pages (the real CMS pages served via bootstrap.staticPages,
per docs/PROJECT_INDEX.md) used a 'content' field, but
content-page.service.ts's normalizePage() only reads 'html' -
ContentPageBootstrapInput has no 'content' field. Title rendered,
body was always empty. Renamed the 3 fixture entries' field from
content to html to match the schema; content now renders.
- compare-table: colour row rendered raw hex/name values as plain text
(e.g. '#fCfCfC') with no swatch, inconsistent with variant-selector's
established colour-swatch pattern used on the product page. Added a
small circular swatch (reusing the same border-radius:50% pattern)
next to the value.
Verified live via ng serve: overflow gone (body/viewport width match
at 1440/1280/375), static pages render real content, compare swatch
displays. tsc --noEmit and ng build both clean (pre-existing bundle-
budget warning only, already tracked in KNOWN-ISSUES item 12).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 20:34:17 +04:00
"html" : {
2026-07-05 04:17:31 +04:00
"ru" : "<h2>О компании</h2><p>Marketplace — мультиарендная B2B commerce-платформа.</p>" ,
"en" : "<h2>About Us</h2><p>Marketplace is a multi-tenant B2B commerce platform.</p>" ,
"hy" : "<h2>Մեր մասին</h2><p>Marketplace-ը բազմավարձակալ B2B առևտրային հարթակ է։</p>"
}
} ,
"privacy-policy" : {
"route" : "/privacy-policy" ,
"title" : {
"ru" : "Политика конфиденциальности" ,
"en" : "Privacy Policy" ,
"hy" : "Գաղտնիության քաղաքականություն"
} ,
fix(storefront): home carousel overflow, static-page content, compare colour swatch
- product-carousel-widget: implicit CSS grid track had no min-width:0,
so the flex scroller's intrinsic content width (fixed 220px product
cards) overflowed the grid item and pushed body width to ~2187px on
a 1440px viewport, squeezing the entire homepage into a ~340px column.
Added min-width:0 to the track and scroller (standard grid/flex
overflow fix).
- bootstrap.json mock fixture: about-us/privacy-policy/terms-of-service
static pages (the real CMS pages served via bootstrap.staticPages,
per docs/PROJECT_INDEX.md) used a 'content' field, but
content-page.service.ts's normalizePage() only reads 'html' -
ContentPageBootstrapInput has no 'content' field. Title rendered,
body was always empty. Renamed the 3 fixture entries' field from
content to html to match the schema; content now renders.
- compare-table: colour row rendered raw hex/name values as plain text
(e.g. '#fCfCfC') with no swatch, inconsistent with variant-selector's
established colour-swatch pattern used on the product page. Added a
small circular swatch (reusing the same border-radius:50% pattern)
next to the value.
Verified live via ng serve: overflow gone (body/viewport width match
at 1440/1280/375), static pages render real content, compare swatch
displays. tsc --noEmit and ng build both clean (pre-existing bundle-
budget warning only, already tracked in KNOWN-ISSUES item 12).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 20:34:17 +04:00
"html" : {
2026-07-05 04:17:31 +04:00
"ru" : "<h2>Политика конфиденциальности</h2><p>Мы обрабатываем только необходимые данные.</p>" ,
"en" : "<h2>Privacy Policy</h2><p>We process only the data required for service operations.</p>" ,
"hy" : "<h2>Գաղտնիության քաղաքականություն</h2><p>Մենք մշակում ենք միայն ծառայության համար անհրաժեշտ տվյալները։</p>"
}
} ,
"terms-of-service" : {
"route" : "/terms-of-service" ,
"title" : {
"ru" : "Условия использования" ,
"en" : "Terms of Service" ,
"hy" : "Օգտագործման պայմաններ"
} ,
fix(storefront): home carousel overflow, static-page content, compare colour swatch
- product-carousel-widget: implicit CSS grid track had no min-width:0,
so the flex scroller's intrinsic content width (fixed 220px product
cards) overflowed the grid item and pushed body width to ~2187px on
a 1440px viewport, squeezing the entire homepage into a ~340px column.
Added min-width:0 to the track and scroller (standard grid/flex
overflow fix).
- bootstrap.json mock fixture: about-us/privacy-policy/terms-of-service
static pages (the real CMS pages served via bootstrap.staticPages,
per docs/PROJECT_INDEX.md) used a 'content' field, but
content-page.service.ts's normalizePage() only reads 'html' -
ContentPageBootstrapInput has no 'content' field. Title rendered,
body was always empty. Renamed the 3 fixture entries' field from
content to html to match the schema; content now renders.
- compare-table: colour row rendered raw hex/name values as plain text
(e.g. '#fCfCfC') with no swatch, inconsistent with variant-selector's
established colour-swatch pattern used on the product page. Added a
small circular swatch (reusing the same border-radius:50% pattern)
next to the value.
Verified live via ng serve: overflow gone (body/viewport width match
at 1440/1280/375), static pages render real content, compare swatch
displays. tsc --noEmit and ng build both clean (pre-existing bundle-
budget warning only, already tracked in KNOWN-ISSUES item 12).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 20:34:17 +04:00
"html" : {
2026-07-05 04:17:31 +04:00
"ru" : "<h2>Условия использования</h2><p>Использование платформы регулируется публичной офертой.</p>" ,
"en" : "<h2>Terms of Service</h2><p>Platform usage is governed by public offer terms.</p>" ,
"hy" : "<h2>Օգտագործման պայմաններ</h2><p>Հարթակի օգտագործումը կարգավորվում է հրապարակային առաջարկի պայմաններով։</p>"
}
2026-08-13 09:26:32 +04:00
} ,
"contacts" : {
"route" : "/contacts" ,
"title" : {
"ru" : "Контакты" ,
"en" : "Contacts" ,
"hy" : "Կապ"
} ,
"html" : {
"ru" : "<h2>Контакты</h2><p>Здесь будет размещена контактная информация продавца — адрес, телефон, email и часы работы. Заполняется администратором маркетплейса.</p>" ,
"en" : "<h2>Contacts</h2><p>Seller contact details (address, phone, email, business hours) go here. Fill this in from the admin panel.</p>" ,
"hy" : "<h2>Կապ</h2><p>Այստեղ կտեղադրվի վաճառողի կոնտակտային տեղեկատվությունը՝ հասցե, հեռախոս, էլ. փոստ և աշխատանքային ժամեր։ Լրացվում է կայքի ադմինիստրատորի կողմից։</p>"
}
2026-07-05 04:17:31 +04:00
}
} ,
2026-07-03 01:31:24 +04:00
"pages" : [
{
"id" : "page-home" ,
"key" : "home" ,
"title" : "Home" ,
"route" : {
2026-07-05 02:08:15 +04:00
"path" : "/" ,
2026-07-03 01:31:24 +04:00
"exact" : true
} ,
2026-07-05 04:17:31 +04:00
"layout" : {
"type" : "default"
} ,
2026-07-03 01:31:24 +04:00
"seoKey" : "home" ,
"visible" : true ,
"sections" : [
{
"id" : "section-hero" ,
"type" : "hero" ,
"order" : 1 ,
2026-07-05 02:08:15 +04:00
"layout" : {
"strategy" : "hero" ,
"columns" : 1 ,
"gap" : "1.5rem" ,
"align" : "stretch"
} ,
"visibility" : {
"desktop" : true ,
"tablet" : true ,
"mobile" : true
} ,
2026-07-03 01:31:24 +04:00
"visible" : true ,
"widgets" : [
{
"id" : "widget-hero-main" ,
"type" : "hero" ,
"version" : "1.0.0" ,
2026-07-05 04:17:31 +04:00
"order" : 1 ,
"padding" : "0.5rem 0" ,
"visibility" : {
"desktop" : true ,
"tablet" : true ,
"mobile" : true
} ,
2026-07-03 01:31:24 +04:00
"visible" : true ,
"props" : {
2026-07-19 22:44:45 +04:00
"title" : {
"ru" : "Добро пожаловать на Маркетплейс" ,
"en" : "Welcome to Marketplace Platform" ,
"hy" : "Բարի գալուստ Մարքեթփլեյս"
} ,
"subtitle" : {
"ru" : "Конфигурируемая мультитенантная торговая площадка" ,
"en" : "Configuration-driven multi-tenant commerce" ,
"hy" : "Կոնֆիգուրացիայով կառավարվող բազմատենանտ առևտրի հարթակ"
} ,
"ctaLabel" : {
"ru" : "Начать покупки" ,
"en" : "Start Shopping" ,
"hy" : "Սկսել գնումները"
}
2026-07-03 01:31:24 +04:00
}
}
]
2026-07-05 02:08:15 +04:00
} ,
{
"id" : "section-categories" ,
"type" : "categories" ,
"order" : 2 ,
"layout" : {
"strategy" : "grid" ,
"columns" : 1 ,
"gap" : "1.5rem" ,
"align" : "stretch"
} ,
"visibility" : {
"desktop" : true ,
"tablet" : true ,
"mobile" : true
} ,
"visible" : true ,
"widgets" : [
{
"id" : "widget-categories-root" ,
"type" : "categories" ,
"version" : "1.0.0" ,
2026-07-05 04:17:31 +04:00
"order" : 1 ,
"padding" : "0.25rem 0" ,
"visibility" : {
"desktop" : true ,
"tablet" : true ,
"mobile" : true
} ,
2026-07-05 02:08:15 +04:00
"visible" : true ,
"props" : {
"title" : "Categories" ,
"source" : "root" ,
"emptyMessage" : "No categories available"
}
}
]
} ,
{
"id" : "section-featured-products" ,
"type" : "product-collection" ,
"order" : 3 ,
"layout" : {
"strategy" : "carousel" ,
"columns" : 1 ,
"gap" : "1rem" ,
"align" : "stretch"
} ,
"visibility" : {
"desktop" : true ,
"tablet" : true ,
"mobile" : true
} ,
"visible" : true ,
"widgets" : [
{
"id" : "widget-featured-products" ,
"type" : "product-collection" ,
"version" : "1.0.0" ,
2026-07-05 04:17:31 +04:00
"order" : 1 ,
"padding" : "0" ,
"visibility" : {
"desktop" : true ,
"tablet" : true ,
"mobile" : true
} ,
2026-07-05 02:08:15 +04:00
"visible" : true ,
"props" : {
"title" : "Featured Products" ,
"source" : "featured" ,
"count" : 8 ,
"actionLabel" : "Select"
}
}
]
2026-07-03 01:31:24 +04:00
}
]
}
]
}