@golemio/fypr 1.10.0 → 1.10.1-dev.2784614109

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 (55) hide show
  1. package/db/migrations/postgresql/20260814093009-add-device-statuses.js +16 -0
  2. package/db/migrations/postgresql/sqls/20260814093009-add-device-statuses-down.sql +1 -0
  3. package/db/migrations/postgresql/sqls/20260814093009-add-device-statuses-up.sql +6 -0
  4. package/dist/integration-engine/data-sources/DCIPStatusOverviewDataSourceFactory.d.ts +8 -0
  5. package/dist/integration-engine/data-sources/DCIPStatusOverviewDataSourceFactory.js +45 -0
  6. package/dist/integration-engine/data-sources/DCIPStatusOverviewDataSourceFactory.js.map +1 -0
  7. package/dist/integration-engine/ioc/Di.js +9 -3
  8. package/dist/integration-engine/ioc/Di.js.map +1 -1
  9. package/dist/integration-engine/ioc/FYPRIEContainerTokens.d.ts +3 -0
  10. package/dist/integration-engine/ioc/FYPRIEContainerTokens.js +5 -0
  11. package/dist/integration-engine/ioc/FYPRIEContainerTokens.js.map +1 -1
  12. package/dist/integration-engine/repositories/DeviceStatusRepository.d.ts +17 -0
  13. package/dist/integration-engine/repositories/DeviceStatusRepository.js +81 -0
  14. package/dist/integration-engine/repositories/DeviceStatusRepository.js.map +1 -0
  15. package/dist/integration-engine/workers/FYPRWorker.js +1 -0
  16. package/dist/integration-engine/workers/FYPRWorker.js.map +1 -1
  17. package/dist/integration-engine/workers/tasks/FetchDCIPStatusTask.d.ts +12 -0
  18. package/dist/integration-engine/workers/tasks/FetchDCIPStatusTask.js +55 -0
  19. package/dist/integration-engine/workers/tasks/FetchDCIPStatusTask.js.map +1 -0
  20. package/dist/output-gateway/fypr/controllers/v1/V1FyprElementKindsController.js +1 -1
  21. package/dist/output-gateway/fypr/controllers/v1/V1FyprElementKindsController.js.map +1 -1
  22. package/dist/output-gateway/fypr/data-access/FyprElementRepository.js +10 -6
  23. package/dist/output-gateway/fypr/data-access/FyprElementRepository.js.map +1 -1
  24. package/dist/output-gateway/fypr/routers/middlewares/cacheMiddleware.d.ts +12 -0
  25. package/dist/output-gateway/fypr/routers/middlewares/cacheMiddleware.js +14 -0
  26. package/dist/output-gateway/fypr/routers/middlewares/cacheMiddleware.js.map +1 -0
  27. package/dist/output-gateway/fypr/routers/v1/V1FyprElementKindsRouter.js +14 -6
  28. package/dist/output-gateway/fypr/routers/v1/V1FyprElementKindsRouter.js.map +1 -1
  29. package/dist/output-gateway/fypr/routers/v1/V1FyprMetadataRouter.js +2 -3
  30. package/dist/output-gateway/fypr/routers/v1/V1FyprMetadataRouter.js.map +1 -1
  31. package/dist/output-gateway/fypr/transformations/InformationPanelOutputTransformation.js +12 -2
  32. package/dist/output-gateway/fypr/transformations/InformationPanelOutputTransformation.js.map +1 -1
  33. package/dist/output-gateway/interfaces/IOGInformationPanelScopes.d.ts +3 -0
  34. package/dist/schema-definitions/const.d.ts +1 -0
  35. package/dist/schema-definitions/const.js +10 -1
  36. package/dist/schema-definitions/const.js.map +1 -1
  37. package/dist/schema-definitions/data-sources/DCIPStatusOverviewJSONSchema.d.ts +3 -0
  38. package/dist/schema-definitions/data-sources/DCIPStatusOverviewJSONSchema.js +25 -0
  39. package/dist/schema-definitions/data-sources/DCIPStatusOverviewJSONSchema.js.map +1 -0
  40. package/dist/schema-definitions/data-sources/interfaces/IDCIPStatusOverview.d.ts +7 -0
  41. package/dist/schema-definitions/data-sources/interfaces/IDCIPStatusOverview.js +3 -0
  42. package/dist/schema-definitions/data-sources/interfaces/IDCIPStatusOverview.js.map +1 -0
  43. package/dist/schema-definitions/index.d.ts +6 -0
  44. package/dist/schema-definitions/index.js +17 -2
  45. package/dist/schema-definitions/index.js.map +1 -1
  46. package/dist/schema-definitions/models/DeviceStatusModel.d.ts +11 -0
  47. package/dist/schema-definitions/models/DeviceStatusModel.js +22 -0
  48. package/dist/schema-definitions/models/DeviceStatusModel.js.map +1 -0
  49. package/dist/schema-definitions/models/interfaces/IDeviceStatus.d.ts +6 -0
  50. package/dist/schema-definitions/models/interfaces/IDeviceStatus.js +3 -0
  51. package/dist/schema-definitions/models/interfaces/IDeviceStatus.js.map +1 -0
  52. package/docs/asyncapi.yaml +17 -0
  53. package/docs/implementation_documentation.md +57 -2
  54. package/docs/openapi-output.yaml +70 -8
  55. package/package.json +1 -1
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.v1FyprMetadataRouter = exports.V1FyprMetadataRouter = void 0;
4
4
  const Di_1 = require("../../../ioc/Di");
5
5
  const FYPROGContainerTokens_1 = require("../../../ioc/FYPROGContainerTokens");
6
+ const cacheMiddleware_1 = require("../middlewares/cacheMiddleware");
6
7
  const CoreToken_1 = require("@golemio/core/dist/helpers/ioc/CoreToken");
7
8
  const AbstractRouter_1 = require("@golemio/core/dist/helpers/routing/AbstractRouter");
8
9
  const ioc_1 = require("@golemio/core/dist/output-gateway/ioc");
@@ -17,9 +18,7 @@ class V1FyprMetadataRouter extends AbstractRouter_1.AbstractRouter {
17
18
  }
18
19
  initRoutes() {
19
20
  const config = ioc_1.OutputGatewayContainer.resolve(CoreToken_1.CoreToken.SimpleConfig);
20
- const maxAge = config.getValue("module.fypr.output-gateway.elements.cache.maxAge", 5 * 60);
21
- const staleWhileRevalidate = config.getValue("module.fypr.output-gateway.elements.cache.staleWhileRevalidate", 60);
22
- const cacheMiddleware = this.cacheHeaderMiddleware.getMiddleware(maxAge, staleWhileRevalidate);
21
+ const cacheMiddleware = (0, cacheMiddleware_1.resolveCacheMiddleware)(this.cacheHeaderMiddleware, config, "module.fypr.output-gateway.elements.cache", { maxAge: 5 * 60, staleWhileRevalidate: 60 });
23
22
  this.router.get("/", cacheMiddleware, this.controller.getMetadata(`/${this.version}/fypr/elements`));
24
23
  }
