@golemio/energetics 1.14.0 → 1.15.0-dev.2817183709

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 (61) hide show
  1. package/db/example/00_clear_test_data.sql +1 -0
  2. package/db/example/10_enapo_budova_spotrebic.sql +14 -0
  3. package/db/migrations/postgresql/20260821090000-enapo-gid-mapping-sync-comment.js +53 -0
  4. package/db/migrations/postgresql/20260827090000-enapo-gid-mapping-pk.js +53 -0
  5. package/db/migrations/postgresql/20260901090000-enapo-budova-spotrebic.js +53 -0
  6. package/db/migrations/postgresql/sqls/20260821090000-enapo-gid-mapping-sync-comment-down.sql +3 -0
  7. package/db/migrations/postgresql/sqls/20260821090000-enapo-gid-mapping-sync-comment-up.sql +4 -0
  8. package/db/migrations/postgresql/sqls/20260827090000-enapo-gid-mapping-pk-down.sql +4 -0
  9. package/db/migrations/postgresql/sqls/20260827090000-enapo-gid-mapping-pk-up.sql +17 -0
  10. package/db/migrations/postgresql/sqls/20260901090000-enapo-budova-spotrebic-down.sql +1 -0
  11. package/db/migrations/postgresql/sqls/20260901090000-enapo-budova-spotrebic-up.sql +20 -0
  12. package/db/scripts/ded_gid_mapping_mock_import.sql +4 -1
  13. package/dist/integration-engine/enapo/datasources/gid-mapping/EnapoGidMappingDataSource.d.ts +14 -0
  14. package/dist/integration-engine/enapo/datasources/gid-mapping/EnapoGidMappingDataSource.js +56 -0
  15. package/dist/integration-engine/enapo/datasources/gid-mapping/EnapoGidMappingDataSource.js.map +1 -0
  16. package/dist/integration-engine/enapo/helpers/EnapoGidMappingNormalizer.d.ts +43 -0
  17. package/dist/integration-engine/enapo/helpers/EnapoGidMappingNormalizer.js +193 -0
  18. package/dist/integration-engine/enapo/helpers/EnapoGidMappingNormalizer.js.map +1 -0
  19. package/dist/integration-engine/enapo/ioc/Di.js +11 -3
  20. package/dist/integration-engine/enapo/ioc/Di.js.map +1 -1
  21. package/dist/integration-engine/enapo/ioc/EnapoWorkerContainerToken.d.ts +4 -0
  22. package/dist/integration-engine/enapo/ioc/EnapoWorkerContainerToken.js +4 -0
  23. package/dist/integration-engine/enapo/ioc/EnapoWorkerContainerToken.js.map +1 -1
  24. package/dist/integration-engine/enapo/repositories/EnapoGidMappingRepository.d.ts +13 -0
  25. package/dist/integration-engine/enapo/repositories/EnapoGidMappingRepository.js +42 -0
  26. package/dist/integration-engine/enapo/repositories/EnapoGidMappingRepository.js.map +1 -0
  27. package/dist/integration-engine/enapo/workers/EnapoWorker.js +1 -0
  28. package/dist/integration-engine/enapo/workers/EnapoWorker.js.map +1 -1
  29. package/dist/integration-engine/enapo/workers/task/EnapoGidMappingSyncTask.d.ts +45 -0
  30. package/dist/integration-engine/enapo/workers/task/EnapoGidMappingSyncTask.js +121 -0
  31. package/dist/integration-engine/enapo/workers/task/EnapoGidMappingSyncTask.js.map +1 -0
  32. package/dist/output-gateway/repositories/EnoBuildingDetailRepository.d.ts +1 -0
  33. package/dist/output-gateway/repositories/EnoBuildingDetailRepository.js +10 -2
  34. package/dist/output-gateway/repositories/EnoBuildingDetailRepository.js.map +1 -1
  35. package/dist/output-gateway/repositories/EnoBuildingHeatSourcesRepository.d.ts +8 -0
  36. package/dist/output-gateway/repositories/EnoBuildingHeatSourcesRepository.js +51 -0
  37. package/dist/output-gateway/repositories/EnoBuildingHeatSourcesRepository.js.map +1 -0
  38. package/dist/output-gateway/repositories/interfaces/IEnoBuildingDetailAggregate.d.ts +2 -0
  39. package/dist/output-gateway/routers/interfaces/IEnoBuildingDetailResponse.d.ts +15 -0
  40. package/dist/output-gateway/routers/v2/V2EnoBuildingsRouter.js +1 -1
  41. package/dist/output-gateway/routers/v2/V2EnoBuildingsRouter.js.map +1 -1
  42. package/dist/output-gateway/transformations/EnoBuildingDetailTransformation.d.ts +1 -0
  43. package/dist/output-gateway/transformations/EnoBuildingDetailTransformation.js +17 -0
  44. package/dist/output-gateway/transformations/EnoBuildingDetailTransformation.js.map +1 -1
  45. package/dist/schema-definitions/datasources/enapo/gid-mapping/EnapoGidMappingCsvSchema.d.ts +3 -0
  46. package/dist/schema-definitions/datasources/enapo/gid-mapping/EnapoGidMappingCsvSchema.js +23 -0
  47. package/dist/schema-definitions/datasources/enapo/gid-mapping/EnapoGidMappingCsvSchema.js.map +1 -0
  48. package/dist/schema-definitions/datasources/enapo/gid-mapping/interfaces/IEnapoGidMappingCsvRow.d.ts +15 -0
  49. package/dist/schema-definitions/datasources/enapo/gid-mapping/interfaces/IEnapoGidMappingCsvRow.js +3 -0
  50. package/dist/schema-definitions/datasources/enapo/gid-mapping/interfaces/IEnapoGidMappingCsvRow.js.map +1 -0
  51. package/dist/schema-definitions/models/enapo/EnapoBudovaSpotrebicModel.d.ts +22 -0
  52. package/dist/schema-definitions/models/enapo/EnapoBudovaSpotrebicModel.js +58 -0
  53. package/dist/schema-definitions/models/enapo/EnapoBudovaSpotrebicModel.js.map +1 -0
  54. package/dist/schema-definitions/models/enapo/EnapoGidMappingModel.js +0 -1
  55. package/dist/schema-definitions/models/enapo/EnapoGidMappingModel.js.map +1 -1
  56. package/dist/schema-definitions/models/enapo/interfaces/IEnapoBudovaSpotrebic.d.ts +15 -0
  57. package/dist/schema-definitions/models/enapo/interfaces/IEnapoBudovaSpotrebic.js +3 -0
  58. package/dist/schema-definitions/models/enapo/interfaces/IEnapoBudovaSpotrebic.js.map +1 -0
  59. package/docs/implementation_documentation.md +43 -2
  60. package/docs/openapi-output.yaml +69 -37
  61. package/package.json +1 -1
