@owox/backend 0.24.0 → 0.25.0-next-20260430151351

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 (17) hide show
  1. package/dist/src/data-marts/data-destination-types/data-destination-providers.d.ts +2 -1
  2. package/dist/src/data-marts/data-destination-types/data-destination-providers.js +2 -0
  3. package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-aggregation-mapper.service.d.ts +12 -0
  4. package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-aggregation-mapper.service.js +72 -0
  5. package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-connector-api-data.service.js +4 -4
  6. package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-connector-api-schema.service.d.ts +4 -2
  7. package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-connector-api-schema.service.js +1 -24
  8. package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-type-mapper.service.d.ts +8 -6
  9. package/dist/src/data-marts/data-destination-types/looker-studio-connector/services/looker-studio-type-mapper.service.js +30 -1
  10. package/dist/src/data-marts/data-storage-types/field-aggregation.d.ts +4 -0
  11. package/dist/src/data-marts/data-storage-types/field-aggregation.js +60 -0
  12. package/dist/src/data-marts/dto/domain/report-data-header.dto.d.ts +5 -7
  13. package/dist/src/data-marts/dto/domain/report-data-header.dto.js +3 -1
  14. package/dist/src/data-marts/dto/domain/storage-field-type.d.ts +6 -0
  15. package/dist/src/data-marts/dto/domain/storage-field-type.js +3 -0
  16. package/dist/src/data-marts/services/blended-report-data.service.js +5 -3
  17. package/package.json +5 -5
@@ -27,6 +27,7 @@ import { LookerStudioConnectorApiService } from './looker-studio-connector/servi
27
27
  import { LookerStudioConnectorCredentialsValidator } from './looker-studio-connector/services/looker-studio-connector-credentials-validator';
28
28
  import { LookerStudioConnectorCredentialsProcessor } from './looker-studio-connector/services/looker-studio-connector-credentials-processor';
29
29
  import { LookerStudioConnectorSecretKeyRotator } from './looker-studio-connector/services/looker-studio-connector-secret-key-rotator';
30
+ import { LookerStudioAggregationMapperService } from './looker-studio-connector/services/looker-studio-aggregation-mapper.service';
30
31
  import { LookerStudioTypeMapperService } from './looker-studio-connector/services/looker-studio-type-mapper.service';
31
32
  import { EmailAccessValidator, GoogleChatAccessValidator, MsTeamsAccessValidator, SlackAccessValidator } from './ee/email/services/email-access-validator';
32
33
  import { EmailCredentialsValidator, GoogleChatCredentialsValidator, MsTeamsCredentialsValidator, SlackCredentialsValidator } from './ee/email/services/email-credentials-validator';
@@ -35,7 +36,7 @@ export declare const DATA_DESTINATION_CREDENTIALS_VALIDATOR_RESOLVER: unique sym
35
36
  export declare const DATA_DESTINATION_CREDENTIALS_PROCESSOR_RESOLVER: unique symbol;
36
37
  export declare const DATA_DESTINATION_REPORT_WRITER_RESOLVER: unique symbol;
37
38
  export declare const DATA_DESTINATION_SECRET_KEY_ROTATOR_RESOLVER: unique symbol;