25
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"V1FyprMetadataRouter.js","sourceRoot":"","sources":["../../../../../src/output-gateway/fypr/routers/v1/V1FyprMetadataRouter.ts"],"names":[],"mappings":";;;AACA,wCAA6C;AAC7C,8EAAsE;AAEtE,wEAAqE;AACrE,sFAAmF;AAEnF,+DAA+F;AAC/F,+DAA2D;AAE3D,MAAa,oBAAqB,SAAQ,+BAAc;IAKpD;QACI,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAL1B,WAAM,GAAW,IAAA,gBAAM,GAAE,CAAC;QAM7B,IAAI,CAAC,qBAAqB,GAAG,4BAAsB,CAAC,OAAO,CAAwB,oBAAc,CAAC,qBAAqB,CAAC,CAAC;QACzH,IAAI,CAAC,UAAU,GAAG,oBAAe,CAAC,OAAO,CAA2B,6CAAqB,CAAC,wBAAwB,CAAC,CAAC;QACpH,IAAI,CAAC,UAAU,EAAE,CAAC;IACtB,CAAC;IAES,UAAU;QAChB,MAAM,MAAM,GAAG,4BAAsB,CAAC,OAAO,CAAgB,qBAAS,CAAC,YAAY,CAAC,CAAC;QACrF,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAS,kDAAkD,EAAE,CAAC,GAAG,EAAE,CAAW,CAAC;QAC7G,MAAM,oBAAoB,GAAG,MAAM,CAAC,QAAQ,CACxC,gEAAgE,EAChE,EAAE,CACK,CAAC;QAEZ,MAAM,eAAe,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;QAC/F,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC;IACzG,CAAC;CACJ;AAvBD,oDAuBC;AAEY,QAAA,oBAAoB,GAAmB,IAAI,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"V1FyprMetadataRouter.js","sourceRoot":"","sources":["../../../../../src/output-gateway/fypr/routers/v1/V1FyprMetadataRouter.ts"],"names":[],"mappings":";;;AACA,wCAA6C;AAC7C,8EAAsE;AACtE,oEAAsF;AAEtF,wEAAqE;AACrE,sFAAmF;AAEnF,+DAA+F;AAC/F,+DAA2D;AAE3D,MAAa,oBAAqB,SAAQ,+BAAc;IAKpD;QACI,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QAL1B,WAAM,GAAW,IAAA,gBAAM,GAAE,CAAC;QAM7B,IAAI,CAAC,qBAAqB,GAAG,4BAAsB,CAAC,OAAO,CAAwB,oBAAc,CAAC,qBAAqB,CAAC,CAAC;QACzH,IAAI,CAAC,UAAU,GAAG,oBAAe,CAAC,OAAO,CAA2B,6CAAqB,CAAC,wBAAwB,CAAC,CAAC;QACpH,IAAI,CAAC,UAAU,EAAE,CAAC;IACtB,CAAC;IAES,UAAU;QAChB,MAAM,MAAM,GAAG,4BAAsB,CAAC,OAAO,CAAgB,qBAAS,CAAC,YAAY,CAAC,CAAC;QACrF,MAAM,eAAe,GAAG,IAAA,wCAAsB,EAC1C,IAAI,CAAC,qBAAqB,EAC1B,MAAM,EACN,2CAA2C,EAC3C,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE,CAC/C,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC;IACzG,CAAC;CACJ;AAtBD,oDAsBC;AAEY,QAAA,oBAAoB,GAAmB,IAAI,oBAAoB,EAAE,CAAC"}
@@ -7,6 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  };
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.InformationPanelOutputTransformation = void 0;
10
+ const _sch_1 = require("../../../schema-definitions");
10
11
  const AbstractTransformation_1 = require("@golemio/core/dist/helpers/transformation/AbstractTransformation");
11
12
  const tsyringe_1 = require("@golemio/core/dist/shared/tsyringe");
