@javalabs/prisma-client 1.0.27 → 1.0.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.
Files changed (168) hide show
  1. package/.github/CODEOWNERS +1 -1
  2. package/README.md +269 -269
  3. package/dist/index.d.ts +7 -0
  4. package/dist/index.js +34 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/prisma-factory.service.d.ts +9 -0
  7. package/dist/prisma-factory.service.js +47 -0
  8. package/dist/prisma-factory.service.js.map +1 -0
  9. package/dist/prisma.module.d.ts +2 -0
  10. package/dist/prisma.module.js +23 -0
  11. package/dist/prisma.module.js.map +1 -0
  12. package/dist/prisma.service.d.ts +6 -0
  13. package/dist/prisma.service.js +27 -0
  14. package/dist/prisma.service.js.map +1 -0
  15. package/dist/scripts/add-uuid-to-table.d.ts +8 -0
  16. package/dist/scripts/add-uuid-to-table.js +98 -0
  17. package/dist/scripts/add-uuid-to-table.js.map +1 -0
  18. package/dist/scripts/create-tenant-schemas.d.ts +1 -0
  19. package/dist/scripts/create-tenant-schemas.js +117 -0
  20. package/dist/scripts/create-tenant-schemas.js.map +1 -0
  21. package/dist/scripts/data-migration/batch-migrator.d.ts +20 -0
  22. package/dist/scripts/data-migration/batch-migrator.js +134 -0
  23. package/dist/scripts/data-migration/batch-migrator.js.map +1 -0
  24. package/dist/scripts/data-migration/data-transformer.d.ts +26 -0
  25. package/dist/scripts/data-migration/data-transformer.js +278 -0
  26. package/dist/scripts/data-migration/data-transformer.js.map +1 -0
  27. package/dist/scripts/data-migration/db-connector.d.ts +12 -0
  28. package/dist/scripts/data-migration/db-connector.js +94 -0
  29. package/dist/scripts/data-migration/db-connector.js.map +1 -0
  30. package/dist/scripts/data-migration/dependency-resolver.d.ts +18 -0
  31. package/dist/scripts/data-migration/dependency-resolver.js +132 -0
  32. package/dist/scripts/data-migration/dependency-resolver.js.map +1 -0
  33. package/dist/scripts/data-migration/entity-discovery.d.ts +11 -0
  34. package/dist/scripts/data-migration/entity-discovery.js +152 -0
  35. package/dist/scripts/data-migration/entity-discovery.js.map +1 -0
  36. package/dist/scripts/data-migration/foreign-key-manager.d.ts +18 -0
  37. package/dist/scripts/data-migration/foreign-key-manager.js +160 -0
  38. package/dist/scripts/data-migration/foreign-key-manager.js.map +1 -0
  39. package/dist/scripts/data-migration/migration-tool.d.ts +48 -0
  40. package/dist/scripts/data-migration/migration-tool.js +290 -0
  41. package/dist/scripts/data-migration/migration-tool.js.map +1 -0
  42. package/dist/scripts/data-migration/schema-utils.d.ts +18 -0
  43. package/dist/scripts/data-migration/schema-utils.js +207 -0
  44. package/dist/scripts/data-migration/schema-utils.js.map +1 -0
  45. package/dist/scripts/data-migration/tenant-migrator.d.ts +15 -0
  46. package/dist/scripts/data-migration/tenant-migrator.js +117 -0
  47. package/dist/scripts/data-migration/tenant-migrator.js.map +1 -0
  48. package/dist/scripts/data-migration/typecast-manager.d.ts +9 -0
  49. package/dist/scripts/data-migration/typecast-manager.js +179 -0
  50. package/dist/scripts/data-migration/typecast-manager.js.map +1 -0
  51. package/dist/scripts/data-migration/types.d.ts +100 -0
  52. package/dist/scripts/data-migration/types.js +3 -0
  53. package/dist/scripts/data-migration/types.js.map +1 -0
  54. package/dist/scripts/database-initializer.d.ts +5 -0
  55. package/dist/scripts/database-initializer.js +45 -0
  56. package/dist/scripts/database-initializer.js.map +1 -0
  57. package/dist/scripts/drop-database.d.ts +10 -0
  58. package/dist/scripts/drop-database.js +81 -0
  59. package/dist/scripts/drop-database.js.map +1 -0
  60. package/dist/scripts/encrypt-user-passwords.d.ts +1 -0
  61. package/dist/scripts/encrypt-user-passwords.js +33 -0
  62. package/dist/scripts/encrypt-user-passwords.js.map +1 -0
  63. package/dist/scripts/error-handler.d.ts +12 -0
  64. package/dist/scripts/error-handler.js +82 -0
  65. package/dist/scripts/error-handler.js.map +1 -0
  66. package/dist/scripts/fix-data-types.d.ts +10 -0
  67. package/dist/scripts/fix-data-types.js +185 -0
  68. package/dist/scripts/fix-data-types.js.map +1 -0
  69. package/dist/scripts/fix-enum-values.d.ts +17 -0
  70. package/dist/scripts/fix-enum-values.js +234 -0
  71. package/dist/scripts/fix-enum-values.js.map +1 -0
  72. package/dist/scripts/fix-schema-discrepancies.d.ts +21 -0
  73. package/dist/scripts/fix-schema-discrepancies.js +240 -0
  74. package/dist/scripts/fix-schema-discrepancies.js.map +1 -0
  75. package/dist/scripts/fix-table-indexes.d.ts +26 -0
  76. package/dist/scripts/fix-table-indexes.js +460 -0
  77. package/dist/scripts/fix-table-indexes.js.map +1 -0
  78. package/dist/scripts/migrate-schema-structure.d.ts +1 -0
  79. package/dist/scripts/migrate-schema-structure.js +76 -0
  80. package/dist/scripts/migrate-schema-structure.js.map +1 -0
  81. package/dist/scripts/migrate-uuid.d.ts +2 -0
  82. package/dist/scripts/migrate-uuid.js +57 -0
  83. package/dist/scripts/migrate-uuid.js.map +1 -0
  84. package/dist/scripts/post-migration-validator.d.ts +34 -0
  85. package/dist/scripts/post-migration-validator.js +363 -0
  86. package/dist/scripts/post-migration-validator.js.map +1 -0
  87. package/dist/scripts/pre-migration-validator.d.ts +25 -0
  88. package/dist/scripts/pre-migration-validator.js +491 -0
  89. package/dist/scripts/pre-migration-validator.js.map +1 -0
  90. package/dist/scripts/reset-database.d.ts +17 -0
  91. package/dist/scripts/reset-database.js +202 -0
  92. package/dist/scripts/reset-database.js.map +1 -0
  93. package/dist/scripts/retry-failed-migrations.d.ts +14 -0
  94. package/dist/scripts/retry-failed-migrations.js +301 -0
  95. package/dist/scripts/retry-failed-migrations.js.map +1 -0
  96. package/dist/scripts/run-migration.d.ts +1 -0
  97. package/dist/scripts/run-migration.js +512 -0
  98. package/dist/scripts/run-migration.js.map +1 -0
  99. package/dist/scripts/schema-sync.d.ts +1 -0
  100. package/dist/scripts/schema-sync.js +85 -0
  101. package/dist/scripts/schema-sync.js.map +1 -0
  102. package/dist/scripts/sequence-sync-cli.d.ts +2 -0
  103. package/dist/scripts/sequence-sync-cli.js +287 -0
  104. package/dist/scripts/sequence-sync-cli.js.map +1 -0
  105. package/dist/scripts/sequence-synchronizer.d.ts +8 -0
  106. package/dist/scripts/sequence-synchronizer.js +88 -0
  107. package/dist/scripts/sequence-synchronizer.js.map +1 -0
  108. package/dist/scripts/sync-enum-types.d.ts +13 -0
  109. package/dist/scripts/sync-enum-types.js +139 -0
  110. package/dist/scripts/sync-enum-types.js.map +1 -0
  111. package/dist/scripts/sync-enum-values.d.ts +20 -0
  112. package/dist/scripts/sync-enum-values.js +336 -0
  113. package/dist/scripts/sync-enum-values.js.map +1 -0
  114. package/dist/scripts/truncate-database.d.ts +10 -0
  115. package/dist/scripts/truncate-database.js +100 -0
  116. package/dist/scripts/truncate-database.js.map +1 -0
  117. package/dist/scripts/verify-migration-setup.d.ts +11 -0
  118. package/dist/scripts/verify-migration-setup.js +120 -0
  119. package/dist/scripts/verify-migration-setup.js.map +1 -0
  120. package/dist/tsconfig.tsbuildinfo +1 -0
  121. package/migration-config.json +63 -63
  122. package/migration-config.json.bk +95 -95
  123. package/migrations/add_reserved_amount.sql +7 -7
  124. package/package.json +44 -44
  125. package/prisma/migrations/add_uuid_to_transactions.sql +13 -13
  126. package/prisma/schema.prisma +609 -601
  127. package/src/index.ts +23 -23
  128. package/src/prisma-factory.service.ts +40 -40
  129. package/src/prisma.module.ts +9 -9
  130. package/src/prisma.service.ts +16 -16
  131. package/src/scripts/add-uuid-to-table.ts +138 -138
  132. package/src/scripts/create-tenant-schemas.ts +145 -145
  133. package/src/scripts/data-migration/batch-migrator.ts +248 -248
  134. package/src/scripts/data-migration/data-transformer.ts +426 -426
  135. package/src/scripts/data-migration/db-connector.ts +120 -120
  136. package/src/scripts/data-migration/dependency-resolver.ts +174 -174
  137. package/src/scripts/data-migration/entity-discovery.ts +196 -196
  138. package/src/scripts/data-migration/foreign-key-manager.ts +277 -277
  139. package/src/scripts/data-migration/migration-config.json +63 -63
  140. package/src/scripts/data-migration/migration-tool.ts +509 -509
  141. package/src/scripts/data-migration/schema-utils.ts +248 -248
  142. package/src/scripts/data-migration/tenant-migrator.ts +201 -201
  143. package/src/scripts/data-migration/typecast-manager.ts +193 -193
  144. package/src/scripts/data-migration/types.ts +113 -113
  145. package/src/scripts/database-initializer.ts +49 -49
  146. package/src/scripts/drop-database.ts +104 -104
  147. package/src/scripts/dump-source-db.sh +61 -61
  148. package/src/scripts/encrypt-user-passwords.ts +36 -36
  149. package/src/scripts/error-handler.ts +117 -117
  150. package/src/scripts/fix-data-types.ts +241 -241
  151. package/src/scripts/fix-enum-values.ts +357 -357
  152. package/src/scripts/fix-schema-discrepancies.ts +317 -317
  153. package/src/scripts/fix-table-indexes.ts +601 -601
  154. package/src/scripts/migrate-schema-structure.ts +90 -90
  155. package/src/scripts/migrate-uuid.ts +76 -76
  156. package/src/scripts/post-migration-validator.ts +526 -526
  157. package/src/scripts/pre-migration-validator.ts +610 -610
  158. package/src/scripts/reset-database.ts +263 -263
  159. package/src/scripts/retry-failed-migrations.ts +416 -416
  160. package/src/scripts/run-migration.ts +707 -707
  161. package/src/scripts/schema-sync.ts +128 -128
  162. package/src/scripts/sequence-sync-cli.ts +416 -416
  163. package/src/scripts/sequence-synchronizer.ts +127 -127
  164. package/src/scripts/sync-enum-types.ts +170 -170
  165. package/src/scripts/sync-enum-values.ts +563 -563
  166. package/src/scripts/truncate-database.ts +123 -123
  167. package/src/scripts/verify-migration-setup.ts +135 -135
  168. package/tsconfig.json +17 -17
