@app-connect/core 1.7.29 → 1.7.30

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.
@@ -1,21 +1,60 @@
1
1
  const { Op } = require('sequelize');
2
2
  const { CacheModel } = require('../models/cacheModel');
3
+ const { AccountDataModel } = require('../models/accountDataModel');
3
4
  const logger = require('./logger');
4
5
 
6
+ const ACCOUNT_CONTACT_DATA_KEY_PATTERN = 'contact-%';
7
+ const ACCOUNT_CONTACT_DATA_RETENTION_MONTHS = 3;
8
+
5
9
  async function clearExpiredCache({ now = new Date() } = {}) {
6
- const deletedCount = await CacheModel.destroy({
10
+ const cacheDeletedCount = await clearExpiredCacheRows({ now });
11
+ const accountContactDataDeletedCount = await clearExpiredAccountContactData({ now });
12
+ const deletedCount = cacheDeletedCount + accountContactDataDeletedCount;
13
+
14
+ logger.info('Expired cache cleanup completed', {
15
+ deletedCount,
16
+ cacheDeletedCount,
17
+ accountContactDataDeletedCount
18
+ });
19
+
20
+ return deletedCount;
21
+ }
22
+
23
+ function getAccountContactDataCutoffDate({ now, retentionMonths }) {
24
+ const cutoffDate = new Date(now.getTime());
25
+ cutoffDate.setMonth(cutoffDate.getMonth() - retentionMonths);
26
+ return cutoffDate;
27
+ }
28
+
29
+ async function clearExpiredCacheRows({ now }) {
30
+ return CacheModel.destroy({
7
31
  where: {
8
32
  expiry: {
9
33
  [Op.lte]: now
10
34
  }
11
35
  }
12
36
  });
37
+ }
13
38
 
14
- logger.info('Expired cache cleanup completed', { deletedCount });
39
+ async function clearExpiredAccountContactData({
40
+ now = new Date(),
41
+ retentionMonths = ACCOUNT_CONTACT_DATA_RETENTION_MONTHS
42
+ } = {}) {
43
+ const cutoffDate = getAccountContactDataCutoffDate({ now, retentionMonths });
15
44
 
16
- return deletedCount;
45
+ return AccountDataModel.destroy({
46
+ where: {
47
+ dataKey: {
48
+ [Op.like]: ACCOUNT_CONTACT_DATA_KEY_PATTERN
49
+ },
50
+ createdAt: {
51
+ [Op.lt]: cutoffDate
52
+ }
53
+ }
54
+ });
17
55
  }
18
56
 
19
57
  module.exports = {
58
+ clearExpiredAccountContactData,
20
59
  clearExpiredCache
21
60
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@app-connect/core",
3
- "version": "1.7.29",
3
+ "version": "1.7.30",
4
4
  "description": "RingCentral App Connect Core",
5
5
  "main": "index.js",
6
6
  "repository": {
package/releaseNotes.json CHANGED
@@ -1,4 +1,16 @@
1
1
  {
2
+ "1.7.30": {
3
+ "global": [
4
+ {
5
+ "type": "Fix",
6
+ "description": "Shared SMS for sites"
7
+ },
8
+ {
9
+ "type": "Fix",
10
+ "description": "Conditional rendering of contact association fields"
11
+ }
12
+ ]
13
+ },
2
14
  "1.7.29": {
3
15
  "global": [
4
16
  {
@@ -1,9 +1,11 @@
1
1
  const { CacheModel } = require('../../models/cacheModel');
2
- const { clearExpiredCache } = require('../../lib/cacheCleanup');
2
+ const { AccountDataModel } = require('../../models/accountDataModel');
3
+ const { clearExpiredAccountContactData, clearExpiredCache } = require('../../lib/cacheCleanup');
3
4
 
4
5
  describe('cacheCleanup', () => {
5
6
  beforeEach(async () => {
6
7
  await CacheModel.destroy({ where: {} });
8
+ await AccountDataModel.destroy({ where: {} });
7
9
  });
8
10
 
9
11
  test('deletes only cache records whose expiry has passed', async () => {
@@ -39,4 +41,87 @@ describe('cacheCleanup', () => {
39
41
  expect(await CacheModel.findByPk('active-cache')).not.toBeNull();
40
42
  expect(await CacheModel.findByPk('cache-without-expiry')).not.toBeNull();
41
43
  });
44
+
45
+ test('deletes only account contact data older than three months', async () => {
46
+ const now = new Date('2026-06-08T00:00:00.000Z');
47
+
48
+ await AccountDataModel.bulkCreate([
49
+ {
50
+ rcAccountId: 'account-1',
51
+ platformName: 'test-platform',
52
+ dataKey: 'contact-+1111111111',
53
+ data: [{ id: 'old-contact' }],
54
+ createdAt: new Date('2026-03-07T23:59:59.000Z'),
55
+ updatedAt: new Date('2026-03-07T23:59:59.000Z')
56
+ },
57
+ {
58
+ rcAccountId: 'account-1',
59
+ platformName: 'test-platform',
60
+ dataKey: 'contact-+2222222222',
61
+ data: [{ id: 'exact-cutoff-contact' }],
62
+ createdAt: new Date('2026-03-08T00:00:00.000Z'),
63
+ updatedAt: new Date('2026-03-08T00:00:00.000Z')
64
+ },
65
+ {
66
+ rcAccountId: 'account-1',
67
+ platformName: 'test-platform',
68
+ dataKey: 'contact-+3333333333',
69
+ data: [{ id: 'active-contact' }],
70
+ createdAt: new Date('2026-03-08T00:00:01.000Z'),
71
+ updatedAt: new Date('2026-03-08T00:00:01.000Z')
72
+ },
73
+ {
74
+ rcAccountId: 'account-1',
75
+ platformName: 'test-platform',
76
+ dataKey: 'pluginData',
77
+ data: { jwtToken: 'plugin-token' },
78
+ createdAt: new Date('2026-03-07T23:59:59.000Z'),
79
+ updatedAt: new Date('2026-03-07T23:59:59.000Z')
80
+ }
81
+ ]);
82
+
83
+ const deletedCount = await clearExpiredAccountContactData({ now });
84
+
85
+ expect(deletedCount).toBe(1);
86
+ expect(await AccountDataModel.findOne({
87
+ where: { rcAccountId: 'account-1', platformName: 'test-platform', dataKey: 'contact-+1111111111' }
88
+ })).toBeNull();
89
+ expect(await AccountDataModel.findOne({
90
+ where: { rcAccountId: 'account-1', platformName: 'test-platform', dataKey: 'contact-+2222222222' }
91
+ })).not.toBeNull();
92
+ expect(await AccountDataModel.findOne({
93
+ where: { rcAccountId: 'account-1', platformName: 'test-platform', dataKey: 'contact-+3333333333' }
94
+ })).not.toBeNull();
95
+ expect(await AccountDataModel.findOne({
96
+ where: { rcAccountId: 'account-1', platformName: 'test-platform', dataKey: 'pluginData' }
97
+ })).not.toBeNull();
98
+ });
99
+
100
+ test('clearExpiredCache includes expired account contact data cleanup', async () => {
101
+ const now = new Date('2026-06-08T00:00:00.000Z');
102
+
103
+ await CacheModel.create({
104
+ id: 'expired-cache',
105
+ userId: 'user-1',
106
+ cacheKey: 'auth-session',
107
+ status: 'expired',
108
+ expiry: new Date('2026-06-07T23:59:59.000Z')
109
+ });
110
+ await AccountDataModel.create({
111
+ rcAccountId: 'account-1',
112
+ platformName: 'test-platform',
113
+ dataKey: 'contact-+1111111111',
114
+ data: [{ id: 'old-contact' }],
115
+ createdAt: new Date('2026-03-07T23:59:59.000Z'),
116
+ updatedAt: new Date('2026-03-07T23:59:59.000Z')
117
+ });
118
+
119
+ const deletedCount = await clearExpiredCache({ now });
120
+
121
+ expect(deletedCount).toBe(2);
122
+ expect(await CacheModel.findByPk('expired-cache')).toBeNull();
123
+ expect(await AccountDataModel.findOne({
124
+ where: { rcAccountId: 'account-1', platformName: 'test-platform', dataKey: 'contact-+1111111111' }
125
+ })).toBeNull();
126
+ });
42
127
  });