12
13
  let InformationPanelOutputTransformation = class InformationPanelOutputTransformation extends AbstractTransformation_1.AbstractTransformation {
@@ -16,13 +17,13 @@ let InformationPanelOutputTransformation = class InformationPanelOutputTransform
16
17
  this.transformArray = (data, embeds) => data.map((item) => this.transformInternal(item.toJSON ? item.toJSON() : item, embeds));
17
18
  this.transformElement = (element, embeds) => this.transformInternal(element.toJSON ? element.toJSON() : element, embeds);
18
19
  this.transformInternal = (panel, embeds) => {
19
- const { preset, panel_size, presetsRoutesAgg, ...rest } = panel;
20
+ const { preset, panel_size, presetsRoutesAgg, deviceStatus, ...rest } = panel;
20
21
  const result = {
21
22
  ...rest,
22
23
  presets: this.convertDelimitedStringToArray(preset),
23
24
  panel_size: this.parsePanelSize(panel_size),
24
25
  };
25
- if (embeds?.includes("routes") && presetsRoutesAgg?.length) {
26
+ if (embeds?.includes(_sch_1.SCOPE_ROUTES) && presetsRoutesAgg?.length) {
26
27
  result.routes = presetsRoutesAgg.map(({ route_name, note, is_testing, routes }) => ({
27
28
  route_name,
28
29
  note,
@@ -30,6 +31,15 @@ let InformationPanelOutputTransformation = class InformationPanelOutputTransform
30
31
  routes,
31
32
  }));
32
33
  }
34
+ if (embeds?.includes(_sch_1.SCOPE_DEVICE_STATUS)) {
35
+ result.deviceStatus = deviceStatus
36
+ ? {
37
+ device_id: deviceStatus.device_id,
38
+ last_contact: deviceStatus.last_contact ? new Date(deviceStatus.last_contact).toISOString() : null,
39
+ status: deviceStatus.status,
40
+ }
41
+ : null;
42
+ }
33
43
  return result;
34
44
  };
35
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"InformationPanelOutputTransformation.js","sourceRoot":"","sources":["../../../../src/output-gateway/fypr/transformations/InformationPanelOutputTransformation.ts"],"names":[],"mappings":";;;;;;;;;AAIA,6GAA0G;AAC1G,iEAAgE;AAGzD,IAAM,oCAAoC,GAA1C,MAAM,oCAAqC,SAAQ,+CAA2D;IAA9G;;QACa,SAAI,GAAG,sCAAsC,CAAC;QAE9C,mBAAc,GAAG,CAAC,IAAsB,EAAE,MAAiB,EAAyB,EAAE,CAClG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAwD,EAAE,EAAE,CAClE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CACrE,CAAC;QAEU,qBAAgB,GAAG,CAC/B,OAA2D,EAC3D,MAAiB,EACE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE5F,sBAAiB,GAAG,CAAC,KAAqB,EAAE,MAAiB,EAAuB,EAAE;YAC5F,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,IAAI,EAAE,GAAG,KAEzD,CAAC;YACF,MAAM,MAAM,GAAwB;gBAChC,GAAG,IAAI;gBACP,OAAO,EAAE,IAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC;gBACnD,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;aAC9C,CAAC;YACF,IAAI,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,gBAAgB,EAAE,MAAM,EAAE,CAAC;gBACzD,MAAM,CAAC,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;oBAChF,UAAU;oBACV,IAAI;oBACJ,UAAU;oBACV,MAAM;iBACT,CAAC,CAAC,CAAC;YACR,CAAC;YACD,OAAO,MAAM,CAAC;QAClB,CAAC,CAAC;IAgBN,CAAC;IAdW,6BAA6B,CAAC,KAAoB;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK;aACd,KAAK,CAAC,QAAQ,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;IAEO,cAAc,CAAC,KAAoB;QACvC,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACzC,CAAC;CACJ,CAAA;AA/CY,oFAAoC;+CAApC,oCAAoC;IADhD,IAAA,qBAAU,GAAE;GACA,oCAAoC,CA+ChD"}
1
+ {"version":3,"file":"InformationPanelOutputTransformation.js","sourceRoot":"","sources":["../../../../src/output-gateway/fypr/transformations/InformationPanelOutputTransformation.ts"],"names":[],"mappings":";;;;;;;;;AAEA,sDAAyE;AAGzE,6GAA0G;AAC1G,iEAAgE;AAGzD,IAAM,oCAAoC,GAA1C,MAAM,oCAAqC,SAAQ,+CAA2D;IAA9G;;QACa,SAAI,GAAG,sCAAsC,CAAC;QAE9C,mBAAc,GAAG,CAAC,IAAsB,EAAE,MAAiB,EAAyB,EAAE,CAClG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAwD,EAAE,EAAE,CAClE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CACrE,CAAC;QAEU,qBAAgB,GAAG,CAC/B,OAA2D,EAC3D,MAAiB,EACE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE5F,sBAAiB,GAAG,CAAC,KAAqB,EAAE,MAAiB,EAAuB,EAAE;YAC5F,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,GAAG,KAGvE,CAAC;YACF,MAAM,MAAM,GAAwB;gBAChC,GAAG,IAAI;gBACP,OAAO,EAAE,IAAI,CAAC,6BAA6B,CAAC,MAAM,CAAC;gBACnD,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;aAC9C,CAAC;YACF,IAAI,MAAM,EAAE,QAAQ,CAAC,mBAAY,CAAC,IAAI,gBAAgB,EAAE,MAAM,EAAE,CAAC;gBAC7D,MAAM,CAAC,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;oBAChF,UAAU;oBACV,IAAI;oBACJ,UAAU;oBACV,MAAM;iBACT,CAAC,CAAC,CAAC;YACR,CAAC;YACD,IAAI,MAAM,EAAE,QAAQ,CAAC,0BAAmB,CAAC,EAAE,CAAC;gBACxC,MAAM,CAAC,YAAY,GAAG,YAAY;oBAC9B,CAAC,CAAC;wBACI,SAAS,EAAE,YAAY,CAAC,SAAS;wBACjC,YAAY,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;wBAClG,MAAM,EAAE,YAAY,CAAC,MAAM;qBAC9B;oBACH,CAAC,CAAC,IAAI,CAAC;YACf,CAAC;YACD,OAAO,MAAM,CAAC;QAClB,CAAC,CAAC;IAgBN,CAAC;IAdW,6BAA6B,CAAC,KAAoB;QACtD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK;aACd,KAAK,CAAC,QAAQ,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;IAEO,cAAc,CAAC,KAAoB;QACvC,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACzC,CAAC;CACJ,CAAA;AAzDY,oFAAoC;+CAApC,oCAAoC;IADhD,IAAA,qBAAU,GAAE;GACA,oCAAoC,CAyDhD"}
@@ -1,3 +1,4 @@
1
+ import { IDCIPStatusOverview } from "../../schema-definitions/data-sources/interfaces/IDCIPStatusOverview";
1
2
  import { IPresetRouteAgg } from "../../schema-definitions/models/interfaces/IPresetRouteAgg";
2
3
  export type IOGPresetRoute = IPresetRouteAgg;
3
4
  export interface IOGPresetRoutes {
@@ -6,6 +7,8 @@ export interface IOGPresetRoutes {
6
7
  is_testing: boolean;
7
8
  routes: IOGPresetRoute[];
8
9
  }
10
+ export type IOGDeviceStatus = IDCIPStatusOverview;
9
11
  export interface IOGInformationPanelScopes {
10
12
  routes: IOGPresetRoutes[];
13
+ deviceStatus: IOGDeviceStatus | null;
11
14
  }
@@ -52,6 +52,7 @@ export declare const nullableInteger: {
52
52
  readonly nullable: true;
53
53
  }];
54
54
  };
55
+ export declare const deviceStatusValues: readonly ["not_charging", "low_power", "ok", "not_ok", "intermittent_outages", "not_monitored", "off"];
55
56
  export declare const stateEnum: {
56
57
  readonly type: "string";
57
58
  readonly enum: readonly ["Plánováno", "V přípravě", "Hotovo", "Zrušeno", "Neplánováno"];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.stateEnum = exports.nullableInteger = exports.nullableStringArray = exports.nullableDateString = exports.nullableBoolean = exports.nullableNumber = exports.nullableString = exports.STALE_ROW_THRESHOLD = exports.PG_SCHEMA = void 0;
3
+ exports.stateEnum = exports.deviceStatusValues = exports.nullableInteger = exports.nullableStringArray = exports.nullableDateString = exports.nullableBoolean = exports.nullableNumber = exports.nullableString = exports.STALE_ROW_THRESHOLD = exports.PG_SCHEMA = void 0;
4
4
  const fyprElementStates_1 = require("./models/interfaces/fyprElementStates");
5
5
  exports.PG_SCHEMA = "fypr";
6
6
  exports.STALE_ROW_THRESHOLD = "NOW() - INTERVAL '1 minute'";
@@ -21,6 +21,15 @@ exports.nullableStringArray = {
21
21
  ],
22
22
  };
23
23
  exports.nullableInteger = { oneOf: [{ type: "integer" }, { type: "null", nullable: true }] };
24
+ exports.deviceStatusValues = [
25
+ "not_charging",
26
+ "low_power",
27
+ "ok",
28
+ "not_ok",
29
+ "intermittent_outages",
30
+ "not_monitored",
31
+ "off",
32
+ ];
24
33
  // Required `state` / source `stav_prvku` enum fragment (non-null).
