@hed-hog/catalog 0.0.276
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/catalog-resource.config.d.ts +12 -0
- package/dist/catalog-resource.config.d.ts.map +1 -0
- package/dist/catalog-resource.config.js +209 -0
- package/dist/catalog-resource.config.js.map +1 -0
- package/dist/catalog.controller.d.ts +29 -0
- package/dist/catalog.controller.d.ts.map +1 -0
- package/dist/catalog.controller.js +117 -0
- package/dist/catalog.controller.js.map +1 -0
- package/dist/catalog.module.d.ts +3 -0
- package/dist/catalog.module.d.ts.map +1 -0
- package/dist/catalog.module.js +25 -0
- package/dist/catalog.module.js.map +1 -0
- package/dist/catalog.service.d.ts +36 -0
- package/dist/catalog.service.d.ts.map +1 -0
- package/dist/catalog.service.js +142 -0
- package/dist/catalog.service.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/hedhog/data/menu.yaml +233 -0
- package/hedhog/data/role.yaml +7 -0
- package/hedhog/data/route.yaml +56 -0
- package/hedhog/frontend/app/[resource]/page.tsx.ejs +684 -0
- package/hedhog/frontend/app/_components/catalog-nav.tsx.ejs +85 -0
- package/hedhog/frontend/app/_lib/catalog-resources.tsx.ejs +569 -0
- package/hedhog/frontend/app/dashboard/page.tsx.ejs +566 -0
- package/hedhog/frontend/app/page.tsx.ejs +5 -0
- package/hedhog/frontend/messages/en.json +293 -0
- package/hedhog/frontend/messages/pt.json +293 -0
- package/hedhog/table/catalog_affiliate_program.yaml +41 -0
- package/hedhog/table/catalog_attribute.yaml +53 -0
- package/hedhog/table/catalog_attribute_group.yaml +18 -0
- package/hedhog/table/catalog_brand.yaml +34 -0
- package/hedhog/table/catalog_category_attribute.yaml +36 -0
- package/hedhog/table/catalog_click_event.yaml +50 -0
- package/hedhog/table/catalog_comparison.yaml +65 -0
- package/hedhog/table/catalog_comparison_highlight.yaml +39 -0
- package/hedhog/table/catalog_comparison_item.yaml +30 -0
- package/hedhog/table/catalog_content_relation.yaml +42 -0
- package/hedhog/table/catalog_import_run.yaml +33 -0
- package/hedhog/table/catalog_import_source.yaml +24 -0
- package/hedhog/table/catalog_merchant.yaml +29 -0
- package/hedhog/table/catalog_offer.yaml +83 -0
- package/hedhog/table/catalog_price_history.yaml +34 -0
- package/hedhog/table/catalog_product.yaml +76 -0
- package/hedhog/table/catalog_product_attribute_value.yaml +60 -0
- package/hedhog/table/catalog_product_category.yaml +26 -0
- package/hedhog/table/catalog_product_image.yaml +34 -0
- package/hedhog/table/catalog_product_score.yaml +38 -0
- package/hedhog/table/catalog_product_site.yaml +47 -0
- package/hedhog/table/catalog_product_tag.yaml +19 -0
- package/hedhog/table/catalog_score_criterion.yaml +37 -0
- package/hedhog/table/catalog_seo_page_rule.yaml +51 -0
- package/hedhog/table/catalog_similarity_rule.yaml +28 -0
- package/hedhog/table/catalog_site.yaml +40 -0
- package/hedhog/table/catalog_site_category.yaml +26 -0
- package/package.json +40 -0
- package/src/catalog-resource.config.ts +218 -0
- package/src/catalog.controller.ts +82 -0
- package/src/catalog.module.ts +12 -0
- package/src/catalog.service.ts +167 -0
- package/src/index.ts +1 -0
- package/src/language/en.json +4 -0
- package/src/language/pt.json +4 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: product_id
|
|
4
|
+
type: fk
|
|
5
|
+
references:
|
|
6
|
+
table: catalog_product
|
|
7
|
+
column: id
|
|
8
|
+
onDelete: CASCADE
|
|
9
|
+
- name: file_id
|
|
10
|
+
type: fk
|
|
11
|
+
references:
|
|
12
|
+
table: file
|
|
13
|
+
column: id
|
|
14
|
+
onDelete: CASCADE
|
|
15
|
+
- name: role
|
|
16
|
+
type: enum
|
|
17
|
+
values: [primary, gallery, thumbnail, lifestyle, technical]
|
|
18
|
+
default: gallery
|
|
19
|
+
- name: sort_order
|
|
20
|
+
type: int
|
|
21
|
+
default: 0
|
|
22
|
+
- name: is_primary
|
|
23
|
+
type: boolean
|
|
24
|
+
default: false
|
|
25
|
+
- name: alt_text
|
|
26
|
+
type: varchar
|
|
27
|
+
length: 255
|
|
28
|
+
isNullable: true
|
|
29
|
+
- type: created_at
|
|
30
|
+
- type: updated_at
|
|
31
|
+
indices:
|
|
32
|
+
- columns: [product_id, sort_order]
|
|
33
|
+
- columns: [product_id, is_primary]
|
|
34
|
+
- columns: [file_id]
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: product_id
|
|
4
|
+
type: fk
|
|
5
|
+
references:
|
|
6
|
+
table: catalog_product
|
|
7
|
+
column: id
|
|
8
|
+
onDelete: CASCADE
|
|
9
|
+
- name: criterion_id
|
|
10
|
+
type: fk
|
|
11
|
+
references:
|
|
12
|
+
table: catalog_score_criterion
|
|
13
|
+
column: id
|
|
14
|
+
onDelete: CASCADE
|
|
15
|
+
- name: score_value
|
|
16
|
+
type: decimal
|
|
17
|
+
precision: 5
|
|
18
|
+
scale: 2
|
|
19
|
+
- name: score_label
|
|
20
|
+
type: varchar
|
|
21
|
+
length: 255
|
|
22
|
+
isNullable: true
|
|
23
|
+
- name: summary
|
|
24
|
+
type: text
|
|
25
|
+
isNullable: true
|
|
26
|
+
- name: calculation_source
|
|
27
|
+
type: varchar
|
|
28
|
+
length: 255
|
|
29
|
+
isNullable: true
|
|
30
|
+
- name: is_manual_override
|
|
31
|
+
type: boolean
|
|
32
|
+
default: false
|
|
33
|
+
- type: created_at
|
|
34
|
+
- type: updated_at
|
|
35
|
+
indices:
|
|
36
|
+
- columns: [product_id, criterion_id]
|
|
37
|
+
isUnique: true
|
|
38
|
+
- columns: [criterion_id, score_value]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: product_id
|
|
4
|
+
type: fk
|
|
5
|
+
references:
|
|
6
|
+
table: catalog_product
|
|
7
|
+
column: id
|
|
8
|
+
onDelete: CASCADE
|
|
9
|
+
- name: site_id
|
|
10
|
+
type: fk
|
|
11
|
+
references:
|
|
12
|
+
table: catalog_site
|
|
13
|
+
column: id
|
|
14
|
+
onDelete: CASCADE
|
|
15
|
+
- name: publication_status
|
|
16
|
+
type: enum
|
|
17
|
+
values: [draft, published, hidden]
|
|
18
|
+
default: draft
|
|
19
|
+
- name: canonical_slug
|
|
20
|
+
type: varchar
|
|
21
|
+
length: 255
|
|
22
|
+
- name: is_featured
|
|
23
|
+
type: boolean
|
|
24
|
+
default: false
|
|
25
|
+
- name: visibility_score
|
|
26
|
+
type: int
|
|
27
|
+
default: 0
|
|
28
|
+
- name: override_brand_name
|
|
29
|
+
type: varchar
|
|
30
|
+
length: 255
|
|
31
|
+
isNullable: true
|
|
32
|
+
- name: seo_title
|
|
33
|
+
type: varchar
|
|
34
|
+
length: 255
|
|
35
|
+
isNullable: true
|
|
36
|
+
- name: seo_description
|
|
37
|
+
type: varchar
|
|
38
|
+
length: 500
|
|
39
|
+
isNullable: true
|
|
40
|
+
- type: created_at
|
|
41
|
+
- type: updated_at
|
|
42
|
+
indices:
|
|
43
|
+
- columns: [site_id, product_id]
|
|
44
|
+
isUnique: true
|
|
45
|
+
- columns: [site_id, canonical_slug]
|
|
46
|
+
isUnique: true
|
|
47
|
+
- columns: [site_id, publication_status]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: product_id
|
|
4
|
+
type: fk
|
|
5
|
+
references:
|
|
6
|
+
table: catalog_product
|
|
7
|
+
column: id
|
|
8
|
+
onDelete: CASCADE
|
|
9
|
+
- name: tag_id
|
|
10
|
+
type: fk
|
|
11
|
+
references:
|
|
12
|
+
table: tag
|
|
13
|
+
column: id
|
|
14
|
+
onDelete: CASCADE
|
|
15
|
+
- type: created_at
|
|
16
|
+
- type: updated_at
|
|
17
|
+
indices:
|
|
18
|
+
- columns: [product_id, tag_id]
|
|
19
|
+
isUnique: true
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: category_id
|
|
4
|
+
type: fk
|
|
5
|
+
references:
|
|
6
|
+
table: category
|
|
7
|
+
column: id
|
|
8
|
+
onDelete: CASCADE
|
|
9
|
+
- name: slug
|
|
10
|
+
type: varchar
|
|
11
|
+
length: 255
|
|
12
|
+
- name: name
|
|
13
|
+
type: varchar
|
|
14
|
+
length: 255
|
|
15
|
+
- name: weight
|
|
16
|
+
type: int
|
|
17
|
+
default: 1
|
|
18
|
+
- name: score_type
|
|
19
|
+
type: enum
|
|
20
|
+
values: [manual, weighted, formula]
|
|
21
|
+
default: manual
|
|
22
|
+
- name: formula_json
|
|
23
|
+
type: json
|
|
24
|
+
isNullable: true
|
|
25
|
+
- name: display_order
|
|
26
|
+
type: int
|
|
27
|
+
default: 0
|
|
28
|
+
- name: status
|
|
29
|
+
type: enum
|
|
30
|
+
values: [active, inactive]
|
|
31
|
+
default: active
|
|
32
|
+
- type: created_at
|
|
33
|
+
- type: updated_at
|
|
34
|
+
indices:
|
|
35
|
+
- columns: [category_id, slug]
|
|
36
|
+
isUnique: true
|
|
37
|
+
- columns: [category_id, status]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: site_id
|
|
4
|
+
type: fk
|
|
5
|
+
references:
|
|
6
|
+
table: catalog_site
|
|
7
|
+
column: id
|
|
8
|
+
onDelete: CASCADE
|
|
9
|
+
- name: category_id
|
|
10
|
+
type: fk
|
|
11
|
+
isNullable: true
|
|
12
|
+
references:
|
|
13
|
+
table: category
|
|
14
|
+
column: id
|
|
15
|
+
onDelete: SET NULL
|
|
16
|
+
- name: page_type
|
|
17
|
+
type: enum
|
|
18
|
+
values: [comparison, best_of, cost_benefit, attribute, price_range, brand, use_case]
|
|
19
|
+
default: comparison
|
|
20
|
+
- name: rule_slug
|
|
21
|
+
type: varchar
|
|
22
|
+
length: 255
|
|
23
|
+
- name: status
|
|
24
|
+
type: enum
|
|
25
|
+
values: [active, inactive]
|
|
26
|
+
default: active
|
|
27
|
+
- name: generation_query_json
|
|
28
|
+
type: json
|
|
29
|
+
isNullable: true
|
|
30
|
+
- name: min_product_count
|
|
31
|
+
type: int
|
|
32
|
+
default: 2
|
|
33
|
+
- name: min_attribute_coverage
|
|
34
|
+
type: int
|
|
35
|
+
default: 1
|
|
36
|
+
- name: canonical_strategy
|
|
37
|
+
type: enum
|
|
38
|
+
values: [self, parent, custom]
|
|
39
|
+
default: self
|
|
40
|
+
- name: priority
|
|
41
|
+
type: int
|
|
42
|
+
default: 0
|
|
43
|
+
- name: template_json
|
|
44
|
+
type: json
|
|
45
|
+
isNullable: true
|
|
46
|
+
- type: created_at
|
|
47
|
+
- type: updated_at
|
|
48
|
+
indices:
|
|
49
|
+
- columns: [site_id, rule_slug]
|
|
50
|
+
isUnique: true
|
|
51
|
+
- columns: [site_id, page_type, status]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: category_id
|
|
4
|
+
type: fk
|
|
5
|
+
references:
|
|
6
|
+
table: category
|
|
7
|
+
column: id
|
|
8
|
+
onDelete: CASCADE
|
|
9
|
+
- name: rule_type
|
|
10
|
+
type: enum
|
|
11
|
+
values: [same_category, compatible_category, shared_attribute, manual]
|
|
12
|
+
default: same_category
|
|
13
|
+
- name: rule_json
|
|
14
|
+
type: json
|
|
15
|
+
isNullable: true
|
|
16
|
+
- name: min_similarity_score
|
|
17
|
+
type: decimal
|
|
18
|
+
precision: 5
|
|
19
|
+
scale: 2
|
|
20
|
+
default: 0
|
|
21
|
+
- name: status
|
|
22
|
+
type: enum
|
|
23
|
+
values: [active, inactive]
|
|
24
|
+
default: active
|
|
25
|
+
- type: created_at
|
|
26
|
+
- type: updated_at
|
|
27
|
+
indices:
|
|
28
|
+
- columns: [category_id, status]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: slug
|
|
4
|
+
type: varchar
|
|
5
|
+
length: 255
|
|
6
|
+
- name: name
|
|
7
|
+
type: varchar
|
|
8
|
+
length: 255
|
|
9
|
+
- name: domain
|
|
10
|
+
type: varchar
|
|
11
|
+
length: 255
|
|
12
|
+
- name: status
|
|
13
|
+
type: enum
|
|
14
|
+
values: [active, inactive]
|
|
15
|
+
default: active
|
|
16
|
+
- name: site_type
|
|
17
|
+
type: enum
|
|
18
|
+
values: [portal, niche, tenant]
|
|
19
|
+
default: portal
|
|
20
|
+
- name: default_locale_id
|
|
21
|
+
type: fk
|
|
22
|
+
references:
|
|
23
|
+
table: locale
|
|
24
|
+
column: id
|
|
25
|
+
onDelete: RESTRICT
|
|
26
|
+
- name: theme_settings_json
|
|
27
|
+
type: json
|
|
28
|
+
isNullable: true
|
|
29
|
+
- name: seo_defaults_json
|
|
30
|
+
type: json
|
|
31
|
+
isNullable: true
|
|
32
|
+
- type: created_at
|
|
33
|
+
- type: updated_at
|
|
34
|
+
indices:
|
|
35
|
+
- columns: [slug]
|
|
36
|
+
isUnique: true
|
|
37
|
+
- columns: [domain]
|
|
38
|
+
isUnique: true
|
|
39
|
+
- columns: [status]
|
|
40
|
+
- columns: [default_locale_id]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
columns:
|
|
2
|
+
- type: pk
|
|
3
|
+
- name: site_id
|
|
4
|
+
type: fk
|
|
5
|
+
references:
|
|
6
|
+
table: catalog_site
|
|
7
|
+
column: id
|
|
8
|
+
onDelete: CASCADE
|
|
9
|
+
- name: category_id
|
|
10
|
+
type: fk
|
|
11
|
+
references:
|
|
12
|
+
table: category
|
|
13
|
+
column: id
|
|
14
|
+
onDelete: CASCADE
|
|
15
|
+
- name: is_primary
|
|
16
|
+
type: boolean
|
|
17
|
+
default: false
|
|
18
|
+
- name: visibility_status
|
|
19
|
+
type: enum
|
|
20
|
+
values: [visible, hidden]
|
|
21
|
+
default: visible
|
|
22
|
+
- type: created_at
|
|
23
|
+
- type: updated_at
|
|
24
|
+
indices:
|
|
25
|
+
- columns: [site_id, category_id]
|
|
26
|
+
isUnique: true
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hed-hog/catalog",
|
|
3
|
+
"version": "0.0.276",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@nestjs/common": "*",
|
|
8
|
+
"@nestjs/config": "^4.0.2",
|
|
9
|
+
"@nestjs/core": "^11",
|
|
10
|
+
"@nestjs/jwt": "^11",
|
|
11
|
+
"@nestjs/mapped-types": "*",
|
|
12
|
+
"@hed-hog/api-locale": "0.0.13",
|
|
13
|
+
"@hed-hog/api": "0.0.4",
|
|
14
|
+
"@hed-hog/core": "0.0.276",
|
|
15
|
+
"@hed-hog/api-pagination": "0.0.6",
|
|
16
|
+
"@hed-hog/api-prisma": "0.0.5",
|
|
17
|
+
"@hed-hog/category": "0.0.276",
|
|
18
|
+
"@hed-hog/content": "0.0.276",
|
|
19
|
+
"@hed-hog/tag": "0.0.276"
|
|
20
|
+
},
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"import": "./dist/index.js",
|
|
24
|
+
"require": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"src",
|
|
31
|
+
"hedhog"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
|
|
35
|
+
"prebuild": "npx ts-node ../../scripts/build-dependencies.ts libraries/catalog",
|
|
36
|
+
"build": "tsc --project tsconfig.production.json",
|
|
37
|
+
"patch": "npx ts-node ../../scripts/patch.ts libraries/catalog",
|
|
38
|
+
"prod": "pnpm run patch && pnpm run build && pnpm publish --access public --no-git-checks"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
export type CatalogResourceConfig = {
|
|
2
|
+
resource: string;
|
|
3
|
+
model: string;
|
|
4
|
+
searchFields: string[];
|
|
5
|
+
filterFields?: string[];
|
|
6
|
+
fields: string[];
|
|
7
|
+
defaultOrderBy?: Record<string, 'asc' | 'desc'>;
|
|
8
|
+
statusField?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const catalogResources: CatalogResourceConfig[] = [
|
|
12
|
+
{
|
|
13
|
+
resource: 'brands',
|
|
14
|
+
model: 'catalog_brand',
|
|
15
|
+
searchFields: ['slug', 'name', 'normalized_name'],
|
|
16
|
+
filterFields: ['status', 'logo_file_id'],
|
|
17
|
+
fields: ['slug', 'name', 'normalized_name', 'logo_file_id', 'status', 'website_url'],
|
|
18
|
+
statusField: 'status',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
resource: 'sites',
|
|
22
|
+
model: 'catalog_site',
|
|
23
|
+
searchFields: ['slug', 'name', 'domain'],
|
|
24
|
+
filterFields: ['status', 'site_type', 'default_locale_id'],
|
|
25
|
+
fields: ['slug', 'name', 'domain', 'status', 'site_type', 'default_locale_id', 'theme_settings_json', 'seo_defaults_json'],
|
|
26
|
+
statusField: 'status',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
resource: 'products',
|
|
30
|
+
model: 'catalog_product',
|
|
31
|
+
searchFields: ['slug', 'name', 'model_name', 'sku', 'gtin'],
|
|
32
|
+
filterFields: ['status', 'comparison_status', 'brand_id', 'category_id', 'primary_content_id', 'is_active'],
|
|
33
|
+
fields: ['brand_id', 'category_id', 'primary_content_id', 'slug', 'name', 'short_description', 'description', 'model_name', 'sku', 'gtin', 'status', 'comparison_status', 'release_date', 'spec_snapshot_json', 'comparison_snapshot_json', 'is_active'],
|
|
34
|
+
statusField: 'status',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
resource: 'product-categories',
|
|
38
|
+
model: 'catalog_product_category',
|
|
39
|
+
searchFields: [],
|
|
40
|
+
filterFields: ['product_id', 'category_id', 'is_primary'],
|
|
41
|
+
fields: ['product_id', 'category_id', 'is_primary', 'sort_order'],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
resource: 'product-images',
|
|
45
|
+
model: 'catalog_product_image',
|
|
46
|
+
searchFields: ['alt_text', 'role'],
|
|
47
|
+
filterFields: ['product_id', 'file_id', 'role', 'is_primary'],
|
|
48
|
+
fields: ['product_id', 'file_id', 'role', 'sort_order', 'is_primary', 'alt_text'],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
resource: 'product-sites',
|
|
52
|
+
model: 'catalog_product_site',
|
|
53
|
+
searchFields: ['canonical_slug', 'override_brand_name', 'seo_title'],
|
|
54
|
+
filterFields: ['product_id', 'site_id', 'publication_status', 'is_featured'],
|
|
55
|
+
fields: ['product_id', 'site_id', 'publication_status', 'canonical_slug', 'is_featured', 'visibility_score', 'override_brand_name', 'seo_title', 'seo_description'],
|
|
56
|
+
statusField: 'publication_status',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
resource: 'attribute-groups',
|
|
60
|
+
model: 'catalog_attribute_group',
|
|
61
|
+
searchFields: ['slug', 'name'],
|
|
62
|
+
filterFields: ['status'],
|
|
63
|
+
fields: ['slug', 'name', 'status'],
|
|
64
|
+
statusField: 'status',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
resource: 'attributes',
|
|
68
|
+
model: 'catalog_attribute',
|
|
69
|
+
searchFields: ['slug', 'label', 'description', 'unit'],
|
|
70
|
+
filterFields: ['group_id', 'data_type', 'comparison_mode', 'is_filterable', 'is_sortable', 'is_required_for_comparison'],
|
|
71
|
+
fields: ['group_id', 'slug', 'label', 'description', 'data_type', 'unit', 'comparison_mode', 'is_filterable', 'is_sortable', 'is_required_for_comparison', 'normalization_rule_json', 'display_order'],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
resource: 'category-attributes',
|
|
75
|
+
model: 'catalog_category_attribute',
|
|
76
|
+
searchFields: [],
|
|
77
|
+
filterFields: ['category_id', 'attribute_id', 'is_required', 'is_highlighted', 'facet_mode'],
|
|
78
|
+
fields: ['category_id', 'attribute_id', 'is_required', 'is_highlighted', 'display_order', 'weight', 'facet_mode'],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
resource: 'product-attributes',
|
|
82
|
+
model: 'catalog_product_attribute_value',
|
|
83
|
+
searchFields: ['value_text', 'normalized_text', 'source_type'],
|
|
84
|
+
filterFields: ['product_id', 'attribute_id', 'is_verified'],
|
|
85
|
+
fields: ['product_id', 'attribute_id', 'value_text', 'value_number', 'value_boolean', 'value_json', 'value_unit', 'normalized_text', 'normalized_number', 'source_type', 'confidence_score', 'is_verified'],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
resource: 'score-criteria',
|
|
89
|
+
model: 'catalog_score_criterion',
|
|
90
|
+
searchFields: ['slug', 'name'],
|
|
91
|
+
filterFields: ['category_id', 'status', 'score_type'],
|
|
92
|
+
fields: ['category_id', 'slug', 'name', 'weight', 'score_type', 'formula_json', 'display_order', 'status'],
|
|
93
|
+
statusField: 'status',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
resource: 'product-scores',
|
|
97
|
+
model: 'catalog_product_score',
|
|
98
|
+
searchFields: ['score_label', 'summary', 'calculation_source'],
|
|
99
|
+
filterFields: ['product_id', 'criterion_id', 'is_manual_override'],
|
|
100
|
+
fields: ['product_id', 'criterion_id', 'score_value', 'score_label', 'summary', 'calculation_source', 'is_manual_override'],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
resource: 'comparisons',
|
|
104
|
+
model: 'catalog_comparison',
|
|
105
|
+
searchFields: ['slug', 'title', 'summary', 'verdict', 'eligibility_hash'],
|
|
106
|
+
filterFields: ['category_id', 'site_id', 'primary_content_id', 'comparison_type', 'generation_mode', 'status'],
|
|
107
|
+
fields: ['category_id', 'site_id', 'primary_content_id', 'slug', 'comparison_type', 'generation_mode', 'status', 'title', 'summary', 'intro', 'verdict', 'spec_snapshot_json', 'eligibility_hash', 'published_at'],
|
|
108
|
+
statusField: 'status',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
resource: 'comparison-items',
|
|
112
|
+
model: 'catalog_comparison_item',
|
|
113
|
+
searchFields: ['badge_label'],
|
|
114
|
+
filterFields: ['comparison_id', 'product_id', 'is_winner'],
|
|
115
|
+
fields: ['comparison_id', 'product_id', 'sort_order', 'is_winner', 'badge_label'],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
resource: 'comparison-highlights',
|
|
119
|
+
model: 'catalog_comparison_highlight',
|
|
120
|
+
searchFields: ['highlight_type', 'title', 'body'],
|
|
121
|
+
filterFields: ['comparison_id', 'product_id', 'attribute_id', 'highlight_type'],
|
|
122
|
+
fields: ['comparison_id', 'product_id', 'attribute_id', 'highlight_type', 'title', 'body', 'sort_order'],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
resource: 'similarity-rules',
|
|
126
|
+
model: 'catalog_similarity_rule',
|
|
127
|
+
searchFields: ['rule_type'],
|
|
128
|
+
filterFields: ['category_id', 'status'],
|
|
129
|
+
fields: ['category_id', 'rule_type', 'rule_json', 'min_similarity_score', 'status'],
|
|
130
|
+
statusField: 'status',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
resource: 'merchants',
|
|
134
|
+
model: 'catalog_merchant',
|
|
135
|
+
searchFields: ['slug', 'name'],
|
|
136
|
+
filterFields: ['status', 'merchant_type', 'logo_file_id'],
|
|
137
|
+
fields: ['slug', 'name', 'status', 'merchant_type', 'logo_file_id'],
|
|
138
|
+
statusField: 'status',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
resource: 'affiliate-programs',
|
|
142
|
+
model: 'catalog_affiliate_program',
|
|
143
|
+
searchFields: ['slug', 'name', 'network_type', 'commission_type'],
|
|
144
|
+
filterFields: ['merchant_id', 'status', 'network_type'],
|
|
145
|
+
fields: ['merchant_id', 'slug', 'name', 'network_type', 'tracking_template', 'commission_type', 'default_commission_value', 'status'],
|
|
146
|
+
statusField: 'status',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
resource: 'offers',
|
|
150
|
+
model: 'catalog_offer',
|
|
151
|
+
searchFields: ['external_offer_id', 'title', 'availability_status'],
|
|
152
|
+
filterFields: ['product_id', 'merchant_id', 'affiliate_program_id', 'site_id', 'availability_status', 'is_featured'],
|
|
153
|
+
fields: ['product_id', 'merchant_id', 'affiliate_program_id', 'site_id', 'external_offer_id', 'title', 'price_amount', 'price_currency', 'original_price_amount', 'installment_json', 'availability_status', 'affiliate_url', 'deep_link_url', 'priority_score', 'is_featured', 'valid_from', 'valid_until', 'last_seen_at'],
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
resource: 'price-history',
|
|
157
|
+
model: 'catalog_price_history',
|
|
158
|
+
searchFields: ['availability_status'],
|
|
159
|
+
filterFields: ['offer_id', 'product_id', 'availability_status'],
|
|
160
|
+
fields: ['offer_id', 'product_id', 'captured_at', 'price_amount', 'original_price_amount', 'availability_status'],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
resource: 'click-events',
|
|
164
|
+
model: 'catalog_click_event',
|
|
165
|
+
searchFields: ['placement', 'session_hash', 'referrer_host'],
|
|
166
|
+
filterFields: ['offer_id', 'product_id', 'site_id', 'comparison_id'],
|
|
167
|
+
fields: ['offer_id', 'product_id', 'site_id', 'comparison_id', 'clicked_at', 'placement', 'utm_json', 'session_hash', 'referrer_host'],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
resource: 'site-categories',
|
|
171
|
+
model: 'catalog_site_category',
|
|
172
|
+
searchFields: ['visibility_status'],
|
|
173
|
+
filterFields: ['site_id', 'category_id', 'is_primary', 'visibility_status'],
|
|
174
|
+
fields: ['site_id', 'category_id', 'is_primary', 'visibility_status'],
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
resource: 'content-relations',
|
|
178
|
+
model: 'catalog_content_relation',
|
|
179
|
+
searchFields: ['relation_type'],
|
|
180
|
+
filterFields: ['site_id', 'content_id', 'product_id', 'comparison_id', 'relation_type'],
|
|
181
|
+
fields: ['site_id', 'content_id', 'product_id', 'comparison_id', 'relation_type', 'sort_order'],
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
resource: 'seo-rules',
|
|
185
|
+
model: 'catalog_seo_page_rule',
|
|
186
|
+
searchFields: ['page_type', 'rule_slug', 'canonical_strategy'],
|
|
187
|
+
filterFields: ['site_id', 'category_id', 'status', 'page_type'],
|
|
188
|
+
fields: ['site_id', 'category_id', 'page_type', 'rule_slug', 'status', 'generation_query_json', 'min_product_count', 'min_attribute_coverage', 'canonical_strategy', 'priority', 'template_json'],
|
|
189
|
+
statusField: 'status',
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
resource: 'import-sources',
|
|
193
|
+
model: 'catalog_import_source',
|
|
194
|
+
searchFields: ['slug', 'name', 'source_type'],
|
|
195
|
+
filterFields: ['source_type', 'status'],
|
|
196
|
+
fields: ['slug', 'name', 'source_type', 'config_json', 'status'],
|
|
197
|
+
statusField: 'status',
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
resource: 'import-runs',
|
|
201
|
+
model: 'catalog_import_run',
|
|
202
|
+
searchFields: ['status', 'idempotency_key'],
|
|
203
|
+
filterFields: ['source_id', 'status'],
|
|
204
|
+
fields: ['source_id', 'started_at', 'finished_at', 'status', 'stats_json', 'error_log', 'idempotency_key'],
|
|
205
|
+
statusField: 'status',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
resource: 'product-tags',
|
|
209
|
+
model: 'catalog_product_tag',
|
|
210
|
+
searchFields: [],
|
|
211
|
+
filterFields: ['product_id', 'tag_id'],
|
|
212
|
+
fields: ['product_id', 'tag_id'],
|
|
213
|
+
}
|
|
214
|
+
];
|
|
215
|
+
|
|
216
|
+
export const catalogResourceMap = new Map(
|
|
217
|
+
catalogResources.map((resource) => [resource.resource, resource]),
|
|
218
|
+
);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Role } from '@hed-hog/api';
|
|
2
|
+
import { Locale } from '@hed-hog/api-locale';
|
|
3
|
+
import { Pagination } from '@hed-hog/api-pagination';
|
|
4
|
+
import {
|
|
5
|
+
Body,
|
|
6
|
+
Controller,
|
|
7
|
+
Delete,
|
|
8
|
+
Get,
|
|
9
|
+
Param,
|
|
10
|
+
ParseIntPipe,
|
|
11
|
+
Patch,
|
|
12
|
+
Post,
|
|
13
|
+
Query,
|
|
14
|
+
} from '@nestjs/common';
|
|
15
|
+
import { CatalogService } from './catalog.service';
|
|
16
|
+
|
|
17
|
+
@Role()
|
|
18
|
+
@Controller('catalog')
|
|
19
|
+
export class CatalogController {
|
|
20
|
+
constructor(private readonly catalogService: CatalogService) {}
|
|
21
|
+
|
|
22
|
+
@Get('products/:id/images')
|
|
23
|
+
async listProductImages(
|
|
24
|
+
@Param('id', ParseIntPipe) id: number,
|
|
25
|
+
@Pagination() paginationParams,
|
|
26
|
+
@Locale() locale: string,
|
|
27
|
+
) {
|
|
28
|
+
return this.catalogService.listProductImages(id, locale, paginationParams);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@Get(':resource/stats')
|
|
32
|
+
async stats(@Param('resource') resource: string, @Locale() locale: string) {
|
|
33
|
+
return this.catalogService.stats(resource, locale);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Get(':resource/:id')
|
|
37
|
+
async getById(
|
|
38
|
+
@Param('resource') resource: string,
|
|
39
|
+
@Param('id', ParseIntPipe) id: number,
|
|
40
|
+
@Locale() locale: string,
|
|
41
|
+
) {
|
|
42
|
+
return this.catalogService.getById(resource, id, locale);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Patch(':resource/:id')
|
|
46
|
+
async update(
|
|
47
|
+
@Param('resource') resource: string,
|
|
48
|
+
@Param('id', ParseIntPipe) id: number,
|
|
49
|
+
@Body() body: Record<string, unknown>,
|
|
50
|
+
@Locale() locale: string,
|
|
51
|
+
) {
|
|
52
|
+
return this.catalogService.update(resource, id, body, locale);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@Delete(':resource/:id')
|
|
56
|
+
async delete(
|
|
57
|
+
@Param('resource') resource: string,
|
|
58
|
+
@Param('id', ParseIntPipe) id: number,
|
|
59
|
+
@Locale() locale: string,
|
|
60
|
+
) {
|
|
61
|
+
return this.catalogService.delete(resource, id, locale);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@Get(':resource')
|
|
65
|
+
async list(
|
|
66
|
+
@Param('resource') resource: string,
|
|
67
|
+
@Pagination() paginationParams,
|
|
68
|
+
@Query() query: Record<string, unknown>,
|
|
69
|
+
@Locale() locale: string,
|
|
70
|
+
) {
|
|
71
|
+
return this.catalogService.list(resource, locale, paginationParams, query);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@Post(':resource')
|
|
75
|
+
async create(
|
|
76
|
+
@Param('resource') resource: string,
|
|
77
|
+
@Body() body: Record<string, unknown>,
|
|
78
|
+
@Locale() locale: string,
|
|
79
|
+
) {
|
|
80
|
+
return this.catalogService.create(resource, body, locale);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PaginationModule } from '@hed-hog/api-pagination';
|
|
2
|
+
import { Module, forwardRef } from '@nestjs/common';
|
|
3
|
+
import { CatalogController } from './catalog.controller';
|
|
4
|
+
import { CatalogService } from './catalog.service';
|
|
5
|
+
|
|
6
|
+
@Module({
|
|
7
|
+
imports: [forwardRef(() => PaginationModule)],
|
|
8
|
+
controllers: [CatalogController],
|
|
9
|
+
providers: [CatalogService],
|
|
10
|
+
exports: [CatalogService],
|
|
11
|
+
})
|
|
12
|
+
export class CatalogModule {}
|