@owox/backend 0.38.0 → 0.39.0

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 (179) hide show
  1. package/dist/src/common/helpers/read-bounded-body.helper.d.ts +1 -0
  2. package/dist/src/common/helpers/read-bounded-body.helper.js +28 -0
  3. package/dist/src/common/scheduler/system-tasks/system-trigger-type.d.ts +3 -1
  4. package/dist/src/common/scheduler/system-tasks/system-trigger-type.js +2 -0
  5. package/dist/src/config/data-source-options.config.d.ts +4 -3
  6. package/dist/src/config/data-source-options.config.js +10 -3
  7. package/dist/src/config/plugin-collections-body-parser.config.js +3 -0
  8. package/dist/src/data-marts/credentials/credential.types.d.ts +26 -2
  9. package/dist/src/data-marts/credentials/credential.types.js +18 -6
  10. package/dist/src/data-marts/credentials/dto/credential-api.dto.d.ts +5 -1
  11. package/dist/src/data-marts/credentials/dto/credential-api.dto.js +21 -0
  12. package/dist/src/data-marts/credentials/dto/credential.dto.d.ts +2 -1
  13. package/dist/src/data-marts/credentials/entities/credential.entity.d.ts +2 -1
  14. package/dist/src/data-marts/credentials/entities/credential.entity.js +5 -0
  15. package/dist/src/data-marts/credentials/facades/credential-consumer-binding.facade.impl.js +6 -1
  16. package/dist/src/data-marts/credentials/mappers/credential.mapper.js +2 -0
  17. package/dist/src/data-marts/credentials/services/builtin-credential-definitions.js +8 -0
  18. package/dist/src/data-marts/credentials/services/credential-external-definition-registry.service.d.ts +4 -0
  19. package/dist/src/data-marts/credentials/services/credential-external-definition-registry.service.js +36 -17
  20. package/dist/src/data-marts/credentials/services/credential-fetch.service.d.ts +8 -0
  21. package/dist/src/data-marts/credentials/services/credential-fetch.service.js +115 -46
  22. package/dist/src/data-marts/credentials/services/credential-validation-probe.service.d.ts +3 -1
  23. package/dist/src/data-marts/credentials/services/credential-validation-probe.service.js +10 -2
  24. package/dist/src/data-marts/credentials/services/credential.service.d.ts +4 -0
  25. package/dist/src/data-marts/credentials/services/credential.service.js +36 -0
  26. package/dist/src/data-marts/credentials/services/google-service-account-key.d.ts +6 -0
  27. package/dist/src/data-marts/credentials/services/google-service-account-key.js +46 -0
  28. package/dist/src/data-marts/credentials/services/google-service-account-token.service.d.ts +25 -0
  29. package/dist/src/data-marts/credentials/services/google-service-account-token.service.js +177 -0
  30. package/dist/src/data-marts/credentials/use-cases/create-credential.service.d.ts +1 -0
  31. package/dist/src/data-marts/credentials/use-cases/create-credential.service.js +10 -2
  32. package/dist/src/data-marts/credentials/use-cases/update-credential.service.d.ts +1 -0
  33. package/dist/src/data-marts/credentials/use-cases/update-credential.service.js +28 -4
  34. package/dist/src/data-marts/credentials/use-cases/validate-credential.service.js +2 -5
  35. package/dist/src/data-marts/data-marts.module.js +4 -0
  36. package/dist/src/data-marts/data-storage-types/snowflake/adapters/snowflake-api.adapter.js +1 -0
  37. package/dist/src/data-marts/dto/presentation/run-data-mart-request-api.dto.js +4 -2
  38. package/dist/src/data-marts/services/connector/backfill-segment.d.ts +22 -0
  39. package/dist/src/data-marts/services/connector/backfill-segment.js +91 -0
  40. package/dist/src/data-marts/services/connector/connector-execution.service.d.ts +1 -0
  41. package/dist/src/data-marts/services/connector/connector-execution.service.js +3 -0
  42. package/dist/src/data-marts/services/connector/connector-executor.service.d.ts +4 -1
  43. package/dist/src/data-marts/services/connector/connector-executor.service.js +107 -23
  44. package/dist/src/data-marts/services/connector/connector-run.service.d.ts +3 -0
  45. package/dist/src/data-marts/services/connector/connector-run.service.js +98 -4
  46. package/dist/src/data-marts/services/data-mart-run.service.d.ts +1 -0
  47. package/dist/src/data-marts/services/data-mart-run.service.js +9 -0
  48. package/dist/src/data-marts/system-triggers/processors/repair-backfill-chains-processor.d.ts +14 -0
  49. package/dist/src/data-marts/system-triggers/processors/repair-backfill-chains-processor.js +45 -0
  50. package/dist/src/data-marts/use-cases/cancel-data-mart-run.service.d.ts +4 -0
  51. package/dist/src/data-marts/use-cases/cancel-data-mart-run.service.js +46 -1
  52. package/dist/src/data-marts/utils/manual-backfill-range.d.ts +52 -0
  53. package/dist/src/data-marts/utils/manual-backfill-range.js +110 -8
  54. package/dist/src/ee/mcp/instructions/mcp-system-instructions.d.ts +1 -1
  55. package/dist/src/ee/mcp/instructions/mcp-system-instructions.js +1 -0
  56. package/dist/src/idp/decorators/auth-context.decorator.js +1 -0
  57. package/dist/src/idp/guards/idp.guard.d.ts +3 -0
  58. package/dist/src/idp/guards/idp.guard.js +38 -8
  59. package/dist/src/idp/oauth/controllers/oauth-authorization.controller.js +8 -6
  60. package/dist/src/idp/oauth/mcp-client-integration.d.ts +1 -0
  61. package/dist/src/idp/oauth/mcp-client-integration.js +15 -0
  62. package/dist/src/idp/ports/plugin-runtime-authorizer.port.d.ts +6 -0
  63. package/dist/src/idp/types/auth.types.d.ts +1 -0
  64. package/dist/src/migrations/1790900000000-add-plugin-version-backend.d.ts +6 -0
  65. package/dist/src/migrations/1790900000000-add-plugin-version-backend.js +21 -0
  66. package/dist/src/migrations/1790900000001-create-plugin-action-execution.d.ts +6 -0
  67. package/dist/src/migrations/1790900000001-create-plugin-action-execution.js +77 -0
  68. package/dist/src/migrations/1791000000000-add-credential-public-metadata.d.ts +6 -0
  69. package/dist/src/migrations/1791000000000-add-credential-public-metadata.js +23 -0
  70. package/dist/src/plugin-host/collections/dto/domain/plugin-collection.types.d.ts +1 -0
  71. package/dist/src/plugin-host/collections/errors/plugin-collection.errors.d.ts +6 -0
  72. package/dist/src/plugin-host/collections/errors/plugin-collection.errors.js +19 -1
  73. package/dist/src/plugin-host/collections/services/plugin-collection-declaration.service.js +3 -3
  74. package/dist/src/plugin-host/collections/use-cases/put-plugin-collection-document.service.js +7 -0
  75. package/dist/src/plugin-host/constants/plugin-action-limits.d.ts +34 -0
  76. package/dist/src/plugin-host/constants/plugin-action-limits.js +51 -0
  77. package/dist/src/plugin-host/controllers/plugin-action-runtime.controller.d.ts +20 -0
  78. package/dist/src/plugin-host/controllers/plugin-action-runtime.controller.js +123 -0
  79. package/dist/src/plugin-host/controllers/plugin-credential-runtime.controller.js +11 -19
  80. package/dist/src/plugin-host/controllers/plugin-history.controller.d.ts +10 -0
  81. package/dist/src/plugin-host/controllers/plugin-history.controller.js +57 -0
  82. package/dist/src/plugin-host/controllers/plugin-release-check.controller.d.ts +10 -0
  83. package/dist/src/plugin-host/controllers/plugin-release-check.controller.js +58 -0
  84. package/dist/src/plugin-host/dto/domain/check-plugin-release.command.d.ts +22 -0
  85. package/dist/src/plugin-host/dto/domain/check-plugin-release.command.js +17 -0
  86. package/dist/src/plugin-host/dto/domain/list-plugin-history.command.d.ts +10 -0
  87. package/dist/src/plugin-host/dto/domain/list-plugin-history.command.js +18 -0
  88. package/dist/src/plugin-host/dto/domain/plugin-action-execution.command.d.ts +23 -0
  89. package/dist/src/plugin-host/dto/domain/plugin-action-execution.command.js +44 -0
  90. package/dist/src/plugin-host/dto/domain/plugin-action-execution.dto.d.ts +36 -0
  91. package/dist/src/plugin-host/dto/domain/plugin-action-execution.dto.js +3 -0
  92. package/dist/src/plugin-host/dto/domain/plugin-history.dto.d.ts +29 -0
  93. package/dist/src/plugin-host/dto/domain/plugin-history.dto.js +3 -0
  94. package/dist/src/plugin-host/dto/domain/plugin-view.dto.d.ts +1 -0
  95. package/dist/src/plugin-host/dto/presentation/plugin-action-api.dto.d.ts +44 -0
  96. package/dist/src/plugin-host/dto/presentation/plugin-action-api.dto.js +208 -0
  97. package/dist/src/plugin-host/dto/presentation/plugin-gallery-api.dto.d.ts +2 -0
  98. package/dist/src/plugin-host/dto/presentation/plugin-gallery-api.dto.js +7 -0
  99. package/dist/src/plugin-host/dto/presentation/plugin-history-api.dto.d.ts +29 -0
  100. package/dist/src/plugin-host/dto/presentation/plugin-history-api.dto.js +148 -0
  101. package/dist/src/plugin-host/dto/presentation/publication-api.dto.d.ts +17 -0
  102. package/dist/src/plugin-host/dto/presentation/publication-api.dto.js +95 -1
  103. package/dist/src/plugin-host/entities/plugin-action-execution.entity.d.ts +24 -0
  104. package/dist/src/plugin-host/entities/plugin-action-execution.entity.js +136 -0
  105. package/dist/src/plugin-host/entities/plugin-version.entity.d.ts +2 -1
  106. package/dist/src/plugin-host/entities/plugin-version.entity.js +5 -0
  107. package/dist/src/plugin-host/enums/plugin-action-execution-status.enum.d.ts +9 -0
  108. package/dist/src/plugin-host/enums/plugin-action-execution-status.enum.js +22 -0
  109. package/dist/src/plugin-host/enums/release-rejection-code.enum.d.ts +3 -0
  110. package/dist/src/plugin-host/enums/release-rejection-code.enum.js +6 -0
  111. package/dist/src/plugin-host/errors/plugin-action.errors.d.ts +45 -0
  112. package/dist/src/plugin-host/errors/plugin-action.errors.js +70 -0
  113. package/dist/src/plugin-host/errors/plugin-host.errors.d.ts +6 -0
  114. package/dist/src/plugin-host/errors/plugin-host.errors.js +10 -1
  115. package/dist/src/plugin-host/filters/plugin-host-exception.filter.js +2 -2
  116. package/dist/src/plugin-host/mappers/plugin-action-execution.mapper.d.ts +3 -0
  117. package/dist/src/plugin-host/mappers/plugin-action-execution.mapper.js +22 -0
  118. package/dist/src/plugin-host/mappers/plugin-presentation.mapper.d.ts +16 -1
  119. package/dist/src/plugin-host/mappers/plugin-presentation.mapper.js +80 -1
  120. package/dist/src/plugin-host/plugin-host.module.js +32 -0
  121. package/dist/src/plugin-host/services/action-input-validator.service.d.ts +23 -0
  122. package/dist/src/plugin-host/services/action-input-validator.service.js +277 -0
  123. package/dist/src/plugin-host/services/external-credential-definition-sync.service.d.ts +3 -0
  124. package/dist/src/plugin-host/services/external-credential-definition-sync.service.js +47 -15
  125. package/dist/src/plugin-host/services/plugin-action-dispatcher.service.d.ts +13 -0
  126. package/dist/src/plugin-host/services/plugin-action-dispatcher.service.js +140 -0
  127. package/dist/src/plugin-host/services/plugin-action-execution.service.d.ts +69 -0
  128. package/dist/src/plugin-host/services/plugin-action-execution.service.js +239 -0
  129. package/dist/src/plugin-host/services/plugin-action-starter.service.d.ts +22 -0
  130. package/dist/src/plugin-host/services/plugin-action-starter.service.js +81 -0
  131. package/dist/src/plugin-host/services/plugin-audit.service.d.ts +13 -0
  132. package/dist/src/plugin-host/services/plugin-audit.service.js +78 -0
  133. package/dist/src/plugin-host/services/plugin-publication.service.d.ts +2 -0
  134. package/dist/src/plugin-host/services/plugin-publication.service.js +18 -10
  135. package/dist/src/plugin-host/services/plugin-runtime-authorizer.service.d.ts +5 -2
  136. package/dist/src/plugin-host/services/plugin-runtime-authorizer.service.js +31 -3
  137. package/dist/src/plugin-host/services/plugin-version.service.d.ts +2 -1
  138. package/dist/src/plugin-host/services/release-candidate-rules.service.d.ts +51 -0
  139. package/dist/src/plugin-host/services/release-candidate-rules.service.js +198 -0
  140. package/dist/src/plugin-host/services/remote-url-validator.service.d.ts +7 -0
  141. package/dist/src/plugin-host/services/remote-url-validator.service.js +4 -0
  142. package/dist/src/plugin-host/system-triggers/plugin-action-execution-sweep.processor.d.ts +14 -0
  143. package/dist/src/plugin-host/system-triggers/plugin-action-execution-sweep.processor.js +50 -0
  144. package/dist/src/plugin-host/use-cases/cancel-plugin-action-execution.service.d.ts +8 -0
  145. package/dist/src/plugin-host/use-cases/cancel-plugin-action-execution.service.js +39 -0
  146. package/dist/src/plugin-host/use-cases/check-plugin-release.service.d.ts +22 -0
  147. package/dist/src/plugin-host/use-cases/check-plugin-release.service.js +152 -0
  148. package/dist/src/plugin-host/use-cases/get-current-plugin-action-execution.service.d.ts +14 -0
  149. package/dist/src/plugin-host/use-cases/get-current-plugin-action-execution.service.js +85 -0
  150. package/dist/src/plugin-host/use-cases/get-plugin-action-execution.service.d.ts +9 -0
  151. package/dist/src/plugin-host/use-cases/get-plugin-action-execution.service.js +67 -0
  152. package/dist/src/plugin-host/use-cases/get-plugin-installation-entry.service.js +2 -7
  153. package/dist/src/plugin-host/use-cases/install-plugin.service.js +4 -0
  154. package/dist/src/plugin-host/use-cases/list-plugin-history.service.d.ts +25 -0
  155. package/dist/src/plugin-host/use-cases/list-plugin-history.service.js +147 -0
  156. package/dist/src/plugin-host/use-cases/plugin-publisher-access.d.ts +5 -0
  157. package/dist/src/plugin-host/use-cases/plugin-publisher-access.js +28 -0
  158. package/dist/src/plugin-host/use-cases/start-plugin-action-execution.service.d.ts +12 -0
  159. package/dist/src/plugin-host/use-cases/start-plugin-action-execution.service.js +64 -0
  160. package/dist/src/plugin-host/use-cases/sync-plugin-releases.service.d.ts +3 -5
  161. package/dist/src/plugin-host/use-cases/sync-plugin-releases.service.js +15 -59
  162. package/dist/src/plugin-host/use-cases/uninstall-plugin.service.js +3 -1
  163. package/dist/src/plugin-host/use-cases/update-plugin.service.d.ts +0 -1
  164. package/dist/src/plugin-host/use-cases/update-plugin.service.js +3 -25
  165. package/dist/src/plugin-host/utils/action-input-schema.util.d.ts +14 -0
  166. package/dist/src/plugin-host/utils/action-input-schema.util.js +133 -0
  167. package/dist/src/plugin-host/utils/credential-handles.util.d.ts +3 -0
  168. package/dist/src/plugin-host/utils/credential-handles.util.js +13 -0
  169. package/dist/src/plugin-host/utils/execution-token.util.d.ts +5 -0
  170. package/dist/src/plugin-host/utils/execution-token.util.js +13 -0
  171. package/dist/src/plugin-host/utils/json-shape.util.d.ts +1 -0
  172. package/dist/src/plugin-host/utils/json-shape.util.js +21 -0
  173. package/dist/src/plugin-host/utils/plugin-action-outcome.util.d.ts +10 -0
  174. package/dist/src/plugin-host/utils/plugin-action-outcome.util.js +67 -0
  175. package/dist/src/plugin-host/utils/plugin-manifest.util.d.ts +121 -0
  176. package/dist/src/plugin-host/utils/plugin-manifest.util.js +111 -1
  177. package/dist/src/plugin-host/utils/request-abort-signal.util.d.ts +5 -0
  178. package/dist/src/plugin-host/utils/request-abort-signal.util.js +19 -0
  179. package/package.json +10 -8
