joye-backend-utility 7.2.13 → 7.3.1

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.
@@ -0,0 +1,6 @@
1
+ /** Inner hash range per platform segment (each segment has 1000 slots). */
2
+ export declare const BUCKET_SEGMENT_SPAN = 1000;
3
+ /** Deterministic value in `0 .. modulus-1` (default segment span 1000). */
4
+ export declare function stableBucketFromEmployeeId(employeeId: string, modulus?: number): number;
5
+ /** Stored bucket = segment base + inner hash in `[0, BUCKET_SEGMENT_SPAN)`. */
6
+ export declare function notificationBucketFromSegmentBase(employeeId: string, segmentBase: number): number;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.notificationBucketFromSegmentBase = exports.stableBucketFromEmployeeId = exports.BUCKET_SEGMENT_SPAN = void 0;
4
+ const crypto_1 = require("crypto");
5
+ /** Inner hash range per platform segment (each segment has 1000 slots). */
6
+ exports.BUCKET_SEGMENT_SPAN = 1000;
7
+ /** Deterministic value in `0 .. modulus-1` (default segment span 1000). */
8
+ function stableBucketFromEmployeeId(employeeId, modulus = exports.BUCKET_SEGMENT_SPAN) {
9
+ const m = Math.max(2, Math.floor(modulus));
10
+ const h = crypto_1.default.createHash('sha256').update(employeeId, 'utf8').digest();
11
+ return h.readUInt32BE(0) % m;
12
+ }
13
+ exports.stableBucketFromEmployeeId = stableBucketFromEmployeeId;
14
+ /** Stored bucket = segment base + inner hash in `[0, BUCKET_SEGMENT_SPAN)`. */
15
+ function notificationBucketFromSegmentBase(employeeId, segmentBase) {
16
+ return segmentBase + stableBucketFromEmployeeId(employeeId, exports.BUCKET_SEGMENT_SPAN);
17
+ }
18
+ exports.notificationBucketFromSegmentBase = notificationBucketFromSegmentBase;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Platform → segment base (added before `hash(employeeId) % 1000` for stored `User.bucket`).
3
+ *
4
+ * Only platforms listed in **`DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM`** get a `bucket`.
5
+ * Keys are matched **case-insensitively** to `Organization.platformKey`. Anything else → no bucket.
6
+ */
7
+ /** Edit this object only — add one entry per platform that should participate in notification sharding. */
8
+ export declare const DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM: Record<string, number>;
9
+ export declare function getBucketSegmentMapping(): Record<string, number>;
10
+ export declare function segmentBaseForPlatformKey(orgPlatformKey: string, mapping: Record<string, number>): number | null;
11
+ /** Segment base if `platformKey` is in the map; otherwise `null` (do not set `User.bucket`). */
12
+ export declare function resolveBucketSegmentBase(orgPlatformKey: string): number | null;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * Platform → segment base (added before `hash(employeeId) % 1000` for stored `User.bucket`).
4
+ *
5
+ * Only platforms listed in **`DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM`** get a `bucket`.
6
+ * Keys are matched **case-insensitively** to `Organization.platformKey`. Anything else → no bucket.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.resolveBucketSegmentBase = exports.segmentBaseForPlatformKey = exports.getBucketSegmentMapping = exports.DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM = void 0;
10
+ /** Edit this object only — add one entry per platform that should participate in notification sharding. */
11
+ exports.DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM = {
12
+ teams: 0,
13
+ visit: 1000,
14
+ medibuddy: 3000,
15
+ };
16
+ function lowercaseKeys(map) {
17
+ const out = {};
18
+ for (const [k, v] of Object.entries(map)) {
19
+ if (typeof v === 'number' && Number.isFinite(v) && v >= 0) {
20
+ out[k.toLowerCase()] = v;
21
+ }
22
+ }
23
+ return out;
24
+ }
25
+ const BUCKET_SEGMENT_MAPPING = lowercaseKeys(Object.assign({}, exports.DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM));
26
+ function getBucketSegmentMapping() {
27
+ return BUCKET_SEGMENT_MAPPING;
28
+ }
29
+ exports.getBucketSegmentMapping = getBucketSegmentMapping;
30
+ function segmentBaseForPlatformKey(orgPlatformKey, mapping) {
31
+ const k = String(orgPlatformKey || '')
32
+ .trim()
33
+ .toLowerCase();
34
+ if (!k)
35
+ return null;
36
+ if (Object.prototype.hasOwnProperty.call(mapping, k))
37
+ return mapping[k];
38
+ return null;
39
+ }
40
+ exports.segmentBaseForPlatformKey = segmentBaseForPlatformKey;
41
+ /** Segment base if `platformKey` is in the map; otherwise `null` (do not set `User.bucket`). */
42
+ function resolveBucketSegmentBase(orgPlatformKey) {
43
+ return segmentBaseForPlatformKey(orgPlatformKey, getBucketSegmentMapping());
44
+ }
45
+ exports.resolveBucketSegmentBase = resolveBucketSegmentBase;
package/dist/index.d.ts CHANGED
@@ -4,3 +4,5 @@ export { createHashPassword, createUuid } from './util';
4
4
  export { createToken, jwtVerify } from './jwt';
5
5
  export { getPreviousWorkday, get2ndLastPreviousWorkday, addDays, addMinutes, addYears, getCurrentDateTime, getCurrentUtcTime, newDate, getDatesBetweenRange, getMoment, getCurrentEpoch, } from './dateTime';
6
6
  export { RedisClient } from './redisClient';
