@deenruv/replicate-plugin 1.0.0

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.
Files changed (62) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +43 -0
  3. package/dist/plugin-server/constants.d.ts +2 -0
  4. package/dist/plugin-server/constants.js +5 -0
  5. package/dist/plugin-server/controllers/replicate.d.ts +22 -0
  6. package/dist/plugin-server/controllers/replicate.js +56 -0
  7. package/dist/plugin-server/e2e/order-export.e2e.test.d.ts +1 -0
  8. package/dist/plugin-server/e2e/order-export.e2e.test.js +163 -0
  9. package/dist/plugin-server/e2e/with-token.e2e.test.d.ts +1 -0
  10. package/dist/plugin-server/e2e/with-token.e2e.test.js +72 -0
  11. package/dist/plugin-server/e2e/without-token.e2e.test.d.ts +1 -0
  12. package/dist/plugin-server/e2e/without-token.e2e.test.js +75 -0
  13. package/dist/plugin-server/entites/replicate.entity.d.ts +13 -0
  14. package/dist/plugin-server/entites/replicate.entity.js +41 -0
  15. package/dist/plugin-server/extensions/replicate.extension.d.ts +1 -0
  16. package/dist/plugin-server/extensions/replicate.extension.js +78 -0
  17. package/dist/plugin-server/graphql/generated-admin-types.d.ts +5847 -0
  18. package/dist/plugin-server/graphql/generated-admin-types.js +1036 -0
  19. package/dist/plugin-server/index.d.ts +5 -0
  20. package/dist/plugin-server/index.js +42 -0
  21. package/dist/plugin-server/resolvers/replicate-admin.resolver.d.ts +35 -0
  22. package/dist/plugin-server/resolvers/replicate-admin.resolver.js +84 -0
  23. package/dist/plugin-server/services/replicate.service.d.ts +43 -0
  24. package/dist/plugin-server/services/replicate.service.js +389 -0
  25. package/dist/plugin-server/types.d.ts +19 -0
  26. package/dist/plugin-server/types.js +2 -0
  27. package/dist/plugin-server/zeus/const.d.ts +6 -0
  28. package/dist/plugin-server/zeus/const.js +3777 -0
  29. package/dist/plugin-server/zeus/index.d.ts +19250 -0
  30. package/dist/plugin-server/zeus/index.js +1104 -0
  31. package/dist/plugin-server/zeus/typedDocumentNode.d.ts +3 -0
  32. package/dist/plugin-server/zeus/typedDocumentNode.js +13 -0
  33. package/dist/plugin-ui/components/Replicate.d.ts +2 -0
  34. package/dist/plugin-ui/components/Replicate.js +307 -0
  35. package/dist/plugin-ui/components/ReplicateUtilities.d.ts +4 -0
  36. package/dist/plugin-ui/components/ReplicateUtilities.js +57 -0
  37. package/dist/plugin-ui/components/index.d.ts +1 -0
  38. package/dist/plugin-ui/components/index.js +1 -0
  39. package/dist/plugin-ui/graphql/mutations.d.ts +11 -0
  40. package/dist/plugin-ui/graphql/mutations.js +11 -0
  41. package/dist/plugin-ui/graphql/queries.d.ts +73 -0
  42. package/dist/plugin-ui/graphql/queries.js +30 -0
  43. package/dist/plugin-ui/graphql/selectors.d.ts +24 -0
  44. package/dist/plugin-ui/graphql/selectors.js +17 -0
  45. package/dist/plugin-ui/index.d.ts +1 -0
  46. package/dist/plugin-ui/index.js +25 -0
  47. package/dist/plugin-ui/locales/en/badges.json +25 -0
  48. package/dist/plugin-ui/locales/en/index.d.ts +26 -0
  49. package/dist/plugin-ui/locales/en/index.js +2 -0
  50. package/dist/plugin-ui/locales/pl/badges.json +25 -0
  51. package/dist/plugin-ui/locales/pl/index.d.ts +26 -0
  52. package/dist/plugin-ui/locales/pl/index.js +2 -0
  53. package/dist/plugin-ui/translation-ns.d.ts +1 -0
  54. package/dist/plugin-ui/translation-ns.js +1 -0
  55. package/dist/plugin-ui/tsconfig.json +18 -0
  56. package/dist/plugin-ui/zeus/const.d.ts +6 -0
  57. package/dist/plugin-ui/zeus/const.js +3774 -0
  58. package/dist/plugin-ui/zeus/index.d.ts +19250 -0
  59. package/dist/plugin-ui/zeus/index.js +1096 -0
  60. package/dist/plugin-ui/zeus/typedDocumentNode.d.ts +3 -0
  61. package/dist/plugin-ui/zeus/typedDocumentNode.js +9 -0
  62. package/package.json +54 -0