38
- export declare const dataDestinationResolverProviders: (typeof AvailableDestinationTypesService | typeof DataDestinationPublicCredentialsFactory | typeof DataDestinationCredentialsUtils | typeof EmailReportWriter | typeof SlackReportWriter | typeof MsTeamsReportWriter | typeof GoogleChatReportWriter | typeof GoogleSheetsApiAdapterFactory | typeof SheetMetadataFormatter | typeof GoogleSheetsReportCreatedListener | typeof GoogleSheetsReportDeletedListener | typeof GoogleSheetsAccessValidator | typeof GoogleSheetsCredentialsValidator | typeof SheetHeaderFormatter | typeof SheetValuesFormatter | typeof GoogleSheetsReportWriter | typeof LookerStudioConnectorAccessValidator | typeof LookerStudioConnectorApiConfigService | typeof LookerStudioTypeMapperService | typeof LookerStudioConnectorApiDataService | typeof LookerStudioConnectorApiSchemaService | typeof LookerStudioConnectorApiService | typeof LookerStudioConnectorCredentialsValidator | typeof LookerStudioConnectorCredentialsProcessor | typeof LookerStudioConnectorSecretKeyRotator | typeof EmailAccessValidator | typeof SlackAccessValidator | typeof MsTeamsAccessValidator | typeof GoogleChatAccessValidator | typeof EmailCredentialsValidator | typeof SlackCredentialsValidator | typeof MsTeamsCredentialsValidator | typeof GoogleChatCredentialsValidator | {
39
+ export declare const dataDestinationResolverProviders: (typeof AvailableDestinationTypesService | typeof DataDestinationPublicCredentialsFactory | typeof DataDestinationCredentialsUtils | typeof EmailReportWriter | typeof SlackReportWriter | typeof MsTeamsReportWriter | typeof GoogleChatReportWriter | typeof GoogleSheetsApiAdapterFactory | typeof SheetMetadataFormatter | typeof GoogleSheetsReportCreatedListener | typeof GoogleSheetsReportDeletedListener | typeof GoogleSheetsAccessValidator | typeof GoogleSheetsCredentialsValidator | typeof SheetHeaderFormatter | typeof SheetValuesFormatter | typeof GoogleSheetsReportWriter | typeof LookerStudioConnectorAccessValidator | typeof LookerStudioConnectorApiConfigService | typeof LookerStudioAggregationMapperService | typeof LookerStudioTypeMapperService | typeof LookerStudioConnectorApiDataService | typeof LookerStudioConnectorApiSchemaService | typeof LookerStudioConnectorApiService | typeof LookerStudioConnectorCredentialsValidator | typeof LookerStudioConnectorCredentialsProcessor | typeof LookerStudioConnectorSecretKeyRotator | typeof EmailAccessValidator | typeof SlackAccessValidator | typeof MsTeamsAccessValidator | typeof GoogleChatAccessValidator | typeof EmailCredentialsValidator | typeof SlackCredentialsValidator | typeof MsTeamsCredentialsValidator | typeof GoogleChatCredentialsValidator | {
39
40
  provide: symbol;
40
41
  useFactory: (available: AvailableDestinationTypesService, ...validators: DataDestinationAccessValidator[]) => TypeResolver<DataDestinationType, DataDestinationAccessValidator>;
41
42
  inject: (typeof AvailableDestinationTypesService | typeof GoogleSheetsAccessValidator | typeof LookerStudioConnectorAccessValidator | typeof EmailAccessValidator | typeof SlackAccessValidator | typeof MsTeamsAccessValidator | typeof GoogleChatAccessValidator)[];
@@ -24,6 +24,7 @@ const looker_studio_connector_api_service_1 = require("./looker-studio-connector
24
24
  const looker_studio_connector_credentials_validator_1 = require("./looker-studio-connector/services/looker-studio-connector-credentials-validator");
25
25
  const looker_studio_connector_credentials_processor_1 = require("./looker-studio-connector/services/looker-studio-connector-credentials-processor");
26
26
  const looker_studio_connector_secret_key_rotator_1 = require("./looker-studio-connector/services/looker-studio-connector-secret-key-rotator");
27
+ const looker_studio_aggregation_mapper_service_1 = require("./looker-studio-connector/services/looker-studio-aggregation-mapper.service");
27
28
  const looker_studio_type_mapper_service_1 = require("./looker-studio-connector/services/looker-studio-type-mapper.service");
28
29
  const email_access_validator_1 = require("./ee/email/services/email-access-validator");
29
30
  const email_credentials_validator_1 = require("./ee/email/services/email-credentials-validator");
@@ -82,6 +83,7 @@ exports.dataDestinationResolverProviders = [
82
83
  looker_studio_connector_api_schema_service_1.LookerStudioConnectorApiSchemaService,
83
84
  looker_studio_connector_api_data_service_1.LookerStudioConnectorApiDataService,
84
85
  looker_studio_connector_api_service_1.LookerStudioConnectorApiService,
86
+ looker_studio_aggregation_mapper_service_1.LookerStudioAggregationMapperService,
85
87
  looker_studio_type_mapper_service_1.LookerStudioTypeMapperService,
86
88
  {
87
89
  provide: exports.DATA_DESTINATION_ACCESS_VALIDATOR_RESOLVER,
@@ -0,0 +1,12 @@
1
+ import { AggregateFunction } from '../../../dto/schemas/aggregate-function.schema';
2
+ import { AggregationType } from '../enums/aggregation-type.enum';
3
+ import { FieldConceptType } from '../enums/field-concept-type.enum';
4
+ import { FieldDataType } from '../enums/field-data-type.enum';
5
+ export interface AggregationSemantics {
6
+ conceptType: FieldConceptType;
7
+ defaultAggregationType?: AggregationType;
8
+ isReaggregatable?: boolean;
9
+ }
10
+ export declare class LookerStudioAggregationMapperService {
11
+ mapAggregateFunctionToLookerType(aggFunc: AggregateFunction | undefined, dataType: FieldDataType): AggregationSemantics;
12
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.LookerStudioAggregationMapperService = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const aggregation_type_enum_1 = require("../enums/aggregation-type.enum");
12
+ const field_concept_type_enum_1 = require("../enums/field-concept-type.enum");
13
+ const field_data_type_enum_1 = require("../enums/field-data-type.enum");
14
+ let LookerStudioAggregationMapperService = class LookerStudioAggregationMapperService {
15
+ mapAggregateFunctionToLookerType(aggFunc, dataType) {
16
+ if (aggFunc === undefined) {
17
+ return dataType === field_data_type_enum_1.FieldDataType.NUMBER
18
+ ? {
19
+ conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
20
+ defaultAggregationType: aggregation_type_enum_1.AggregationType.SUM,
21
+ isReaggregatable: true,
22
+ }
23
+ : { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
24
+ }
25
+ switch (aggFunc) {
26
+ case 'SUM':
27
+ return dataType === field_data_type_enum_1.FieldDataType.NUMBER
28
+ ? {
29
+ conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
30
+ defaultAggregationType: aggregation_type_enum_1.AggregationType.SUM,
31
+ isReaggregatable: true,
32
+ }
33
+ : { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
34
+ case 'MIN':
35
+ return dataType === field_data_type_enum_1.FieldDataType.NUMBER
36
+ ? {
37
+ conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
38
+ defaultAggregationType: aggregation_type_enum_1.AggregationType.MIN,
39
+ isReaggregatable: true,
40
+ }
41
+ : { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
42
+ case 'MAX':
43
+ return dataType === field_data_type_enum_1.FieldDataType.NUMBER
44
+ ? {
45
+ conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
46
+ defaultAggregationType: aggregation_type_enum_1.AggregationType.MAX,
47
+ isReaggregatable: true,
48
+ }
49
+ : { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
50
+ case 'COUNT':
51
+ return {
52
+ conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
53
+ defaultAggregationType: aggregation_type_enum_1.AggregationType.SUM,
54
+ isReaggregatable: true,
55
+ };
56
+ case 'COUNT_DISTINCT':
57
+ return { conceptType: field_concept_type_enum_1.FieldConceptType.METRIC, isReaggregatable: false };
58
+ case 'STRING_AGG':
59
+ case 'ANY_VALUE':
60
+ return { conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION };
61
+ default: {
62
+ const _exhaustive = aggFunc;
63
+ return _exhaustive;
64
+ }
65
+ }
66
+ }
67
+ };
68
+ exports.LookerStudioAggregationMapperService = LookerStudioAggregationMapperService;
69
+ exports.LookerStudioAggregationMapperService = LookerStudioAggregationMapperService = __decorate([
70
+ (0, common_1.Injectable)()
71
+ ], LookerStudioAggregationMapperService);
72
+ //# sourceMappingURL=looker-studio-aggregation-mapper.service.js.map
@@ -93,10 +93,10 @@ let LookerStudioConnectorApiDataService = LookerStudioConnectorApiDataService_1
93
93
  };
94
94
  }
95
95
  buildResponseSchema(filteredHeaders, storageType) {
96
- return filteredHeaders.map(header => ({
97
- name: header.name,
98
- dataType: this.typeMapperService.mapToLookerStudioDataType(header.storageFieldType, storageType),
99
- }));
96
+ return filteredHeaders.map(header => {
97
+ const field = this.typeMapperService.buildSchemaField(header, storageType);
98
+ return { name: field.name, dataType: field.dataType };
99
+ });
100
100
  }
101
101
  async readAndProcessData(reportReader, fieldIndexMap, rowLimit) {
102
102
  const allRows = [];
@@ -1,7 +1,9 @@
1
+ import { DataStorageType } from '../../../data-storage-types/enums/data-storage-type.enum';
1
2
  import { CachedReaderData } from '../../../dto/domain/cached-reader-data.dto';
3
+ import { ReportDataHeader } from '../../../dto/domain/report-data-header.dto';
2
4
  import { Report } from '../../../entities/report.entity';
3
5
  import { DataMartService } from '../../../services/data-mart.service';
4
- import { GetSchemaRequest, GetSchemaResponse } from '../schemas/get-schema.schema';
6
+ import { GetSchemaRequest, GetSchemaResponse, SchemaField } from '../schemas/get-schema.schema';
5
7
  import { LookerStudioTypeMapperService } from './looker-studio-type-mapper.service';
6
8
  export declare class LookerStudioConnectorApiSchemaService {
7
9
  private readonly dataMartService;
@@ -9,5 +11,5 @@ export declare class LookerStudioConnectorApiSchemaService {
9
11
  private readonly logger;
10
12
  constructor(dataMartService: DataMartService, typeMapperService: LookerStudioTypeMapperService);
11
13
  getSchema(request: GetSchemaRequest, report: Report, cachedReader: CachedReaderData): Promise<GetSchemaResponse>;
12
- private getSchemaFields;
14
+ getSchemaFields(reportDataHeaders: ReportDataHeader[], storageType: DataStorageType): SchemaField[];
13
15
  }
@@ -13,9 +13,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.LookerStudioConnectorApiSchemaService = void 0;
14
14
  const common_1 = require("@nestjs/common");
15
15
  const data_mart_service_1 = require("../../../services/data-mart.service");
16
- const aggregation_type_enum_1 = require("../enums/aggregation-type.enum");
17
- const field_concept_type_enum_1 = require("../enums/field-concept-type.enum");
18
- const field_data_type_enum_1 = require("../enums/field-data-type.enum");
19
16
  const looker_studio_type_mapper_service_1 = require("./looker-studio-type-mapper.service");
20
17
  let LookerStudioConnectorApiSchemaService = LookerStudioConnectorApiSchemaService_1 = class LookerStudioConnectorApiSchemaService {
21
18
  dataMartService;
@@ -37,27 +34,7 @@ let LookerStudioConnectorApiSchemaService = LookerStudioConnectorApiSchemaServic
37
34
  };
38
35
  }
39
36
  getSchemaFields(reportDataHeaders, storageType) {
40
- return reportDataHeaders.map(header => {
41
- const schemaField = {
42
- name: header.name,
43
- label: header.alias || header.name,
44
- description: header.description,
45
- dataType: this.typeMapperService.mapToLookerStudioDataType(header.storageFieldType, storageType),
46
- };
47
- if (schemaField.dataType === field_data_type_enum_1.FieldDataType.NUMBER) {
48
- schemaField.semantics = {
49
- conceptType: field_concept_type_enum_1.FieldConceptType.METRIC,
50
- isReaggregatable: true,
51
- };
52
- schemaField.defaultAggregationType = aggregation_type_enum_1.AggregationType.SUM;
53
- }
54
- else {
55
- schemaField.semantics = {
56
- conceptType: field_concept_type_enum_1.FieldConceptType.DIMENSION,
57
- };
58
- }
59
- return schemaField;
60
- });
37
+ return reportDataHeaders.map(header => this.typeMapperService.buildSchemaField(header, storageType));
61
38
  }
62
39
  };
63
40
  exports.LookerStudioConnectorApiSchemaService = LookerStudioConnectorApiSchemaService;
@@ -1,12 +1,14 @@
1
- import { AthenaFieldType } from '../../../data-storage-types/athena/enums/athena-field-type.enum';
2
- import { BigQueryFieldType } from '../../../data-storage-types/bigquery/enums/bigquery-field-type.enum';
3
- import { DatabricksFieldType } from '../../../data-storage-types/databricks/enums/databricks-field-type.enum';
4
1
  import { DataStorageType } from '../../../data-storage-types/enums/data-storage-type.enum';
5
- import { RedshiftFieldType } from '../../../data-storage-types/redshift/enums/redshift-field-type.enum';
6
- import { SnowflakeFieldType } from '../../../data-storage-types/snowflake/enums/snowflake-field-type.enum';
2
+ import { ReportDataHeader } from '../../../dto/domain/report-data-header.dto';
3
+ import { StorageFieldType } from '../../../dto/domain/storage-field-type';
7
4
  import { FieldDataType } from '../enums/field-data-type.enum';
5
+ import { SchemaField } from '../schemas/get-schema.schema';
6
+ import { LookerStudioAggregationMapperService } from './looker-studio-aggregation-mapper.service';
8
7
  export declare class LookerStudioTypeMapperService {
9
- mapToLookerStudioDataType(fieldType: BigQueryFieldType | AthenaFieldType | SnowflakeFieldType | RedshiftFieldType | DatabricksFieldType, storageType: DataStorageType): FieldDataType;
8
+ private readonly aggregationMapper;
9
+ constructor(aggregationMapper: LookerStudioAggregationMapperService);
10
+ mapToLookerStudioDataType(fieldType: StorageFieldType, storageType: DataStorageType): FieldDataType;
11
+ buildSchemaField(header: ReportDataHeader, storageType: DataStorageType): SchemaField;
10
12
  private mapBigQueryTypeToLookerStudio;
11
13
  private mapAthenaTypeToLookerStudio;
12
14
  private mapSnowflakeTypeToLookerStudio;
@@ -5,6 +5,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.LookerStudioTypeMapperService = void 0;
10
13
  const common_1 = require("@nestjs/common");
@@ -15,7 +18,12 @@ const data_storage_type_enum_1 = require("../../../data-storage-types/enums/data
15
18
  const redshift_field_type_enum_1 = require("../../../data-storage-types/redshift/enums/redshift-field-type.enum");
16
19
  const snowflake_field_type_enum_1 = require("../../../data-storage-types/snowflake/enums/snowflake-field-type.enum");
17
20
  const field_data_type_enum_1 = require("../enums/field-data-type.enum");
21
+ const looker_studio_aggregation_mapper_service_1 = require("./looker-studio-aggregation-mapper.service");
18
22
  let LookerStudioTypeMapperService = class LookerStudioTypeMapperService {
23
+ aggregationMapper;
24
+ constructor(aggregationMapper) {
25
+ this.aggregationMapper = aggregationMapper;
26
+ }
19
27
  mapToLookerStudioDataType(fieldType, storageType) {
20
28
  if (storageType === data_storage_type_enum_1.DataStorageType.GOOGLE_BIGQUERY ||
21
29
  storageType === data_storage_type_enum_1.DataStorageType.LEGACY_GOOGLE_BIGQUERY) {
@@ -35,6 +43,26 @@ let LookerStudioTypeMapperService = class LookerStudioTypeMapperService {
35
43
  }
36
44
  return field_data_type_enum_1.FieldDataType.STRING;
37
45
  }
46
+ buildSchemaField(header, storageType) {
47
+ const dataType = header.storageFieldType
48
+ ? this.mapToLookerStudioDataType(header.storageFieldType, storageType)
49
+ : field_data_type_enum_1.FieldDataType.STRING;
50
+ const { conceptType, defaultAggregationType, isReaggregatable } = this.aggregationMapper.mapAggregateFunctionToLookerType(header.aggregateFunction, dataType);
51
+ const field = {
52
+ name: header.name,
53
+ label: header.alias || header.name,
54
+ description: header.description,
55
+ dataType,
56
+ semantics: {
57
+ conceptType,
58
+ ...(isReaggregatable !== undefined && { isReaggregatable }),
59
+ },
60
+ };
61
+ if (defaultAggregationType !== undefined) {
62
+ field.defaultAggregationType = defaultAggregationType;
63
+ }
64
+ return field;
65
+ }
38
66
  mapBigQueryTypeToLookerStudio(type) {
39
67
  switch (type) {
40
68
  case bigquery_field_type_enum_1.BigQueryFieldType.INTEGER:
@@ -172,6 +200,7 @@ let LookerStudioTypeMapperService = class LookerStudioTypeMapperService {
172
200
  };
173
201
  exports.LookerStudioTypeMapperService = LookerStudioTypeMapperService;
174
202
  exports.LookerStudioTypeMapperService = LookerStudioTypeMapperService = __decorate([
175
- (0, common_1.Injectable)()
203
+ (0, common_1.Injectable)(),
204
+ __metadata("design:paramtypes", [looker_studio_aggregation_mapper_service_1.LookerStudioAggregationMapperService])
176
205
  ], LookerStudioTypeMapperService);
177
206
  //# sourceMappingURL=looker-studio-type-mapper.service.js.map
@@ -0,0 +1,4 @@
1
+ import { DataStorageType } from './enums/data-storage-type.enum';
2
+ import { AggregateFunction } from '../dto/schemas/aggregate-function.schema';
3
+ import { StorageFieldType } from '../dto/domain/storage-field-type';
4
+ export declare function computeEffectiveType(rawType: StorageFieldType, aggFunc: AggregateFunction | undefined, storageType: DataStorageType): StorageFieldType;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeEffectiveType = computeEffectiveType;
4
+ const athena_field_type_enum_1 = require("./athena/enums/athena-field-type.enum");
5
+ const bigquery_field_type_enum_1 = require("./bigquery/enums/bigquery-field-type.enum");
6
+ const databricks_field_type_enum_1 = require("./databricks/enums/databricks-field-type.enum");
7
+ const data_storage_type_enum_1 = require("./enums/data-storage-type.enum");
8
+ const redshift_field_type_enum_1 = require("./redshift/enums/redshift-field-type.enum");
9
+ const snowflake_field_type_enum_1 = require("./snowflake/enums/snowflake-field-type.enum");
10
+ function computeEffectiveType(rawType, aggFunc, storageType) {
11
+ if (!aggFunc)
12
+ return rawType;
13
+ switch (aggFunc) {
14
+ case 'COUNT':
15
+ case 'COUNT_DISTINCT':
16
+ return getIntegerType(storageType);
17
+ case 'STRING_AGG':
18
+ return getStringType(storageType);
19
+ case 'SUM':
20
+ case 'MIN':
21
+ case 'MAX':
22
+ case 'ANY_VALUE':
23
+ return rawType;
24
+ default: {
25
+ const _exhaustive = aggFunc;
26
+ return _exhaustive;
27
+ }
28
+ }
29
+ }
30
+ function getIntegerType(storageType) {
31
+ switch (storageType) {
32
+ case data_storage_type_enum_1.DataStorageType.GOOGLE_BIGQUERY:
33
+ case data_storage_type_enum_1.DataStorageType.LEGACY_GOOGLE_BIGQUERY:
34
+ return bigquery_field_type_enum_1.BigQueryFieldType.INTEGER;
35
+ case data_storage_type_enum_1.DataStorageType.AWS_ATHENA:
36
+ return athena_field_type_enum_1.AthenaFieldType.INTEGER;
37
+ case data_storage_type_enum_1.DataStorageType.SNOWFLAKE:
38
+ return snowflake_field_type_enum_1.SnowflakeFieldType.INTEGER;
39
+ case data_storage_type_enum_1.DataStorageType.AWS_REDSHIFT:
40
+ return redshift_field_type_enum_1.RedshiftFieldType.INTEGER;
41
+ case data_storage_type_enum_1.DataStorageType.DATABRICKS:
42
+ return databricks_field_type_enum_1.DatabricksFieldType.INT;
43
+ }
44
+ }
45
+ function getStringType(storageType) {
46
+ switch (storageType) {
47
+ case data_storage_type_enum_1.DataStorageType.GOOGLE_BIGQUERY:
48
+ case data_storage_type_enum_1.DataStorageType.LEGACY_GOOGLE_BIGQUERY:
49
+ return bigquery_field_type_enum_1.BigQueryFieldType.STRING;
50
+ case data_storage_type_enum_1.DataStorageType.AWS_ATHENA:
51
+ return athena_field_type_enum_1.AthenaFieldType.STRING;
52
+ case data_storage_type_enum_1.DataStorageType.SNOWFLAKE:
53
+ return snowflake_field_type_enum_1.SnowflakeFieldType.STRING;
54
+ case data_storage_type_enum_1.DataStorageType.AWS_REDSHIFT:
55
+ return redshift_field_type_enum_1.RedshiftFieldType.VARCHAR;
56
+ case data_storage_type_enum_1.DataStorageType.DATABRICKS:
57
+ return databricks_field_type_enum_1.DatabricksFieldType.STRING;
58
+ }
59
+ }
60
+ //# sourceMappingURL=field-aggregation.js.map
@@ -1,12 +1,10 @@
1
- import { BigQueryFieldType } from '../../data-storage-types/bigquery/enums/bigquery-field-type.enum';
2
- import { AthenaFieldType } from '../../data-storage-types/athena/enums/athena-field-type.enum';
3
- import { SnowflakeFieldType } from '../../data-storage-types/snowflake/enums/snowflake-field-type.enum';
4
- import { RedshiftFieldType } from '../../data-storage-types/redshift/enums/redshift-field-type.enum';
5
- import { DatabricksFieldType } from '../../data-storage-types/databricks/enums/databricks-field-type.enum';
1
+ import { AggregateFunction } from '../schemas/aggregate-function.schema';
2
+ import { StorageFieldType } from './storage-field-type';
6
3
  export declare class ReportDataHeader {
7
4
  readonly name: string;
8
5
  readonly alias?: string | undefined;
9
6
  readonly description?: string | undefined;
10
- readonly storageFieldType?: (BigQueryFieldType | AthenaFieldType | SnowflakeFieldType | RedshiftFieldType | DatabricksFieldType) | undefined;
11
- constructor(name: string, alias?: string | undefined, description?: string | undefined, storageFieldType?: (BigQueryFieldType | AthenaFieldType | SnowflakeFieldType | RedshiftFieldType | DatabricksFieldType) | undefined);
7
+ readonly storageFieldType?: StorageFieldType | undefined;
8
+ readonly aggregateFunction?: AggregateFunction | undefined;
9
+ constructor(name: string, alias?: string | undefined, description?: string | undefined, storageFieldType?: StorageFieldType | undefined, aggregateFunction?: AggregateFunction | undefined);
12
10
  }
@@ -6,11 +6,13 @@ class ReportDataHeader {
6
6
  alias;
7
7
  description;
8
8
  storageFieldType;
9
- constructor(name, alias, description, storageFieldType) {
9
+ aggregateFunction;
10
+ constructor(name, alias, description, storageFieldType, aggregateFunction) {
10
11
  this.name = name;
11
12
  this.alias = alias;
12
13
  this.description = description;
13
14
  this.storageFieldType = storageFieldType;
15
+ this.aggregateFunction = aggregateFunction;
14
16
  }
15
17
  }
16
18
  exports.ReportDataHeader = ReportDataHeader;
@@ -0,0 +1,6 @@
1
+ import { AthenaFieldType } from '../../data-storage-types/athena/enums/athena-field-type.enum';
2
+ import { BigQueryFieldType } from '../../data-storage-types/bigquery/enums/bigquery-field-type.enum';
3
+ import { DatabricksFieldType } from '../../data-storage-types/databricks/enums/databricks-field-type.enum';
4
+ import { RedshiftFieldType } from '../../data-storage-types/redshift/enums/redshift-field-type.enum';
5
+ import { SnowflakeFieldType } from '../../data-storage-types/snowflake/enums/snowflake-field-type.enum';
6
+ export type StorageFieldType = BigQueryFieldType | AthenaFieldType | SnowflakeFieldType | RedshiftFieldType | DatabricksFieldType;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=storage-field-type.js.map
@@ -16,6 +16,7 @@ const data_mart_relationship_service_1 = require("./data-mart-relationship.servi
16
16
  const data_mart_table_reference_service_1 = require("./data-mart-table-reference.service");
17
17
  const blended_query_builder_facade_1 = require("../data-storage-types/facades/blended-query-builder.facade");
18
18
  const report_data_header_dto_1 = require("../dto/domain/report-data-header.dto");
19
+ const field_aggregation_1 = require("../data-storage-types/field-aggregation");
19
20
  const public_origin_service_1 = require("../../common/config/public-origin.service");
20
21
  const business_violation_exception_1 = require("../../common/exceptions/business-violation.exception");
21
22
  const data_mart_url_helper_1 = require("../../common/helpers/data-mart-url.helper");
@@ -40,7 +41,7 @@ let BlendedReportDataService = class BlendedReportDataService {
40
41
  const blendableSchema = await this.blendableSchemaService.computeBlendableSchema(dataMart.id, dataMart.projectId);
41
42
  const blendedFieldsByName = new Map(blendableSchema.blendedFields.map(f => [f.name, f]));
42
43
  const hasBlendedColumns = columnConfig.some(col => blendedFieldsByName.has(col));
43
- const blendedDataHeaders = this.buildBlendedDataHeaders(columnConfig, blendedFieldsByName);
44
+ const blendedDataHeaders = this.buildBlendedDataHeaders(columnConfig, blendedFieldsByName, dataMart.storage.type);
44
45
  if (!hasBlendedColumns) {
45
46
  return {
46
47
  needsBlending: false,
@@ -67,12 +68,13 @@ let BlendedReportDataService = class BlendedReportDataService {
67
68
  blendedDataHeaders,
68
69
  };
69
70
  }
70
- buildBlendedDataHeaders(columnConfig, blendedFieldsByName) {
71
+ buildBlendedDataHeaders(columnConfig, blendedFieldsByName, storageType) {
71
72
  const headers = [];
72
73
  for (const col of columnConfig) {
73
74
  const blendedField = blendedFieldsByName.get(col);
74
75
  if (blendedField) {
75
- headers.push(new report_data_header_dto_1.ReportDataHeader(blendedField.name, `${blendedField.outputPrefix} ${blendedField.alias || blendedField.originalFieldName}`, blendedField.description || undefined, undefined));
76
+ const effectiveType = (0, field_aggregation_1.computeEffectiveType)(blendedField.type, blendedField.aggregateFunction, storageType);
77
+ headers.push(new report_data_header_dto_1.ReportDataHeader(blendedField.name, `${blendedField.outputPrefix} ${blendedField.alias || blendedField.originalFieldName}`, blendedField.description || undefined, effectiveType, blendedField.aggregateFunction));
76
78
  }
77
79
  }
78
80
  return headers;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owox/backend",
3
- "version": "0.24.0",
3
+ "version": "0.25.0-next-20260430151351",
4
4
  "description": "OWOX Data Marts Backend - Full-stack data orchestration platform",
5
5
  "author": "OWOX",
6
6
  "license": "ELv2",
@@ -78,9 +78,9 @@
78
78
  "@nestjs/schedule": "^6.0.0",
79
79
  "@nestjs/swagger": "^11.2.0",
80
80
  "@nestjs/typeorm": "^11.0.0",
81
- "@owox/connectors": "0.24.0",
82
- "@owox/idp-protocol": "0.24.0",
83
- "@owox/internal-helpers": "0.24.0",
81
+ "@owox/connectors": "0.25.0-next-20260430151351",
82
+ "@owox/idp-protocol": "0.25.0-next-20260430151351",
83
+ "@owox/internal-helpers": "0.25.0-next-20260430151351",
84
84
  "better-sqlite3": "^12.2.0",
85
85
  "class-transformer": "^0.5.1",
86
86
  "class-validator": "^0.14.2",
@@ -139,7 +139,7 @@
139
139
  "ts-node": "^10.9.2",
140
140
  "tsconfig-paths": "^4.2.0",
141
141
  "typeorm-ts-node-commonjs": "^0.3.20",
142
- "@owox/test-utils": "*"
142
+ "@owox/test-utils": "4.0.0-next-20260430151351"
143
143
  },
144
144
  "jest": {
145
145
  "moduleFileExtensions": [