tt-entities 0.0.39 → 0.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/libs/tatayab-entities-library/entities/app-config.entity.d.ts +5 -0
- package/dist/libs/tatayab-entities-library/entities/app-config.entity.js +28 -0
- package/dist/libs/tatayab-entities-library/entities/app-config.entity.js.map +1 -0
- package/dist/libs/tatayab-entities-library/entities/banner.entity.d.ts +42 -0
- package/dist/libs/tatayab-entities-library/entities/banner.entity.js +118 -0
- package/dist/libs/tatayab-entities-library/entities/banner.entity.js.map +1 -0
- package/dist/libs/tatayab-entities-library/index.d.ts +2 -0
- package/dist/libs/tatayab-entities-library/index.js +12 -2
- package/dist/libs/tatayab-entities-library/index.js.map +1 -1
- package/dist/src/main.js +180 -3
- package/libs/tatayab-entities-library/src/entities/app-config.entity.ts +9 -0
- package/libs/tatayab-entities-library/src/entities/banner.entity.ts +121 -0
- package/libs/tatayab-entities-library/src/index.ts +14 -0
- package/package.json +1 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Model,
|
|
3
|
+
Table,
|
|
4
|
+
Column,
|
|
5
|
+
DataType,
|
|
6
|
+
ForeignKey,
|
|
7
|
+
BelongsTo,
|
|
8
|
+
} from 'sequelize-typescript';
|
|
9
|
+
|
|
10
|
+
// ── Where the banner appears ──────────────────────────────────────────────────
|
|
11
|
+
export enum BannerPlacement {
|
|
12
|
+
HOME = 'home', // horizontal list on the home page
|
|
13
|
+
CATEGORY = 'category', // top of a specific category page
|
|
14
|
+
BRAND = 'brand', // top of a specific brand page
|
|
15
|
+
SEARCH = 'search', // search results page
|
|
16
|
+
CUSTOM = 'custom', // any future placement — identified by placementKey
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export enum BannerStatus {
|
|
20
|
+
ACTIVE = 'active',
|
|
21
|
+
INACTIVE = 'inactive',
|
|
22
|
+
DRAFT = 'draft',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// ── Filter shape stored in the JSON column ────────────────────────────────────
|
|
26
|
+
// All fields are optional — any combination is valid.
|
|
27
|
+
// An empty object {} means "show everything" (no filter).
|
|
28
|
+
export interface BannerFilters {
|
|
29
|
+
categoryIds?: number[]; // products/bundles in these categories
|
|
30
|
+
brandIds?: number[]; // products belonging to these brands
|
|
31
|
+
tagSlugs?: string[]; // products tagged with any of these slugs
|
|
32
|
+
types?: ('product' | 'bundle')[]; // limit to only products or only bundles
|
|
33
|
+
isFeatured?: boolean; // only featured items
|
|
34
|
+
minPrice?: number;
|
|
35
|
+
maxPrice?: number;
|
|
36
|
+
// Future: collectionId, promotionId, etc.
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Table
|
|
40
|
+
export class Banner extends Model {
|
|
41
|
+
// ── Identity ────────────────────────────────────────────────────────────────
|
|
42
|
+
@Column({ allowNull: false })
|
|
43
|
+
declare titleEn: string;
|
|
44
|
+
|
|
45
|
+
@Column({ allowNull: false })
|
|
46
|
+
declare titleAr: string;
|
|
47
|
+
|
|
48
|
+
@Column({ type: DataType.TEXT, allowNull: true })
|
|
49
|
+
declare subtitleEn: string | null;
|
|
50
|
+
|
|
51
|
+
@Column({ type: DataType.TEXT, allowNull: true })
|
|
52
|
+
declare subtitleAr: string | null;
|
|
53
|
+
|
|
54
|
+
// ── Media ───────────────────────────────────────────────────────────────────
|
|
55
|
+
@Column({ allowNull: false })
|
|
56
|
+
declare coverImage: string; // S3 URL
|
|
57
|
+
|
|
58
|
+
@Column({ allowNull: true })
|
|
59
|
+
declare coverImageMobile: string | null; // optional separate mobile crop
|
|
60
|
+
|
|
61
|
+
// ── Placement ───────────────────────────────────────────────────────────────
|
|
62
|
+
// WHERE this banner appears
|
|
63
|
+
@Column({
|
|
64
|
+
type: DataType.ENUM(...Object.values(BannerPlacement)),
|
|
65
|
+
allowNull: false,
|
|
66
|
+
defaultValue: BannerPlacement.HOME,
|
|
67
|
+
})
|
|
68
|
+
declare placement: BannerPlacement;
|
|
69
|
+
|
|
70
|
+
// For placement=category → placementRefId = categoryId
|
|
71
|
+
// For placement=brand → placementRefId = brandId
|
|
72
|
+
// For placement=home/search/custom → null
|
|
73
|
+
@Column({ allowNull: true })
|
|
74
|
+
declare placementRefId?: number;
|
|
75
|
+
|
|
76
|
+
// Human-readable key for custom placements (e.g. "ramadan_sale", "checkout_top")
|
|
77
|
+
@Column({ allowNull: true })
|
|
78
|
+
declare placementKey?: string;
|
|
79
|
+
|
|
80
|
+
// ── Catalog filters (what products/bundles appear INSIDE the banner) ─────────
|
|
81
|
+
// Stored as JSON — resolved at runtime via CatalogListService
|
|
82
|
+
@Column({
|
|
83
|
+
type: DataType.JSON,
|
|
84
|
+
allowNull: false,
|
|
85
|
+
defaultValue: {},
|
|
86
|
+
})
|
|
87
|
+
declare filters: BannerFilters;
|
|
88
|
+
|
|
89
|
+
// Max number of items to return inside the banner (null = use API default)
|
|
90
|
+
@Column({ allowNull: true })
|
|
91
|
+
declare itemLimit?: number;
|
|
92
|
+
|
|
93
|
+
// ── CTA (optional tap action on the banner cover itself) ─────────────────────
|
|
94
|
+
@Column({ allowNull: true })
|
|
95
|
+
declare ctaLabelEn?: string;
|
|
96
|
+
|
|
97
|
+
@Column({ allowNull: true })
|
|
98
|
+
declare ctaLabelAr?: string;
|
|
99
|
+
|
|
100
|
+
// Deep link or web URL the cover image taps to
|
|
101
|
+
@Column({ allowNull: true })
|
|
102
|
+
declare ctaUrl?: string;
|
|
103
|
+
|
|
104
|
+
// ── Scheduling ───────────────────────────────────────────────────────────────
|
|
105
|
+
@Column({ type: DataType.DATE, allowNull: true })
|
|
106
|
+
declare startDate?: Date; // null = show immediately
|
|
107
|
+
|
|
108
|
+
@Column({ type: DataType.DATE, allowNull: true })
|
|
109
|
+
declare endDate?: Date; // null = show indefinitely
|
|
110
|
+
|
|
111
|
+
// ── Display ─────────────────────────────────────────────────────────────────
|
|
112
|
+
@Column({ defaultValue: 0 })
|
|
113
|
+
declare sortOrder: number;
|
|
114
|
+
|
|
115
|
+
@Column({
|
|
116
|
+
type: DataType.ENUM(...Object.values(BannerStatus)),
|
|
117
|
+
allowNull: false,
|
|
118
|
+
defaultValue: BannerStatus.DRAFT,
|
|
119
|
+
})
|
|
120
|
+
declare status: BannerStatus;
|
|
121
|
+
}
|
|
@@ -11,6 +11,8 @@ import { ApiKey } from './entities/apikey.entity';
|
|
|
11
11
|
import { UserAddress } from './entities/user-address.entity';
|
|
12
12
|
import { UserFavorite } from './entities/user-favorite.entity';
|
|
13
13
|
import { UserFavoriteCatalog } from './entities/user-favorite-catalog.entity';
|
|
14
|
+
import { Banner } from './entities/banner.entity';
|
|
15
|
+
import { AppConfig } from './entities/app-config.entity';
|
|
14
16
|
|
|
15
17
|
// ─── Catalogue ────────────────────────────────────────────────────────────────
|
|
16
18
|
import { Category } from './entities/category.entity';
|
|
@@ -92,6 +94,13 @@ export {
|
|
|
92
94
|
UserFavoriteCatalog,
|
|
93
95
|
FavoriteCatalogItemType,
|
|
94
96
|
} from './entities/user-favorite-catalog.entity';
|
|
97
|
+
export {
|
|
98
|
+
Banner,
|
|
99
|
+
BannerPlacement,
|
|
100
|
+
BannerStatus,
|
|
101
|
+
BannerFilters,
|
|
102
|
+
} from './entities/banner.entity';
|
|
103
|
+
export { AppConfig } from './entities/app-config.entity';
|
|
95
104
|
|
|
96
105
|
// ─── Catalogue ────────────────────────────────────────────────────────────────
|
|
97
106
|
export { Category } from './entities/category.entity';
|
|
@@ -267,5 +276,10 @@ export function getDbModels(): ModelCtor[] {
|
|
|
267
276
|
OrderStatusHistory,
|
|
268
277
|
UserTransaction,
|
|
269
278
|
PurchaseOrderOrderItem,
|
|
279
|
+
|
|
280
|
+
// Banners
|
|
281
|
+
Banner,
|
|
282
|
+
|
|
283
|
+
AppConfig,
|
|
270
284
|
];
|
|
271
285
|
}
|