@@ -1,277 +1,277 @@
1
- import { Logger } from "@nestjs/common";
2
- import { PrismaClient } from "@prisma/client";
3
- import { DatabaseConnections } from "./types";
4
-
5
- export class ForeignKeyManager {
6
- private readonly logger = new Logger("ForeignKeyManager");
7
- private readonly dependencyCache: Map<string, any[]> = new Map();
8
-
9
- constructor(private readonly connections: DatabaseConnections) {}
10
-
11
- async getForeignKeyDependencies(
12
- schemaName: string,
13
- tableName: string
14
- ): Promise<
15
- Array<{ column: string; foreignTable: string; foreignColumn: string }>
16
- > {
17
- const cacheKey = `${schemaName}.${tableName}`;
18
- if (this.dependencyCache.has(cacheKey)) {
19
- return this.dependencyCache.get(cacheKey);
20
- }
21
-
22
- try {
23
- this.logger.log(
24
- `Obteniendo dependencias de llaves foráneas para ${schemaName}.${tableName}`
25
- );
26
- const query = `
27
- SELECT
28
- kcu.column_name,
29
- ccu.table_name AS foreign_table_name,
30
- ccu.column_name AS foreign_column_name
31
- FROM
32
- information_schema.table_constraints tc
33
- JOIN information_schema.key_column_usage kcu
34
- ON tc.constraint_name = kcu.constraint_name
35
- AND tc.table_schema = kcu.table_schema
36
- JOIN information_schema.constraint_column_usage ccu
37
- ON ccu.constraint_name = tc.constraint_name
38
- AND ccu.table_schema = tc.table_schema
39
- WHERE
40
- tc.constraint_type = 'FOREIGN KEY'
41
- AND tc.table_schema = $1
42
- AND tc.table_name = $2;
43
- `;
44
-
45
- const { rows } = await this.connections.targetPool.query(query, [
46
- schemaName,
47
- tableName,
48
- ]);
49
-
50
- const dependencies = rows.map((row) => ({
51
- column: row.column_name,
52
- foreignTable: row.foreign_table_name,
53
- foreignColumn: row.foreign_column_name,
54
- }));
55
-
56
- this.logger.log(
57
- `Encontradas ${
58
- dependencies.length
59
- } dependencias para ${schemaName}.${tableName}:
60
- ${dependencies
61
- .map(
62
- (d) => `\n - ${d.column} -> ${d.foreignTable}.${d.foreignColumn}`
63
- )
64
- .join("")}`
65
- );
66
-
67
- this.dependencyCache.set(cacheKey, dependencies);
68
- return dependencies;
69
- } catch (error) {
70
- this.logger.error(
71
- `Error obteniendo dependencias de ${schemaName}.${tableName}: ${error.message}`
72
- );
73
- return [];
74
- }
75
- }
76
-
77
- async checkForeignKeyDependencies(
78
- prisma: PrismaClient,
79
- tenantId: string,
80
- record: any,
81
- dependencies: any[]
82
- ): Promise<string[]> {
83
- const missingDependencies: string[] = [];
84
- const recordId = record.id || "unknown";
85
-
86
- this.logger.debug(
87
- `Verificando dependencias para registro ${recordId} en tenant ${tenantId}`
88
- );
89
-
90
- for (const dep of dependencies) {
91
- const { table, column, references } = dep;
92
- const foreignKeyValue = record[column];
93
-
94
- if (foreignKeyValue === null) {
95
- this.logger.debug(
96
- `Dependencia ${table}.${references} es nula para registro ${recordId}, continuando`
97
- );
98
- continue;
99
- }
100
-
101
- // Verificar en origen
102
- const sourceExists = await this.checkSourceDependency(
103
- table,
104
- references,
105
- foreignKeyValue
106
- );
107
-
108
- if (!sourceExists) {
109
- this.logger.debug(
110
- `Registro ${recordId}: Dependencia ${table}.${references}=${foreignKeyValue} no existe en origen, ignorando`
111
- );
112
- continue;
113
- }
114
-
115
- // Verificar en destino
116
- const exists = await this.checkDependencyExists(
117
- prisma,
118
- tenantId,
119
- table,
120
- references,
121
- foreignKeyValue
122
- );
123
-
124
- if (!exists) {
125
- const depString = `${table}.${references}=${foreignKeyValue}`;
126
- this.logger.debug(
127
- `Registro ${recordId}: Dependencia ${depString} existe en origen pero falta en destino`
128
- );
129
- missingDependencies.push(depString);
130
- } else {
131
- this.logger.debug(
132
- `Registro ${recordId}: Dependencia ${table}.${references}=${foreignKeyValue} verificada OK`
133
- );
134
- }
135
- }
136
-
137
- if (missingDependencies.length > 0) {
138
- this.logger.debug(
139
- `Registro ${recordId}: Faltan ${
140
- missingDependencies.length
141
- } dependencias:
142
- ${missingDependencies.map((dep) => `\n - ${dep}`).join("")}`
143
- );
144
- } else {
145
- this.logger.debug(`Registro ${recordId}: Todas las dependencias OK`);
146
- }
147
-
148
- return missingDependencies;
149
- }
150
-
151
- private async checkSourceDependency(
152
- table: string,
153
- column: string,
154
- value: any
155
- ): Promise<boolean> {
156
- try {
157
- const result = await this.connections.sourcePool.query(
158
- `SELECT 1 FROM "${table}" WHERE "${column}" = $1 LIMIT 1`,
159
- [value]
160
- );
161
- const exists = result.rows.length > 0;
162
- this.logger.debug(
163
- `Verificación en origen ${table}.${column}=${value}: ${
164
- exists ? "EXISTE" : "NO EXISTE"
165
- }`
166
- );
167
- return exists;
168
- } catch (error) {
169
- this.logger.error(
170
- `Error verificando en origen ${table}.${column}=${value}: ${error.message}`
171
- );
172
- return false;
173
- }
174
- }
175
-
176
- private async checkDependencyExists(
177
- prisma: PrismaClient,
178
- tenantId: string,
179
- table: string,
180
- column: string,
181
- value: any
182
- ): Promise<boolean> {
183
- try {
184
- const result = await prisma.$queryRawUnsafe(
185
- `SELECT 1 FROM "${tenantId}"."${table}" WHERE "${column}" = $1 LIMIT 1`,
186
- value
187
- );
188
- const exists = Array.isArray(result) && result.length > 0;
189
- this.logger.debug(
190
- `Verificación en destino ${tenantId}.${table}.${column}=${value}: ${
191
- exists ? "EXISTE" : "NO EXISTE"
192
- }`
193
- );
194
- return exists;
195
- } catch (error) {
196
- this.logger.error(
197
- `Error verificando en destino ${tenantId}.${table}.${column}=${value}: ${error.message}`
198
- );
199
- return false;
200
- }
201
- }
202
-
203
- async verifyDependencies(
204
- tableName: string,
205
- record: any,
206
- tenantId: string
207
- ): Promise<boolean> {
208
- try {
209
- const dependencies = await this.getForeignKeyDependencies(
210
- tableName,
211
- tableName
212
- );
213
-
214
- for (const dep of dependencies) {
215
- const { foreignTable, foreignColumn } = dep;
216
-
217
- // Verificar si la tabla existe antes de hacer la consulta
218
- const tableExists = await this.checkTableExists(foreignTable);
219
- if (!tableExists) {
220
- this.logger.warn(
221
- `Table ${foreignTable} does not exist, skipping dependency check`
222
- );
223
- continue;
224
- }
225
-
226
- // Verificar el valor de la dependencia
227
- const foreignKeyValue = record[foreignColumn];
228
- if (foreignKeyValue) {
229
- const exists = await this.checkDependencyExists(
230
- this.connections.targetPrisma,
231
- tenantId,
232
- foreignTable,
233
- foreignColumn,
234
- foreignKeyValue
235
- );
236
-
237
- if (!exists) {
238
- this.logger.warn(
239
- `Valor ${foreignKeyValue} no existe en ${foreignTable}.${foreignColumn}`
240
- );
241
- return false;
242
- }
243
- }
244
- }
245
-
246
- return true;
247
- } catch (error) {
248
- this.logger.error(`Error verifying dependencies: ${error.message}`);
249
- return false;
250
- }
251
- }
252
-
253
- private async checkTableExists(tableName: string): Promise<boolean> {
254
- try {
255
- const result = await this.connections.sourcePool.query(
256
- `SELECT EXISTS (
257
- SELECT FROM information_schema.tables
258
- WHERE table_schema = 'public'
259
- AND table_name = $1
260
- )`,
261
- [tableName]
262
- );
263
- const exists = result.rows[0].exists;
264
- this.logger.debug(
265
- `Verificación de existencia de tabla ${tableName}: ${
266
- exists ? "EXISTE" : "NO EXISTE"
267
- }`
268
- );
269
- return exists;
270
- } catch (error) {
271
- this.logger.error(
272
- `Error verificando existencia de tabla ${tableName}: ${error.message}`
273
- );
274
- return false;
275
- }
276
- }
277
- }
1
+ import { Logger } from "@nestjs/common";
2
+ import { PrismaClient } from "@prisma/client";
3
+ import { DatabaseConnections } from "./types";
4
+
5
+ export class ForeignKeyManager {
6
+ private readonly logger = new Logger("ForeignKeyManager");
7
+ private readonly dependencyCache: Map<string, any[]> = new Map();
8
+
9
+ constructor(private readonly connections: DatabaseConnections) {}
10
+
11
+ async getForeignKeyDependencies(
12
+ schemaName: string,
13
+ tableName: string
14
+ ): Promise<
15
+ Array<{ column: string; foreignTable: string; foreignColumn: string }>
16
+ > {
17
+ const cacheKey = `${schemaName}.${tableName}`;
18
+ if (this.dependencyCache.has(cacheKey)) {
19
+ return this.dependencyCache.get(cacheKey);
20
+ }
21
+
22
+ try {
23
+ this.logger.log(
24
+ `Obteniendo dependencias de llaves foráneas para ${schemaName}.${tableName}`
25
+ );
26
+ const query = `
27
+ SELECT
28
+ kcu.column_name,
29
+ ccu.table_name AS foreign_table_name,
30
+ ccu.column_name AS foreign_column_name
31
+ FROM
32
+ information_schema.table_constraints tc
33
+ JOIN information_schema.key_column_usage kcu
34
+ ON tc.constraint_name = kcu.constraint_name
35
+ AND tc.table_schema = kcu.table_schema
36
+ JOIN information_schema.constraint_column_usage ccu
37
+ ON ccu.constraint_name = tc.constraint_name
38
+ AND ccu.table_schema = tc.table_schema
39
+ WHERE
40
+ tc.constraint_type = 'FOREIGN KEY'
41
+ AND tc.table_schema = $1
42
+ AND tc.table_name = $2;
43
+ `;
44
+
45
+ const { rows } = await this.connections.targetPool.query(query, [
46
+ schemaName,
47
+ tableName,
48
+ ]);
49
+
50
+ const dependencies = rows.map((row) => ({
51
+ column: row.column_name,
52
+ foreignTable: row.foreign_table_name,
53
+ foreignColumn: row.foreign_column_name,
54
+ }));
55
+
56
+ this.logger.log(
57
+ `Encontradas ${
58
+ dependencies.length
59
+ } dependencias para ${schemaName}.${tableName}:
60
+ ${dependencies
61
+ .map(
62
+ (d) => `\n - ${d.column} -> ${d.foreignTable}.${d.foreignColumn}`
63
+ )
64
+ .join("")}`
65
+ );
66
+
67
+ this.dependencyCache.set(cacheKey, dependencies);
68
+ return dependencies;
69
+ } catch (error) {
70
+ this.logger.error(
71
+ `Error obteniendo dependencias de ${schemaName}.${tableName}: ${error.message}`
72
+ );
73
+ return [];
74
+ }
75
+ }
76
+
77
+ async checkForeignKeyDependencies(
78
+ prisma: PrismaClient,
79
+ tenantId: string,
80
+ record: any,
81
+ dependencies: any[]
82
+ ): Promise<string[]> {
83
+ const missingDependencies: string[] = [];
84
+ const recordId = record.id || "unknown";
85
+
86
+ this.logger.debug(
87
+ `Verificando dependencias para registro ${recordId} en tenant ${tenantId}`
88
+ );
89
+
90
+ for (const dep of dependencies) {
91
+ const { table, column, references } = dep;
92
+ const foreignKeyValue = record[column];
93
+
94
+ if (foreignKeyValue === null) {
95
+ this.logger.debug(
96
+ `Dependencia ${table}.${references} es nula para registro ${recordId}, continuando`
97
+ );
98
+ continue;
99
+ }
100
+
101
+ // Verificar en origen
102
+ const sourceExists = await this.checkSourceDependency(
103
+ table,
104
+ references,
105
+ foreignKeyValue
106
+ );
107
+
108
+ if (!sourceExists) {
109
+ this.logger.debug(
110
+ `Registro ${recordId}: Dependencia ${table}.${references}=${foreignKeyValue} no existe en origen, ignorando`
111
+ );
112
+ continue;
113
+ }
114
+
115
+ // Verificar en destino
116
+ const exists = await this.checkDependencyExists(
117
+ prisma,
118
+ tenantId,
119
+ table,
120
+ references,
121
+ foreignKeyValue
122
+ );
123
+
124
+ if (!exists) {
125
+ const depString = `${table}.${references}=${foreignKeyValue}`;
126
+ this.logger.debug(
127
+ `Registro ${recordId}: Dependencia ${depString} existe en origen pero falta en destino`
128
+ );
129
+ missingDependencies.push(depString);
130
+ } else {
131
+ this.logger.debug(
132
+ `Registro ${recordId}: Dependencia ${table}.${references}=${foreignKeyValue} verificada OK`
133
+ );
134
+ }
135
+ }
136
+
137
+ if (missingDependencies.length > 0) {
138
+ this.logger.debug(
139
+ `Registro ${recordId}: Faltan ${
140
+ missingDependencies.length
141
+ } dependencias:
142
+ ${missingDependencies.map((dep) => `\n - ${dep}`).join("")}`
143
+ );
144
+ } else {
145
+ this.logger.debug(`Registro ${recordId}: Todas las dependencias OK`);
146
+ }
147
+
148
+ return missingDependencies;
149
+ }
150
+
151
+ private async checkSourceDependency(
152
+ table: string,
153
+ column: string,
154
+ value: any
155
+ ): Promise<boolean> {
156
+ try {
157
+ const result = await this.connections.sourcePool.query(
158
+ `SELECT 1 FROM "${table}" WHERE "${column}" = $1 LIMIT 1`,
159
+ [value]
160
+ );
161
+ const exists = result.rows.length > 0;
162
+ this.logger.debug(
163
+ `Verificación en origen ${table}.${column}=${value}: ${
164
+ exists ? "EXISTE" : "NO EXISTE"
165
+ }`
166
+ );
167
+ return exists;
168
+ } catch (error) {
169
+ this.logger.error(
170
+ `Error verificando en origen ${table}.${column}=${value}: ${error.message}`
171
+ );
172
+ return false;
173
+ }
174
+ }
175
+
176
+ private async checkDependencyExists(
177
+ prisma: PrismaClient,
178
+ tenantId: string,
179
+ table: string,
180
+ column: string,
181
+ value: any
182
+ ): Promise<boolean> {
183
+ try {
184
+ const result = await prisma.$queryRawUnsafe(
185
+ `SELECT 1 FROM "${tenantId}"."${table}" WHERE "${column}" = $1 LIMIT 1`,
186
+ value
187
+ );
188
+ const exists = Array.isArray(result) && result.length > 0;
189
+ this.logger.debug(
190
+ `Verificación en destino ${tenantId}.${table}.${column}=${value}: ${
191
+ exists ? "EXISTE" : "NO EXISTE"
192
+ }`
193
+ );
194
+ return exists;
195
+ } catch (error) {
196
+ this.logger.error(
197
+ `Error verificando en destino ${tenantId}.${table}.${column}=${value}: ${error.message}`
198
+ );
199
+ return false;
200
+ }
201
+ }
202
+
203
+ async verifyDependencies(
204
+ tableName: string,
205
+ record: any,
206
+ tenantId: string
207
+ ): Promise<boolean> {
208
+ try {
209
+ const dependencies = await this.getForeignKeyDependencies(
210
+ tableName,
211
+ tableName
212
+ );
213
+
214
+ for (const dep of dependencies) {
215
+ const { foreignTable, foreignColumn } = dep;
216
+
217
+ // Verificar si la tabla existe antes de hacer la consulta
218
+ const tableExists = await this.checkTableExists(foreignTable);
219
+ if (!tableExists) {
220
+ this.logger.warn(
221
+ `Table ${foreignTable} does not exist, skipping dependency check`
222
+ );
223
+ continue;
224
+ }
225
+
226
+ // Verificar el valor de la dependencia
227
+ const foreignKeyValue = record[foreignColumn];
228
+ if (foreignKeyValue) {
229
+ const exists = await this.checkDependencyExists(
230
+ this.connections.targetPrisma,
231
+ tenantId,
232
+ foreignTable,
233
+ foreignColumn,
234
+ foreignKeyValue
235
+ );
236
+
237
+ if (!exists) {
238
+ this.logger.warn(
239
+ `Valor ${foreignKeyValue} no existe en ${foreignTable}.${foreignColumn}`
240
+ );
241
+ return false;
242
+ }
243
+ }
244
+ }
245
+
246
+ return true;
247
+ } catch (error) {
248
+ this.logger.error(`Error verifying dependencies: ${error.message}`);
249
+ return false;
250
+ }
251
+ }
252
+
253
+ private async checkTableExists(tableName: string): Promise<boolean> {
254
+ try {
255
+ const result = await this.connections.sourcePool.query(
256
+ `SELECT EXISTS (
257
+ SELECT FROM information_schema.tables
258
+ WHERE table_schema = 'public'
259
+ AND table_name = $1
260
+ )`,
261
+ [tableName]
262
+ );
263
+ const exists = result.rows[0].exists;
264
+ this.logger.debug(
265
+ `Verificación de existencia de tabla ${tableName}: ${
266
+ exists ? "EXISTE" : "NO EXISTE"
267
+ }`
268
+ );
269
+ return exists;
270
+ } catch (error) {
271
+ this.logger.error(
272
+ `Error verificando existencia de tabla ${tableName}: ${error.message}`
273
+ );
274
+ return false;
275
+ }
276
+ }
277
+ }
@@ -1,63 +1,63 @@
1
- {
2
- "commonSchema": "public",
3
- "tenantInfo": {
4
- "sourceTable": "users",
5
- "tenantIdColumn": "user_id",
6
- "providerIdColumn": "provider_id"
7
- },
8
- "migrationPriorities": {
9
- "high": ["countries", "providers", "users", "api_keys"],
10
- "medium": ["transactions", "charges", "balances"],
11
- "low": ["invoices", "api_request_logs"]
12
- },
13
- "tables": {
14
- "countries": {
15
- "type": "public",
16
- "idField": "id"
17
- },
18
- "providers": {
19
- "type": "public",
20
- "idField": "provider_id",
21
- "dependencies": ["countries"]
22
- },
23
- "users": {
24
- "type": "public",
25
- "idField": "user_id",
26
- "dependencies": ["providers"]
27
- },
28
- "api_keys": {
29
- "type": "public",
30
- "idField": "id",
31
- "dependencies": ["users"]
32
- },
33
- "transactions": {
34
- "type": "filteredPublic",
35
- "idField": "id",
36
- "filterColumn": "provider_id",
37
- "dependencies": ["users", "providers"]
38
- },
39
- "charges": {
40
- "type": "filteredPublic",
41
- "idField": "id",
42
- "filterColumn": "provider_id",
43
- "dependencies": ["transactions"]
44
- },
45
- "invoices": {
46
- "type": "filteredPublic",
47
- "idField": "id",
48
- "filterColumn": "provider_id",
49
- "dependencies": ["transactions", "charges"]
50
- },
51
- "balances": {
52
- "type": "filteredPublic",
53
- "idField": "id",
54
- "filterColumn": "provider_id",
55
- "dependencies": ["users"]
56
- },
57
- "api_request_logs": {
58
- "type": "filteredPublic",
59
- "idField": "id",
60
- "dependencies": ["api_keys"]
61
- }
62
- }
63
- }
1
+ {
2
+ "commonSchema": "public",
3
+ "tenantInfo": {
4
+ "sourceTable": "users",
5
+ "tenantIdColumn": "user_id",
6
+ "providerIdColumn": "provider_id"
7
+ },
8
+ "migrationPriorities": {
9
+ "high": ["countries", "providers", "users", "api_keys"],
10
+ "medium": ["transactions", "charges", "balances"],
11
+ "low": ["invoices", "api_request_logs"]
12
+ },
13
+ "tables": {
14
+ "countries": {
15
+ "type": "public",
16
+ "idField": "id"
17
+ },
18
+ "providers": {
19
+ "type": "public",
20
+ "idField": "provider_id",
21
+ "dependencies": ["countries"]
22
+ },
23
+ "users": {
24
+ "type": "public",
25
+ "idField": "user_id",
26
+ "dependencies": ["providers"]
27
+ },
28
+ "api_keys": {
29
+ "type": "public",
30
+ "idField": "id",
31
+ "dependencies": ["users"]
32
+ },
33
+ "transactions": {
34
+ "type": "filteredPublic",
35
+ "idField": "id",
36
+ "filterColumn": "provider_id",
37
+ "dependencies": ["users", "providers"]
38
+ },
39
+ "charges": {
40
+ "type": "filteredPublic",
41
+ "idField": "id",
42
+ "filterColumn": "provider_id",
43
+ "dependencies": ["transactions"]
44
+ },
45
+ "invoices": {
46
+ "type": "filteredPublic",
47
+ "idField": "id",
48
+ "filterColumn": "provider_id",
49
+ "dependencies": ["transactions", "charges"]
50
+ },
51
+ "balances": {
52
+ "type": "filteredPublic",
53
+ "idField": "id",
54
+ "filterColumn": "provider_id",
55
+ "dependencies": ["users"]
56
+ },
57
+ "api_request_logs": {
58
+ "type": "filteredPublic",
59
+ "idField": "id",
60
+ "dependencies": ["api_keys"]
61
+ }
62
+ }
63
+ }