@@ -26,6 +26,7 @@ const credential_context_entity_1 = require("../entities/credential-context.enti
26
26
  const credential_owner_entity_1 = require("../entities/credential-owner.entity");
27
27
  const credential_definition_service_1 = require("../services/credential-definition.service");
28
28
  const credential_service_1 = require("../services/credential.service");
29
+ const google_service_account_key_1 = require("../services/google-service-account-key");
29
30
  const credential_view_service_1 = require("../services/credential-view.service");
30
31
  const credential_validation_probe_service_1 = require("../services/credential-validation-probe.service");
31
32
  const credential_types_1 = require("../credential.types");
@@ -51,10 +52,16 @@ let CreateCredentialService = class CreateCredentialService {
51
52
  async run(context, input) {
52
53
  const definition = await this.definitions.get(input.definitionId);
53
54
  const aiConfiguration = normalizeAiConfiguration(input.aiModelMappings, input.aiModelMappingModes, definition.contract.ai);
55
+ const publicMetadata = definition.contract.auth.type === 'google-service-account'
56
+ ? (0, google_service_account_key_1.parseGoogleServiceAccountKey)(input.secret.value).metadata
57
+ : null;
54
58
  const validation = await this.validationProbe.run(definition, { value: input.secret.value });
55
59
  if (validation.state === 'rejected') {
56
60
  throw new common_1.BadRequestException(validation.message);
57
61
  }
62
+ return this.persist(context, input, definition, aiConfiguration, publicMetadata, validation);
63
+ }
64
+ async persist(context, input, definition, aiConfiguration, publicMetadata, validation) {
58
65
  const credential = await this.credentials.save(this.credentials.create({
59
66
  projectId: context.projectId,
60
67
  title: input.title.trim(),
@@ -71,6 +78,7 @@ let CreateCredentialService = class CreateCredentialService {
71
78
  validationState: validation.state,
72
79
  validationMessage: validation.message,
73
80
  validatedAt: validation.validatedAt,
81
+ publicMetadata,
74
82
  createdById: context.userId,
75
83
  }));
76
84
  const ownerIds = [...new Set([context.userId, ...(input.ownerIds ?? [])])];
@@ -90,9 +98,9 @@ exports.CreateCredentialService = CreateCredentialService;
90
98
  __decorate([
91
99
  (0, typeorm_transactional_1.Transactional)(),
92
100
  __metadata("design:type", Function),
93
- __metadata("design:paramtypes", [Object, Function]),
101
+ __metadata("design:paramtypes", [Object, Function, Object, void 0, Object, Object]),
94
102
  __metadata("design:returntype", Promise)
95
- ], CreateCredentialService.prototype, "run", null);
103
+ ], CreateCredentialService.prototype, "persist", null);
96
104
  exports.CreateCredentialService = CreateCredentialService = __decorate([
97
105
  (0, common_1.Injectable)(),
98
106
  __param(6, (0, typeorm_1.InjectRepository)(credential_owner_entity_1.CredentialOwner)),
@@ -21,5 +21,6 @@ export declare class UpdateCredentialService {
21
21
  private readonly owners;
22
22
  constructor(credentials: CredentialService, definitions: CredentialDefinitionService, access: AccessDecisionService, contextAccess: ContextAccessService, view: CredentialViewService, validationProbe: CredentialValidationProbeService, idpProjections: IdpProjectionsFacade, owners: Repository<CredentialOwner>);
23
23
  run(id: string, context: AuthorizationContext, input: UpdateCredentialApiDto): Promise<CredentialDto>;
24
+ private apply;
24
25
  private assertAccess;
25
26
  }
@@ -24,6 +24,7 @@ const sync_owners_1 = require("../../utils/sync-owners");
24
24
  const credential_owner_entity_1 = require("../entities/credential-owner.entity");
25
25
  const credential_definition_service_1 = require("../services/credential-definition.service");
26
26
  const credential_service_1 = require("../services/credential.service");
27
+ const google_service_account_key_1 = require("../services/google-service-account-key");
27
28
  const credential_view_service_1 = require("../services/credential-view.service");
28
29
  const credential_validation_probe_service_1 = require("../services/credential-validation-probe.service");
29
30
  const create_credential_service_1 = require("./create-credential.service");
@@ -65,14 +66,29 @@ let UpdateCredentialService = class UpdateCredentialService {
65
66
  ? await this.definitions.getForCredential(credential)
66
67
  : await this.definitions.getForView(credential);
67
68
  let validation;
68
- if (input.title !== undefined)
69
- credential.title = input.title.trim();
69
+ let publicMetadata = credential.publicMetadata;
70
70
  if (input.secret !== undefined) {
71
+ if (definition.contract.auth.type === 'google-service-account') {
72
+ publicMetadata = (0, google_service_account_key_1.parseGoogleServiceAccountKey)(input.secret.value).metadata;
73
+ const savedEmail = credential.publicMetadata?.clientEmail ?? storedClientEmail(credential.secret.value);
74
+ if (savedEmail && publicMetadata.clientEmail.toLowerCase() !== savedEmail.toLowerCase()) {
75
+ throw new common_1.BadRequestException(`The replacement key must belong to ${savedEmail}. Create another Credential for a different service account.`);
76
+ }
77
+ }
71
78
  validation = await this.validationProbe.run(definition, { value: input.secret.value });
72
79
  if (validation.state === 'rejected') {
73
80
  throw new common_1.BadRequestException(validation.message);
74
81
  }
82
+ }
83
+ return this.apply(id, context, input, definition, validation, publicMetadata);
84
+ }
85
+ async apply(id, context, input, definition, validation, publicMetadata) {
86
+ const credential = await this.credentials.getByIdAndProjectId(id, context.projectId);
87
+ if (input.title !== undefined)
88
+ credential.title = input.title.trim();
89
+ if (input.secret !== undefined && validation) {
75
90
  credential.secret = { value: input.secret.value };
91
+ credential.publicMetadata = publicMetadata;
76
92
  credential.validationState = validation.state;
77
93
  credential.validationMessage = validation.message;
78
94
  credential.validatedAt = validation.validatedAt;
@@ -113,9 +129,9 @@ exports.UpdateCredentialService = UpdateCredentialService;
113
129
  __decorate([
114
130
  (0, typeorm_transactional_1.Transactional)(),
115
131
  __metadata("design:type", Function),
116
- __metadata("design:paramtypes", [String, Object, Function]),
132
+ __metadata("design:paramtypes", [String, Object, Function, Object, Object, Object]),
117
133
  __metadata("design:returntype", Promise)
118
- ], UpdateCredentialService.prototype, "run", null);
134
+ ], UpdateCredentialService.prototype, "apply", null);
119
135
  exports.UpdateCredentialService = UpdateCredentialService = __decorate([
120
136
  (0, common_1.Injectable)(),
121
137
  __param(7, (0, typeorm_1.InjectRepository)(credential_owner_entity_1.CredentialOwner)),
@@ -128,4 +144,12 @@ exports.UpdateCredentialService = UpdateCredentialService = __decorate([
128
144
  idp_projections_facade_1.IdpProjectionsFacade,
129
145
  typeorm_2.Repository])
130
146
  ], UpdateCredentialService);
147
+ function storedClientEmail(secretValue) {
148
+ try {
149
+ return (0, google_service_account_key_1.parseGoogleServiceAccountKey)(secretValue).metadata.clientEmail;
150
+ }
151
+ catch {
152
+ return undefined;
153
+ }
154
+ }
131
155
  //# sourceMappingURL=update-credential.service.js.map
@@ -36,11 +36,8 @@ let ValidateCredentialService = class ValidateCredentialService {
36
36
  }
37
37
  const definition = await this.definitions.getForCredential(credential);
38
38
  const validation = await this.validationProbe.run(definition, credential.secret);
39
- credential.validationState = validation.state;
40
- credential.validationMessage = validation.message;
41
- credential.validatedAt = validation.validatedAt;
42
- await this.credentials.save(credential);
43
- return this.view.build(credential);
39
+ await this.credentials.writeValidation(id, credential.secret, validation);
40
+ return this.view.build(await this.credentials.getByIdAndProjectId(id, context.projectId));
44
41
  }
45
42
  };
46
43
  exports.ValidateCredentialService = ValidateCredentialService;
@@ -265,6 +265,7 @@ const update_insight_template_source_service_1 = require("./use-cases/update-ins
265
265
  const delete_insight_template_source_service_1 = require("./use-cases/delete-insight-template-source.service");
266
266
  const delete_insight_template_service_1 = require("./use-cases/delete-insight-template.service");
267
267
  const retry_interrupted_connector_runs_processor_1 = require("./system-triggers/processors/retry-interrupted-connector-runs-processor");
268
+ const repair_backfill_chains_processor_1 = require("./system-triggers/processors/repair-backfill-chains-processor");
268
269
  const sql_run_service_1 = require("./use-cases/sql-run.service");
269
270
  const create_view_service_1 = require("./use-cases/create-view.service");
270
271
  const ai_insights_providers_1 = require("./ai-insights/ai-insights-providers");
@@ -477,6 +478,7 @@ const validate_credential_service_1 = require("./credentials/use-cases/validate-
477
478
  const credential_consumer_binding_facade_1 = require("./credentials/facades/credential-consumer-binding.facade");
478
479
  const credential_consumer_binding_facade_impl_1 = require("./credentials/facades/credential-consumer-binding.facade.impl");
479
480
  const credential_fetch_service_1 = require("./credentials/services/credential-fetch.service");
481
+ const google_service_account_token_service_1 = require("./credentials/services/google-service-account-token.service");
480
482
  const credential_ai_service_1 = require("./credentials/services/credential-ai.service");
481
483
  const credential_validation_probe_service_1 = require("./credentials/services/credential-validation-probe.service");
482
484
  const credential_external_definition_registry_service_1 = require("./credentials/services/credential-external-definition-registry.service");
@@ -818,6 +820,7 @@ exports.DataMartsModule = DataMartsModule = __decorate([
818
820
  ai_helper_trigger_service_1.AiHelperTriggerService,
819
821
  ai_helper_trigger_handler_service_1.AiHelperTriggerHandlerService,
820
822
  retry_interrupted_connector_runs_processor_1.RetryInterruptedConnectorRunsProcessor,
823
+ repair_backfill_chains_processor_1.RepairBackfillChainsProcessor,
821
824
  scheduled_trigger_service_1.ScheduledTriggerService,
822
825
  scheduled_trigger_mapper_1.ScheduledTriggerMapper,
823
826
  create_scheduled_trigger_service_1.CreateScheduledTriggerService,
@@ -994,6 +997,7 @@ exports.DataMartsModule = DataMartsModule = __decorate([
994
997
  delete_credential_service_1.DeleteCredentialService,
995
998
  validate_credential_service_1.ValidateCredentialService,
996
999
  credential_fetch_service_1.CredentialFetchService,
1000
+ google_service_account_token_service_1.GoogleServiceAccountTokenService,
997
1001
  credential_ai_service_1.CredentialAiService,
998
1002
  credential_validation_probe_service_1.CredentialValidationProbeService,
999
1003
  credential_external_definition_registry_service_1.CredentialExternalDefinitionRegistryService,
@@ -51,6 +51,7 @@ class SnowflakeApiAdapter {
51
51
  warehouse: config.warehouse,
52
52
  retryTimeout: 10000,
53
53
  sfRetryMaxLoginRetries: 1,
54
+ certRevocationCheckMode: 'ADVISORY',
54
55
  };
55
56
  if (credentials.authMethod === snowflake_auth_method_enum_1.SnowflakeAuthMethod.PASSWORD) {
56
57
  connectionOptions.username = credentials.username;
@@ -171,8 +171,10 @@ __decorate([
171
171
  description: `Payload for the manual run. Omit it or select INCREMENTAL for an incremental run.
172
172
  MANUAL_BACKFILL can include connector-specific fields in data; connectors without backfill
173
173
  fields can omit data. StartDate and EndDate accept YYYY-MM-DD (or the date part of an
174
- ISO-8601 timestamp). A missing or future EndDate counts as today, and the resulting range
175
- may cover at most 31 days.`,
174
+ ISO-8601 timestamp). A missing or future EndDate counts as today. A StartDate earlier than
175
+ 2000-01-01 is rejected. The range has no other length limit: a range longer than 31 days runs
176
+ as a chain of runs, one segment of up to 31 days each. A segment counts as one connector run
177
+ once any of its accounts loads data.`,
176
178
  }),
177
179
  __metadata("design:type", Object)
178
180
  ], RunDataMartRequestApiDto.prototype, "payload", void 0);
@@ -0,0 +1,22 @@
1
+ import { Repository } from 'typeorm';
2
+ import { ConnectorMessage } from '../../connector-types/connector-message/schemas/connector-message.schema';
3
+ import { ConnectorMessageType } from '../../connector-types/enums/connector-message-type-enum';
4
+ import { DataMart } from '../../entities/data-mart.entity';
5
+ import { DataMartRun } from '../../entities/data-mart-run.entity';
6
+ import { BackfillChainMeta, BackfillDateRange } from '../../utils/manual-backfill-range';
7
+ import { ConnectorRunTriggerService } from './connector-run-trigger.service';
8
+ export declare const BACKFILL_SEGMENT_METRIC = "backfill_segment";
9
+ export type SegmentMarkerPhase = 'started' | 'completed' | 'failed';
10
+ export type SegmentChainEnd = 'finished' | 'stopped';
11
+ export interface SegmentMarkerOutcome {
12
+ readonly loadedThrough?: string;
13
+ readonly configurationsLoaded?: number;
14
+ readonly configurationsTotal?: number;
15
+ readonly counted?: boolean;
16
+ readonly chainContinues?: boolean;
17
+ readonly chainEnd?: SegmentChainEnd;
18
+ }
19
+ export declare function buildSegmentMarker(meta: BackfillChainMeta, window: BackfillDateRange, phase: SegmentMarkerPhase, at: string, outcome?: SegmentMarkerOutcome): Extract<ConnectorMessage, {
20
+ type: ConnectorMessageType.LOG;
21
+ }>;
22
+ export declare function createNextSegmentRun(runRepository: Repository<DataMartRun>, triggerService: ConnectorRunTriggerService, previousRun: DataMartRun, dataMart: DataMart, meta: BackfillChainMeta, window: BackfillDateRange): Promise<DataMartRun>;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BACKFILL_SEGMENT_METRIC = void 0;
4
+ exports.buildSegmentMarker = buildSegmentMarker;
5
+ exports.createNextSegmentRun = createNextSegmentRun;
6
+ const connector_message_type_enum_1 = require("../../connector-types/enums/connector-message-type-enum");
7
+ const data_mart_run_status_enum_1 = require("../../enums/data-mart-run-status.enum");
8
+ const data_mart_run_type_enum_1 = require("../../enums/data-mart-run-type.enum");
9
+ const manual_backfill_range_1 = require("../../utils/manual-backfill-range");
10
+ exports.BACKFILL_SEGMENT_METRIC = 'backfill_segment';
11
+ function describeLoadedDays(outcome) {
12
+ if (!outcome.loadedThrough)
13
+ return 'no days of this segment were loaded';
14
+ const { configurationsLoaded, configurationsTotal } = outcome;
15
+ const isPartial = configurationsLoaded !== undefined &&
16
+ configurationsTotal !== undefined &&
17
+ configurationsLoaded < configurationsTotal;
18
+ const scope = isPartial
19
+ ? ` (${configurationsLoaded} of ${configurationsTotal} configurations)`
20
+ : '';
21
+ return `days through ${outcome.loadedThrough} were loaded${scope}`;
22
+ }
23
+ function describeUnloadedPeriod(meta, window) {
24
+ const isLastSegment = meta.segmentIndex >= meta.segmentsTotal;
25
+ const segments = isLastSegment
26
+ ? `segment ${meta.segmentIndex}`
27
+ : `segments ${meta.segmentIndex}–${meta.segmentsTotal}`;
28
+ return `${segments} (${window.startDate} – ${meta.requestedEnd}) ${isLastSegment ? 'was' : 'were'} not loaded`;
29
+ }
30
+ function buildSegmentMarker(meta, window, phase, at, outcome = {}) {
31
+ const period = `${meta.requestedStart} – ${meta.requestedEnd}`;
32
+ const position = `segment ${meta.segmentIndex} of ${meta.segmentsTotal} (${window.startDate} – ${window.endDate})`;
33
+ let message;
34
+ switch (phase) {
35
+ case 'started':
36
+ message = `Backfill ${period}: loading ${position}`;
37
+ break;
38
+ case 'completed':
39
+ message = `Backfill ${period}: ${position} completed — counted as 1 run`;
40
+ break;
41
+ case 'failed':
42
+ message =
43
+ outcome.chainEnd === 'stopped'
44
+ ? `Backfill stopped: the project is restricted; ${describeUnloadedPeriod(meta, window)}.`
45
+ : `Backfill ${period}: ${position} failed; ${describeLoadedDays(outcome)}${outcome.counted ? ' — counted as 1 run' : ''}`;
46
+ break;
47
+ }
48
+ return {
49
+ type: connector_message_type_enum_1.ConnectorMessageType.LOG,
50
+ at,
51
+ metric: exports.BACKFILL_SEGMENT_METRIC,
52
+ value: meta.segmentIndex,
53
+ tags: {
54
+ phase,
55
+ segmentStart: window.startDate,
56
+ segmentEnd: window.endDate,
57
+ backfillStart: meta.requestedStart,
58
+ backfillEnd: meta.requestedEnd,
59
+ segmentsTotal: meta.segmentsTotal,
60
+ ...(outcome.loadedThrough ? { loadedThrough: outcome.loadedThrough } : {}),
61
+ ...(outcome.chainContinues === undefined ? {} : { chainContinues: outcome.chainContinues }),
62
+ ...(outcome.chainEnd ? { chainEnd: outcome.chainEnd } : {}),
63
+ },
64
+ message,
65
+ toFormattedString: () => `[LOG] ${message}`,
66
+ };
67
+ }
68
+ async function createNextSegmentRun(runRepository, triggerService, previousRun, dataMart, meta, window) {
69
+ const additionalParams = (0, manual_backfill_range_1.nextSegmentAdditionalParams)(previousRun.additionalParams, meta, window);
70
+ const nextRun = await runRepository.save(runRepository.create({
71
+ dataMartId: previousRun.dataMartId,
72
+ type: data_mart_run_type_enum_1.DataMartRunType.CONNECTOR,
73
+ definitionRun: dataMart.definition,
74
+ status: data_mart_run_status_enum_1.DataMartRunStatus.PENDING,
75
+ createdById: previousRun.createdById ?? undefined,
76
+ runType: previousRun.runType,
77
+ logs: [],
78
+ errors: [],
79
+ additionalParams,
80
+ }));
81
+ await triggerService.createTrigger({
82
+ dataMartId: previousRun.dataMartId,
83
+ projectId: dataMart.projectId,
84
+ createdById: previousRun.createdById ?? 'system',
85
+ dataMartRunId: nextRun.id,
86
+ runType: previousRun.runType,
87
+ payload: additionalParams,
88
+ });
89
+ return nextRun;
90
+ }
91
+ //# sourceMappingURL=backfill-segment.js.map
@@ -9,5 +9,6 @@ export declare class ConnectorExecutionService {
9
9
  run(dataMart: DataMart, createdById: string, runType: RunType, payload?: Record<string, unknown>): Promise<string>;
10
10
  executeExistingRun(dataMart: DataMart, run: DataMartRun, payload?: Record<string, unknown> | null, signal?: AbortSignal): Promise<void>;
11
11
  executeInterruptedRuns(): Promise<void>;
12
+ repairBackfillChains(): Promise<void>;
12
13
  getDataMartConnectorRunsByStatus(status: DataMartRunStatus): Promise<DataMartRun[]>;
13
14
  }
@@ -26,6 +26,9 @@ let ConnectorExecutionService = class ConnectorExecutionService {
26
26
  async executeInterruptedRuns() {
27
27
  return this.connectorRunService.executeInterruptedRuns();
28
28
  }
29
+ async repairBackfillChains() {
30
+ return this.connectorRunService.repairBackfillChains();
31
+ }
29
32
  async getDataMartConnectorRunsByStatus(status) {
30
33
  return this.connectorRunService.getDataMartConnectorRunsByStatus(status);
31
34
  }
@@ -11,6 +11,7 @@ import { SystemTimeService } from '../../../common/scheduler/services/system-tim
11
11
  import { OwoxEventDispatcher } from '../../../common/event-dispatcher/owox-event-dispatcher';
12
12
  import { ProjectBillingService } from '../project-billing/project-billing.service';
13
13
  import { ConnectorDefinitionService } from './connector-definition.service';
14
+ import { ConnectorRunTriggerService } from './connector-run-trigger.service';
14
15
  import { ConnectorProcessSpawnerService } from './connector-process-spawner.service';
15
16
  import { ConnectorStorageConfigService } from './connector-storage-config.service';
16
17
  import { ConnectorSourceConfigService } from './connector-source-config.service';
@@ -32,8 +33,9 @@ export declare class ConnectorExecutorService {
32
33
  private readonly connectorDefinitionService;
33
34
  private readonly connectorSourceCredentialsService;
34
35
  private readonly configService;
36
+ private readonly connectorRunTriggerService;
35
37
  private readonly logger;
36
- constructor(dataMartRunRepository: Repository<DataMartRun>, processSpawner: ConnectorProcessSpawnerService, storageConfigService: ConnectorStorageConfigService, sourceConfigService: ConnectorSourceConfigService, credentialInjector: ConnectorCredentialInjectorService, connectorOutputCaptureService: ConnectorOutputCaptureService, connectorStateService: ConnectorStateService, gracefulShutdownService: GracefulShutdownService, systemTimeService: SystemTimeService, eventDispatcher: OwoxEventDispatcher, projectBillingService: ProjectBillingService, dataMartService: DataMartService, connectorDefinitionService: ConnectorDefinitionService, connectorSourceCredentialsService: ConnectorSourceCredentialsService, configService: ConfigService);
38
+ constructor(dataMartRunRepository: Repository<DataMartRun>, processSpawner: ConnectorProcessSpawnerService, storageConfigService: ConnectorStorageConfigService, sourceConfigService: ConnectorSourceConfigService, credentialInjector: ConnectorCredentialInjectorService, connectorOutputCaptureService: ConnectorOutputCaptureService, connectorStateService: ConnectorStateService, gracefulShutdownService: GracefulShutdownService, systemTimeService: SystemTimeService, eventDispatcher: OwoxEventDispatcher, projectBillingService: ProjectBillingService, dataMartService: DataMartService, connectorDefinitionService: ConnectorDefinitionService, connectorSourceCredentialsService: ConnectorSourceCredentialsService, configService: ConfigService, connectorRunTriggerService: ConnectorRunTriggerService);
37
39
  executeInBackground(dataMart: DataMart, run: DataMartRun, payload?: Record<string, unknown> | null, signal?: AbortSignal): Promise<void>;
38
40
  private actualizeSchemaAfterConnectorExecution;
39
41
  private runConnectorConfigurations;
@@ -49,6 +51,7 @@ export declare class ConnectorExecutorService {
49
51
  private stripManifestForRunner;
50
52
  private createRunLogFlusher;
51
53
  private updateRunStatus;
54
+ private writeRunOutcome;
52
55
  private mergeWithPersistedOutput;
53
56
  private discountFlushedEntries;
54
57
  private capMergedEntries;
@@ -18,13 +18,14 @@ const common_1 = require("@nestjs/common");
18
18
  const config_1 = require("@nestjs/config");
19
19
  const typeorm_1 = require("@nestjs/typeorm");
20
20
  const typeorm_2 = require("typeorm");
21
+ const typeorm_transactional_1 = require("typeorm-transactional");
21
22
  const connectors_1 = require("@owox/connectors");
22
23
  const internal_helpers_1 = require("@owox/internal-helpers");
23
24
  const { ConfigDto, GENERATED_REFRESH_TOKEN_CREDENTIAL_FIELD } = connectors_1.Core;
24
25
  const GENERATED_REFRESH_TOKEN_MAX_LENGTH = 4096;
25
26
  exports.MAX_MERGED_RUN_OUTPUT_ENTRIES = 10000;
26
27
  const MAX_MERGED_RUN_OUTPUT_BYTES = 6 * 1024 * 1024;
27
- const MAX_RUN_BUFFER_ENTRIES = exports.MAX_MERGED_RUN_OUTPUT_ENTRIES - 1;
28
+ const MAX_RUN_BUFFER_ENTRIES = exports.MAX_MERGED_RUN_OUTPUT_ENTRIES - 2;
28
29
  const MAX_TRACE_ENTRIES = 1000;
29
30
  const data_mart_run_entity_1 = require("../../entities/data-mart-run.entity");
30
31
  const data_mart_run_status_enum_1 = require("../../enums/data-mart-run-status.enum");
@@ -42,6 +43,8 @@ const owox_event_dispatcher_1 = require("../../../common/event-dispatcher/owox-e
42
43
  const connector_run_event_1 = require("../../events/connector-run.event");
43
44
  const project_billing_service_1 = require("../project-billing/project-billing.service");
44
45
  const connector_definition_service_1 = require("./connector-definition.service");
46
+ const connector_run_trigger_service_1 = require("./connector-run-trigger.service");
47
+ const backfill_segment_1 = require("./backfill-segment");
45
48
  const connector_process_spawner_service_1 = require("./connector-process-spawner.service");
46
49
  const connector_storage_config_service_1 = require("./connector-storage-config.service");
47
50
  const connector_source_config_service_1 = require("./connector-source-config.service");
@@ -69,8 +72,9 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
69
72
  connectorDefinitionService;
70
73
  connectorSourceCredentialsService;
71
74
  configService;
75
+ connectorRunTriggerService;
72
76
  logger = new common_1.Logger(ConnectorExecutorService_1.name);
73
- constructor(dataMartRunRepository, processSpawner, storageConfigService, sourceConfigService, credentialInjector, connectorOutputCaptureService, connectorStateService, gracefulShutdownService, systemTimeService, eventDispatcher, projectBillingService, dataMartService, connectorDefinitionService, connectorSourceCredentialsService, configService) {
77
+ constructor(dataMartRunRepository, processSpawner, storageConfigService, sourceConfigService, credentialInjector, connectorOutputCaptureService, connectorStateService, gracefulShutdownService, systemTimeService, eventDispatcher, projectBillingService, dataMartService, connectorDefinitionService, connectorSourceCredentialsService, configService, connectorRunTriggerService) {
74
78
  this.dataMartRunRepository = dataMartRunRepository;
75
79
  this.processSpawner = processSpawner;
76
80
  this.storageConfigService = storageConfigService;
@@ -86,6 +90,7 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
86
90
  this.connectorDefinitionService = connectorDefinitionService;
87
91
  this.connectorSourceCredentialsService = connectorSourceCredentialsService;
88
92
  this.configService = configService;
93
+ this.connectorRunTriggerService = connectorRunTriggerService;
89
94
  }
90
95
  async executeInBackground(dataMart, run, payload, signal) {
91
96
  const runId = run.id;
@@ -102,6 +107,8 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
102
107
  let hasAnySuccessfulConfiguration = false;
103
108
  let wasCancelled = false;
104
109
  let operationBlockedException;
110
+ const chainMeta = (0, manual_backfill_range_1.readBackfillChainMeta)(run.additionalParams);
111
+ const segmentWindow = chainMeta ? (0, manual_backfill_range_1.readBackfillRange)((0, manual_backfill_range_1.unwrapRunPayload)(payload)) : undefined;
105
112
  try {
106
113
  if (this.gracefulShutdownService.isInShutdownMode()) {
107
114
  throw new connector_execution_error_1.ConnectorExecutionError('Skipping connector execution. Application is shutting down.', undefined, { dataMartId: dataMart.id, projectId: dataMart.projectId, runId });
@@ -119,7 +126,12 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
119
126
  }
120
127
  logFlusher = this.createRunLogFlusher(runId, liveLogs, liveErrors, hasOutputFromEarlierAttempt);
121
128
  logFlusher?.start();
122
- configurationResults = await this.runConnectorConfigurations(run, processId, dataMart, payload, signal, liveLogs, liveErrors);
129
+ if (chainMeta && segmentWindow) {
130
+ const startedMarker = (0, backfill_segment_1.buildSegmentMarker)(chainMeta, segmentWindow, 'started', this.systemTimeService.now().toISOString());
131
+ addBoundedMessage(capturedLogs, startedMarker);
132
+ addBoundedMessage(liveLogs, startedMarker);
133
+ }
134
+ configurationResults = await this.runConnectorConfigurations(run, processId, dataMart, payload, signal, liveLogs, liveErrors, chainMeta !== undefined);
123
135
  configurationResults.forEach(result => {
124
136
  result.logs.forEach(log => addBoundedMessage(capturedLogs, log));
125
137
  result.errors.forEach(error => addBoundedMessage(capturedErrors, error));
@@ -155,6 +167,37 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
155
167
  }
156
168
  }
157
169
  finally {
170
+ const isShuttingDown = this.gracefulShutdownService.isInShutdownMode();
171
+ const willBeInterrupted = isShuttingDown && !wasCancelled && !allConfigurationsSucceeded;
172
+ const anyDateProgress = configurationResults.some(result => result.backfillLoadedThrough !== undefined);
173
+ const chainStep = chainMeta &&
174
+ !wasCancelled &&
175
+ signal?.aborted !== true &&
176
+ !operationBlockedException &&
177
+ !willBeInterrupted
178
+ ? (0, manual_backfill_range_1.nextBackfillChainStep)(chainMeta, {
179
+ segmentSucceeded: allConfigurationsSucceeded,
180
+ anyProgressAdvanced: anyDateProgress,
181
+ }, (0, manual_backfill_range_1.getMaxManualBackfillDays)())
182
+ : undefined;
183
+ const chainContinues = chainStep?.action === 'continue';
184
+ if (chainMeta && segmentWindow && !wasCancelled && !willBeInterrupted) {
185
+ const reportedDays = configurationResults.flatMap(result => result.backfillLoadedThrough ? [result.backfillLoadedThrough] : []);
186
+ const loadedThrough = reportedDays.length > 0 ? reportedDays.reduce((a, b) => (a < b ? a : b)) : undefined;
187
+ const chainEnd = operationBlockedException
188
+ ? 'stopped'
189
+ : chainStep?.action === 'end'
190
+ ? chainStep.chainEnd
191
+ : undefined;
192
+ (0, connector_message_utils_1.addMessageToArray)(capturedLogs, (0, backfill_segment_1.buildSegmentMarker)(chainMeta, segmentWindow, allConfigurationsSucceeded ? 'completed' : 'failed', this.systemTimeService.now().toISOString(), {
193
+ loadedThrough,
194
+ configurationsLoaded: reportedDays.length,
195
+ configurationsTotal: configurationResults.length,
196
+ counted: hasAnySuccessfulConfiguration,
197
+ chainContinues,
198
+ ...(chainEnd ? { chainEnd } : {}),
199
+ }));
200
+ }
158
201
  const hasSuccessfulFieldsUpdate = configurationResults.some(result => result.success && result.fieldsUpdate);
159
202
  try {
160
203
  await this.persistSuccessfulFieldsUpdate(dataMart, configurationResults, runId);
@@ -180,21 +223,21 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
180
223
  }
181
224
  await logFlusher?.stop();
182
225
  const flushedSnapshot = logFlusher?.persistedSnapshot() ?? null;
183
- const persistedStatus = await this.updateRunStatus(runId, allConfigurationsSucceeded, capturedLogs, capturedErrors, operationBlockedException, wasCancelled, flushedSnapshot);
226
+ const persistedStatus = await this.updateRunStatus(runId, allConfigurationsSucceeded, capturedLogs, capturedErrors, operationBlockedException, wasCancelled, willBeInterrupted, flushedSnapshot, chainStep?.action === 'continue'
227
+ ? { run, dataMart, meta: chainStep.meta, window: chainStep.window }
228
+ : undefined);
184
229
  if (hasAnySuccessfulConfiguration &&
185
230
  persistedStatus !== null &&
186
231
  persistedStatus !== data_mart_run_status_enum_1.DataMartRunStatus.INTERRUPTED) {
187
232
  await this.projectBillingService.registerConnectorRunConsumption(dataMart, runId);
188
233
  }
189
- if (allConfigurationsSucceeded && persistedStatus !== null) {
234
+ if (persistedStatus === data_mart_run_status_enum_1.DataMartRunStatus.SUCCESS) {
190
235
  await this.eventDispatcher.publishExternal(new connector_run_event_1.ConnectorRunEvent(dataMart.id, runId, dataMart.projectId, run.createdById ?? 'system', run.runType, 'successfully'));
191
236
  }
192
- else if (persistedStatus !== null &&
193
- !wasCancelled &&
194
- !this.gracefulShutdownService.isInShutdownMode()) {
237
+ else if (persistedStatus !== null && !wasCancelled && !willBeInterrupted) {
195
238
  await this.eventDispatcher.publishExternal(new connector_run_event_1.ConnectorRunEvent(dataMart.id, runId, dataMart.projectId, run.createdById ?? 'system', run.runType, 'unsuccessfully'));
196
239
  }
197
- if (!hasSuccessfulFieldsUpdate) {
240
+ if (!hasSuccessfulFieldsUpdate && !chainContinues) {
198
241
  await this.actualizeSchemaAfterConnectorExecution(dataMart, runId);
199
242
  }
200
243
  this.gracefulShutdownService.unregisterActiveProcess(processId);
@@ -225,7 +268,7 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
225
268
  }
226
269
  }
227
270
  }
228
- async runConnectorConfigurations(run, processId, dataMart, payload, signal, liveLogs = [], liveErrors = []) {
271
+ async runConnectorConfigurations(run, processId, dataMart, payload, signal, liveLogs = [], liveErrors = [], isChainSegment = false) {
229
272
  const runId = run.id;
230
273
  const definition = dataMart.definition;
231
274
  const { connector } = definition;
@@ -549,6 +592,9 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
549
592
  logs: configLogs,
550
593
  errors: configErrors,
551
594
  fieldsUpdate,
595
+ ...(isChainSegment && backfillProgress[configId] !== undefined
596
+ ? { backfillLoadedThrough: backfillProgress[configId] }
597
+ : {}),
552
598
  });
553
599
  }
554
600
  }
@@ -742,7 +788,7 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
742
788
  });
743
789
  }, error => this.logger.warn(`Incremental log flush failed for run ${runId}: ${(0, internal_helpers_1.castError)(error).message}`));
744
790
  }
745
- async updateRunStatus(runId, allConfigurationsSucceeded, capturedLogs, capturedErrors, operationBlockedException, wasCancelled = false, flushedSnapshot = null) {
791
+ async updateRunStatus(runId, allConfigurationsSucceeded, capturedLogs, capturedErrors, operationBlockedException, wasCancelled = false, willBeInterrupted = false, flushedSnapshot = null, nextSegment) {
746
792
  let status = wasCancelled
747
793
  ? data_mart_run_status_enum_1.DataMartRunStatus.CANCELLED
748
794
  : allConfigurationsSucceeded
@@ -750,21 +796,37 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
750
796
  : operationBlockedException
751
797
  ? data_mart_run_status_enum_1.DataMartRunStatus.RESTRICTED
752
798
  : data_mart_run_status_enum_1.DataMartRunStatus.FAILED;
753
- if (!wasCancelled &&
754
- !allConfigurationsSucceeded &&
755
- this.gracefulShutdownService.isInShutdownMode()) {
799
+ if (willBeInterrupted) {
756
800
  status = data_mart_run_status_enum_1.DataMartRunStatus.INTERRUPTED;
757
801
  }
758
802
  const newLogStrings = capturedLogs.map(log => JSON.stringify(log));
759
803
  const newErrorStrings = capturedErrors.map(error => JSON.stringify(error));
760
- const { logs: logsToSave, errors: errorsToSave } = await this.mergeWithPersistedOutput(runId, newLogStrings, newErrorStrings, flushedSnapshot);
761
- const result = await this.dataMartRunRepository.update({ id: runId, status: (0, typeorm_2.In)(data_mart_run_cancellation_1.NON_TERMINAL_DATA_MART_RUN_STATUSES) }, {
762
- status,
763
- finishedAt: this.systemTimeService.now(),
764
- logs: logsToSave,
765
- errors: errorsToSave,
766
- });
767
- if (result.affected) {
804
+ const merged = await this.mergeWithPersistedOutput(runId, newLogStrings, newErrorStrings, flushedSnapshot);
805
+ let logsToSave = merged.logs;
806
+ const errorsToSave = merged.errors;
807
+ let landed;
808
+ try {
809
+ landed = await this.writeRunOutcome(runId, status, logsToSave, errorsToSave, nextSegment);
810
+ }
811
+ catch (error) {
812
+ if (!nextSegment)
813
+ throw error;
814
+ const failure = (0, internal_helpers_1.castError)(error);
815
+ this.logger.error(`Failed to queue the next backfill segment: ${failure.message}`, failure.stack, {
816
+ runId,
817
+ });
818
+ const queueWarning = 'Could not queue the next backfill segment. The backfill continues automatically within 15 minutes.';
819
+ logsToSave = this.capMergedEntries([
820
+ ...(logsToSave ?? []),
821
+ JSON.stringify({
822
+ type: connector_message_type_enum_1.ConnectorMessageType.WARNING,
823
+ at: this.systemTimeService.now().toISOString(),
824
+ warning: queueWarning,
825
+ }),
826
+ ]);
827
+ landed = await this.writeRunOutcome(runId, status, logsToSave, errorsToSave);
828
+ }
829
+ if (landed) {
768
830
  return status;
769
831
  }
770
832
  this.logger.log(`Skipped final status update for run ${runId}: run already reached a terminal status`);
@@ -773,6 +835,21 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
773
835
  }
774
836
  return null;
775
837
  }
838
+ async writeRunOutcome(runId, status, logs, errors, nextSegment) {
839
+ const result = await this.dataMartRunRepository.update({ id: runId, status: (0, typeorm_2.In)(data_mart_run_cancellation_1.NON_TERMINAL_DATA_MART_RUN_STATUSES) }, { status, finishedAt: this.systemTimeService.now(), logs, errors });
840
+ if (!result.affected)
841
+ return false;
842
+ if (!nextSegment)
843
+ return true;
844
+ const { run, dataMart, meta, window } = nextSegment;
845
+ if (status !== data_mart_run_status_enum_1.DataMartRunStatus.SUCCESS && status !== data_mart_run_status_enum_1.DataMartRunStatus.FAILED) {
846
+ this.logger.warn(`Not queueing backfill segment ${meta.segmentIndex} of ${meta.segmentsTotal}: run ended ${status}`, { dataMartId: run.dataMartId, projectId: dataMart.projectId, runId });
847
+ return true;
848
+ }
849
+ const nextRun = await (0, backfill_segment_1.createNextSegmentRun)(this.dataMartRunRepository, this.connectorRunTriggerService, run, dataMart, meta, window);
850
+ this.logger.log(`Queued backfill segment ${meta.segmentIndex} of ${meta.segmentsTotal} as run ${nextRun.id}`, { dataMartId: run.dataMartId, projectId: dataMart.projectId, runId, nextRunId: nextRun.id });
851
+ return true;
852
+ }
776
853
  async mergeWithPersistedOutput(runId, newLogStrings, newErrorStrings, flushedSnapshot = null) {
777
854
  const existing = await this.dataMartRunRepository.findOne({ where: { id: runId } });
778
855
  const existingLogs = this.discountFlushedEntries(existing?.logs ?? [], flushedSnapshot?.logs, newLogStrings);
@@ -824,6 +901,12 @@ let ConnectorExecutorService = ConnectorExecutorService_1 = class ConnectorExecu
824
901
  }
825
902
  };
826
903
  exports.ConnectorExecutorService = ConnectorExecutorService;
904
+ __decorate([
905
+ (0, typeorm_transactional_1.Transactional)(),
906
+ __metadata("design:type", Function),
907
+ __metadata("design:paramtypes", [String, String, Object, Object, Object]),
908
+ __metadata("design:returntype", Promise)
909
+ ], ConnectorExecutorService.prototype, "writeRunOutcome", null);
827
910
  exports.ConnectorExecutorService = ConnectorExecutorService = ConnectorExecutorService_1 = __decorate([
828
911
  (0, common_1.Injectable)(),
829
912
  __param(0, (0, typeorm_1.InjectRepository)(data_mart_run_entity_1.DataMartRun)),
@@ -841,6 +924,7 @@ exports.ConnectorExecutorService = ConnectorExecutorService = ConnectorExecutorS
841
924
  data_mart_service_1.DataMartService,
842
925
  connector_definition_service_1.ConnectorDefinitionService,
843
926
  connector_source_credentials_service_1.ConnectorSourceCredentialsService,
844
- config_1.ConfigService])
927
+ config_1.ConfigService,
928
+ connector_run_trigger_service_1.ConnectorRunTriggerService])
845
929
  ], ConnectorExecutorService);
846
930
  //# sourceMappingURL=connector-executor.service.js.map
@@ -17,6 +17,9 @@ export declare class ConnectorRunService {
17
17
  executeExistingRun(dataMart: DataMart, run: DataMartRun, payload?: Record<string, unknown> | null, signal?: AbortSignal): Promise<void>;
18
18
  getDataMartConnectorRunsByStatus(status: DataMartRunStatus): Promise<DataMartRun[]>;
19
19
  executeInterruptedRuns(): Promise<void>;
20
+ repairBackfillChains(): Promise<void>;
21
+ private hasLaterRun;
22
+ private queueChainSegment;
20
23
  private validateDataMartForConnector;
21
24
  private checkDataMartIsRunning;
22
25
  private createDataMartRun;