@carbonbox/domain 0.48.1 → 0.49.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 (85) hide show
  1. package/build/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationActivationRequirement.js +61 -0
  2. package/build/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationCompletionRequirement.js +28 -0
  3. package/build/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationActivationPolicy.js +349 -0
  4. package/build/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationCompletionPolicy.js +151 -0
  5. package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationActivationFacts.js +2 -0
  6. package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationCompletionFacts.js +2 -0
  7. package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationRequirementContext.js +2 -0
  8. package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/CorporateCarbonFootprintConfigurationActivationFacts.js +2 -0
  9. package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationActivationRequirement.js +2 -0
  10. package/build/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationCompletionRequirement.js +2 -0
  11. package/build/carbonbox/shared/domain/enums/ErrorCode.js +5 -1
  12. package/build/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyBlockingReason.js +104 -0
  13. package/build/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStep.js +52 -0
  14. package/build/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStepStatus.js +30 -0
  15. package/build/carbonbox/shared/domain/journeys/enums/PendingActionType.js +59 -0
  16. package/build/carbonbox/stakeholders/user-preferences/domain/entity/IUserPreference.js +2 -0
  17. package/build/carbonbox/stakeholders/user-preferences/domain/entity/UserPreference.js +122 -0
  18. package/build/carbonbox/stakeholders/user-preferences/domain/exceptions/DuplicateUserPreferenceCodeError.js +31 -0
  19. package/build/carbonbox/stakeholders/user-preferences/domain/exceptions/InvalidUserPreferenceCodeError.js +33 -0
  20. package/build/carbonbox/stakeholders/user-preferences/domain/exceptions/UserPreferenceCodeLimitExceededError.js +31 -0
  21. package/build/carbonbox/stakeholders/user-preferences/domain/repository/IUserPreferenceRepository.js +2 -0
  22. package/build/carbonbox/stakeholders/user-preferences/domain/types/UserPreferencePrimitives.js +2 -0
  23. package/build/carbonbox/stakeholders/user-preferences/domain/types/UserPreferenceProps.js +2 -0
  24. package/build/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceCodes.js +93 -0
  25. package/build/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceDismissedChecklistCodes.js +29 -0
  26. package/build/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceSeenOnboardingTourCodes.js +29 -0
  27. package/build/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceUserId.js +47 -0
  28. package/build/main/index.js +53 -16
  29. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationActivationRequirement.d.ts +48 -0
  30. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationActivationRequirement.d.ts.map +1 -0
  31. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationCompletionRequirement.d.ts +22 -0
  32. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/enums/CarbonFootprintConfigurationCompletionRequirement.d.ts.map +1 -0
  33. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationActivationPolicy.d.ts +121 -0
  34. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationActivationPolicy.d.ts.map +1 -0
  35. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationCompletionPolicy.d.ts +71 -0
  36. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/policies/CarbonFootprintConfigurationCompletionPolicy.d.ts.map +1 -0
  37. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationActivationFacts.d.ts +16 -0
  38. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationActivationFacts.d.ts.map +1 -0
  39. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationCompletionFacts.d.ts +29 -0
  40. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationCompletionFacts.d.ts.map +1 -0
  41. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationRequirementContext.d.ts +34 -0
  42. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CarbonFootprintConfigurationRequirementContext.d.ts.map +1 -0
  43. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CorporateCarbonFootprintConfigurationActivationFacts.d.ts +22 -0
  44. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/CorporateCarbonFootprintConfigurationActivationFacts.d.ts.map +1 -0
  45. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationActivationRequirement.d.ts +11 -0
  46. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationActivationRequirement.d.ts.map +1 -0
  47. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationCompletionRequirement.d.ts +11 -0
  48. package/build/types/carbonbox/carbon-footprint-configurations/shared/domain/types/UnmetCarbonFootprintConfigurationCompletionRequirement.d.ts.map +1 -0
  49. package/build/types/carbonbox/shared/domain/enums/ErrorCode.d.ts +4 -1
  50. package/build/types/carbonbox/shared/domain/enums/ErrorCode.d.ts.map +1 -1
  51. package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyBlockingReason.d.ts +93 -0
  52. package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyBlockingReason.d.ts.map +1 -0
  53. package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStep.d.ts +49 -0
  54. package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStep.d.ts.map +1 -0
  55. package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStepStatus.d.ts +27 -0
  56. package/build/types/carbonbox/shared/domain/journeys/enums/CarbonClientJourneyStepStatus.d.ts.map +1 -0
  57. package/build/types/carbonbox/shared/domain/journeys/enums/PendingActionType.d.ts +56 -0
  58. package/build/types/carbonbox/shared/domain/journeys/enums/PendingActionType.d.ts.map +1 -0
  59. package/build/types/carbonbox/stakeholders/user-preferences/domain/entity/IUserPreference.d.ts +10 -0
  60. package/build/types/carbonbox/stakeholders/user-preferences/domain/entity/IUserPreference.d.ts.map +1 -0
  61. package/build/types/carbonbox/stakeholders/user-preferences/domain/entity/UserPreference.d.ts +45 -0
  62. package/build/types/carbonbox/stakeholders/user-preferences/domain/entity/UserPreference.d.ts.map +1 -0
  63. package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/DuplicateUserPreferenceCodeError.d.ts +7 -0
  64. package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/DuplicateUserPreferenceCodeError.d.ts.map +1 -0
  65. package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/InvalidUserPreferenceCodeError.d.ts +7 -0
  66. package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/InvalidUserPreferenceCodeError.d.ts.map +1 -0
  67. package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/UserPreferenceCodeLimitExceededError.d.ts +7 -0
  68. package/build/types/carbonbox/stakeholders/user-preferences/domain/exceptions/UserPreferenceCodeLimitExceededError.d.ts.map +1 -0
  69. package/build/types/carbonbox/stakeholders/user-preferences/domain/repository/IUserPreferenceRepository.d.ts +21 -0
  70. package/build/types/carbonbox/stakeholders/user-preferences/domain/repository/IUserPreferenceRepository.d.ts.map +1 -0
  71. package/build/types/carbonbox/stakeholders/user-preferences/domain/types/UserPreferencePrimitives.d.ts +22 -0
  72. package/build/types/carbonbox/stakeholders/user-preferences/domain/types/UserPreferencePrimitives.d.ts.map +1 -0
  73. package/build/types/carbonbox/stakeholders/user-preferences/domain/types/UserPreferenceProps.d.ts +18 -0
  74. package/build/types/carbonbox/stakeholders/user-preferences/domain/types/UserPreferenceProps.d.ts.map +1 -0
  75. package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceCodes.d.ts +53 -0
  76. package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceCodes.d.ts.map +1 -0
  77. package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceDismissedChecklistCodes.d.ts +16 -0
  78. package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceDismissedChecklistCodes.d.ts.map +1 -0
  79. package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceSeenOnboardingTourCodes.d.ts +16 -0
  80. package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceSeenOnboardingTourCodes.d.ts.map +1 -0
  81. package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceUserId.d.ts +18 -0
  82. package/build/types/carbonbox/stakeholders/user-preferences/domain/value-objects/UserPreferenceUserId.d.ts.map +1 -0
  83. package/build/types/main/index.d.ts +26 -0
  84. package/build/types/main/index.d.ts.map +1 -1
  85. 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();
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });