@carbonbox/domain 0.48.1 → 0.49.1
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.
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationActivationRequirement.js +61 -0
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationCompletionRequirement.js +28 -0
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationActivationPolicy.js +349 -0
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationCompletionPolicy.js +151 -0
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationActivationFacts.js +2 -0
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationCompletionFacts.js +2 -0
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationRequirementContext.js +2 -0
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/CorporateCarbonFootprintConfigurationActivationFacts.js +2 -0
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationActivationRequirement.js +2 -0
- package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationCompletionRequirement.js +2 -0
- package/build/carbonbox/shared/domain/enums/ErrorCode.js +5 -1
- package/build/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyBlockingReason.js +104 -0
- package/build/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStep.js +52 -0
- package/build/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStepStatus.js +30 -0
- package/build/carbonbox/shared/domain/journeys/enums/PendingActionType.js +59 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/entity/IUserPreference.js +2 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/entity/UserPreference.js +122 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/exceptions/DuplicateUserPreferenceCodeError.js +31 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/exceptions/InvalidUserPreferenceCodeError.js +33 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/exceptions/UserPreferenceCodeLimitExceededError.js +31 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/repository/IUserPreferenceRepository.js +2 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/types/UserPreferencePrimitives.js +2 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/types/UserPreferenceProps.js +2 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceCodes.js +93 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceDismissedChecklistCodes.js +29 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceSeenOnboardingTourCodes.js +29 -0
- package/build/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceUserId.js +47 -0
- package/build/main/index.js +53 -16
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationActivationRequirement.d.ts +48 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationActivationRequirement.d.ts.map +1 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationCompletionRequirement.d.ts +22 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationCompletionRequirement.d.ts.map +1 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationActivationPolicy.d.ts +121 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationActivationPolicy.d.ts.map +1 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationCompletionPolicy.d.ts +71 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationCompletionPolicy.d.ts.map +1 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationActivationFacts.d.ts +16 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationActivationFacts.d.ts.map +1 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationCompletionFacts.d.ts +29 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationCompletionFacts.d.ts.map +1 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationRequirementContext.d.ts +34 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationRequirementContext.d.ts.map +1 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CorporateCarbonFootprintConfigurationActivationFacts.d.ts +22 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CorporateCarbonFootprintConfigurationActivationFacts.d.ts.map +1 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationActivationRequirement.d.ts +11 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationActivationRequirement.d.ts.map +1 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationCompletionRequirement.d.ts +11 -0
- package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationCompletionRequirement.d.ts.map +1 -0
- package/build/types/carbonbox/shared/domain/enums/ErrorCode.d.ts +4 -1
- package/build/types/carbonbox/shared/domain/enums/ErrorCode.d.ts.map +1 -1
- package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyBlockingReason.d.ts +93 -0
- package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyBlockingReason.d.ts.map +1 -0
- package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStep.d.ts +49 -0
- package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStep.d.ts.map +1 -0
- package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStepStatus.d.ts +27 -0
- package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStepStatus.d.ts.map +1 -0
- package/build/types/carbonbox/shared/domain/journeys/enums/PendingActionType.d.ts +56 -0
- package/build/types/carbonbox/shared/domain/journeys/enums/PendingActionType.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/entity/IUserPreference.d.ts +10 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/entity/IUserPreference.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/entity/UserPreference.d.ts +45 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/entity/UserPreference.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/DuplicateUserPreferenceCodeError.d.ts +7 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/DuplicateUserPreferenceCodeError.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/InvalidUserPreferenceCodeError.d.ts +7 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/InvalidUserPreferenceCodeError.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/UserPreferenceCodeLimitExceededError.d.ts +7 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/UserPreferenceCodeLimitExceededError.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/repository/IUserPreferenceRepository.d.ts +21 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/repository/IUserPreferenceRepository.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/types/UserPreferencePrimitives.d.ts +22 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/types/UserPreferencePrimitives.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/types/UserPreferenceProps.d.ts +18 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/types/UserPreferenceProps.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceCodes.d.ts +53 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceCodes.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceDismissedChecklistCodes.d.ts +16 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceDismissedChecklistCodes.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceSeenOnboardingTourCodes.d.ts +16 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceSeenOnboardingTourCodes.d.ts.map +1 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceUserId.d.ts +18 -0
- package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceUserId.d.ts.map +1 -0
- package/build/types/main/index.d.ts +26 -0
- package/build/types/main/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CarbonFootprintConfigurationActivationRequirement = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Requirements a carbon footprint configuration (corporate, event or
|
|
6
|
+
* product) must meet to move from `DRAFT` to `ACTIVE`.
|
|
7
|
+
*
|
|
8
|
+
* Each member identifies ONE rule evaluated by
|
|
9
|
+
* `CarbonFootprintConfigurationActivationPolicy`. The members are listed in
|
|
10
|
+
* the order the policy evaluates them; a given footprint type only
|
|
11
|
+
* evaluates the members that apply to it (e.g. `FACILITY_*` is corporate
|
|
12
|
+
* only, `ANALYSIS_UNIT_*` is event only).
|
|
13
|
+
*
|
|
14
|
+
* The detail needed to describe an unmet requirement (index, received value,
|
|
15
|
+
* dates...) travels in `CarbonFootprintConfigurationRequirementContext`.
|
|
16
|
+
*/
|
|
17
|
+
var CarbonFootprintConfigurationActivationRequirement;
|
|
18
|
+
(function (CarbonFootprintConfigurationActivationRequirement) {
|
|
19
|
+
// ─── Gates (all footprint types) ──────────────────────────────────────────
|
|
20
|
+
CarbonFootprintConfigurationActivationRequirement["CARBON_CLIENT_NOT_ENTITLED"] = "CARBON_CLIENT_NOT_ENTITLED";
|
|
21
|
+
CarbonFootprintConfigurationActivationRequirement["CONFIGURATION_MUST_BE_DRAFT"] = "CONFIGURATION_MUST_BE_DRAFT";
|
|
22
|
+
// ─── Segment configurations (corporate, product) ─────────────────────────
|
|
23
|
+
CarbonFootprintConfigurationActivationRequirement["SEGMENT_CONFIGURATION_REQUIRED"] = "SEGMENT_CONFIGURATION_REQUIRED";
|
|
24
|
+
CarbonFootprintConfigurationActivationRequirement["SEGMENT_CONFIGURATION_SEGMENT_ID_REQUIRED"] = "SEGMENT_CONFIGURATION_SEGMENT_ID_REQUIRED";
|
|
25
|
+
CarbonFootprintConfigurationActivationRequirement["SEGMENT_CONFIGURATION_EMISSION_SOURCE_REQUIRED"] = "SEGMENT_CONFIGURATION_EMISSION_SOURCE_REQUIRED";
|
|
26
|
+
// ─── Event edition lifecycle stage configurations (event) ────────────────
|
|
27
|
+
CarbonFootprintConfigurationActivationRequirement["LIFECYCLE_STAGE_CONFIGURATION_REQUIRED"] = "LIFECYCLE_STAGE_CONFIGURATION_REQUIRED";
|
|
28
|
+
CarbonFootprintConfigurationActivationRequirement["LIFECYCLE_STAGE_CONFIGURATION_STAGE_ID_REQUIRED"] = "LIFECYCLE_STAGE_CONFIGURATION_STAGE_ID_REQUIRED";
|
|
29
|
+
CarbonFootprintConfigurationActivationRequirement["LIFECYCLE_STAGE_CONFIGURATION_EMISSION_SOURCE_REQUIRED"] = "LIFECYCLE_STAGE_CONFIGURATION_EMISSION_SOURCE_REQUIRED";
|
|
30
|
+
// ─── Event edition and analysis unit (event) ─────────────────────────────
|
|
31
|
+
CarbonFootprintConfigurationActivationRequirement["EVENT_EDITION_REFERENCE_INCOMPLETE"] = "EVENT_EDITION_REFERENCE_INCOMPLETE";
|
|
32
|
+
CarbonFootprintConfigurationActivationRequirement["ANALYSIS_UNIT_REQUIRED"] = "ANALYSIS_UNIT_REQUIRED";
|
|
33
|
+
CarbonFootprintConfigurationActivationRequirement["ANALYSIS_UNIT_BENCHMARK_VALUE_INVALID"] = "ANALYSIS_UNIT_BENCHMARK_VALUE_INVALID";
|
|
34
|
+
CarbonFootprintConfigurationActivationRequirement["ANALYSIS_UNIT_MEASUREMENT_UNIT_INVALID"] = "ANALYSIS_UNIT_MEASUREMENT_UNIT_INVALID";
|
|
35
|
+
// ─── Product, system boundary and functional unit (product) ──────────────
|
|
36
|
+
CarbonFootprintConfigurationActivationRequirement["PRODUCT_REFERENCE_INCOMPLETE"] = "PRODUCT_REFERENCE_INCOMPLETE";
|
|
37
|
+
CarbonFootprintConfigurationActivationRequirement["SYSTEM_BOUNDARY_REFERENCE_INCOMPLETE"] = "SYSTEM_BOUNDARY_REFERENCE_INCOMPLETE";
|
|
38
|
+
CarbonFootprintConfigurationActivationRequirement["FUNCTIONAL_UNIT_REQUIRED"] = "FUNCTIONAL_UNIT_REQUIRED";
|
|
39
|
+
CarbonFootprintConfigurationActivationRequirement["FUNCTIONAL_UNIT_BENCHMARK_VALUE_INVALID"] = "FUNCTIONAL_UNIT_BENCHMARK_VALUE_INVALID";
|
|
40
|
+
CarbonFootprintConfigurationActivationRequirement["FUNCTIONAL_UNIT_MEASUREMENT_UNIT_REQUIRED"] = "FUNCTIONAL_UNIT_MEASUREMENT_UNIT_REQUIRED";
|
|
41
|
+
// ─── Execution period (corporate) ────────────────────────────────────────
|
|
42
|
+
CarbonFootprintConfigurationActivationRequirement["EXECUTION_PERIOD_START_DATE_REQUIRED"] = "EXECUTION_PERIOD_START_DATE_REQUIRED";
|
|
43
|
+
CarbonFootprintConfigurationActivationRequirement["EXECUTION_PERIOD_START_DATE_INVALID_FORMAT"] = "EXECUTION_PERIOD_START_DATE_INVALID_FORMAT";
|
|
44
|
+
CarbonFootprintConfigurationActivationRequirement["EXECUTION_PERIOD_START_DATE_TOO_OLD"] = "EXECUTION_PERIOD_START_DATE_TOO_OLD";
|
|
45
|
+
CarbonFootprintConfigurationActivationRequirement["EXECUTION_PERIOD_END_DATE_INVALID_FORMAT"] = "EXECUTION_PERIOD_END_DATE_INVALID_FORMAT";
|
|
46
|
+
CarbonFootprintConfigurationActivationRequirement["EXECUTION_PERIOD_START_DATE_NOT_BEFORE_END_DATE"] = "EXECUTION_PERIOD_START_DATE_NOT_BEFORE_END_DATE";
|
|
47
|
+
// ─── Intensity indicators (all footprint types) ──────────────────────────
|
|
48
|
+
CarbonFootprintConfigurationActivationRequirement["INTENSITY_INDICATOR_CONFIGURATIONS_INVALID"] = "INTENSITY_INDICATOR_CONFIGURATIONS_INVALID";
|
|
49
|
+
CarbonFootprintConfigurationActivationRequirement["INTENSITY_INDICATOR_ASSIGNMENT_REQUIRED"] = "INTENSITY_INDICATOR_ASSIGNMENT_REQUIRED";
|
|
50
|
+
CarbonFootprintConfigurationActivationRequirement["INTENSITY_INDICATOR_TARGET_VALUE_NOT_POSITIVE"] = "INTENSITY_INDICATOR_TARGET_VALUE_NOT_POSITIVE";
|
|
51
|
+
CarbonFootprintConfigurationActivationRequirement["INTENSITY_INDICATOR_BENCHMARK_VALUE_NOT_POSITIVE"] = "INTENSITY_INDICATOR_BENCHMARK_VALUE_NOT_POSITIVE";
|
|
52
|
+
// ─── Facilities (corporate) ──────────────────────────────────────────────
|
|
53
|
+
CarbonFootprintConfigurationActivationRequirement["FACILITY_REQUIRED"] = "FACILITY_REQUIRED";
|
|
54
|
+
CarbonFootprintConfigurationActivationRequirement["FACILITY_REFERENCE_INCOMPLETE"] = "FACILITY_REFERENCE_INCOMPLETE";
|
|
55
|
+
CarbonFootprintConfigurationActivationRequirement["FACILITY_NOT_FOUND"] = "FACILITY_NOT_FOUND";
|
|
56
|
+
// ─── Reporting standard (all footprint types) ────────────────────────────
|
|
57
|
+
CarbonFootprintConfigurationActivationRequirement["CARBON_FOOTPRINT_OBJECTIVE_TOO_SHORT"] = "CARBON_FOOTPRINT_OBJECTIVE_TOO_SHORT";
|
|
58
|
+
// ─── Ownership references (all footprint types) ──────────────────────────
|
|
59
|
+
CarbonFootprintConfigurationActivationRequirement["OWNED_BY_CARBON_CLIENT_REFERENCE_INCOMPLETE"] = "OWNED_BY_CARBON_CLIENT_REFERENCE_INCOMPLETE";
|
|
60
|
+
CarbonFootprintConfigurationActivationRequirement["CREATED_BY_STAKEHOLDER_REFERENCE_INCOMPLETE"] = "CREATED_BY_STAKEHOLDER_REFERENCE_INCOMPLETE";
|
|
61
|
+
})(CarbonFootprintConfigurationActivationRequirement || (exports.CarbonFootprintConfigurationActivationRequirement = CarbonFootprintConfigurationActivationRequirement = {}));
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CarbonFootprintConfigurationCompletionRequirement = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Requirements a carbon footprint configuration (corporate, event or
|
|
6
|
+
* product) must meet to move from `ACTIVE` to `COMPLETED`.
|
|
7
|
+
*
|
|
8
|
+
* Each member identifies ONE rule evaluated by
|
|
9
|
+
* `CarbonFootprintConfigurationCompletionPolicy`, listed in evaluation
|
|
10
|
+
* order. The `EXECUTION_PERIOD_*` members are corporate only: event and
|
|
11
|
+
* product footprints have no reporting window at footprint level.
|
|
12
|
+
*
|
|
13
|
+
* The detail needed to describe an unmet requirement travels in
|
|
14
|
+
* `CarbonFootprintConfigurationRequirementContext`.
|
|
15
|
+
*/
|
|
16
|
+
var CarbonFootprintConfigurationCompletionRequirement;
|
|
17
|
+
(function (CarbonFootprintConfigurationCompletionRequirement) {
|
|
18
|
+
// ─── Gates (all footprint types) ──────────────────────────────────────────
|
|
19
|
+
CarbonFootprintConfigurationCompletionRequirement["CARBON_CLIENT_NOT_ENTITLED"] = "CARBON_CLIENT_NOT_ENTITLED";
|
|
20
|
+
CarbonFootprintConfigurationCompletionRequirement["CONFIGURATION_MUST_BE_ACTIVE"] = "CONFIGURATION_MUST_BE_ACTIVE";
|
|
21
|
+
// ─── Execution period (corporate) ────────────────────────────────────────
|
|
22
|
+
CarbonFootprintConfigurationCompletionRequirement["EXECUTION_PERIOD_END_DATE_REQUIRED"] = "EXECUTION_PERIOD_END_DATE_REQUIRED";
|
|
23
|
+
CarbonFootprintConfigurationCompletionRequirement["EXECUTION_PERIOD_END_DATE_INVALID_FORMAT"] = "EXECUTION_PERIOD_END_DATE_INVALID_FORMAT";
|
|
24
|
+
CarbonFootprintConfigurationCompletionRequirement["EXECUTION_PERIOD_NOT_ENDED"] = "EXECUTION_PERIOD_NOT_ENDED";
|
|
25
|
+
// ─── Calculation and data coverage (all footprint types) ─────────────────
|
|
26
|
+
CarbonFootprintConfigurationCompletionRequirement["ACTIVE_CALCULATION_PROCESSES_PRESENT"] = "ACTIVE_CALCULATION_PROCESSES_PRESENT";
|
|
27
|
+
CarbonFootprintConfigurationCompletionRequirement["SCOPE_1_OR_SCOPE_2_SUBMISSION_REQUIRED"] = "SCOPE_1_OR_SCOPE_2_SUBMISSION_REQUIRED";
|
|
28
|
+
})(CarbonFootprintConfigurationCompletionRequirement || (exports.CarbonFootprintConfigurationCompletionRequirement = CarbonFootprintConfigurationCompletionRequirement = {}));
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CarbonFootprintConfigurationActivationPolicy = void 0;
|
|
4
|
+
const ReportingStandard_1 = require("../../../../shared/domain/enums/ReportingStandard");
|
|
5
|
+
const DateTimeFormattingDomainService_1 = require("../../../../shared/domain/services/implementations/DateTimeFormattingDomainService");
|
|
6
|
+
const MeasurementUnitType_1 = require("../../../event-configurations/domain/enums/MeasurementUnitType");
|
|
7
|
+
const CarbonFootprintConfigurationActivationRequirement_1 = require("../enums/CarbonFootprintConfigurationActivationRequirement");
|
|
8
|
+
const ConfigurationStatus_1 = require("../enums/ConfigurationStatus");
|
|
9
|
+
/**
|
|
10
|
+
* Pure domain policy that decides whether a carbon footprint configuration
|
|
11
|
+
* (corporate, event or product) can move from `DRAFT` to `ACTIVE`, and if
|
|
12
|
+
* not, which requirements it does not meet.
|
|
13
|
+
*
|
|
14
|
+
* Why this exists: the activation rules used to live only inside the
|
|
15
|
+
* `Activate*` command handlers, which throw on the FIRST broken rule. The
|
|
16
|
+
* web needs the complete list up front (readiness) and the command must keep
|
|
17
|
+
* rejecting exactly as before. Both now call this policy: the command throws
|
|
18
|
+
* from the first item, the readiness query returns the whole list.
|
|
19
|
+
*
|
|
20
|
+
* Every `evaluate*` method returns the unmet requirements in evaluation
|
|
21
|
+
* order (empty list = ready to activate). The order reproduces the command
|
|
22
|
+
* handlers, so `list[0]` is always the error the handler raised before this
|
|
23
|
+
* policy existed:
|
|
24
|
+
* 1. `CARBON_CLIENT_NOT_ENTITLED` (context: `configurationId`) — the
|
|
25
|
+
* entitlement gate runs before the handler body, so it goes first.
|
|
26
|
+
* 2. `CONFIGURATION_MUST_BE_DRAFT` (`configurationId`, `currentStatus`).
|
|
27
|
+
* When the status is not `DRAFT` nothing else is evaluated.
|
|
28
|
+
* 3. Footprint-type specific structure, in handler order:
|
|
29
|
+
* - corporate / product: `SEGMENT_CONFIGURATION_REQUIRED`; then, per
|
|
30
|
+
* item, `SEGMENT_CONFIGURATION_SEGMENT_ID_REQUIRED` and
|
|
31
|
+
* `SEGMENT_CONFIGURATION_EMISSION_SOURCE_REQUIRED` (`index`,
|
|
32
|
+
* `segmentConfigurationId`).
|
|
33
|
+
* - event: `LIFECYCLE_STAGE_CONFIGURATION_REQUIRED`; then, per item,
|
|
34
|
+
* `LIFECYCLE_STAGE_CONFIGURATION_STAGE_ID_REQUIRED` and
|
|
35
|
+
* `LIFECYCLE_STAGE_CONFIGURATION_EMISSION_SOURCE_REQUIRED` (`index`,
|
|
36
|
+
* `lifecycleStageConfigurationId`); `EVENT_EDITION_REFERENCE_INCOMPLETE`;
|
|
37
|
+
* `ANALYSIS_UNIT_REQUIRED` (suppresses the next two),
|
|
38
|
+
* `ANALYSIS_UNIT_BENCHMARK_VALUE_INVALID` (finite and >= 0),
|
|
39
|
+
* `ANALYSIS_UNIT_MEASUREMENT_UNIT_INVALID` (`receivedValue`).
|
|
40
|
+
* - product: `PRODUCT_REFERENCE_INCOMPLETE`,
|
|
41
|
+
* `SYSTEM_BOUNDARY_REFERENCE_INCOMPLETE`, `FUNCTIONAL_UNIT_REQUIRED`
|
|
42
|
+
* (suppresses the next two), `FUNCTIONAL_UNIT_BENCHMARK_VALUE_INVALID`
|
|
43
|
+
* (finite and >= 0), `FUNCTIONAL_UNIT_MEASUREMENT_UNIT_REQUIRED`.
|
|
44
|
+
* - corporate execution period: `EXECUTION_PERIOD_START_DATE_REQUIRED`
|
|
45
|
+
* or `EXECUTION_PERIOD_START_DATE_INVALID_FORMAT` (`startDate`,
|
|
46
|
+
* `parseErrorMessage`); `EXECUTION_PERIOD_START_DATE_TOO_OLD`
|
|
47
|
+
* (`startDate`, `earliestAllowedStartDate`: at most one year before
|
|
48
|
+
* `facts.evaluatedAt`); `EXECUTION_PERIOD_END_DATE_INVALID_FORMAT`
|
|
49
|
+
* (`endDate`, `parseErrorMessage`; only when an end date is set);
|
|
50
|
+
* `EXECUTION_PERIOD_START_DATE_NOT_BEFORE_END_DATE` (`startDate`,
|
|
51
|
+
* `endDate`). A date that is missing or cannot be parsed suppresses
|
|
52
|
+
* the requirements that compare it.
|
|
53
|
+
* 4. Intensity indicators (all types): `INTENSITY_INDICATOR_CONFIGURATIONS_INVALID`
|
|
54
|
+
* (not an array; suppresses the per-item checks); then, per item,
|
|
55
|
+
* `INTENSITY_INDICATOR_ASSIGNMENT_REQUIRED`,
|
|
56
|
+
* `INTENSITY_INDICATOR_TARGET_VALUE_NOT_POSITIVE` and
|
|
57
|
+
* `INTENSITY_INDICATOR_BENCHMARK_VALUE_NOT_POSITIVE` (`index`).
|
|
58
|
+
* 5. Facilities (corporate only): `FACILITY_REQUIRED`; then
|
|
59
|
+
* `FACILITY_REFERENCE_INCOMPLETE` for every reference without `id` or
|
|
60
|
+
* `commercialBranchName` (`index`, `facilityId`, `commercialBranchName`);
|
|
61
|
+
* then `FACILITY_NOT_FOUND` for every COMPLETE reference whose id is not
|
|
62
|
+
* in `facts.existingFacilityIds` (`index`, `facilityId`,
|
|
63
|
+
* `commercialBranchName`). All incomplete references are listed before
|
|
64
|
+
* any missing one because the handler validated completeness of the
|
|
65
|
+
* whole list before looking any facility up.
|
|
66
|
+
* 6. `CARBON_FOOTPRINT_OBJECTIVE_TOO_SHORT` (all types; `reportingStandard`,
|
|
67
|
+
* `minimumLength`) — only for `ISO_14064_1` and `HYBRID`.
|
|
68
|
+
* 7. `OWNED_BY_CARBON_CLIENT_REFERENCE_INCOMPLETE` and
|
|
69
|
+
* `CREATED_BY_STAKEHOLDER_REFERENCE_INCOMPLETE` (all types; both
|
|
70
|
+
* references need `id` and `displayName`).
|
|
71
|
+
*
|
|
72
|
+
* Dates: execution period dates are `DD/MM/YYYY` strings parsed with the
|
|
73
|
+
* domain `DateTimeFormattingDomainService` (pure, no I/O), exactly as the
|
|
74
|
+
* handlers did; "now" is never read from the clock but taken from
|
|
75
|
+
* `facts.evaluatedAt`, so the result only depends on the arguments.
|
|
76
|
+
*
|
|
77
|
+
* The policy is intentionally a pure function — it does not load data,
|
|
78
|
+
* throw, or mutate. Facts that need I/O (entitlement, existing facilities)
|
|
79
|
+
* are gathered by the caller and passed in.
|
|
80
|
+
*/
|
|
81
|
+
class CarbonFootprintConfigurationActivationPolicy {
|
|
82
|
+
constructor() {
|
|
83
|
+
// Static-only — not instantiable.
|
|
84
|
+
}
|
|
85
|
+
static evaluateCorporateConfiguration(primitives, facts) {
|
|
86
|
+
const gateRequirements = CarbonFootprintConfigurationActivationPolicy.evaluateGates(primitives, facts.isCarbonClientEntitledToFootprintType);
|
|
87
|
+
if (!CarbonFootprintConfigurationActivationPolicy.isDraft(primitives)) {
|
|
88
|
+
return gateRequirements;
|
|
89
|
+
}
|
|
90
|
+
return [
|
|
91
|
+
...gateRequirements,
|
|
92
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateSegmentConfigurations(primitives.segmentConfigurations),
|
|
93
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateExecutionPeriod(primitives.executionPeriod, facts.evaluatedAt),
|
|
94
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateIntensityIndicatorConfigurations(primitives.intensityIndicatorConfigurations),
|
|
95
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateFacilities(primitives.facilities, facts.existingFacilityIds),
|
|
96
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateCarbonFootprintObjective(primitives),
|
|
97
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateOwnershipReferences(primitives),
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
static evaluateEventConfiguration(primitives, facts) {
|
|
101
|
+
const gateRequirements = CarbonFootprintConfigurationActivationPolicy.evaluateGates(primitives, facts.isCarbonClientEntitledToFootprintType);
|
|
102
|
+
if (!CarbonFootprintConfigurationActivationPolicy.isDraft(primitives)) {
|
|
103
|
+
return gateRequirements;
|
|
104
|
+
}
|
|
105
|
+
return [
|
|
106
|
+
...gateRequirements,
|
|
107
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateLifecycleStageConfigurations(primitives.eventEditionLifecycleStageConfigurations),
|
|
108
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateEventEdition(primitives),
|
|
109
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateAnalysisUnit(primitives),
|
|
110
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateIntensityIndicatorConfigurations(primitives.intensityIndicatorConfigurations),
|
|
111
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateCarbonFootprintObjective(primitives),
|
|
112
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateOwnershipReferences(primitives),
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
static evaluateProductConfiguration(primitives, facts) {
|
|
116
|
+
const gateRequirements = CarbonFootprintConfigurationActivationPolicy.evaluateGates(primitives, facts.isCarbonClientEntitledToFootprintType);
|
|
117
|
+
if (!CarbonFootprintConfigurationActivationPolicy.isDraft(primitives)) {
|
|
118
|
+
return gateRequirements;
|
|
119
|
+
}
|
|
120
|
+
return [
|
|
121
|
+
...gateRequirements,
|
|
122
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateSegmentConfigurations(primitives.segmentConfigurations),
|
|
123
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateProduct(primitives),
|
|
124
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateSystemBoundary(primitives),
|
|
125
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateFunctionalUnit(primitives),
|
|
126
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateIntensityIndicatorConfigurations(primitives.intensityIndicatorConfigurations),
|
|
127
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateCarbonFootprintObjective(primitives),
|
|
128
|
+
...CarbonFootprintConfigurationActivationPolicy.evaluateOwnershipReferences(primitives),
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
static isDraft(primitives) {
|
|
132
|
+
return primitives.status === ConfigurationStatus_1.ConfigurationStatus.DRAFT;
|
|
133
|
+
}
|
|
134
|
+
static evaluateGates(primitives, isCarbonClientEntitledToFootprintType) {
|
|
135
|
+
const requirements = [];
|
|
136
|
+
if (!isCarbonClientEntitledToFootprintType) {
|
|
137
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.CARBON_CLIENT_NOT_ENTITLED, { configurationId: primitives.id }));
|
|
138
|
+
}
|
|
139
|
+
if (!CarbonFootprintConfigurationActivationPolicy.isDraft(primitives)) {
|
|
140
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.CONFIGURATION_MUST_BE_DRAFT, { configurationId: primitives.id, currentStatus: primitives.status }));
|
|
141
|
+
}
|
|
142
|
+
return requirements;
|
|
143
|
+
}
|
|
144
|
+
static evaluateSegmentConfigurations(segmentConfigurations) {
|
|
145
|
+
if (!Array.isArray(segmentConfigurations) || segmentConfigurations.length === 0) {
|
|
146
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.SEGMENT_CONFIGURATION_REQUIRED)];
|
|
147
|
+
}
|
|
148
|
+
const requirements = [];
|
|
149
|
+
segmentConfigurations.forEach((segmentConfiguration, index) => {
|
|
150
|
+
if (!segmentConfiguration?.segment?.id) {
|
|
151
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.SEGMENT_CONFIGURATION_SEGMENT_ID_REQUIRED, { index, segmentConfigurationId: segmentConfiguration?.id }));
|
|
152
|
+
}
|
|
153
|
+
if (!Array.isArray(segmentConfiguration?.emissionSourceConfigurations) || segmentConfiguration.emissionSourceConfigurations.length === 0) {
|
|
154
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.SEGMENT_CONFIGURATION_EMISSION_SOURCE_REQUIRED, { index, segmentConfigurationId: segmentConfiguration?.id }));
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
return requirements;
|
|
158
|
+
}
|
|
159
|
+
static evaluateLifecycleStageConfigurations(lifecycleStageConfigurations) {
|
|
160
|
+
if (!Array.isArray(lifecycleStageConfigurations) || lifecycleStageConfigurations.length === 0) {
|
|
161
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.LIFECYCLE_STAGE_CONFIGURATION_REQUIRED)];
|
|
162
|
+
}
|
|
163
|
+
const requirements = [];
|
|
164
|
+
lifecycleStageConfigurations.forEach((lifecycleStageConfiguration, index) => {
|
|
165
|
+
if (!lifecycleStageConfiguration?.stage?.id) {
|
|
166
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.LIFECYCLE_STAGE_CONFIGURATION_STAGE_ID_REQUIRED, { index, lifecycleStageConfigurationId: lifecycleStageConfiguration?.id }));
|
|
167
|
+
}
|
|
168
|
+
if (!Array.isArray(lifecycleStageConfiguration?.emissionSourceConfigurations) || lifecycleStageConfiguration.emissionSourceConfigurations.length === 0) {
|
|
169
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.LIFECYCLE_STAGE_CONFIGURATION_EMISSION_SOURCE_REQUIRED, { index, lifecycleStageConfigurationId: lifecycleStageConfiguration?.id }));
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
return requirements;
|
|
173
|
+
}
|
|
174
|
+
static evaluateEventEdition(primitives) {
|
|
175
|
+
const { eventEdition } = primitives;
|
|
176
|
+
if (!eventEdition || !eventEdition.id || !eventEdition.code || !eventEdition.name) {
|
|
177
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.EVENT_EDITION_REFERENCE_INCOMPLETE)];
|
|
178
|
+
}
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
static evaluateAnalysisUnit(primitives) {
|
|
182
|
+
const { analysisUnit } = primitives;
|
|
183
|
+
if (!analysisUnit) {
|
|
184
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.ANALYSIS_UNIT_REQUIRED)];
|
|
185
|
+
}
|
|
186
|
+
const requirements = [];
|
|
187
|
+
if (CarbonFootprintConfigurationActivationPolicy.isNotNonNegativeFiniteNumber(analysisUnit.benchmarkValue)) {
|
|
188
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.ANALYSIS_UNIT_BENCHMARK_VALUE_INVALID));
|
|
189
|
+
}
|
|
190
|
+
if (!Object.values(MeasurementUnitType_1.MeasurementUnitType).includes(analysisUnit.measurementUnit)) {
|
|
191
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.ANALYSIS_UNIT_MEASUREMENT_UNIT_INVALID, { receivedValue: String(analysisUnit.measurementUnit) }));
|
|
192
|
+
}
|
|
193
|
+
return requirements;
|
|
194
|
+
}
|
|
195
|
+
static evaluateProduct(primitives) {
|
|
196
|
+
const { product } = primitives;
|
|
197
|
+
if (!product || !product.id || !product.code || !product.name) {
|
|
198
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.PRODUCT_REFERENCE_INCOMPLETE)];
|
|
199
|
+
}
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
static evaluateSystemBoundary(primitives) {
|
|
203
|
+
const { systemBoundary } = primitives;
|
|
204
|
+
if (!systemBoundary || !systemBoundary.id || !systemBoundary.code || !systemBoundary.name || !systemBoundary.type) {
|
|
205
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.SYSTEM_BOUNDARY_REFERENCE_INCOMPLETE)];
|
|
206
|
+
}
|
|
207
|
+
return [];
|
|
208
|
+
}
|
|
209
|
+
static evaluateFunctionalUnit(primitives) {
|
|
210
|
+
const { functionalUnit } = primitives;
|
|
211
|
+
if (!functionalUnit) {
|
|
212
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.FUNCTIONAL_UNIT_REQUIRED)];
|
|
213
|
+
}
|
|
214
|
+
const requirements = [];
|
|
215
|
+
if (CarbonFootprintConfigurationActivationPolicy.isNotNonNegativeFiniteNumber(functionalUnit.benchmarkValue)) {
|
|
216
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.FUNCTIONAL_UNIT_BENCHMARK_VALUE_INVALID));
|
|
217
|
+
}
|
|
218
|
+
if (typeof functionalUnit.measurementUnit !== 'string' || functionalUnit.measurementUnit.trim() === '') {
|
|
219
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.FUNCTIONAL_UNIT_MEASUREMENT_UNIT_REQUIRED));
|
|
220
|
+
}
|
|
221
|
+
return requirements;
|
|
222
|
+
}
|
|
223
|
+
static evaluateExecutionPeriod(executionPeriod, evaluatedAt) {
|
|
224
|
+
const requirements = [];
|
|
225
|
+
const startDateValue = executionPeriod?.startDate || '';
|
|
226
|
+
const endDateValue = executionPeriod?.endDate || '';
|
|
227
|
+
const startDateResult = startDateValue === ''
|
|
228
|
+
? null
|
|
229
|
+
: CarbonFootprintConfigurationActivationPolicy.DATE_TIME_FORMATTING.parseDateString(startDateValue);
|
|
230
|
+
const endDateResult = endDateValue === ''
|
|
231
|
+
? null
|
|
232
|
+
: CarbonFootprintConfigurationActivationPolicy.DATE_TIME_FORMATTING.parseDateString(endDateValue);
|
|
233
|
+
if (startDateResult === null) {
|
|
234
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.EXECUTION_PERIOD_START_DATE_REQUIRED));
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
requirements.push(...startDateResult.fold((error) => [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.EXECUTION_PERIOD_START_DATE_INVALID_FORMAT, { startDate: startDateValue, parseErrorMessage: error.message })], (startDate) => CarbonFootprintConfigurationActivationPolicy.evaluateStartDateAge(startDateValue, startDate, evaluatedAt)));
|
|
238
|
+
}
|
|
239
|
+
if (endDateResult !== null) {
|
|
240
|
+
requirements.push(...endDateResult.fold((error) => [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.EXECUTION_PERIOD_END_DATE_INVALID_FORMAT, { endDate: endDateValue, parseErrorMessage: error.message })], () => []));
|
|
241
|
+
}
|
|
242
|
+
const startDate = startDateResult?.getRight();
|
|
243
|
+
const endDate = endDateResult?.getRight();
|
|
244
|
+
if (startDate !== undefined && endDate !== undefined && startDate >= endDate) {
|
|
245
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.EXECUTION_PERIOD_START_DATE_NOT_BEFORE_END_DATE, { startDate: startDateValue, endDate: endDateValue }));
|
|
246
|
+
}
|
|
247
|
+
return requirements;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* The start date may be at most `MAXIMUM_START_DATE_AGE_IN_YEARS` before
|
|
251
|
+
* the evaluation instant (same calendar arithmetic as the handler:
|
|
252
|
+
* `setFullYear(year - 1)` on a copy of "now").
|
|
253
|
+
*/
|
|
254
|
+
static evaluateStartDateAge(startDateValue, startDate, evaluatedAt) {
|
|
255
|
+
const earliestAllowedStartDate = new Date(evaluatedAt.getTime());
|
|
256
|
+
earliestAllowedStartDate.setFullYear(earliestAllowedStartDate.getFullYear() - CarbonFootprintConfigurationActivationPolicy.MAXIMUM_START_DATE_AGE_IN_YEARS);
|
|
257
|
+
if (startDate < earliestAllowedStartDate) {
|
|
258
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.EXECUTION_PERIOD_START_DATE_TOO_OLD, {
|
|
259
|
+
startDate: startDateValue,
|
|
260
|
+
earliestAllowedStartDate: CarbonFootprintConfigurationActivationPolicy.DATE_TIME_FORMATTING
|
|
261
|
+
.formatDateToString(earliestAllowedStartDate)
|
|
262
|
+
.getRight(),
|
|
263
|
+
})];
|
|
264
|
+
}
|
|
265
|
+
return [];
|
|
266
|
+
}
|
|
267
|
+
static evaluateIntensityIndicatorConfigurations(intensityIndicatorConfigurations) {
|
|
268
|
+
if (!Array.isArray(intensityIndicatorConfigurations)) {
|
|
269
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.INTENSITY_INDICATOR_CONFIGURATIONS_INVALID)];
|
|
270
|
+
}
|
|
271
|
+
const requirements = [];
|
|
272
|
+
intensityIndicatorConfigurations.forEach((intensityIndicatorConfiguration, index) => {
|
|
273
|
+
if (!intensityIndicatorConfiguration?.assignedIntensityIndicator?.id) {
|
|
274
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.INTENSITY_INDICATOR_ASSIGNMENT_REQUIRED, { index }));
|
|
275
|
+
}
|
|
276
|
+
if (CarbonFootprintConfigurationActivationPolicy.isNotPositiveNumber(intensityIndicatorConfiguration?.targetValue)) {
|
|
277
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.INTENSITY_INDICATOR_TARGET_VALUE_NOT_POSITIVE, { index }));
|
|
278
|
+
}
|
|
279
|
+
if (CarbonFootprintConfigurationActivationPolicy.isNotPositiveNumber(intensityIndicatorConfiguration?.benchmarkValue)) {
|
|
280
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.INTENSITY_INDICATOR_BENCHMARK_VALUE_NOT_POSITIVE, { index }));
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
return requirements;
|
|
284
|
+
}
|
|
285
|
+
static evaluateFacilities(facilities, existingFacilityIds) {
|
|
286
|
+
if (!Array.isArray(facilities) || facilities.length === 0) {
|
|
287
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.FACILITY_REQUIRED)];
|
|
288
|
+
}
|
|
289
|
+
const incompleteReferenceRequirements = [];
|
|
290
|
+
const missingFacilityRequirements = [];
|
|
291
|
+
facilities.forEach((facility, index) => {
|
|
292
|
+
if (!facility?.id || !facility.commercialBranchName) {
|
|
293
|
+
incompleteReferenceRequirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.FACILITY_REFERENCE_INCOMPLETE, { index, facilityId: facility?.id, commercialBranchName: facility?.commercialBranchName }));
|
|
294
|
+
}
|
|
295
|
+
else if (!existingFacilityIds.includes(facility.id)) {
|
|
296
|
+
missingFacilityRequirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.FACILITY_NOT_FOUND, { index, facilityId: facility.id, commercialBranchName: facility.commercialBranchName }));
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
return [...incompleteReferenceRequirements, ...missingFacilityRequirements];
|
|
300
|
+
}
|
|
301
|
+
static evaluateCarbonFootprintObjective(primitives) {
|
|
302
|
+
const { reportingStandard, carbonFootprintObjective } = primitives;
|
|
303
|
+
const minimumLength = CarbonFootprintConfigurationActivationPolicy.MINIMUM_CARBON_FOOTPRINT_OBJECTIVE_LENGTH;
|
|
304
|
+
if (!CarbonFootprintConfigurationActivationPolicy.STANDARDS_REQUIRING_DETAILED_OBJECTIVE.includes(reportingStandard)) {
|
|
305
|
+
return [];
|
|
306
|
+
}
|
|
307
|
+
if (!carbonFootprintObjective || carbonFootprintObjective.length < minimumLength) {
|
|
308
|
+
return [CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.CARBON_FOOTPRINT_OBJECTIVE_TOO_SHORT, { reportingStandard, minimumLength })];
|
|
309
|
+
}
|
|
310
|
+
return [];
|
|
311
|
+
}
|
|
312
|
+
static evaluateOwnershipReferences(primitives) {
|
|
313
|
+
const { ownedByCarbonClient, createdByStakeholder } = primitives;
|
|
314
|
+
const requirements = [];
|
|
315
|
+
if (!ownedByCarbonClient || !ownedByCarbonClient.id || !ownedByCarbonClient.displayName) {
|
|
316
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.OWNED_BY_CARBON_CLIENT_REFERENCE_INCOMPLETE));
|
|
317
|
+
}
|
|
318
|
+
if (!createdByStakeholder || !createdByStakeholder.id || !createdByStakeholder.displayName) {
|
|
319
|
+
requirements.push(CarbonFootprintConfigurationActivationPolicy.unmet(CarbonFootprintConfigurationActivationRequirement_1.CarbonFootprintConfigurationActivationRequirement.CREATED_BY_STAKEHOLDER_REFERENCE_INCOMPLETE));
|
|
320
|
+
}
|
|
321
|
+
return requirements;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Same predicate as the handlers' benchmark check: rejects non-numbers,
|
|
325
|
+
* `NaN`, `±Infinity` and negatives.
|
|
326
|
+
*/
|
|
327
|
+
static isNotNonNegativeFiniteNumber(value) {
|
|
328
|
+
return typeof value !== 'number' || !Number.isFinite(value) || value < 0;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Same predicate as the handlers' intensity indicator check: rejects
|
|
332
|
+
* non-numbers and values `<= 0`. `NaN` is NOT rejected (`NaN <= 0` is
|
|
333
|
+
* false), exactly as before.
|
|
334
|
+
*/
|
|
335
|
+
static isNotPositiveNumber(value) {
|
|
336
|
+
return typeof value !== 'number' || value <= 0;
|
|
337
|
+
}
|
|
338
|
+
static unmet(code, context = {}) {
|
|
339
|
+
return { code, context };
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
exports.CarbonFootprintConfigurationActivationPolicy = CarbonFootprintConfigurationActivationPolicy;
|
|
343
|
+
CarbonFootprintConfigurationActivationPolicy.MINIMUM_CARBON_FOOTPRINT_OBJECTIVE_LENGTH = 10;
|
|
344
|
+
CarbonFootprintConfigurationActivationPolicy.MAXIMUM_START_DATE_AGE_IN_YEARS = 1;
|
|
345
|
+
CarbonFootprintConfigurationActivationPolicy.STANDARDS_REQUIRING_DETAILED_OBJECTIVE = [
|
|
346
|
+
ReportingStandard_1.ReportingStandard.ISO_14064_1,
|
|
347
|
+
ReportingStandard_1.ReportingStandard.HYBRID,
|
|
348
|
+
];
|
|
349
|
+
CarbonFootprintConfigurationActivationPolicy.DATE_TIME_FORMATTING = DateTimeFormattingDomainService_1.DateTimeFormattingDomainService.create();
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CarbonFootprintConfigurationCompletionPolicy = void 0;
|
|
4
|
+
const GHGScope_1 = require("../../../../shared/domain/enums/GHGScope");
|
|
5
|
+
const ReportingStandard_1 = require("../../../../shared/domain/enums/ReportingStandard");
|
|
6
|
+
const DateTimeFormattingDomainService_1 = require("../../../../shared/domain/services/implementations/DateTimeFormattingDomainService");
|
|
7
|
+
const CarbonFootprintConfigurationCompletionRequirement_1 = require("../enums/CarbonFootprintConfigurationCompletionRequirement");
|
|
8
|
+
const ConfigurationStatus_1 = require("../enums/ConfigurationStatus");
|
|
9
|
+
/**
|
|
10
|
+
* Pure domain policy that decides whether a carbon footprint configuration
|
|
11
|
+
* (corporate, event or product) can move from `ACTIVE` to `COMPLETED`, and
|
|
12
|
+
* if not, which requirements it does not meet.
|
|
13
|
+
*
|
|
14
|
+
* Why this exists: the completion rules used to live only inside the
|
|
15
|
+
* `Complete*` command handlers, which throw on the FIRST broken rule. The
|
|
16
|
+
* command (throws from `list[0]`) and the readiness query (returns the whole
|
|
17
|
+
* list) now share this single source of truth.
|
|
18
|
+
*
|
|
19
|
+
* Every `evaluate*` method returns the unmet requirements in evaluation
|
|
20
|
+
* order (empty list = ready to complete), reproducing the handlers so that
|
|
21
|
+
* `list[0]` is always the error they raised before:
|
|
22
|
+
* 1. `CARBON_CLIENT_NOT_ENTITLED` (context: `configurationId`) — the
|
|
23
|
+
* entitlement gate runs before the handler body, so it goes first.
|
|
24
|
+
* 2. `CONFIGURATION_MUST_BE_ACTIVE` (`configurationId`, `currentStatus`).
|
|
25
|
+
* When the status is not `ACTIVE` nothing else is evaluated.
|
|
26
|
+
* 3. Corporate only — the execution period must have ended:
|
|
27
|
+
* `EXECUTION_PERIOD_END_DATE_REQUIRED`;
|
|
28
|
+
* `EXECUTION_PERIOD_END_DATE_INVALID_FORMAT` (`endDate`,
|
|
29
|
+
* `parseErrorMessage`); `EXECUTION_PERIOD_NOT_ENDED` (`endDate`,
|
|
30
|
+
* `evaluatedAt` as ISO-8601) when `facts.evaluatedAt` is before the end
|
|
31
|
+
* date. A missing or unparseable end date suppresses the last one.
|
|
32
|
+
* Event and product footprints have no reporting window at footprint
|
|
33
|
+
* level, so they skip this step.
|
|
34
|
+
* 4. `ACTIVE_CALCULATION_PROCESSES_PRESENT` (`activeCalculationProcessCount`)
|
|
35
|
+
* when calculation processes are still `SCHEDULED`, `QUEUED` or
|
|
36
|
+
* `RUNNING`.
|
|
37
|
+
* 5. `SCOPE_1_OR_SCOPE_2_SUBMISSION_REQUIRED` (`reportingStandard`,
|
|
38
|
+
* `emissionScopesFound`: distinct scopes in first-seen order, empty when
|
|
39
|
+
* there are no submissions) — only for `GHG_PROTOCOL` and `HYBRID`, when
|
|
40
|
+
* no activity data submission (any status) reports `SCOPE_1` or
|
|
41
|
+
* `SCOPE_2`.
|
|
42
|
+
*
|
|
43
|
+
* Dates: the end date is a `DD/MM/YYYY` string parsed with the domain
|
|
44
|
+
* `DateTimeFormattingDomainService` (pure, no I/O), exactly as the handler
|
|
45
|
+
* did; "now" is taken from `facts.evaluatedAt`, never from the clock.
|
|
46
|
+
*
|
|
47
|
+
* The policy is intentionally a pure function — it does not load data,
|
|
48
|
+
* throw, or mutate. Facts that need I/O (entitlement, calculation processes,
|
|
49
|
+
* submissions) are gathered by the caller and passed in.
|
|
50
|
+
*/
|
|
51
|
+
class CarbonFootprintConfigurationCompletionPolicy {
|
|
52
|
+
constructor() {
|
|
53
|
+
// Static-only — not instantiable.
|
|
54
|
+
}
|
|
55
|
+
static evaluateCorporateConfiguration(primitives, facts) {
|
|
56
|
+
const gateRequirements = CarbonFootprintConfigurationCompletionPolicy.evaluateGates(primitives, facts);
|
|
57
|
+
if (!CarbonFootprintConfigurationCompletionPolicy.isActive(primitives)) {
|
|
58
|
+
return gateRequirements;
|
|
59
|
+
}
|
|
60
|
+
return [
|
|
61
|
+
...gateRequirements,
|
|
62
|
+
...CarbonFootprintConfigurationCompletionPolicy.evaluateExecutionPeriodEnded(primitives.executionPeriod, facts.evaluatedAt),
|
|
63
|
+
...CarbonFootprintConfigurationCompletionPolicy.evaluateCalculationAndCoverage(primitives, facts),
|
|
64
|
+
];
|
|
65
|
+
}
|
|
66
|
+
static evaluateEventConfiguration(primitives, facts) {
|
|
67
|
+
return CarbonFootprintConfigurationCompletionPolicy.evaluateConfigurationWithoutExecutionPeriod(primitives, facts);
|
|
68
|
+
}
|
|
69
|
+
static evaluateProductConfiguration(primitives, facts) {
|
|
70
|
+
return CarbonFootprintConfigurationCompletionPolicy.evaluateConfigurationWithoutExecutionPeriod(primitives, facts);
|
|
71
|
+
}
|
|
72
|
+
static evaluateConfigurationWithoutExecutionPeriod(primitives, facts) {
|
|
73
|
+
const gateRequirements = CarbonFootprintConfigurationCompletionPolicy.evaluateGates(primitives, facts);
|
|
74
|
+
if (!CarbonFootprintConfigurationCompletionPolicy.isActive(primitives)) {
|
|
75
|
+
return gateRequirements;
|
|
76
|
+
}
|
|
77
|
+
return [
|
|
78
|
+
...gateRequirements,
|
|
79
|
+
...CarbonFootprintConfigurationCompletionPolicy.evaluateCalculationAndCoverage(primitives, facts),
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
static isActive(primitives) {
|
|
83
|
+
return primitives.status === ConfigurationStatus_1.ConfigurationStatus.ACTIVE;
|
|
84
|
+
}
|
|
85
|
+
static evaluateGates(primitives, facts) {
|
|
86
|
+
const requirements = [];
|
|
87
|
+
if (!facts.isCarbonClientEntitledToFootprintType) {
|
|
88
|
+
requirements.push(CarbonFootprintConfigurationCompletionPolicy.unmet(CarbonFootprintConfigurationCompletionRequirement_1.CarbonFootprintConfigurationCompletionRequirement.CARBON_CLIENT_NOT_ENTITLED, { configurationId: primitives.id }));
|
|
89
|
+
}
|
|
90
|
+
if (!CarbonFootprintConfigurationCompletionPolicy.isActive(primitives)) {
|
|
91
|
+
requirements.push(CarbonFootprintConfigurationCompletionPolicy.unmet(CarbonFootprintConfigurationCompletionRequirement_1.CarbonFootprintConfigurationCompletionRequirement.CONFIGURATION_MUST_BE_ACTIVE, { configurationId: primitives.id, currentStatus: primitives.status }));
|
|
92
|
+
}
|
|
93
|
+
return requirements;
|
|
94
|
+
}
|
|
95
|
+
static evaluateExecutionPeriodEnded(executionPeriod, evaluatedAt) {
|
|
96
|
+
const endDateValue = executionPeriod?.endDate || '';
|
|
97
|
+
if (endDateValue === '') {
|
|
98
|
+
return [CarbonFootprintConfigurationCompletionPolicy.unmet(CarbonFootprintConfigurationCompletionRequirement_1.CarbonFootprintConfigurationCompletionRequirement.EXECUTION_PERIOD_END_DATE_REQUIRED)];
|
|
99
|
+
}
|
|
100
|
+
return CarbonFootprintConfigurationCompletionPolicy.DATE_TIME_FORMATTING
|
|
101
|
+
.parseDateString(endDateValue)
|
|
102
|
+
.fold((error) => [CarbonFootprintConfigurationCompletionPolicy.unmet(CarbonFootprintConfigurationCompletionRequirement_1.CarbonFootprintConfigurationCompletionRequirement.EXECUTION_PERIOD_END_DATE_INVALID_FORMAT, { endDate: endDateValue, parseErrorMessage: error.message })], (endDate) => CarbonFootprintConfigurationCompletionPolicy.evaluateEndDateReached(endDateValue, endDate, evaluatedAt));
|
|
103
|
+
}
|
|
104
|
+
static evaluateEndDateReached(endDateValue, endDate, evaluatedAt) {
|
|
105
|
+
if (evaluatedAt < endDate) {
|
|
106
|
+
return [CarbonFootprintConfigurationCompletionPolicy.unmet(CarbonFootprintConfigurationCompletionRequirement_1.CarbonFootprintConfigurationCompletionRequirement.EXECUTION_PERIOD_NOT_ENDED, { endDate: endDateValue, evaluatedAt: evaluatedAt.toISOString() })];
|
|
107
|
+
}
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
static evaluateCalculationAndCoverage(primitives, facts) {
|
|
111
|
+
return [
|
|
112
|
+
...CarbonFootprintConfigurationCompletionPolicy.evaluateActiveCalculationProcesses(facts.activeCalculationProcessCount),
|
|
113
|
+
...CarbonFootprintConfigurationCompletionPolicy.evaluateScopeCoverage(primitives.reportingStandard, facts),
|
|
114
|
+
];
|
|
115
|
+
}
|
|
116
|
+
static evaluateActiveCalculationProcesses(activeCalculationProcessCount) {
|
|
117
|
+
if (activeCalculationProcessCount > 0) {
|
|
118
|
+
return [CarbonFootprintConfigurationCompletionPolicy.unmet(CarbonFootprintConfigurationCompletionRequirement_1.CarbonFootprintConfigurationCompletionRequirement.ACTIVE_CALCULATION_PROCESSES_PRESENT, { activeCalculationProcessCount })];
|
|
119
|
+
}
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* GHG Protocol coverage rule: the reporting period must include at least
|
|
124
|
+
* one Scope 1 or Scope 2 emission; Scope 3 alone is not a valid GHG
|
|
125
|
+
* Protocol report. The scope is declared per activity data submission.
|
|
126
|
+
*/
|
|
127
|
+
static evaluateScopeCoverage(reportingStandard, facts) {
|
|
128
|
+
if (!CarbonFootprintConfigurationCompletionPolicy.STANDARDS_REQUIRING_SCOPE_1_OR_SCOPE_2_COVERAGE.includes(reportingStandard)) {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
const { emissionScopesOfSubmissions } = facts;
|
|
132
|
+
const hasScope1OrScope2Submission = emissionScopesOfSubmissions.some((emissionScope) => CarbonFootprintConfigurationCompletionPolicy.SCOPES_SATISFYING_COVERAGE.includes(emissionScope));
|
|
133
|
+
if (hasScope1OrScope2Submission) {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
return [CarbonFootprintConfigurationCompletionPolicy.unmet(CarbonFootprintConfigurationCompletionRequirement_1.CarbonFootprintConfigurationCompletionRequirement.SCOPE_1_OR_SCOPE_2_SUBMISSION_REQUIRED, { reportingStandard, emissionScopesFound: Array.from(new Set(emissionScopesOfSubmissions)) })];
|
|
137
|
+
}
|
|
138
|
+
static unmet(code, context = {}) {
|
|
139
|
+
return { code, context };
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exports.CarbonFootprintConfigurationCompletionPolicy = CarbonFootprintConfigurationCompletionPolicy;
|
|
143
|
+
CarbonFootprintConfigurationCompletionPolicy.STANDARDS_REQUIRING_SCOPE_1_OR_SCOPE_2_COVERAGE = [
|
|
144
|
+
ReportingStandard_1.ReportingStandard.GHG_PROTOCOL,
|
|
145
|
+
ReportingStandard_1.ReportingStandard.HYBRID,
|
|
146
|
+
];
|
|
147
|
+
CarbonFootprintConfigurationCompletionPolicy.SCOPES_SATISFYING_COVERAGE = [
|
|
148
|
+
GHGScope_1.GHGScope.SCOPE_1,
|
|
149
|
+
GHGScope_1.GHGScope.SCOPE_2,
|
|
150
|
+
];
|
|
151
|
+
CarbonFootprintConfigurationCompletionPolicy.DATE_TIME_FORMATTING = DateTimeFormattingDomainService_1.DateTimeFormattingDomainService.create();
|