phase-2: add shared platform interfaces and type contracts
This commit is contained in:
2
src/app/shared/index.ts
Normal file
2
src/app/shared/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './models';
|
||||||
|
export * from './types';
|
||||||
12
src/app/shared/models/config/api-endpoints.model.ts
Normal file
12
src/app/shared/models/config/api-endpoints.model.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
export interface ApiEndpointConfig {
|
||||||
|
path: string;
|
||||||
|
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
||||||
|
timeoutMs?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiEndpointsConfig {
|
||||||
|
bootstrap: ApiEndpointConfig;
|
||||||
|
website: Record<string, ApiEndpointConfig>;
|
||||||
|
builder: Record<string, ApiEndpointConfig>;
|
||||||
|
backoffice: Record<string, ApiEndpointConfig>;
|
||||||
|
}
|
||||||
27
src/app/shared/models/config/bootstrap-config.model.ts
Normal file
27
src/app/shared/models/config/bootstrap-config.model.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { ApiEndpointsConfig } from './api-endpoints.model';
|
||||||
|
import { BrandingConfig } from './branding.model';
|
||||||
|
import { CompanyConfig } from './company.model';
|
||||||
|
import { FeatureFlagsConfig } from './feature-flags.model';
|
||||||
|
import { LocalizationConfig } from './localization.model';
|
||||||
|
import { NavigationConfig } from './navigation.model';
|
||||||
|
import { PageConfig } from './page.model';
|
||||||
|
import { PermissionsConfig } from './permissions.model';
|
||||||
|
import { SeoConfig } from './seo.model';
|
||||||
|
import { TenantConfig } from './tenant.model';
|
||||||
|
import { ThemeConfig } from './theme.model';
|
||||||
|
|
||||||
|
export interface BootstrapConfig {
|
||||||
|
schemaVersion: string;
|
||||||
|
generatedAt: string;
|
||||||
|
tenant: TenantConfig;
|
||||||
|
branding: BrandingConfig;
|
||||||
|
theme: ThemeConfig;
|
||||||
|
company: CompanyConfig;
|
||||||
|
featureFlags: FeatureFlagsConfig;
|
||||||
|
apiEndpoints: ApiEndpointsConfig;
|
||||||
|
localization: LocalizationConfig;
|
||||||
|
seo: SeoConfig;
|
||||||
|
permissions: PermissionsConfig;
|
||||||
|
navigation: NavigationConfig;
|
||||||
|
pages: PageConfig[];
|
||||||
|
}
|
||||||
13
src/app/shared/models/config/branding.model.ts
Normal file
13
src/app/shared/models/config/branding.model.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { UrlString } from '../../types/primitive.types';
|
||||||
|
|
||||||
|
export interface BrandingConfig {
|
||||||
|
brandName: string;
|
||||||
|
legalName: string;
|
||||||
|
slogan?: string;
|
||||||
|
logoUrl: UrlString;
|
||||||
|
logoCompactUrl?: UrlString;
|
||||||
|
faviconUrl: UrlString;
|
||||||
|
appIconUrl?: UrlString;
|
||||||
|
supportEmail?: string;
|
||||||
|
supportPhone?: string;
|
||||||
|
}
|
||||||
22
src/app/shared/models/config/company.model.ts
Normal file
22
src/app/shared/models/config/company.model.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
export interface CompanyAddressConfig {
|
||||||
|
country: string;
|
||||||
|
region?: string;
|
||||||
|
city: string;
|
||||||
|
street?: string;
|
||||||
|
postalCode?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompanyContactConfig {
|
||||||
|
email: string;
|
||||||
|
phone?: string;
|
||||||
|
telegram?: string;
|
||||||
|
website?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompanyConfig {
|
||||||
|
companyName: string;
|
||||||
|
registrationNumber?: string;
|
||||||
|
taxId?: string;
|
||||||
|
address: CompanyAddressConfig;
|
||||||
|
contacts: CompanyContactConfig;
|
||||||
|
}
|
||||||
14
src/app/shared/models/config/feature-flags.model.ts
Normal file
14
src/app/shared/models/config/feature-flags.model.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export interface FeatureFlagsConfig {
|
||||||
|
wishlist: boolean;
|
||||||
|
compare: boolean;
|
||||||
|
reviews: boolean;
|
||||||
|
blog: boolean;
|
||||||
|
chat: boolean;
|
||||||
|
analytics: boolean;
|
||||||
|
notifications: boolean;
|
||||||
|
coupons: boolean;
|
||||||
|
loyalty: boolean;
|
||||||
|
giftCards: boolean;
|
||||||
|
invoices: boolean;
|
||||||
|
[key: string]: boolean;
|
||||||
|
}
|
||||||
14
src/app/shared/models/config/index.ts
Normal file
14
src/app/shared/models/config/index.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export * from './api-endpoints.model';
|
||||||
|
export * from './bootstrap-config.model';
|
||||||
|
export * from './branding.model';
|
||||||
|
export * from './company.model';
|
||||||
|
export * from './feature-flags.model';
|
||||||
|
export * from './localization.model';
|
||||||
|
export * from './navigation.model';
|
||||||
|
export * from './page.model';
|
||||||
|
export * from './permissions.model';
|
||||||
|
export * from './section.model';
|
||||||
|
export * from './seo.model';
|
||||||
|
export * from './tenant.model';
|
||||||
|
export * from './theme.model';
|
||||||
|
export * from './widget.model';
|
||||||
12
src/app/shared/models/config/localization.model.ts
Normal file
12
src/app/shared/models/config/localization.model.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
export interface LocalizationDictionaryRef {
|
||||||
|
locale: string;
|
||||||
|
dictionaryUrl: string;
|
||||||
|
version: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LocalizationConfig {
|
||||||
|
defaultLocale: string;
|
||||||
|
supportedLocales: string[];
|
||||||
|
currencyByLocale: Record<string, string>;
|
||||||
|
dictionaries: LocalizationDictionaryRef[];
|
||||||
|
}
|
||||||
15
src/app/shared/models/config/navigation.model.ts
Normal file
15
src/app/shared/models/config/navigation.model.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
export interface NavigationItemConfig {
|
||||||
|
id: string;
|
||||||
|
labelKey: string;
|
||||||
|
route: string;
|
||||||
|
icon?: string;
|
||||||
|
order: number;
|
||||||
|
visibleWhenFlags?: string[];
|
||||||
|
children?: NavigationItemConfig[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NavigationConfig {
|
||||||
|
header: NavigationItemConfig[];
|
||||||
|
footer: NavigationItemConfig[];
|
||||||
|
sidebar?: NavigationItemConfig[];
|
||||||
|
}
|
||||||
18
src/app/shared/models/config/page.model.ts
Normal file
18
src/app/shared/models/config/page.model.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { SectionConfig } from './section.model';
|
||||||
|
|
||||||
|
export interface PageRouteConfig {
|
||||||
|
path: string;
|
||||||
|
exact?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PageConfig {
|
||||||
|
id: string;
|
||||||
|
key: string;
|
||||||
|
title: string;
|
||||||
|
route: PageRouteConfig;
|
||||||
|
layout: string;
|
||||||
|
sections: SectionConfig[];
|
||||||
|
seoKey?: string;
|
||||||
|
featureFlag?: string;
|
||||||
|
visible?: boolean;
|
||||||
|
}
|
||||||
14
src/app/shared/models/config/permissions.model.ts
Normal file
14
src/app/shared/models/config/permissions.model.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export interface PermissionDefinition {
|
||||||
|
key: string;
|
||||||
|
description?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RolePermissions {
|
||||||
|
role: string;
|
||||||
|
permissions: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PermissionsConfig {
|
||||||
|
definitions: PermissionDefinition[];
|
||||||
|
roles: RolePermissions[];
|
||||||
|
}
|
||||||
17
src/app/shared/models/config/section.model.ts
Normal file
17
src/app/shared/models/config/section.model.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { WidgetConfig } from './widget.model';
|
||||||
|
|
||||||
|
export interface SectionLayoutConfig {
|
||||||
|
columns?: number;
|
||||||
|
gap?: string;
|
||||||
|
align?: 'start' | 'center' | 'end' | 'stretch';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SectionConfig {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
order: number;
|
||||||
|
layout?: SectionLayoutConfig;
|
||||||
|
widgets: WidgetConfig[];
|
||||||
|
featureFlag?: string;
|
||||||
|
visible?: boolean;
|
||||||
|
}
|
||||||
18
src/app/shared/models/config/seo.model.ts
Normal file
18
src/app/shared/models/config/seo.model.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
export interface SeoMetaTagConfig {
|
||||||
|
name?: string;
|
||||||
|
property?: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SeoPageConfig {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
canonicalUrl?: string;
|
||||||
|
robots?: string;
|
||||||
|
metaTags?: SeoMetaTagConfig[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SeoConfig {
|
||||||
|
default: SeoPageConfig;
|
||||||
|
byPageKey: Record<string, SeoPageConfig>;
|
||||||
|
}
|
||||||
17
src/app/shared/models/config/tenant.model.ts
Normal file
17
src/app/shared/models/config/tenant.model.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { UUID, UrlString } from '../../types/primitive.types';
|
||||||
|
|
||||||
|
export interface TenantConfig {
|
||||||
|
id: UUID;
|
||||||
|
slug: string;
|
||||||
|
code: string;
|
||||||
|
host: string;
|
||||||
|
name: string;
|
||||||
|
websiteBaseUrl: UrlString;
|
||||||
|
builderBaseUrl: UrlString;
|
||||||
|
backofficeBaseUrl: UrlString;
|
||||||
|
defaultLocale: string;
|
||||||
|
supportedLocales: string[];
|
||||||
|
defaultCurrency: string;
|
||||||
|
supportedCurrencies: string[];
|
||||||
|
timezone: string;
|
||||||
|
}
|
||||||
36
src/app/shared/models/config/theme.model.ts
Normal file
36
src/app/shared/models/config/theme.model.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
export interface ThemeTypographyConfig {
|
||||||
|
primaryFontFamily: string;
|
||||||
|
headingFontFamily?: string;
|
||||||
|
baseFontSize: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ThemeSpacingConfig {
|
||||||
|
unit: number;
|
||||||
|
scale: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ThemePaletteConfig {
|
||||||
|
primary: string;
|
||||||
|
secondary: string;
|
||||||
|
accent: string;
|
||||||
|
success: string;
|
||||||
|
warning: string;
|
||||||
|
danger: string;
|
||||||
|
info: string;
|
||||||
|
textPrimary: string;
|
||||||
|
textSecondary: string;
|
||||||
|
backgroundPrimary: string;
|
||||||
|
backgroundSecondary: string;
|
||||||
|
border: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ThemeConfig {
|
||||||
|
themeId: string;
|
||||||
|
mode: 'light' | 'dark' | 'system';
|
||||||
|
palette: ThemePaletteConfig;
|
||||||
|
typography: ThemeTypographyConfig;
|
||||||
|
spacing: ThemeSpacingConfig;
|
||||||
|
borderRadiusScale: Record<string, string>;
|
||||||
|
shadows: Record<string, string>;
|
||||||
|
iconSet: string;
|
||||||
|
}
|
||||||
15
src/app/shared/models/config/widget.model.ts
Normal file
15
src/app/shared/models/config/widget.model.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
export interface WidgetActionConfig {
|
||||||
|
type: 'navigate' | 'open' | 'submit' | 'custom';
|
||||||
|
target?: string;
|
||||||
|
payload?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WidgetConfig {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
version: string;
|
||||||
|
props: Record<string, unknown>;
|
||||||
|
actions?: Record<string, WidgetActionConfig>;
|
||||||
|
featureFlag?: string;
|
||||||
|
visible?: boolean;
|
||||||
|
}
|
||||||
1
src/app/shared/models/domain/index.ts
Normal file
1
src/app/shared/models/domain/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './user-preferences.model';
|
||||||
8
src/app/shared/models/domain/user-preferences.model.ts
Normal file
8
src/app/shared/models/domain/user-preferences.model.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export interface UserPreferences {
|
||||||
|
locale: string;
|
||||||
|
currency: string;
|
||||||
|
themeMode: 'light' | 'dark' | 'system';
|
||||||
|
compactMode?: boolean;
|
||||||
|
wishlistEnabled?: boolean;
|
||||||
|
notificationsEnabled?: boolean;
|
||||||
|
}
|
||||||
3
src/app/shared/models/index.ts
Normal file
3
src/app/shared/models/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export * as ConfigModels from './config';
|
||||||
|
export * as DomainModels from './domain';
|
||||||
|
export * as UiModels from './ui';
|
||||||
13
src/app/shared/models/ui/button.model.ts
Normal file
13
src/app/shared/models/ui/button.model.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export interface ButtonConfig {
|
||||||
|
id?: string;
|
||||||
|
label: string;
|
||||||
|
variant: 'primary' | 'secondary' | 'tertiary' | 'ghost' | 'danger';
|
||||||
|
size?: 'sm' | 'md' | 'lg';
|
||||||
|
icon?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
loading?: boolean;
|
||||||
|
action?: {
|
||||||
|
type: 'navigate' | 'submit' | 'emit' | 'custom';
|
||||||
|
target?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
11
src/app/shared/models/ui/category-card.model.ts
Normal file
11
src/app/shared/models/ui/category-card.model.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { ButtonConfig } from './button.model';
|
||||||
|
|
||||||
|
export interface CategoryCardConfig {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
imageUrl?: string;
|
||||||
|
icon?: string;
|
||||||
|
itemsCount?: number;
|
||||||
|
action?: ButtonConfig;
|
||||||
|
}
|
||||||
3
src/app/shared/models/ui/index.ts
Normal file
3
src/app/shared/models/ui/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export * from './button.model';
|
||||||
|
export * from './category-card.model';
|
||||||
|
export * from './product-card.model';
|
||||||
23
src/app/shared/models/ui/product-card.model.ts
Normal file
23
src/app/shared/models/ui/product-card.model.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { ButtonConfig } from './button.model';
|
||||||
|
|
||||||
|
export interface ProductCardPrice {
|
||||||
|
amount: number;
|
||||||
|
currency: string;
|
||||||
|
originalAmount?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProductCardConfig {
|
||||||
|
id: string;
|
||||||
|
sku: string;
|
||||||
|
title: string;
|
||||||
|
subtitle?: string;
|
||||||
|
imageUrl: string;
|
||||||
|
badges?: string[];
|
||||||
|
tags?: string[];
|
||||||
|
rating?: number;
|
||||||
|
reviewsCount?: number;
|
||||||
|
price: ProductCardPrice;
|
||||||
|
stockStatus?: 'in_stock' | 'low_stock' | 'out_of_stock';
|
||||||
|
primaryAction?: ButtonConfig;
|
||||||
|
secondaryAction?: ButtonConfig;
|
||||||
|
}
|
||||||
1
src/app/shared/types/index.ts
Normal file
1
src/app/shared/types/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './primitive.types';
|
||||||
5
src/app/shared/types/primitive.types.ts
Normal file
5
src/app/shared/types/primitive.types.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export type UUID = string;
|
||||||
|
export type ISODateTime = string;
|
||||||
|
export type LocaleCode = string;
|
||||||
|
export type CurrencyCode = string;
|
||||||
|
export type UrlString = string;
|
||||||
Reference in New Issue
Block a user