@things-factory/headless-twin 10.0.15 → 10.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-server/engine/attention-digest.d.ts +4 -4
- package/dist-server/engine/attention-digest.js +7 -7
- package/dist-server/engine/attention-digest.js.map +1 -1
- package/dist-server/engine/canonical-ingest.d.ts +18 -82
- package/dist-server/engine/canonical-ingest.js +183 -18
- package/dist-server/engine/canonical-ingest.js.map +1 -1
- package/dist-server/engine/command-routing.js +1 -1
- package/dist-server/engine/command-routing.js.map +1 -1
- package/dist-server/engine/declared-stimulus.js +1 -1
- package/dist-server/engine/declared-stimulus.js.map +1 -1
- package/dist-server/engine/energy-topology.js +4 -4
- package/dist-server/engine/energy-topology.js.map +1 -1
- package/dist-server/engine/ingest-dedupe.d.ts +38 -0
- package/dist-server/engine/ingest-dedupe.js +145 -0
- package/dist-server/engine/ingest-dedupe.js.map +1 -0
- package/dist-server/engine/ingest-health.d.ts +90 -10
- package/dist-server/engine/ingest-health.js +125 -16
- package/dist-server/engine/ingest-health.js.map +1 -1
- package/dist-server/engine/integration-probes.d.ts +3 -3
- package/dist-server/engine/integration-probes.js +6 -6
- package/dist-server/engine/integration-probes.js.map +1 -1
- package/dist-server/engine/kpi-baseline.js +4 -4
- package/dist-server/engine/kpi-baseline.js.map +1 -1
- package/dist-server/engine/kpi-fold.d.ts +212 -14
- package/dist-server/engine/kpi-fold.js +374 -21
- package/dist-server/engine/kpi-fold.js.map +1 -1
- package/dist-server/engine/kpi-query.d.ts +11 -11
- package/dist-server/engine/kpi-query.js +281 -36
- package/dist-server/engine/kpi-query.js.map +1 -1
- package/dist-server/engine/live-feed-registry.d.ts +1 -1
- package/dist-server/engine/live-feed-registry.js +1 -1
- package/dist-server/engine/live-feed-registry.js.map +1 -1
- package/dist-server/engine/load-meter.d.ts +1 -1
- package/dist-server/engine/load-meter.js.map +1 -1
- package/dist-server/engine/local-declarations.d.ts +7 -7
- package/dist-server/engine/local-declarations.js +15 -14
- package/dist-server/engine/local-declarations.js.map +1 -1
- package/dist-server/engine/log.d.ts +1 -1
- package/dist-server/engine/log.js +1 -1
- package/dist-server/engine/log.js.map +1 -1
- package/dist-server/engine/measured-estimator.js +1 -1
- package/dist-server/engine/measured-estimator.js.map +1 -1
- package/dist-server/engine/measured-yield.js +1 -1
- package/dist-server/engine/measured-yield.js.map +1 -1
- package/dist-server/engine/model-basis.d.ts +1 -1
- package/dist-server/engine/model-basis.js +1 -1
- package/dist-server/engine/model-basis.js.map +1 -1
- package/dist-server/engine/model-gap.d.ts +3 -3
- package/dist-server/engine/model-gap.js +1 -1
- package/dist-server/engine/model-gap.js.map +1 -1
- package/dist-server/engine/model-vocabulary.js +3 -3
- package/dist-server/engine/model-vocabulary.js.map +1 -1
- package/dist-server/engine/oee-accumulator.d.ts +6 -5
- package/dist-server/engine/oee-accumulator.js +6 -5
- package/dist-server/engine/oee-accumulator.js.map +1 -1
- package/dist-server/engine/property-effects.js +2 -2
- package/dist-server/engine/property-effects.js.map +1 -1
- package/dist-server/engine/read-time.d.ts +22 -0
- package/dist-server/engine/read-time.js +81 -0
- package/dist-server/engine/read-time.js.map +1 -0
- package/dist-server/engine/restart-policy.js +1 -1
- package/dist-server/engine/restart-policy.js.map +1 -1
- package/dist-server/engine/runtime-key.js +1 -1
- package/dist-server/engine/runtime-key.js.map +1 -1
- package/dist-server/engine/spec-coverage.d.ts +2 -2
- package/dist-server/engine/spec-coverage.js +1 -1
- package/dist-server/engine/spec-coverage.js.map +1 -1
- package/dist-server/engine/stage-path.d.ts +4 -4
- package/dist-server/engine/stage-path.js +1 -1
- package/dist-server/engine/stage-path.js.map +1 -1
- package/dist-server/engine/state-axes.d.ts +1 -1
- package/dist-server/engine/state-axes.js +2 -2
- package/dist-server/engine/state-axes.js.map +1 -1
- package/dist-server/engine/travel-estimator.d.ts +2 -2
- package/dist-server/engine/travel-estimator.js +1 -1
- package/dist-server/engine/travel-estimator.js.map +1 -1
- package/dist-server/engine/twin-engine.d.ts +307 -54
- package/dist-server/engine/twin-engine.js +822 -196
- package/dist-server/engine/twin-engine.js.map +1 -1
- package/dist-server/engine/warm-start.d.ts +2 -2
- package/dist-server/engine/warm-start.js +5 -5
- package/dist-server/engine/warm-start.js.map +1 -1
- package/dist-server/index.js +1 -1
- package/dist-server/index.js.map +1 -1
- package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js +1 -1
- package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js.map +1 -1
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js +3 -3
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +1 -1
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js +2 -2
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +1 -1
- package/dist-server/migrations/1786300000000-IndexEventTypeByTime.d.ts +5 -0
- package/dist-server/migrations/1786300000000-IndexEventTypeByTime.js +54 -0
- package/dist-server/migrations/1786300000000-IndexEventTypeByTime.js.map +1 -0
- package/dist-server/migrations/1786400000000-IndexEventCreatedAt.d.ts +5 -0
- package/dist-server/migrations/1786400000000-IndexEventCreatedAt.js +44 -0
- package/dist-server/migrations/1786400000000-IndexEventCreatedAt.js.map +1 -0
- package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.d.ts +6 -0
- package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.js +84 -0
- package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.js.map +1 -0
- package/dist-server/migrations/index.js +7 -1
- package/dist-server/migrations/index.js.map +1 -1
- package/dist-server/routes.d.ts +1 -0
- package/dist-server/routes.js +69 -5
- package/dist-server/routes.js.map +1 -1
- package/dist-server/service/index.d.ts +2 -2
- package/dist-server/service/index.js +30 -24
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/reference/control-routing.d.ts +1 -1
- package/dist-server/service/reference/control-routing.js +1 -1
- package/dist-server/service/reference/control-routing.js.map +1 -1
- package/dist-server/service/reference/discovery-result.d.ts +2 -2
- package/dist-server/service/reference/discovery-result.js +3 -3
- package/dist-server/service/reference/discovery-result.js.map +1 -1
- package/dist-server/service/reference/hook-contract.d.ts +43 -0
- package/dist-server/service/reference/hook-contract.js +59 -0
- package/dist-server/service/reference/hook-contract.js.map +1 -0
- package/dist-server/service/reference/ingest-space.d.ts +1 -1
- package/dist-server/service/reference/ingest-space.js +4 -4
- package/dist-server/service/reference/ingest-space.js.map +1 -1
- package/dist-server/service/reference/knob-defaults.d.ts +1 -1
- package/dist-server/service/reference/knob-defaults.js +4 -4
- package/dist-server/service/reference/knob-defaults.js.map +1 -1
- package/dist-server/service/reference/reference-adapter.d.ts +116 -9
- package/dist-server/service/reference/reference-adapter.js +27 -0
- package/dist-server/service/reference/reference-adapter.js.map +1 -1
- package/dist-server/service/reference/reference-hook.d.ts +20 -0
- package/dist-server/service/reference/reference-hook.js +133 -0
- package/dist-server/service/reference/reference-hook.js.map +1 -0
- package/dist-server/service/reference/reference-live.d.ts +2 -2
- package/dist-server/service/reference/reference-live.js +76 -13
- package/dist-server/service/reference/reference-live.js.map +1 -1
- package/dist-server/service/reference/reference-master.d.ts +25 -16
- package/dist-server/service/reference/reference-master.js +35 -13
- package/dist-server/service/reference/reference-master.js.map +1 -1
- package/dist-server/service/reference/reference-resolver.d.ts +1 -1
- package/dist-server/service/reference/reference-resolver.js +12 -12
- package/dist-server/service/reference/reference-resolver.js.map +1 -1
- package/dist-server/service/reference/template-registry.d.ts +1 -1
- package/dist-server/service/reference/template-registry.js.map +1 -1
- package/dist-server/service/reference/twin-reference.d.ts +3 -3
- package/dist-server/service/reference/twin-reference.js.map +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.d.ts +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.js +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.js.map +1 -1
- package/dist-server/service/twin-audit/command-audit.d.ts +1 -1
- package/dist-server/service/twin-audit/command-audit.js.map +1 -1
- package/dist-server/service/twin-audit/twin-audit-event.d.ts +1 -1
- package/dist-server/service/twin-audit/twin-audit-event.js.map +1 -1
- package/dist-server/service/twin-audit/twin-audit-query.js +1 -1
- package/dist-server/service/twin-audit/twin-audit-query.js.map +1 -1
- package/dist-server/service/twin-backfill/backfill-period-facts.d.ts +24 -0
- package/dist-server/service/twin-backfill/backfill-period-facts.js +96 -0
- package/dist-server/service/twin-backfill/backfill-period-facts.js.map +1 -0
- package/dist-server/service/twin-backfill/backfill-shape.d.ts +34 -0
- package/dist-server/service/twin-backfill/backfill-shape.js +75 -0
- package/dist-server/service/twin-backfill/backfill-shape.js.map +1 -0
- package/dist-server/service/twin-backfill/index.d.ts +2 -0
- package/dist-server/service/twin-backfill/index.js +6 -0
- package/dist-server/service/twin-backfill/index.js.map +1 -0
- package/dist-server/service/twin-backfill/twin-backfill-resolver.d.ts +10 -0
- package/dist-server/service/twin-backfill/twin-backfill-resolver.js +44 -0
- package/dist-server/service/twin-backfill/twin-backfill-resolver.js.map +1 -0
- package/dist-server/service/twin-control/twin-control-mutation.js +3 -3
- package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
- package/dist-server/service/twin-event/twin-event-keys.d.ts +1 -1
- package/dist-server/service/twin-event/twin-event-keys.js +2 -2
- package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
- package/dist-server/service/twin-event/twin-event-type.d.ts +1 -0
- package/dist-server/service/twin-event/twin-event-type.js +8 -1
- package/dist-server/service/twin-event/twin-event-type.js.map +1 -1
- package/dist-server/service/twin-event/twin-event.d.ts +2 -2
- package/dist-server/service/twin-event/twin-event.js +32 -4
- package/dist-server/service/twin-event/twin-event.js.map +1 -1
- package/dist-server/service/twin-forecast/forecast-metrics.js +1 -1
- package/dist-server/service/twin-forecast/forecast-metrics.js.map +1 -1
- package/dist-server/service/twin-forecast/gap-analytics.d.ts +1 -1
- package/dist-server/service/twin-forecast/gap-analytics.js.map +1 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js +29 -11
- package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.d.ts +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +1 -1
- package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
- package/dist-server/service/twin-journal/event-type-split-shape.d.ts +50 -0
- package/dist-server/service/twin-journal/event-type-split-shape.js +111 -0
- package/dist-server/service/twin-journal/event-type-split-shape.js.map +1 -0
- package/dist-server/service/twin-journal/event-type-split.d.ts +15 -0
- package/dist-server/service/twin-journal/event-type-split.js +102 -0
- package/dist-server/service/twin-journal/event-type-split.js.map +1 -0
- package/dist-server/service/twin-journal/journal-order.d.ts +15 -0
- package/dist-server/service/twin-journal/journal-order.js +17 -0
- package/dist-server/service/twin-journal/journal-order.js.map +1 -0
- package/dist-server/service/twin-journal/twin-journal-query.d.ts +5 -5
- package/dist-server/service/twin-journal/twin-journal-query.js +232 -21
- package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
- package/dist-server/service/twin-lifecycle/domain-catalog.js +2 -1
- package/dist-server/service/twin-lifecycle/domain-catalog.js.map +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +27 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +59 -3
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.js +14 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
- package/dist-server/service/twin-model/axis-journal-evidence.js +1 -1
- package/dist-server/service/twin-model/axis-journal-evidence.js.map +1 -1
- package/dist-server/service/twin-model/epcis-coverage.js +34 -3
- package/dist-server/service/twin-model/epcis-coverage.js.map +1 -1
- package/dist-server/service/twin-model/iec61850-coverage.js +1 -1
- package/dist-server/service/twin-model/iec61850-coverage.js.map +1 -1
- package/dist-server/service/twin-model/isa95-coverage.d.ts +12 -9
- package/dist-server/service/twin-model/isa95-coverage.js +33 -9
- package/dist-server/service/twin-model/isa95-coverage.js.map +1 -1
- package/dist-server/service/twin-model/item-ref.js +2 -2
- package/dist-server/service/twin-model/item-ref.js.map +1 -1
- package/dist-server/service/twin-model/name-index.d.ts +1 -1
- package/dist-server/service/twin-model/name-index.js +2 -2
- package/dist-server/service/twin-model/name-index.js.map +1 -1
- package/dist-server/service/twin-model/project-structure.d.ts +1 -1
- package/dist-server/service/twin-model/project-structure.js +7 -6
- package/dist-server/service/twin-model/project-structure.js.map +1 -1
- package/dist-server/service/twin-model/twin-equipment.d.ts +2 -2
- package/dist-server/service/twin-model/twin-equipment.js +3 -3
- package/dist-server/service/twin-model/twin-equipment.js.map +1 -1
- package/dist-server/service/twin-model/twin-lineage-query.js +16 -5
- package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-location.d.ts +1 -1
- package/dist-server/service/twin-model/twin-location.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-item-query.d.ts +3 -3
- package/dist-server/service/twin-model/twin-model-item-query.js +15 -15
- package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-mutation.d.ts +2 -2
- package/dist-server/service/twin-model/twin-model-mutation.js +4 -4
- package/dist-server/service/twin-model/twin-model-mutation.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-query.js +51 -30
- package/dist-server/service/twin-model/twin-model-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-tree-query.js +23 -1
- package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-operation.d.ts +1 -1
- package/dist-server/service/twin-model/twin-operation.js +1 -1
- package/dist-server/service/twin-model/twin-operation.js.map +1 -1
- package/dist-server/service/twin-space/move-space.js +2 -2
- package/dist-server/service/twin-space/move-space.js.map +1 -1
- package/dist-server/service/twin-space/representation-role.d.ts +2 -0
- package/dist-server/service/twin-space/representation-role.js +18 -0
- package/dist-server/service/twin-space/representation-role.js.map +1 -0
- package/dist-server/service/twin-space/space-integrity.d.ts +1 -1
- package/dist-server/service/twin-space/space-integrity.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-representation.d.ts +2 -0
- package/dist-server/service/twin-space/twin-space-representation.js +16 -0
- package/dist-server/service/twin-space/twin-space-representation.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-resolver.d.ts +2 -2
- package/dist-server/service/twin-space/twin-space-resolver.js +37 -8
- package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
- package/dist-server/service/twin-structure/twin-structure.js +3 -3
- package/dist-server/service/twin-structure/twin-structure.js.map +1 -1
- package/dist-server/service/twin-subject/event-subjects.d.ts +43 -0
- package/dist-server/service/twin-subject/event-subjects.js +137 -0
- package/dist-server/service/twin-subject/event-subjects.js.map +1 -0
- package/dist-server/service/twin-subject/index.d.ts +9 -0
- package/dist-server/service/twin-subject/index.js +16 -0
- package/dist-server/service/twin-subject/index.js.map +1 -0
- package/dist-server/service/twin-subject/item-resolver.d.ts +10 -0
- package/dist-server/service/twin-subject/item-resolver.js +93 -0
- package/dist-server/service/twin-subject/item-resolver.js.map +1 -0
- package/dist-server/service/twin-subject/subject-query-shape.d.ts +22 -0
- package/dist-server/service/twin-subject/subject-query-shape.js +88 -0
- package/dist-server/service/twin-subject/subject-query-shape.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-backfill.d.ts +23 -0
- package/dist-server/service/twin-subject/twin-subject-backfill.js +159 -0
- package/dist-server/service/twin-subject/twin-subject-backfill.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-event.d.ts +14 -0
- package/dist-server/service/twin-subject/twin-subject-event.js +111 -0
- package/dist-server/service/twin-subject/twin-subject-event.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-fast-path.d.ts +39 -0
- package/dist-server/service/twin-subject/twin-subject-fast-path.js +295 -0
- package/dist-server/service/twin-subject/twin-subject-fast-path.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-query.d.ts +27 -0
- package/dist-server/service/twin-subject/twin-subject-query.js +232 -0
- package/dist-server/service/twin-subject/twin-subject-query.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-writer.d.ts +27 -0
- package/dist-server/service/twin-subject/twin-subject-writer.js +166 -0
- package/dist-server/service/twin-subject/twin-subject-writer.js.map +1 -0
- package/dist-server/service/twin-target/twin-target-resolver.js +1 -1
- package/dist-server/service/twin-target/twin-target-resolver.js.map +1 -1
- package/dist-shared/entity-delta.d.ts +1 -1
- package/dist-shared/entity-delta.js +4 -4
- package/dist-shared/entity-delta.js.map +1 -1
- package/dist-shared/touched-items.js +2 -2
- package/dist-shared/touched-items.js.map +1 -1
- package/dist-shared/twin-level.js +1 -1
- package/dist-shared/twin-level.js.map +1 -1
- package/package.json +7 -6
- package/server/engine/attention-digest.ts +9 -9
- package/server/engine/canonical-ingest.ts +202 -87
- package/server/engine/command-routing.ts +1 -1
- package/server/engine/declared-stimulus.ts +1 -1
- package/server/engine/energy-topology.ts +2 -2
- package/server/engine/ingest-dedupe.ts +149 -0
- package/server/engine/ingest-health.ts +171 -22
- package/server/engine/integration-probes.ts +7 -7
- package/server/engine/kpi-baseline.ts +4 -4
- package/server/engine/kpi-fold.ts +592 -41
- package/server/engine/kpi-query.ts +307 -48
- package/server/engine/live-feed-registry.ts +1 -1
- package/server/engine/load-meter.ts +1 -1
- package/server/engine/local-declarations.ts +15 -14
- package/server/engine/log.ts +1 -1
- package/server/engine/measured-estimator.ts +1 -1
- package/server/engine/measured-yield.ts +1 -1
- package/server/engine/model-basis.ts +2 -2
- package/server/engine/model-gap.ts +3 -3
- package/server/engine/model-vocabulary.ts +2 -2
- package/server/engine/oee-accumulator.ts +8 -6
- package/server/engine/property-effects.ts +2 -2
- package/server/engine/read-time.ts +77 -0
- package/server/engine/restart-policy.ts +1 -1
- package/server/engine/runtime-key.ts +1 -1
- package/server/engine/spec-coverage.ts +3 -3
- package/server/engine/stage-path.ts +5 -5
- package/server/engine/state-axes.ts +2 -2
- package/server/engine/travel-estimator.ts +2 -2
- package/server/engine/twin-engine.ts +906 -205
- package/server/engine/warm-start.ts +6 -6
- package/server/index.ts +1 -1
- package/server/migrations/1786000000000-RenameTwinInstanceBoardToModel.ts +1 -1
- package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +3 -3
- package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +2 -2
- package/server/migrations/1786300000000-IndexEventTypeByTime.ts +48 -0
- package/server/migrations/1786400000000-IndexEventCreatedAt.ts +38 -0
- package/server/migrations/1786500000000-CreateTwinSubjectEvents.ts +93 -0
- package/server/migrations/index.ts +7 -1
- package/server/routes.ts +73 -5
- package/server/service/index.ts +7 -1
- package/server/service/reference/control-routing.ts +1 -1
- package/server/service/reference/discovery-result.ts +3 -3
- package/server/service/reference/hook-contract.ts +103 -0
- package/server/service/reference/ingest-space.ts +4 -4
- package/server/service/reference/knob-defaults.ts +4 -4
- package/server/service/reference/reference-adapter.ts +145 -10
- package/server/service/reference/reference-hook.ts +145 -0
- package/server/service/reference/reference-live.ts +87 -15
- package/server/service/reference/reference-master.ts +51 -20
- package/server/service/reference/reference-resolver.ts +11 -11
- package/server/service/reference/template-registry.ts +1 -1
- package/server/service/reference/twin-reference.ts +3 -3
- package/server/service/twin-attention/twin-attention-query.ts +1 -1
- package/server/service/twin-audit/command-audit.ts +1 -1
- package/server/service/twin-audit/twin-audit-event.ts +2 -2
- package/server/service/twin-audit/twin-audit-query.ts +1 -1
- package/server/service/twin-backfill/backfill-period-facts.ts +168 -0
- package/server/service/twin-backfill/backfill-shape.ts +86 -0
- package/server/service/twin-backfill/index.ts +3 -0
- package/server/service/twin-backfill/twin-backfill-resolver.ts +35 -0
- package/server/service/twin-control/twin-control-mutation.ts +2 -2
- package/server/service/twin-event/twin-event-keys.ts +2 -2
- package/server/service/twin-event/twin-event-type.ts +18 -1
- package/server/service/twin-event/twin-event.ts +32 -6
- package/server/service/twin-forecast/forecast-metrics.ts +1 -1
- package/server/service/twin-forecast/gap-analytics.ts +1 -1
- package/server/service/twin-forecast/twin-forecast-query.ts +30 -11
- package/server/service/twin-ingest-window/twin-ingest-window-query.ts +1 -1
- package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +1 -1
- package/server/service/twin-instance/twin-instance.ts +4 -4
- package/server/service/twin-journal/event-type-split-shape.ts +112 -0
- package/server/service/twin-journal/event-type-split.ts +144 -0
- package/server/service/twin-journal/journal-order.ts +20 -0
- package/server/service/twin-journal/twin-journal-query.ts +224 -20
- package/server/service/twin-lifecycle/domain-catalog.ts +2 -1
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +58 -4
- package/server/service/twin-metrics/twin-metrics-query.ts +14 -1
- package/server/service/twin-model/axis-journal-evidence.ts +1 -1
- package/server/service/twin-model/epcis-coverage.ts +34 -3
- package/server/service/twin-model/iec61850-coverage.ts +1 -1
- package/server/service/twin-model/isa95-coverage.ts +43 -16
- package/server/service/twin-model/item-ref.ts +2 -2
- package/server/service/twin-model/name-index.ts +2 -2
- package/server/service/twin-model/project-structure.ts +7 -6
- package/server/service/twin-model/twin-equipment.ts +16 -4
- package/server/service/twin-model/twin-lineage-query.ts +16 -5
- package/server/service/twin-model/twin-location.ts +1 -1
- package/server/service/twin-model/twin-model-item-query.ts +15 -15
- package/server/service/twin-model/twin-model-mutation.ts +4 -4
- package/server/service/twin-model/twin-model-query.ts +49 -28
- package/server/service/twin-model/twin-model-tree-query.ts +26 -2
- package/server/service/twin-model/twin-operation.ts +2 -2
- package/server/service/twin-space/move-space.ts +3 -3
- package/server/service/twin-space/representation-role.ts +15 -0
- package/server/service/twin-space/space-integrity.ts +1 -1
- package/server/service/twin-space/twin-space-representation.ts +37 -0
- package/server/service/twin-space/twin-space-resolver.ts +40 -8
- package/server/service/twin-structure/twin-structure.ts +3 -3
- package/server/service/twin-subject/event-subjects.ts +155 -0
- package/server/service/twin-subject/index.ts +10 -0
- package/server/service/twin-subject/item-resolver.ts +92 -0
- package/server/service/twin-subject/subject-query-shape.ts +84 -0
- package/server/service/twin-subject/twin-subject-backfill.ts +196 -0
- package/server/service/twin-subject/twin-subject-event.ts +101 -0
- package/server/service/twin-subject/twin-subject-fast-path.ts +346 -0
- package/server/service/twin-subject/twin-subject-query.ts +210 -0
- package/server/service/twin-subject/twin-subject-writer.ts +189 -0
- package/server/service/twin-target/twin-target-resolver.ts +1 -1
- package/shared/entity-delta.ts +4 -4
- package/shared/touched-items.ts +2 -2
- package/shared/twin-level.ts +1 -1
- package/test/adopt-structure-live.test.ts +3 -3
- package/test/aggregate-not-findone.test.ts +112 -0
- package/test/attention-digest.test.ts +6 -6
- package/test/axis-read.test.ts +6 -5
- package/test/backfill-shape.test.ts +89 -0
- package/test/boot-resume.test.ts +20 -7
- package/test/broadcast-cost-baseline.test.ts +2 -1
- package/test/broadcast-period.test.ts +2 -2
- package/test/broadcast-queue-overflow.test.ts +244 -0
- package/test/canonical-ingest-vocabularies.test.ts +259 -8
- package/test/canonical-quantity-door.test.ts +2 -2
- package/test/capability-mapping.test.ts +1 -1
- package/test/checkpoint-refuses-empty.test.ts +2 -2
- package/test/connector-capability-declaration.test.ts +88 -0
- package/test/contract-layer-guard.test.ts +48 -0
- package/test/control-capability.test.ts +1 -1
- package/test/cursor-stall-not-read-failure.test.ts +2 -2
- package/test/declaration-reaches-model.test.ts +7 -5
- package/test/declared-stimulus.test.ts +4 -4
- package/test/discovery-result.test.ts +2 -2
- package/test/entity-delta.test.ts +4 -4
- package/test/equipment-identity-reaches.test.ts +57 -0
- package/test/event-subjects.test.ts +147 -0
- package/test/event-time-column.test.ts +3 -3
- package/test/event-type-split.test.ts +155 -0
- package/test/fact-scope-wiring.test.ts +96 -0
- package/test/fold-gap-speaks.test.ts +53 -0
- package/test/forecast-metrics.test.ts +1 -1
- package/test/forecast-tuning.test.ts +1 -1
- package/test/generated-not-counted.test.ts +99 -0
- package/test/ingest-bench.test.ts +2 -1
- package/test/ingest-health-engine.test.ts +2 -2
- package/test/ingest-health-wiring.test.ts +7 -5
- package/test/ingest-health.test.ts +6 -6
- package/test/ingest-history.test.ts +2 -2
- package/test/ingest-idempotent.test.ts +132 -0
- package/test/ingest-space.test.ts +3 -3
- package/test/ingest-wiring-guard.test.ts +197 -0
- package/test/integration-probes.test.ts +3 -3
- package/test/integration-runner.test.ts +1 -1
- package/test/item-ref.test.ts +1 -1
- package/test/journal-order-axis.test.ts +80 -0
- package/test/journal-read-discipline.test.ts +16 -6
- package/test/journal-retention.test.ts +171 -29
- package/test/journal-sort-axis.test.ts +1 -1
- package/test/journal-write-door.test.ts +3 -3
- package/test/journal-write-trend.test.ts +1 -1
- package/test/kernel-kind-guard.test.ts +3 -3
- package/test/knob-defaults.test.ts +1 -1
- package/test/kpi-baseline-db.test.ts +2 -2
- package/test/kpi-fold.test.ts +266 -14
- package/test/kpi-query-bench.test.ts +3 -3
- package/test/live-cursor-wiring.test.ts +6 -6
- package/test/live-kernel-facts.test.ts +11 -11
- package/test/live-mirror-parity.test.ts +9 -6
- package/test/load-meter.test.ts +1 -1
- package/test/local-declarations.test.ts +13 -12
- package/test/log-stamp.test.ts +1 -1
- package/test/master-to-twin.test.ts +2 -2
- package/test/measured-yield.test.ts +2 -2
- package/test/merge-streams.test.ts +70 -0
- package/test/mirror-resumes-from-checkpoint.test.ts +13 -13
- package/test/model-basis.test.ts +2 -2
- package/test/model-gap.test.ts +4 -4
- package/test/model-vocabulary.test.ts +2 -2
- package/test/move-space.test.ts +1 -1
- package/test/oee-accumulator.test.ts +20 -5
- package/test/operational-vocabulary.test.ts +2 -2
- package/test/project-structure-db.test.ts +2 -2
- package/test/projection-reaches-screen.test.ts +7 -2
- package/test/projection-reads-declared.test.ts +109 -0
- package/test/property-effects.test.ts +10 -6
- package/test/read-failure-ledger.test.ts +106 -0
- package/test/read-failure-visible.test.ts +7 -7
- package/test/read-time.test.ts +118 -0
- package/test/reference-grounding.test.ts +1 -1
- package/test/reference-hook.test.ts +86 -0
- package/test/registry-key-guard.test.ts +1 -1
- package/test/rename-twin.test.ts +81 -0
- package/test/restart-policy.test.ts +3 -3
- package/test/resync-origin-site.test.ts +3 -3
- package/test/revision-axis.test.ts +14 -8
- package/test/runtime-key.test.ts +3 -3
- package/test/scale-twin-bench.test.ts +2 -1
- package/test/snapshot-freshness.test.ts +4 -4
- package/test/source-outcome-audit.test.ts +1 -1
- package/test/space-integrity.test.ts +1 -1
- package/test/space-representation.test.ts +66 -0
- package/test/space-scope-includes-stopped.test.ts +55 -0
- package/test/spec-coverage.test.ts +1 -1
- package/test/standard-coverage.test.ts +19 -21
- package/test/status-tally.test.ts +1 -1
- package/test/structure-revision-db.test.ts +7 -7
- package/test/subject-fast-path.test.ts +148 -0
- package/test/subject-read-model.test.ts +175 -0
- package/test/touched-items.test.ts +2 -2
- package/test/twin-audit.test.ts +1 -1
- package/test/twin-event-keys.test.ts +1 -1
- package/test/twin-model-item-db.test.ts +5 -5
- package/test/twin-model-tree-db.test.ts +35 -2
- package/test/twin-origin-resync.test.ts +1 -1
- package/test/vocabulary-guard.test.ts +1 -1
- package/test/warm-start-seam.test.ts +1 -1
- package/test/warm-start.test.ts +6 -6
- package/test/withheld-door.test.ts +2 -2
- package/test/yield-loop.test.ts +4 -4
- package/tsconfig.shared.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -14,9 +14,9 @@ export interface AttentionDigestResult {
|
|
|
14
14
|
/** 전체 개수 — 레일의 "N건 더" 가 이 값에서 나온다(자른 사실을 밝힌다). */
|
|
15
15
|
attentionTotal: number;
|
|
16
16
|
/**
|
|
17
|
-
* 자리별 최고 심각도 — **전량을 근거로**
|
|
17
|
+
* 자리별 최고 심각도 — **전량을 근거로** 계산한다.
|
|
18
18
|
*
|
|
19
|
-
* 상위 N 만으로
|
|
19
|
+
* 상위 N 만으로 계산하면 20위 밖의 신호를 가진 자리가 색을 잃는다. 그것이 이 요약의 핵심 이유다:
|
|
20
20
|
* 레일은 잘라도 되지만 **지도 색은 잘라선 안 된다.**
|
|
21
21
|
*/
|
|
22
22
|
severityByLocation: Record<string, string>;
|
|
@@ -27,7 +27,7 @@ export declare const compareAttentions: (a: AttentionLike, b: AttentionLike) =>
|
|
|
27
27
|
* 신호를 요약한다.
|
|
28
28
|
*
|
|
29
29
|
* `limit` 이 없거나 0 이하면 **자르지 않는다** — 자르는 쪽이 기본이면 이 값을 모르는 소비처가
|
|
30
|
-
*
|
|
30
|
+
* 알리지 않고 일부만 받는다(요약을 도입하다 만드는 전형적인 사고다).
|
|
31
31
|
*/
|
|
32
32
|
export declare function digestAttentions(attentions: readonly AttentionLike[] | undefined | null, limit?: number): AttentionDigestResult;
|
|
33
33
|
/** 렌즈 하나가 낸 신호 — 어느 트윈에서 왔는지와 함께. */
|
|
@@ -45,7 +45,7 @@ export interface LensAttentions {
|
|
|
45
45
|
* 같은 자리 id 가 렌즈마다 다른 것을 가리킬 수 있다.
|
|
46
46
|
* ② **순서는 렌즈 순서가 아니라 급한 순서다** — 앞 렌즈의 낮은 신호가 뒤 렌즈의 심각한 신호를
|
|
47
47
|
* 밀어내면, 상위 N 만 보는 화면에서 정작 급한 것이 안 보인다.
|
|
48
|
-
* ③ **자리 색은 렌즈를 가로질러 가장 급한 것으로**
|
|
48
|
+
* ③ **자리 색은 렌즈를 가로질러 가장 급한 것으로** 계산한다 — 두 렌즈가 같은 자리를 가리키면 그 자리는
|
|
49
49
|
* 하나의 현실이므로 더 급한 쪽이 이긴다(둘 중 하나를 임의로 고르면 색이 렌즈 순서에 따라 달라진다).
|
|
50
50
|
*/
|
|
51
51
|
export declare function mergeLensAttentions(lenses: readonly LensAttentions[], limit?: number): AttentionDigestResult;
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
* 는 신호 397건이 108KB 라 5배 감소에 그쳤다. 그런데 화면이 그 397건으로 하는 일은 둘뿐이다.
|
|
8
8
|
*
|
|
9
9
|
* ① 레일에 **20건**만 보여주고 나머지는 "N건 더" 라고만 말한다.
|
|
10
|
-
* ② 자리(폴리곤)를 칠할 **자리별 최고 심각도**를 뽑는다 — 397건이 자리 7곳의 색 7개로
|
|
10
|
+
* ② 자리(폴리곤)를 칠할 **자리별 최고 심각도**를 뽑는다 — 397건이 자리 7곳의 색 7개로 줄어든다.
|
|
11
11
|
*
|
|
12
|
-
* 즉 전량을 내려보내 클라이언트가
|
|
12
|
+
* 즉 전량을 내려보내 클라이언트가 계산하는 구조였다. 계산하는 것은 값싸므로 **서버가 계산해서 보낸다.**
|
|
13
13
|
*
|
|
14
|
-
* ──
|
|
15
|
-
* 잘랐다는 사실과 **전체 개수**를 함께 보낸다. 경고 목록에서
|
|
14
|
+
* ── 알리지 않고 자르지 않는다 ────────────────────────────────────────────────────
|
|
15
|
+
* 잘랐다는 사실과 **전체 개수**를 함께 보낸다. 경고 목록에서 들어온 것이 없는 누락은 "괜찮은 줄 알았다" 로
|
|
16
16
|
* 이어진다 — 레일이 이미 "N건 더" 를 말하고 있었고, 그 N 은 전체 개수에서 나와야 맞다.
|
|
17
17
|
*
|
|
18
18
|
* ── 정렬을 한 곳에 둔다 ─────────────────────────────────────────────────────
|
|
@@ -34,11 +34,11 @@ exports.compareAttentions = compareAttentions;
|
|
|
34
34
|
* 신호를 요약한다.
|
|
35
35
|
*
|
|
36
36
|
* `limit` 이 없거나 0 이하면 **자르지 않는다** — 자르는 쪽이 기본이면 이 값을 모르는 소비처가
|
|
37
|
-
*
|
|
37
|
+
* 알리지 않고 일부만 받는다(요약을 도입하다 만드는 전형적인 사고다).
|
|
38
38
|
*/
|
|
39
39
|
function digestAttentions(attentions, limit) {
|
|
40
40
|
const all = Array.isArray(attentions) ? attentions : [];
|
|
41
|
-
/* 자리 색은 전량으로
|
|
41
|
+
/* 자리 색은 전량으로 처리한다 — 잘린 뒤에 계산하면 색을 잃는 자리가 생긴다. */
|
|
42
42
|
const severityByLocation = {};
|
|
43
43
|
for (const a of all) {
|
|
44
44
|
const nid = a?.anchor?.locationId;
|
|
@@ -62,7 +62,7 @@ function digestAttentions(attentions, limit) {
|
|
|
62
62
|
* 같은 자리 id 가 렌즈마다 다른 것을 가리킬 수 있다.
|
|
63
63
|
* ② **순서는 렌즈 순서가 아니라 급한 순서다** — 앞 렌즈의 낮은 신호가 뒤 렌즈의 심각한 신호를
|
|
64
64
|
* 밀어내면, 상위 N 만 보는 화면에서 정작 급한 것이 안 보인다.
|
|
65
|
-
* ③ **자리 색은 렌즈를 가로질러 가장 급한 것으로**
|
|
65
|
+
* ③ **자리 색은 렌즈를 가로질러 가장 급한 것으로** 계산한다 — 두 렌즈가 같은 자리를 가리키면 그 자리는
|
|
66
66
|
* 하나의 현실이므로 더 급한 쪽이 이긴다(둘 중 하나를 임의로 고르면 색이 렌즈 순서에 따라 달라진다).
|
|
67
67
|
*/
|
|
68
68
|
function mergeLensAttentions(lenses, limit) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attention-digest.js","sourceRoot":"","sources":["../../server/engine/attention-digest.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAuCH,4CAeC;AAqBD,kDAMC;AA/ED,uCAAuC;AACvC,MAAM,IAAI,GAA2B,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;AAyBhF,+CAA+C;AACxC,MAAM,iBAAiB,GAAG,CAAC,CAAgB,EAAE,CAAgB,EAAU,EAAE,CAC9E,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;AAFlD,QAAA,iBAAiB,qBAEiC;AAE/D;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,UAAuD,EAAE,KAAc;IACtG,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;IAEvD
|
|
1
|
+
{"version":3,"file":"attention-digest.js","sourceRoot":"","sources":["../../server/engine/attention-digest.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAuCH,4CAeC;AAqBD,kDAMC;AA/ED,uCAAuC;AACvC,MAAM,IAAI,GAA2B,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAA;AAyBhF,+CAA+C;AACxC,MAAM,iBAAiB,GAAG,CAAC,CAAgB,EAAE,CAAgB,EAAU,EAAE,CAC9E,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;AAFlD,QAAA,iBAAiB,qBAEiC;AAE/D;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,UAAuD,EAAE,KAAc;IACtG,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;IAEvD,iDAAiD;IACjD,MAAM,kBAAkB,GAA2B,EAAE,CAAA;IACrD,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,CAAA;QACjC,IAAI,CAAC,GAAG;YAAE,SAAQ;QAClB,MAAM,GAAG,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;QACnC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAAE,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAA;IAC1G,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,yBAAiB,CAAC,CAAA;IAC/C,MAAM,MAAM,GAAG,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IACnE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAA;AAC/E,CAAC;AAQD;;;;;;;;;;;;GAYG;AACH,SAAgB,mBAAmB,CAAC,MAAiC,EAAE,KAAc;IACnF,MAAM,GAAG,GAAoB,EAAE,CAAA;IAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAmB,CAAC,CAAA;IACzG,CAAC;IACD,OAAO,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;AACrC,CAAC","sourcesContent":["/*\n * 주의 신호 요약 — **순수**. \"화면이 실제로 쓰는 두 가지만 값싸게 만든다.\"\n *\n * ── 왜 있나 (2026-08-05) ────────────────────────────────────────────────────\n * 축 선택으로 리프레시를 80KB → 2KB 로 줄였는데, **신호가 많은 트윈은 거기서 막혔다**: `hatio-yard`\n * 는 신호 397건이 108KB 라 5배 감소에 그쳤다. 그런데 화면이 그 397건으로 하는 일은 둘뿐이다.\n *\n * ① 레일에 **20건**만 보여주고 나머지는 \"N건 더\" 라고만 말한다.\n * ② 자리(폴리곤)를 칠할 **자리별 최고 심각도**를 뽑는다 — 397건이 자리 7곳의 색 7개로 줄어든다.\n *\n * 즉 전량을 내려보내 클라이언트가 계산하는 구조였다. 계산하는 것은 값싸므로 **서버가 계산해서 보낸다.**\n *\n * ── 알리지 않고 자르지 않는다 ────────────────────────────────────────────────────\n * 잘랐다는 사실과 **전체 개수**를 함께 보낸다. 경고 목록에서 들어온 것이 없는 누락은 \"괜찮은 줄 알았다\" 로\n * 이어진다 — 레일이 이미 \"N건 더\" 를 말하고 있었고, 그 N 은 전체 개수에서 나와야 맞다.\n *\n * ── 정렬을 한 곳에 둔다 ─────────────────────────────────────────────────────\n * 상위 N 을 서버가 고르므로 **클라이언트와 같은 순서**여야 한다. 순서가 다르면 서버가 고른 20건이\n * 화면이 고를 20건과 달라지고, 그 어긋남은 아무 데서도 오류로 드러나지 않는다.\n * 순서 = 확인된 것은 아래로, 그다음 심각도 높은 것부터(클라이언트 정렬과 동일).\n */\n\n/** 알람 표준(ISA-18.2) 우선순위 — 큰 값이 급하다. */\nconst RANK: Record<string, number> = { low: 1, medium: 2, high: 3, critical: 4 }\n\ninterface AttentionLike {\n id?: string\n /** 어느 트윈(렌즈)에서 온 신호인가 — 공간에서 모을 때 붙는다. */\n instanceId?: string\n severity?: string\n state?: string\n anchor?: { locationId?: string }\n}\n\nexport interface AttentionDigestResult {\n /** 상위 N — 레일이 그리는 것. */\n attentions: AttentionLike[]\n /** 전체 개수 — 레일의 \"N건 더\" 가 이 값에서 나온다(자른 사실을 밝힌다). */\n attentionTotal: number\n /**\n * 자리별 최고 심각도 — **전량을 근거로** 계산한다.\n *\n * 상위 N 만으로 계산하면 20위 밖의 신호를 가진 자리가 색을 잃는다. 그것이 이 요약의 핵심 이유다:\n * 레일은 잘라도 되지만 **지도 색은 잘라선 안 된다.**\n */\n severityByLocation: Record<string, string>\n}\n\n/** 화면 정렬과 같은 순서 — 확인된 것은 아래로, 그다음 심각도 내림차순. */\nexport const compareAttentions = (a: AttentionLike, b: AttentionLike): number =>\n (a.state === 'acknowledged' ? 1 : 0) - (b.state === 'acknowledged' ? 1 : 0) ||\n (RANK[b.severity ?? ''] ?? 0) - (RANK[a.severity ?? ''] ?? 0)\n\n/**\n * 신호를 요약한다.\n *\n * `limit` 이 없거나 0 이하면 **자르지 않는다** — 자르는 쪽이 기본이면 이 값을 모르는 소비처가\n * 알리지 않고 일부만 받는다(요약을 도입하다 만드는 전형적인 사고다).\n */\nexport function digestAttentions(attentions: readonly AttentionLike[] | undefined | null, limit?: number): AttentionDigestResult {\n const all = Array.isArray(attentions) ? attentions : []\n\n /* 자리 색은 전량으로 처리한다 — 잘린 뒤에 계산하면 색을 잃는 자리가 생긴다. */\n const severityByLocation: Record<string, string> = {}\n for (const a of all) {\n const nid = a?.anchor?.locationId\n if (!nid) continue\n const cur = severityByLocation[nid]\n if (!cur || (RANK[a.severity ?? ''] ?? 0) > (RANK[cur] ?? 0)) severityByLocation[nid] = a.severity ?? ''\n }\n\n const sorted = [...all].sort(compareAttentions)\n const capped = limit && limit > 0 ? sorted.slice(0, limit) : sorted\n return { attentions: capped, attentionTotal: all.length, severityByLocation }\n}\n\n/** 렌즈 하나가 낸 신호 — 어느 트윈에서 왔는지와 함께. */\nexport interface LensAttentions {\n instanceId: string\n attentions: readonly AttentionLike[] | undefined | null\n}\n\n/**\n * 여러 렌즈의 신호를 **한 현장의 목록으로** 모은다.\n *\n * 한 공장에 WMS·MES·YMS 가 함께 있으므로 \"이 현장에서 봐야 할 것\" 은 렌즈 하나로 답할 수 없다.\n * 모으면서 지키는 것 셋:\n *\n * ① **어느 트윈에서 왔는지 붙인다**(`instanceId`) — 조치는 결국 그 트윈에 보내야 하고, 공간에서 보면\n * 같은 자리 id 가 렌즈마다 다른 것을 가리킬 수 있다.\n * ② **순서는 렌즈 순서가 아니라 급한 순서다** — 앞 렌즈의 낮은 신호가 뒤 렌즈의 심각한 신호를\n * 밀어내면, 상위 N 만 보는 화면에서 정작 급한 것이 안 보인다.\n * ③ **자리 색은 렌즈를 가로질러 가장 급한 것으로** 계산한다 — 두 렌즈가 같은 자리를 가리키면 그 자리는\n * 하나의 현실이므로 더 급한 쪽이 이긴다(둘 중 하나를 임의로 고르면 색이 렌즈 순서에 따라 달라진다).\n */\nexport function mergeLensAttentions(lenses: readonly LensAttentions[], limit?: number): AttentionDigestResult {\n const all: AttentionLike[] = []\n for (const lens of lenses) {\n for (const a of lens.attentions ?? []) all.push({ ...a, instanceId: lens.instanceId } as AttentionLike)\n }\n return digestAttentions(all, limit)\n}\n"]}
|
|
@@ -1,89 +1,25 @@
|
|
|
1
|
-
import { type EnergyRecord, type EnergyEquipmentRecord, type OperationalRecord, type IngestResult } from '@operato/
|
|
2
|
-
/**
|
|
3
|
-
export
|
|
4
|
-
/**
|
|
5
|
-
* 개체 하나의 식별자. **`quantityList` 를 쓰면 없어도 된다** — 낱개 번호가 없는 자재(밀가루 3.5kg)는
|
|
6
|
-
* 개체가 없다. 둘 다 없으면 무엇을 관측했는지 말하지 않은 것이므로 커널 매핑이 거부한다.
|
|
7
|
-
*/
|
|
8
|
-
epc?: string;
|
|
9
|
-
/**
|
|
10
|
-
* 클래스와 수량 — `{ epcClass, quantity, uom? }`. **잔량 절대값을 싣는다**(「얼마 뺐다」가 아니라
|
|
11
|
-
* 「얼마 남았다」). 그래야 사건 하나를 놓쳐도 다음 사건이 정답을 다시 말해 주고 오차가 쌓이지 않는다.
|
|
12
|
-
*
|
|
13
|
-
* 담김(`childQuantityList`)이 하루 먼저 이 자리를 받았다 — 그때와 같은 이유다. 원본이 비직렬 수량을
|
|
14
|
-
* 말할 길이 없어서, 그것이 주된 경로인 시스템(식품 제조 MES)은 라이브를 낼 수 없었다. 커널의
|
|
15
|
-
* 관측 리듀서는 처음부터 이 값을 읽었고 문만 없었다.
|
|
16
|
-
*/
|
|
17
|
-
quantityList?: {
|
|
18
|
-
epcClass: string;
|
|
19
|
-
quantity?: number;
|
|
20
|
-
uom?: string;
|
|
21
|
-
}[];
|
|
22
|
-
action: string;
|
|
23
|
-
bizStep: string;
|
|
24
|
-
disposition?: string;
|
|
25
|
-
readPoint?: string;
|
|
26
|
-
bizLocation?: string;
|
|
27
|
-
}
|
|
1
|
+
import { type CanonicalRecord, type CanonicalAggregationRecord, type CanonicalTransformationRecord, type EnergyRecord, type EnergyEquipmentRecord, type OperationalRecord, type IngestResult, type MasterDataRecord } from '@operato/ops-contract';
|
|
2
|
+
/** 정규 레코드[] → 검증된 CanonicalEnvelope[] (+ 거부분). 순수 함수. 단일→객체도 배열로 정규화. */
|
|
3
|
+
export declare function ingestCanonicalRecords(records: CanonicalRecord | CanonicalAggregationRecord | CanonicalTransformationRecord | EnergyRecord | EnergyEquipmentRecord | OperationalRecord | MasterDataRecord | (CanonicalRecord | CanonicalAggregationRecord | CanonicalTransformationRecord | EnergyRecord | EnergyEquipmentRecord | OperationalRecord | MasterDataRecord)[] | undefined | null, tenantId: string, defaultEventTime: string,
|
|
28
4
|
/**
|
|
29
|
-
*
|
|
5
|
+
* **이 사실들이 어느 트윈의 것인가** — 마감된 구간 사실의 이름에 쓰인다(커널 §`SubjectBasis`).
|
|
30
6
|
*
|
|
31
|
-
*
|
|
32
|
-
* 같은
|
|
7
|
+
* 커널은 도메인으로 서므로 자기가 어느 트윈인지 모른다. 그런데 설비 번호·계량 지점 번호는 트윈
|
|
8
|
+
* 안에서만 통하는 이름표라, 한 도메인에 현장이 둘이면 서로 다른 설비의 같은 날이 한 사실이 된다.
|
|
9
|
+
* 실측으로 그 일이 났다 — 두 발전소의 `002` 가 겹쳤다.
|
|
10
|
+
*
|
|
11
|
+
* 주지 않으면 이름표를 그대로 쓰고 `twin-local` 로 표시된다 — 겹칠 수 있다는 뜻이다.
|
|
33
12
|
*/
|
|
13
|
+
scope?: {
|
|
14
|
+
scopeId?: string;
|
|
15
|
+
identityOf?: (kind: 'equipment' | 'meter', localId: string) => string | undefined;
|
|
16
|
+
}): CanonicalIngestResult;
|
|
34
17
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* 따로 보내면(「이 로트가 없어졌다」와 「이 제품이 생겼다」) 그 둘을 이을 근거가 없다. 그래서 표준이
|
|
38
|
-
* 한 사건에 둘을 담고, 우리 레코드도 같은 모양이다.
|
|
18
|
+
* 유입 결과 — 사건(봉투)과 **사건이 아닌 것**을 갈라 낸다.
|
|
39
19
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* 매핑은 그 안에서 값을 고른다.
|
|
43
|
-
*
|
|
44
|
-
* **없는 쪽은 필드를 만들지 않는다.** 빈 배열을 실으면 「없다」고 말하는 것이 된다. 소실(N→0)과
|
|
45
|
-
* 생성(0→N)도 표준이 인정하는 변환이다.
|
|
46
|
-
*
|
|
47
|
-
* `transformationID` 가 한 오더의 여러 단계를 잇는다 — 소비를 먼저 알고 산출을 나중에 알게 되는 원본에서
|
|
48
|
-
* 그 둘을 묶는 유일한 자리다.
|
|
20
|
+
* 마스터데이터를 `accepted` 에 섞지 않는 이유: 부르는 쪽이 그것을 저널에 적게 되고, 시각축이 없는 값이
|
|
21
|
+
* 「그때 일어난 일」로 남는다. 갈래를 타입으로 갈라 두면 그 실수를 할 수 없다.
|
|
49
22
|
*/
|
|
50
|
-
export interface
|
|
51
|
-
|
|
52
|
-
inputEPCList?: string[];
|
|
53
|
-
/** 클래스와 수량으로 소비된 것 — 로트 단위 소비가 이 자리다. */
|
|
54
|
-
inputQuantityList?: {
|
|
55
|
-
epcClass: string;
|
|
56
|
-
quantity?: number;
|
|
57
|
-
uom?: string;
|
|
58
|
-
}[];
|
|
59
|
-
outputEPCList?: string[];
|
|
60
|
-
outputQuantityList?: {
|
|
61
|
-
epcClass: string;
|
|
62
|
-
quantity?: number;
|
|
63
|
-
uom?: string;
|
|
64
|
-
}[];
|
|
65
|
-
/** 한 오더의 여러 단계를 잇는 식별자. */
|
|
66
|
-
transformationID?: string;
|
|
67
|
-
bizStep: string;
|
|
68
|
-
disposition?: string;
|
|
69
|
-
readPoint?: string;
|
|
70
|
-
bizLocation?: string;
|
|
23
|
+
export interface CanonicalIngestResult extends IngestResult {
|
|
24
|
+
masterData: MasterDataRecord[];
|
|
71
25
|
}
|
|
72
|
-
export interface CanonicalAggregationRecord {
|
|
73
|
-
parentID: string;
|
|
74
|
-
/** 개체로 담긴 자식. 수량으로만 담겼으면 없다(둘 중 하나는 있어야 한다). */
|
|
75
|
-
childEPCs?: string[];
|
|
76
|
-
/** 수량으로 담긴 자식 — `{ epcClass, quantity, uom? }`. 값의 옳고 그름은 커널 검증이 본다. */
|
|
77
|
-
childQuantityList?: {
|
|
78
|
-
epcClass: string;
|
|
79
|
-
quantity?: number;
|
|
80
|
-
uom?: string;
|
|
81
|
-
}[];
|
|
82
|
-
action: string;
|
|
83
|
-
bizStep: string;
|
|
84
|
-
disposition?: string;
|
|
85
|
-
readPoint?: string;
|
|
86
|
-
bizLocation?: string;
|
|
87
|
-
}
|
|
88
|
-
/** 정규 레코드[] → 검증된 CanonicalEnvelope[] (+ 거부분). 순수 함수. 단일→객체도 배열로 정규화. */
|
|
89
|
-
export declare function ingestCanonicalRecords(records: CanonicalRecord | CanonicalAggregationRecord | CanonicalTransformationRecord | EnergyRecord | EnergyEquipmentRecord | OperationalRecord | (CanonicalRecord | CanonicalAggregationRecord | CanonicalTransformationRecord | EnergyRecord | EnergyEquipmentRecord | OperationalRecord)[] | undefined | null, tenantId: string, defaultEventTime: string): IngestResult;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ingestCanonicalRecords = ingestCanonicalRecords;
|
|
4
|
-
const
|
|
4
|
+
const ops_contract_1 = require("@operato/ops-contract");
|
|
5
5
|
/*
|
|
6
6
|
* 정규 레코드 → 커널 검증 ACL → CanonicalEnvelope (P1 seam 코어).
|
|
7
7
|
* 순수(커널만 의존; shell·integration-base 무의존 → node:test 검증 가능).
|
|
@@ -9,6 +9,9 @@ const twin_kernel_1 = require("@operato/twin-kernel");
|
|
|
9
9
|
* 여기 도착하는 레코드는 이미 정규 필드다 — 어휘마다 자기 필드 이름이 계약이다:
|
|
10
10
|
* EPCIS 품목 { epc, action, bizStep, disposition?, readPoint?, bizLocation? }
|
|
11
11
|
* 에너지 계량 { meterId, kW?, kWh?, … } · 설비 에너지 { equipmentId, generatedKW?, soc?, … }
|
|
12
|
+
* 발전 적산 { equipmentId, kWh, kWhSince?, … }
|
|
13
|
+
* 사용 구간 { meterId, from, to, kWh, unitPrice?, basis?, … } · 청구서 { from, to, total?, … }
|
|
14
|
+
* 요금 기준 { from, to, billingDemandKW?, demandChargePerKW?, currency }
|
|
12
15
|
* 담김(적재) { parentID, childEPCs[] | childQuantityList[], action, bizStep, … }
|
|
13
16
|
* 운영 사실 { taskId | moverId | personId | assetId | orderId, status, … } // vocabulary-guard: allow 저널 와이어 필드
|
|
14
17
|
* 커널은 objectEvent 구성 + EPCIS 검증(위반=오염 차단) + 봉투 래핑만(방언 없음).
|
|
@@ -37,10 +40,25 @@ const TWIN_INGEST_RULES = [
|
|
|
37
40
|
* 재고 950건·59,785kg 이 어디에도 나타나지 않았고, 빈 화면이 「이상 없음」으로 읽혔다.
|
|
38
41
|
*
|
|
39
42
|
* ★ **표준이 `action: 'ADD'` 일 때만 허용한다**(또는 변환). 마스터데이터는 로트가 **생길 때**
|
|
40
|
-
* 말하는 사실이고, 주기 관측마다 실으면 커널이 거부한다 —
|
|
43
|
+
* 말하는 사실이고, 주기 관측마다 실으면 커널이 거부한다 — 알리지 않고 통과시키지 않는 것이 옳다
|
|
41
44
|
* (커넥터가 첫 목격에 `ADD`, 그 뒤로 `OBSERVE` 를 내야 한다).
|
|
42
45
|
*/
|
|
43
46
|
ilmd: '$.ilmd',
|
|
47
|
+
/*
|
|
48
|
+
* **정정 선언** — 「이 사건은 없던 일이 되었다」(커널 0.7.65 에서 이 자리가 열렸다).
|
|
49
|
+
*
|
|
50
|
+
* 세 값이 함께여야 뜻이 있어 묶음으로 온다. 커널이 선언 시각을 요구하고, 없으면 사건 시각으로
|
|
51
|
+
* 메우지 않고 이유와 함께 돌려준다 — 「언제 정정했나」와 「언제 일어났나」가 같아지면 둘을 다시
|
|
52
|
+
* 갈라낼 수 없다.
|
|
53
|
+
*
|
|
54
|
+
* 상태는 이것으로 흔들리지 않는다. 커널은 정정을 목록에 적고 재고를 그대로 둔다 — 무엇을 어떻게
|
|
55
|
+
* 되돌릴지는 도메인 판단이고, 참 재고는 그 뒤의 잔량 관측이 다시 말해 준다.
|
|
56
|
+
*/
|
|
57
|
+
errorDeclaration: {
|
|
58
|
+
declarationTime: '$.errorDeclaration.declarationTime',
|
|
59
|
+
reason: '$.errorDeclaration.reason',
|
|
60
|
+
correctiveEventIDs: '$.errorDeclaration.correctiveEventIDs'
|
|
61
|
+
},
|
|
44
62
|
readPoint: '$.readPoint',
|
|
45
63
|
bizLocation: '$.bizLocation'
|
|
46
64
|
}
|
|
@@ -57,6 +75,11 @@ const TWIN_INGEST_RULES = [
|
|
|
57
75
|
outputEPCList: '$.outputEPCList',
|
|
58
76
|
outputQuantityList: '$.outputQuantityList',
|
|
59
77
|
transformationID: '$.transformationID',
|
|
78
|
+
errorDeclaration: {
|
|
79
|
+
declarationTime: '$.errorDeclaration.declarationTime',
|
|
80
|
+
reason: '$.errorDeclaration.reason',
|
|
81
|
+
correctiveEventIDs: '$.errorDeclaration.correctiveEventIDs'
|
|
82
|
+
},
|
|
60
83
|
readPoint: '$.readPoint',
|
|
61
84
|
bizLocation: '$.bizLocation'
|
|
62
85
|
}
|
|
@@ -77,14 +100,56 @@ const TWIN_INGEST_RULES = [
|
|
|
77
100
|
childEPCs: '$.childEPCs',
|
|
78
101
|
/* 낱개 식별자 없이 **수량으로** 담긴 자식(「이 품번 40개」) — 입고·포장이 이 모양으로 온다. */
|
|
79
102
|
childQuantityList: '$.childQuantityList',
|
|
103
|
+
errorDeclaration: {
|
|
104
|
+
declarationTime: '$.errorDeclaration.declarationTime',
|
|
105
|
+
reason: '$.errorDeclaration.reason',
|
|
106
|
+
correctiveEventIDs: '$.errorDeclaration.correctiveEventIDs'
|
|
107
|
+
},
|
|
80
108
|
readPoint: '$.readPoint',
|
|
81
109
|
bizLocation: '$.bizLocation'
|
|
82
110
|
}
|
|
83
111
|
}
|
|
84
112
|
];
|
|
113
|
+
/*
|
|
114
|
+
* 정규 레코드 셋(`CanonicalRecord` · `CanonicalTransformationRecord` · `CanonicalAggregationRecord`)은
|
|
115
|
+
* **계약으로 옮겼다**(2026-08-30, `@operato/ops-contract` 0.2.0).
|
|
116
|
+
*
|
|
117
|
+
* 여기 있던 이유는 소비 방식 때문이었다 — EPCIS 는 커널의 범용 어댑터를 지나서 타입을 요구하지 않았다.
|
|
118
|
+
* 그런데 모양 자체는 EPCIS 2.0 의 필드 이름이고 호스트의 것이 아니다. 이제 MES 가 이 모양 그대로
|
|
119
|
+
* 보낸다.
|
|
120
|
+
*
|
|
121
|
+
* **매핑 룰(`TWIN_INGEST_RULES`)은 여기 남는다** — 이 모양을 EPCIS 사건으로 옮기는 정책이지 모양이 아니다.
|
|
122
|
+
*/
|
|
85
123
|
/** 정규 레코드[] → 검증된 CanonicalEnvelope[] (+ 거부분). 순수 함수. 단일→객체도 배열로 정규화. */
|
|
86
|
-
function ingestCanonicalRecords(records, tenantId, defaultEventTime
|
|
124
|
+
function ingestCanonicalRecords(records, tenantId, defaultEventTime,
|
|
125
|
+
/**
|
|
126
|
+
* **이 사실들이 어느 트윈의 것인가** — 마감된 구간 사실의 이름에 쓰인다(커널 §`SubjectBasis`).
|
|
127
|
+
*
|
|
128
|
+
* 커널은 도메인으로 서므로 자기가 어느 트윈인지 모른다. 그런데 설비 번호·계량 지점 번호는 트윈
|
|
129
|
+
* 안에서만 통하는 이름표라, 한 도메인에 현장이 둘이면 서로 다른 설비의 같은 날이 한 사실이 된다.
|
|
130
|
+
* 실측으로 그 일이 났다 — 두 발전소의 `002` 가 겹쳤다.
|
|
131
|
+
*
|
|
132
|
+
* 주지 않으면 이름표를 그대로 쓰고 `twin-local` 로 표시된다 — 겹칠 수 있다는 뜻이다.
|
|
133
|
+
*/
|
|
134
|
+
scope) {
|
|
87
135
|
const arr = Array.isArray(records) ? records : records ? [records] : [];
|
|
136
|
+
/*
|
|
137
|
+
* ── **다섯째 어휘는 사건이 아니다** (2026-08-28) ────────────────────────────
|
|
138
|
+
*
|
|
139
|
+
* 마스터데이터 — 변하지 않는 속성(유통기한·로트번호·자리의 성질). 표준은 이것을 사건이 아니라
|
|
140
|
+
* **어휘 요소의 속성**으로 담고, 커널에 그 자리가 없어서 지금까지 사건에 실려 왔다.
|
|
141
|
+
*
|
|
142
|
+
* 그 결과가 유입에서 이렇게 났다. 전량을 읽는 원본이 유통기한을 실으려고 **들어오지 않은 것을
|
|
143
|
+
* `ADD`** 라고 말했고, `ilmd` 가 사건 단위라 자리별로 묶을 수도 없어 낱개로 나갔다 — 재기동 한 번에
|
|
144
|
+
* 2,665건이다.
|
|
145
|
+
*
|
|
146
|
+
* 그래서 여기서 갈라 낸다. 이것은 봉투가 되지 않고 저널에도 적히지 않는다(시각축이 없는 값이다).
|
|
147
|
+
* 갈래 판정은 커널의 것을 부른다 — 다른 넷과 같은 규율이다.
|
|
148
|
+
*
|
|
149
|
+
* 설계: `operato-twin/design/plans/master-data.md`
|
|
150
|
+
*/
|
|
151
|
+
const masterCandidates = arr.filter(ops_contract_1.isMasterDataRecord);
|
|
152
|
+
const master = masterCandidates.length ? (0, ops_contract_1.ingestMasterData)(masterCandidates) : { accepted: [], rejected: [] };
|
|
88
153
|
/*
|
|
89
154
|
* **어휘가 넷이다** — 물류(EPCIS)·에너지 계량·설비 에너지·운영 사실. 예전에는 이 함수가 무조건
|
|
90
155
|
* `ObjectEvent` 를 만들었고, 그래서 계측을 이 길로 넣으면 `epc` 가 없어 거부되거나(그나마 나은 쪽)
|
|
@@ -96,20 +161,79 @@ function ingestCanonicalRecords(records, tenantId, defaultEventTime) {
|
|
|
96
161
|
* 소비처마다 답이 달라진다. 봉투는 같은 것을 쓰므로 아래 소비처(미러·저널·브로드캐스팅)는 이 갈림을 알
|
|
97
162
|
* 필요가 없다.
|
|
98
163
|
*/
|
|
99
|
-
|
|
164
|
+
/*
|
|
165
|
+
* 여섯째·일곱째 어휘 — **마감된 사용 구간**과 **청구서**. 커널 0.7.72 가 이 문들을 열었다.
|
|
166
|
+
*
|
|
167
|
+
* ── ★ 사용 구간을 계량보다 **먼저** 가른다 ─────────────────────────────────
|
|
168
|
+
* `isEnergyRecord` 는 `meterId` 가 있으면 참이므로 사용 구간에도 참이다. 순서를 정하지 않으면
|
|
169
|
+
* 시간별 사용량이 계량 표본으로 들어가고, 그 문은 `kWh` 를 **적산 레지스터**로 읽는다. 그러면
|
|
170
|
+
* 커널이 구간 전력량을 차분으로 구하는데 우리가 넣은 값이 이미 구간의 양이다 — 차분의 차분이 되어
|
|
171
|
+
* 값이 조용히 틀린다. 거부되지도 않는다.
|
|
172
|
+
*/
|
|
173
|
+
const usagePeriods = arr.filter(ops_contract_1.isEnergyUsagePeriodRecord);
|
|
174
|
+
const bills = arr.filter(ops_contract_1.isEnergyBillRecord);
|
|
175
|
+
/*
|
|
176
|
+
* 여덟째 어휘 — **그 주기에 적용되는 요금 기준**. 커널 0.7.76 이 이 문을 열었다.
|
|
177
|
+
*
|
|
178
|
+
* ★ 청구서와 겹친다. 청구서가 `billingDemandKW` 를 실을 수 있고, 그러면 두 판정이 다 참이다.
|
|
179
|
+
* 그때 요금 기준 문으로 보내면 「금액은 이 문이 받지 않는다」로 거부된다 — 정산이 통째로
|
|
180
|
+
* 사라진다. 그래서 청구서인 것을 뺀다. 커널에서 배타로 만들어 달라고 올렸다.
|
|
181
|
+
*/
|
|
182
|
+
const tariffBases = arr.filter(r => (0, ops_contract_1.isEnergyTariffBasisRecord)(r) && !(0, ops_contract_1.isEnergyBillRecord)(r));
|
|
183
|
+
/*
|
|
184
|
+
* 아홉째 어휘 — **발전 단가**. 낸 것에 매겨지는 1kWh 당 값이고 날마다 바뀐다(커널 0.7.79).
|
|
185
|
+
*
|
|
186
|
+
* 다른 문과 겹치지 않는다: 계량 지점이나 설비 id 가 있으면 이 문이 아니고(커널이 배타로 막는다),
|
|
187
|
+
* 요금적용전력·기본요금 단가가 없으므로 요금 기준도 아니다.
|
|
188
|
+
*/
|
|
189
|
+
const generationPrices = arr.filter(ops_contract_1.isEnergyGenerationPriceRecord);
|
|
190
|
+
/* 마감된 발전 기간 — 지난 기록 채우기가 쓴다. 적산의 문과 배타다(구간이 있으면 이쪽). */
|
|
191
|
+
const generationPeriods = arr.filter(ops_contract_1.isEnergyGenerationPeriodRecord);
|
|
192
|
+
const energy = arr.filter(r => (0, ops_contract_1.isEnergyRecord)(r) && !(0, ops_contract_1.isEnergyUsagePeriodRecord)(r));
|
|
100
193
|
/* 세 번째 어휘 — 설비가 낸 자기 에너지 상태(발전·저장·감축 여지·개폐 위치). 계량과 갈라 두는
|
|
101
194
|
이유는 커널에 적혀 있다: 계량은 구간에 누적되고, 이것들은 그 설비의 지금이다. */
|
|
102
|
-
|
|
195
|
+
/*
|
|
196
|
+
* 다섯 번째 어휘 — **발전 적산**(설비가 지금까지 만든 양). 커널 0.7.69 가 이 문을 열었다.
|
|
197
|
+
*
|
|
198
|
+
* ── ★ 설비 상태보다 **먼저** 가른다 ──────────────────────────────────────────
|
|
199
|
+
* 두 판정이 겹친다. `isEnergyEquipmentRecord` 는 `equipmentId` 가 있고 물류·계량 어휘가 아니면
|
|
200
|
+
* 참이므로 발전 적산도 함께 참이다. 그래서 순서가 갈림을 정한다.
|
|
201
|
+
*
|
|
202
|
+
* 순서를 잘못 두면 조용히 사라지는 것이 아니라 **엉뚱한 이유로 거부된다**: 설비 상태 문은 적산을
|
|
203
|
+
* 값으로 세지 않아 「바꿀 상태가 하나도 없다」로 돌려보낸다. 커넥터는 보냈다고 믿고, 화면에는
|
|
204
|
+
* 발전량이 없다.
|
|
205
|
+
*/
|
|
206
|
+
const energyGeneration = arr.filter(ops_contract_1.isEnergyGenerationRecord);
|
|
207
|
+
const energyEquipment = arr.filter(r => (0, ops_contract_1.isEnergyEquipmentRecord)(r) && !(0, ops_contract_1.isEnergyGenerationRecord)(r));
|
|
103
208
|
/*
|
|
104
209
|
* 네 번째 어휘 — **운영 사실**(작업·설비·사람·자산·오더·품질). 관측 리듀서는 이것을 오래전부터
|
|
105
|
-
*
|
|
210
|
+
* 계산했는데 **들어올 문이 없었다**: 원본이 「이 작업이 끝났다」를 말할 길이 없어 시뮬 커널만 그것을
|
|
106
211
|
* 아는 상태가 남았다(같은 화면이 두 구동에서 다른 것을 말한다).
|
|
107
212
|
*/
|
|
108
|
-
const operational = arr.filter(
|
|
109
|
-
|
|
213
|
+
const operational = arr.filter(ops_contract_1.isOperationalRecord);
|
|
214
|
+
/*
|
|
215
|
+
* ── 이 목록은 **어휘를 더할 때마다 함께 늘어야 한다** (2026-08-30) ─────────
|
|
216
|
+
*
|
|
217
|
+
* EPCIS 갈래는 「나머지 전부」다. 새 어휘를 빼 주지 않으면 그 레코드가 제 문으로 가면서
|
|
218
|
+
* **EPCIS 문으로도 들어가** 거부된다. 받아들여지기도 하고 거부되기도 하는 상태가 되어,
|
|
219
|
+
* 유입 장부의 거부 수가 늘고 사람이 그것을 진짜 결함으로 읽는다.
|
|
220
|
+
*
|
|
221
|
+
* 실제로 발전 단가를 더할 때 그렇게 됐다. 목록을 손으로 지키는 대신 시험이 지킨다
|
|
222
|
+
* (§`canonical-ingest-vocabularies` — 어휘마다 한 문으로만 가는지).
|
|
223
|
+
*/
|
|
224
|
+
const epcis = arr.filter(r => !(0, ops_contract_1.isEnergyRecord)(r) &&
|
|
225
|
+
!(0, ops_contract_1.isEnergyEquipmentRecord)(r) &&
|
|
226
|
+
!(0, ops_contract_1.isEnergyGenerationRecord)(r) &&
|
|
227
|
+
!(0, ops_contract_1.isEnergyUsagePeriodRecord)(r) &&
|
|
228
|
+
!(0, ops_contract_1.isEnergyBillRecord)(r) &&
|
|
229
|
+
!(0, ops_contract_1.isEnergyTariffBasisRecord)(r) &&
|
|
230
|
+
!(0, ops_contract_1.isEnergyGenerationPriceRecord)(r) &&
|
|
231
|
+
!(0, ops_contract_1.isEnergyGenerationPeriodRecord)(r) &&
|
|
232
|
+
!(0, ops_contract_1.isOperationalRecord)(r) &&
|
|
233
|
+
!(0, ops_contract_1.isMasterDataRecord)(r));
|
|
110
234
|
/* 품목 어휘 안에서도 갈림이 있다(개체 관측 / 담김) — 그 판정도 커널의 것을 부른다. */
|
|
111
235
|
const epcisResult = epcis.length
|
|
112
|
-
? (0,
|
|
236
|
+
? (0, ops_contract_1.ingest)(epcis.map(r => ({
|
|
113
237
|
...r,
|
|
114
238
|
/*
|
|
115
239
|
* ── **시각의 이름을 둘 흡수한다** (2026-08-24 실측) ────────────────────
|
|
@@ -131,9 +255,9 @@ function ingestCanonicalRecords(records, tenantId, defaultEventTime) {
|
|
|
131
255
|
? { eventTime: r.eventTime ?? r.at }
|
|
132
256
|
: {}),
|
|
133
257
|
/* 판정은 커널이 한 곳에서 한다 — 여기서 다시 짐작하면 소비처마다 답이 달라진다. */
|
|
134
|
-
sourceType: (0,
|
|
258
|
+
sourceType: (0, ops_contract_1.isTransformationRecord)(r)
|
|
135
259
|
? 'twin-transformation'
|
|
136
|
-
: (0,
|
|
260
|
+
: (0, ops_contract_1.isAggregationRecord)(r)
|
|
137
261
|
? 'twin-aggregation'
|
|
138
262
|
: 'twin'
|
|
139
263
|
})), TWIN_INGEST_RULES,
|
|
@@ -141,29 +265,70 @@ function ingestCanonicalRecords(records, tenantId, defaultEventTime) {
|
|
|
141
265
|
* **레코드가 시각을 말하면 그것을 쓴다** (2026-08-23).
|
|
142
266
|
*
|
|
143
267
|
* `eventTimePath` 를 주지 않던 동안 이 경로는 **언제나 폴링 시각**을 썼다(`defaultEventTime`).
|
|
144
|
-
* 그래서 커넥터가 이미 싣고 있던 `eventTime`(변환 레코드의 `finishedAt` 등)이
|
|
268
|
+
* 그래서 커넥터가 이미 싣고 있던 `eventTime`(변환 레코드의 `finishedAt` 등)이 **알리지 않고
|
|
145
269
|
* 무시됐다** — 커넥터를 붙인 쪽은 그것이 먹는다고 믿고 있었고, 어디에도 오류가 나지 않았다.
|
|
146
270
|
*
|
|
147
271
|
* 무엇이 걸렸나: 계보(변환)의 시각이다. 4월에 만든 로트가 8월에 만들어진 것으로 저널에 남았다.
|
|
148
272
|
* 그리고 실측 소요를 재는 폴드가 봉투 시각을 쓰므로(§`kpi-fold`: `workMs = 완료 − 첫 착수`),
|
|
149
273
|
* 폴링 간격을 작업시간으로 배울 수 있었다 — 못 배우는 것보다 나쁘다.
|
|
150
274
|
*
|
|
151
|
-
* 레코드에 `eventTime` 이 없으면 커널이
|
|
275
|
+
* 레코드에 `eventTime` 이 없으면 커널이 알리지 않고 기본값으로 떨어진다(§`resolve` — 없는 값은
|
|
152
276
|
* 오류가 아니다). 그래서 이 한 줄이 기존 경로를 막지 않는다: 시각을 말하는 레코드만 사실이 된다.
|
|
153
277
|
*/
|
|
154
278
|
{ tenantId, defaultEventTime, eventTimePath: 'eventTime' })
|
|
155
279
|
: { accepted: [], rejected: [] };
|
|
156
|
-
const energyResult = energy.length ? (0,
|
|
280
|
+
const energyResult = energy.length ? (0, ops_contract_1.ingestEnergyRecords)(energy, { tenantId, defaultEventTime, ...scope }) : { accepted: [], rejected: [] };
|
|
157
281
|
const equipmentResult = energyEquipment.length
|
|
158
|
-
? (0,
|
|
282
|
+
? (0, ops_contract_1.ingestEnergyEquipmentRecords)(energyEquipment, { tenantId, defaultEventTime, ...scope })
|
|
283
|
+
: { accepted: [], rejected: [] };
|
|
284
|
+
const usageResult = usagePeriods.length
|
|
285
|
+
? (0, ops_contract_1.ingestEnergyUsagePeriodRecords)(usagePeriods, { tenantId, defaultEventTime, ...scope })
|
|
286
|
+
: { accepted: [], rejected: [] };
|
|
287
|
+
const billResult = bills.length ? (0, ops_contract_1.ingestEnergyBillRecords)(bills, { tenantId, defaultEventTime, ...scope }) : { accepted: [], rejected: [] };
|
|
288
|
+
const tariffBasisResult = tariffBases.length
|
|
289
|
+
? (0, ops_contract_1.ingestEnergyTariffBasisRecords)(tariffBases, { tenantId, defaultEventTime, ...scope })
|
|
290
|
+
: { accepted: [], rejected: [] };
|
|
291
|
+
const generationPeriodResult = generationPeriods.length
|
|
292
|
+
? (0, ops_contract_1.ingestEnergyGenerationPeriodRecords)(generationPeriods, { tenantId, defaultEventTime, ...scope })
|
|
293
|
+
: { accepted: [], rejected: [] };
|
|
294
|
+
const generationPriceResult = generationPrices.length
|
|
295
|
+
? (0, ops_contract_1.ingestEnergyGenerationPriceRecords)(generationPrices, { tenantId, defaultEventTime, ...scope })
|
|
296
|
+
: { accepted: [], rejected: [] };
|
|
297
|
+
const generationResult = energyGeneration.length
|
|
298
|
+
? (0, ops_contract_1.ingestEnergyGenerationRecords)(energyGeneration, { tenantId, defaultEventTime, ...scope })
|
|
159
299
|
: { accepted: [], rejected: [] };
|
|
160
300
|
const operationalResult = operational.length
|
|
161
|
-
? (0,
|
|
301
|
+
? (0, ops_contract_1.ingestOperationalRecords)(operational, { tenantId, defaultEventTime, ...scope })
|
|
162
302
|
: { accepted: [], rejected: [] };
|
|
163
303
|
/* 거부분을 합쳐 돌려준다 — 어느 어휘에서 거부됐는지는 이유 문구가 말한다. */
|
|
164
304
|
return {
|
|
165
|
-
accepted: [
|
|
166
|
-
|
|
305
|
+
accepted: [
|
|
306
|
+
...epcisResult.accepted,
|
|
307
|
+
...energyResult.accepted,
|
|
308
|
+
...equipmentResult.accepted,
|
|
309
|
+
...generationResult.accepted,
|
|
310
|
+
...usageResult.accepted,
|
|
311
|
+
...generationPriceResult.accepted,
|
|
312
|
+
...generationPeriodResult.accepted,
|
|
313
|
+
...billResult.accepted,
|
|
314
|
+
...tariffBasisResult.accepted,
|
|
315
|
+
...operationalResult.accepted
|
|
316
|
+
],
|
|
317
|
+
rejected: [
|
|
318
|
+
...epcisResult.rejected,
|
|
319
|
+
...energyResult.rejected,
|
|
320
|
+
...equipmentResult.rejected,
|
|
321
|
+
...generationResult.rejected,
|
|
322
|
+
...usageResult.rejected,
|
|
323
|
+
...billResult.rejected,
|
|
324
|
+
...tariffBasisResult.rejected,
|
|
325
|
+
...generationPriceResult.rejected,
|
|
326
|
+
...generationPeriodResult.rejected,
|
|
327
|
+
...operationalResult.rejected,
|
|
328
|
+
...master.rejected
|
|
329
|
+
],
|
|
330
|
+
/* 사건이 아닌 것은 따로 낸다 — 부르는 쪽이 상태 세우는 문으로 보낸다(저널로 가지 않게). */
|
|
331
|
+
masterData: master.accepted
|
|
167
332
|
};
|
|
168
333
|
}
|
|
169
334
|
//# sourceMappingURL=canonical-ingest.js.map
|