@@ -0,0 +1,5 @@
1
+ import { ReplicatePluginOptions } from "./types.js";
2
+ export declare class ReplicatePlugin {
3
+ private static options;
4
+ static init(options: ReplicatePluginOptions): typeof ReplicatePlugin;
5
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.ReplicatePlugin = void 0;
10
+ const core_1 = require("@deenruv/core");
11
+ const replicate_admin_resolver_js_1 = require("./resolvers/replicate-admin.resolver.js");
12
+ const replicate_service_js_1 = require("./services/replicate.service.js");
13
+ const replicate_js_1 = require("./controllers/replicate.js");
14
+ const constants_js_1 = require("./constants.js");
15
+ const replicate_extension_js_1 = require("./extensions/replicate.extension.js");
16
+ const replicate_entity_js_1 = require("./entites/replicate.entity.js");
17
+ let ReplicatePlugin = class ReplicatePlugin {
18
+ static init(options) {
19
+ this.options = options;
20
+ return this;
21
+ }
22
+ };
23
+ exports.ReplicatePlugin = ReplicatePlugin;
24
+ exports.ReplicatePlugin = ReplicatePlugin = __decorate([
25
+ (0, core_1.DeenruvPlugin)({
26
+ compatibility: "^0.0.20",
27
+ imports: [core_1.PluginCommonModule],
28
+ entities: [replicate_entity_js_1.ReplicateEntity],
29
+ providers: [
30
+ {
31
+ provide: constants_js_1.REPLICATE_PLUGIN_OPTIONS,
32
+ useFactory: () => ReplicatePlugin.options,
33
+ },
34
+ replicate_service_js_1.ReplicateService,
35
+ ],
36
+ controllers: [replicate_js_1.ReplicateController],
37
+ adminApiExtensions: {
38
+ schema: replicate_extension_js_1.AdminExtension,
39
+ resolvers: [replicate_admin_resolver_js_1.ReplicateAdminResolver],
40
+ },
41
+ })
42
+ ], ReplicatePlugin);
@@ -0,0 +1,35 @@
1
+ import { ReplicateService } from "../services/replicate.service.js";
2
+ import { RequestContext, Customer } from "@deenruv/core";
3
+ import { StartOrderExportToReplicateInput } from "../graphql/generated-admin-types.js";
4
+ export declare class ReplicateAdminResolver {
5
+ private replicateService;
6
+ constructor(replicateService: ReplicateService);
7
+ startModelTraining({ input, }: {
8
+ input: {
9
+ numLastOrder: number;
10
+ startDate: string;
11
+ endDate: string;
12
+ };
13
+ }, ctx: RequestContext): Promise<string>;
14
+ startOrderExportToReplicate({ input }: {
15
+ input: StartOrderExportToReplicateInput;
16
+ }, ctx: RequestContext): Promise<import("@deenruv/core").ID>;
17
+ getPredictionID(ctx: RequestContext, { input }: {
18
+ input: {
19
+ prediction_entity_id: string;
20
+ };
21
+ }): Promise<string | undefined>;
22
+ getReplicatePredictions(ctx: RequestContext, { options }: {
23
+ options: any;
24
+ }): Promise<import("@deenruv/core").PaginatedList<import("../entites/replicate.entity.js").ReplicateEntity>>;
25
+ getPredictionItem(ctx: RequestContext, { id }: {
26
+ id: string;
27
+ }): Promise<{
28
+ status: string;
29
+ predictions: {
30
+ id: import("@deenruv/core").ID;
31
+ score: number;
32
+ customer: Customer | null;
33
+ }[];
34
+ }>;
35
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ReplicateAdminResolver = void 0;
16
+ const graphql_1 = require("@nestjs/graphql");
17
+ const replicate_service_js_1 = require("../services/replicate.service.js");
18
+ const core_1 = require("@deenruv/core");
19
+ let ReplicateAdminResolver = class ReplicateAdminResolver {
20
+ constructor(replicateService) {
21
+ this.replicateService = replicateService;
22
+ }
23
+ async startModelTraining({ input, }, ctx) {
24
+ await this.replicateService.modelTrainingJob(ctx, input);
25
+ return "model training done";
26
+ }
27
+ async startOrderExportToReplicate({ input }, ctx) {
28
+ return this.replicateService.orderExportJob(ctx, input);
29
+ }
30
+ async getPredictionID(ctx, { input }) {
31
+ return this.replicateService.getPredictionID(ctx, input.prediction_entity_id);
32
+ }
33
+ async getReplicatePredictions(ctx, { options }) {
34
+ return this.replicateService.getPredictionItems(ctx, options);
35
+ }
36
+ async getPredictionItem(ctx, { id }) {
37
+ return this.replicateService.getPredictionItem(ctx, id);
38
+ }
39
+ };
40
+ exports.ReplicateAdminResolver = ReplicateAdminResolver;
41
+ __decorate([
42
+ (0, graphql_1.Mutation)(),
43
+ __param(0, (0, graphql_1.Args)()),
44
+ __param(1, (0, core_1.Ctx)()),
45
+ __metadata("design:type", Function),
46
+ __metadata("design:paramtypes", [Object, core_1.RequestContext]),
47
+ __metadata("design:returntype", Promise)
48
+ ], ReplicateAdminResolver.prototype, "startModelTraining", null);
49
+ __decorate([
50
+ (0, graphql_1.Mutation)(),
51
+ __param(0, (0, graphql_1.Args)()),
52
+ __param(1, (0, core_1.Ctx)()),
53
+ __metadata("design:type", Function),
54
+ __metadata("design:paramtypes", [Object, core_1.RequestContext]),
55
+ __metadata("design:returntype", Promise)
56
+ ], ReplicateAdminResolver.prototype, "startOrderExportToReplicate", null);
57
+ __decorate([
58
+ (0, graphql_1.Query)(),
59
+ __param(0, (0, core_1.Ctx)()),
60
+ __param(1, (0, graphql_1.Args)()),
61
+ __metadata("design:type", Function),
62
+ __metadata("design:paramtypes", [core_1.RequestContext, Object]),
63
+ __metadata("design:returntype", Promise)
64
+ ], ReplicateAdminResolver.prototype, "getPredictionID", null);
65
+ __decorate([
66
+ (0, graphql_1.Query)(),
67
+ __param(0, (0, core_1.Ctx)()),
68
+ __param(1, (0, graphql_1.Args)()),
69
+ __metadata("design:type", Function),
70
+ __metadata("design:paramtypes", [core_1.RequestContext, Object]),
71
+ __metadata("design:returntype", Promise)
72
+ ], ReplicateAdminResolver.prototype, "getReplicatePredictions", null);
73
+ __decorate([
74
+ (0, graphql_1.Query)(),
75
+ __param(0, (0, core_1.Ctx)()),
76
+ __param(1, (0, graphql_1.Args)()),
77
+ __metadata("design:type", Function),
78
+ __metadata("design:paramtypes", [core_1.RequestContext, Object]),
79
+ __metadata("design:returntype", Promise)
80
+ ], ReplicateAdminResolver.prototype, "getPredictionItem", null);
81
+ exports.ReplicateAdminResolver = ReplicateAdminResolver = __decorate([
82
+ (0, graphql_1.Resolver)(),
83
+ __metadata("design:paramtypes", [replicate_service_js_1.ReplicateService])
84
+ ], ReplicateAdminResolver);
@@ -0,0 +1,43 @@
1
+ import { OnModuleInit } from "@nestjs/common";
2
+ import { ReplicatePluginOptions, ModelTrainingQueueType, OrderExportQueueType } from "../types.js";
3
+ import { Job, JobQueueService, RequestContext, OrderService, PaginatedList, CustomerService, TransactionalConnection, ID, Customer, ListQueryBuilder, ListQueryOptions } from "@deenruv/core";
4
+ import { StartOrderExportToReplicateInput } from "../graphql/generated-admin-types.js";
5
+ import { ReplicateEntity } from "../entites/replicate.entity.js";
6
+ import { PredictionStatus } from "../zeus/index.js";
7
+ export declare class ReplicateService implements OnModuleInit {
8
+ private readonly options;
9
+ private readonly connection;
10
+ private readonly jobQueueService;
11
+ private readonly orderService;
12
+ private readonly customerService;
13
+ private readonly listQueryBuilder;
14
+ private modelTrainingQueue;
15
+ private orderExportQueue;
16
+ constructor(options: ReplicatePluginOptions, connection: TransactionalConnection, jobQueueService: JobQueueService, orderService: OrderService, customerService: CustomerService, listQueryBuilder: ListQueryBuilder);
17
+ processModelTrainingJob(job: Job<ModelTrainingQueueType>): Promise<void>;
18
+ processOrderExportJob(job: Job<OrderExportQueueType>): Promise<void>;
19
+ modelTrainingJob(ctx: RequestContext, input: any): Promise<void>;
20
+ getPredictionID(ctx: RequestContext, prediction_id: string): Promise<string | undefined>;
21
+ orderExportJob(ctx: RequestContext, input: StartOrderExportToReplicateInput): Promise<ID>;
22
+ onModuleInit(): Promise<void>;
23
+ startModelTraining(ctx: RequestContext, input: any): Promise<void>;
24
+ startOrderExportJob(ctx: RequestContext, input: StartOrderExportToReplicateInput & {
25
+ replicateEntityID: ID;
26
+ }): Promise<void>;
27
+ private randomDate;
28
+ private saveOrdersToCsv;
29
+ private triggerPredictApi;
30
+ checkAndUpdatePredictionStatus(ctx: RequestContext, prediction_id: string): Promise<{
31
+ predictions: never[];
32
+ status: PredictionStatus;
33
+ } | undefined>;
34
+ getPredictionItems(ctx: RequestContext, options?: ListQueryOptions<ReplicateEntity>): Promise<PaginatedList<ReplicateEntity>>;
35
+ getPredictionItem(ctx: RequestContext, id: string): Promise<{
36
+ status: string;
37
+ predictions: {
38
+ id: ID;
39
+ score: number;
40
+ customer: Customer | null;
41
+ }[];
42
+ }>;
43
+ }
@@ -0,0 +1,389 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.ReplicateService = void 0;
19
+ const common_1 = require("@nestjs/common");
20
+ const constants_js_1 = require("../constants.js");
21
+ const core_1 = require("@deenruv/core");
22
+ const fs_1 = __importDefault(require("fs"));
23
+ const path_1 = __importDefault(require("path"));
24
+ const axios_1 = __importDefault(require("axios"));
25
+ const generated_admin_types_js_1 = require("../graphql/generated-admin-types.js");
26
+ const generated_types_js_1 = require("@deenruv/common/lib/generated-types.js");
27
+ const promises_1 = require("fs/promises");
28
+ const replicate_entity_js_1 = require("../entites/replicate.entity.js");
29
+ const index_js_1 = require("../zeus/index.js");
30
+ const typeorm_1 = require("typeorm");
31
+ let ReplicateService = class ReplicateService {
32
+ constructor(options, connection, jobQueueService, orderService, customerService, listQueryBuilder) {
33
+ this.options = options;
34
+ this.connection = connection;
35
+ this.jobQueueService = jobQueueService;
36
+ this.orderService = orderService;
37
+ this.customerService = customerService;
38
+ this.listQueryBuilder = listQueryBuilder;
39
+ }
40
+ async processModelTrainingJob(job) {
41
+ core_1.Logger.info("initializing model training", constants_js_1.LOGGER_CTX);
42
+ const { serializedContext, startDate, endDate } = job.data;
43
+ const ctx = core_1.RequestContext.deserialize(serializedContext);
44
+ await this.startModelTraining(ctx, { startDate, endDate });
45
+ this.jobQueueService.start();
46
+ }
47
+ async processOrderExportJob(job) {
48
+ core_1.Logger.info("initializing order export", constants_js_1.LOGGER_CTX);
49
+ const { replicateEntityID, serializedContext, startDate, endDate, showMetrics, } = job.data;
50
+ const ctx = core_1.RequestContext.deserialize(serializedContext);
51
+ await this.startOrderExportJob(ctx, {
52
+ replicateEntityID,
53
+ startDate,
54
+ endDate,
55
+ showMetrics,
56
+ });
57
+ this.jobQueueService.start();
58
+ }
59
+ async modelTrainingJob(ctx, input) {
60
+ var _a, _b, _c;
61
+ const serializedContext = ctx.serialize();
62
+ await this.modelTrainingQueue.add({
63
+ serializedContext,
64
+ numLastOrder: (_a = input.numLastOrder) !== null && _a !== void 0 ? _a : 30000,
65
+ startDate: (_b = input.startDate) !== null && _b !== void 0 ? _b : "",
66
+ endDate: (_c = input.endDate) !== null && _c !== void 0 ? _c : "",
67
+ });
68
+ }
69
+ async getPredictionID(ctx, prediction_id) {
70
+ const entity = await this.connection
71
+ .getRepository(ctx, replicate_entity_js_1.ReplicateEntity)
72
+ .findOne({
73
+ where: { id: prediction_id },
74
+ });
75
+ return entity === null || entity === void 0 ? void 0 : entity.prediction_id;
76
+ }
77
+ async orderExportJob(ctx, input) {
78
+ var _a, _b, _c, _d;
79
+ const entity = await this.connection
80
+ .getRepository(ctx, replicate_entity_js_1.ReplicateEntity)
81
+ .save({});
82
+ const serializedContext = ctx.serialize();
83
+ await this.orderExportQueue.add({
84
+ replicateEntityID: entity.id,
85
+ serializedContext,
86
+ startDate: (_a = input.startDate) !== null && _a !== void 0 ? _a : "",
87
+ endDate: (_b = input.endDate) !== null && _b !== void 0 ? _b : "",
88
+ predictType: (_c = input.predictType) !== null && _c !== void 0 ? _c : generated_admin_types_js_1.PredictionType.RFM_SCORE,
89
+ showMetrics: (_d = input.showMetrics) !== null && _d !== void 0 ? _d : false,
90
+ });
91
+ return entity.id;
92
+ }
93
+ async onModuleInit() {
94
+ this.modelTrainingQueue = await this.jobQueueService.createQueue({
95
+ name: "train-model",
96
+ process: (job) => {
97
+ return this.processModelTrainingJob(job);
98
+ },
99
+ });
100
+ this.orderExportQueue = await this.jobQueueService.createQueue({
101
+ name: "order-export",
102
+ process: (job) => {
103
+ return this.processOrderExportJob(job);
104
+ },
105
+ });
106
+ }
107
+ async startModelTraining(ctx, input) {
108
+ try {
109
+ const { numLastOrder } = input;
110
+ const customerService = this.customerService;
111
+ const orderService = this.orderService;
112
+ for (let i = 0; i < (numLastOrder !== null && numLastOrder !== void 0 ? numLastOrder : 30000); i++) {
113
+ const uniqueEmail = `test${i}_${Date.now()}@example.com`;
114
+ const customer = await customerService.create(ctx, {
115
+ emailAddress: uniqueEmail,
116
+ firstName: "test",
117
+ lastName: "replicatetest",
118
+ phoneNumber: "123456789",
119
+ title: "Mr",
120
+ });
121
+ if ("errorCode" in customer) {
122
+ core_1.Logger.error(`Failed to create customer: ${customer.errorCode}`, constants_js_1.LOGGER_CTX);
123
+ continue;
124
+ }
125
+ const randomNumber = Math.floor(Math.random() * 7) + 1;
126
+ for (let j = 0; j < randomNumber; j++) {
127
+ const order = await orderService.addCustomerToOrder(ctx, await orderService.create(ctx, 1), customer);
128
+ const itemsToAdd = Math.floor(Math.random() * 5) + 1;
129
+ await orderService.addItemToOrder(ctx, order.id, 1, itemsToAdd);
130
+ await orderService.transitionToState(ctx, order.id, "AddingItems");
131
+ await orderService.setShippingAddress(ctx, order.id, {
132
+ streetLine1: "test",
133
+ countryCode: "PL",
134
+ });
135
+ await orderService.setShippingMethod(ctx, order.id, [1, 2]);
136
+ await orderService.transitionToState(ctx, order.id, "ArrangingPayment");
137
+ await orderService.addPaymentToOrder(ctx, order.id, {
138
+ method: "standard-payment",
139
+ metadata: {
140
+ transfer_group: "",
141
+ },
142
+ });
143
+ await orderService.transitionToState(ctx, order.id, "PaymentAuthorized");
144
+ }
145
+ }
146
+ }
147
+ catch (error) {
148
+ core_1.Logger.error("model training failed", constants_js_1.LOGGER_CTX);
149
+ console.error("Error:", error);
150
+ }
151
+ }
152
+ async startOrderExportJob(ctx, input) {
153
+ const { showMetrics, replicateEntityID } = input;
154
+ let { startDate, endDate, predictType } = input;
155
+ startDate = startDate || null;
156
+ endDate = endDate || null;
157
+ predictType = predictType !== null && predictType !== void 0 ? predictType : generated_admin_types_js_1.PredictionType.RFM_SCORE;
158
+ core_1.Logger.info("starting order export", constants_js_1.LOGGER_CTX);
159
+ const columnNames = [
160
+ "InvoiceNo",
161
+ "InvoiceDate",
162
+ "Total",
163
+ "CustomerId",
164
+ "Products",
165
+ ];
166
+ const csv = [columnNames.join(",")];
167
+ const LatestOrders = await this.orderService.findAll(ctx, {
168
+ filter: {
169
+ orderPlacedAt: startDate && endDate
170
+ ? {
171
+ between: {
172
+ start: new Date(startDate),
173
+ end: new Date(endDate),
174
+ },
175
+ }
176
+ : { isNull: false },
177
+ },
178
+ });
179
+ const numLatestOrders = LatestOrders.totalItems;
180
+ let batch = 1;
181
+ if (numLatestOrders > 1000) {
182
+ batch = Math.ceil(numLatestOrders / 1000);
183
+ }
184
+ for (let i = 0; i < batch; i++) {
185
+ const orders = await this.orderService.findAll(ctx, {
186
+ skip: i * 1000,
187
+ take: 1000,
188
+ filter: {
189
+ orderPlacedAt: startDate && endDate
190
+ ? {
191
+ between: {
192
+ start: new Date(startDate),
193
+ end: new Date(endDate),
194
+ },
195
+ }
196
+ : { isNull: false },
197
+ },
198
+ sort: {
199
+ orderPlacedAt: generated_types_js_1.SortOrder.DESC,
200
+ },
201
+ });
202
+ if (!orders.items.length)
203
+ break;
204
+ await this.saveOrdersToCsv(csv, orders);
205
+ }
206
+ const csvString = csv.join("\n");
207
+ const tmp = await (0, promises_1.mkdtemp)("orders");
208
+ const filePath = path_1.default.join(tmp, "./orders.csv");
209
+ fs_1.default.writeFileSync(filePath, csvString);
210
+ core_1.Logger.info("order export completed", constants_js_1.LOGGER_CTX);
211
+ const result = await this.triggerPredictApi(filePath, predictType, showMetrics || false);
212
+ if (!result) {
213
+ throw new Error("Failed to trigger predict API");
214
+ }
215
+ const { prediction_id, status } = result;
216
+ await this.connection
217
+ .getRepository(ctx, replicate_entity_js_1.ReplicateEntity)
218
+ .update({ id: replicateEntityID, status: status }, { prediction_id, status });
219
+ await (0, promises_1.rm)(tmp, { recursive: true, force: true });
220
+ }
221
+ async randomDate(start, end, startHour, endHour) {
222
+ const date = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
223
+ const hour = (startHour + Math.random() * (endHour - startHour)) | 0;
224
+ date.setHours(hour);
225
+ return date;
226
+ }
227
+ async saveOrdersToCsv(csv, orders) {
228
+ const orderData = await Promise.all(orders.items.map(async (order) => {
229
+ var _a;
230
+ return [
231
+ order.id,
232
+ ((_a = order.orderPlacedAt) !== null && _a !== void 0 ? _a : (await this.randomDate(new Date(2024, 1, 1), new Date(2025, 1, 1), 0, 23))).toISOString(),
233
+ order.totalWithTax,
234
+ order.customerId,
235
+ "ALL",
236
+ ].join(",");
237
+ }));
238
+ csv.push(...orderData);
239
+ }
240
+ async triggerPredictApi(filePath, predictType, showMetrics) {
241
+ try {
242
+ const fileData = await fs_1.default.promises.readFile(filePath);
243
+ const base64Data = fileData.toString("base64");
244
+ const fileInput = `data:text/csv;base64,${base64Data}`;
245
+ let replicatePredictType = "";
246
+ if (predictType === generated_admin_types_js_1.PredictionType.RFM_SCORE)
247
+ replicatePredictType = "rfm-score";
248
+ if (predictType === generated_admin_types_js_1.PredictionType.SEGMENTATION)
249
+ replicatePredictType = "segmentation";
250
+ if (!this.options.deploymentName === undefined) {
251
+ throw new Error("Replicate: deployment name token not set");
252
+ }
253
+ if (!this.options.apiToken === undefined) {
254
+ throw new Error("Replicate: API token not set");
255
+ }
256
+ const response = await axios_1.default.post(`https://api.replicate.com/v1/deployments/aexol-studio/${this.options.deploymentName}/predictions`, {
257
+ input: {
258
+ data_path: fileInput,
259
+ predict_type: replicatePredictType,
260
+ show_metrics: showMetrics,
261
+ },
262
+ }, {
263
+ headers: {
264
+ Authorization: `Bearer ${this.options.apiToken}`,
265
+ "Content-Type": `application/json`,
266
+ },
267
+ });
268
+ return { prediction_id: response.data.id, status: response.data.status };
269
+ }
270
+ catch (error) {
271
+ core_1.Logger.error("API call to replicate failed", constants_js_1.LOGGER_CTX);
272
+ console.error("Error:", error);
273
+ }
274
+ }
275
+ async checkAndUpdatePredictionStatus(ctx, prediction_id) {
276
+ var _a, _b;
277
+ try {
278
+ const response = await axios_1.default.get(`https://api.replicate.com/v1/predictions/${prediction_id}`, {
279
+ headers: {
280
+ Authorization: `Bearer ${this.options.apiToken}`,
281
+ "Content-Type": "application/json",
282
+ },
283
+ });
284
+ const status = response.data.status;
285
+ let outputDict = {};
286
+ if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.error) {
287
+ await this.connection.getRepository(ctx, replicate_entity_js_1.ReplicateEntity).update({ prediction_id }, {
288
+ status: index_js_1.PredictionStatus.failed,
289
+ finishedAt: response.data.completed_at,
290
+ });
291
+ return { predictions: [], status: index_js_1.PredictionStatus.failed };
292
+ }
293
+ try {
294
+ outputDict = JSON.parse(((_b = response === null || response === void 0 ? void 0 : response.data) === null || _b === void 0 ? void 0 : _b.output) || "{}");
295
+ }
296
+ catch (error) {
297
+ core_1.Logger.error("Failed to parse output", constants_js_1.LOGGER_CTX);
298
+ }
299
+ const data = [];
300
+ for (const key in outputDict) {
301
+ data.push([key, outputDict[key]]);
302
+ }
303
+ data.sort(([_1, ascore], [_2, bscore]) => bscore - ascore);
304
+ const predictions = [];
305
+ for (let i = 0; i < data.length; i += 100) {
306
+ const view = data.slice(i, Math.max(i + 100, data.length));
307
+ const res = await this.connection.getRepository(ctx, core_1.Customer).find({
308
+ where: {
309
+ id: (0, typeorm_1.In)(view.map(([id]) => parseInt(id))),
310
+ },
311
+ });
312
+ predictions.push(...view
313
+ .map(([id, score]) => {
314
+ const customer = res.find((r) => +r.id === +id);
315
+ if (!(customer === null || customer === void 0 ? void 0 : customer.emailAddress)) {
316
+ return null;
317
+ }
318
+ return {
319
+ id,
320
+ score,
321
+ customer: res.find((r) => +r.id === +id),
322
+ };
323
+ })
324
+ .filter((x) => !!x));
325
+ }
326
+ const output = predictions.map(({ customer, score }) => ({
327
+ customerId: customer === null || customer === void 0 ? void 0 : customer.id,
328
+ score,
329
+ customer,
330
+ }));
331
+ if (status !== "starting" && response.data.output) {
332
+ await this.connection.getRepository(ctx, replicate_entity_js_1.ReplicateEntity).update({ prediction_id }, {
333
+ output: output,
334
+ status: status,
335
+ finishedAt: response.data.completed_at,
336
+ });
337
+ }
338
+ }
339
+ catch (error) {
340
+ core_1.Logger.error("API call to check and update prediction status failed", constants_js_1.LOGGER_CTX);
341
+ console.error("Error:", error);
342
+ }
343
+ }
344
+ async getPredictionItems(ctx, options) {
345
+ const qb = this.listQueryBuilder.build(replicate_entity_js_1.ReplicateEntity, options, { ctx });
346
+ const [items, totalItems] = await qb.getManyAndCount();
347
+ return { items, totalItems };
348
+ }
349
+ async getPredictionItem(ctx, id) {
350
+ const prediction = await this.connection
351
+ .getRepository(ctx, replicate_entity_js_1.ReplicateEntity)
352
+ .findOne({ where: { id } });
353
+ if (!prediction) {
354
+ throw new Error("Prediction not found");
355
+ }
356
+ if (prediction.status === index_js_1.PredictionStatus.starting) {
357
+ await this.checkAndUpdatePredictionStatus(ctx, prediction.prediction_id.toString());
358
+ }
359
+ if (prediction.output) {
360
+ const output = await Promise.all(prediction.output.map(async ({ customerId, score }) => {
361
+ const customer = await this.connection
362
+ .getRepository(ctx, core_1.Customer)
363
+ .findOne({ where: { id: customerId } });
364
+ return {
365
+ id: customerId,
366
+ score,
367
+ customer,
368
+ };
369
+ }));
370
+ return { status: prediction.status, predictions: output };
371
+ }
372
+ return { status: prediction.status, predictions: [] };
373
+ }
374
+ };
375
+ exports.ReplicateService = ReplicateService;
376
+ exports.ReplicateService = ReplicateService = __decorate([
377
+ (0, common_1.Injectable)(),
378
+ __param(0, (0, common_1.Inject)(constants_js_1.REPLICATE_PLUGIN_OPTIONS)),
379
+ __param(1, (0, common_1.Inject)(core_1.TransactionalConnection)),
380
+ __param(2, (0, common_1.Inject)(core_1.JobQueueService)),
381
+ __param(3, (0, common_1.Inject)(core_1.OrderService)),
382
+ __param(4, (0, common_1.Inject)(core_1.CustomerService)),
383
+ __param(5, (0, common_1.Inject)(core_1.ListQueryBuilder)),
384
+ __metadata("design:paramtypes", [Object, core_1.TransactionalConnection,
385
+ core_1.JobQueueService,
386
+ core_1.OrderService,
387
+ core_1.CustomerService,
388
+ core_1.ListQueryBuilder])
389
+ ], ReplicateService);
@@ -0,0 +1,19 @@
1
+ import { ID, SerializedRequestContext } from "@deenruv/core";
2
+ export interface ReplicatePluginOptions {
3
+ deploymentName: string;
4
+ apiToken: string;
5
+ }
6
+ export interface ModelTrainingQueueType {
7
+ serializedContext: SerializedRequestContext;
8
+ numLastOrder: number;
9
+ startDate: string;
10
+ endDate: string;
11
+ }
12
+ export interface OrderExportQueueType {
13
+ serializedContext: SerializedRequestContext;
14
+ startDate: string;
15
+ endDate: string;
16
+ predictType: string;
17
+ showMetrics: boolean;
18
+ replicateEntityID: ID;
19
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ export declare const AllTypesProps: Record<string, any>;
2
+ export declare const ReturnTypes: Record<string, any>;
3
+ export declare const Ops: {
4
+ query: "Query";
5
+ mutation: "Mutation";
6
+ };