@@ -25,6 +25,7 @@ truncate enapo_ppas_commercial_invoice;
25
25
  truncate enapo_ppas_commercial_invoice_installations;
26
26
  truncate enapo_ppas_commercial_invoice_device;
27
27
  truncate enapo_ppas_commercial_invoice_price;
28
+ truncate enapo_budova_spotrebic;
28
29
  truncate enapo_porsenna_buildings;
29
30
  truncate enapo_porsenna_devices;
30
31
  truncate enapo_porsenna_consumption;
@@ -0,0 +1,14 @@
1
+ INSERT INTO enapo_budova_spotrebic (id_bud_spotrebic, gid, kod_eno, id_budova, id_typ_bud_spotrebic, nazev_typ_bud_spotrebic,
2
+ nazev_spotrebic, poznamka, palivo, vykon_kw, monitoring, provoz_od, adresa) VALUES
3
+ (9001, 'GID100', 'GID100', 22354, 1, 'boiler',
4
+ '2x gas boiler Viessmann Vitocrossal 200', 'boiler nameplates', 2, 530.00, false, '2025-01-01',
5
+ 'Testovací 123/4, 100 00 Praha 10'),
6
+ (9002, 'GID100', 'GID100', 22354, 1, 'boiler',
7
+ 'Viadrus G100E - 120 kW', NULL, 2, 120.50, true, '2004-01-01',
8
+ 'Testovací 123/4, 100 00 Praha 10'),
9
+ (9003, 'GID100', 'GID100| GID200', 22354, 1, 'boiler',
10
+ 'Gas boiler - output not stated', 'info from building manager', 1, NULL, false, '2007-01-01',
11
+ 'Testovací 123/4, 100 00 Praha 10'),
12
+ (9003, 'GID200', 'GID100| GID200', 22355, 1, 'boiler',
13
+ 'Gas boiler - output not stated', 'info from building manager', 1, NULL, false, '2007-01-01',
14
+ 'Testovací 123/4, 100 00 Praha 10');
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var dbm;
4
+ var type;
5
+ var seed;
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+ var Promise;
9
+
10
+ /**
11
+ * We receive the dbmigrate dependency from dbmigrate initially.
12
+ * This enables us to not have to rely on NODE_PATH.
13
+ */
14
+ exports.setup = function(options, seedLink) {
15
+ dbm = options.dbmigrate;
16
+ type = dbm.dataType;
17
+ seed = seedLink;
18
+ Promise = options.Promise;
19
+ };
20
+
21
+ exports.up = function(db) {
22
+ var filePath = path.join(__dirname, 'sqls', '20260821090000-enapo-gid-mapping-sync-comment-up.sql');
23
+ return new Promise( function( resolve, reject ) {
24
+ fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25
+ if (err) return reject(err);
26
+ console.log('received data: ' + data);
27
+
28
+ resolve(data);
29
+ });
30
+ })
31
+ .then(function(data) {
32
+ return db.runSql(data);
33
+ });
34
+ };
35
+
36
+ exports.down = function(db) {
37
+ var filePath = path.join(__dirname, 'sqls', '20260821090000-enapo-gid-mapping-sync-comment-down.sql');
38
+ return new Promise( function( resolve, reject ) {
39
+ fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40
+ if (err) return reject(err);
41
+ console.log('received data: ' + data);
42
+
43
+ resolve(data);
44
+ });
45
+ })
46
+ .then(function(data) {
47
+ return db.runSql(data);
48
+ });
49
+ };
50
+
51
+ exports._meta = {
52
+ "version": 1
53
+ };
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var dbm;
4
+ var type;
5
+ var seed;
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+ var Promise;
9
+
10
+ /**
11
+ * We receive the dbmigrate dependency from dbmigrate initially.
12
+ * This enables us to not have to rely on NODE_PATH.
13
+ */
14
+ exports.setup = function(options, seedLink) {
15
+ dbm = options.dbmigrate;
16
+ type = dbm.dataType;
17
+ seed = seedLink;
18
+ Promise = options.Promise;
19
+ };
20
+
21
+ exports.up = function(db) {
22
+ var filePath = path.join(__dirname, 'sqls', '20260827090000-enapo-gid-mapping-pk-up.sql');
23
+ return new Promise( function( resolve, reject ) {
24
+ fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25
+ if (err) return reject(err);
26
+ console.log('received data: ' + data);
27
+
28
+ resolve(data);
29
+ });
30
+ })
31
+ .then(function(data) {
32
+ return db.runSql(data);
33
+ });
34
+ };
35
+
36
+ exports.down = function(db) {
37
+ var filePath = path.join(__dirname, 'sqls', '20260827090000-enapo-gid-mapping-pk-down.sql');
38
+ return new Promise( function( resolve, reject ) {
39
+ fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40
+ if (err) return reject(err);
41
+ console.log('received data: ' + data);
42
+
43
+ resolve(data);
44
+ });
45
+ })
46
+ .then(function(data) {
47
+ return db.runSql(data);
48
+ });
49
+ };
50
+
51
+ exports._meta = {
52
+ "version": 1
53
+ };
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var dbm;
4
+ var type;
5
+ var seed;
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+ var Promise;
9
+
10
+ /**
11
+ * We receive the dbmigrate dependency from dbmigrate initially.
12
+ * This enables us to not have to rely on NODE_PATH.
13
+ */
14
+ exports.setup = function(options, seedLink) {
15
+ dbm = options.dbmigrate;
16
+ type = dbm.dataType;
17
+ seed = seedLink;
18
+ Promise = options.Promise;
19
+ };
20
+
21
+ exports.up = function(db) {
22
+ var filePath = path.join(__dirname, 'sqls', '20260901090000-enapo-budova-spotrebic-up.sql');
23
+ return new Promise( function( resolve, reject ) {
24
+ fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
25
+ if (err) return reject(err);
26
+ console.log('received data: ' + data);
27
+
28
+ resolve(data);
29
+ });
30
+ })
31
+ .then(function(data) {
32
+ return db.runSql(data);
33
+ });
34
+ };
35
+
36
+ exports.down = function(db) {
37
+ var filePath = path.join(__dirname, 'sqls', '20260901090000-enapo-budova-spotrebic-down.sql');
38
+ return new Promise( function( resolve, reject ) {
39
+ fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
40
+ if (err) return reject(err);
41
+ console.log('received data: ' + data);
42
+
43
+ resolve(data);
44
+ });
45
+ })
46
+ .then(function(data) {
47
+ return db.runSql(data);
48
+ });
49
+ };
50
+
51
+ exports._meta = {
52
+ "version": 1
53
+ };
@@ -0,0 +1,3 @@
1
+ -- Restores the comment as it was created by 20260807090000-enapo-gid-mapping-om-detail-up.sql.
2
+
3
+ COMMENT ON TABLE enapo_gid_mapping IS 'Mapping of consumption points (EAN/EIC) to ENO building GIDs. Module-owned contract; currently seeded with mock data (link_source = ''mock''), the future sync task from the data-team dbt output (tmp.ded_gid_mapping) will use link_source = ''energobroker_kod_eno''.';
@@ -0,0 +1,4 @@
1
+ -- The mapping table is no longer mock-only: EnapoGidMappingSyncTask fills it daily from the
2
+ -- ded_gid_mapping CSV export. Only the table comment changes, no data or structure is touched.
3
+
4
+ COMMENT ON TABLE enapo_gid_mapping IS 'Mapping of consumption points (EAN/EIC) to ENO building GIDs. Module-owned contract, filled daily by EnapoGidMappingSyncTask from the ded_gid_mapping CSV export (every synced row gets link_source = ''manual_entry''); electricity and gas only, water/heat (''eb_cis_odb_mista'') is out of scope. Upsert-only keyed on (place_id, gid): nothing is ever deleted, so a mapping missing from a later export stays. A synced row overwrites a manual mock row (link_source = ''mock'') for the same (place_id, gid).';
@@ -0,0 +1,4 @@
1
+ -- Restores the original three-column primary key. Rows collapsed by the up migration are not restored
2
+ -- (the data is gone); this only rebuilds the constraint shape.
3
+ ALTER TABLE enapo_gid_mapping DROP CONSTRAINT enapo_gid_mapping_pk;
4
+ ALTER TABLE enapo_gid_mapping ADD CONSTRAINT enapo_gid_mapping_pk PRIMARY KEY (place_id, gid, link_source);
@@ -0,0 +1,17 @@
1
+ -- Drops link_source from the enapo_gid_mapping primary key. A consumption point (place_id) maps to a
2
+ -- building (gid) regardless of which source produced the link, so (place_id, gid) is the real identity.
3
+ -- The CSV sync now stores a single link_source ('manual_entry'), so several source rows for one
4
+ -- (place_id, gid) collapse to a single row that would otherwise violate the old three-column key.
5
+
6
+ -- Collapse rows that become duplicate under the new key before the constraint is added, so ADD
7
+ -- CONSTRAINT cannot fail on existing data. Per (place_id, gid) keep an active mapping (valid_to IS NULL)
8
+ -- and then the newest valid_from, matching EnapoGidMappingNormalizer.isPreferred.
9
+ DELETE FROM enapo_gid_mapping t
10
+ WHERE t.ctid NOT IN (
11
+ SELECT DISTINCT ON (place_id, gid) ctid
12
+ FROM enapo_gid_mapping
13
+ ORDER BY place_id, gid, (valid_to IS NULL) DESC, valid_from DESC NULLS LAST, ctid
14
+ );
15
+
16
+ ALTER TABLE enapo_gid_mapping DROP CONSTRAINT enapo_gid_mapping_pk;
17
+ ALTER TABLE enapo_gid_mapping ADD CONSTRAINT enapo_gid_mapping_pk PRIMARY KEY (place_id, gid);
@@ -0,0 +1 @@
1
+ DROP TABLE IF EXISTS enapo_budova_spotrebic;
@@ -0,0 +1,20 @@
1
+ CREATE TABLE enapo_budova_spotrebic (
2
+ id_bud_spotrebic int4 NOT NULL,
3
+ gid varchar NOT NULL,
4
+ kod_eno varchar(50) NOT NULL,
5
+ id_budova int4 NULL,
6
+ id_typ_bud_spotrebic int4 NULL,
7
+ nazev_typ_bud_spotrebic varchar(50) NULL,
8
+ nazev_spotrebic varchar(255) NULL,
9
+ poznamka varchar(500) NULL,
10
+ palivo int4 NULL,
11
+ vykon_kw numeric(12, 2) NULL,
12
+ monitoring bool NULL,
13
+ provoz_od date NULL,
14
+ adresa varchar(255) NULL,
15
+ created_at timestamptz DEFAULT now() NULL,
16
+ updated_at timestamptz NULL,
17
+ CONSTRAINT enapo_budova_spotrebic_pk PRIMARY KEY (id_bud_spotrebic, gid)
18
+ );
19
+
20
+ CREATE INDEX enapo_budova_spotrebic_gid_idx ON enapo_budova_spotrebic (gid);
@@ -9,7 +9,10 @@
9
9
  -- - Full refresh of mock rows only: rows are inserted with link_source = 'mock', so this
