@itleanchatbot/shared-models-js-postgres 3.0.0 → 3.0.2

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,7 +1,7 @@
1
1
  [
2
2
  {
3
- "alias": "leanbot-1",
4
- "name": "IT Lean Tech LTDA",
5
- "cnpj": "12.082.645/0001-08"
3
+ "alias": "leanbot-volks",
4
+ "name": "Volkswagen Brasil",
5
+ "cnpj": "59.104.422/0001-50"
6
6
  }
7
7
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itleanchatbot/shared-models-js-postgres",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Shared Models JS Postgres",
5
5
  "main": "index.js",
6
6
  "license": "ISC",
@@ -0,0 +1,14 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ up: async (queryInterface, _) => {
5
+ await queryInterface.addIndex('Attendances', {
6
+ name: 'leanbot_attendances_07',
7
+ fields: ['EnterpriseId', 'LineId', 'status', 'createdAt']
8
+ })
9
+ },
10
+
11
+ down: async (queryInterface, _) => {
12
+ await queryInterface.removeIndex('Attendances', 'leanbot_attendances_07')
13
+ },
14
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Índices adicionados para fins de performance do processo de inatividade
3
+ */
4
+
5
+ 'use strict'
6
+
7
+ module.exports = {
8
+ up: async (queryInterface, _) => {
9
+ await queryInterface.addIndex('ConversationSessions', {
10
+ name: 'leanbot_conversationSessions_04',
11
+ fields: ['ClientId', 'createdAt']
12
+ })
13
+
14
+ await queryInterface.addIndex('InactivityTriggers', {
15
+ name: 'leanbot_inactivityTriggers_03',
16
+ fields: ['SkillId', 'order']
17
+ })
18
+
19
+ await queryInterface.addIndex('Sessions', {
20
+ name: 'leanbot_sessions_03',
21
+ fields: ['status', 'tranship', 'createdAt']
22
+ })
23
+
24
+ await queryInterface.addIndex('Channels', {
25
+ name: 'leanbot_channels_05',
26
+ fields: ['deletedAt', 'id']
27
+ })
28
+ },
29
+
30
+ down: async (queryInterface, _) => {
31
+
32
+ await queryInterface.removeIndex('Channels', 'leanbot_channels_05')
33
+
34
+ await queryInterface.removeIndex('Sessions', 'leanbot_sessions_03')
35
+
36
+ await queryInterface.removeIndex('InactivityTriggers', 'leanbot_inactivityTriggers_03')
37
+
38
+ await queryInterface.removeIndex('ConversationSessions', 'leanbot_conversationSessions_04')
39
+ },
40
+ }
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Função modificada para fins de performance
3
+ */
4
+
5
+ 'use strict'
6
+
7
+ module.exports = {
8
+ up: async (queryInterface, _) => {
9
+
10
+ await queryInterface.sequelize.query(
11
+ `
12
+ CREATE OR REPLACE FUNCTION get_inactive_sessions(first_call boolean, records_per_page int, starter_page int, maximun int, current_page int DEFAULT 1)
13
+ RETURNS TABLE ("id" uuid) AS $$
14
+ declare r RECORD;
15
+ declare last_iterable "BotIterables"%ROWTYPE;
16
+ declare min_diff INT;
17
+ declare counter INT := 0;
18
+ BEGIN
19
+
20
+ IF ((records_per_page * current_page) > maximun) THEN
21
+ RETURN;
22
+ END IF;
23
+
24
+ IF (first_call) THEN
25
+ DROP TABLE IF EXISTS _tmp_get_inactive_sessions;
26
+ CREATE TEMPORARY TABLE _tmp_get_inactive_sessions (
27
+ "id" uuid
28
+ );
29
+ END IF;
30
+
31
+ FOR r IN (
32
+ select distinct
33
+ "Sessions"."id",
34
+ "Sessions"."EnterpriseId",
35
+ "InactivityTriggers"."min",
36
+ "Sessions"."createdAt"
37
+ from "Sessions"
38
+ inner join "Clients"
39
+ on "Clients"."id" = "Sessions"."ClientId"
40
+ inner join "ConversationSessions"
41
+ on "ConversationSessions"."ClientId" = "Clients"."id"
42
+ and age(current_timestamp, "ConversationSessions"."createdAt") < interval '24 hours'
43
+ inner join "Channels"
44
+ on "Channels"."id" = "Sessions"."ChannelId"
45
+ and "Channels"."deletedAt" is null
46
+ inner join "InactivityTriggers"
47
+ on "InactivityTriggers"."SkillId" = "Channels"."SkillId"
48
+ and "InactivityTriggers"."order" = "Sessions"."inactivityCounter"
49
+ where "Sessions"."status" = 'open'
50
+ and "Sessions"."tranship" = false
51
+ order by "Sessions"."createdAt"
52
+ limit records_per_page
53
+ offset ((starter_page - 1)*records_per_page)
54
+ ) LOOP
55
+
56
+ select * into last_iterable
57
+ from "BotIterables"
58
+ where "BotIterables"."EnterpriseId" = r."EnterpriseId"
59
+ and "BotIterables"."SessionId" = r."id"
60
+ order by "BotIterables"."createdAt" DESC
61
+ limit 1;
62
+
63
+ min_diff := (
64
+ (SELECT DATE_PART('day', current_timestamp - last_iterable."createdAt") * 24 * 60) +
65
+ (SELECT DATE_PART('hour', current_timestamp - last_iterable."createdAt") * 60) +
66
+ (SELECT DATE_PART('minute', current_timestamp - last_iterable."createdAt"))
67
+ );
68
+
69
+ IF (last_iterable."action" = 'bot' and min_diff >= r."min") THEN
70
+
71
+ INSERT INTO _tmp_get_inactive_sessions ("id")
72
+ VALUES (r."id");
73
+
74
+ END IF;
75
+
76
+ counter := counter + 1;
77
+
78
+ END LOOP;
79
+
80
+ IF (counter = records_per_page) THEN
81
+ PERFORM get_inactive_sessions(false, records_per_page, starter_page + 1, maximun, current_page + 1);
82
+ END IF;
83
+
84
+ RETURN QUERY
85
+ SELECT * FROM _tmp_get_inactive_sessions;
86
+
87
+ END;
88
+ $$ LANGUAGE plpgsql;
89
+ `
90
+ )
91
+ },
92
+
93
+ down: async (queryInterface, _) => {
94
+
95
+ await queryInterface.sequelize.query(
96
+ `
97
+ CREATE OR REPLACE FUNCTION get_inactive_sessions(first_call boolean, records_per_page int, starter_page int, maximun int, current_page int DEFAULT 1)
98
+ RETURNS TABLE ("id" uuid) AS $$
99
+ declare r RECORD;
100
+ declare last_iterable "BotIterables"%ROWTYPE;
101
+ declare min_diff INT;
102
+ declare counter INT := 0;
103
+ BEGIN
104
+
105
+ IF ((records_per_page * current_page) > maximun) THEN
106
+ RETURN;
107
+ END IF;
108
+
109
+ IF (first_call) THEN
110
+ DROP TABLE IF EXISTS _tmp_get_inactive_sessions;
111
+ CREATE TEMPORARY TABLE _tmp_get_inactive_sessions (
112
+ "id" uuid
113
+ );
114
+ END IF;
115
+
116
+ FOR r IN (
117
+ select distinct
118
+ "Sessions"."id",
119
+ "InactivityTriggers"."min",
120
+ "Sessions"."createdAt"
121
+ from "Sessions"
122
+ inner join "Clients"
123
+ on "Clients"."id" = "Sessions"."ClientId"
124
+ inner join "ConversationSessions"
125
+ on "ConversationSessions"."ClientId" = "Clients"."id"
126
+ and age(current_timestamp, "ConversationSessions"."createdAt") < interval '24 hours'
127
+ inner join "Channels"
128
+ on "Channels"."id" = "Sessions"."ChannelId"
129
+ inner join "InactivityTriggers"
130
+ on "InactivityTriggers"."SkillId" = "Channels"."SkillId"
131
+ and "InactivityTriggers"."order" = "Sessions"."inactivityCounter"
132
+ where "Sessions"."status" = 'open'
133
+ and "Sessions"."tranship" = false
134
+ and "Channels"."deletedAt" is null
135
+ order by "Sessions"."createdAt"
136
+ limit records_per_page
137
+ offset ((starter_page - 1)*records_per_page)
138
+ ) LOOP
139
+
140
+ select * into last_iterable
141
+ from "BotIterables"
142
+ where "BotIterables"."SessionId" = r."id"
143
+ order by "BotIterables"."createdAt" DESC
144
+ limit 1;
145
+
146
+ min_diff := (
147
+ (SELECT DATE_PART('day', current_timestamp - last_iterable."createdAt") * 24 * 60) +
148
+ (SELECT DATE_PART('hour', current_timestamp - last_iterable."createdAt") * 60) +
149
+ (SELECT DATE_PART('minute', current_timestamp - last_iterable."createdAt"))
150
+ );
151
+
152
+ IF (last_iterable."action" = 'bot' and min_diff >= r."min") THEN
153
+
154
+ INSERT INTO _tmp_get_inactive_sessions ("id")
155
+ VALUES (r."id");
156
+
157
+ END IF;
158
+
159
+ counter := counter + 1;
160
+
161
+ END LOOP;
162
+
163
+ IF (counter = records_per_page) THEN
164
+ PERFORM get_inactive_sessions(false, records_per_page, starter_page + 1, maximun, current_page + 1);
165
+ END IF;
166
+
167
+ RETURN QUERY
168
+ SELECT * FROM _tmp_get_inactive_sessions;
169
+
170
+ END;
171
+ $$ LANGUAGE plpgsql;
172
+ `
173
+ )
174
+ },
175
+ }
@@ -0,0 +1,176 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ up: async (queryInterface, _) => {
5
+
6
+ await queryInterface.sequelize.query(
7
+ `
8
+ CREATE OR REPLACE FUNCTION get_inactive_attendances(first_call boolean, records_per_page int, starter_page int, maximun int, current_page int DEFAULT 1)
9
+ RETURNS TABLE ("id" uuid) AS $$
10
+ declare r RECORD;
11
+ declare last_iterable "TranshipConversations"%ROWTYPE;
12
+ declare min_diff INT;
13
+ declare counter INT := 0;
14
+ BEGIN
15
+
16
+ IF ((records_per_page * current_page) > maximun) THEN
17
+ RETURN;
18
+ END IF;
19
+
20
+ IF (first_call) THEN
21
+ DROP TABLE IF EXISTS _tmp_get_inactive_attendances;
22
+ CREATE TEMPORARY TABLE _tmp_get_inactive_attendances (
23
+ "id" uuid
24
+ );
25
+ END IF;
26
+
27
+ FOR r IN (
28
+ select distinct
29
+ "Sessions"."id",
30
+ "Sessions"."EnterpriseId",
31
+ "Attendances"."id" as "AttendanceId",
32
+ "TranshipInactivityTriggers"."min",
33
+ "Sessions"."createdAt"
34
+ from "Sessions"
35
+ inner join "Clients"
36
+ on "Clients"."id" = "Sessions"."ClientId"
37
+ inner join "ConversationSessions"
38
+ on "ConversationSessions"."ClientId" = "Clients"."id"
39
+ and age(current_timestamp, "ConversationSessions"."createdAt") < interval '24 hours'
40
+ inner join "Channels"
41
+ on "Channels"."id" = "Sessions"."ChannelId"
42
+ and "Channels"."deletedAt" is null
43
+ inner join "Attendances"
44
+ on "Attendances"."SessionId" = "Sessions"."id"
45
+ and "Attendances"."status" = 'started'
46
+ inner join "TranshipInactivityTriggers"
47
+ on "Attendances"."LineId" = "TranshipInactivityTriggers"."LineId"
48
+ and "TranshipInactivityTriggers"."order" = "Attendances"."inactivityCounter"
49
+ where "Sessions"."tranship" = true
50
+ and "Sessions"."status" = 'open'
51
+ order by "Sessions"."createdAt"
52
+ limit records_per_page
53
+ offset ((starter_page - 1)*records_per_page)
54
+ ) LOOP
55
+
56
+ select * into last_iterable
57
+ from "TranshipConversations"
58
+ where "TranshipConversations"."EnterpriseId" = r."EnterpriseId"
59
+ and "TranshipConversations"."AttendanceId" = r."AttendanceId"
60
+ order by "TranshipConversations"."createdAt" DESC
61
+ limit 1;
62
+
63
+ min_diff := (
64
+ (SELECT DATE_PART('day', current_timestamp - last_iterable."createdAt") * 24 * 60) +
65
+ (SELECT DATE_PART('hour', current_timestamp - last_iterable."createdAt") * 60) +
66
+ (SELECT DATE_PART('minute', current_timestamp - last_iterable."createdAt"))
67
+ );
68
+
69
+ IF (last_iterable."action" = 'tranship' and min_diff >= r."min") THEN
70
+
71
+ INSERT INTO _tmp_get_inactive_attendances ("id")
72
+ VALUES (r."id");
73
+
74
+ END IF;
75
+
76
+ counter := counter + 1;
77
+
78
+ END LOOP;
79
+
80
+ IF (counter = records_per_page) THEN
81
+ PERFORM get_inactive_attendances(false, records_per_page, starter_page + 1, maximun, current_page + 1);
82
+ END IF;
83
+
84
+ RETURN QUERY
85
+ SELECT * FROM _tmp_get_inactive_attendances;
86
+
87
+ END;
88
+ $$ LANGUAGE plpgsql;
89
+ `
90
+ )
91
+ },
92
+
93
+ down: async (queryInterface, _) => {
94
+
95
+ await queryInterface.sequelize.query(
96
+ `
97
+ CREATE OR REPLACE FUNCTION get_inactive_attendances(first_call boolean, records_per_page int, starter_page int, maximun int, current_page int DEFAULT 1)
98
+ RETURNS TABLE ("id" uuid) AS $$
99
+ declare r RECORD;
100
+ declare last_iterable "TranshipConversations"%ROWTYPE;
101
+ declare min_diff INT;
102
+ declare counter INT := 0;
103
+ BEGIN
104
+
105
+ IF ((records_per_page * current_page) > maximun) THEN
106
+ RETURN;
107
+ END IF;
108
+
109
+ IF (first_call) THEN
110
+ DROP TABLE IF EXISTS _tmp_get_inactive_attendances;
111
+ CREATE TEMPORARY TABLE _tmp_get_inactive_attendances (
112
+ "id" uuid
113
+ );
114
+ END IF;
115
+
116
+ FOR r IN (
117
+ select distinct
118
+ "Sessions"."id",
119
+ "Attendances"."id" as "AttendanceId",
120
+ "TranshipInactivityTriggers"."min",
121
+ "Sessions"."createdAt"
122
+ from "Sessions"
123
+ inner join "Clients"
124
+ on "Clients"."id" = "Sessions"."ClientId"
125
+ inner join "ConversationSessions"
126
+ on "ConversationSessions"."ClientId" = "Clients"."id"
127
+ and age(current_timestamp, "ConversationSessions"."createdAt") < interval '24 hours'
128
+ inner join "Attendances"
129
+ on "Attendances"."SessionId" = "Sessions"."id"
130
+ and "Attendances"."status" = 'started'
131
+ inner join "TranshipInactivityTriggers"
132
+ on "Attendances"."LineId" = "TranshipInactivityTriggers"."LineId"
133
+ and "TranshipInactivityTriggers"."order" = "Attendances"."inactivityCounter"
134
+ where "Sessions"."tranship" = true
135
+ and "Sessions"."status" = 'open'
136
+ order by "Sessions"."createdAt"
137
+ limit records_per_page
138
+ offset ((starter_page - 1)*records_per_page)
139
+ ) LOOP
140
+
141
+ select * into last_iterable
142
+ from "TranshipConversations"
143
+ where "TranshipConversations"."AttendanceId" = r."AttendanceId"
144
+ order by "TranshipConversations"."createdAt" DESC
145
+ limit 1;
146
+
147
+ min_diff := (
148
+ (SELECT DATE_PART('day', current_timestamp - last_iterable."createdAt") * 24 * 60) +
149
+ (SELECT DATE_PART('hour', current_timestamp - last_iterable."createdAt") * 60) +
150
+ (SELECT DATE_PART('minute', current_timestamp - last_iterable."createdAt"))
151
+ );
152
+
153
+ IF (last_iterable."action" = 'tranship' and min_diff >= r."min") THEN
154
+
155
+ INSERT INTO _tmp_get_inactive_attendances ("id")
156
+ VALUES (r."id");
157
+
158
+ END IF;
159
+
160
+ counter := counter + 1;
161
+
162
+ END LOOP;
163
+
164
+ IF (counter = records_per_page) THEN
165
+ PERFORM get_inactive_attendances(false, records_per_page, starter_page + 1, maximun, current_page + 1);
166
+ END IF;
167
+
168
+ RETURN QUERY
169
+ SELECT * FROM _tmp_get_inactive_attendances;
170
+
171
+ END;
172
+ $$ LANGUAGE plpgsql;
173
+ `
174
+ )
175
+ },
176
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Índices adicionados para fins de performance do processo de inatividade
3
+ */
4
+
5
+ 'use strict'
6
+
7
+ module.exports = {
8
+ up: async (queryInterface, _) => {
9
+ await queryInterface.addIndex('Attendances', {
10
+ name: 'leanbot_attendances_08',
11
+ fields: ['SessionId', 'status']
12
+ })
13
+
14
+ await queryInterface.addIndex('TranshipInactivityTriggers', {
15
+ name: 'leanbot_transhipInactivityTriggers_02',
16
+ fields: ['LineId', 'order']
17
+ })
18
+ },
19
+
20
+ down: async (queryInterface, _) => {
21
+
22
+ await queryInterface.removeIndex('TranshipInactivityTriggers', 'leanbot_transhipInactivityTriggers_02')
23
+
24
+ await queryInterface.removeIndex('Attendances', 'leanbot_attendances_08')
25
+ },
26
+ }
27
+
@@ -6,7 +6,11 @@ const { argv } = require('process')
6
6
 
7
7
  const minDateArg = argv[2]
8
8
  const maxDateArg = argv[3]
9
- const oldDatabaseNameArg = argv[4]
9
+ const oldDatabaseNameArg = argv[4]
10
+
11
+ const hostaddr = process.env.DATABASE_HOST
12
+ const user = process.env.DB_USERNAME
13
+ const password = process.env.DB_PASSWORD
10
14
 
11
15
  function getDatabaseConfig(databaseName) {
12
16
  return {
@@ -57,7 +61,7 @@ function runQuery(sequelize, date, EnterpriseId) {
57
61
  )
58
62
  select *
59
63
  from dblink(
60
- 'dbname=${oldDatabaseNameArg}',
64
+ 'user=${user} password=${password} dbname=${oldDatabaseNameArg}',
61
65
  'select ''${EnterpriseId}'',
62
66
  "id",
63
67
  "SessionId",
@@ -0,0 +1,151 @@
1
+ require('dotenv/config')
2
+ const moment = require('moment')
3
+ const Sequelize = require('sequelize')
4
+
5
+ const { argv } = require('process')
6
+
7
+ const minDateArg = argv[2]
8
+ const maxDateArg = argv[3]
9
+ const oldDatabaseNameArg = argv[4]
10
+
11
+ const hostaddr = process.env.DATABASE_HOST
12
+ const user = process.env.DB_USERNAME
13
+ const password = process.env.DB_PASSWORD
14
+
15
+ function getDatabaseConfig(databaseName) {
16
+ return {
17
+ username: process.env.DB_USERNAME,
18
+ password: process.env.DB_PASSWORD,
19
+ database: databaseName,
20
+ host: process.env.DATABASE_HOST,
21
+ dialect: process.env.DATABASE_TYPE,
22
+ logging: false,
23
+ omitNull: true,
24
+ minifyAliases: true,
25
+ timezone: process.env.DATABASE_TIMEZONE || 'Etc/UTC',
26
+ pool: {
27
+ max: 100,
28
+ min: 0,
29
+ idle: 10000,
30
+ },
31
+ }
32
+ }
33
+
34
+ function runQuery(sequelize, date, EnterpriseId) {
35
+ return sequelize.query(
36
+ `insert into "Clients" (
37
+ "EnterpriseId",
38
+ "id",
39
+ "clientId",
40
+ "serverId",
41
+ "createdAt",
42
+ "updatedAt"
43
+ )
44
+ select *
45
+ from dblink(
46
+ 'user=${user} password=${password} dbname=${oldDatabaseNameArg}',
47
+ 'select ''${EnterpriseId}'',
48
+ "id",
49
+ "clientId",
50
+ "serverId",
51
+ "createdAt",
52
+ "updatedAt"
53
+ from "Clients"
54
+ where cast("createdAt" as date) = ''${date.format('YYYY-MM-DD')}'''
55
+ ) as linktable
56
+ (
57
+ "EnterpriseId" uuid,
58
+ "id" uuid,
59
+ "clientId" varchar(255),
60
+ "serverId" varchar(255),
61
+ "createdAt" timestamp with time zone,
62
+ "updatedAt" timestamp with time zone
63
+ )`
64
+ )
65
+ }
66
+
67
+ async function migrateBotIterables() {
68
+
69
+ const oldConfig = getDatabaseConfig(oldDatabaseNameArg)
70
+ const oldDatabase = new Sequelize(
71
+ oldConfig.database,
72
+ oldConfig.username,
73
+ oldConfig.password,
74
+ oldConfig
75
+ )
76
+
77
+ const oldEnterpriseModel = require('../legacy/models/enterprises').model(oldDatabase, Sequelize.DataTypes)
78
+ const { id: EnterpriseId } = await oldEnterpriseModel.findOne()
79
+
80
+ const dataInicial = moment(minDateArg, 'YYYY-MM-DD')
81
+ const dataFinalStr = moment(maxDateArg, 'YYYY-MM-DD').format('YYYY-MM-DD')
82
+
83
+ const config = getDatabaseConfig(process.env.DATABASE_NAME)
84
+
85
+ const newDatabase = new Sequelize(
86
+ config.database,
87
+ config.username,
88
+ config.password,
89
+ config
90
+ )
91
+
92
+ while (dataInicial.format('YYYY-MM-DD') <= dataFinalStr) {
93
+
94
+ console.log(`MIGRANDO DATA: ${dataInicial.format('YYYY-MM-DD')}`)
95
+
96
+ await runQuery(newDatabase, dataInicial, EnterpriseId)
97
+
98
+ dataInicial.add(1, 'days')
99
+ }
100
+
101
+ console.log('finalizado')
102
+ }
103
+
104
+ function executeValidationSequence(readline, sequence, callback, index = 0) {
105
+ readline.question(`${sequence[index]} (y/n): `, resp => {
106
+
107
+ if (resp.toLowerCase() == 'y') {
108
+
109
+ if (index == sequence.length - 1) {
110
+ readline.close()
111
+ callback()
112
+ }
113
+ else executeValidationSequence(readline, sequence, callback, ++index)
114
+
115
+ } else if (resp.toLowerCase() == 'n') {
116
+
117
+ console.log('\nEste processo será encerrado. Reinicie-o após a regularização das configurações\n')
118
+ readline.close()
119
+ process.exit()
120
+
121
+ } else {
122
+
123
+ console.log('\nResponsta inválida!')
124
+ executeValidationSequence(readline, sequence, callback, index)
125
+ }
126
+ })
127
+ }
128
+
129
+ const validationSequence = [
130
+ `\nEste processo foi iniciado à partir do diretório: ${process.cwd()}\nEstá correto?`,
131
+ '\nO arquivo .env foi criado e está correto?',
132
+ `\nA origem desta migração será executada no host ${process.env.DATABASE_HOST}, database ${oldDatabaseNameArg}. Está correto?`,
133
+ `\nO destino desta migração será executada no host ${process.env.DATABASE_HOST}, database ${process.env.DATABASE_NAME}. Está correto?`,
134
+ `\nSerão migrados somente os dados da tabela "Clients" de ${minDateArg} à ${maxDateArg}. Está correto?`
135
+ ]
136
+
137
+ async function main() {
138
+
139
+ if (minDateArg > maxDateArg) return console.log('Data inicial deve ser inferior ou igual à Data final.')
140
+
141
+ const readline = require('readline').createInterface({
142
+ input: process.stdin,
143
+ output: process.stdout
144
+ })
145
+
146
+ console.log('\n*** Antes de iniciar o processo de migração, confirme os dados solicitados abaixo. ***\n')
147
+
148
+ executeValidationSequence(readline, validationSequence, migrateBotIterables)
149
+ }
150
+
151
+ main()