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.
Files changed (67) hide show
  1. package/.medusa/server/medusa-config.d.ts +1 -0
  2. package/.medusa/server/medusa-config.js +23 -0
  3. package/.medusa/server/src/admin/index.js +8633 -0
  4. package/.medusa/server/src/admin/index.mjs +8631 -0
  5. package/.medusa/server/src/api/admin/complaint-stats/products/[id]/route.d.ts +3 -0
  6. package/.medusa/server/src/api/admin/complaint-stats/products/[id]/route.js +21 -0
  7. package/.medusa/server/src/api/admin/complaint-stats/recalculate/route.d.ts +2 -0
  8. package/.medusa/server/src/api/admin/complaint-stats/recalculate/route.js +40 -0
  9. package/.medusa/server/src/api/admin/complaint-stats/route.d.ts +1 -0
  10. package/.medusa/server/src/api/admin/complaint-stats/route.js +16 -0
  11. package/.medusa/server/src/api/admin/complaint-tags/[id]/route.d.ts +5 -0
  12. package/.medusa/server/src/api/admin/complaint-tags/[id]/route.js +34 -0
  13. package/.medusa/server/src/api/admin/complaint-tags/route.d.ts +5 -0
  14. package/.medusa/server/src/api/admin/complaint-tags/route.js +37 -0
  15. package/.medusa/server/src/api/admin/complaints/[id]/activities/[entryId]/route.d.ts +5 -0
  16. package/.medusa/server/src/api/admin/complaints/[id]/activities/[entryId]/route.js +35 -0
  17. package/.medusa/server/src/api/admin/complaints/[id]/activities/route.d.ts +5 -0
  18. package/.medusa/server/src/api/admin/complaints/[id]/activities/route.js +43 -0
  19. package/.medusa/server/src/api/admin/complaints/[id]/notes/[noteId]/route.d.ts +4 -0
  20. package/.medusa/server/src/api/admin/complaints/[id]/notes/[noteId]/route.js +20 -0
  21. package/.medusa/server/src/api/admin/complaints/[id]/notes/route.d.ts +3 -0
  22. package/.medusa/server/src/api/admin/complaints/[id]/notes/route.js +12 -0
  23. package/.medusa/server/src/api/admin/complaints/[id]/route.d.ts +5 -0
  24. package/.medusa/server/src/api/admin/complaints/[id]/route.js +43 -0
  25. package/.medusa/server/src/api/admin/complaints/route.d.ts +5 -0
  26. package/.medusa/server/src/api/admin/complaints/route.js +48 -0
  27. package/.medusa/server/src/api/middlewares.d.ts +2 -0
  28. package/.medusa/server/src/api/middlewares.js +150 -0
  29. package/.medusa/server/src/api/validators.d.ts +547 -0
  30. package/.medusa/server/src/api/validators.js +215 -0
  31. package/.medusa/server/src/jobs/update-complaint-stats.d.ts +6 -0
  32. package/.medusa/server/src/jobs/update-complaint-stats.js +50 -0
  33. package/.medusa/server/src/links/complaint-activity-user.d.ts +2 -0
  34. package/.medusa/server/src/links/complaint-activity-user.js +15 -0
  35. package/.medusa/server/src/links/complaint-customer.d.ts +2 -0
  36. package/.medusa/server/src/links/complaint-customer.js +15 -0
  37. package/.medusa/server/src/links/complaint-order.d.ts +2 -0
  38. package/.medusa/server/src/links/complaint-order.js +15 -0
  39. package/.medusa/server/src/links/complaint-product.d.ts +2 -0
  40. package/.medusa/server/src/links/complaint-product.js +15 -0
  41. package/.medusa/server/src/links/customer-complaint.d.ts +2 -0
  42. package/.medusa/server/src/links/customer-complaint.js +18 -0
  43. package/.medusa/server/src/links/order-complaint.d.ts +2 -0
  44. package/.medusa/server/src/links/order-complaint.js +18 -0
  45. package/.medusa/server/src/links/product-complaint.d.ts +2 -0
  46. package/.medusa/server/src/links/product-complaint.js +18 -0
  47. package/.medusa/server/src/links/user-complaint-activity.d.ts +2 -0
  48. package/.medusa/server/src/links/user-complaint-activity.js +18 -0
  49. package/.medusa/server/src/modules/complaint/index.d.ts +64 -0
  50. package/.medusa/server/src/modules/complaint/index.js +25 -0
  51. package/.medusa/server/src/modules/complaint/migrations/Migration20260409171742.d.ts +5 -0
  52. package/.medusa/server/src/modules/complaint/migrations/Migration20260409171742.js +36 -0
  53. package/.medusa/server/src/modules/complaint/models/complaint-activity.d.ts +30 -0
  54. package/.medusa/server/src/modules/complaint/models/complaint-activity.js +22 -0
  55. package/.medusa/server/src/modules/complaint/models/complaint-product-stat.d.ts +9 -0
  56. package/.medusa/server/src/modules/complaint/models/complaint-product-stat.js +15 -0
  57. package/.medusa/server/src/modules/complaint/models/complaint-stat.d.ts +1 -0
  58. package/.medusa/server/src/modules/complaint/models/complaint-stat.js +8 -0
  59. package/.medusa/server/src/modules/complaint/models/complaint-tag.d.ts +25 -0
  60. package/.medusa/server/src/modules/complaint/models/complaint-tag.js +11 -0
  61. package/.medusa/server/src/modules/complaint/models/complaint.d.ts +29 -0
  62. package/.medusa/server/src/modules/complaint/models/complaint.js +32 -0
  63. package/.medusa/server/src/modules/complaint/service.d.ts +236 -0
  64. package/.medusa/server/src/modules/complaint/service.js +87 -0
  65. package/LICENSE +21 -0
  66. package/README.md +69 -0
  67. 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,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.