medusa-plugin-complaints 0.1.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.
- package/.medusa/server/medusa-config.d.ts +1 -0
- package/.medusa/server/medusa-config.js +23 -0
- package/.medusa/server/src/admin/index.js +8633 -0
- package/.medusa/server/src/admin/index.mjs +8631 -0
- package/.medusa/server/src/api/admin/complaint-stats/products/[id]/route.d.ts +3 -0
- package/.medusa/server/src/api/admin/complaint-stats/products/[id]/route.js +21 -0
- package/.medusa/server/src/api/admin/complaint-stats/recalculate/route.d.ts +2 -0
- package/.medusa/server/src/api/admin/complaint-stats/recalculate/route.js +40 -0
- package/.medusa/server/src/api/admin/complaint-stats/route.d.ts +1 -0
- package/.medusa/server/src/api/admin/complaint-stats/route.js +16 -0
- package/.medusa/server/src/api/admin/complaint-tags/[id]/route.d.ts +5 -0
- package/.medusa/server/src/api/admin/complaint-tags/[id]/route.js +34 -0
- package/.medusa/server/src/api/admin/complaint-tags/route.d.ts +5 -0
- package/.medusa/server/src/api/admin/complaint-tags/route.js +37 -0
- package/.medusa/server/src/api/admin/complaints/[id]/activities/[entryId]/route.d.ts +5 -0
- package/.medusa/server/src/api/admin/complaints/[id]/activities/[entryId]/route.js +35 -0
- package/.medusa/server/src/api/admin/complaints/[id]/activities/route.d.ts +5 -0
- package/.medusa/server/src/api/admin/complaints/[id]/activities/route.js +43 -0
- package/.medusa/server/src/api/admin/complaints/[id]/notes/[noteId]/route.d.ts +4 -0
- package/.medusa/server/src/api/admin/complaints/[id]/notes/[noteId]/route.js +20 -0
- package/.medusa/server/src/api/admin/complaints/[id]/notes/route.d.ts +3 -0
- package/.medusa/server/src/api/admin/complaints/[id]/notes/route.js +12 -0
- package/.medusa/server/src/api/admin/complaints/[id]/route.d.ts +5 -0
- package/.medusa/server/src/api/admin/complaints/[id]/route.js +43 -0
- package/.medusa/server/src/api/admin/complaints/route.d.ts +5 -0
- package/.medusa/server/src/api/admin/complaints/route.js +48 -0
- package/.medusa/server/src/api/middlewares.d.ts +2 -0
- package/.medusa/server/src/api/middlewares.js +150 -0
- package/.medusa/server/src/api/validators.d.ts +547 -0
- package/.medusa/server/src/api/validators.js +215 -0
- package/.medusa/server/src/jobs/update-complaint-stats.d.ts +6 -0
- package/.medusa/server/src/jobs/update-complaint-stats.js +50 -0
- package/.medusa/server/src/links/complaint-activity-user.d.ts +2 -0
- package/.medusa/server/src/links/complaint-activity-user.js +15 -0
- package/.medusa/server/src/links/complaint-customer.d.ts +2 -0
- package/.medusa/server/src/links/complaint-customer.js +15 -0
- package/.medusa/server/src/links/complaint-order.d.ts +2 -0
- package/.medusa/server/src/links/complaint-order.js +15 -0
- package/.medusa/server/src/links/complaint-product.d.ts +2 -0
- package/.medusa/server/src/links/complaint-product.js +15 -0
- package/.medusa/server/src/links/customer-complaint.d.ts +2 -0
- package/.medusa/server/src/links/customer-complaint.js +18 -0
- package/.medusa/server/src/links/order-complaint.d.ts +2 -0
- package/.medusa/server/src/links/order-complaint.js +18 -0
- package/.medusa/server/src/links/product-complaint.d.ts +2 -0
- package/.medusa/server/src/links/product-complaint.js +18 -0
- package/.medusa/server/src/links/user-complaint-activity.d.ts +2 -0
- package/.medusa/server/src/links/user-complaint-activity.js +18 -0
- package/.medusa/server/src/modules/complaint/index.d.ts +64 -0
- package/.medusa/server/src/modules/complaint/index.js +25 -0
- package/.medusa/server/src/modules/complaint/migrations/Migration20260409171742.d.ts +5 -0
- package/.medusa/server/src/modules/complaint/migrations/Migration20260409171742.js +36 -0
- package/.medusa/server/src/modules/complaint/models/complaint-activity.d.ts +30 -0
- package/.medusa/server/src/modules/complaint/models/complaint-activity.js +22 -0
- package/.medusa/server/src/modules/complaint/models/complaint-product-stat.d.ts +9 -0
- package/.medusa/server/src/modules/complaint/models/complaint-product-stat.js +15 -0
- package/.medusa/server/src/modules/complaint/models/complaint-stat.d.ts +1 -0
- package/.medusa/server/src/modules/complaint/models/complaint-stat.js +8 -0
- package/.medusa/server/src/modules/complaint/models/complaint-tag.d.ts +25 -0
- package/.medusa/server/src/modules/complaint/models/complaint-tag.js +11 -0
- package/.medusa/server/src/modules/complaint/models/complaint.d.ts +29 -0
- package/.medusa/server/src/modules/complaint/models/complaint.js +32 -0
- package/.medusa/server/src/modules/complaint/service.d.ts +236 -0
- package/.medusa/server/src/modules/complaint/service.js +87 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/package.json +89 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare enum ComplaintActivityType {
|
|
2
|
+
OPEN = "open",
|
|
3
|
+
CLOSE = "close",
|
|
4
|
+
NOTE = "note"
|
|
5
|
+
}
|
|
6
|
+
export declare const ComplaintActivity: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
7
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
8
|
+
type: import("@medusajs/framework/utils").EnumProperty<typeof ComplaintActivityType>;
|
|
9
|
+
user_id: import("@medusajs/framework/utils").TextProperty;
|
|
10
|
+
note: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
11
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
12
|
+
complaint: import("@medusajs/framework/utils").BelongsTo<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
13
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
14
|
+
number: import("@medusajs/framework/utils").AutoIncrementProperty;
|
|
15
|
+
status: import("@medusajs/framework/utils").EnumProperty<typeof import("./complaint").ComplaintStatus>;
|
|
16
|
+
description: import("@medusajs/framework/utils").TextProperty;
|
|
17
|
+
customer_id: import("@medusajs/framework/utils").TextProperty;
|
|
18
|
+
order_id: import("@medusajs/framework/utils").TextProperty;
|
|
19
|
+
product_id: import("@medusajs/framework/utils").TextProperty;
|
|
20
|
+
serial_number_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
21
|
+
stock_lot_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
22
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
23
|
+
tags: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
24
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
25
|
+
value: import("@medusajs/framework/utils").TextProperty;
|
|
26
|
+
complaints: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint">>;
|
|
27
|
+
}>, "complaint_tag">>;
|
|
28
|
+
activity: import("@medusajs/framework/utils").HasMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint_activity">>;
|
|
29
|
+
}>, "complaint">, undefined>;
|
|
30
|
+
}>, "complaint_activity">;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComplaintActivity = exports.ComplaintActivityType = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const complaint_1 = require("./complaint");
|
|
6
|
+
var ComplaintActivityType;
|
|
7
|
+
(function (ComplaintActivityType) {
|
|
8
|
+
ComplaintActivityType["OPEN"] = "open";
|
|
9
|
+
ComplaintActivityType["CLOSE"] = "close";
|
|
10
|
+
ComplaintActivityType["NOTE"] = "note";
|
|
11
|
+
})(ComplaintActivityType || (exports.ComplaintActivityType = ComplaintActivityType = {}));
|
|
12
|
+
exports.ComplaintActivity = utils_1.model.define('complaint_activity', {
|
|
13
|
+
id: utils_1.model.id().primaryKey(),
|
|
14
|
+
type: utils_1.model.enum(ComplaintActivityType).default(ComplaintActivityType.NOTE),
|
|
15
|
+
user_id: utils_1.model.text(),
|
|
16
|
+
note: utils_1.model.text().nullable(),
|
|
17
|
+
metadata: utils_1.model.json().nullable(),
|
|
18
|
+
complaint: utils_1.model.belongsTo(() => complaint_1.Complaint, {
|
|
19
|
+
mappedBy: 'activity'
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxhaW50LWFjdGl2aXR5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL21vZHVsZXMvY29tcGxhaW50L21vZGVscy9jb21wbGFpbnQtYWN0aXZpdHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscURBQWlEO0FBQ2pELDJDQUF1QztBQUV2QyxJQUFZLHFCQUlYO0FBSkQsV0FBWSxxQkFBcUI7SUFDaEMsc0NBQWEsQ0FBQTtJQUNiLHdDQUFlLENBQUE7SUFDZixzQ0FBYSxDQUFBO0FBQ2QsQ0FBQyxFQUpXLHFCQUFxQixxQ0FBckIscUJBQXFCLFFBSWhDO0FBRVksUUFBQSxpQkFBaUIsR0FBRyxhQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFO0lBQ25FLEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQzNCLElBQUksRUFBRSxhQUFLLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQztJQUMzRSxPQUFPLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRTtJQUNyQixJQUFJLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUM3QixRQUFRLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNqQyxTQUFTLEVBQUUsYUFBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxxQkFBUyxFQUFFO1FBQzNDLFFBQVEsRUFBRSxVQUFVO0tBQ3BCLENBQUM7Q0FDRixDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const ComplaintProductStat: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
2
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
3
|
+
product_id: import("@medusajs/framework/utils").TextProperty;
|
|
4
|
+
total_orders: import("@medusajs/framework/utils").NumberProperty;
|
|
5
|
+
total_complaints: import("@medusajs/framework/utils").NumberProperty;
|
|
6
|
+
complaint_rate: import("@medusajs/framework/utils").FloatProperty;
|
|
7
|
+
last_calculated_at: import("@medusajs/framework/utils").NullableModifier<Date, import("@medusajs/framework/utils").DateTimeProperty>;
|
|
8
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
9
|
+
}>, "complaint_product_stat">;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComplaintProductStat = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
// change this to keep each calculation for comparison over time instead of overwriting the same record
|
|
6
|
+
exports.ComplaintProductStat = utils_1.model.define('complaint_product_stat', {
|
|
7
|
+
id: utils_1.model.id().primaryKey(),
|
|
8
|
+
product_id: utils_1.model.text(),
|
|
9
|
+
total_orders: utils_1.model.number().default(0),
|
|
10
|
+
total_complaints: utils_1.model.number().default(0),
|
|
11
|
+
complaint_rate: utils_1.model.float().default(0),
|
|
12
|
+
last_calculated_at: utils_1.model.dateTime().nullable(),
|
|
13
|
+
metadata: utils_1.model.json().nullable()
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxhaW50LXByb2R1Y3Qtc3RhdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2NvbXBsYWludC9tb2RlbHMvY29tcGxhaW50LXByb2R1Y3Qtc3RhdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxREFBaUQ7QUFFakQsdUdBQXVHO0FBQzFGLFFBQUEsb0JBQW9CLEdBQUcsYUFBSyxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRTtJQUMxRSxFQUFFLEVBQUUsYUFBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsRUFBRTtJQUMzQixVQUFVLEVBQUUsYUFBSyxDQUFDLElBQUksRUFBRTtJQUN4QixZQUFZLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDdkMsZ0JBQWdCLEVBQUUsYUFBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDM0MsY0FBYyxFQUFFLGFBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLGtCQUFrQixFQUFFLGFBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDL0MsUUFBUSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDakMsQ0FBQyxDQUFBIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// track number of complaints over time
|
|
4
|
+
// export const ComplaintStat = model.define('complaint_stat', {
|
|
5
|
+
// id: model.id().primaryKey(),
|
|
6
|
+
// metadata: model.json().nullable()
|
|
7
|
+
// })
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxhaW50LXN0YXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9jb21wbGFpbnQvbW9kZWxzL2NvbXBsYWludC1zdGF0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBRUEsdUNBQXVDO0FBQ3ZDLGdFQUFnRTtBQUNoRSxnQ0FBZ0M7QUFFaEMscUNBQXFDO0FBQ3JDLEtBQUsifQ==
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const ComplaintTag: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
2
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
3
|
+
value: import("@medusajs/framework/utils").TextProperty;
|
|
4
|
+
complaints: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
5
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
6
|
+
number: import("@medusajs/framework/utils").AutoIncrementProperty;
|
|
7
|
+
status: import("@medusajs/framework/utils").EnumProperty<typeof import("./complaint").ComplaintStatus>;
|
|
8
|
+
description: import("@medusajs/framework/utils").TextProperty;
|
|
9
|
+
customer_id: import("@medusajs/framework/utils").TextProperty;
|
|
10
|
+
order_id: import("@medusajs/framework/utils").TextProperty;
|
|
11
|
+
product_id: import("@medusajs/framework/utils").TextProperty;
|
|
12
|
+
serial_number_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
13
|
+
stock_lot_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
14
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
15
|
+
tags: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint_tag">>;
|
|
16
|
+
activity: import("@medusajs/framework/utils").HasMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
17
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
18
|
+
type: import("@medusajs/framework/utils").EnumProperty<typeof import("./complaint-activity").ComplaintActivityType>;
|
|
19
|
+
user_id: import("@medusajs/framework/utils").TextProperty;
|
|
20
|
+
note: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
21
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
22
|
+
complaint: import("@medusajs/framework/utils").BelongsTo<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint">, undefined>;
|
|
23
|
+
}>, "complaint_activity">>;
|
|
24
|
+
}>, "complaint">>;
|
|
25
|
+
}>, "complaint_tag">;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComplaintTag = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const complaint_1 = require("./complaint");
|
|
6
|
+
exports.ComplaintTag = utils_1.model.define('complaint_tag', {
|
|
7
|
+
id: utils_1.model.id().primaryKey(),
|
|
8
|
+
value: utils_1.model.text(),
|
|
9
|
+
complaints: utils_1.model.manyToMany(() => complaint_1.Complaint)
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxhaW50LXRhZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2NvbXBsYWludC9tb2RlbHMvY29tcGxhaW50LXRhZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxxREFBaUQ7QUFDakQsMkNBQXVDO0FBRTFCLFFBQUEsWUFBWSxHQUFHLGFBQUssQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFO0lBQ3pELEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQzNCLEtBQUssRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ25CLFVBQVUsRUFBRSxhQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHFCQUFTLENBQUM7Q0FDN0MsQ0FBQyxDQUFBIn0=
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare enum ComplaintStatus {
|
|
2
|
+
OPEN = "open",
|
|
3
|
+
CLOSED = "closed"
|
|
4
|
+
}
|
|
5
|
+
export declare const Complaint: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
6
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
7
|
+
number: import("@medusajs/framework/utils").AutoIncrementProperty;
|
|
8
|
+
status: import("@medusajs/framework/utils").EnumProperty<typeof ComplaintStatus>;
|
|
9
|
+
description: import("@medusajs/framework/utils").TextProperty;
|
|
10
|
+
customer_id: import("@medusajs/framework/utils").TextProperty;
|
|
11
|
+
order_id: import("@medusajs/framework/utils").TextProperty;
|
|
12
|
+
product_id: import("@medusajs/framework/utils").TextProperty;
|
|
13
|
+
serial_number_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
14
|
+
stock_lot_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
15
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
16
|
+
tags: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
17
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
18
|
+
value: import("@medusajs/framework/utils").TextProperty;
|
|
19
|
+
complaints: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint">>;
|
|
20
|
+
}>, "complaint_tag">>;
|
|
21
|
+
activity: import("@medusajs/framework/utils").HasMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
22
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
23
|
+
type: import("@medusajs/framework/utils").EnumProperty<typeof import("./complaint-activity").ComplaintActivityType>;
|
|
24
|
+
user_id: import("@medusajs/framework/utils").TextProperty;
|
|
25
|
+
note: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
26
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
27
|
+
complaint: import("@medusajs/framework/utils").BelongsTo<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint">, undefined>;
|
|
28
|
+
}>, "complaint_activity">>;
|
|
29
|
+
}>, "complaint">;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Complaint = exports.ComplaintStatus = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const complaint_tag_1 = require("./complaint-tag");
|
|
6
|
+
const complaint_activity_1 = require("./complaint-activity");
|
|
7
|
+
var ComplaintStatus;
|
|
8
|
+
(function (ComplaintStatus) {
|
|
9
|
+
ComplaintStatus["OPEN"] = "open";
|
|
10
|
+
ComplaintStatus["CLOSED"] = "closed";
|
|
11
|
+
})(ComplaintStatus || (exports.ComplaintStatus = ComplaintStatus = {}));
|
|
12
|
+
exports.Complaint = utils_1.model
|
|
13
|
+
.define('complaint', {
|
|
14
|
+
id: utils_1.model.id().primaryKey(),
|
|
15
|
+
number: utils_1.model.autoincrement(),
|
|
16
|
+
status: utils_1.model.enum(ComplaintStatus).default(ComplaintStatus.OPEN),
|
|
17
|
+
description: utils_1.model.text().searchable(),
|
|
18
|
+
customer_id: utils_1.model.text(),
|
|
19
|
+
order_id: utils_1.model.text(),
|
|
20
|
+
product_id: utils_1.model.text(),
|
|
21
|
+
serial_number_id: utils_1.model.text().nullable(),
|
|
22
|
+
stock_lot_id: utils_1.model.text().nullable(),
|
|
23
|
+
metadata: utils_1.model.json().nullable(),
|
|
24
|
+
tags: utils_1.model.manyToMany(() => complaint_tag_1.ComplaintTag),
|
|
25
|
+
activity: utils_1.model.hasMany(() => complaint_activity_1.ComplaintActivity, {
|
|
26
|
+
mappedBy: 'complaint'
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
.cascades({
|
|
30
|
+
delete: ['activity'] // <-- delete all activity records when complaint is deleted
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGxhaW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL21vZHVsZXMvY29tcGxhaW50L21vZGVscy9jb21wbGFpbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscURBQWlEO0FBQ2pELG1EQUE4QztBQUM5Qyw2REFBd0Q7QUFFeEQsSUFBWSxlQUdYO0FBSEQsV0FBWSxlQUFlO0lBQzFCLGdDQUFhLENBQUE7SUFDYixvQ0FBaUIsQ0FBQTtBQUNsQixDQUFDLEVBSFcsZUFBZSwrQkFBZixlQUFlLFFBRzFCO0FBRVksUUFBQSxTQUFTLEdBQUcsYUFBSztLQUM1QixNQUFNLENBQUMsV0FBVyxFQUFFO0lBQ3BCLEVBQUUsRUFBRSxhQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQzNCLE1BQU0sRUFBRSxhQUFLLENBQUMsYUFBYSxFQUFFO0lBQzdCLE1BQU0sRUFBRSxhQUFLLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDO0lBQ2pFLFdBQVcsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsVUFBVSxFQUFFO0lBQ3RDLFdBQVcsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ3pCLFFBQVEsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ3RCLFVBQVUsRUFBRSxhQUFLLENBQUMsSUFBSSxFQUFFO0lBQ3hCLGdCQUFnQixFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDekMsWUFBWSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDckMsUUFBUSxFQUFFLGFBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDakMsSUFBSSxFQUFFLGFBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsNEJBQVksQ0FBQztJQUMxQyxRQUFRLEVBQUUsYUFBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxzQ0FBaUIsRUFBRTtRQUNoRCxRQUFRLEVBQUUsV0FBVztLQUNyQixDQUFDO0NBQ0YsQ0FBQztLQUNELFFBQVEsQ0FBQztJQUNULE1BQU0sRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLDREQUE0RDtDQUNqRixDQUFDLENBQUEifQ==
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { Logger } from '@medusajs/framework/types';
|
|
2
|
+
import { ComplaintActivityType } from './models/complaint-activity';
|
|
3
|
+
declare const ComplaintService_base: import("@medusajs/framework/utils").MedusaServiceReturnType<import("@medusajs/framework/utils").ModelConfigurationsToConfigTemplate<{
|
|
4
|
+
readonly Complaint: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
5
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
6
|
+
number: import("@medusajs/framework/utils").AutoIncrementProperty;
|
|
7
|
+
status: import("@medusajs/framework/utils").EnumProperty<typeof import("./models/complaint").ComplaintStatus>;
|
|
8
|
+
description: import("@medusajs/framework/utils").TextProperty;
|
|
9
|
+
customer_id: import("@medusajs/framework/utils").TextProperty;
|
|
10
|
+
order_id: import("@medusajs/framework/utils").TextProperty;
|
|
11
|
+
product_id: import("@medusajs/framework/utils").TextProperty;
|
|
12
|
+
serial_number_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
13
|
+
stock_lot_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
14
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
15
|
+
tags: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
16
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
17
|
+
value: import("@medusajs/framework/utils").TextProperty;
|
|
18
|
+
complaints: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint">>;
|
|
19
|
+
}>, "complaint_tag">>;
|
|
20
|
+
activity: import("@medusajs/framework/utils").HasMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
21
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
22
|
+
type: import("@medusajs/framework/utils").EnumProperty<typeof ComplaintActivityType>;
|
|
23
|
+
user_id: import("@medusajs/framework/utils").TextProperty;
|
|
24
|
+
note: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
25
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
26
|
+
complaint: import("@medusajs/framework/utils").BelongsTo<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint">, undefined>;
|
|
27
|
+
}>, "complaint_activity">>;
|
|
28
|
+
}>, "complaint">;
|
|
29
|
+
readonly ComplaintTag: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
30
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
31
|
+
value: import("@medusajs/framework/utils").TextProperty;
|
|
32
|
+
complaints: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
33
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
34
|
+
number: import("@medusajs/framework/utils").AutoIncrementProperty;
|
|
35
|
+
status: import("@medusajs/framework/utils").EnumProperty<typeof import("./models/complaint").ComplaintStatus>;
|
|
36
|
+
description: import("@medusajs/framework/utils").TextProperty;
|
|
37
|
+
customer_id: import("@medusajs/framework/utils").TextProperty;
|
|
38
|
+
order_id: import("@medusajs/framework/utils").TextProperty;
|
|
39
|
+
product_id: import("@medusajs/framework/utils").TextProperty;
|
|
40
|
+
serial_number_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
41
|
+
stock_lot_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
42
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
43
|
+
tags: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint_tag">>;
|
|
44
|
+
activity: import("@medusajs/framework/utils").HasMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
45
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
46
|
+
type: import("@medusajs/framework/utils").EnumProperty<typeof ComplaintActivityType>;
|
|
47
|
+
user_id: import("@medusajs/framework/utils").TextProperty;
|
|
48
|
+
note: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
49
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
50
|
+
complaint: import("@medusajs/framework/utils").BelongsTo<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint">, undefined>;
|
|
51
|
+
}>, "complaint_activity">>;
|
|
52
|
+
}>, "complaint">>;
|
|
53
|
+
}>, "complaint_tag">;
|
|
54
|
+
readonly ComplaintActivity: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
55
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
56
|
+
type: import("@medusajs/framework/utils").EnumProperty<typeof ComplaintActivityType>;
|
|
57
|
+
user_id: import("@medusajs/framework/utils").TextProperty;
|
|
58
|
+
note: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
59
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
60
|
+
complaint: import("@medusajs/framework/utils").BelongsTo<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
61
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
62
|
+
number: import("@medusajs/framework/utils").AutoIncrementProperty;
|
|
63
|
+
status: import("@medusajs/framework/utils").EnumProperty<typeof import("./models/complaint").ComplaintStatus>;
|
|
64
|
+
description: import("@medusajs/framework/utils").TextProperty;
|
|
65
|
+
customer_id: import("@medusajs/framework/utils").TextProperty;
|
|
66
|
+
order_id: import("@medusajs/framework/utils").TextProperty;
|
|
67
|
+
product_id: import("@medusajs/framework/utils").TextProperty;
|
|
68
|
+
serial_number_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
69
|
+
stock_lot_id: import("@medusajs/framework/utils").NullableModifier<string, import("@medusajs/framework/utils").TextProperty>;
|
|
70
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
71
|
+
tags: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
72
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
73
|
+
value: import("@medusajs/framework/utils").TextProperty;
|
|
74
|
+
complaints: import("@medusajs/framework/utils").ManyToMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint">>;
|
|
75
|
+
}>, "complaint_tag">>;
|
|
76
|
+
activity: import("@medusajs/framework/utils").HasMany<() => import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder</*elided*/ any>, "complaint_activity">>;
|
|
77
|
+
}>, "complaint">, undefined>;
|
|
78
|
+
}>, "complaint_activity">;
|
|
79
|
+
readonly ComplaintProductStat: import("@medusajs/framework/utils").DmlEntity<import("@medusajs/framework/utils").DMLEntitySchemaBuilder<{
|
|
80
|
+
id: import("@medusajs/framework/utils").PrimaryKeyModifier<string, import("@medusajs/framework/utils").IdProperty>;
|
|
81
|
+
product_id: import("@medusajs/framework/utils").TextProperty;
|
|
82
|
+
total_orders: import("@medusajs/framework/utils").NumberProperty;
|
|
83
|
+
total_complaints: import("@medusajs/framework/utils").NumberProperty;
|
|
84
|
+
complaint_rate: import("@medusajs/framework/utils").FloatProperty;
|
|
85
|
+
last_calculated_at: import("@medusajs/framework/utils").NullableModifier<Date, import("@medusajs/framework/utils").DateTimeProperty>;
|
|
86
|
+
metadata: import("@medusajs/framework/utils").NullableModifier<Record<string, unknown>, import("@medusajs/framework/utils").JSONProperty>;
|
|
87
|
+
}>, "complaint_product_stat">;
|
|
88
|
+
}>>;
|
|
89
|
+
export declare class ComplaintService extends ComplaintService_base {
|
|
90
|
+
protected logger_: Logger;
|
|
91
|
+
constructor(container: {
|
|
92
|
+
logger: Logger;
|
|
93
|
+
}, _options?: any);
|
|
94
|
+
addNote(complaintId: string, userId: string, note: string): Promise<{
|
|
95
|
+
id: string;
|
|
96
|
+
type: ComplaintActivityType;
|
|
97
|
+
user_id: string;
|
|
98
|
+
note: string | null;
|
|
99
|
+
metadata: Record<string, unknown> | null;
|
|
100
|
+
complaint: {
|
|
101
|
+
id: string;
|
|
102
|
+
number: number;
|
|
103
|
+
status: import("./models/complaint").ComplaintStatus;
|
|
104
|
+
description: string;
|
|
105
|
+
customer_id: string;
|
|
106
|
+
order_id: string;
|
|
107
|
+
product_id: string;
|
|
108
|
+
serial_number_id: string | null;
|
|
109
|
+
stock_lot_id: string | null;
|
|
110
|
+
metadata: Record<string, unknown> | null;
|
|
111
|
+
tags: {
|
|
112
|
+
id: string;
|
|
113
|
+
value: string;
|
|
114
|
+
complaints: /*elided*/ any[];
|
|
115
|
+
created_at: Date;
|
|
116
|
+
updated_at: Date;
|
|
117
|
+
deleted_at: Date | null;
|
|
118
|
+
}[];
|
|
119
|
+
activity: /*elided*/ any[];
|
|
120
|
+
created_at: Date;
|
|
121
|
+
updated_at: Date;
|
|
122
|
+
deleted_at: Date | null;
|
|
123
|
+
};
|
|
124
|
+
created_at: Date;
|
|
125
|
+
updated_at: Date;
|
|
126
|
+
deleted_at: Date | null;
|
|
127
|
+
complaint_id: string;
|
|
128
|
+
}>;
|
|
129
|
+
updateNote(noteId: string, note: string): Promise<{
|
|
130
|
+
id: string;
|
|
131
|
+
type: ComplaintActivityType;
|
|
132
|
+
user_id: string;
|
|
133
|
+
note: string | null;
|
|
134
|
+
metadata: Record<string, unknown> | null;
|
|
135
|
+
complaint: {
|
|
136
|
+
id: string;
|
|
137
|
+
number: number;
|
|
138
|
+
status: import("./models/complaint").ComplaintStatus;
|
|
139
|
+
description: string;
|
|
140
|
+
customer_id: string;
|
|
141
|
+
order_id: string;
|
|
142
|
+
product_id: string;
|
|
143
|
+
serial_number_id: string | null;
|
|
144
|
+
stock_lot_id: string | null;
|
|
145
|
+
metadata: Record<string, unknown> | null;
|
|
146
|
+
tags: {
|
|
147
|
+
id: string;
|
|
148
|
+
value: string;
|
|
149
|
+
complaints: /*elided*/ any[];
|
|
150
|
+
created_at: Date;
|
|
151
|
+
updated_at: Date;
|
|
152
|
+
deleted_at: Date | null;
|
|
153
|
+
}[];
|
|
154
|
+
activity: /*elided*/ any[];
|
|
155
|
+
created_at: Date;
|
|
156
|
+
updated_at: Date;
|
|
157
|
+
deleted_at: Date | null;
|
|
158
|
+
};
|
|
159
|
+
created_at: Date;
|
|
160
|
+
updated_at: Date;
|
|
161
|
+
deleted_at: Date | null;
|
|
162
|
+
complaint_id: string;
|
|
163
|
+
}>;
|
|
164
|
+
addCloseEntry(complaintId: string, userId: string): Promise<{
|
|
165
|
+
id: string;
|
|
166
|
+
type: ComplaintActivityType;
|
|
167
|
+
user_id: string;
|
|
168
|
+
note: string | null;
|
|
169
|
+
metadata: Record<string, unknown> | null;
|
|
170
|
+
complaint: {
|
|
171
|
+
id: string;
|
|
172
|
+
number: number;
|
|
173
|
+
status: import("./models/complaint").ComplaintStatus;
|
|
174
|
+
description: string;
|
|
175
|
+
customer_id: string;
|
|
176
|
+
order_id: string;
|
|
177
|
+
product_id: string;
|
|
178
|
+
serial_number_id: string | null;
|
|
179
|
+
stock_lot_id: string | null;
|
|
180
|
+
metadata: Record<string, unknown> | null;
|
|
181
|
+
tags: {
|
|
182
|
+
id: string;
|
|
183
|
+
value: string;
|
|
184
|
+
complaints: /*elided*/ any[];
|
|
185
|
+
created_at: Date;
|
|
186
|
+
updated_at: Date;
|
|
187
|
+
deleted_at: Date | null;
|
|
188
|
+
}[];
|
|
189
|
+
activity: /*elided*/ any[];
|
|
190
|
+
created_at: Date;
|
|
191
|
+
updated_at: Date;
|
|
192
|
+
deleted_at: Date | null;
|
|
193
|
+
};
|
|
194
|
+
created_at: Date;
|
|
195
|
+
updated_at: Date;
|
|
196
|
+
deleted_at: Date | null;
|
|
197
|
+
complaint_id: string;
|
|
198
|
+
}>;
|
|
199
|
+
addOpenEntry(complaintId: string, userId: string): Promise<{
|
|
200
|
+
id: string;
|
|
201
|
+
type: ComplaintActivityType;
|
|
202
|
+
user_id: string;
|
|
203
|
+
note: string | null;
|
|
204
|
+
metadata: Record<string, unknown> | null;
|
|
205
|
+
complaint: {
|
|
206
|
+
id: string;
|
|
207
|
+
number: number;
|
|
208
|
+
status: import("./models/complaint").ComplaintStatus;
|
|
209
|
+
description: string;
|
|
210
|
+
customer_id: string;
|
|
211
|
+
order_id: string;
|
|
212
|
+
product_id: string;
|
|
213
|
+
serial_number_id: string | null;
|
|
214
|
+
stock_lot_id: string | null;
|
|
215
|
+
metadata: Record<string, unknown> | null;
|
|
216
|
+
tags: {
|
|
217
|
+
id: string;
|
|
218
|
+
value: string;
|
|
219
|
+
complaints: /*elided*/ any[];
|
|
220
|
+
created_at: Date;
|
|
221
|
+
updated_at: Date;
|
|
222
|
+
deleted_at: Date | null;
|
|
223
|
+
}[];
|
|
224
|
+
activity: /*elided*/ any[];
|
|
225
|
+
created_at: Date;
|
|
226
|
+
updated_at: Date;
|
|
227
|
+
deleted_at: Date | null;
|
|
228
|
+
};
|
|
229
|
+
created_at: Date;
|
|
230
|
+
updated_at: Date;
|
|
231
|
+
deleted_at: Date | null;
|
|
232
|
+
complaint_id: string;
|
|
233
|
+
}>;
|
|
234
|
+
calculateComplaintRates(orderCountsByProduct: Record<string, number>): Promise<void>;
|
|
235
|
+
}
|
|
236
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ComplaintService = void 0;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const complaint_1 = require("./models/complaint");
|
|
6
|
+
const complaint_tag_1 = require("./models/complaint-tag");
|
|
7
|
+
const complaint_product_stat_1 = require("./models/complaint-product-stat");
|
|
8
|
+
const complaint_activity_1 = require("./models/complaint-activity");
|
|
9
|
+
class ComplaintService extends (0, utils_1.MedusaService)({
|
|
10
|
+
Complaint: complaint_1.Complaint,
|
|
11
|
+
ComplaintTag: complaint_tag_1.ComplaintTag,
|
|
12
|
+
ComplaintActivity: complaint_activity_1.ComplaintActivity,
|
|
13
|
+
ComplaintProductStat: complaint_product_stat_1.ComplaintProductStat
|
|
14
|
+
}) {
|
|
15
|
+
constructor(container, _options) {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.logger_ = container.logger;
|
|
18
|
+
}
|
|
19
|
+
async addNote(complaintId, userId, note) {
|
|
20
|
+
return await this.createComplaintActivities({
|
|
21
|
+
complaint_id: complaintId,
|
|
22
|
+
user_id: userId,
|
|
23
|
+
type: complaint_activity_1.ComplaintActivityType.NOTE,
|
|
24
|
+
note
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
async updateNote(noteId, note) {
|
|
28
|
+
return await this.updateComplaintActivities({
|
|
29
|
+
id: noteId,
|
|
30
|
+
note
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async addCloseEntry(complaintId, userId) {
|
|
34
|
+
return this.createComplaintActivities({
|
|
35
|
+
complaint_id: complaintId,
|
|
36
|
+
user_id: userId,
|
|
37
|
+
type: complaint_activity_1.ComplaintActivityType.CLOSE
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async addOpenEntry(complaintId, userId) {
|
|
41
|
+
return this.createComplaintActivities({
|
|
42
|
+
complaint_id: complaintId,
|
|
43
|
+
user_id: userId,
|
|
44
|
+
type: complaint_activity_1.ComplaintActivityType.OPEN
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
async calculateComplaintRates(orderCountsByProduct) {
|
|
48
|
+
this.logger_.info(`Calculating complaint rates for ${Object.keys(orderCountsByProduct).length} products`);
|
|
49
|
+
const [complaints] = await this.listAndCountComplaints({}, { select: ['id', 'product_id'] });
|
|
50
|
+
const complaintsByProduct = {};
|
|
51
|
+
for (const complaint of complaints) {
|
|
52
|
+
if (!complaint.product_id)
|
|
53
|
+
continue;
|
|
54
|
+
complaintsByProduct[complaint.product_id] =
|
|
55
|
+
(complaintsByProduct[complaint.product_id] || 0) + 1;
|
|
56
|
+
}
|
|
57
|
+
// for (const [productId, complaintCount] of Object.entries(complaintsByProduct)) {
|
|
58
|
+
for (const productId in orderCountsByProduct) {
|
|
59
|
+
const complaintCount = complaintsByProduct[productId] ?? 0;
|
|
60
|
+
const totalOrders = orderCountsByProduct[productId] ?? 0;
|
|
61
|
+
const complaintRate = totalOrders > 0 ? complaintCount / totalOrders : 0;
|
|
62
|
+
const [existing] = await this.listComplaintProductStats({
|
|
63
|
+
product_id: productId
|
|
64
|
+
});
|
|
65
|
+
if (existing) {
|
|
66
|
+
await this.updateComplaintProductStats({
|
|
67
|
+
id: existing.id,
|
|
68
|
+
total_complaints: complaintCount,
|
|
69
|
+
total_orders: totalOrders,
|
|
70
|
+
complaint_rate: complaintRate,
|
|
71
|
+
last_calculated_at: new Date()
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
await this.createComplaintProductStats({
|
|
76
|
+
product_id: productId,
|
|
77
|
+
total_complaints: complaintCount,
|
|
78
|
+
total_orders: totalOrders,
|
|
79
|
+
complaint_rate: complaintRate,
|
|
80
|
+
last_calculated_at: new Date()
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.ComplaintService = ComplaintService;
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL2NvbXBsYWludC9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFEQUF5RDtBQUV6RCxrREFBOEM7QUFDOUMsMERBQXFEO0FBQ3JELDRFQUFzRTtBQUN0RSxvRUFBc0Y7QUFFdEYsTUFBYSxnQkFBaUIsU0FBUSxJQUFBLHFCQUFhLEVBQUM7SUFDbkQsU0FBUyxFQUFULHFCQUFTO0lBQ1QsWUFBWSxFQUFaLDRCQUFZO0lBQ1osaUJBQWlCLEVBQWpCLHNDQUFpQjtJQUNqQixvQkFBb0IsRUFBcEIsNkNBQW9CO0NBQ3BCLENBQUM7SUFHRCxZQUFZLFNBQTZCLEVBQUUsUUFBYztRQUN4RCxLQUFLLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQTtRQUNuQixJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUE7SUFDaEMsQ0FBQztJQUVELEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBbUIsRUFBRSxNQUFjLEVBQUUsSUFBWTtRQUM5RCxPQUFPLE1BQU0sSUFBSSxDQUFDLHlCQUF5QixDQUFDO1lBQzNDLFlBQVksRUFBRSxXQUFXO1lBQ3pCLE9BQU8sRUFBRSxNQUFNO1lBQ2YsSUFBSSxFQUFFLDBDQUFxQixDQUFDLElBQUk7WUFDaEMsSUFBSTtTQUNKLENBQUMsQ0FBQTtJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQWMsRUFBRSxJQUFZO1FBQzVDLE9BQU8sTUFBTSxJQUFJLENBQUMseUJBQXlCLENBQUM7WUFDM0MsRUFBRSxFQUFFLE1BQU07WUFDVixJQUFJO1NBQ0osQ0FBQyxDQUFBO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsV0FBbUIsRUFBRSxNQUFjO1FBQ3RELE9BQU8sSUFBSSxDQUFDLHlCQUF5QixDQUFDO1lBQ3JDLFlBQVksRUFBRSxXQUFXO1lBQ3pCLE9B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
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lacey Pevey
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# medusa-plugin-complaints
|
|
2
|
+
|
|
3
|
+
Complaint management plugin for Medusa v2. Track, tag, and manage customer complaints with activity logging and product-level statistics.
|
|
4
|
+
|
|
5
|
+
[Documentation](https://pevey.com/medusa-plugin-complaints)
|
|
6
|
+
|
|
7
|
+
If you are not familiar with Medusa, you can learn more on [the project web site](https://www.medusajs.com/).
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Full complaint CRUD with open/closed status workflow
|
|
12
|
+
- Tagging system for categorizing complaints
|
|
13
|
+
- Activity tracking
|
|
14
|
+
- Widgets on Order, Customer, and Product detail pages
|
|
15
|
+
- Product-level complaint rate statistics with scheduled recalculation
|
|
16
|
+
|
|
17
|
+
## Background
|
|
18
|
+
|
|
19
|
+
Some regulated industries require companies to formally log complaints. This plugin allows you to do that within your Medusa admin dashboard. Complaints can be initiated from order pages with customer and order prefilled. Complaint activity (closing complaints, adding notes) is recorded by Medusa user id. Optionally allows creating tags and assigning tags to complaints to facilitate data analysis. Complaint statistics by product are generated daily via a scheduled job.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
Inside your medusa backend root folder:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
yarn add medusa-plugin-complaints
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Replace "yarn add" with the correct command for your package manager if you are using (for example) npm, pnpm, or bun.
|
|
30
|
+
|
|
31
|
+
## Configuration
|
|
32
|
+
|
|
33
|
+
Enable in your `medusa-config.ts` file. Example:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
module.exports = defineConfig({
|
|
37
|
+
//... other config
|
|
38
|
+
plugins: [
|
|
39
|
+
{
|
|
40
|
+
resolve: 'medusa-plugin-complaints',
|
|
41
|
+
options: {}
|
|
42
|
+
}
|
|
43
|
+
// ... other plugins
|
|
44
|
+
]
|
|
45
|
+
})
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
To ensure complaints cannot be queried in GET requests to the API, add 'complaint' to your restricted fields in `medusa-config.ts`.
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
module.exports = defineConfig({
|
|
52
|
+
projectConfig: {
|
|
53
|
+
// ... other settings
|
|
54
|
+
http: {
|
|
55
|
+
// ... other settings
|
|
56
|
+
restrictedFields: {
|
|
57
|
+
store: ['complaint']
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Usage
|
|
65
|
+
|
|
66
|
+
- Create and manage complaints from the Complaints section in the Medusa admin sidebar.
|
|
67
|
+
- Define complaint tags in Settings > Complaint Tags.
|
|
68
|
+
- Widgets on Order, Customer, and Product pages show related complaints at a glance.
|
|
69
|
+
- Product complaint statistics are recalculated daily via a scheduled job.
|