10
10
  -- script can be re-run any time and never touches future non-mock (sync task) rows.
11
11
  -- - The dbt table has no primary key; DISTINCT ON collapses duplicates per (place_id, gid),
12
- -- preferring an active mapping (valid_to IS NULL) and then the newest valid_from.
12
+ -- preferring an active mapping (valid_to IS NULL) and then the newest valid_from. This script
13
+ -- writes link_source = 'mock'; the sync task (EnapoGidMappingSyncTask) writes link_source =
14
+ -- 'manual_entry'. Both deduplicate on (place_id, gid) — the table primary key — so a synced row
15
+ -- and a mock row for the same point collapse to one (the sync run wins, being the later upsert).
13
16
  -- - id_type / commodity are resolved from each other so a row survives when only one of the
14
17
  -- two columns is filled: an explicit value wins, the other column is the fallback.
15
18
  -- commodity uses EB codes ('1' -> electricity, '2' -> gas) as well as the DeD names.
@@ -0,0 +1,14 @@
1
+ import { IEnapoGidMappingCsvRow } from "../../../../schema-definitions/datasources/enapo/gid-mapping/interfaces/IEnapoGidMappingCsvRow";
2
+ import { ISimpleConfig } from "@golemio/core/dist/helpers/configuration/ISimpleConfig";
3
+ /**
4
+ * Reads the ded_gid_mapping CSV export from blob storage over plain HTTP GET. The full blob URL comes
5
+ * from config so golem and rabin point at their own containers. It is a single value (not base + path):
6
+ * only one file is fetched, and a one-piece URL can carry a SAS token query string, which a
7
+ * base-plus-path join would drop.
8
+ */
9
+ export declare class EnapoGidMappingDataSource {
10
+ private config;
11
+ private static readonly DATASOURCE_NAME;
12
+ constructor(config: ISimpleConfig);
13
+ getAll(): Promise<IEnapoGidMappingCsvRow[]>;
14
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var EnapoGidMappingDataSource_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.EnapoGidMappingDataSource = void 0;
17
+ const EnapoGidMappingCsvSchema_1 = require("../../../../schema-definitions/datasources/enapo/gid-mapping/EnapoGidMappingCsvSchema");
18
+ const CoreToken_1 = require("@golemio/core/dist/helpers/ioc/CoreToken");
19
+ const integration_engine_1 = require("@golemio/core/dist/integration-engine");
20
+ const CSVDataTypeStrategy_1 = require("@golemio/core/dist/integration-engine/datasources/datatype-strategy/CSVDataTypeStrategy");
21
+ const HTTPFetchProtocolStrategy_1 = require("@golemio/core/dist/integration-engine/datasources/protocol-strategy/HTTPFetchProtocolStrategy");
22
+ const golemio_validator_1 = require("@golemio/core/dist/shared/golemio-validator");
23
+ const tsyringe_1 = require("@golemio/core/dist/shared/tsyringe");
24
+ /**
25
+ * Reads the ded_gid_mapping CSV export from blob storage over plain HTTP GET. The full blob URL comes
26
+ * from config so golem and rabin point at their own containers. It is a single value (not base + path):
27
+ * only one file is fetched, and a one-piece URL can carry a SAS token query string, which a
28
+ * base-plus-path join would drop.
29
+ */
30
+ let EnapoGidMappingDataSource = EnapoGidMappingDataSource_1 = class EnapoGidMappingDataSource {
31
+ constructor(config) {
32
+ this.config = config;
33
+ }
34
+ async getAll() {
35
+ const url = this.config.getValue("module.energetics.enapo.gidMapping.url");
36
+ const dataSource = new integration_engine_1.DataSource(EnapoGidMappingDataSource_1.DATASOURCE_NAME, new HTTPFetchProtocolStrategy_1.HTTPFetchProtocolStrategy({
37
+ headers: { Accept: "text/csv" },
38
+ method: "GET",
39
+ responseType: "text",
40
+ timeoutInSeconds: 30,
41
+ url,
42
+ }), new CSVDataTypeStrategy_1.CSVDataTypeStrategy({
43
+ fastcsvParams: { headers: true, delimiter: "," },
44
+ subscribe: (row) => row,
45
+ }), new golemio_validator_1.JSONSchemaValidator(EnapoGidMappingDataSource_1.DATASOURCE_NAME, EnapoGidMappingCsvSchema_1.enapoGidMappingCsvSchema));
46
+ return dataSource.getAll();
47
+ }
48
+ };
49
+ exports.EnapoGidMappingDataSource = EnapoGidMappingDataSource;
50
+ EnapoGidMappingDataSource.DATASOURCE_NAME = "EnapoGidMapping";
51
+ exports.EnapoGidMappingDataSource = EnapoGidMappingDataSource = EnapoGidMappingDataSource_1 = __decorate([
52
+ (0, tsyringe_1.injectable)(),
53
+ __param(0, (0, tsyringe_1.inject)(CoreToken_1.CoreToken.SimpleConfig)),
54
+ __metadata("design:paramtypes", [Object])
55
+ ], EnapoGidMappingDataSource);
56
+ //# sourceMappingURL=EnapoGidMappingDataSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnapoGidMappingDataSource.js","sourceRoot":"","sources":["../../../../../src/integration-engine/enapo/datasources/gid-mapping/EnapoGidMappingDataSource.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oIAAuG;AAGvG,wEAAqE;AACrE,8EAAmE;AACnE,iIAA8H;AAC9H,6IAA0I;AAC1I,mFAAkF;AAClF,iEAAwE;AAExE;;;;;GAKG;AAEI,IAAM,yBAAyB,iCAA/B,MAAM,yBAAyB;IAGlC,YAAoD,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAEtE,KAAK,CAAC,MAAM;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAS,wCAAwC,CAAC,CAAC;QAEnF,MAAM,UAAU,GAAG,IAAI,+BAAU,CAC7B,2BAAyB,CAAC,eAAe,EACzC,IAAI,qDAAyB,CAAC;YAC1B,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;YAC/B,MAAM,EAAE,KAAK;YACb,YAAY,EAAE,MAAM;YACpB,gBAAgB,EAAE,EAAE;YACpB,GAAG;SACN,CAAC,EACF,IAAI,yCAAmB,CAAC;YACpB,aAAa,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE;YAChD,SAAS,EAAE,CAAC,GAA2B,EAAE,EAAE,CAAC,GAAG;SAClD,CAAC,EACF,IAAI,uCAAmB,CAAC,2BAAyB,CAAC,eAAe,EAAE,mDAAwB,CAAC,CAC/F,CAAC;QAEF,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC;;AAzBQ,8DAAyB;AACV,yCAAe,GAAG,iBAAiB,AAApB,CAAqB;oCADnD,yBAAyB;IADrC,IAAA,qBAAU,GAAE;IAII,WAAA,IAAA,iBAAM,EAAC,qBAAS,CAAC,YAAY,CAAC,CAAA;;GAHlC,yBAAyB,CA0BrC"}
@@ -0,0 +1,43 @@
1
+ import { IEnapoGidMappingCsvRow } from "../../../schema-definitions/datasources/enapo/gid-mapping/interfaces/IEnapoGidMappingCsvRow";
2
+ import { IEnapoGidMapping } from "../../../schema-definitions/models/enapo/interfaces/IEnapoGidMapping";
3
+ type EnapoGidMappingSkipReason = "missing_required" | "place_id_too_long" | "invalid_date" | "contradicting_pair" | "unresolvable_commodity";
4
+ export interface IEnapoGidMappingSkipReport {
5
+ total: number;
6
+ byReason: Record<EnapoGidMappingSkipReason, number>;
7
+ samples: Record<EnapoGidMappingSkipReason, string[]>;
8
+ }
9
+ interface IEnapoGidMappingNormalizeResult {
10
+ mappings: IEnapoGidMapping[];
11
+ skipped: IEnapoGidMappingSkipReport;
12
+ outOfScopeCount: number;
13
+ }
14
+ /**
15
+ * Normalizes raw ded_gid_mapping CSV rows into rows written to energetics.enapo_gid_mapping. Deduplicates
16
+ * across the whole dataset (a per-row map cannot), so it is a plain helper, not an AbstractTransformation.
17
+ */
18
+ export declare class EnapoGidMappingNormalizer {
19
+ private static readonly EB_PLACEHOLDER_DATE;
20
+ private static readonly MAX_PLACE_ID_LENGTH;
21
+ private static readonly LINK_SOURCE;
22
+ private static readonly ISO_DATE_PATTERN;
23
+ private static readonly EXCLUDED_LINK_SOURCE;
24
+ private static readonly ELECTRICITY_CODES;
25
+ private static readonly GAS_CODES;
26
+ private static readonly HEAT_WATER_CODES;
27
+ private static readonly TRUE_VALUES;
28
+ private static readonly MAX_SAMPLES_PER_REASON;
29
+ private static readonly SKIP_REASONS;
30
+ normalize(rows: IEnapoGidMappingCsvRow[]): IEnapoGidMappingNormalizeResult;
31
+ private isOutOfScope;
32
+ private normalizeRow;
33
+ private describeMissing;
34
+ private emptyReport;
35
+ private skip;
36
+ private resolveIdType;
37
+ private resolveCommodity;
38
+ private isConsistentPair;
39
+ private parseDate;
40
+ private isRealDate;
41
+ private isPreferred;
42
+ }
43
+ export {};
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var EnapoGidMappingNormalizer_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.EnapoGidMappingNormalizer = void 0;
11
+ const tsyringe_1 = require("@golemio/core/dist/shared/tsyringe");
12
+ /**
13
+ * Normalizes raw ded_gid_mapping CSV rows into rows written to energetics.enapo_gid_mapping. Deduplicates
14
+ * across the whole dataset (a per-row map cannot), so it is a plain helper, not an AbstractTransformation.
15
+ */
16
+ let EnapoGidMappingNormalizer = EnapoGidMappingNormalizer_1 = class EnapoGidMappingNormalizer {
17
+ normalize(rows) {
18
+ const skipped = this.emptyReport();
19
+ const byKey = new Map();
20
+ let outOfScopeCount = 0;
21
+ for (const row of rows) {
22
+ if (this.isOutOfScope(row)) {
23
+ outOfScopeCount += 1;
24
+ continue;
25
+ }
26
+ const mapping = this.normalizeRow(row, skipped);
27
+ if (!mapping) {
28
+ continue;
29
+ }
30
+ const key = `${mapping.place_id}|${mapping.gid}`;
31
+ const current = byKey.get(key);
32
+ if (!current || this.isPreferred(mapping, current)) {
33
+ byKey.set(key, mapping);
34
+ }
35
+ }
36
+ return { mappings: [...byKey.values()], skipped, outOfScopeCount };
37
+ }
38
+ // Dropped before any other check so an out-of-scope row that is also malformed cannot inflate the defect counters.
39
+ isOutOfScope(row) {
40
+ const linkSource = (row.link_source ?? "").trim().toLowerCase();
41
+ const commodity = (row.commodity ?? "").trim().toLowerCase();
42
+ return (linkSource === EnapoGidMappingNormalizer_1.EXCLUDED_LINK_SOURCE ||
43
+ EnapoGidMappingNormalizer_1.HEAT_WATER_CODES.includes(commodity));
44
+ }
45
+ normalizeRow(row, skipped) {
46
+ const placeId = (row.place_id ?? "").trim();
47
+ const gid = (row.gid ?? "").trim();
48
+ if (!placeId || !gid) {
49
+ return this.skip(skipped, "missing_required", this.describeMissing(placeId, gid));
50
+ }
51
+ if (placeId.length > EnapoGidMappingNormalizer_1.MAX_PLACE_ID_LENGTH) {
52
+ return this.skip(skipped, "place_id_too_long", placeId);
53
+ }
54
+ const idTypeRaw = (row.id_type ?? "").trim().toLowerCase();
55
+ const commodityRaw = (row.commodity ?? "").trim().toLowerCase();
56
+ const idType = this.resolveIdType(idTypeRaw, commodityRaw);
57
+ const commodity = this.resolveCommodity(idTypeRaw, commodityRaw);
58
+ if (!idType || !commodity) {
59
+ return this.skip(skipped, "unresolvable_commodity", placeId);
60
+ }
61
+ // EAN is always electricity, EIC always gas, so a disagreeing pair is bad source data.
62
+ if (!this.isConsistentPair(idType, commodity)) {
63
+ return this.skip(skipped, "contradicting_pair", placeId);
64
+ }
65
+ const validFrom = this.parseDate(row.valid_from);
66
+ const validTo = this.parseDate(row.valid_to);
67
+ if (!validFrom.isValid || !validTo.isValid) {
68
+ return this.skip(skipped, "invalid_date", `${placeId} (${row.valid_from ?? ""}/${row.valid_to ?? ""})`);
69
+ }
70
+ return {
71
+ place_id: placeId,
72
+ id_type: idType,
73
+ commodity,
74
+ gid,
75
+ is_first_gid: EnapoGidMappingNormalizer_1.TRUE_VALUES.includes((row.is_first_gid ?? "").trim().toLowerCase()),
76
+ link_source: EnapoGidMappingNormalizer_1.LINK_SOURCE,
77
+ valid_from: validFrom.value,
78
+ valid_to: validTo.value === EnapoGidMappingNormalizer_1.EB_PLACEHOLDER_DATE ? null : validTo.value,
79
+ };
80
+ }
81
+ // Names the missing columns and keeps whatever identifier the row still has, so the logged sample says what is wrong.
82
+ describeMissing(placeId, gid) {
83
+ const missing = [];
84
+ if (!placeId) {
85
+ missing.push("place_id");
86
+ }
87
+ if (!gid) {
88
+ missing.push("gid");
89
+ }
90
+ const present = [placeId ? `place_id=${placeId}` : null, gid ? `gid=${gid}` : null].filter((part) => part !== null);
91
+ return `missing ${missing.join("+")}${present.length > 0 ? ` (${present.join(", ")})` : ""}`;
92
+ }
93
+ emptyReport() {
94
+ const byReason = {};
95
+ const samples = {};
96
+ for (const reason of EnapoGidMappingNormalizer_1.SKIP_REASONS) {
97
+ byReason[reason] = 0;
98
+ samples[reason] = [];
99
+ }
100
+ return { total: 0, byReason, samples };
101
+ }
102
+ skip(report, reason, sample) {
103
+ report.total += 1;
104
+ report.byReason[reason] += 1;
105
+ if (report.samples[reason].length < EnapoGidMappingNormalizer_1.MAX_SAMPLES_PER_REASON && sample) {
106
+ report.samples[reason].push(sample);
107
+ }
108
+ return null;
109
+ }
110
+ resolveIdType(idTypeRaw, commodityRaw) {
111
+ if (idTypeRaw === "ean" || idTypeRaw === "eic") {
112
+ return idTypeRaw;
113
+ }
114
+ if (EnapoGidMappingNormalizer_1.ELECTRICITY_CODES.includes(commodityRaw)) {
115
+ return "ean";
116
+ }
117
+ if (EnapoGidMappingNormalizer_1.GAS_CODES.includes(commodityRaw)) {
118
+ return "eic";
119
+ }
120
+ return null;
121
+ }
122
+ resolveCommodity(idTypeRaw, commodityRaw) {
123
+ if (EnapoGidMappingNormalizer_1.ELECTRICITY_CODES.includes(commodityRaw)) {
124
+ return "electricity";
125
+ }
126
+ if (EnapoGidMappingNormalizer_1.GAS_CODES.includes(commodityRaw)) {
127
+ return "gas";
128
+ }
129
+ if (idTypeRaw === "ean") {
130
+ return "electricity";
131
+ }
132
+ if (idTypeRaw === "eic") {
133
+ return "gas";
134
+ }
135
+ return null;
136
+ }
137
+ isConsistentPair(idType, commodity) {
138
+ return (idType === "ean" && commodity === "electricity") || (idType === "eic" && commodity === "gas");
139
+ }
140
+ // Empty cell is a valid null; a timestamp suffix is tolerated (only the date part is stored). Anything
141
+ // that is not a real ISO calendar date is rejected, because the target columns are typed date.
142
+ parseDate(raw) {
143
+ const value = (raw ?? "").trim();
144
+ if (!value) {
145
+ return { isValid: true, value: null };
146
+ }
147
+ const datePart = value.slice(0, 10);
148
+ if (!EnapoGidMappingNormalizer_1.ISO_DATE_PATTERN.test(datePart) || !this.isRealDate(datePart)) {
149
+ return { isValid: false, value: null };
150
+ }
151
+ return { isValid: true, value: datePart };
152
+ }
153
+ // Guards against a well-shaped but non-existent date such as 2019-02-31 that the pattern alone lets through.
154
+ isRealDate(isoDate) {
155
+ const parsed = new Date(`${isoDate}T00:00:00Z`);
156
+ return !Number.isNaN(parsed.getTime()) && parsed.toISOString().slice(0, 10) === isoDate;
157
+ }
158
+ isPreferred(candidate, current) {
159
+ const candidateActive = candidate.valid_to === null;
160
+ const currentActive = current.valid_to === null;
161
+ if (candidateActive !== currentActive) {
162
+ return candidateActive;
163
+ }
164
+ // Both dates are normalized to ISO, so a plain string comparison orders them correctly.
165
+ return (candidate.valid_from ?? "") > (current.valid_from ?? "");
166
+ }
167
+ };
168
+ exports.EnapoGidMappingNormalizer = EnapoGidMappingNormalizer;
169
+ EnapoGidMappingNormalizer.EB_PLACEHOLDER_DATE = "1900-01-01";
170
+ EnapoGidMappingNormalizer.MAX_PLACE_ID_LENGTH = 50;
171
+ // link_source is not part of the primary key anymore and the CSV value is not stored: every synced
172
+ // mapping is written with a single fixed link_source, so downstream can tell sync rows from the
173
+ // manual mock import (link_source = "mock") and from the Porsenna view branch (link_source = "porsenna").
174
+ EnapoGidMappingNormalizer.LINK_SOURCE = "manual_entry";
175
+ EnapoGidMappingNormalizer.ISO_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
176
+ // Water/heat mapping, out of scope until the source codes are cleaned up (separate issue).
177
+ EnapoGidMappingNormalizer.EXCLUDED_LINK_SOURCE = "eb_cis_odb_mista";
178
+ EnapoGidMappingNormalizer.ELECTRICITY_CODES = ["1", "electricity", "elektrina"];
179
+ EnapoGidMappingNormalizer.GAS_CODES = ["2", "gas", "plyn"];
180
+ EnapoGidMappingNormalizer.HEAT_WATER_CODES = ["3", "4", "heat", "teplo", "water", "voda"];
181
+ EnapoGidMappingNormalizer.TRUE_VALUES = ["true", "1", "t", "yes"];
182
+ EnapoGidMappingNormalizer.MAX_SAMPLES_PER_REASON = 5;
183
+ EnapoGidMappingNormalizer.SKIP_REASONS = [
184
+ "missing_required",
185
+ "place_id_too_long",
186
+ "invalid_date",
187
+ "contradicting_pair",
188
+ "unresolvable_commodity",
189
+ ];
190
+ exports.EnapoGidMappingNormalizer = EnapoGidMappingNormalizer = EnapoGidMappingNormalizer_1 = __decorate([
191
+ (0, tsyringe_1.injectable)()
192
+ ], EnapoGidMappingNormalizer);
193
+ //# sourceMappingURL=EnapoGidMappingNormalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnapoGidMappingNormalizer.js","sourceRoot":"","sources":["../../../../src/integration-engine/enapo/helpers/EnapoGidMappingNormalizer.ts"],"names":[],"mappings":"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"}