shuttlepro-shared 1.5.30 → 1.5.31

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.
@@ -38,3 +38,48 @@ exports.DYNAMIC_FIELD_TYPES = [
38
38
  "colour",
39
39
  "file",
40
40
  ];
41
+
42
+ // --- Feedback-style chatbots -------------------------------------------------
43
+ // "zero-slip-bot" is a behavioural replica of "feedback-bot": same question /
44
+ // answer flow, same FeedbackBot collection, same report screen. It differs only
45
+ // in how its runs are bucketed in the Feedback Bot Report, and in that it is
46
+ // workflow-only (no Shop/QR entry point).
47
+ //
48
+ // Anything asking "does this chatbot run the feedback question flow?" must go
49
+ // through isFeedbackStyleBot() rather than comparing against FEEDBACK_BOT_TYPE
50
+ // directly, otherwise the zero slip bot silently loses that behaviour.
51
+ const FEEDBACK_BOT_TYPE = "feedback-bot";
52
+ const ZERO_SLIP_BOT_TYPE = "zero-slip-bot";
53
+ const FEEDBACK_STYLE_BOT_TYPES = [FEEDBACK_BOT_TYPE, ZERO_SLIP_BOT_TYPE];
54
+
55
+ exports.FEEDBACK_BOT_TYPE = FEEDBACK_BOT_TYPE;
56
+ exports.ZERO_SLIP_BOT_TYPE = ZERO_SLIP_BOT_TYPE;
57
+ exports.FEEDBACK_STYLE_BOT_TYPES = FEEDBACK_STYLE_BOT_TYPES;
58
+ exports.isFeedbackStyleBot = (type) => FEEDBACK_STYLE_BOT_TYPES.includes(type);
59
+
60
+ // Redis keys are namespaced per bot type so a feedback bot and a zero slip bot
61
+ // can be pending/active for the same phone number at the same time without
62
+ // clobbering each other. The feedback bot keeps its original un-namespaced keys
63
+ // so sessions already live in Redis when this ships keep working.
64
+ exports.getChatbotEnabledRedisKey = (
65
+ phoneNumber,
66
+ botType = FEEDBACK_BOT_TYPE
67
+ ) =>
68
+ botType === FEEDBACK_BOT_TYPE
69
+ ? `feedback-chatbot-enabled:${phoneNumber}`
70
+ : `feedback-chatbot-enabled:${botType}:${phoneNumber}`;
71
+
72
+ exports.getFeedbackSessionRedisKey = (
73
+ phoneNumber,
74
+ orderId,
75
+ botType = FEEDBACK_BOT_TYPE
76
+ ) =>
77
+ botType === FEEDBACK_BOT_TYPE
78
+ ? `feedback-bot:${phoneNumber}:${orderId}`
79
+ : `${botType}:${phoneNumber}:${orderId}`;
80
+
81
+ // FeedbackBot rows written before `botType` existed are feedback-bot runs. In
82
+ // MongoDB `null` also matches documents where the field is missing, so this
83
+ // query covers legacy rows without a backfill.
84
+ exports.getBotTypeQuery = (botType = FEEDBACK_BOT_TYPE) =>
85
+ botType === FEEDBACK_BOT_TYPE ? { $in: [FEEDBACK_BOT_TYPE, null] } : botType;
package/models/Chatbot.js CHANGED
@@ -20,7 +20,7 @@ const ChatbotSchema = new Schema(
20
20
  },
21
21
  type: {
22
22
  type: String,
23
- enum: ["chatbot", "agent", "interactive", "feedback-bot"],
23
+ enum: ["chatbot", "agent", "interactive", "feedback-bot", "zero-slip-bot"],
24
24
  default: "chatbot",
25
25
  },
26
26
  interactiveId: {
@@ -85,6 +85,15 @@ const FeedbackBotSchema = new Schema(
85
85
  enum: ["shop", "workflow"],
86
86
  default: null,
87
87
  },
88
+ // Which flavour of feedback-style chatbot produced this run. Rows written
89
+ // before this field existed are feedback-bot runs, so queries must treat a
90
+ // missing/null value as "feedback-bot" (see getBotTypeQuery in
91
+ // shuttlepro-shared/constants).
92
+ botType: {
93
+ type: String,
94
+ enum: ["feedback-bot", "zero-slip-bot"],
95
+ default: "feedback-bot",
96
+ },
88
97
  },
89
98
  { timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } }
90
99
  );
@@ -94,8 +103,12 @@ FeedbackBotSchema.index({ workspaceId: 1, phoneNumber: 1, createdAt: -1 });
94
103
  FeedbackBotSchema.index({ conversationId: 1 });
95
104
  FeedbackBotSchema.index({ chatbotId: 1 });
96
105
  FeedbackBotSchema.index({ status: 1 });
97
- // Index for order_id based queries (allows multiple feedback per conversation)
98
- FeedbackBotSchema.index({ workspaceId: 1, phoneNumber: 1, orderId: 1 });
106
+ // Index for order_id based queries (allows multiple feedback per conversation).
107
+ // botType is part of the key because a feedback bot and a zero slip bot can both
108
+ // run against the same phone + order.
109
+ FeedbackBotSchema.index({ workspaceId: 1, phoneNumber: 1, orderId: 1, botType: 1 });
110
+ // Report screen filters by workspace + bot type, newest first.
111
+ FeedbackBotSchema.index({ workspaceId: 1, botType: 1, createdAt: -1 });
99
112
 
100
113
  module.exports = FeedbackBotSchema;
101
114
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shuttlepro-shared",
3
- "version": "1.5.30",
3
+ "version": "1.5.31",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {