@things-factory/headless-twin 10.1.277 → 10.1.279
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/package.json +21 -7
- package/dist-server/engine/attention-digest.js.map +0 -1
- package/dist-server/engine/canonical-ingest.js.map +0 -1
- package/dist-server/engine/checkpoint-fold.js.map +0 -1
- package/dist-server/engine/command-routing.js.map +0 -1
- package/dist-server/engine/declared-stimulus.js.map +0 -1
- package/dist-server/engine/energy-topology.js.map +0 -1
- package/dist-server/engine/event-time.js.map +0 -1
- package/dist-server/engine/index.js.map +0 -1
- package/dist-server/engine/ingest-dedupe.js.map +0 -1
- package/dist-server/engine/ingest-health.js.map +0 -1
- package/dist-server/engine/integration-coverage.js.map +0 -1
- package/dist-server/engine/integration-probes.js.map +0 -1
- package/dist-server/engine/integration-runner.js.map +0 -1
- package/dist-server/engine/integration-target-profile.js.map +0 -1
- package/dist-server/engine/kpi-baseline.js.map +0 -1
- package/dist-server/engine/kpi-fold.js.map +0 -1
- package/dist-server/engine/kpi-query.js.map +0 -1
- package/dist-server/engine/kpi-target.js.map +0 -1
- package/dist-server/engine/live-attentions.js.map +0 -1
- package/dist-server/engine/live-feed-registry.js.map +0 -1
- package/dist-server/engine/load-meter.js.map +0 -1
- package/dist-server/engine/local-declarations.js.map +0 -1
- package/dist-server/engine/log.js.map +0 -1
- package/dist-server/engine/loop-lag.js.map +0 -1
- package/dist-server/engine/measured-estimator.js.map +0 -1
- package/dist-server/engine/measured-yield.js.map +0 -1
- package/dist-server/engine/model-basis.js.map +0 -1
- package/dist-server/engine/model-gap.js.map +0 -1
- package/dist-server/engine/model-refusal.js.map +0 -1
- package/dist-server/engine/model-vocabulary.js.map +0 -1
- package/dist-server/engine/oee-accumulator.js.map +0 -1
- package/dist-server/engine/operation-basis.js.map +0 -1
- package/dist-server/engine/producer-guard.js.map +0 -1
- package/dist-server/engine/property-effects.js.map +0 -1
- package/dist-server/engine/read-time.js.map +0 -1
- package/dist-server/engine/restart-policy.js.map +0 -1
- package/dist-server/engine/runtime-key.js.map +0 -1
- package/dist-server/engine/spec-coverage.js.map +0 -1
- package/dist-server/engine/stage-path.js.map +0 -1
- package/dist-server/engine/state-axes.js.map +0 -1
- package/dist-server/engine/structure-diff.js.map +0 -1
- package/dist-server/engine/travel-estimator.js.map +0 -1
- package/dist-server/engine/twin-engine.js.map +0 -1
- package/dist-server/engine/twin-state-channel.js.map +0 -1
- package/dist-server/engine/warm-start.js.map +0 -1
- package/dist-server/index.js.map +0 -1
- package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js.map +0 -1
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +0 -1
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +0 -1
- package/dist-server/migrations/1786300000000-IndexEventTypeByTime.js.map +0 -1
- package/dist-server/migrations/1786400000000-IndexEventCreatedAt.js.map +0 -1
- package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.js.map +0 -1
- package/dist-server/migrations/1786600000000-RenameOperatoMesAdapterType.js.map +0 -1
- package/dist-server/migrations/1786700000000-AddDispatchRetryColumns.js.map +0 -1
- package/dist-server/migrations/1786800000000-CreateTwinReferenceReconciliations.js.map +0 -1
- package/dist-server/migrations/index.js.map +0 -1
- package/dist-server/routes.js.map +0 -1
- package/dist-server/service/actuation/actuation-advisor.js.map +0 -1
- package/dist-server/service/actuation/actuation-outcome.js.map +0 -1
- package/dist-server/service/actuation/actuation-rule-resolver.js.map +0 -1
- package/dist-server/service/actuation/actuation-rule.js.map +0 -1
- package/dist-server/service/actuation/approval-gateway.js.map +0 -1
- package/dist-server/service/actuation/catch-up-effects.js.map +0 -1
- package/dist-server/service/actuation/command-dispatcher.js.map +0 -1
- package/dist-server/service/actuation/command-store.js.map +0 -1
- package/dist-server/service/actuation/dispatch-after-approval.js.map +0 -1
- package/dist-server/service/actuation/effect-match.js.map +0 -1
- package/dist-server/service/actuation/index.js.map +0 -1
- package/dist-server/service/actuation/retry-plan.js.map +0 -1
- package/dist-server/service/actuation/rule-evaluate.js.map +0 -1
- package/dist-server/service/actuation/rule-loop.js.map +0 -1
- package/dist-server/service/actuation/rule-runner.js.map +0 -1
- package/dist-server/service/actuation/rule-wiring.js.map +0 -1
- package/dist-server/service/actuation/settle-effects.js.map +0 -1
- package/dist-server/service/actuation/sweep-dispatch.js.map +0 -1
- package/dist-server/service/actuation/twin-command-resolver.js.map +0 -1
- package/dist-server/service/actuation/twin-command.js.map +0 -1
- package/dist-server/service/actuation/twin-now.js.map +0 -1
- package/dist-server/service/index.js.map +0 -1
- package/dist-server/service/reference/actuation-routing.js.map +0 -1
- package/dist-server/service/reference/actuation-target.js.map +0 -1
- package/dist-server/service/reference/actuation-verification.js.map +0 -1
- package/dist-server/service/reference/attention-lane.js.map +0 -1
- package/dist-server/service/reference/connection-portability-resolver.js.map +0 -1
- package/dist-server/service/reference/connection-portability.js.map +0 -1
- package/dist-server/service/reference/control-routing.js.map +0 -1
- package/dist-server/service/reference/discovery-result.js.map +0 -1
- package/dist-server/service/reference/fill-cadence.js.map +0 -1
- package/dist-server/service/reference/fill-dedupe.js.map +0 -1
- package/dist-server/service/reference/fill-loop.js.map +0 -1
- package/dist-server/service/reference/fill-span.js.map +0 -1
- package/dist-server/service/reference/hook-contract.js.map +0 -1
- package/dist-server/service/reference/hook-rejected.js.map +0 -1
- package/dist-server/service/reference/hook-store.js.map +0 -1
- package/dist-server/service/reference/index.js.map +0 -1
- package/dist-server/service/reference/ingest-space.js.map +0 -1
- package/dist-server/service/reference/knob-defaults.js.map +0 -1
- package/dist-server/service/reference/live-cadence.js.map +0 -1
- package/dist-server/service/reference/live-feed-lease.js.map +0 -1
- package/dist-server/service/reference/live-ingest.js.map +0 -1
- package/dist-server/service/reference/reference-adapter.js.map +0 -1
- package/dist-server/service/reference/reference-assessment.js.map +0 -1
- package/dist-server/service/reference/reference-fill-run.js.map +0 -1
- package/dist-server/service/reference/reference-fill.js.map +0 -1
- package/dist-server/service/reference/reference-hook.js.map +0 -1
- package/dist-server/service/reference/reference-link-groups.js.map +0 -1
- package/dist-server/service/reference/reference-links.js.map +0 -1
- package/dist-server/service/reference/reference-live.js.map +0 -1
- package/dist-server/service/reference/reference-master.js.map +0 -1
- package/dist-server/service/reference/reference-probe.js.map +0 -1
- package/dist-server/service/reference/reference-progress-channel.js.map +0 -1
- package/dist-server/service/reference/reference-progress-subscription.js.map +0 -1
- package/dist-server/service/reference/reference-progress.js.map +0 -1
- package/dist-server/service/reference/reference-reconciliation-query.js.map +0 -1
- package/dist-server/service/reference/reference-reconciliation-writer.js.map +0 -1
- package/dist-server/service/reference/reference-reconciliation.js.map +0 -1
- package/dist-server/service/reference/reference-registry.js.map +0 -1
- package/dist-server/service/reference/reference-resolver.js.map +0 -1
- package/dist-server/service/reference/template-registry.js.map +0 -1
- package/dist-server/service/reference/twin-reference-reconciliation.js.map +0 -1
- package/dist-server/service/reference/twin-reference.js.map +0 -1
- package/dist-server/service/twin-attention/index.js.map +0 -1
- package/dist-server/service/twin-attention/twin-attention-query.js.map +0 -1
- package/dist-server/service/twin-audit/command-audit.js.map +0 -1
- package/dist-server/service/twin-audit/index.js.map +0 -1
- package/dist-server/service/twin-audit/twin-audit-event.js.map +0 -1
- package/dist-server/service/twin-audit/twin-audit-query.js.map +0 -1
- package/dist-server/service/twin-backfill/backfill-period-facts.js.map +0 -1
- package/dist-server/service/twin-backfill/backfill-shape.js.map +0 -1
- package/dist-server/service/twin-backfill/index.js.map +0 -1
- package/dist-server/service/twin-backfill/twin-backfill-resolver.js.map +0 -1
- package/dist-server/service/twin-control/index.js.map +0 -1
- package/dist-server/service/twin-control/twin-control-mutation.js.map +0 -1
- package/dist-server/service/twin-event/index.js.map +0 -1
- package/dist-server/service/twin-event/journal-count.js.map +0 -1
- package/dist-server/service/twin-event/twin-event-keys.js.map +0 -1
- package/dist-server/service/twin-event/twin-event-type.js.map +0 -1
- package/dist-server/service/twin-event/twin-event.js.map +0 -1
- package/dist-server/service/twin-forecast/forecast-metrics.js.map +0 -1
- package/dist-server/service/twin-forecast/forecast-tuning.js.map +0 -1
- package/dist-server/service/twin-forecast/gap-analytics.js.map +0 -1
- package/dist-server/service/twin-forecast/index.js.map +0 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js.map +0 -1
- package/dist-server/service/twin-ingest-window/index.js.map +0 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +0 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +0 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window.js.map +0 -1
- package/dist-server/service/twin-instance/index.js.map +0 -1
- package/dist-server/service/twin-instance/twin-instance.js.map +0 -1
- package/dist-server/service/twin-journal/event-type-split-shape.js.map +0 -1
- package/dist-server/service/twin-journal/event-type-split.js.map +0 -1
- package/dist-server/service/twin-journal/index.js.map +0 -1
- package/dist-server/service/twin-journal/journal-order.js.map +0 -1
- package/dist-server/service/twin-journal/twin-journal-query.js.map +0 -1
- package/dist-server/service/twin-lifecycle/domain-catalog.js.map +0 -1
- package/dist-server/service/twin-lifecycle/index.js.map +0 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +0 -1
- package/dist-server/service/twin-metrics/index.js.map +0 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.js.map +0 -1
- package/dist-server/service/twin-model/axis-journal-evidence.js.map +0 -1
- package/dist-server/service/twin-model/choose-recipe.js.map +0 -1
- package/dist-server/service/twin-model/epcis-coverage.js.map +0 -1
- package/dist-server/service/twin-model/external-resolver.js.map +0 -1
- package/dist-server/service/twin-model/iec61850-coverage.js.map +0 -1
- package/dist-server/service/twin-model/index.js.map +0 -1
- package/dist-server/service/twin-model/isa95-coverage.js.map +0 -1
- package/dist-server/service/twin-model/item-ref.js.map +0 -1
- package/dist-server/service/twin-model/name-index.js.map +0 -1
- package/dist-server/service/twin-model/project-structure.js.map +0 -1
- package/dist-server/service/twin-model/standard-coverage.js.map +0 -1
- package/dist-server/service/twin-model/status-tally.js.map +0 -1
- package/dist-server/service/twin-model/twin-equipment.js.map +0 -1
- package/dist-server/service/twin-model/twin-lineage-query.js.map +0 -1
- package/dist-server/service/twin-model/twin-location.js.map +0 -1
- package/dist-server/service/twin-model/twin-model-item-query.js.map +0 -1
- package/dist-server/service/twin-model/twin-model-mutation.js.map +0 -1
- package/dist-server/service/twin-model/twin-model-query.js.map +0 -1
- package/dist-server/service/twin-model/twin-model-tree-query.js.map +0 -1
- package/dist-server/service/twin-model/twin-operation.js.map +0 -1
- package/dist-server/service/twin-readiness/index.js.map +0 -1
- package/dist-server/service/twin-readiness/twin-readiness-query.js.map +0 -1
- package/dist-server/service/twin-space/area-resolver.js.map +0 -1
- package/dist-server/service/twin-space/index.js.map +0 -1
- package/dist-server/service/twin-space/move-space.js.map +0 -1
- package/dist-server/service/twin-space/representation-role.js.map +0 -1
- package/dist-server/service/twin-space/space-integrity.js.map +0 -1
- package/dist-server/service/twin-space/twin-area.js.map +0 -1
- package/dist-server/service/twin-space/twin-space-area.js.map +0 -1
- package/dist-server/service/twin-space/twin-space-representation.js.map +0 -1
- package/dist-server/service/twin-space/twin-space-resolver.js.map +0 -1
- package/dist-server/service/twin-space/twin-space.js.map +0 -1
- package/dist-server/service/twin-state/index.js.map +0 -1
- package/dist-server/service/twin-state/twin-state-subscription.js.map +0 -1
- package/dist-server/service/twin-structure/index.js.map +0 -1
- package/dist-server/service/twin-structure/twin-structure.js.map +0 -1
- package/dist-server/service/twin-subject/event-subjects.js.map +0 -1
- package/dist-server/service/twin-subject/index.js.map +0 -1
- package/dist-server/service/twin-subject/item-resolver.js.map +0 -1
- package/dist-server/service/twin-subject/subject-query-shape.js.map +0 -1
- package/dist-server/service/twin-subject/twin-subject-backfill.js.map +0 -1
- package/dist-server/service/twin-subject/twin-subject-event.js.map +0 -1
- package/dist-server/service/twin-subject/twin-subject-fast-path.js.map +0 -1
- package/dist-server/service/twin-subject/twin-subject-query.js.map +0 -1
- package/dist-server/service/twin-subject/twin-subject-writer.js.map +0 -1
- package/dist-server/service/twin-target/index.js.map +0 -1
- package/dist-server/service/twin-target/twin-target-resolver.js.map +0 -1
- package/dist-server/service/twin-target/twin-target.js.map +0 -1
- package/dist-shared/axis-read.js.map +0 -1
- package/dist-shared/entity-delta.js.map +0 -1
- package/dist-shared/kpi-broadcast.js.map +0 -1
- package/dist-shared/touched-items.js.map +0 -1
- package/dist-shared/twin-level.js.map +0 -1
- package/server/engine/attention-digest.ts +0 -102
- package/server/engine/canonical-ingest.ts +0 -511
- package/server/engine/checkpoint-fold.ts +0 -12
- package/server/engine/command-routing.ts +0 -67
- package/server/engine/declared-stimulus.ts +0 -66
- package/server/engine/energy-topology.ts +0 -189
- package/server/engine/event-time.ts +0 -96
- package/server/engine/index.ts +0 -51
- package/server/engine/ingest-dedupe.ts +0 -24
- package/server/engine/ingest-health.ts +0 -24
- package/server/engine/integration-coverage.ts +0 -147
- package/server/engine/integration-probes.ts +0 -144
- package/server/engine/integration-runner.ts +0 -95
- package/server/engine/integration-target-profile.ts +0 -103
- package/server/engine/kpi-baseline.ts +0 -202
- package/server/engine/kpi-fold.ts +0 -1516
- package/server/engine/kpi-query.ts +0 -1210
- package/server/engine/kpi-target.ts +0 -248
- package/server/engine/live-attentions.ts +0 -30
- package/server/engine/live-feed-registry.ts +0 -59
- package/server/engine/load-meter.ts +0 -393
- package/server/engine/local-declarations.ts +0 -779
- package/server/engine/log.ts +0 -72
- package/server/engine/loop-lag.ts +0 -120
- package/server/engine/measured-estimator.ts +0 -91
- package/server/engine/measured-yield.ts +0 -89
- package/server/engine/model-basis.ts +0 -162
- package/server/engine/model-gap.ts +0 -168
- package/server/engine/model-refusal.ts +0 -31
- package/server/engine/model-vocabulary.ts +0 -82
- package/server/engine/oee-accumulator.ts +0 -195
- package/server/engine/operation-basis.ts +0 -131
- package/server/engine/producer-guard.ts +0 -64
- package/server/engine/property-effects.ts +0 -216
- package/server/engine/read-time.ts +0 -77
- package/server/engine/restart-policy.ts +0 -55
- package/server/engine/runtime-key.ts +0 -58
- package/server/engine/spec-coverage.ts +0 -105
- package/server/engine/stage-path.ts +0 -172
- package/server/engine/state-axes.ts +0 -60
- package/server/engine/structure-diff.ts +0 -88
- package/server/engine/travel-estimator.ts +0 -138
- package/server/engine/twin-engine.ts +0 -4979
- package/server/engine/twin-state-channel.ts +0 -39
- package/server/engine/warm-start.ts +0 -265
- package/server/index.ts +0 -90
- package/server/migrations/1786000000000-RenameTwinInstanceBoardToModel.ts +0 -43
- package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +0 -54
- package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +0 -53
- package/server/migrations/1786300000000-IndexEventTypeByTime.ts +0 -48
- package/server/migrations/1786400000000-IndexEventCreatedAt.ts +0 -38
- package/server/migrations/1786500000000-CreateTwinSubjectEvents.ts +0 -93
- package/server/migrations/1786600000000-RenameOperatoMesAdapterType.ts +0 -66
- package/server/migrations/1786700000000-AddDispatchRetryColumns.ts +0 -82
- package/server/migrations/1786800000000-CreateTwinReferenceReconciliations.ts +0 -39
- package/server/migrations/index.ts +0 -25
- package/server/routes.ts +0 -75
- package/server/service/actuation/actuation-advisor.ts +0 -131
- package/server/service/actuation/actuation-outcome.ts +0 -97
- package/server/service/actuation/actuation-rule-resolver.ts +0 -147
- package/server/service/actuation/actuation-rule.ts +0 -139
- package/server/service/actuation/approval-gateway.ts +0 -44
- package/server/service/actuation/catch-up-effects.ts +0 -152
- package/server/service/actuation/command-dispatcher.ts +0 -474
- package/server/service/actuation/command-store.ts +0 -236
- package/server/service/actuation/dispatch-after-approval.ts +0 -71
- package/server/service/actuation/effect-match.ts +0 -124
- package/server/service/actuation/index.ts +0 -27
- package/server/service/actuation/retry-plan.ts +0 -145
- package/server/service/actuation/rule-evaluate.ts +0 -352
- package/server/service/actuation/rule-loop.ts +0 -160
- package/server/service/actuation/rule-runner.ts +0 -216
- package/server/service/actuation/rule-wiring.ts +0 -84
- package/server/service/actuation/settle-effects.ts +0 -115
- package/server/service/actuation/sweep-dispatch.ts +0 -179
- package/server/service/actuation/twin-command-resolver.ts +0 -387
- package/server/service/actuation/twin-command.ts +0 -232
- package/server/service/actuation/twin-now.ts +0 -97
- package/server/service/index.ts +0 -100
- package/server/service/reference/actuation-routing.ts +0 -192
- package/server/service/reference/actuation-target.ts +0 -163
- package/server/service/reference/actuation-verification.ts +0 -85
- package/server/service/reference/attention-lane.ts +0 -21
- package/server/service/reference/connection-portability-resolver.ts +0 -171
- package/server/service/reference/connection-portability.ts +0 -329
- package/server/service/reference/control-routing.ts +0 -62
- package/server/service/reference/discovery-result.ts +0 -95
- package/server/service/reference/fill-cadence.ts +0 -29
- package/server/service/reference/fill-dedupe.ts +0 -66
- package/server/service/reference/fill-loop.ts +0 -153
- package/server/service/reference/fill-span.ts +0 -31
- package/server/service/reference/hook-contract.ts +0 -364
- package/server/service/reference/hook-rejected.ts +0 -53
- package/server/service/reference/hook-store.ts +0 -28
- package/server/service/reference/index.ts +0 -18
- package/server/service/reference/ingest-space.ts +0 -104
- package/server/service/reference/knob-defaults.ts +0 -59
- package/server/service/reference/live-cadence.ts +0 -129
- package/server/service/reference/live-feed-lease.ts +0 -56
- package/server/service/reference/live-ingest.ts +0 -94
- package/server/service/reference/reference-adapter.ts +0 -985
- package/server/service/reference/reference-assessment.ts +0 -250
- package/server/service/reference/reference-fill-run.ts +0 -179
- package/server/service/reference/reference-fill.ts +0 -223
- package/server/service/reference/reference-hook.ts +0 -479
- package/server/service/reference/reference-link-groups.ts +0 -21
- package/server/service/reference/reference-links.ts +0 -77
- package/server/service/reference/reference-live.ts +0 -420
- package/server/service/reference/reference-master.ts +0 -999
- package/server/service/reference/reference-probe.ts +0 -264
- package/server/service/reference/reference-progress-channel.ts +0 -26
- package/server/service/reference/reference-progress-subscription.ts +0 -78
- package/server/service/reference/reference-progress.ts +0 -95
- package/server/service/reference/reference-reconciliation-query.ts +0 -28
- package/server/service/reference/reference-reconciliation-writer.ts +0 -38
- package/server/service/reference/reference-reconciliation.ts +0 -55
- package/server/service/reference/reference-registry.ts +0 -17
- package/server/service/reference/reference-resolver.ts +0 -969
- package/server/service/reference/template-registry.ts +0 -85
- package/server/service/reference/twin-reference-reconciliation.ts +0 -27
- package/server/service/reference/twin-reference.ts +0 -190
- package/server/service/twin-attention/index.ts +0 -3
- package/server/service/twin-attention/twin-attention-query.ts +0 -70
- package/server/service/twin-audit/command-audit.ts +0 -114
- package/server/service/twin-audit/index.ts +0 -5
- package/server/service/twin-audit/twin-audit-event.ts +0 -158
- package/server/service/twin-audit/twin-audit-query.ts +0 -72
- package/server/service/twin-backfill/backfill-period-facts.ts +0 -168
- package/server/service/twin-backfill/backfill-shape.ts +0 -86
- package/server/service/twin-backfill/index.ts +0 -3
- package/server/service/twin-backfill/twin-backfill-resolver.ts +0 -35
- package/server/service/twin-control/index.ts +0 -3
- package/server/service/twin-control/twin-control-mutation.ts +0 -150
- package/server/service/twin-event/index.ts +0 -3
- package/server/service/twin-event/journal-count.ts +0 -53
- package/server/service/twin-event/twin-event-keys.ts +0 -215
- package/server/service/twin-event/twin-event-type.ts +0 -68
- package/server/service/twin-event/twin-event.ts +0 -250
- package/server/service/twin-forecast/forecast-metrics.ts +0 -106
- package/server/service/twin-forecast/forecast-tuning.ts +0 -40
- package/server/service/twin-forecast/gap-analytics.ts +0 -139
- package/server/service/twin-forecast/index.ts +0 -3
- package/server/service/twin-forecast/twin-forecast-query.ts +0 -486
- package/server/service/twin-ingest-window/index.ts +0 -7
- package/server/service/twin-ingest-window/twin-ingest-window-query.ts +0 -125
- package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +0 -57
- package/server/service/twin-ingest-window/twin-ingest-window.ts +0 -113
- package/server/service/twin-instance/index.ts +0 -3
- package/server/service/twin-instance/twin-instance.ts +0 -199
- package/server/service/twin-journal/event-type-split-shape.ts +0 -112
- package/server/service/twin-journal/event-type-split.ts +0 -144
- package/server/service/twin-journal/index.ts +0 -3
- package/server/service/twin-journal/journal-order.ts +0 -20
- package/server/service/twin-journal/twin-journal-query.ts +0 -615
- package/server/service/twin-lifecycle/domain-catalog.ts +0 -51
- package/server/service/twin-lifecycle/index.ts +0 -3
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +0 -285
- package/server/service/twin-metrics/index.ts +0 -3
- package/server/service/twin-metrics/twin-metrics-query.ts +0 -172
- package/server/service/twin-model/axis-journal-evidence.ts +0 -57
- package/server/service/twin-model/choose-recipe.ts +0 -31
- package/server/service/twin-model/epcis-coverage.ts +0 -251
- package/server/service/twin-model/external-resolver.ts +0 -173
- package/server/service/twin-model/iec61850-coverage.ts +0 -111
- package/server/service/twin-model/index.ts +0 -25
- package/server/service/twin-model/isa95-coverage.ts +0 -320
- package/server/service/twin-model/item-ref.ts +0 -80
- package/server/service/twin-model/name-index.ts +0 -94
- package/server/service/twin-model/project-structure.ts +0 -213
- package/server/service/twin-model/standard-coverage.ts +0 -35
- package/server/service/twin-model/status-tally.ts +0 -37
- package/server/service/twin-model/twin-equipment.ts +0 -191
- package/server/service/twin-model/twin-lineage-query.ts +0 -327
- package/server/service/twin-model/twin-location.ts +0 -147
- package/server/service/twin-model/twin-model-item-query.ts +0 -1029
- package/server/service/twin-model/twin-model-mutation.ts +0 -503
- package/server/service/twin-model/twin-model-query.ts +0 -792
- package/server/service/twin-model/twin-model-tree-query.ts +0 -211
- package/server/service/twin-model/twin-operation.ts +0 -157
- package/server/service/twin-readiness/index.ts +0 -3
- package/server/service/twin-readiness/twin-readiness-query.ts +0 -96
- package/server/service/twin-space/area-resolver.ts +0 -75
- package/server/service/twin-space/index.ts +0 -8
- package/server/service/twin-space/move-space.ts +0 -262
- package/server/service/twin-space/representation-role.ts +0 -15
- package/server/service/twin-space/space-integrity.ts +0 -293
- package/server/service/twin-space/twin-area.ts +0 -63
- package/server/service/twin-space/twin-space-area.ts +0 -66
- package/server/service/twin-space/twin-space-representation.ts +0 -99
- package/server/service/twin-space/twin-space-resolver.ts +0 -582
- package/server/service/twin-space/twin-space.ts +0 -148
- package/server/service/twin-state/index.ts +0 -3
- package/server/service/twin-state/twin-state-subscription.ts +0 -62
- package/server/service/twin-structure/index.ts +0 -3
- package/server/service/twin-structure/twin-structure.ts +0 -96
- package/server/service/twin-subject/event-subjects.ts +0 -162
- package/server/service/twin-subject/index.ts +0 -10
- package/server/service/twin-subject/item-resolver.ts +0 -92
- package/server/service/twin-subject/subject-query-shape.ts +0 -84
- package/server/service/twin-subject/twin-subject-backfill.ts +0 -196
- package/server/service/twin-subject/twin-subject-event.ts +0 -101
- package/server/service/twin-subject/twin-subject-fast-path.ts +0 -346
- package/server/service/twin-subject/twin-subject-query.ts +0 -210
- package/server/service/twin-subject/twin-subject-writer.ts +0 -189
- package/server/service/twin-target/index.ts +0 -5
- package/server/service/twin-target/twin-target-resolver.ts +0 -142
- package/server/service/twin-target/twin-target.ts +0 -97
- package/server/types/global.d.ts +0 -22
- package/shared/axis-read.ts +0 -28
- package/shared/entity-delta.ts +0 -335
- package/shared/kpi-broadcast.ts +0 -13
- package/shared/touched-items.ts +0 -73
- package/shared/twin-level.ts +0 -48
- package/test/ack-shape-alignment.test.ts +0 -97
- package/test/actuation-advisor.test.ts +0 -55
- package/test/actuation-approval-door.test.ts +0 -411
- package/test/actuation-dispatch.test.ts +0 -209
- package/test/actuation-effect.test.ts +0 -162
- package/test/actuation-outcome.test.ts +0 -152
- package/test/actuation-rule-runner.test.ts +0 -281
- package/test/actuation-rule.test.ts +0 -266
- package/test/actuation-seam.test.ts +0 -255
- package/test/actuation-settle.test.ts +0 -164
- package/test/actuation-target.test.ts +0 -145
- package/test/actuation-verification-state.test.ts +0 -139
- package/test/adopt-structure-live.test.ts +0 -133
- package/test/aggregate-not-findone.test.ts +0 -112
- package/test/area-resolver-db.test.ts +0 -110
- package/test/attention-digest.test.ts +0 -161
- package/test/axis-declaration-passthrough-db.test.ts +0 -152
- package/test/axis-journal-evidence.test.ts +0 -71
- package/test/axis-read.test.ts +0 -188
- package/test/backfill-shape.test.ts +0 -89
- package/test/boot-resume.test.ts +0 -287
- package/test/broadcast-cost-baseline.test.ts +0 -201
- package/test/broadcast-period.test.ts +0 -58
- package/test/broadcast-queue-overflow.test.ts +0 -244
- package/test/canonical-ingest-vocabularies.test.ts +0 -451
- package/test/canonical-quantity-door.test.ts +0 -61
- package/test/capability-mapping.test.ts +0 -89
- package/test/checkpoint-refuses-empty.test.ts +0 -103
- package/test/choose-recipe.test.ts +0 -117
- package/test/column-type-portability.test.ts +0 -122
- package/test/command-routing.test.ts +0 -61
- package/test/command-store-writes-columns.test.ts +0 -126
- package/test/connection-portability-doors.test.ts +0 -87
- package/test/connector-capability-declaration.test.ts +0 -195
- package/test/contract-layer-guard.test.ts +0 -48
- package/test/control-capability.test.ts +0 -98
- package/test/cursor-stall-not-read-failure.test.ts +0 -126
- package/test/declaration-reaches-model.test.ts +0 -226
- package/test/declared-location-types.test.ts +0 -89
- package/test/declared-stimulus.test.ts +0 -88
- package/test/dedupe-transformation.test.ts +0 -112
- package/test/discovery-result.test.ts +0 -75
- package/test/dispatch-after-approval-source.test.ts +0 -81
- package/test/duration-estimators.test.ts +0 -144
- package/test/energy-topology.test.ts +0 -113
- package/test/entity-delta.test.ts +0 -352
- package/test/equipment-identity-reaches.test.ts +0 -57
- package/test/event-subjects.test.ts +0 -148
- package/test/event-time-column.test.ts +0 -67
- package/test/event-type-split.test.ts +0 -178
- package/test/external-resolver.test.ts +0 -177
- package/test/fact-scope-wiring.test.ts +0 -96
- package/test/fill-dedupe.test.ts +0 -59
- package/test/fill-loop.test.ts +0 -35
- package/test/first-envelope.test.ts +0 -153
- package/test/fold-gap-speaks.test.ts +0 -53
- package/test/fold-shift-dst.test.ts +0 -110
- package/test/forecast-metrics.test.ts +0 -157
- package/test/forecast-tuning.test.ts +0 -42
- package/test/gap-analytics.test.ts +0 -113
- package/test/generated-not-counted.test.ts +0 -99
- package/test/guard-roots.ts +0 -76
- package/test/home-in-area.test.ts +0 -90
- package/test/hook-address.test.ts +0 -28
- package/test/hook-rejected-shape.test.ts +0 -86
- package/test/hook-response-sum.test.ts +0 -193
- package/test/hook-sequence.test.ts +0 -333
- package/test/ingest-bench.test.ts +0 -70
- package/test/ingest-dedupe.test.ts +0 -56
- package/test/ingest-expected-quiet.test.ts +0 -111
- package/test/ingest-health-engine.test.ts +0 -248
- package/test/ingest-health-wiring.test.ts +0 -120
- package/test/ingest-health.test.ts +0 -306
- package/test/ingest-history.test.ts +0 -247
- package/test/ingest-idempotent.test.ts +0 -211
- package/test/ingest-reconcile-four-ways.test.ts +0 -97
- package/test/ingest-rules-header.test.ts +0 -100
- package/test/ingest-running-guard.test.ts +0 -136
- package/test/ingest-space.test.ts +0 -78
- package/test/ingest-window-rolls-unobserved.test.ts +0 -72
- package/test/ingest-wiring-guard.test.ts +0 -197
- package/test/instance-cache-lifecycle.test.ts +0 -110
- package/test/intake-mapping-parity.test.ts +0 -175
- package/test/integration-probes.test.ts +0 -103
- package/test/integration-runner.test.ts +0 -95
- package/test/item-ref.test.ts +0 -78
- package/test/journal-order-axis.test.ts +0 -80
- package/test/journal-read-discipline.test.ts +0 -186
- package/test/journal-retention.test.ts +0 -275
- package/test/journal-sort-axis.test.ts +0 -142
- package/test/journal-write-door.test.ts +0 -110
- package/test/journal-write-trend.test.ts +0 -115
- package/test/kernel-kind-guard.test.ts +0 -98
- package/test/knob-defaults.test.ts +0 -72
- package/test/kpi-baseline-db.test.ts +0 -216
- package/test/kpi-baseline.test.ts +0 -196
- package/test/kpi-fold.test.ts +0 -1456
- package/test/kpi-query-bench.test.ts +0 -130
- package/test/lens-own-places.test.ts +0 -50
- package/test/lineage-survives-restart.test.ts +0 -234
- package/test/live-cadence.test.ts +0 -170
- package/test/live-cursor-wiring.test.ts +0 -87
- package/test/live-feed-lease.test.ts +0 -63
- package/test/live-feed-registry.test.ts +0 -75
- package/test/live-kernel-facts.test.ts +0 -161
- package/test/live-mirror-parity.test.ts +0 -286
- package/test/load-meter.test.ts +0 -328
- package/test/local-declarations.test.ts +0 -662
- package/test/log-stamp.test.ts +0 -59
- package/test/loop-lag.test.ts +0 -82
- package/test/master-to-twin.test.ts +0 -279
- package/test/measured-yield.test.ts +0 -90
- package/test/merge-streams.test.ts +0 -70
- package/test/mirror-resumes-from-checkpoint.test.ts +0 -192
- package/test/model-basis.test.ts +0 -141
- package/test/model-gap.test.ts +0 -153
- package/test/model-refusal.test.ts +0 -75
- package/test/model-vocabulary.test.ts +0 -114
- package/test/move-space.test.ts +0 -149
- package/test/mutation-gate.test.ts +0 -122
- package/test/oee-accumulator.test.ts +0 -204
- package/test/oee-site-calendar.test.ts +0 -146
- package/test/open-doors.test.ts +0 -197
- package/test/operation-basis.test.ts +0 -127
- package/test/operational-vocabulary.test.ts +0 -108
- package/test/operations-capability-db.test.ts +0 -165
- package/test/order-and-transaction-split.test.ts +0 -107
- package/test/order-fold-host.test.ts +0 -112
- package/test/producer-guard.test.ts +0 -66
- package/test/project-structure-db.test.ts +0 -226
- package/test/projection-reaches-screen.test.ts +0 -277
- package/test/projection-reads-declared.test.ts +0 -109
- package/test/property-effects.test.ts +0 -128
- package/test/provenance-promotion.test.ts +0 -99
- package/test/read-failure-ledger.test.ts +0 -106
- package/test/read-failure-visible.test.ts +0 -145
- package/test/read-time.test.ts +0 -118
- package/test/reference-fill.test.ts +0 -235
- package/test/reference-grounding.test.ts +0 -70
- package/test/reference-hook.test.ts +0 -177
- package/test/reference-links.test.ts +0 -56
- package/test/reference-reconciliation.test.ts +0 -39
- package/test/registry-key-guard.test.ts +0 -80
- package/test/rejection-carries-event-id.test.ts +0 -101
- package/test/rename-twin.test.ts +0 -89
- package/test/resolve-ts-siblings.mjs +0 -52
- package/test/restart-policy.test.ts +0 -111
- package/test/resync-origin-site.test.ts +0 -83
- package/test/retry-plan.test.ts +0 -139
- package/test/revision-axis.test.ts +0 -110
- package/test/runtime-key.test.ts +0 -66
- package/test/save-intake-collision.test.ts +0 -91
- package/test/scale-twin-bench.test.ts +0 -103
- package/test/secrets-at-rest.test.ts +0 -135
- package/test/snapshot-freshness.test.ts +0 -60
- package/test/source-outcome-audit.test.ts +0 -104
- package/test/space-integrity.test.ts +0 -223
- package/test/space-representation.test.ts +0 -66
- package/test/space-scope-includes-stopped.test.ts +0 -55
- package/test/spec-coverage.test.ts +0 -113
- package/test/stage-path.test.ts +0 -95
- package/test/standard-coverage.test.ts +0 -148
- package/test/state-axes.test.ts +0 -74
- package/test/status-tally.test.ts +0 -55
- package/test/streamline-e2e.test.ts +0 -76
- package/test/structure-revision-db.test.ts +0 -315
- package/test/subject-fast-path.test.ts +0 -148
- package/test/subject-read-model.test.ts +0 -175
- package/test/sweep-dispatch.test.ts +0 -191
- package/test/tenant-registry-db.test.ts +0 -149
- package/test/time-range.test.ts +0 -152
- package/test/touched-items.test.ts +0 -61
- package/test/twin-audit.test.ts +0 -83
- package/test/twin-event-keys.test.ts +0 -193
- package/test/twin-model-item-db.test.ts +0 -319
- package/test/twin-model-parent-relation-db.test.ts +0 -125
- package/test/twin-model-tree-db.test.ts +0 -209
- package/test/twin-origin-resync.test.ts +0 -133
- package/test/twin-state-channel.test.ts +0 -111
- package/test/vocabulary-guard.test.ts +0 -43
- package/test/warm-start-seam.test.ts +0 -162
- package/test/warm-start.test.ts +0 -297
- package/test/withheld-door.test.ts +0 -95
- package/test/yield-loop.test.ts +0 -199
- package/tsconfig.json +0 -15
- package/tsconfig.shared.json +0 -23
- package/tsconfig.shared.tsbuildinfo +0 -1
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* **원본이 말한 적 없는 것** — 미해결 참조를 세는 한 자리. 순수(import 없음).
|
|
3
|
-
*
|
|
4
|
-
* ── 무엇을 답하나 ───────────────────────────────────────────────────────────
|
|
5
|
-
* 원천이 우리 모델에 없는 id 를 보내면 어떻게 되나. 유입 문(`ingestCanonicalRecords`)은 **거부하지
|
|
6
|
-
* 않는다** — 실측으로 확인했다(2026-08-20):
|
|
7
|
-
*
|
|
8
|
-
* 모르는 로케이션 「오타-99」 → 통과
|
|
9
|
-
* 모르는 bizStep 「PUTAWAY_X17」 → 통과
|
|
10
|
-
* 모르는 계량기 「MMXU-오타-99」 → 통과
|
|
11
|
-
*
|
|
12
|
-
* 거부하지 않는 것이 옳다. 원천이 모델보다 먼저 새 로케이션을 말하는 것은 정상이고(구조 갱신은 늦게 온다),
|
|
13
|
-
* 거부하면 그 선행 계측을 잃는다. 그래서 커널은 **흡수하고 표시한다** — 마스터에 없던 로케이션은
|
|
14
|
-
* `origin: 'observed'` 로 승격되어 스냅샷에 실린다(`ObservedReducer.touchLocation`).
|
|
15
|
-
*
|
|
16
|
-
* ── 왜 이 파일이 있나 ───────────────────────────────────────────────────────
|
|
17
|
-
* 그 표시를 읽는 곳이 **모델 인스펙션 화면 하나**였다. 그런데 이 사실을 필요로 하는 사람은 「이 트윈이
|
|
18
|
-
* 현장과 맞춰지고 있나」를 보는 사람이다 — 원천이 우리가 모르는 로케이션만 보내고 있으면 트윈은 도는데
|
|
19
|
-
* 스키매틱은 비어 있고, 그것이 우리가 「빈 공장」이라 불러 온 상태다.
|
|
20
|
-
*
|
|
21
|
-
* 도출을 두 곳에 적으면 두 화면이 다른 수를 말하게 된다. 그래서 여기 한 벌만 둔다.
|
|
22
|
-
*
|
|
23
|
-
* ── 판정을 바꾸지 않는다 ────────────────────────────────────────────────────
|
|
24
|
-
* 동기화 판정(`syncVerdictOf`)은 **피드**를 말한다: 오고 있나, 통과하나. 이 갭은 **모델**을 말한다:
|
|
25
|
-
* 원천이 아는 것을 우리가 선언했나. 둘을 한 판정에 섞으면 「유입은 정상인데 모델이 뒤처졌다」와
|
|
26
|
-
* 「유입이 막혔다」가 같은 색으로 보이고, 처방이 완전히 다르다.
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
/** 커널 스냅샷에서 우리가 읽는 것만. 나머지 필드는 알 필요가 없다. */
|
|
30
|
-
export interface ModelGapSource {
|
|
31
|
-
locations?: { id?: string; origin?: string }[]
|
|
32
|
-
equipment?: { id?: string; origin?: string }[]
|
|
33
|
-
persons?: { id?: string; origin?: string }[]
|
|
34
|
-
/** 커널이 담을 줄 몰라 세어 둔 사건 — 종류별 개수와 처음·마지막 시각. */
|
|
35
|
-
unhandled?: { eventType: string; count: number; firstAtMs?: number; lastAtMs?: number }[]
|
|
36
|
-
/**
|
|
37
|
-
* EMS 상태 — **`energy` 안에 있다.**
|
|
38
|
-
*
|
|
39
|
-
* `unknownEquipment` 를 루트에서 읽고 있었다(2026-08-20에 잡음). 커널은 그것을 `EnergyState` 안에
|
|
40
|
-
* 담으므로, 루트에서 읽으면 **영원히 `null`** 이다 — 오류도 없이 「에너지 트윈이 아니다」로 읽힌다.
|
|
41
|
-
* 나만 읽는 필드를 잘못된 경로에서 읽으면 이렇게 오류 없이 사라진다.
|
|
42
|
-
*
|
|
43
|
-
* 계량 지점의 `origin` 은 **없을 수 있다**(옛 스냅샷에서 이어받은 지점). 그때는 「선언되었다」가
|
|
44
|
-
* 아니라 **모른다**다.
|
|
45
|
-
*/
|
|
46
|
-
energy?: {
|
|
47
|
-
points?: { id?: string; origin?: string }[]
|
|
48
|
-
/** 모델이 모르는 설비가 에너지 상태를 보내 온 횟수. 0 이면 커널이 이 칸을 만들지 않는다. */
|
|
49
|
-
unknownEquipment?: number
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* 화면에 내는 id 수 상한.
|
|
55
|
-
*
|
|
56
|
-
* 오타 하나를 찾는 데 스무 개면 충분하고, 원천이 수천 개를 보내는 경우(모델을 아예 안 맞춘 경우)에
|
|
57
|
-
* 목록으로 화면을 채울 이유가 없다. **넘친 수는 함께 낸다** — 알리지 않고 자르지 않는다.
|
|
58
|
-
*/
|
|
59
|
-
export const GAP_ID_LIMIT = 20
|
|
60
|
-
|
|
61
|
-
export interface ModelGapAxis {
|
|
62
|
-
/** 관측으로만 알게 된 id 수. */
|
|
63
|
-
count: number
|
|
64
|
-
/** 그중 화면에 싣는 것(최대 `GAP_ID_LIMIT`). */
|
|
65
|
-
ids: string[]
|
|
66
|
-
/** 상한에서 밀려난 수. 0 이면 전부 실었다. */
|
|
67
|
-
more: number
|
|
68
|
-
/**
|
|
69
|
-
* 출처를 **모르는** 수 — 표시가 없는 항목.
|
|
70
|
-
*
|
|
71
|
-
* 「선언되었다」로 세지 않는다. 계량기는 이 표시가 늦게 생겼으므로 옛 스냅샷에서 이어받은 지점에는
|
|
72
|
-
* 칸이 없다(`undefined`). 그것을 마스터로 세면 오타를 놓치고, 관측으로 세면 정상을 문제로 만든다.
|
|
73
|
-
* 둘 다 틀리므로 **모른다고 센다.**
|
|
74
|
-
*/
|
|
75
|
-
unknown: number
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface ModelGapView {
|
|
79
|
-
locations: ModelGapAxis
|
|
80
|
-
equipment: ModelGapAxis
|
|
81
|
-
persons: ModelGapAxis
|
|
82
|
-
/**
|
|
83
|
-
* EMS 계량 지점.
|
|
84
|
-
*
|
|
85
|
-
* ── 이 축이 가장 무겁다 ────────────────────────────────────────────────────
|
|
86
|
-
* 모르는 `meterId` 는 알리지 않고 새 계량기가 되고 그 kW 가 그 현장의 **수요 구간·피크·요금 판정**에
|
|
87
|
-
* 더해진다. 오타 하나면 진짜 계량기는 멈추고 유령이 누적된다 — 숫자는 그럴듯하고 틀린다. 자리 오타는
|
|
88
|
-
* 스키매틱이 비는 것으로 드러나지만, 이건 그럴듯한 숫자로 나온다.
|
|
89
|
-
*
|
|
90
|
-
* 커널이 `origin` 을 **표본마다 다시 맞춘다** — 선언의 정본은 모델이고 모델은 채택으로 늘어나므로,
|
|
91
|
-
* 한 번 찍고 두면 나중에 선언된 계량기가 영원히 `observed` 로 남는다. 그래서 이 값은 「지금 모델에
|
|
92
|
-
* 있는가」의 답이고, 「한 번 오타였다」의 답이 아니다.
|
|
93
|
-
*/
|
|
94
|
-
meters: ModelGapAxis
|
|
95
|
-
/** 세 축의 합 — 화면이 「있나 없나」를 한 번에 묻기 위한 값. */
|
|
96
|
-
total: number
|
|
97
|
-
/** 커널이 담을 줄 모른 사건들(종류별). 참조 문제와 다른 사실이므로 따로 낸다. */
|
|
98
|
-
unhandled: { eventType: string; count: number; lastAt: string | null }[]
|
|
99
|
-
/** EMS: 모델이 모르는 설비의 에너지 보고 횟수. 없으면 `null`(0 과 구별한다). */
|
|
100
|
-
unknownEquipmentReports: number | null
|
|
101
|
-
/**
|
|
102
|
-
* 아직 덮지 못하는 축 — **모르는 것을 모른다고 말한다.**
|
|
103
|
-
*
|
|
104
|
-
* 계량기는 커널 0.7.39 부터 덮인다(그 전에는 `origin` 표시가 없어 오타를 찾아 줄 수 없었다).
|
|
105
|
-
* 비어 있는 것이 정상이고, 새 축이 표시 없이 들어오면 여기에 이름을 넣는다 — 화면이 「다 찾아
|
|
106
|
-
* 준다」고 말하지 않게.
|
|
107
|
-
*/
|
|
108
|
-
notCovered: string[]
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/** 계량기 축이 아직 덮이지 않는 이유 — 화면이 그대로 말할 수 있게 이름을 여기 둔다. */
|
|
112
|
-
export const NOT_COVERED_METERS = 'meters'
|
|
113
|
-
|
|
114
|
-
function axisOf(rows: { id?: string; origin?: string }[] | undefined): ModelGapAxis {
|
|
115
|
-
const ids: string[] = []
|
|
116
|
-
let count = 0
|
|
117
|
-
let unknown = 0
|
|
118
|
-
for (const r of rows ?? []) {
|
|
119
|
-
if (r?.origin === 'observed') {
|
|
120
|
-
count++
|
|
121
|
-
if (ids.length < GAP_ID_LIMIT) ids.push(String(r.id ?? ''))
|
|
122
|
-
} else if (r?.origin !== 'master') {
|
|
123
|
-
/* 표시가 없다 — 마스터로도 관측으로도 세지 않는다. 모르는 것은 모른다고 센다. */
|
|
124
|
-
unknown++
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return { count, ids, more: Math.max(0, count - ids.length), unknown }
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* 스냅샷 → 모델 갭.
|
|
132
|
-
*
|
|
133
|
-
* 스냅샷이 없으면 `null` 이다 — **0 이 아니다.** 트윈이 돌지 않으면 비교할 상대가 없고, 「없다」와
|
|
134
|
-
* 「세어 보지 못했다」는 다른 사실이다(모델 인스펙션이 같은 규율을 쓴다).
|
|
135
|
-
*/
|
|
136
|
-
export function modelGapOf(snapshot: ModelGapSource | null | undefined): ModelGapView | null {
|
|
137
|
-
if (!snapshot) return null
|
|
138
|
-
|
|
139
|
-
const locations = axisOf(snapshot.locations)
|
|
140
|
-
const equipment = axisOf(snapshot.equipment)
|
|
141
|
-
const persons = axisOf(snapshot.persons)
|
|
142
|
-
const meters = axisOf(snapshot.energy?.points)
|
|
143
|
-
|
|
144
|
-
return {
|
|
145
|
-
locations,
|
|
146
|
-
equipment,
|
|
147
|
-
persons,
|
|
148
|
-
meters,
|
|
149
|
-
total: locations.count + equipment.count + persons.count + meters.count,
|
|
150
|
-
unhandled: (snapshot.unhandled ?? []).map(u => ({
|
|
151
|
-
eventType: u.eventType,
|
|
152
|
-
count: u.count,
|
|
153
|
-
/* 마지막 시각이 멈춘 종류는 이미 고쳐진 것이다. 없으면 지어내지 않는다. */
|
|
154
|
-
lastAt: Number.isFinite(u.lastAtMs) ? new Date(u.lastAtMs as number).toISOString() : null
|
|
155
|
-
})),
|
|
156
|
-
/*
|
|
157
|
-
* 커널은 0 이면 이 칸을 만들지 않는다. 그래서 「없음」은 두 뜻이다 — 에너지 트윈이 아니거나, 세었고
|
|
158
|
-
* 0 이었다. 둘을 가르려면 `energy` 자체가 있는지를 본다: 있으면 세었고 0 이다.
|
|
159
|
-
*/
|
|
160
|
-
unknownEquipmentReports:
|
|
161
|
-
typeof snapshot.energy?.unknownEquipment === 'number' ? snapshot.energy.unknownEquipment : snapshot.energy ? 0 : null,
|
|
162
|
-
/*
|
|
163
|
-
* 이제 계량기도 덮는다(커널 0.7.39 가 `MeterPointState.origin` 을 낸다). 덮지 못하는 축이 생기면
|
|
164
|
-
* 다시 여기에 이름을 넣는다 — 화면이 「다 찾아 준다」고 말하지 않게.
|
|
165
|
-
*/
|
|
166
|
-
notCovered: []
|
|
167
|
-
}
|
|
168
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Refusal } from '@things-factory/shell'
|
|
2
|
-
|
|
3
|
-
/*
|
|
4
|
-
* **A twin model the kernel refuses is said by name** (ADR-0054).
|
|
5
|
-
*
|
|
6
|
-
* ── What went wrong (2026-10-10) ─────────────────────────────────────────────
|
|
7
|
-
* The MES kernel refuses a model without a production declaration. The engine let that error through
|
|
8
|
-
* as it was, so `twinReplay(miratek)` reached the screen as INTERNAL_SERVER_ERROR with the kernel's
|
|
9
|
-
* English sentence in the shell's notice. The model was what was wrong, not the server.
|
|
10
|
-
*
|
|
11
|
-
* ── The rule ─────────────────────────────────────────────────────────────────
|
|
12
|
-
* The kernel names its refusals: an error that carries a string `code` and an object `params`. The
|
|
13
|
-
* kernel cannot reach the shell, so the host turns that into a shell `Refusal` here, adding which twin
|
|
14
|
-
* it was. The sentence is made where the reader's language is known (`SpeakRefusals`, or the import
|
|
15
|
-
* result's `refusal()`), under `error.<code>`. Anything without a name passes through untouched.
|
|
16
|
-
*/
|
|
17
|
-
export function asModelRefusal(error: unknown, instanceId: string): unknown {
|
|
18
|
-
if (error instanceof Refusal) return error
|
|
19
|
-
const e = error as { code?: unknown; params?: unknown; message?: unknown } | null
|
|
20
|
-
if (!e || typeof e.code !== 'string' || !e.code || !e.params || typeof e.params !== 'object') return error
|
|
21
|
-
return new Refusal(e.code, { ...(e.params as Record<string, any>), instanceId }, String(e.message ?? e.code))
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** Run a step that loads or replays a model; a kernel refusal comes out as a `Refusal`. */
|
|
25
|
-
export function refusingModel<T>(instanceId: string, step: () => T): T {
|
|
26
|
-
try {
|
|
27
|
-
return step()
|
|
28
|
-
} catch (error) {
|
|
29
|
-
throw asModelRefusal(error, instanceId)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 저장된 트윈 모델의 **어휘 세대를 흡수한다** — 읽는 순간 한 어휘로. 순수.
|
|
3
|
-
*
|
|
4
|
-
* ── 계기 (2026-08-06, 사용자 신고) ───────────────────────────────────────────
|
|
5
|
-
* 트윈 모델러의 엔티티 목록이 **통째로 비어 있었다.** 오류도 없었다. 원인은 이 인스턴스의 저장된 모델가
|
|
6
|
-
* 옛 어휘였고 화면과 호스트는 새 어휘(`locations`/`equipment`)를 읽었기 때문이다. 그 옛 이름들은
|
|
7
|
-
* 아래 `RETIRED_KEYS` 에 있다 — 흡수할 세대의 이름을 적지 않고는 이 파일을 쓸 수 없다.
|
|
8
|
-
*
|
|
9
|
-
* 커널에는 이미 세대를 흡수하는 리더가 있다(`readBoardLocations`·`readBoardEquipment` — 세 세대
|
|
10
|
-
* `movers`→`equipmentList`→`equipment`, 실측 주석에 "저장된 모델 23개 중 13개가 `movers`"). 그런데 **그
|
|
11
|
-
* 리더를 거치는 곳이 목록뿐**이었다. 상세·구조 서명·주행 추정기·설비 동기는 컬렉션을 직접 읽어
|
|
12
|
-
* **오류 없이 빈 공장**으로 읽었다:
|
|
13
|
-
*
|
|
14
|
-
* · 모델러·팔레트·보드 자동생성 → 엔티티 0(사용자가 본 증상)
|
|
15
|
-
* · 구조 서명 → `N[]M[]` — **서로 다른 두 공장이 구조적으로 같아 보인다**(변경 감지가 죽는다)
|
|
16
|
-
* · 주행 추정기 → 설비 0이라 거리 기반 소요시간을 못 만든다
|
|
17
|
-
* · 설비 동기 → 아는 설비가 0이라 중복 append + 한 모델에 두 세대가 섞인다
|
|
18
|
-
*
|
|
19
|
-
* ── 왜 자리마다 고치지 않나 ─────────────────────────────────────────────────
|
|
20
|
-
* 저장된 모델를 읽는 자리가 **27곳**이다. 자리마다 리더를 쓰게 하면 다음에 추가되는 자리가 또 빠진다 —
|
|
21
|
-
* 그리고 빠진 것은 오류가 아니라 **빈 공장**이라 들어온 것이 없다. 그래서 **DB에서 읽는 순간 한 번** 정규화한다
|
|
22
|
-
* (엔티티 컬럼 변환기). 그 뒤로는 코드가 세대를 알 필요가 없다.
|
|
23
|
-
*
|
|
24
|
-
* ── 쓰기는 건드리지 않는다 ──────────────────────────────────────────────────
|
|
25
|
-
* 저장은 주는 대로 한다(새 쓰기는 이미 새 어휘다). 읽기가 정규화되므로, 저장된 옛 모델는 **다음에
|
|
26
|
-
* 저장될 때 자연히 새 어휘로 옮겨간다** — 마이그레이션을 따로 실행하지 않는다.
|
|
27
|
-
*/
|
|
28
|
-
import { readBoardLocations, readBoardEquipment } from '@operato/ops-contract'
|
|
29
|
-
|
|
30
|
-
/** 흡수하고 **내보내지 않는** 옛 키 — 남겨 두면 소비처가 두 어휘를 다시 보게 된다. */
|
|
31
|
-
const RETIRED_KEYS = ['nodes', 'movers', 'equipmentList'] as const // vocabulary-guard: allow — 옛 어휘를 흡수하는 것이 이 코드의 일이다(세대 이름을 적어야 흡수할 수 있다)
|
|
32
|
-
|
|
33
|
-
/** 등급 축들 — 넷이 같은 모양이라 같은 규칙을 쓴다(어느 자원이든 표시명은 `name`). */
|
|
34
|
-
const CLASS_KEYS = ['personnelClasses', 'equipmentClasses', 'assetClasses', 'materialClasses'] as const
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 보드를 정본 어휘로 — `locations`·`equipment` 만 남는다. 새 어휘 모델에는 **아무 일도 하지 않는다**
|
|
38
|
-
* (같은 값을 다시 담을 뿐이라 멱등).
|
|
39
|
-
*
|
|
40
|
-
* 모델이 아닌 것(없음·배열·원시값)은 **그대로 통과**시킨다 — 모양을 짐작해 고치지 않는다.
|
|
41
|
-
*/
|
|
42
|
-
export function canonicalModel<T = any>(model: T): T {
|
|
43
|
-
if (!model || typeof model !== 'object' || Array.isArray(model)) return model
|
|
44
|
-
|
|
45
|
-
const rest: Record<string, unknown> = {}
|
|
46
|
-
for (const [k, v] of Object.entries(model as Record<string, unknown>)) {
|
|
47
|
-
if ((RETIRED_KEYS as readonly string[]).includes(k)) continue
|
|
48
|
-
rest[k] = v
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/*
|
|
52
|
-
* **등급의 표시명은 `name` 이다** — 옛 모델는 `description` 에 담았다.
|
|
53
|
-
*
|
|
54
|
-
* 표준 마스터가 등급 표시명을 `description` 으로 주기 때문에 그대로 저장돼 있었고, 화면은 그것을
|
|
55
|
-
* "설명" 열에 앉혔다 — 사용자에게는 이름인데 머리글은 설명이라, 같은 것을 축마다 다른 이름으로
|
|
56
|
-
* 부르게 된다. 인제스트 문에서 이미 `name` 으로 옮기고 있지만, **이미 저장된 모델**가 그대로 남아
|
|
57
|
-
* 새 트윈만 고쳐진다. 정규화의 집은 여기 하나다(위 머리말의 이유 그대로).
|
|
58
|
-
*/
|
|
59
|
-
for (const key of CLASS_KEYS) {
|
|
60
|
-
const list = rest[key]
|
|
61
|
-
if (!Array.isArray(list)) continue
|
|
62
|
-
rest[key] = list.map((c: any) =>
|
|
63
|
-
c && typeof c === 'object' && !c.name && c.description
|
|
64
|
-
? (({ description, ...keep }) => ({ ...keep, name: description }))(c)
|
|
65
|
-
: c
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/* 리더가 세대를 고른다 — 여기서 `??` 사슬을 다시 적으면 세대 규칙이 두 곳이 된다. */
|
|
70
|
-
return { ...rest, locations: readBoardLocations(model as any), equipment: readBoardEquipment(model as any) } as T
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* 엔티티 컬럼 변환기 — **읽을 때만** 정규화한다.
|
|
75
|
-
*
|
|
76
|
-
* `to`(쓰기)는 손대지 않는다: 저장은 호출부가 준 그대로가 진실이고, 읽기가 정규화되므로 다음 저장에서
|
|
77
|
-
* 자연히 새 어휘가 된다.
|
|
78
|
-
*/
|
|
79
|
-
export const modelColumnTransformer = {
|
|
80
|
-
from: (value: any) => canonicalModel(value),
|
|
81
|
-
to: (value: any) => value
|
|
82
|
-
}
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* OEE 이벤트 누적기 (순수·근사) — live-모드 OEE 입력 생산의 한 경로(face2-inbound-live §1.1, option ②).
|
|
3
|
-
*
|
|
4
|
-
* 문제: OEE 공식(computeOee)은 sim/live 공유되나, 입력 카운터(runMs/downMs/…)는 미러 State·이벤트에 없다
|
|
5
|
-
* (emitEquipment 는 status/location/motion 만 방출). → live 는 카운터를 별도 생산해야 한다.
|
|
6
|
-
* 이 누적기: equipment.status 전이 스트림으로 무버별 시간-in-상태를 누적해 카운터를 근사 생산.
|
|
7
|
-
*
|
|
8
|
-
* 정확: downMs(고장 시간 = down 구간 합) · quality(good/scrap = quality.output 델타). 근사·한계:
|
|
9
|
-
* - busyMs 를 runMs 로(setup 분리 불가 — 이벤트에 setup 없음) → performance 낙관·availability 는 setup 손실 미반영.
|
|
10
|
-
* - quality.output 이 없으면(예: WMS/YMS) quality=1(품질 개념 없음).
|
|
11
|
-
* 시간축 = Date.parse(eventTime)(ms) — 구간 차분은 sim/실시간 무관하게 정확(고정 오프셋 상쇄).
|
|
12
|
-
*/
|
|
13
|
-
/* OEE 공식은 계약에 있다 — 소비자가 셋이라(시뮬·미러·MES) 커널에 두면 밖에서 다시 쓰게 된다. */
|
|
14
|
-
import { computeOee, nonWorkingMsIn } from '@operato/ops-contract'
|
|
15
|
-
import type { OeeCounters, WorkCalendarEntry } from '@operato/ops-contract'
|
|
16
|
-
import type { CanonicalEnvelope, OeeMetrics } from '@operato/ops-contract'
|
|
17
|
-
|
|
18
|
-
interface Acc {
|
|
19
|
-
status?: string
|
|
20
|
-
lastMs: number
|
|
21
|
-
startMs: number
|
|
22
|
-
busyMs: number
|
|
23
|
-
downMs: number
|
|
24
|
-
goodCount: number
|
|
25
|
-
nonconformingCount: number
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** 누적기의 완전한 재개점 — 저장했다 되살릴 수 있어야 꼬리만 계산할 수 있다. */
|
|
29
|
-
export interface OeeCheckpoint {
|
|
30
|
-
maxMs: number
|
|
31
|
-
acc: ({ moverId: string } & Acc)[]
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export class OeeAccumulator {
|
|
35
|
-
private acc = new Map<string, Acc>()
|
|
36
|
-
private maxMs = 0 // 최신 이벤트 시각 — nowMs 기본값(현재 계측 시점)
|
|
37
|
-
|
|
38
|
-
/*
|
|
39
|
-
* ── 현장이 언제 도나 — **계획 조업 시간의 근거** (2026-09-07) ────────────────
|
|
40
|
-
* 이것이 없던 동안 계획 조업 시간이 「재기 시작한 뒤 흐른 시간 전부」였다. 주말도 야간도 휴일도
|
|
41
|
-
* 계획 조업으로 세었다.
|
|
42
|
-
*
|
|
43
|
-
* [산술] 8시간 × 주5일이면 168시간 중 40시간이 조업이다 — PBT 가 4.2배 크고 가동률이 그만큼 작다.
|
|
44
|
-
* 그리고 그 수가 1로 잘려 있어서(오늘 걷었다) 그럴싸하게 보였다. 두 오류가 서로를 가렸다.
|
|
45
|
-
*
|
|
46
|
-
* plant 레인이 같은 자리를 먼저 겪고 실측을 냈다 — 3교대를 물려받으면 `availability 0.4583`,
|
|
47
|
-
* 달력이 아예 없으면 **수를 안 낸다**. 트윈은 창 전체를 계획으로 쳐서 수를 냈다.
|
|
48
|
-
*
|
|
49
|
-
* ⚠ **선언이 없으면 채우지 않는다.** `nonWorkingMsIn` 이 그때 `undefined` 를 내고, 그 값을 0 으로
|
|
50
|
-
* 바꾸지 않는다 — 0 은 「달력을 봤고 쉬는 시간이 없었다」는 주장이다. 지금은 그러면 PBT 가 창 전체가
|
|
51
|
-
* 되어 예전과 같은 수가 나온다. **그것을 「안 낸다」로 바꿀지는 아직 결정되지 않았다** — 거동 변화가
|
|
52
|
-
* 크고 화면이 비는 자리라 사용자 판단을 기다린다(성숙도에 미달로 세우는 짝과 함께 가야 한다).
|
|
53
|
-
*/
|
|
54
|
-
private siteCalendar?: readonly WorkCalendarEntry[]
|
|
55
|
-
private calendarByResource = new Map<string, readonly WorkCalendarEntry[]>()
|
|
56
|
-
private utcOffsetMinutes?: number
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* 모델에서 조업 달력을 읽어 얹는다 — 모델을 들고 있는 쪽(`TwinEngine`)이 부른다.
|
|
60
|
-
*
|
|
61
|
-
* ── 우선순위가 여기 있는 이유 ───────────────────────────────────────────────
|
|
62
|
-
* ```
|
|
63
|
-
* 설비의 달력 이 설비의 가동 계획 — 선언했으면 이것이 이긴다 (24시간 도는 로)
|
|
64
|
-
* 현장의 달력 이 현장의 조업일
|
|
65
|
-
* 없음 제약 없음 — 계획 조업 시간이 창 전체가 된다
|
|
66
|
-
* ```
|
|
67
|
-
* 계획 조업 시간을 내는 자리가 여기라 그 규칙도 여기 둔다. 부르는 쪽마다 고르게 하면 라이브와
|
|
68
|
-
* 히스토리가 다른 답을 낸다.
|
|
69
|
-
*
|
|
70
|
-
* ⚠ **설비의 달력은 사람의 근무조가 아니다.** 씨앗이 사람의 근무조를 설비 달력에 복사한 일이 있었고,
|
|
71
|
-
* 그때 아무도 근무하지 않는 시간이 근무 시간으로 기록됐다. 사람 쪽은 `persons[].workCalendar` 다.
|
|
72
|
-
*
|
|
73
|
-
* 세우는 자리에서 한 번만 주지 않고 따로 부르는 이유는 모델이 다시 실릴 수 있기 때문이다
|
|
74
|
-
* (재동기화 · 이관). 그때 달력만 갈아 끼우면 누적된 계측을 버리지 않는다.
|
|
75
|
-
*/
|
|
76
|
-
setWorkCalendar(model?: { workCalendar?: readonly WorkCalendarEntry[]; equipment?: readonly any[]; utcOffsetMinutes?: number }): void {
|
|
77
|
-
this.siteCalendar = model?.workCalendar?.length ? model.workCalendar : undefined
|
|
78
|
-
this.utcOffsetMinutes = model?.utcOffsetMinutes
|
|
79
|
-
this.calendarByResource.clear()
|
|
80
|
-
for (const e of model?.equipment ?? []) {
|
|
81
|
-
const cal = e?.workCalendar
|
|
82
|
-
if (e?.id && Array.isArray(cal) && cal.length) this.calendarByResource.set(String(e.id), cal)
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 이 설비의 계획 가동 달력 — 자기 것이 있으면 그것, 없으면 현장의 것.
|
|
88
|
-
*
|
|
89
|
-
* 인자 이름이 `moverId` 인 것은 **봉투의 옛 세대 필드 이름**이라 그렇다(§`apply`). 새로 만드는
|
|
90
|
-
* 이름에는 그 낱말을 쓰지 않는다 — 어휘 가드가 그것을 잡았고, 맞게 잡았다.
|
|
91
|
-
*/
|
|
92
|
-
private calendarFor(moverId: string): readonly WorkCalendarEntry[] | undefined {
|
|
93
|
-
return this.calendarByResource.get(moverId) ?? this.siteCalendar
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
private ensure(moverId: string, t: number): Acc {
|
|
97
|
-
let a = this.acc.get(moverId)
|
|
98
|
-
if (!a) {
|
|
99
|
-
a = { lastMs: t, startMs: t, busyMs: 0, downMs: 0, goodCount: 0, nonconformingCount: 0 }
|
|
100
|
-
this.acc.set(moverId, a)
|
|
101
|
-
}
|
|
102
|
-
return a
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* **재개점** — 이 누적기의 상태 전부(이어 계산의 씨앗).
|
|
107
|
-
*
|
|
108
|
-
* ── 왜 필요한가 (2026-08-18) ────────────────────────────────────────────────
|
|
109
|
-
* 가동 이력은 원 시스템이 누적을 주지 않아 **우리가 이벤트를 적분해** 만든다. 그래서 저널을 꼬리만
|
|
110
|
-
* 계산하면 이 누적기는 꼬리분만 갖게 되고, 화면의 가용률·수율이 알리지 않고 작아진다(오류는 나지 않는다).
|
|
111
|
-
* 재개점을 함께 저장·복원해야 「이어 계산한 값」이 「0부터 계산한 값」과 같아진다.
|
|
112
|
-
*/
|
|
113
|
-
serialize(): OeeCheckpoint {
|
|
114
|
-
return {
|
|
115
|
-
maxMs: this.maxMs,
|
|
116
|
-
acc: [...this.acc.entries()].map(([moverId, a]) => ({ moverId, ...a }))
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** 재개점에서 되세운다 — 모르는 것은 지어내지 않는다(없으면 빈 누적기다). */
|
|
121
|
-
restore(cp: OeeCheckpoint | undefined | null): void {
|
|
122
|
-
this.maxMs = cp?.maxMs ?? 0
|
|
123
|
-
this.acc = new Map((cp?.acc ?? []).map(({ moverId, ...a }) => [moverId, { ...a }]))
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/** equipment.status(시간-in-상태) + quality.output(양품/불량) 소비. 다른 eventType 무시. */
|
|
127
|
-
apply(env: CanonicalEnvelope): void {
|
|
128
|
-
const t = Date.parse(env.eventTime)
|
|
129
|
-
if (t > this.maxMs) this.maxMs = t
|
|
130
|
-
if (env.eventType === 'quality.output') {
|
|
131
|
-
const q = env.data as { moverId?: string; goodCount?: number; nonconformingCount?: number }
|
|
132
|
-
if (!q?.moverId) return
|
|
133
|
-
const a = this.ensure(q.moverId, t)
|
|
134
|
-
a.goodCount = q.goodCount ?? a.goodCount // 누적값 최신화(good/scrap 은 무버 누적)
|
|
135
|
-
a.nonconformingCount = q.nonconformingCount ?? a.nonconformingCount
|
|
136
|
-
return
|
|
137
|
-
}
|
|
138
|
-
if (env.eventType !== 'equipment.status') return
|
|
139
|
-
const d = env.data as { moverId?: string; status?: string }
|
|
140
|
-
if (!d?.moverId) return
|
|
141
|
-
const a = this.ensure(d.moverId, t)
|
|
142
|
-
const dt = Math.max(0, t - a.lastMs)
|
|
143
|
-
if (a.status === 'busy') a.busyMs += dt
|
|
144
|
-
else if (a.status === 'down') a.downMs += dt
|
|
145
|
-
a.status = d.status
|
|
146
|
-
a.lastMs = t
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/** 무버 OEE 카운터 — 마지막 상태 구간을 nowMs(기본=최신 이벤트 시각)까지 flush. busy→run 근사, setup=0. */
|
|
150
|
-
counters(moverId: string, nowMs: number = this.maxMs): OeeCounters {
|
|
151
|
-
const a = this.acc.get(moverId)
|
|
152
|
-
/*
|
|
153
|
-
* **이 설비의 이벤트를 하나도 못 봤다** — 계측 창이 없다는 뜻이고, 그것을 `0` 으로 메우면
|
|
154
|
-
* "1970년부터 재고 있었다" 가 된다. 시각이 밀리초 epoch 이므로 그 값이 곧 지금 시각이 되어,
|
|
155
|
-
* 화면에 `idleMs 1767226603000`(약 56,000년) 유휴가 섰다. 창을 **말하지 않는다** — 공식이
|
|
156
|
-
* 없음을 없음으로 다룬다(§computeOee).
|
|
157
|
-
*/
|
|
158
|
-
if (!a) return { runMs: 0, setupMs: 0, downMs: 0, goodCount: 0, nonconformingCount: 0 }
|
|
159
|
-
const dt = Math.max(0, nowMs - a.lastMs)
|
|
160
|
-
let busyMs = a.busyMs
|
|
161
|
-
let downMs = a.downMs
|
|
162
|
-
if (a.status === 'busy') busyMs += dt
|
|
163
|
-
else if (a.status === 'down') downMs += dt
|
|
164
|
-
/*
|
|
165
|
-
* 계획 정지 — 계약이 이 칸에 그 뜻을 적어 뒀다(점심 · 예방보전 · 교대). 휴일과 주말이 같은
|
|
166
|
-
* 갈래다. `metricsSinceMs` 를 당겨서 같은 효과를 내지 않는다: 그 칸은 「언제부터 쟀나」라는
|
|
167
|
-
* 사실이고, 파생값을 얹으면 실제보다 늦게 재기 시작했다고 말하는 것이 된다.
|
|
168
|
-
*/
|
|
169
|
-
const holdMs = nonWorkingMsIn(this.calendarFor(moverId), a.startMs, nowMs, this.utcOffsetMinutes)
|
|
170
|
-
return {
|
|
171
|
-
runMs: busyMs,
|
|
172
|
-
setupMs: 0,
|
|
173
|
-
downMs,
|
|
174
|
-
goodCount: a.goodCount,
|
|
175
|
-
nonconformingCount: a.nonconformingCount,
|
|
176
|
-
metricsSinceMs: a.startMs,
|
|
177
|
-
...(holdMs !== undefined ? { holdMs } : {})
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/** 공유 공식으로 근사 OEE 산출 — 정확한 OEE 는 실 텔레메트리(option ①). nowMs 기본=최신 이벤트 시각. */
|
|
182
|
-
oee(moverId: string, nowMs: number = this.maxMs): OeeMetrics {
|
|
183
|
-
return computeOee(this.counters(moverId, nowMs), nowMs)
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* live State 를 OEE 로 보강 — projector 미러 State(관측)의 무버에 누적기 OEE(계산)를 채운다.
|
|
189
|
-
* live-모드 publishEntityData 가 buildEntityDeltas 전에 적용 → equipment data(tag) payload 에 oee 포함
|
|
190
|
-
* (sim 은 커널이 채움 — 이로써 live 도 동일 payload 형상). 순수(입력 불변, 얕은 복사).
|
|
191
|
-
*/
|
|
192
|
-
export function withLiveOee<S extends { equipment?: any[] }>(state: S, acc: OeeAccumulator, nowMs?: number): S {
|
|
193
|
-
if (!state?.equipment) return state
|
|
194
|
-
return { ...state, equipment: state.equipment.map(m => ({ ...m, oee: acc.oee(m.id, nowMs) })) }
|
|
195
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* 이 트윈이 **어떤 공정을 돌리고, 그 시간이 어디서 오나.**
|
|
3
|
-
*
|
|
4
|
-
* ── 왜 이 목록이 필요한가 (2026-08-18) ─────────────────────────────────────
|
|
5
|
-
* 「측정이 없을 때의 표준 시간」을 현장이 선언하려면 먼저 **무엇에 선언할지** 보여야 한다. 그런데 공정은
|
|
6
|
-
* 자리·설비와 달리 모델에 행이 없을 수 있다 — 실측: 운영 중인 트윈 35개 중 창고·야드는 공정 명세 행이
|
|
7
|
-
* 0개였고(MES만 4개), 그 트윈들의 시간은 전부 커널 상수에서 왔다.
|
|
8
|
-
*
|
|
9
|
-
* 그래서 목록을 **지어내지 않고 네 곳에서 모은다**:
|
|
10
|
-
* ① 원천 명세 행(`model.operations`) — 원 시스템이 말한 공정.
|
|
11
|
-
* ② 커널의 자기보고(`specCoverage()`) — **실제로 돌린** 공정과 그 시간의 출처.
|
|
12
|
-
* ③ 이력에서 배운 종류(`measuredOperationKinds`) — 재기동에도 남는 근거.
|
|
13
|
-
* ④ 우리가 이미 선언한 것(`model.localDurations`·`model.localParams`) — 선언해 둔 공정이 목록에서
|
|
14
|
-
* 사라지지 않게(사라지면 철회할 자리가 없다).
|
|
15
|
-
*
|
|
16
|
-
* ③이 필요한 이유는 실측으로 드러났다: ②는 **작업이 새로 생길 때** 채워지므로, 이력이 풍부한 창고
|
|
17
|
-
* 트윈도 재기동 직후에는 목록이 비었다 — 값을 채울 곳을 보여야 하는 화면이 정작 그때 아무 말도 못 한다.
|
|
18
|
-
*
|
|
19
|
-
* 그래도 셋 다 비는 트윈은 있다(한 번도 돌지 않고 명세 행도 없는 새 트윈). 그때 「공정이 없다」고 말하지
|
|
20
|
-
* 않는다(모르는 것이다) — 부르는 쪽이 그 사실을 그대로 화면에 옮긴다.
|
|
21
|
-
*/
|
|
22
|
-
import { readSpecCoverage } from './spec-coverage.ts'
|
|
23
|
-
|
|
24
|
-
/** 공정 한 종류 — 이름과 「지금 무엇으로 도나」. */
|
|
25
|
-
export interface OperationBasisRow {
|
|
26
|
-
/** 작업 종류(`FlowTask.kind` = `OperationDef.key`) — 선언이 겨누는 id 다. */
|
|
27
|
-
kind: string
|
|
28
|
-
/** 사람이 읽는 이름 — 원천 명세 행이 있을 때만(없으면 종류 이름이 곧 이름이다). */
|
|
29
|
-
label?: string
|
|
30
|
-
/**
|
|
31
|
-
* 지금 이 종류의 시간이 어디서 오나 — 커널의 자기보고, 또는 **이력에서 배운 사실**. 없으면 모른다.
|
|
32
|
-
* · `measured` — 이 현장의 이력에서 배운 값(가장 강한 근거). **선언보다 이긴다.**
|
|
33
|
-
* · `declared` — 선언된 값(현장이 정한 것 또는 원천 명세 행).
|
|
34
|
-
* · `default` — 커널 소스의 상수. 이 목록의 존재 이유다.
|
|
35
|
-
*/
|
|
36
|
-
basis?: 'measured' | 'declared' | 'default'
|
|
37
|
-
/** 원천 명세 행이 말한 시간(ISO 8601) — 있으면. 우리 선언이 이것을 이긴다. */
|
|
38
|
-
referenceDuration?: string
|
|
39
|
-
/** 우리가 선언해 둔 시간(ISO 8601) — 있으면. */
|
|
40
|
-
localDuration?: string
|
|
41
|
-
/**
|
|
42
|
-
* 우리가 선언해 둔 공정 모수 — **커널이 읽는 표기 그대로**(수율 0..1, 셋업 ISO 8601).
|
|
43
|
-
*
|
|
44
|
-
* 사람 단위(퍼센트·분)로 되돌리지 않는다: 화면은 선언 겹에서 사용자가 넣은 값을 그대로 들고 있고,
|
|
45
|
-
* 여기 있는 것은 **실제로 커널에 실린 값**이다 — 둘을 견주면 환산이 잘못된 것도 드러난다.
|
|
46
|
-
*/
|
|
47
|
-
localParams?: Record<string, string>
|
|
48
|
-
/** 원천 명세 행이 말한 모수 — 있으면(우리 선언이 이것을 이긴다). */
|
|
49
|
-
referenceParams?: Record<string, string>
|
|
50
|
-
/**
|
|
51
|
-
* 모수를 **무엇으로 읽었나** — 커널의 자기보고(`id → measured|declared`) (2026-08-19).
|
|
52
|
-
*
|
|
53
|
-
* 수율이 이력에서 온 값이면 선언값은 예비로만 남는다(소요시간과 같은 규율) — 화면이 그 사실을 말해야
|
|
54
|
-
* 사람이 헛일을 하지 않는다. 커널이 아직 그 공정을 돌리지 않았으면 이 칸이 빈다(모른다).
|
|
55
|
-
*/
|
|
56
|
-
paramBasis?: Record<string, 'measured' | 'declared'>
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* 공정 목록을 모은다 — **넷의 합집합**, 순서는 원천 행 → 돌린 것 → 이력에서 배운 것 → 선언한 것.
|
|
61
|
-
*
|
|
62
|
-
* `kernel` 이 없으면(정지 트윈) ②가 빠지고, `measuredKinds` 를 주지 않으면 ③이 빠진다: 그 사실은
|
|
63
|
-
* `basis` 가 비는 것으로 드러난다(빈칸이 곧 「모른다」다).
|
|
64
|
-
*/
|
|
65
|
-
export function operationBasis(model: any, kernel?: any, measuredKinds?: readonly string[]): OperationBasisRow[] {
|
|
66
|
-
const rows = new Map<string, OperationBasisRow>()
|
|
67
|
-
const at = (kind: string): OperationBasisRow => {
|
|
68
|
-
const cur = rows.get(kind)
|
|
69
|
-
if (cur) return cur
|
|
70
|
-
const row: OperationBasisRow = { kind }
|
|
71
|
-
rows.set(kind, row)
|
|
72
|
-
return row
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
for (const o of (model?.operations ?? []) as any[]) {
|
|
76
|
-
if (!o?.key) continue
|
|
77
|
-
const row = at(String(o.key))
|
|
78
|
-
if (o.label) row.label = String(o.label)
|
|
79
|
-
if (o.duration) row.referenceDuration = String(o.duration)
|
|
80
|
-
/* 원천이 말한 모수도 함께 든다 — 우리 선언과 견줄 수 있어야 「무엇을 고쳤나」가 보인다. */
|
|
81
|
-
for (const p of (o.parameters ?? []) as any[]) {
|
|
82
|
-
if (!p?.id || p.value === undefined) continue
|
|
83
|
-
row.referenceParams = { ...(row.referenceParams ?? {}), [String(p.id)]: String(p.value) }
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const coverage = kernel ? readSpecCoverage(kernel) : undefined
|
|
88
|
-
for (const o of coverage?.operations ?? []) {
|
|
89
|
-
if (!o?.kind) continue
|
|
90
|
-
const row = at(String(o.kind))
|
|
91
|
-
row.basis = o.duration
|
|
92
|
-
if (o.parameterBasis && Object.keys(o.parameterBasis).length) row.paramBasis = { ...o.parameterBasis }
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/*
|
|
96
|
-
* 이력에서 배운 종류 — 커널이 아직 이 종류를 돌리지 않았어도 **추정기가 답할 수 있다**. 그래서 근거를
|
|
97
|
-
* `measured` 로 채운다: 짐작이 아니라 설치된 추정기가 그 종류에 실측값을 줄 것이라는 사실이다.
|
|
98
|
-
* 커널이 이미 보고한 종류는 **덮지 않는다** — 실제로 돌린 것이 더 강한 사실이다.
|
|
99
|
-
*/
|
|
100
|
-
for (const kind of measuredKinds ?? []) {
|
|
101
|
-
if (!kind) continue
|
|
102
|
-
const row = at(String(kind))
|
|
103
|
-
if (!row.basis) row.basis = 'measured'
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const declared = (model?.localDurations ?? {}) as Record<string, string>
|
|
107
|
-
for (const [kind, iso] of Object.entries(declared)) {
|
|
108
|
-
if (!kind) continue
|
|
109
|
-
at(kind).localDuration = String(iso)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const params = (model?.localParams ?? {}) as Record<string, Record<string, string>>
|
|
113
|
-
for (const [kind, entries] of Object.entries(params)) {
|
|
114
|
-
if (!kind) continue
|
|
115
|
-
const row = at(kind)
|
|
116
|
-
for (const [id, value] of Object.entries(entries ?? {})) row.localParams = { ...(row.localParams ?? {}), [id]: String(value) }
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return [...rows.values()]
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* 선언을 받아도 되는 공정 이름들 — **하나도 확인할 수 없으면 `undefined`**(모른다).
|
|
124
|
-
*
|
|
125
|
-
* 빈 배열로 답하지 않는 이유: 빈 배열은 「어떤 이름도 안 된다」로 읽히고, 그러면 아직 돌지 않은 트윈에는
|
|
126
|
-
* 아무것도 선언할 수 없다. 모르는 것과 없는 것은 다르다 — 모를 때는 받아 주고 그 사실을 말한다.
|
|
127
|
-
*/
|
|
128
|
-
export function knownOperationKinds(model: any, kernel?: any, measuredKinds?: readonly string[]): string[] | undefined {
|
|
129
|
-
const kinds = operationBasis(model, kernel, measuredKinds).map(r => r.kind)
|
|
130
|
-
return kinds.length ? kinds : undefined
|
|
131
|
-
}
|