25
34
  exports.stateEnum = { type: "string", enum: fyprElementStates_1.fyprElementStates };
26
35
  //# sourceMappingURL=const.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"const.js","sourceRoot":"","sources":["../../src/schema-definitions/const.ts"],"names":[],"mappings":";;;AAAA,6EAA0E;AAE7D,QAAA,SAAS,GAAG,MAAM,CAAC;AACnB,QAAA,mBAAmB,GAAG,6BAA6B,CAAC;AAEjE,yDAAyD;AAC5C,QAAA,cAAc,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAC5F,QAAA,cAAc,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAC5F,QAAA,eAAe,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAC9F,QAAA,kBAAkB,GAAG;IAC9B,KAAK,EAAE;QACH,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;QAClC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;KACnC;CACK,CAAC;AACE,QAAA,mBAAmB,GAAG;IAC/B,KAAK,EAAE;QACH,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QAC5C,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;KACnC;CACK,CAAC;AACE,QAAA,eAAe,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAE3G,mEAAmE;AACtD,QAAA,SAAS,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,qCAAiB,EAAW,CAAC"}
1
+ {"version":3,"file":"const.js","sourceRoot":"","sources":["../../src/schema-definitions/const.ts"],"names":[],"mappings":";;;AAAA,6EAA0E;AAE7D,QAAA,SAAS,GAAG,MAAM,CAAC;AACnB,QAAA,mBAAmB,GAAG,6BAA6B,CAAC;AAEjE,yDAAyD;AAC5C,QAAA,cAAc,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAC5F,QAAA,cAAc,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAC5F,QAAA,eAAe,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAC9F,QAAA,kBAAkB,GAAG;IAC9B,KAAK,EAAE;QACH,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;QAClC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;KACnC;CACK,CAAC;AACE,QAAA,mBAAmB,GAAG;IAC/B,KAAK,EAAE;QACH,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QAC5C,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;KACnC;CACK,CAAC;AACE,QAAA,eAAe,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAW,CAAC;AAE9F,QAAA,kBAAkB,GAAG;IAC9B,cAAc;IACd,WAAW;IACX,IAAI;IACJ,QAAQ;IACR,sBAAsB;IACtB,eAAe;IACf,KAAK;CACC,CAAC;AAEX,mEAAmE;AACtD,QAAA,SAAS,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,qCAAiB,EAAW,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { JSONSchemaType } from "@golemio/core/dist/shared/ajv";
2
+ import { IDCIPStatusOverview } from "./interfaces/IDCIPStatusOverview";
3
+ export declare const dcipStatusOverviewJSONSchema: JSONSchemaType<IDCIPStatusOverview[]>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dcipStatusOverviewJSONSchema = void 0;
4
+ const const_1 = require("../const");
5
+ // additionalProperties is intentionally left permissive (not `false`): DCIP may add fields to its
6
+ // response over time, and rejecting the whole record over an unrecognized field would silently
7
+ // freeze the entire feed rather than just ignoring data we don't use.
8
+ exports.dcipStatusOverviewJSONSchema = {
9
+ type: "array",
10
+ items: {
11
+ type: "object",
12
+ properties: {
13
+ device_id: { type: "string" },
14
+ last_contact: {
15
+ oneOf: [
16
+ { type: "string", format: "date-time" },
17
+ { type: "null", nullable: true },
18
+ ],
19
+ },
20
+ status: { type: "string", enum: const_1.deviceStatusValues },
21
+ },
22
+ required: ["device_id", "last_contact", "status"],
23
+ },
24
+ };
25
+ //# sourceMappingURL=DCIPStatusOverviewJSONSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DCIPStatusOverviewJSONSchema.js","sourceRoot":"","sources":["../../../src/schema-definitions/data-sources/DCIPStatusOverviewJSONSchema.ts"],"names":[],"mappings":";;;AACA,oCAAgD;AAGhD,kGAAkG;AAClG,+FAA+F;AAC/F,sEAAsE;AACzD,QAAA,4BAA4B,GAA0C;IAC/E,IAAI,EAAE,OAAO;IACb,KAAK,EAAE;QACH,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACR,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC7B,YAAY,EAAE;gBACV,KAAK,EAAE;oBACH,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE;oBACvC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;iBACnC;aACJ;YACD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,0BAAkB,EAAE;SACvD;QACD,QAAQ,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,QAAQ,CAAC;KACpD;CACqC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { deviceStatusValues } from "../../const";
2
+ export type DCIPDeviceStatus = typeof deviceStatusValues[number];
3
+ export interface IDCIPStatusOverview {
4
+ device_id: string;
5
+ last_contact: string | null;
6
+ status: DCIPDeviceStatus;
7
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=IDCIPStatusOverview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IDCIPStatusOverview.js","sourceRoot":"","sources":["../../../../src/schema-definitions/data-sources/interfaces/IDCIPStatusOverview.ts"],"names":[],"mappings":""}
@@ -1,12 +1,18 @@
1
1
  import { Model, ModelAttributes } from "@golemio/core/dist/shared/sequelize";
2
2
  export { AnyFyprElement } from "./FyprElementTypes";
3
3
  export { fyprElementStates, FyprElementState } from "./models/interfaces/fyprElementStates";
4
+ export declare const SCOPE_ROUTES = "routes";
5
+ export declare const SCOPE_DEVICE_STATUS = "device_status";
6
+ export declare const informationPanelScopes: readonly ["routes", "device_status"];
7
+ export type InformationPanelScope = typeof informationPanelScopes[number];
4
8
  export type FyprEmbedConfig = {
5
9
  tableName: string;
6
10
  as: string;
7
11
  foreignKey: string;
8
12
  sourceKey: string;
9
13
  attributeModel: ModelAttributes<Model>;
14
+ /** Relation cardinality from the parent element to the embed's table. Defaults to "many". */
15
+ cardinality?: "one" | "many";
10
16
  };
11
17
  type FyprElementConfig = {
12
18
  cs_singular: string;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fyprElementKinds = exports.FyprElementsConfig = exports.fyprElementStates = void 0;
3
+ exports.fyprElementKinds = exports.FyprElementsConfig = exports.informationPanelScopes = exports.SCOPE_DEVICE_STATUS = exports.SCOPE_ROUTES = exports.fyprElementStates = void 0;
4
+ const DeviceStatusModel_1 = require("./models/DeviceStatusModel");
4
5
  const DisplayCaseModel_1 = require("./models/DisplayCaseModel");
5
6
  const InformationPanelModel_1 = require("./models/InformationPanelModel");
6
7
  const InformationPanelPresetsRoutesAggModel_1 = require("./models/InformationPanelPresetsRoutesAggModel");
@@ -9,6 +10,12 @@ const SignpostModel_1 = require("./models/SignpostModel");
9
10
  const TotemModel_1 = require("./models/TotemModel");
10
11
  var fyprElementStates_1 = require("./models/interfaces/fyprElementStates");
11
12
  Object.defineProperty(exports, "fyprElementStates", { enumerable: true, get: function () { return fyprElementStates_1.fyprElementStates; } });
13
+ // Single source of truth for ?scopes=... values on information-panels. Each value doubles as the
14
+ // key of the matching embeds config below — a typo in either place is a compile/validation error,
15
+ // not a silently dropped embed.
16
+ exports.SCOPE_ROUTES = "routes";
17
+ exports.SCOPE_DEVICE_STATUS = "device_status";
18
+ exports.informationPanelScopes = [exports.SCOPE_ROUTES, exports.SCOPE_DEVICE_STATUS];
12
19
  exports.FyprElementsConfig = {
13
20
  "display-cases": {
14
21
  cs_singular: "vitrína",
@@ -24,13 +31,21 @@ exports.FyprElementsConfig = {
24
31
  tableName: InformationPanelModel_1.InformationPanelModel.tableName,
25
32
  attributeModel: InformationPanelModel_1.InformationPanelModel.attributeModel,
26
33
  embeds: {
27
- routes: {
34
+ [exports.SCOPE_ROUTES]: {
28
35
  tableName: InformationPanelPresetsRoutesAggModel_1.InformationPanelPresetsRoutesAggModel.tableName,
29
36
  as: "presetsRoutesAgg",
30
37
  foreignKey: "information_panel_document_id",
31
38
  sourceKey: "document_id",
32
39
  attributeModel: InformationPanelPresetsRoutesAggModel_1.InformationPanelPresetsRoutesAggModel.attributeModel,
33
40
  },
41
+ [exports.SCOPE_DEVICE_STATUS]: {
42
+ tableName: DeviceStatusModel_1.DeviceStatusModel.tableName,
43
+ as: "deviceStatus",
44
+ foreignKey: "device_id",
45
+ sourceKey: "device_id",
46
+ attributeModel: DeviceStatusModel_1.DeviceStatusModel.attributeModel,
47
+ cardinality: "one",
48
+ },
34
49
  },
35
50
  },
36
51
  obelisks: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema-definitions/index.ts"],"names":[],"mappings":";;;AACA,gEAA6D;AAC7D,0EAAuE;AACvE,0GAAuG;AACvG,wDAAqD;AACrD,0DAAuD;AACvD,oDAAiD;AAGjD,2EAA4F;AAAnF,sHAAA,iBAAiB,OAAA;AAmBb,QAAA,kBAAkB,GAM3B;IACA,eAAe,EAAE;QACb,WAAW,EAAE,SAAS;QACtB,EAAE,EAAE,SAAS;QACb,SAAS,EAAE,eAAe;QAC1B,SAAS,EAAE,mCAAgB,CAAC,SAAS;QACrC,cAAc,EAAE,mCAAgB,CAAC,cAAc;KAClD;IACD,oBAAoB,EAAE;QAClB,WAAW,EAAE,kBAAkB;QAC/B,EAAE,EAAE,mBAAmB;QACvB,SAAS,EAAE,oBAAoB;QAC/B,SAAS,EAAE,6CAAqB,CAAC,SAAS;QAC1C,cAAc,EAAE,6CAAqB,CAAC,cAAc;QACpD,MAAM,EAAE;YACJ,MAAM,EAAE;gBACJ,SAAS,EAAE,6EAAqC,CAAC,SAAS;gBAC1D,EAAE,EAAE,kBAAkB;gBACtB,UAAU,EAAE,+BAA+B;gBAC3C,SAAS,EAAE,aAAa;gBACxB,cAAc,EAAE,6EAAqC,CAAC,cAAc;aACvE;SACJ;KACJ;IACD,QAAQ,EAAE;QACN,WAAW,EAAE,SAAS;QACtB,EAAE,EAAE,UAAU;QACd,SAAS,EAAE,UAAU;QACrB,SAAS,EAAE,2BAAY,CAAC,SAAS;QACjC,cAAc,EAAE,2BAAY,CAAC,cAAc;KAC9C;IACD,SAAS,EAAE;QACP,WAAW,EAAE,WAAW;QACxB,EAAE,EAAE,YAAY;QAChB,SAAS,EAAE,WAAW;QACtB,SAAS,EAAE,6BAAa,CAAC,SAAS;QAClC,cAAc,EAAE,6BAAa,CAAC,cAAc;KAC/C;IACD,MAAM,EAAE;QACJ,WAAW,EAAE,OAAO;QACpB,EAAE,EAAE,QAAQ;QACZ,SAAS,EAAE,QAAQ;QACnB,SAAS,EAAE,uBAAU,CAAC,SAAS;QAC/B,cAAc,EAAE,uBAAU,CAAC,cAAc;KAC5C;CACJ,CAAC;AAIW,QAAA,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,0BAAkB,CAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema-definitions/index.ts"],"names":[],"mappings":";;;AACA,kEAA+D;AAC/D,gEAA6D;AAC7D,0EAAuE;AACvE,0GAAuG;AACvG,wDAAqD;AACrD,0DAAuD;AACvD,oDAAiD;AAGjD,2EAA4F;AAAnF,sHAAA,iBAAiB,OAAA;AAE1B,iGAAiG;AACjG,kGAAkG;AAClG,gCAAgC;AACnB,QAAA,YAAY,GAAG,QAAQ,CAAC;AACxB,QAAA,mBAAmB,GAAG,eAAe,CAAC;AACtC,QAAA,sBAAsB,GAAG,CAAC,oBAAY,EAAE,2BAAmB,CAAU,CAAC;AAsBtE,QAAA,kBAAkB,GAM3B;IACA,eAAe,EAAE;QACb,WAAW,EAAE,SAAS;QACtB,EAAE,EAAE,SAAS;QACb,SAAS,EAAE,eAAe;QAC1B,SAAS,EAAE,mCAAgB,CAAC,SAAS;QACrC,cAAc,EAAE,mCAAgB,CAAC,cAAc;KAClD;IACD,oBAAoB,EAAE;QAClB,WAAW,EAAE,kBAAkB;QAC/B,EAAE,EAAE,mBAAmB;QACvB,SAAS,EAAE,oBAAoB;QAC/B,SAAS,EAAE,6CAAqB,CAAC,SAAS;QAC1C,cAAc,EAAE,6CAAqB,CAAC,cAAc;QACpD,MAAM,EAAE;YACJ,CAAC,oBAAY,CAAC,EAAE;gBACZ,SAAS,EAAE,6EAAqC,CAAC,SAAS;gBAC1D,EAAE,EAAE,kBAAkB;gBACtB,UAAU,EAAE,+BAA+B;gBAC3C,SAAS,EAAE,aAAa;gBACxB,cAAc,EAAE,6EAAqC,CAAC,cAAc;aACvE;YACD,CAAC,2BAAmB,CAAC,EAAE;gBACnB,SAAS,EAAE,qCAAiB,CAAC,SAAS;gBACtC,EAAE,EAAE,cAAc;gBAClB,UAAU,EAAE,WAAW;gBACvB,SAAS,EAAE,WAAW;gBACtB,cAAc,EAAE,qCAAiB,CAAC,cAAc;gBAChD,WAAW,EAAE,KAAK;aACrB;SACJ;KACJ;IACD,QAAQ,EAAE;QACN,WAAW,EAAE,SAAS;QACtB,EAAE,EAAE,UAAU;QACd,SAAS,EAAE,UAAU;QACrB,SAAS,EAAE,2BAAY,CAAC,SAAS;QACjC,cAAc,EAAE,2BAAY,CAAC,cAAc;KAC9C;IACD,SAAS,EAAE;QACP,WAAW,EAAE,WAAW;QACxB,EAAE,EAAE,YAAY;QAChB,SAAS,EAAE,WAAW;QACtB,SAAS,EAAE,6BAAa,CAAC,SAAS;QAClC,cAAc,EAAE,6BAAa,CAAC,cAAc;KAC/C;IACD,MAAM,EAAE;QACJ,WAAW,EAAE,OAAO;QACpB,EAAE,EAAE,QAAQ;QACZ,SAAS,EAAE,QAAQ;QACnB,SAAS,EAAE,uBAAU,CAAC,SAAS;QAC/B,cAAc,EAAE,uBAAU,CAAC,cAAc;KAC5C;CACJ,CAAC;AAIW,QAAA,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,0BAAkB,CAAsB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { CreationOptional, InferAttributes, InferCreationAttributes, Model, ModelAttributes } from "@golemio/core/dist/shared/sequelize";
2
+ import { IDeviceStatus } from "./interfaces/IDeviceStatus";
3
+ export declare class DeviceStatusModel extends Model<InferAttributes<DeviceStatusModel>, InferCreationAttributes<DeviceStatusModel>> implements IDeviceStatus {
4
+ static readonly tableName = "device_statuses";
5
+ device_id: string;
6
+ last_contact: Date | null;
7
+ status: IDeviceStatus["status"];
8
+ updated_at: CreationOptional<Date>;
9
+ static readonly attributeModel: ModelAttributes<DeviceStatusModel>;
10
+ static getUpdateAttributes(): string[];
11
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeviceStatusModel = void 0;
4
+ const sequelize_1 = require("@golemio/core/dist/shared/sequelize");
5
+ class DeviceStatusModel extends sequelize_1.Model {
6
+ static getUpdateAttributes() {
7
+ return ["last_contact", "status", "updated_at"];
8
+ }
9
+ }
10
+ exports.DeviceStatusModel = DeviceStatusModel;
11
+ DeviceStatusModel.tableName = "device_statuses";
12
+ DeviceStatusModel.attributeModel = {
13
+ device_id: {
14
+ primaryKey: true,
15
+ allowNull: false,
16
+ type: sequelize_1.DataTypes.STRING(255),
17
+ },
18
+ last_contact: { type: sequelize_1.DataTypes.DATE, allowNull: true },
19
+ status: { type: sequelize_1.DataTypes.STRING(50), allowNull: false },
20
+ updated_at: { type: sequelize_1.DataTypes.DATE, allowNull: false, defaultValue: sequelize_1.DataTypes.NOW },
21
+ };
22
+ //# sourceMappingURL=DeviceStatusModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeviceStatusModel.js","sourceRoot":"","sources":["../../../src/schema-definitions/models/DeviceStatusModel.ts"],"names":[],"mappings":";;;AAAA,mEAO6C;AAI7C,MAAa,iBACT,SAAQ,iBAAqF;IAqBtF,MAAM,CAAC,mBAAmB;QAC7B,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IACpD,CAAC;;AAxBL,8CAyBC;AArB0B,2BAAS,GAAG,iBAAiB,CAAC;AAO9B,gCAAc,GAAuC;IACxE,SAAS,EAAE;QACP,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,KAAK;QAChB,IAAI,EAAE,qBAAS,CAAC,MAAM,CAAC,GAAG,CAAC;KAC9B;IACD,YAAY,EAAE,EAAE,IAAI,EAAE,qBAAS,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;IACvD,MAAM,EAAE,EAAE,IAAI,EAAE,qBAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE;IACxD,UAAU,EAAE,EAAE,IAAI,EAAE,qBAAS,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,qBAAS,CAAC,GAAG,EAAE;CACtF,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { DCIPDeviceStatus } from "../../data-sources/interfaces/IDCIPStatusOverview";
2
+ export interface IDeviceStatus {
3
+ device_id: string;
4
+ last_contact: Date | null;
5
+ status: DCIPDeviceStatus;
6
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=IDeviceStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IDeviceStatus.js","sourceRoot":"","sources":["../../../../src/schema-definitions/models/interfaces/IDeviceStatus.ts"],"names":[],"mappings":""}
@@ -36,6 +36,11 @@ operations:
36
36
  channel:
37
37
  $ref: "#/channels/fypr.updateTotems"
38
38
 
39
+ fypr.fetchDCIPStatus:
40
+ action: "send"
41
+ channel:
42
+ $ref: "#/channels/fypr.fetchDCIPStatus"
43
+
39
44
  channels:
40
45
  fypr.fetchDBFYPR:
41
46
  address: vehicle-positions.fypr.fetchDBFYPR
@@ -49,6 +54,18 @@ channels:
49
54
  empty:
50
55
  $ref: "#/components/messages/emptyMessage"
51
56
 
57
+ fypr.fetchDCIPStatus:
58
+ address: vehicle-positions.fypr.fetchDCIPStatus
59
+ description: Fetch device status overview from DCIP and upsert it into fypr.device_statuses
60
+ bindings:
61
+ amqp:
62
+ is: queue
63
+ queue:
64
+ durable: true
65
+ messages:
66
+ empty:
67
+ $ref: "#/components/messages/emptyMessage"
68
+
52
69
  fypr.updateDisplayCases:
53
70
  address: vehicle-positions.fypr.updateDisplayCases
54
71
  description: Update display cases data in database
@@ -39,6 +39,35 @@ Modul slouží k ukládání a poskytování informací o fyzických informačn
39
39
  - název RabbitMQ fronty
40
40
  - `vehicle-positions.fypr.fetchDBFYPR`
41
41
 
42
+ #### *DCIP status-overview*
43
+
44
+ - zdroj dat
45
+ - base URL: `module.fypr.dcipApi.baseUrl`
46
+ - URL path: `module.fypr.dcipApi.statusOverviewPath` (výchozí `/api/v1/status-overview`)
47
+ - autentizace: hlavička `X-Api-Key`, hodnota z `module.fypr.dcipApi.apiKey`
48
+ - timeout: `module.fypr.dcipApi.clientTimeoutInSeconds` (výchozí 20 s; musí být výrazně pod TTL fronty 55 s, aby se zpracování nepřekrývalo s dalším cron během)
49
+ - poznámka: `last_contact: null` znamená, že zařízení nikdy neposlalo stavovou zprávu (není v provozu, bylo zrušeno bez fyzické likvidace, nebo ho nelze sledovat) — nejedná se o chybu
50
+ - významy stavů (`status`):
51
+ - `ok` — zařízení funguje
52
+ - `not_ok` — nefunguje už delší souvislou dobu (zařízení nefunguje, ale mělo by)
53
+ - `intermittent_outages` — hodně krátkých výpadků po sobě
54
+ - `not_monitored` — zařízení evidujeme, ale nemáme jak sledovat
55
+ - `off` — zařízení nefunguje a víme o tom (nastavuje se ručně)
56
+ - `not_charging` — rezervováno (zařízení funguje, ale nedobíjí)
57
+ - `low_power` — rezervováno (zařízení funguje, ale má vybitou baterku)
58
+ - formát dat
59
+ - protokol: HTTP
60
+ - datový typ: JSON
61
+ - data source: [`DCIPStatusOverviewDataSourceFactory`](../src/integration-engine/data-sources/DCIPStatusOverviewDataSourceFactory.ts)
62
+ - validační schéma: [`dcipStatusOverviewJSONSchema`](../src/schema-definitions/data-sources/DCIPStatusOverviewJSONSchema.ts) (validace probíhá na úrovni data source)
63
+ - frekvence stahování
64
+ - cron definice
65
+ - cron.vehicle-positions.fypr.fetchDCIPStatus
66
+ - rabin 1min
67
+ - prod 1min
68
+ - název RabbitMQ fronty
69
+ - `vehicle-positions.fypr.fetchDCIPStatus`
70
+
42
71
 
43
72
 
44
73
  ## Zpracování dat / transformace
@@ -166,6 +195,26 @@ Worker má na starost stahování dat o fyzických prvcích z DBFYPR backend (St
166
195
  - repository: [`TotemRepository`](../src/integration-engine/repositories/TotemRepository.ts)
167
196
  - tabulka: `fypr.totems`
168
197
 
198
+ #### Task *FetchDCIPStatus*
199
+
200
+ - vstupní RabbitMQ fronta
201
+ - název: `vehicle-positions.fypr.fetchDCIPStatus`
202
+ - TTL: 55 sekund
203
+ - parametry: žádné
204
+ - závislé fronty (do kterých jsou odesílány zprávy z metody workeru)
205
+ - žádné (fetch i upsert probíhá přímo v rámci tasku, viz `UpdatePresetsTask` pro obdobný vzor)
206
+ - datové zdroje
207
+ - DCIP status-overview
208
+ - transformace
209
+ - žádné
210
+ - data modely
211
+ - výstupní model: [`DeviceStatusModel`](../src/schema-definitions/models/DeviceStatusModel.ts)
212
+ - rozhraní: [`IDeviceStatus`](../src/schema-definitions/models/interfaces/IDeviceStatus.ts)
213
+ - repository: [`DeviceStatusRepository`](../src/integration-engine/repositories/DeviceStatusRepository.ts)
214
+ - tabulka: `fypr.device_statuses`
215
+ - poznámka: pouze UPSERT dle `device_id`, bez mazání
216
+ - validace: probíhá na úrovni data source (viz výše); schéma toleruje neznámá pole (forward-compatible s budoucím rozšířením DCIP API); duplicitní `device_id` v jedné odpovědi se deduplikuje (vyhrává záznam s nejnovějším `last_contact`)
217
+ - alerting: při chybě task vyhodí chybu s klíčovým slovem `DCIP_STATUS_IMPORT_FAILED` na začátku zprávy včetně počtu selhání po sobě — na to lze navázat alert v Loki (např. 3+ selhání po sobě)
169
218
 
170
219
 
171
220
  ## Uložení dat
@@ -186,9 +235,11 @@ Popis ukládání dat.
186
235
  - `obelisks` - obelisky
187
236
  - `signposts` - směrovníky
188
237
  - `totems` - totemy
238
+ - samostatná tabulka `device_statuses` (stav DCIP zařízení, klíč `device_id`; není element a nedědí z `elements`)
189
239
  - data jsou ukládána bez automatického promazávání
190
240
  - aktualizace dat probíhá pomocí UPSERT
191
241
  - starší verze dat jsou přepsány novými daty ze zdroje
242
+ - výjimka: `device_statuses` se pouze UPSERTuje — zařízení chybějící v aktuální DCIP odpovědi si ponechá poslední známý stav (nikdy se nemaže)
192
243
 
193
244
  ### Datové modely
194
245
 
@@ -199,6 +250,7 @@ Pro podrobnou strukturu jednotlivých tabulek viz:
199
250
  - [SignpostModel](../src/schema-definitions/models/SignpostModel.ts)
200
251
  - [TotemModel](../src/schema-definitions/models/TotemModel.ts)
201
252
  - [AbstractElementModel](../src/schema-definitions/models/AbstractElementModel.ts) (společné atributy)
253
+ - [DeviceStatusModel](../src/schema-definitions/models/DeviceStatusModel.ts) (`device_statuses`, samostatná tabulka)
202
254
 
203
255
 
204
256
  ## Output API
@@ -210,10 +262,12 @@ Pro podrobnou strukturu jednotlivých tabulek viz:
210
262
  - rabin: <https://rabin.golemio.cz/pid/docs/openapi/>
211
263
  - golem: <https://api.golemio.cz/pid/docs/openapi/>
212
264
 
213
- - cache hlavičky: `max-age=300, stale-while-revalidate=60` (5 minut / 1 minuta)
265
+ - cache hlavičky: `max-age=300, stale-while-revalidate=60` (5 minut / 1 minuta), konfigurace: `module.fypr.output-gateway.elements.cache.{maxAge,staleWhileRevalidate}`
266
+ - výjimka: odpovědi na `GET /v1/fypr/elements/information-panels` s `scopes=device_status` mají kratší cache `max-age=60, stale-while-revalidate=30` (1 minuta / 30 sekund), konfigurace: `module.fypr.output-gateway.deviceStatuses.cache.{maxAge,staleWhileRevalidate}` — odpovídá frekvenci stahování dat z DCIP (1×/min), aby změna stavu nebyla vidět se zpožděním až 5 minut jako u běžného výpisu prvků
214
267
  - architektura:
215
268
  - router: [`V1FyprElementKindsRouter`](../src/output-gateway/fypr/routers/v1/V1FyprElementKindsRouter.ts) — base path `v1/fypr/elements`
216
269
  - router: [`V1FyprMetadataRouter`](../src/output-gateway/fypr/routers/v1/V1FyprMetadataRouter.ts) — base path `v1/fypr/metadata`
270
+ - middleware pro cache hlavičky: [`src/output-gateway/fypr/routers/middlewares/cacheMiddleware.ts`](../src/output-gateway/fypr/routers/middlewares/cacheMiddleware.ts)
217
271
  - controller: [`V1FyprElementKindsController`](../src/output-gateway/fypr/controllers/v1/V1FyprElementKindsController.ts)
218
272
  - controller: [`V1FyprMetadataController`](../src/output-gateway/fypr/controllers/v1/V1FyprMetadataController.ts)
219
273
  - repository: [`FyprElementRepository<T>`](../src/output-gateway/fypr/data-access/FyprElementRepository.ts) — generická třída, 5 instancí (jedna pro každý druh prvku)
@@ -294,8 +348,9 @@ Výsledky jsou řazeny dle `source_created_at ASC` (nejstarší záznamy první,
294
348
  (`state=Hotovo&state=Plánováno`); platné hodnoty: `Plánováno`, `V přípravě`, `Hotovo`, `Zrušeno`, `Neplánováno`
295
349
  - `hasDeviceId` (boolean) — `true` vrátí infopanely s vyplněným `device_id`, `false` infopanely bez něj
296
350
 
297
- - volitelné query parametry pro připojení souvisejících dat (embed/join, pouze pro `information-panels`):
351
+ - volitelné query parametry pro připojení souvisejících dat (embed/join, pouze pro `information-panels`); parametr lze opakovat pro připojení více zdrojů najednou (`scopes=routes&scopes=device_status`):
298
352
  - `scopes=routes` — připojí k infopanelům související linky (`routes`) z navázaných tabulek presetů
353
+ - `scopes=device_status` — připojí k infopanelu aktuální DCIP stav zařízení (`deviceStatus: { device_id, last_contact, status } | null`) dle shody `device_id`
299
354
 
300
355
  - chybové stavové kódy:
301
356
  - `400` — neznámý `:kind`, neplatný `limit` (mimo rozsah 1–10000), záporný `offset`,
@@ -151,14 +151,22 @@ paths:
151
151
  - name: scopes
152
152
  in: query
153
153
  required: false
154
+ style: form
155
+ explode: true
154
156
  schema:
155
- type: string
156
- enum:
157
- - routes
157
+ type: array
158
+ items:
159
+ type: string
160
+ enum:
161
+ - routes
162
+ - device_status
158
163
  description: >-
159
- Extend the panel response with related resources. Currently only "routes" is
160
- supported — adds routes directly to each panel with preset routes grouped by
161
- preset name. Only valid for information-panels.
164
+ Extend the panel response with related resources. Repeat the parameter to
165
+ request more than one (e.g. scopes=routes&scopes=device_status). "routes" adds
166
+ routes directly to each panel with preset routes grouped by preset name.
167
+ "device_status" adds the latest DCIP device status (matched by device_id) as a
168
+ deviceStatus object, or null when no status has been reported for that device.
169
+ Only valid for information-panels.
162
170
  - name: state
163
171
  in: query
164
172
  required: false
@@ -450,6 +458,48 @@ components:
450
458
  - error_status
451
459
 
452
460
  schemas:
461
+ DeviceStatus:
462
+ type: object
463
+ required:
464
+ - device_id
465
+ - last_contact
466
+ - status
467
+ properties:
468
+ device_id:
469
+ type: string
470
+ example: "bustec127"
471
+ description: Identifier of the device, as reported by DCIP.
472
+ last_contact:
473
+ type: string
474
+ format: date-time
475
+ nullable: true
476
+ example: "2026-08-14T08:00:00.000Z"
477
+ description: >-
478
+ Timestamp of the device's last reported contact. Null means the device
479
+ has never reported a status (not yet in service, decommissioned but not
480
+ physically removed, or its source cannot be monitored).
481
+ status:
482
+ type: string
483
+ enum:
484
+ - not_charging
485
+ - low_power
486
+ - ok
487
+ - not_ok
488
+ - intermittent_outages
489
+ - not_monitored
490
+ - off
491
+ example: "ok"
492
+ description: >-
493
+ Current operational status of the device, as reported by DCIP.
494
+ Approximate meaning of the values:
495
+ `ok` — device is working normally;
496
+ `not_ok` — device has been down for a longer continuous period (it should be working, but is not);
497
+ `intermittent_outages` — many short outages in a row;
498
+ `not_monitored` — device is registered, but there is no way to monitor it;
499
+ `off` — device is not working and this is known (set manually);
500
+ `not_charging` — reserved (device works, but is not charging);
501
+ `low_power` — reserved (device works, but its battery is drained).
502
+
453
503
  ElementStateEnum:
454
504
  type: string
455
505
  nullable: true
@@ -1127,6 +1177,8 @@ components:
1127
1177
  Returned by the list endpoint GET /v1/information-panels.
1128
1178
  When ?scopes=routes is provided, the response includes a routes array directly
1129
1179
  on each panel with preset routes grouped by preset name.
1180
+ When ?scopes=device_status is provided, the response includes a deviceStatus object
1181
+ (or null) with the latest DCIP status matched by device_id.
1130
1182
  allOf:
1131
1183
  - $ref: "#/components/schemas/ElementReadOnly"
1132
1184
  - $ref: "#/components/schemas/InformationPanelBase"
@@ -1138,10 +1190,20 @@ components:
1138
1190
 
1139
1191
  InformationPanelScopes:
1140
1192
  description: >-
1141
- Additional resources included when ?scopes=routes is requested.
1142
- Present only when the panel has presets with associated routes.
1193
+ Additional resources included when ?scopes=routes or ?scopes=device_status is
1194
+ requested. routes is present only when the panel has presets with associated
1195
+ routes; deviceStatus is present (possibly null) whenever ?scopes=device_status
1196
+ is requested.
1143
1197
  type: object
1144
1198
  properties:
1199
+ deviceStatus:
1200
+ allOf:
1201
+ - $ref: "#/components/schemas/DeviceStatus"
1202
+ nullable: true
1203
+ description: >-
1204
+ Latest DCIP status for the panel's device_id, or null when no status
1205
+ has been reported for that device. Only present when ?scopes=device_status
1206
+ is requested.
1145
1207
  routes:
1146
1208
  type: array
1147
1209
  description: Preset routes grouped by preset name.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@golemio/fypr",
3
- "version": "1.10.0",
3
+ "version": "1.10.1-dev.2784614109",
4
4
  "description": "Golemio FYPR Module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",