@mamindom/contracts 1.0.136 → 1.0.138

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.
@@ -18,7 +18,7 @@ export interface BannerListItemResponse {
18
18
  name: {
19
19
  [key: string]: string;
20
20
  };
21
- placement: BannerPlacement;
21
+ placements: BannerPlacement[];
22
22
  status: boolean;
23
23
  sortOrder: number;
24
24
  categoryId?: string | undefined;
@@ -36,7 +36,7 @@ export interface BannerDetailResponse {
36
36
  name: {
37
37
  [key: string]: string;
38
38
  };
39
- placement: BannerPlacement;
39
+ placements: BannerPlacement[];
40
40
  status: boolean;
41
41
  sortOrder: number;
42
42
  categoryId?: string | undefined;
@@ -97,7 +97,7 @@ export interface CreateBannerRequest {
97
97
  name: {
98
98
  [key: string]: string;
99
99
  };
100
- placement: BannerPlacement;
100
+ placements: BannerPlacement[];
101
101
  status: boolean;
102
102
  sortOrder: number;
103
103
  categoryId?: string | undefined;
@@ -118,7 +118,8 @@ export interface UpdateBannerRequest {
118
118
  name: {
119
119
  [key: string]: string;
120
120
  };
121
- placement?: BannerPlacement | undefined;
121
+ /** empty = не оновлювати; non-empty = заміна повного списку плейсментів. */
122
+ placements: BannerPlacement[];
122
123
  status?: boolean | undefined;
123
124
  sortOrder?: number | undefined;
124
125
  categoryId?: string | undefined;
@@ -0,0 +1,161 @@
1
+ import { Observable } from "rxjs";
2
+ import { DeleteResponse, SuccessResponse } from "./common";
3
+ export declare const protobufPackage = "catalog.v1";
4
+ export declare enum SynonymType {
5
+ SYNONYM_MULTI_WAY = 0,
6
+ SYNONYM_ONE_WAY = 1,
7
+ UNRECOGNIZED = -1
8
+ }
9
+ export interface SuggestRequest {
10
+ q: string;
11
+ /** 1..20, default 8 */
12
+ limit: number;
13
+ /** default true */
14
+ onlyInStock: boolean;
15
+ /** 'uk' | 'ru', default 'uk' */
16
+ locale: string;
17
+ }
18
+ export interface SuggestProduct {
19
+ id: string;
20
+ sku: string;
21
+ slug: string;
22
+ /** already локалізована (uk/ru) */
23
+ name: string;
24
+ mainImage: string;
25
+ price: number;
26
+ oldPrice?: number | undefined;
27
+ rating: number;
28
+ reviewCount: number;
29
+ inStock: boolean;
30
+ }
31
+ export interface SuggestCategory {
32
+ id: string;
33
+ slug: string;
34
+ name: string;
35
+ productCount: number;
36
+ }
37
+ export interface SuggestResponse {
38
+ query: string;
39
+ products: SuggestProduct[];
40
+ categories: SuggestCategory[];
41
+ popularQueries: string[];
42
+ /** загальна кількість збігів у продуктах */
43
+ total: number;
44
+ }
45
+ export interface SynonymResponse {
46
+ id: string;
47
+ type: SynonymType;
48
+ queryTerms: string[];
49
+ synonyms: string[];
50
+ locale?: string | undefined;
51
+ isActive: boolean;
52
+ createdAt: string;
53
+ updatedAt: string;
54
+ }
55
+ export interface ListSynonymsRequest {
56
+ search?: string | undefined;
57
+ isActive?: boolean | undefined;
58
+ }
59
+ export interface ListSynonymsResponse {
60
+ items: SynonymResponse[];
61
+ }
62
+ export interface CreateSynonymRequest {
63
+ type: SynonymType;
64
+ queryTerms: string[];
65
+ synonyms: string[];
66
+ locale?: string | undefined;
67
+ isActive: boolean;
68
+ }
69
+ export interface UpdateSynonymRequest {
70
+ id: string;
71
+ type?: SynonymType | undefined;
72
+ queryTerms: string[];
73
+ synonyms: string[];
74
+ locale?: string | undefined;
75
+ isActive?: boolean | undefined;
76
+ clearQueryTerms: boolean;
77
+ clearSynonyms: boolean;
78
+ }
79
+ export interface DeleteSynonymRequest {
80
+ id: string;
81
+ }
82
+ export interface SyncSynonymsRequest {
83
+ }
84
+ export interface PopularQueryResponse {
85
+ id: string;
86
+ query: string;
87
+ sortOrder: number;
88
+ isActive: boolean;
89
+ createdAt: string;
90
+ updatedAt: string;
91
+ }
92
+ export interface ListPopularQueriesRequest {
93
+ isActive?: boolean | undefined;
94
+ }
95
+ export interface ListPopularQueriesResponse {
96
+ items: PopularQueryResponse[];
97
+ }
98
+ export interface CreatePopularQueryRequest {
99
+ query: string;
100
+ sortOrder: number;
101
+ isActive: boolean;
102
+ }
103
+ export interface UpdatePopularQueryRequest {
104
+ id: string;
105
+ query?: string | undefined;
106
+ sortOrder?: number | undefined;
107
+ isActive?: boolean | undefined;
108
+ }
109
+ export interface DeletePopularQueryRequest {
110
+ id: string;
111
+ }
112
+ export interface ReorderPopularQueriesRequest {
113
+ items: ReorderPopularQueryItem[];
114
+ }
115
+ export interface ReorderPopularQueryItem {
116
+ id: string;
117
+ sortOrder: number;
118
+ }
119
+ export declare const CATALOG_V1_PACKAGE_NAME = "catalog.v1";
120
+ /**
121
+ * SearchService — окремий сервіс під autocomplete та керування пошуком
122
+ * (синоніми, популярні запити). Логіка та індекс живуть у catalog-service.
123
+ */
124
+ export interface SearchServiceClient {
125
+ /** ─── Public (autocomplete) ─────────────────────────────────────────────── */
126
+ suggest(request: SuggestRequest): Observable<SuggestResponse>;
127
+ /** ─── Admin: synonyms ───────────────────────────────────────────────────── */
128
+ listSynonyms(request: ListSynonymsRequest): Observable<ListSynonymsResponse>;
129
+ createSynonym(request: CreateSynonymRequest): Observable<SynonymResponse>;
130
+ updateSynonym(request: UpdateSynonymRequest): Observable<SynonymResponse>;
131
+ deleteSynonym(request: DeleteSynonymRequest): Observable<DeleteResponse>;
132
+ syncSynonymsToTypesense(request: SyncSynonymsRequest): Observable<SuccessResponse>;
133
+ /** ─── Admin: popular queries ────────────────────────────────────────────── */
134
+ listPopularQueries(request: ListPopularQueriesRequest): Observable<ListPopularQueriesResponse>;
135
+ createPopularQuery(request: CreatePopularQueryRequest): Observable<PopularQueryResponse>;
136
+ updatePopularQuery(request: UpdatePopularQueryRequest): Observable<PopularQueryResponse>;
137
+ deletePopularQuery(request: DeletePopularQueryRequest): Observable<DeleteResponse>;
138
+ reorderPopularQueries(request: ReorderPopularQueriesRequest): Observable<SuccessResponse>;
139
+ }
140
+ /**
141
+ * SearchService — окремий сервіс під autocomplete та керування пошуком
142
+ * (синоніми, популярні запити). Логіка та індекс живуть у catalog-service.
143
+ */
144
+ export interface SearchServiceController {
145
+ /** ─── Public (autocomplete) ─────────────────────────────────────────────── */
146
+ suggest(request: SuggestRequest): Promise<SuggestResponse> | Observable<SuggestResponse> | SuggestResponse;
147
+ /** ─── Admin: synonyms ───────────────────────────────────────────────────── */
148
+ listSynonyms(request: ListSynonymsRequest): Promise<ListSynonymsResponse> | Observable<ListSynonymsResponse> | ListSynonymsResponse;
149
+ createSynonym(request: CreateSynonymRequest): Promise<SynonymResponse> | Observable<SynonymResponse> | SynonymResponse;
150
+ updateSynonym(request: UpdateSynonymRequest): Promise<SynonymResponse> | Observable<SynonymResponse> | SynonymResponse;
151
+ deleteSynonym(request: DeleteSynonymRequest): Promise<DeleteResponse> | Observable<DeleteResponse> | DeleteResponse;
152
+ syncSynonymsToTypesense(request: SyncSynonymsRequest): Promise<SuccessResponse> | Observable<SuccessResponse> | SuccessResponse;
153
+ /** ─── Admin: popular queries ────────────────────────────────────────────── */
154
+ listPopularQueries(request: ListPopularQueriesRequest): Promise<ListPopularQueriesResponse> | Observable<ListPopularQueriesResponse> | ListPopularQueriesResponse;
155
+ createPopularQuery(request: CreatePopularQueryRequest): Promise<PopularQueryResponse> | Observable<PopularQueryResponse> | PopularQueryResponse;
156
+ updatePopularQuery(request: UpdatePopularQueryRequest): Promise<PopularQueryResponse> | Observable<PopularQueryResponse> | PopularQueryResponse;
157
+ deletePopularQuery(request: DeletePopularQueryRequest): Promise<DeleteResponse> | Observable<DeleteResponse> | DeleteResponse;
158
+ reorderPopularQueries(request: ReorderPopularQueriesRequest): Promise<SuccessResponse> | Observable<SuccessResponse> | SuccessResponse;
159
+ }
160
+ export declare function SearchServiceControllerMethods(): (constructor: Function) => void;
161
+ export declare const SEARCH_SERVICE_NAME = "SearchService";
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
+ // versions:
4
+ // protoc-gen-ts_proto v2.11.4
5
+ // protoc v3.21.12
6
+ // source: search.proto
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.SEARCH_SERVICE_NAME = exports.CATALOG_V1_PACKAGE_NAME = exports.SynonymType = exports.protobufPackage = void 0;
9
+ exports.SearchServiceControllerMethods = SearchServiceControllerMethods;
10
+ /* eslint-disable */
11
+ const microservices_1 = require("@nestjs/microservices");
12
+ exports.protobufPackage = "catalog.v1";
13
+ var SynonymType;
14
+ (function (SynonymType) {
15
+ SynonymType[SynonymType["SYNONYM_MULTI_WAY"] = 0] = "SYNONYM_MULTI_WAY";
16
+ SynonymType[SynonymType["SYNONYM_ONE_WAY"] = 1] = "SYNONYM_ONE_WAY";
17
+ SynonymType[SynonymType["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
18
+ })(SynonymType || (exports.SynonymType = SynonymType = {}));
19
+ exports.CATALOG_V1_PACKAGE_NAME = "catalog.v1";
20
+ function SearchServiceControllerMethods() {
21
+ return function (constructor) {
22
+ const grpcMethods = [
23
+ "suggest",
24
+ "listSynonyms",
25
+ "createSynonym",
26
+ "updateSynonym",
27
+ "deleteSynonym",
28
+ "syncSynonymsToTypesense",
29
+ "listPopularQueries",
30
+ "createPopularQuery",
31
+ "updatePopularQuery",
32
+ "deletePopularQuery",
33
+ "reorderPopularQueries",
34
+ ];
35
+ for (const method of grpcMethods) {
36
+ const descriptor = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
37
+ (0, microservices_1.GrpcMethod)("SearchService", method)(constructor.prototype[method], method, descriptor);
38
+ }
39
+ const grpcStreamMethods = [];
40
+ for (const method of grpcStreamMethods) {
41
+ const descriptor = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
42
+ (0, microservices_1.GrpcStreamMethod)("SearchService", method)(constructor.prototype[method], method, descriptor);
43
+ }
44
+ };
45
+ }
46
+ exports.SEARCH_SERVICE_NAME = "SearchService";
@@ -38,7 +38,7 @@ message BannerListItemResponse {
38
38
  string id = 1;
39
39
  string slug = 2;
40
40
  map<string, string> name = 3;
41
- BannerPlacement placement = 4;
41
+ repeated BannerPlacement placements = 4;
42
42
  bool status = 5;
43
43
  int32 sort_order = 6;
44
44
  optional string category_id = 7;
@@ -51,7 +51,7 @@ message BannerDetailResponse {
51
51
  string id = 1;
52
52
  string slug = 2;
53
53
  map<string, string> name = 3;
54
- BannerPlacement placement = 4;
54
+ repeated BannerPlacement placements = 4;
55
55
  bool status = 5;
56
56
  int32 sort_order = 6;
57
57
  optional string category_id = 7;
@@ -102,7 +102,7 @@ message GetBannerRequest {
102
102
  message CreateBannerRequest {
103
103
  optional string slug = 1;
104
104
  map<string, string> name = 2;
105
- BannerPlacement placement = 3;
105
+ repeated BannerPlacement placements = 3;
106
106
  bool status = 4;
107
107
  int32 sort_order = 5;
108
108
  optional string category_id = 6;
@@ -118,7 +118,8 @@ message UpdateBannerRequest {
118
118
  string id = 1;
119
119
  optional string slug = 2;
120
120
  map<string, string> name = 3;
121
- optional BannerPlacement placement = 4;
121
+ // empty = не оновлювати; non-empty = заміна повного списку плейсментів.
122
+ repeated BannerPlacement placements = 4;
122
123
  optional bool status = 5;
123
124
  optional int32 sort_order = 6;
124
125
  optional string category_id = 7;
@@ -0,0 +1,161 @@
1
+ syntax = "proto3";
2
+
3
+ package catalog.v1;
4
+
5
+ import "common.proto";
6
+
7
+ // SearchService — окремий сервіс під autocomplete та керування пошуком
8
+ // (синоніми, популярні запити). Логіка та індекс живуть у catalog-service.
9
+ service SearchService {
10
+ // ─── Public (autocomplete) ───────────────────────────────────────────────
11
+ rpc Suggest (SuggestRequest) returns (SuggestResponse);
12
+
13
+ // ─── Admin: synonyms ─────────────────────────────────────────────────────
14
+ rpc ListSynonyms (ListSynonymsRequest) returns (ListSynonymsResponse);
15
+ rpc CreateSynonym (CreateSynonymRequest) returns (SynonymResponse);
16
+ rpc UpdateSynonym (UpdateSynonymRequest) returns (SynonymResponse);
17
+ rpc DeleteSynonym (DeleteSynonymRequest) returns (DeleteResponse);
18
+ rpc SyncSynonymsToTypesense (SyncSynonymsRequest) returns (SuccessResponse);
19
+
20
+ // ─── Admin: popular queries ──────────────────────────────────────────────
21
+ rpc ListPopularQueries (ListPopularQueriesRequest) returns (ListPopularQueriesResponse);
22
+ rpc CreatePopularQuery (CreatePopularQueryRequest) returns (PopularQueryResponse);
23
+ rpc UpdatePopularQuery (UpdatePopularQueryRequest) returns (PopularQueryResponse);
24
+ rpc DeletePopularQuery (DeletePopularQueryRequest) returns (DeleteResponse);
25
+ rpc ReorderPopularQueries (ReorderPopularQueriesRequest) returns (SuccessResponse);
26
+ }
27
+
28
+ // ─────────────────────────── Suggest (public) ─────────────────────────────
29
+
30
+ message SuggestRequest {
31
+ string q = 1;
32
+ int32 limit = 2; // 1..20, default 8
33
+ bool only_in_stock = 3; // default true
34
+ string locale = 4; // 'uk' | 'ru', default 'uk'
35
+ }
36
+
37
+ message SuggestProduct {
38
+ string id = 1;
39
+ string sku = 2;
40
+ string slug = 3;
41
+ string name = 4; // already локалізована (uk/ru)
42
+ string main_image = 5;
43
+ double price = 6;
44
+ optional double old_price = 7;
45
+ float rating = 8;
46
+ int32 review_count = 9;
47
+ bool in_stock = 10;
48
+ }
49
+
50
+ message SuggestCategory {
51
+ string id = 1;
52
+ string slug = 2;
53
+ string name = 3;
54
+ int32 product_count = 4;
55
+ }
56
+
57
+ message SuggestResponse {
58
+ string query = 1;
59
+ repeated SuggestProduct products = 2;
60
+ repeated SuggestCategory categories = 3;
61
+ repeated string popular_queries = 4;
62
+ int32 total = 5; // загальна кількість збігів у продуктах
63
+ }
64
+
65
+ // ─────────────────────────── Synonyms (admin) ─────────────────────────────
66
+
67
+ enum SynonymType {
68
+ SYNONYM_MULTI_WAY = 0;
69
+ SYNONYM_ONE_WAY = 1;
70
+ }
71
+
72
+ message SynonymResponse {
73
+ string id = 1;
74
+ SynonymType type = 2;
75
+ repeated string query_terms = 3;
76
+ repeated string synonyms = 4;
77
+ optional string locale = 5;
78
+ bool is_active = 6;
79
+ string created_at = 7;
80
+ string updated_at = 8;
81
+ }
82
+
83
+ message ListSynonymsRequest {
84
+ optional string search = 1;
85
+ optional bool is_active = 2;
86
+ }
87
+
88
+ message ListSynonymsResponse {
89
+ repeated SynonymResponse items = 1;
90
+ }
91
+
92
+ message CreateSynonymRequest {
93
+ SynonymType type = 1;
94
+ repeated string query_terms = 2;
95
+ repeated string synonyms = 3;
96
+ optional string locale = 4;
97
+ bool is_active = 5;
98
+ }
99
+
100
+ message UpdateSynonymRequest {
101
+ string id = 1;
102
+ optional SynonymType type = 2;
103
+ repeated string query_terms = 3;
104
+ repeated string synonyms = 4;
105
+ optional string locale = 5;
106
+ optional bool is_active = 6;
107
+ bool clear_query_terms = 7;
108
+ bool clear_synonyms = 8;
109
+ }
110
+
111
+ message DeleteSynonymRequest {
112
+ string id = 1;
113
+ }
114
+
115
+ message SyncSynonymsRequest {
116
+ }
117
+
118
+ // ───────────────────────── Popular queries (admin) ────────────────────────
119
+
120
+ message PopularQueryResponse {
121
+ string id = 1;
122
+ string query = 2;
123
+ int32 sort_order = 3;
124
+ bool is_active = 4;
125
+ string created_at = 5;
126
+ string updated_at = 6;
127
+ }
128
+
129
+ message ListPopularQueriesRequest {
130
+ optional bool is_active = 1;
131
+ }
132
+
133
+ message ListPopularQueriesResponse {
134
+ repeated PopularQueryResponse items = 1;
135
+ }
136
+
137
+ message CreatePopularQueryRequest {
138
+ string query = 1;
139
+ int32 sort_order = 2;
140
+ bool is_active = 3;
141
+ }
142
+
143
+ message UpdatePopularQueryRequest {
144
+ string id = 1;
145
+ optional string query = 2;
146
+ optional int32 sort_order = 3;
147
+ optional bool is_active = 4;
148
+ }
149
+
150
+ message DeletePopularQueryRequest {
151
+ string id = 1;
152
+ }
153
+
154
+ message ReorderPopularQueriesRequest {
155
+ repeated ReorderPopularQueryItem items = 1;
156
+ }
157
+
158
+ message ReorderPopularQueryItem {
159
+ string id = 1;
160
+ int32 sort_order = 2;
161
+ }
@@ -15,6 +15,7 @@ export declare const PROTO_PATHS: {
15
15
  readonly STOCK: string;
16
16
  readonly BUNDLE: string;
17
17
  readonly FILTER: string;
18
+ readonly SEARCH: string;
18
19
  readonly PICKUP: string;
19
20
  readonly PRODUCT_REVIEW: string;
20
21
  readonly COMMON_PROMO: string;
@@ -19,6 +19,7 @@ exports.PROTO_PATHS = {
19
19
  STOCK: (0, node_path_1.join)(__dirname, '../../proto/stock.proto'),
20
20
  BUNDLE: (0, node_path_1.join)(__dirname, '../../proto/bundle.proto'),
21
21
  FILTER: (0, node_path_1.join)(__dirname, '../../proto/shop_filters.proto'),
22
+ SEARCH: (0, node_path_1.join)(__dirname, '../../proto/search.proto'),
22
23
  PICKUP: (0, node_path_1.join)(__dirname, '../../proto/pickup.proto'),
23
24
  PRODUCT_REVIEW: (0, node_path_1.join)(__dirname, '../../proto/product_review.proto'),
24
25
  COMMON_PROMO: (0, node_path_1.join)(__dirname, '../../proto/common_promo.proto'),
package/gen/banner.ts CHANGED
@@ -27,7 +27,7 @@ export interface BannerListItemResponse {
27
27
  id: string;
28
28
  slug: string;
29
29
  name: { [key: string]: string };
30
- placement: BannerPlacement;
30
+ placements: BannerPlacement[];
31
31
  status: boolean;
32
32
  sortOrder: number;
33
33
  categoryId?: string | undefined;
@@ -45,7 +45,7 @@ export interface BannerDetailResponse {
45
45
  id: string;
46
46
  slug: string;
47
47
  name: { [key: string]: string };
48
- placement: BannerPlacement;
48
+ placements: BannerPlacement[];
49
49
  status: boolean;
50
50
  sortOrder: number;
51
51
  categoryId?: string | undefined;
@@ -108,7 +108,7 @@ export interface GetBannerRequest {
108
108
  export interface CreateBannerRequest {
109
109
  slug?: string | undefined;
110
110
  name: { [key: string]: string };
111
- placement: BannerPlacement;
111
+ placements: BannerPlacement[];
112
112
  status: boolean;
113
113
  sortOrder: number;
114
114
  categoryId?: string | undefined;
@@ -129,7 +129,8 @@ export interface UpdateBannerRequest {
129
129
  id: string;
130
130
  slug?: string | undefined;
131
131
  name: { [key: string]: string };
132
- placement?: BannerPlacement | undefined;
132
+ /** empty = не оновлювати; non-empty = заміна повного списку плейсментів. */
133
+ placements: BannerPlacement[];
133
134
  status?: boolean | undefined;
134
135
  sortOrder?: number | undefined;
135
136
  categoryId?: string | undefined;
package/gen/search.ts ADDED
@@ -0,0 +1,266 @@
1
+ // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2
+ // versions:
3
+ // protoc-gen-ts_proto v2.11.4
4
+ // protoc v3.21.12
5
+ // source: search.proto
6
+
7
+ /* eslint-disable */
8
+ import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
9
+ import { Observable } from "rxjs";
10
+ import { DeleteResponse, SuccessResponse } from "./common";
11
+
12
+ export const protobufPackage = "catalog.v1";
13
+
14
+ export enum SynonymType {
15
+ SYNONYM_MULTI_WAY = 0,
16
+ SYNONYM_ONE_WAY = 1,
17
+ UNRECOGNIZED = -1,
18
+ }
19
+
20
+ export interface SuggestRequest {
21
+ q: string;
22
+ /** 1..20, default 8 */
23
+ limit: number;
24
+ /** default true */
25
+ onlyInStock: boolean;
26
+ /** 'uk' | 'ru', default 'uk' */
27
+ locale: string;
28
+ }
29
+
30
+ export interface SuggestProduct {
31
+ id: string;
32
+ sku: string;
33
+ slug: string;
34
+ /** already локалізована (uk/ru) */
35
+ name: string;
36
+ mainImage: string;
37
+ price: number;
38
+ oldPrice?: number | undefined;
39
+ rating: number;
40
+ reviewCount: number;
41
+ inStock: boolean;
42
+ }
43
+
44
+ export interface SuggestCategory {
45
+ id: string;
46
+ slug: string;
47
+ name: string;
48
+ productCount: number;
49
+ }
50
+
51
+ export interface SuggestResponse {
52
+ query: string;
53
+ products: SuggestProduct[];
54
+ categories: SuggestCategory[];
55
+ popularQueries: string[];
56
+ /** загальна кількість збігів у продуктах */
57
+ total: number;
58
+ }
59
+
60
+ export interface SynonymResponse {
61
+ id: string;
62
+ type: SynonymType;
63
+ queryTerms: string[];
64
+ synonyms: string[];
65
+ locale?: string | undefined;
66
+ isActive: boolean;
67
+ createdAt: string;
68
+ updatedAt: string;
69
+ }
70
+
71
+ export interface ListSynonymsRequest {
72
+ search?: string | undefined;
73
+ isActive?: boolean | undefined;
74
+ }
75
+
76
+ export interface ListSynonymsResponse {
77
+ items: SynonymResponse[];
78
+ }
79
+
80
+ export interface CreateSynonymRequest {
81
+ type: SynonymType;
82
+ queryTerms: string[];
83
+ synonyms: string[];
84
+ locale?: string | undefined;
85
+ isActive: boolean;
86
+ }
87
+
88
+ export interface UpdateSynonymRequest {
89
+ id: string;
90
+ type?: SynonymType | undefined;
91
+ queryTerms: string[];
92
+ synonyms: string[];
93
+ locale?: string | undefined;
94
+ isActive?: boolean | undefined;
95
+ clearQueryTerms: boolean;
96
+ clearSynonyms: boolean;
97
+ }
98
+
99
+ export interface DeleteSynonymRequest {
100
+ id: string;
101
+ }
102
+
103
+ export interface SyncSynonymsRequest {
104
+ }
105
+
106
+ export interface PopularQueryResponse {
107
+ id: string;
108
+ query: string;
109
+ sortOrder: number;
110
+ isActive: boolean;
111
+ createdAt: string;
112
+ updatedAt: string;
113
+ }
114
+
115
+ export interface ListPopularQueriesRequest {
116
+ isActive?: boolean | undefined;
117
+ }
118
+
119
+ export interface ListPopularQueriesResponse {
120
+ items: PopularQueryResponse[];
121
+ }
122
+
123
+ export interface CreatePopularQueryRequest {
124
+ query: string;
125
+ sortOrder: number;
126
+ isActive: boolean;
127
+ }
128
+
129
+ export interface UpdatePopularQueryRequest {
130
+ id: string;
131
+ query?: string | undefined;
132
+ sortOrder?: number | undefined;
133
+ isActive?: boolean | undefined;
134
+ }
135
+
136
+ export interface DeletePopularQueryRequest {
137
+ id: string;
138
+ }
139
+
140
+ export interface ReorderPopularQueriesRequest {
141
+ items: ReorderPopularQueryItem[];
142
+ }
143
+
144
+ export interface ReorderPopularQueryItem {
145
+ id: string;
146
+ sortOrder: number;
147
+ }
148
+
149
+ export const CATALOG_V1_PACKAGE_NAME = "catalog.v1";
150
+
151
+ /**
152
+ * SearchService — окремий сервіс під autocomplete та керування пошуком
153
+ * (синоніми, популярні запити). Логіка та індекс живуть у catalog-service.
154
+ */
155
+
156
+ export interface SearchServiceClient {
157
+ /** ─── Public (autocomplete) ─────────────────────────────────────────────── */
158
+
159
+ suggest(request: SuggestRequest): Observable<SuggestResponse>;
160
+
161
+ /** ─── Admin: synonyms ───────────────────────────────────────────────────── */
162
+
163
+ listSynonyms(request: ListSynonymsRequest): Observable<ListSynonymsResponse>;
164
+
165
+ createSynonym(request: CreateSynonymRequest): Observable<SynonymResponse>;
166
+
167
+ updateSynonym(request: UpdateSynonymRequest): Observable<SynonymResponse>;
168
+
169
+ deleteSynonym(request: DeleteSynonymRequest): Observable<DeleteResponse>;
170
+
171
+ syncSynonymsToTypesense(request: SyncSynonymsRequest): Observable<SuccessResponse>;
172
+
173
+ /** ─── Admin: popular queries ────────────────────────────────────────────── */
174
+
175
+ listPopularQueries(request: ListPopularQueriesRequest): Observable<ListPopularQueriesResponse>;
176
+
177
+ createPopularQuery(request: CreatePopularQueryRequest): Observable<PopularQueryResponse>;
178
+
179
+ updatePopularQuery(request: UpdatePopularQueryRequest): Observable<PopularQueryResponse>;
180
+
181
+ deletePopularQuery(request: DeletePopularQueryRequest): Observable<DeleteResponse>;
182
+
183
+ reorderPopularQueries(request: ReorderPopularQueriesRequest): Observable<SuccessResponse>;
184
+ }
185
+
186
+ /**
187
+ * SearchService — окремий сервіс під autocomplete та керування пошуком
188
+ * (синоніми, популярні запити). Логіка та індекс живуть у catalog-service.
189
+ */
190
+
191
+ export interface SearchServiceController {
192
+ /** ─── Public (autocomplete) ─────────────────────────────────────────────── */
193
+
194
+ suggest(request: SuggestRequest): Promise<SuggestResponse> | Observable<SuggestResponse> | SuggestResponse;
195
+
196
+ /** ─── Admin: synonyms ───────────────────────────────────────────────────── */
197
+
198
+ listSynonyms(
199
+ request: ListSynonymsRequest,
200
+ ): Promise<ListSynonymsResponse> | Observable<ListSynonymsResponse> | ListSynonymsResponse;
201
+
202
+ createSynonym(
203
+ request: CreateSynonymRequest,
204
+ ): Promise<SynonymResponse> | Observable<SynonymResponse> | SynonymResponse;
205
+
206
+ updateSynonym(
207
+ request: UpdateSynonymRequest,
208
+ ): Promise<SynonymResponse> | Observable<SynonymResponse> | SynonymResponse;
209
+
210
+ deleteSynonym(request: DeleteSynonymRequest): Promise<DeleteResponse> | Observable<DeleteResponse> | DeleteResponse;
211
+
212
+ syncSynonymsToTypesense(
213
+ request: SyncSynonymsRequest,
214
+ ): Promise<SuccessResponse> | Observable<SuccessResponse> | SuccessResponse;
215
+
216
+ /** ─── Admin: popular queries ────────────────────────────────────────────── */
217
+
218
+ listPopularQueries(
219
+ request: ListPopularQueriesRequest,
220
+ ): Promise<ListPopularQueriesResponse> | Observable<ListPopularQueriesResponse> | ListPopularQueriesResponse;
221
+
222
+ createPopularQuery(
223
+ request: CreatePopularQueryRequest,
224
+ ): Promise<PopularQueryResponse> | Observable<PopularQueryResponse> | PopularQueryResponse;
225
+
226
+ updatePopularQuery(
227
+ request: UpdatePopularQueryRequest,
228
+ ): Promise<PopularQueryResponse> | Observable<PopularQueryResponse> | PopularQueryResponse;
229
+
230
+ deletePopularQuery(
231
+ request: DeletePopularQueryRequest,
232
+ ): Promise<DeleteResponse> | Observable<DeleteResponse> | DeleteResponse;
233
+
234
+ reorderPopularQueries(
235
+ request: ReorderPopularQueriesRequest,
236
+ ): Promise<SuccessResponse> | Observable<SuccessResponse> | SuccessResponse;
237
+ }
238
+
239
+ export function SearchServiceControllerMethods() {
240
+ return function (constructor: Function) {
241
+ const grpcMethods: string[] = [
242
+ "suggest",
243
+ "listSynonyms",
244
+ "createSynonym",
245
+ "updateSynonym",
246
+ "deleteSynonym",
247
+ "syncSynonymsToTypesense",
248
+ "listPopularQueries",
249
+ "createPopularQuery",
250
+ "updatePopularQuery",
251
+ "deletePopularQuery",
252
+ "reorderPopularQueries",
253
+ ];
254
+ for (const method of grpcMethods) {
255
+ const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
256
+ GrpcMethod("SearchService", method)(constructor.prototype[method], method, descriptor);
257
+ }
258
+ const grpcStreamMethods: string[] = [];
259
+ for (const method of grpcStreamMethods) {
260
+ const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
261
+ GrpcStreamMethod("SearchService", method)(constructor.prototype[method], method, descriptor);
262
+ }
263
+ };
264
+ }
265
+
266
+ export const SEARCH_SERVICE_NAME = "SearchService";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mamindom/contracts",
3
3
  "description": "proto",
4
- "version": "1.0.136",
4
+ "version": "1.0.138",
5
5
  "main": "./dist/src/index.js",
6
6
  "types": "./dist/src/index.d.ts",
7
7
  "exports": {
@@ -38,7 +38,7 @@ message BannerListItemResponse {
38
38
  string id = 1;
39
39
  string slug = 2;
40
40
  map<string, string> name = 3;
41
- BannerPlacement placement = 4;
41
+ repeated BannerPlacement placements = 4;
42
42
  bool status = 5;
43
43
  int32 sort_order = 6;
44
44
  optional string category_id = 7;
@@ -51,7 +51,7 @@ message BannerDetailResponse {
51
51
  string id = 1;
52
52
  string slug = 2;
53
53
  map<string, string> name = 3;
54
- BannerPlacement placement = 4;
54
+ repeated BannerPlacement placements = 4;
55
55
  bool status = 5;
56
56
  int32 sort_order = 6;
57
57
  optional string category_id = 7;
@@ -102,7 +102,7 @@ message GetBannerRequest {
102
102
  message CreateBannerRequest {
103
103
  optional string slug = 1;
104
104
  map<string, string> name = 2;
105
- BannerPlacement placement = 3;
105
+ repeated BannerPlacement placements = 3;
106
106
  bool status = 4;
107
107
  int32 sort_order = 5;
108
108
  optional string category_id = 6;
@@ -118,7 +118,8 @@ message UpdateBannerRequest {
118
118
  string id = 1;
119
119
  optional string slug = 2;
120
120
  map<string, string> name = 3;
121
- optional BannerPlacement placement = 4;
121
+ // empty = не оновлювати; non-empty = заміна повного списку плейсментів.
122
+ repeated BannerPlacement placements = 4;
122
123
  optional bool status = 5;
123
124
  optional int32 sort_order = 6;
124
125
  optional string category_id = 7;
@@ -0,0 +1,161 @@
1
+ syntax = "proto3";
2
+
3
+ package catalog.v1;
4
+
5
+ import "common.proto";
6
+
7
+ // SearchService — окремий сервіс під autocomplete та керування пошуком
8
+ // (синоніми, популярні запити). Логіка та індекс живуть у catalog-service.
9
+ service SearchService {
10
+ // ─── Public (autocomplete) ───────────────────────────────────────────────
11
+ rpc Suggest (SuggestRequest) returns (SuggestResponse);
12
+
13
+ // ─── Admin: synonyms ─────────────────────────────────────────────────────
14
+ rpc ListSynonyms (ListSynonymsRequest) returns (ListSynonymsResponse);
15
+ rpc CreateSynonym (CreateSynonymRequest) returns (SynonymResponse);
16
+ rpc UpdateSynonym (UpdateSynonymRequest) returns (SynonymResponse);
17
+ rpc DeleteSynonym (DeleteSynonymRequest) returns (DeleteResponse);
18
+ rpc SyncSynonymsToTypesense (SyncSynonymsRequest) returns (SuccessResponse);
19
+
20
+ // ─── Admin: popular queries ──────────────────────────────────────────────
21
+ rpc ListPopularQueries (ListPopularQueriesRequest) returns (ListPopularQueriesResponse);
22
+ rpc CreatePopularQuery (CreatePopularQueryRequest) returns (PopularQueryResponse);
23
+ rpc UpdatePopularQuery (UpdatePopularQueryRequest) returns (PopularQueryResponse);
24
+ rpc DeletePopularQuery (DeletePopularQueryRequest) returns (DeleteResponse);
25
+ rpc ReorderPopularQueries (ReorderPopularQueriesRequest) returns (SuccessResponse);
26
+ }
27
+
28
+ // ─────────────────────────── Suggest (public) ─────────────────────────────
29
+
30
+ message SuggestRequest {
31
+ string q = 1;
32
+ int32 limit = 2; // 1..20, default 8
33
+ bool only_in_stock = 3; // default true
34
+ string locale = 4; // 'uk' | 'ru', default 'uk'
35
+ }
36
+
37
+ message SuggestProduct {
38
+ string id = 1;
39
+ string sku = 2;
40
+ string slug = 3;
41
+ string name = 4; // already локалізована (uk/ru)
42
+ string main_image = 5;
43
+ double price = 6;
44
+ optional double old_price = 7;
45
+ float rating = 8;
46
+ int32 review_count = 9;
47
+ bool in_stock = 10;
48
+ }
49
+
50
+ message SuggestCategory {
51
+ string id = 1;
52
+ string slug = 2;
53
+ string name = 3;
54
+ int32 product_count = 4;
55
+ }
56
+
57
+ message SuggestResponse {
58
+ string query = 1;
59
+ repeated SuggestProduct products = 2;
60
+ repeated SuggestCategory categories = 3;
61
+ repeated string popular_queries = 4;
62
+ int32 total = 5; // загальна кількість збігів у продуктах
63
+ }
64
+
65
+ // ─────────────────────────── Synonyms (admin) ─────────────────────────────
66
+
67
+ enum SynonymType {
68
+ SYNONYM_MULTI_WAY = 0;
69
+ SYNONYM_ONE_WAY = 1;
70
+ }
71
+
72
+ message SynonymResponse {
73
+ string id = 1;
74
+ SynonymType type = 2;
75
+ repeated string query_terms = 3;
76
+ repeated string synonyms = 4;
77
+ optional string locale = 5;
78
+ bool is_active = 6;
79
+ string created_at = 7;
80
+ string updated_at = 8;
81
+ }
82
+
83
+ message ListSynonymsRequest {
84
+ optional string search = 1;
85
+ optional bool is_active = 2;
86
+ }
87
+
88
+ message ListSynonymsResponse {
89
+ repeated SynonymResponse items = 1;
90
+ }
91
+
92
+ message CreateSynonymRequest {
93
+ SynonymType type = 1;
94
+ repeated string query_terms = 2;
95
+ repeated string synonyms = 3;
96
+ optional string locale = 4;
97
+ bool is_active = 5;
98
+ }
99
+
100
+ message UpdateSynonymRequest {
101
+ string id = 1;
102
+ optional SynonymType type = 2;
103
+ repeated string query_terms = 3;
104
+ repeated string synonyms = 4;
105
+ optional string locale = 5;
106
+ optional bool is_active = 6;
107
+ bool clear_query_terms = 7;
108
+ bool clear_synonyms = 8;
109
+ }
110
+
111
+ message DeleteSynonymRequest {
112
+ string id = 1;
113
+ }
114
+
115
+ message SyncSynonymsRequest {
116
+ }
117
+
118
+ // ───────────────────────── Popular queries (admin) ────────────────────────
119
+
120
+ message PopularQueryResponse {
121
+ string id = 1;
122
+ string query = 2;
123
+ int32 sort_order = 3;
124
+ bool is_active = 4;
125
+ string created_at = 5;
126
+ string updated_at = 6;
127
+ }
128
+
129
+ message ListPopularQueriesRequest {
130
+ optional bool is_active = 1;
131
+ }
132
+
133
+ message ListPopularQueriesResponse {
134
+ repeated PopularQueryResponse items = 1;
135
+ }
136
+
137
+ message CreatePopularQueryRequest {
138
+ string query = 1;
139
+ int32 sort_order = 2;
140
+ bool is_active = 3;
141
+ }
142
+
143
+ message UpdatePopularQueryRequest {
144
+ string id = 1;
145
+ optional string query = 2;
146
+ optional int32 sort_order = 3;
147
+ optional bool is_active = 4;
148
+ }
149
+
150
+ message DeletePopularQueryRequest {
151
+ string id = 1;
152
+ }
153
+
154
+ message ReorderPopularQueriesRequest {
155
+ repeated ReorderPopularQueryItem items = 1;
156
+ }
157
+
158
+ message ReorderPopularQueryItem {
159
+ string id = 1;
160
+ int32 sort_order = 2;
161
+ }