@javalabs/prisma-client 1.0.27 → 1.0.29

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 (50) hide show
  1. package/.github/CODEOWNERS +1 -1
  2. package/README.md +269 -269
  3. package/migration-config.json +63 -63
  4. package/migration-config.json.bk +95 -95
  5. package/migrations/add_reserved_amount.sql +7 -7
  6. package/package.json +44 -44
  7. package/prisma/migrations/add_uuid_to_transactions.sql +13 -13
  8. package/prisma/schema.prisma +609 -601
  9. package/src/index.ts +23 -23
  10. package/src/prisma-factory.service.ts +40 -40
  11. package/src/prisma.module.ts +9 -9
  12. package/src/prisma.service.ts +16 -16
  13. package/src/scripts/add-uuid-to-table.ts +138 -138
  14. package/src/scripts/create-tenant-schemas.ts +145 -145
  15. package/src/scripts/data-migration/batch-migrator.ts +248 -248
  16. package/src/scripts/data-migration/data-transformer.ts +426 -426
  17. package/src/scripts/data-migration/db-connector.ts +120 -120
  18. package/src/scripts/data-migration/dependency-resolver.ts +174 -174
  19. package/src/scripts/data-migration/entity-discovery.ts +196 -196
  20. package/src/scripts/data-migration/foreign-key-manager.ts +277 -277
  21. package/src/scripts/data-migration/migration-config.json +63 -63
  22. package/src/scripts/data-migration/migration-tool.ts +509 -509
  23. package/src/scripts/data-migration/schema-utils.ts +248 -248
  24. package/src/scripts/data-migration/tenant-migrator.ts +201 -201
  25. package/src/scripts/data-migration/typecast-manager.ts +193 -193
  26. package/src/scripts/data-migration/types.ts +113 -113
  27. package/src/scripts/database-initializer.ts +49 -49
  28. package/src/scripts/drop-database.ts +104 -104
  29. package/src/scripts/dump-source-db.sh +61 -61
  30. package/src/scripts/encrypt-user-passwords.ts +36 -36
  31. package/src/scripts/error-handler.ts +117 -117
  32. package/src/scripts/fix-data-types.ts +241 -241
  33. package/src/scripts/fix-enum-values.ts +357 -357
  34. package/src/scripts/fix-schema-discrepancies.ts +317 -317
  35. package/src/scripts/fix-table-indexes.ts +601 -601
  36. package/src/scripts/migrate-schema-structure.ts +90 -90
  37. package/src/scripts/migrate-uuid.ts +76 -76
  38. package/src/scripts/post-migration-validator.ts +526 -526
  39. package/src/scripts/pre-migration-validator.ts +610 -610
  40. package/src/scripts/reset-database.ts +263 -263
  41. package/src/scripts/retry-failed-migrations.ts +416 -416
  42. package/src/scripts/run-migration.ts +707 -707
  43. package/src/scripts/schema-sync.ts +128 -128
  44. package/src/scripts/sequence-sync-cli.ts +416 -416
  45. package/src/scripts/sequence-synchronizer.ts +127 -127
  46. package/src/scripts/sync-enum-types.ts +170 -170
  47. package/src/scripts/sync-enum-values.ts +563 -563
  48. package/src/scripts/truncate-database.ts +123 -123
  49. package/src/scripts/verify-migration-setup.ts +135 -135
  50. 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
+ }