7
+ export { DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM, getBucketSegmentMapping, segmentBaseForPlatformKey, resolveBucketSegmentBase, } from './config/notificationBucketSegmentRules';
8
+ export { BUCKET_SEGMENT_SPAN, stableBucketFromEmployeeId, notificationBucketFromSegmentBase } from './config/notificationBucket';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RedisClient = exports.getCurrentEpoch = exports.getMoment = exports.getDatesBetweenRange = exports.newDate = exports.getCurrentUtcTime = exports.getCurrentDateTime = exports.addYears = exports.addMinutes = exports.addDays = exports.get2ndLastPreviousWorkday = exports.getPreviousWorkday = exports.jwtVerify = exports.createToken = exports.createUuid = exports.createHashPassword = void 0;
3
+ exports.notificationBucketFromSegmentBase = exports.stableBucketFromEmployeeId = exports.BUCKET_SEGMENT_SPAN = exports.resolveBucketSegmentBase = exports.segmentBaseForPlatformKey = exports.getBucketSegmentMapping = exports.DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM = exports.RedisClient = exports.getCurrentEpoch = exports.getMoment = exports.getDatesBetweenRange = exports.newDate = exports.getCurrentUtcTime = exports.getCurrentDateTime = exports.addYears = exports.addMinutes = exports.addDays = exports.get2ndLastPreviousWorkday = exports.getPreviousWorkday = exports.jwtVerify = exports.createToken = exports.createUuid = exports.createHashPassword = void 0;
4
4
  const database_1 = require("./database");
5
5
  exports.default = database_1.default;
6
6
  var util_1 = require("./util");
@@ -24,3 +24,12 @@ Object.defineProperty(exports, "getMoment", { enumerable: true, get: function ()
24
24
  Object.defineProperty(exports, "getCurrentEpoch", { enumerable: true, get: function () { return dateTime_1.getCurrentEpoch; } });
25
25
  var redisClient_1 = require("./redisClient");
26
26
  Object.defineProperty(exports, "RedisClient", { enumerable: true, get: function () { return redisClient_1.RedisClient; } });
27
+ var notificationBucketSegmentRules_1 = require("./config/notificationBucketSegmentRules");
28
+ Object.defineProperty(exports, "DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM", { enumerable: true, get: function () { return notificationBucketSegmentRules_1.DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM; } });
29
+ Object.defineProperty(exports, "getBucketSegmentMapping", { enumerable: true, get: function () { return notificationBucketSegmentRules_1.getBucketSegmentMapping; } });
30
+ Object.defineProperty(exports, "segmentBaseForPlatformKey", { enumerable: true, get: function () { return notificationBucketSegmentRules_1.segmentBaseForPlatformKey; } });
31
+ Object.defineProperty(exports, "resolveBucketSegmentBase", { enumerable: true, get: function () { return notificationBucketSegmentRules_1.resolveBucketSegmentBase; } });
32
+ var notificationBucket_1 = require("./config/notificationBucket");
33
+ Object.defineProperty(exports, "BUCKET_SEGMENT_SPAN", { enumerable: true, get: function () { return notificationBucket_1.BUCKET_SEGMENT_SPAN; } });
34
+ Object.defineProperty(exports, "stableBucketFromEmployeeId", { enumerable: true, get: function () { return notificationBucket_1.stableBucketFromEmployeeId; } });
35
+ Object.defineProperty(exports, "notificationBucketFromSegmentBase", { enumerable: true, get: function () { return notificationBucket_1.notificationBucketFromSegmentBase; } });
@@ -79,5 +79,20 @@ const MasterTraining = new mongoose_1.Schema({
79
79
  default: '',
80
80
  index: true,
81
81
  },
82
+ dailyWelcome: {
83
+ type: String,
84
+ required: false,
85
+ default: '',
86
+ },
87
+ weeklyWelcome: {
88
+ type: String,
89
+ required: false,
90
+ default: '',
91
+ },
92
+ monthlyWelcome: {
93
+ type: String,
94
+ required: false,
95
+ default: '',
96
+ },
82
97
  });
83
98
  exports.MasterTrainingSchema = MasterTraining;
@@ -26,6 +26,11 @@ const MasterTrainingDays = new mongoose_1.Schema({
26
26
  type: String,
27
27
  required: false,
28
28
  },
29
+ welcomeMessage: {
30
+ type: String,
31
+ required: false,
32
+ default: '',
33
+ },
29
34
  });
30
35
  MasterTrainingDays.index({ trainingKey: 1, day: 1 });
31
36
  exports.MasterTrainingDaysSchema = MasterTrainingDays;
@@ -205,6 +205,16 @@ const User = new mongoose_1.Schema({
205
205
  type: Array,
206
206
  required: false,
207
207
  },
208
+ /**
209
+ * Stable shard index: segment base from `DEFAULT_BUCKET_SEGMENT_BASE_BY_PLATFORM` + hash(employeeId)%1000; see BUCKET_SHARDING.md.
210
+ * Schedulers filter `bucket` in [BUCKET_MIN, BUCKET_MAX]; omit field for platforms without notification sharding.
211
+ */
212
+ bucket: {
213
+ type: Number,
214
+ required: false,
215
+ min: 0,
216
+ index: true,
217
+ },
208
218
  });
209
219
  User.index({ employeeId: 1 }, {
210
220
  unique: true,
@@ -218,4 +228,7 @@ User.index({ organizationId: 1, botDetails: -1 }, {
218
228
  User.index({ botDetails: 1, organizationId: -1, preferredTimezone: -1 }, {
219
229
  unique: false,
220
230
  });
231
+ User.index({ bucket: 1, botDetails: 1 }, {
232
+ unique: false,
233
+ });
221
234
  exports.UserSchema = User;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "joye-backend-utility",
3
- "version": "7.2.13",
3
+ "version": "7.3.1",
4
4
  "description": "Joye backend utility for db functions and common functions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",