@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
|
@@ -55,15 +55,18 @@ export interface Isa95Concept {
|
|
|
55
55
|
*
|
|
56
56
|
* 그래서 축일 수 없는 것은 갈 곳을 가리킨다. 여기가 비어 있고 축도 없으면 그것은 **진짜 빈칸**이다.
|
|
57
57
|
*
|
|
58
|
-
* ── ★
|
|
59
|
-
* 이
|
|
60
|
-
*
|
|
58
|
+
* ── ★ 뜻을 고쳐 적는다 (2026-08-24, 사용자 지적) ──────────────────────────
|
|
59
|
+
* 한때 이 칸을 「**어디서 보이나**」로 읽고, 화면이 그것을 「해당 축 항목에 표시됩니다」라는 문장으로
|
|
60
|
+
* 냈다. 두 가지가 잘못이었다.
|
|
61
61
|
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
62
|
+
* ① 그 문장은 **한국어가 아니었다**(사용자 지적). 그리고 칩이 이미 갈 곳을 보이므로 **군더더기**다.
|
|
63
|
+
* ② 뜻이 틀렸다. 이 칸은 「**어디에 속하나**」다 — 그 개념이 자기 목록을 갖지 않고 **어느 축의 안에
|
|
64
|
+
* 들어 있나**. 화면에 그려지는지는 `surface` 가 따로 답한다. 둘은 다른 물음이다.
|
|
64
65
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
66
|
+
* 그래서 **`surface` 와 짝을 맞추지 않는다.** 자기 축이 없으면 언제나 갈 곳을 적는다 — 아직 그려지지
|
|
67
|
+
* 않는 개념도 **어디에 속하는지는 사실**이고, 그것을 비우면 「어디에도 없는 것」으로 읽힌다.
|
|
68
|
+
*
|
|
69
|
+
* 여기가 비어 있고 축도 없으면 그것은 **진짜 빈칸**이다(위 규칙).
|
|
67
70
|
*/
|
|
68
71
|
shownOn?: string[]
|
|
69
72
|
}
|
|
@@ -124,7 +127,17 @@ const PART2: Isa95Concept[] = [
|
|
|
124
127
|
* `TestSpecificationID`(로트별 기준 참조 — 품목 정의가 대신 답하므로 두지 않았다) · `Status` ·
|
|
125
128
|
* `HierarchyScope` · `Version`. 채운 것만 세는 것이 이 표의 규율이다.
|
|
126
129
|
*/
|
|
127
|
-
|
|
130
|
+
/*
|
|
131
|
+
* ── 2026-08-25 — 목록이 쌓이기만 하던 것을 고쳤다 ──────────────────────────
|
|
132
|
+
* 연결된 시스템은 매 주기 현재 재고를 전부 보내는데, 트윈은 그것을 낱낱의 관측으로 받아 **더하기만
|
|
133
|
+
* 했다.** 「그리고 이것 말고는 없다」를 받는 곳이 없어서 목록에서 빠진 줄이 영원히 남았다.
|
|
134
|
+
* 실측: 실제 1,704건인데 트윈이 10,038건.
|
|
135
|
+
*
|
|
136
|
+
* 그동안 이 줄은 「기능 있음」이었다. **현재 재고를 맞게 유지하지 못하는 상태로 그렇게 적을 수
|
|
137
|
+
* 없다.** 오늘 「이 목록이 전부다」를 받는 길을 냈고(커널 0.7.63), 수량으로 온 재고도 없어질 수
|
|
138
|
+
* 있게 했다. 이제 사실이다.
|
|
139
|
+
*/
|
|
140
|
+
{ std: 'MaterialLot', part: '2', label: 'twin.isa95.MaterialLot', axis: 'items', structure: 'partial', behavior: 'full', surface: 'partial', note: 'twin.isa95.note.lot' },
|
|
128
141
|
/*
|
|
129
142
|
* ── 2026-08-24 판정 정정: `none` 이 아니었다 ──────────────────────────────
|
|
130
143
|
* 이 줄은 셋 다 `none` 이었는데 **표가 코드보다 뒤처져 있었다.** 커널은 서브로트를 든다:
|
|
@@ -134,7 +147,7 @@ const PART2: Isa95Concept[] = [
|
|
|
134
147
|
* `itemKeyOf(item)` **개체의 정체성이 이 값이다** — `subLotId ?? epc`
|
|
135
148
|
*
|
|
136
149
|
* 기능이 `full` 인 근거: 이 축이 없으면 같은 로트를 rack-1 에 100개·rack-2 에 60개 관측했을 때
|
|
137
|
-
* **뒤에 온 관측이 앞을 덮어 100개가
|
|
150
|
+
* **뒤에 온 관측이 앞을 덮어 100개가 오류 없이 사라진다**(합계 160 → 60). 실제로 그 결함을 이 축으로
|
|
138
151
|
* 고쳤다. 즉 장식이 아니라 정체성을 지탱한다.
|
|
139
152
|
*
|
|
140
153
|
* 구조가 `partial` 인 이유: 서브로트는 로트와 같은 모양이고(위 참조) 그 로트가 `partial` 이다.
|
|
@@ -154,7 +167,7 @@ const PART2: Isa95Concept[] = [
|
|
|
154
167
|
* 기능은 **부분**이다: 호스트의 주행 추정기가 `speed` 를 읽어 이동 시간을 만드는 것이 유일한 소비처다
|
|
155
168
|
* (다른 속성은 아직 아무도 읽지 않는다). 그 사실을 `full` 로 올리면 표가 거짓이 된다.
|
|
156
169
|
*/
|
|
157
|
-
{ std: 'Property', part: '2', label: 'twin.isa95.Property', axis: null, structure: 'full', behavior: 'partial', surface: 'full', note: 'twin.isa95.note.property' },
|
|
170
|
+
{ std: 'Property', part: '2', label: 'twin.isa95.Property', axis: null, shownOn: ['equipment', 'persons', 'assets'], structure: 'full', behavior: 'partial', surface: 'full', note: 'twin.isa95.note.property' },
|
|
158
171
|
/*
|
|
159
172
|
* **자리의 상시 관측** — 2026-08-24 신설(커널 0.7.56). 표에 이 개념이 아예 없었다.
|
|
160
173
|
*
|
|
@@ -172,12 +185,26 @@ const PART2: Isa95Concept[] = [
|
|
|
172
185
|
* 계층이고 냉장실은 `StorageZone` 수준의 설비다. `OperationalLocationType` 에는 이 축이 없다.
|
|
173
186
|
*
|
|
174
187
|
* 구조가 `partial`: 봉투 전체(`ID`·`Description`·사건 분류·`OperationsRecord` 구조)가 아니라 관측
|
|
175
|
-
* 하나를 담는 데 필요한 칸만 든다.
|
|
188
|
+
* 하나를 담는 데 필요한 칸만 든다. 2026-08-25 에 지난 기록의 봉투가 사람이 적은 문장을 함께
|
|
189
|
+
* 나르게 됐지만(`CanonicalEnvelope.description`), 그것은 **기록에 남는 말**이고 이 타입의
|
|
190
|
+
* `Description` 칸이 아니다 — 상태에 담기지 않으므로 이 줄의 등급을 올리지 않는다.
|
|
176
191
|
* 기능이 `full`: 사건 채널(`location.measured`)이 상태를 만들고, 선언된 기준으로 판정해
|
|
177
192
|
* `observation-out-of-limit` 신호를 세운다.
|
|
178
193
|
* 화면이 `none`: 클라이언트에 이 축을 그리는 곳이 없다(실측 0곳).
|
|
179
194
|
*/
|
|
180
|
-
|
|
195
|
+
/*
|
|
196
|
+
* ── 2026-08-25 — 이 줄이 실제보다 높게 적혀 있었다 ────────────────────────
|
|
197
|
+
* 「기능 있음」으로 적어 두었다. 커널이 관측을 반영하고 기준으로 판단하는 것은 사실이었으므로
|
|
198
|
+
* 그렇게 적었는데, **연결된 시스템이 그 값을 보낼 길이 없었다** — 유입 경로가 `locationId` 를
|
|
199
|
+
* 보지 않아 「어느 사실인지 모른다」로 거부했다.
|
|
200
|
+
*
|
|
201
|
+
* **아무도 먹일 수 없는 기능은 동작하는 기능이 아니다.** 오늘 그 경로를 냈고(커널 0.7.62),
|
|
202
|
+
* 이제 「기능 있음」이 사실이다. 그때까지는 「일부」였어야 했다.
|
|
203
|
+
*
|
|
204
|
+
* 같은 부류를 오늘 세 번 만났다 — 표가 **할 수 있는 일을 못 한다고** 적은 것이 여섯 줄이었고,
|
|
205
|
+
* 이것은 반대로 **못 하는 일을 할 수 있다고** 적은 것이다. 뒤쪽이 더 위험하다.
|
|
206
|
+
*/
|
|
207
|
+
{ std: 'OperationsEvent', part: '2', label: 'twin.isa95.OperationsEvent', axis: null, shownOn: ['locations'], structure: 'partial', behavior: 'full', surface: 'none' }
|
|
181
208
|
]
|
|
182
209
|
|
|
183
210
|
/*
|
|
@@ -199,7 +226,7 @@ const PART4: Isa95Concept[] = [
|
|
|
199
226
|
*
|
|
200
227
|
* `surface` 도 `full` 이다(같은 날 두 번째 단계): 목록·상세·관계에 더해 **과거로 다시 계산하는 길**이 화면에
|
|
201
228
|
* 있다 — 시각 커서를 옮기면 그 시점의 사실이 나오고, 무엇을 근거로 답했는지도 화면이 말한다
|
|
202
|
-
* (라이브=권위 · 저널=파생 ·
|
|
229
|
+
* (라이브=권위 · 저널=파생 · 계산한 리비전). 실측: 이른 시각 0건 · 하루 뒤 504건.
|
|
203
230
|
*/
|
|
204
231
|
{ std: 'OperationsSchedule', part: '4', label: 'twin.isa95.OperationsSchedule', axis: 'orders', structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.schedule' },
|
|
205
232
|
{ std: 'OperationsPerformance', part: '4', label: 'twin.isa95.OperationsPerformance', axis: 'tasks', structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.performance' },
|
|
@@ -242,7 +269,7 @@ const PART4: Isa95Concept[] = [
|
|
|
242
269
|
*
|
|
243
270
|
* 화면은 `none` 이다 — 클라이언트에 이 축을 그리는 곳이 없다(실측: `operato-twin/client` 에 0곳).
|
|
244
271
|
*/
|
|
245
|
-
{ std: 'TestResult', part: '4', label: 'twin.isa95.TestResult', axis: null, structure: 'partial', behavior: 'partial', surface: 'none' },
|
|
272
|
+
{ std: 'TestResult', part: '4', label: 'twin.isa95.TestResult', axis: null, shownOn: ['items'], structure: 'partial', behavior: 'partial', surface: 'none' },
|
|
246
273
|
{ std: 'WorkMaster', part: '4', label: 'twin.isa95.WorkMaster', axis: 'recipes', structure: 'full', behavior: 'full', surface: 'full' },
|
|
247
274
|
{ std: 'WorkDirective', part: '4', label: 'twin.isa95.WorkDirective', axis: null, structure: 'none', behavior: 'none', surface: 'none' }
|
|
248
275
|
]
|
|
@@ -254,10 +281,10 @@ export const ISA95_CONCEPTS: Isa95Concept[] = [...PART2, ...PART4]
|
|
|
254
281
|
* 적합성 보고 — **채운 것과 빠진 것을 함께.**
|
|
255
282
|
*
|
|
256
283
|
* `axis` 를 커널 축 목록과 맞춰 본다: 축이 있다고 적혀 있는데 커널에 없으면 그 선언이 낡은 것이므로
|
|
257
|
-
* **구조 없음으로 낮추고 그 사실을 말한다**(
|
|
284
|
+
* **구조 없음으로 낮추고 그 사실을 말한다**(알리지 않고 통과시키면 이 표가 거짓이 된다).
|
|
258
285
|
*/
|
|
259
286
|
/**
|
|
260
|
-
* 선언한 축을 커널의 축 목록과 맞춘다 — **어긋난 것을
|
|
287
|
+
* 선언한 축을 커널의 축 목록과 맞춘다 — **어긋난 것을 알리지 않고 지우지 않는다.**
|
|
261
288
|
*
|
|
262
289
|
* 두 자리가 어긋날 수 있다.
|
|
263
290
|
* · `axis` — 그 개념 자신의 문. 커널에 없으면 구조를 「없음」으로 낮추고 그 사실을 말한다.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* **개체에서 품목으로** — 정체성 모양이 하나가 아니다 (2026-08-23).
|
|
3
3
|
*
|
|
4
|
-
* ── 무엇이
|
|
4
|
+
* ── 무엇이 알리지 않고 비어 있었나 ───────────────────────────────────────────────
|
|
5
5
|
* 화면이 「이 개체는 선언된 자재가 아닙니다(라인 내부의 중간 산물일 수 있습니다)」라고 말했는데, 그
|
|
6
6
|
* 품목은 원본의 선언에 이름까지 있었다(「냉동그린빈스」). 대응 표(`productionSpec.binding`)도 멀쩡했다.
|
|
7
7
|
*
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* https://…/class/product-M0000438@M2R0001 → null (모르던 모양)
|
|
12
12
|
*
|
|
13
13
|
* 웹 URI 로 정체성을 말하는 원본에서는 언제나 `null` 이 나왔고, 그래서 **개체를 자재에 이을 수 없었다.**
|
|
14
|
-
* 그 결과가 화면 두 곳에서
|
|
14
|
+
* 그 결과가 화면 두 곳에서 들어온 것이 없는 빈칸이었다(계보 적합성 · 오더가 무엇을 만드나). 「없으면 붙이지
|
|
15
15
|
* 않는다」는 규율을 지키기 때문에 아무 오류도 나지 않았다.
|
|
16
16
|
*
|
|
17
17
|
* ── 무엇을 돌려주나 ─────────────────────────────────────────────────────────
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* 두 벌을 만들면 한쪽만 고쳐지므로 한 곳에 둔다(재발명 금지).
|
|
7
7
|
*/
|
|
8
8
|
/* 커널 런타임 로드 — 어느 축이 있는지는 카탈로그가 선언한다(이 파일은 도메인 모양을 알지 않는다). */
|
|
9
|
-
const { TWIN_AXES, axisSource } = require('@operato/
|
|
9
|
+
const { TWIN_AXES, axisSource } = require('@operato/ops-contract')
|
|
10
10
|
|
|
11
11
|
/** `productionSpec.definition.recipes` 같은 경로를 문서에서 따라간다. */
|
|
12
12
|
export const at = (o: any, path: string) => path.split('.').reduce((a: any, k: string) => (a == null ? undefined : a[k]), o)
|
|
@@ -16,7 +16,7 @@ export const at = (o: any, path: string) => path.split('.').reduce((a: any, k: s
|
|
|
16
16
|
*
|
|
17
17
|
* 도메인 모양을 코드가 아는 것이 아니라 **식별자 관례**를 아는 것이다. 후보를 순서대로 보고 첫
|
|
18
18
|
* 값을 쓴다. 하나도 없으면 그 항목은 가리킬 수 없으므로 `null` — 목록에서 빼지 않고 **id 없음**으로
|
|
19
|
-
* 낸다(
|
|
19
|
+
* 낸다(오류 없이 빠지면 건수가 안 맞는다).
|
|
20
20
|
*/
|
|
21
21
|
export const idOf = (o: any, info?: { idField?: string | string[] }): string | null => {
|
|
22
22
|
if (typeof o === 'string') return o
|
|
@@ -5,7 +5,7 @@ import { TwinArea } from '../twin-space/twin-area.js'
|
|
|
5
5
|
import { TwinLocation } from './twin-location.js'
|
|
6
6
|
import { TwinEquipment } from './twin-equipment.js'
|
|
7
7
|
import { TwinOperation } from './twin-operation.js'
|
|
8
|
-
import { readBoardEquipment } from '@operato/
|
|
8
|
+
import { readBoardEquipment } from '@operato/ops-contract'
|
|
9
9
|
|
|
10
10
|
/*
|
|
11
11
|
* 구조 투영 — `model`(커널 입력 문서) → **표준 엔티티 행**(ADR-0032).
|
|
@@ -26,7 +26,7 @@ export interface ProjectionReport {
|
|
|
26
26
|
locations: number
|
|
27
27
|
equipment: number
|
|
28
28
|
operations: number
|
|
29
|
-
/** 자리를 못 찾아 기준 자리를 비운 설비 —
|
|
29
|
+
/** 자리를 못 찾아 기준 자리를 비운 설비 — **알리지 않고 넘기지 않는다.** */
|
|
30
30
|
unresolvedHome: string[]
|
|
31
31
|
/** 구역을 못 찾아 비운 자리. 구역은 model 밖(호스트 개념)이라 어긋날 수 있다. */
|
|
32
32
|
unresolvedArea: string[]
|
|
@@ -48,7 +48,7 @@ export async function projectStructure(domainId: string, instanceId: string, mod
|
|
|
48
48
|
* 실측(2026-08-18): 현장 값을 그 현장의 트윈 전부에 얹다가 한 트윈에서 투영이 터졌다. 올라온 것은
|
|
49
49
|
* `SQLITE_CONSTRAINT: UNIQUE constraint failed: twin_equipment...` 뿐이라 **무엇이 잘못됐는지 아무도
|
|
50
50
|
* 알 수 없었다.** 원인은 그 모델에 설비 `load-1` 이 두 번 들어 있던 것이다(id 는 트윈 안에서 유일해야
|
|
51
|
-
* 한다).
|
|
51
|
+
* 한다). 알리지 않고 하나만 남기지 않는다 — 그것은 모델링 오류를 감추는 일이고, 어느 쪽이 맞는지 우리는
|
|
52
52
|
* 모른다.
|
|
53
53
|
*/
|
|
54
54
|
const dupOf = (list: any[] | undefined, what: string): string | undefined => {
|
|
@@ -117,7 +117,7 @@ export async function projectStructure(domainId: string, instanceId: string, mod
|
|
|
117
117
|
parallelism: l.parallelism ?? null,
|
|
118
118
|
area: area ? ({ id: area.id } as any) : null,
|
|
119
119
|
gs1Id: l.gs1Id ?? null,
|
|
120
|
-
/* 자리의 속성도 옮긴다 — 옮기지 않으면 계약전력·요금이 항목 패널에서 사라진다(
|
|
120
|
+
/* 자리의 속성도 옮긴다 — 옮기지 않으면 계약전력·요금이 항목 패널에서 사라진다(들어온 것이 없는 누락). */
|
|
121
121
|
properties: l.properties ?? null,
|
|
122
122
|
sourceRef,
|
|
123
123
|
ingestedAt
|
|
@@ -149,7 +149,8 @@ export async function projectStructure(domainId: string, instanceId: string, mod
|
|
|
149
149
|
homeLocation: home ? ({ id: home.id } as any) : null,
|
|
150
150
|
mtbfMs: m.mtbfMs ?? null,
|
|
151
151
|
mttrMs: m.mttrMs ?? null,
|
|
152
|
-
|
|
152
|
+
/* 선언된 정체성 — 예전에는 선언에 없는 `gs1Id` 를 읽어 이 칸이 늘 비어 있었다. */
|
|
153
|
+
identity: (m as any).identity ?? null,
|
|
153
154
|
sourceRef,
|
|
154
155
|
ingestedAt
|
|
155
156
|
} as any)
|
|
@@ -173,7 +174,7 @@ export async function projectStructure(domainId: string, instanceId: string, mod
|
|
|
173
174
|
intent: o.intent ?? null,
|
|
174
175
|
locationType: o.locationType ?? null,
|
|
175
176
|
resourceType: o.resourceType ?? null,
|
|
176
|
-
/* 소요시간은 ISO 8601 문자열이 정본 — 분으로
|
|
177
|
+
/* 소요시간은 ISO 8601 문자열이 정본 — 분으로 줄이면 초가 오류 없이 사라진다. */
|
|
177
178
|
duration: o.duration ?? null,
|
|
178
179
|
variability: o.variability ?? null,
|
|
179
180
|
parameters: o.parameters ?? null,
|
|
@@ -14,7 +14,7 @@ import { TwinLocation } from './twin-location.js'
|
|
|
14
14
|
*
|
|
15
15
|
* ── 테이블 이름을 명시한다 ──────────────────────────────────────────────────
|
|
16
16
|
* `equipment` 는 영어에서 **불가산**이라 자동 복수화가 다른 표들과 규칙이 어긋난다
|
|
17
|
-
* (`twin_locations` 인데 `twin_equipment`).
|
|
17
|
+
* (`twin_locations` 인데 `twin_equipment`). 들어온 것이 없는 비일관은 나중에 "왜 이것만 다르지" 를
|
|
18
18
|
* 만들므로 이름을 고정한다(ADR-0032-I).
|
|
19
19
|
*/
|
|
20
20
|
@Entity({ name: 'twin_equipment' })
|
|
@@ -97,7 +97,7 @@ export class TwinEquipment {
|
|
|
97
97
|
* 그 시험들의 **결과** — 자격이 성립하는지는 이것이 말한다.
|
|
98
98
|
*
|
|
99
99
|
* 참조만 있으면 "무엇으로 검증한다" 까지다. 오늘 이 저장소에서 네 번 나온 결손과 같은 부류이므로
|
|
100
|
-
* 행에 자리를 함께 만든다 — 모델에는 있는데 행에 없으면 화면이
|
|
100
|
+
* 행에 자리를 함께 만든다 — 모델에는 있는데 행에 없으면 화면이 알리지 않고 잃는다.
|
|
101
101
|
*/
|
|
102
102
|
@Column({ type: 'simple-json', nullable: true })
|
|
103
103
|
@Field(type => ScalarObject, { nullable: true, description: 'Results of those tests (pass/fail with dates). Declared by the source — the twin does not produce them.' })
|
|
@@ -127,9 +127,21 @@ export class TwinEquipment {
|
|
|
127
127
|
@Field(type => Int, { nullable: true, description: 'Declared mean time to repair in ms.' })
|
|
128
128
|
mttrMs?: number
|
|
129
129
|
|
|
130
|
+
/*
|
|
131
|
+
* ── **선언된 설비 정체성** (2026-08-30) ───────────────────────────────────
|
|
132
|
+
*
|
|
133
|
+
* 예전 이름은 `gs1Id` 였고, 투영이 선언의 `m.gs1Id` 를 읽었다. **그런 필드가 선언에 없다** — 그래서
|
|
134
|
+
* 이 칸은 일곱 대 모두 영원히 비어 있었다. 자리는 있고 길이 없었다.
|
|
135
|
+
*
|
|
136
|
+
* 그 사이 커널에 `TwinModelDef.equipment[].identity` 를 열었으므로 어휘가 두 벌이 됐다. 하나로
|
|
137
|
+
* 합친다. 이름을 `identity` 로 두는 이유는 **GS1 키가 아닌 정체성이 정상**이기 때문이다 —
|
|
138
|
+
* 실측한 값은 인버터의 하드웨어 식별자(`ES100000007d8d061d-1`)이고 GS1 키가 아니다.
|
|
139
|
+
*
|
|
140
|
+
* 자리(`twin_location`)의 `gs1Id` 는 그대로 둔다. 그쪽은 실제로 SGLN 이 온다.
|
|
141
|
+
*/
|
|
130
142
|
@Column({ nullable: true })
|
|
131
|
-
@Field({ nullable: true, description: '
|
|
132
|
-
|
|
143
|
+
@Field({ nullable: true, description: 'Declared global identity of this equipment (TwinModelDef.equipment[].identity). Not necessarily a GS1 key.' })
|
|
144
|
+
identity?: string
|
|
133
145
|
|
|
134
146
|
/* ── 캐시라는 사실을 구조로 (ADR-0032-D) ── */
|
|
135
147
|
@Column()
|
|
@@ -52,11 +52,22 @@ export class TwinLineageQuery {
|
|
|
52
52
|
* 변환 이벤트만 읽는다. **최신부터** 읽는다 — 계보를 묻는 개체는 대개 최근에 만들어진 것이고,
|
|
53
53
|
* 창을 넘겨 잘릴 때 잃는 쪽이 오래된 것이어야 덜 아프다.
|
|
54
54
|
*/
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
/*
|
|
56
|
+
* 관계를 **컬럼으로** 묻는다 (2026-08-28). `find({ where: { domain: { id } } })` 은 관계를 가진
|
|
57
|
+
* 엔티티에서 두 단계 질의가 되고 **안쪽에 상한이 없다** — `take` 가 있어도 조건에 맞는 행을 전부
|
|
58
|
+
* 만든 뒤 밖에서 자른다. 변환 사건이 적은 트윈에서는 표가 안 나지만, 변환을 많이 내는 트윈에서는
|
|
59
|
+
* 이 한 번이 그 종류 전체를 만든다. 질의 빌더로 물으면 상한이 안쪽에 걸린다.
|
|
60
|
+
*
|
|
61
|
+
* 종류가 정확일치이므로 `(domain, instance, event_type, event_time)` 색인이 시각 순서까지 준다.
|
|
62
|
+
*/
|
|
63
|
+
const rows: any[] = await getRepository(TwinEvent)
|
|
64
|
+
.createQueryBuilder('e')
|
|
65
|
+
.where('e.domain = :domainId', { domainId })
|
|
66
|
+
.andWhere('e.instanceId = :instanceId', { instanceId })
|
|
67
|
+
.andWhere('e.eventType = :eventType', { eventType: 'epcis.TransformationEvent' })
|
|
68
|
+
.orderBy('e.eventTime', 'DESC')
|
|
69
|
+
.limit(windowCap)
|
|
70
|
+
.getMany()
|
|
60
71
|
const truncated = rows.length >= windowCap
|
|
61
72
|
|
|
62
73
|
/* 산출 → 그 변환. 한 개체는 한 번만 만들어지지만, 데이터가 그렇지 않을 수 있으므로 목록으로 든다. */
|
|
@@ -115,7 +115,7 @@ export class TwinLocation {
|
|
|
115
115
|
* ── 왜 늦게 생겼나 (2026-08-18) ────────────────────────────────────────────
|
|
116
116
|
* 설비 행에는 이 칸이 있었는데 자리 행에는 없었다. 그래서 수전 지점에 계약전력·요금을 넣어도 **항목
|
|
117
117
|
* 패널의 「원본이 말한 값」에 그 줄이 아예 없었다** — 사용자는 값을 넣고도 화면에서 찾을 수 없었고,
|
|
118
|
-
* 「이 값이 무엇을 바꾸나」는 문장도 붙을 자리가 없었다(
|
|
118
|
+
* 「이 값이 무엇을 바꾸나」는 문장도 붙을 자리가 없었다(들어온 것이 없는 누락).
|
|
119
119
|
*/
|
|
120
120
|
@Column({ type: 'simple-json', nullable: true })
|
|
121
121
|
@Field(type => ScalarObject, { nullable: true, description: 'Properties declared on this location (ISA-95 Property: value + dataType + unit of measure). Carries locally-declared numbers too, with source: local.' })
|
|
@@ -17,7 +17,7 @@ import { TwinArea } from '../twin-space/twin-area.js'
|
|
|
17
17
|
import { at, idOf, nameIndex, namesFor } from './name-index.js'
|
|
18
18
|
|
|
19
19
|
/* 커널 런타임 로드 — 축·관계·속성 선언의 SSOT. 이 파일은 도메인 모양을 알지 않는다. */
|
|
20
|
-
const { TWIN_AXES, TWIN_RELATIONS, axisInfo, axisSource, documentPath, relationsFrom, relationsTo, propertiesOf } = require('@operato/
|
|
20
|
+
const { TWIN_AXES, TWIN_RELATIONS, axisInfo, axisSource, documentPath, relationsFrom, relationsTo, propertiesOf } = require('@operato/ops-contract')
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* 축 → 그 축이 이미 **행으로 옮겨졌나**, 그리고 행의 어느 컬럼이 id 인가.
|
|
@@ -54,7 +54,7 @@ function matches(o: any, q: string): boolean {
|
|
|
54
54
|
* 그래서 야드의 도크도어나 에너지의 계량기가 늘어도 여기 손댈 것이 없다(ADR-0031). 이 파일에
|
|
55
55
|
* 도메인 이름이 한 번도 나오지 않는 것이 그 증거다.
|
|
56
56
|
*
|
|
57
|
-
* ──
|
|
57
|
+
* ── 알리지 않고 자르지 않는다 ──────────────────────────────────────────────────────
|
|
58
58
|
* 목록은 항상 **총 건수**와 함께 온다. 그리고 어떻게 셌는지(`basis`)를 밝힌다 — 행이면 DB 가
|
|
59
59
|
* 페이징했고, 문서면 서버가 문서를 통째로 읽어 잘라 냈다. 후자는 규모에서 한계가 되므로 그 사실이
|
|
60
60
|
* 화면에 드러나야 이주 압력이 살아 있다.
|
|
@@ -118,7 +118,7 @@ export class TwinModelItemQuery {
|
|
|
118
118
|
/*
|
|
119
119
|
* 검색은 아직 DB 로 내리지 않았다. **그 사실을 밝힌다**(`basis: 'rows-scanned'`) —
|
|
120
120
|
* 흉내로 덮으면 규모가 오는 날까지 아무도 이 한계를 모른다. 훑는 건수를 상한으로 막고,
|
|
121
|
-
* 상한에 닿았으면 잘렸다고 말한다(
|
|
121
|
+
* 상한에 닿았으면 잘렸다고 말한다(알리지 않고 자르지 않는다).
|
|
122
122
|
*/
|
|
123
123
|
const SCAN_MAX = 5000
|
|
124
124
|
const repo = getRepository(row.entity)
|
|
@@ -159,11 +159,11 @@ export class TwinModelItemQuery {
|
|
|
159
159
|
* **라이브는 권위, 히스토리는 파생.**
|
|
160
160
|
*
|
|
161
161
|
* 지금 도는 커널의 상태가 이 축의 진실이다. 그런데 커널이 멈춰 있거나 사용자가 **과거 시각**을
|
|
162
|
-
* 물으면 답할 것이 없어진다 — 그때 저널을 그 시점까지
|
|
162
|
+
* 물으면 답할 것이 없어진다 — 그때 저널을 그 시점까지 계산해 답한다(`recover`). 둘은 같은 모양이지만
|
|
163
163
|
* **성질이 다르므로 `basis` 로 구별해 낸다**: 파생을 권위처럼 내면 다시 계산한 값을 보고 "지금 이렇다"
|
|
164
164
|
* 로 읽게 된다.
|
|
165
165
|
*
|
|
166
|
-
* 규모:
|
|
166
|
+
* 규모: 계산 비용은 이벤트 수에 비례한다. 감추지 않고 **어느 리비전까지 계산했는지 함께 낸다** —
|
|
167
167
|
* 이 화면이 목록마다 `basis` 를 밝혀 온 규율 그대로다.
|
|
168
168
|
*/
|
|
169
169
|
const live = TwinEngine.isRunning(domainId, instanceId) && !at_
|
|
@@ -341,9 +341,9 @@ export class TwinModelItemQuery {
|
|
|
341
341
|
*/
|
|
342
342
|
if (axisSource(axis) === 'state') {
|
|
343
343
|
/*
|
|
344
|
-
* 동작하지 않으면 **목록과 같은 길로 저널을
|
|
344
|
+
* 동작하지 않으면 **목록과 같은 길로 저널을 계산한다.**
|
|
345
345
|
*
|
|
346
|
-
* 목록만
|
|
346
|
+
* 목록만 계산하고 상세는 안 계산했더니, 목록에는 472건이 보이는데 그 줄을 열면 "자기 속성이 없습니다"
|
|
347
347
|
* 가 나왔다 — 한 화면에서 두 답이 갈리면 어느 쪽이 맞는지 사용자가 알 수 없다.
|
|
348
348
|
*/
|
|
349
349
|
const liveItem = TwinEngine.isRunning(domainId, instanceId)
|
|
@@ -471,7 +471,7 @@ export class TwinModelItemQuery {
|
|
|
471
471
|
observed,
|
|
472
472
|
/*
|
|
473
473
|
* 관측 열이 **자기 근거를 말한다** — 목록의 그 낱말 그대로(`state`=라이브 권위, `journal`=다시 계산한
|
|
474
|
-
* 파생). 없으면 비교하지 못한 것이다. 파생이면 몇 번째 리비전까지
|
|
474
|
+
* 파생). 없으면 비교하지 못한 것이다. 파생이면 몇 번째 리비전까지 계산했는지 함께 낸다.
|
|
475
475
|
*/
|
|
476
476
|
...('value' in seen
|
|
477
477
|
? { observedBasis: seen.basis, ...(seen.foldedRevision != null ? { observedRevision: seen.foldedRevision } : {}) }
|
|
@@ -631,8 +631,8 @@ export class TwinModelItemQuery {
|
|
|
631
631
|
*
|
|
632
632
|
* 근거를 값과 함께 낸다 — 목록이 오래 해 온 그대로다(§twinModelItemList). 라이브(권위)와 저널
|
|
633
633
|
* 폴드(파생)는 **같은 모양의 객체**라서, 근거가 없으면 다시 계산한 값을 "지금 이렇다" 로 읽는다. 근거를
|
|
634
|
-
* 실을 자리가 없던 동안에는 멈춘 트윈의 저널을 아예
|
|
635
|
-
* 자리가 있으니
|
|
634
|
+
* 실을 자리가 없던 동안에는 멈춘 트윈의 저널을 아예 계산하지 않고 `—` 로 두는 편이 정직했다. 이제
|
|
635
|
+
* 자리가 있으니 계산한다 — 멈춘 트윈에도 마지막으로 알던 사실이 있고, 그것을 감출 이유는 없다.
|
|
636
636
|
*
|
|
637
637
|
* 다시 계산할 것이 없으면(모델도 저널도 없다) `null` 이다 — **없는 것과 비교하지 못한 것은 다르다.**
|
|
638
638
|
*/
|
|
@@ -652,9 +652,9 @@ export class TwinModelItemQuery {
|
|
|
652
652
|
const rec = await TwinEngine.recover(domainId, instanceId)
|
|
653
653
|
folded = Number((rec as any)?.revision) || undefined
|
|
654
654
|
/*
|
|
655
|
-
* **이벤트를 하나도
|
|
655
|
+
* **이벤트를 하나도 계산하지 않은 폴드는 관측이 아니다.** 저널이 비어도 복원은 선언을 다시 투영한
|
|
656
656
|
* 기준선을 돌려준다 — 그것을 "트윈이 관측한 값" 열에 실으면 **선언이 관측으로 위장한다**
|
|
657
|
-
* (원본이 말한 값이 오른쪽에도 똑같이 앉아, 견준 것처럼 보인다).
|
|
657
|
+
* (원본이 말한 값이 오른쪽에도 똑같이 앉아, 견준 것처럼 보인다). 계산한 것이 없으면 없다고 한다.
|
|
658
658
|
*/
|
|
659
659
|
if (folded == null) return { absence: 'not-running' as const }
|
|
660
660
|
state = unwrapState(rec)
|
|
@@ -700,7 +700,7 @@ export class TwinModelItemQuery {
|
|
|
700
700
|
const model = inst.model ?? {}
|
|
701
701
|
|
|
702
702
|
/*
|
|
703
|
-
* 관측 축의 항목들 — **한 번만** 읽는다(관계마다 다시
|
|
703
|
+
* 관측 축의 항목들 — **한 번만** 읽는다(관계마다 다시 계산하면 저널을 여러 번 계산한다).
|
|
704
704
|
* 라이브가 있으면 그것, 없으면 저널 폴드. 없으면 빈 배열(없는 것을 지어내지 않는다).
|
|
705
705
|
*/
|
|
706
706
|
let observedState: any
|
|
@@ -725,7 +725,7 @@ export class TwinModelItemQuery {
|
|
|
725
725
|
*
|
|
726
726
|
* 관계 선언의 필드 이름(`locations.parentId`)은 **원본 문서의 어휘**다. 행은 같은 사실을 자기
|
|
727
727
|
* 컬럼 이름으로 담는다(자리의 구역은 `area` FK). 행을 보고 `parentId` 를 찾으면 늘 비어서
|
|
728
|
-
* "이어진 것이 없다" 로
|
|
728
|
+
* "이어진 것이 없다" 로 알리지 않고 답한다 — 실제로 그랬다.
|
|
729
729
|
*
|
|
730
730
|
* 어느 쪽이 정본인가로 구분하면 답이 분명하다: 관계를 선언한 어휘가 문서 어휘이므로 **문서에서
|
|
731
731
|
* 푼다.** 행에만 있고 문서에 없는 항목(있을 수 있다)은 이어진 것이 비지만, 그것은 사실이다.
|
|
@@ -762,7 +762,7 @@ export class TwinModelItemQuery {
|
|
|
762
762
|
const repo = getRepository(row.entity)
|
|
763
763
|
/*
|
|
764
764
|
* **FK 는 부르지 않으면 오지 않는다.** 관계 필드를 로딩하지 않고 조회하면 값이 늘 `undefined`
|
|
765
|
-
* 라서 "나를 가리키는 것이 하나도 없다" 로
|
|
765
|
+
* 라서 "나를 가리키는 것이 하나도 없다" 로 알리지 않고 답한다 — 실제로 그랬다(설비 둘이 이 자리를
|
|
766
766
|
* 기준으로 삼는데 이웃이 비어 있었다).
|
|
767
767
|
*
|
|
768
768
|
* 어느 필드가 관계인지는 **엔티티 메타데이터**가 안다. 축마다 표를 두면 축이 늘 때마다
|
|
@@ -71,7 +71,7 @@ async function spreadSpaceLayer(
|
|
|
71
71
|
t.localDeclarations = out.instanceLayerApplied as any
|
|
72
72
|
const running = TwinEngine.modeOf(domainId, t.instanceId)
|
|
73
73
|
/*
|
|
74
|
-
* **트윈 하나가 실패해도 나머지는 받는다** — 다만
|
|
74
|
+
* **트윈 하나가 실패해도 나머지는 받는다** — 다만 알리지 않고 넘기지 않는다(2026-08-18 실측).
|
|
75
75
|
*
|
|
76
76
|
* 현장 선언을 처음 퍼뜨렸을 때 그 현장의 어떤 트윈에서 구조 투영이 터졌고(그 트윈 모델에 설비 id가
|
|
77
77
|
* 겹쳐 있었다 — 선재 결함), 그 예외가 올라와 **한 트윈 때문에 현장 전체 선언이 실패**했다. 사용자는
|
|
@@ -132,12 +132,12 @@ export class TwinModelMutation {
|
|
|
132
132
|
* 계량이 흐르는 트윈에서도 **금액이 영원히 나오지 않았다** — 넣을 문이 없었기 때문이다.
|
|
133
133
|
*
|
|
134
134
|
* 값은 `model` 에 직접 쓰지 않고 **겹**으로 보관한다: 모델은 원천의 사본이므로 다시 읽기가 그것을
|
|
135
|
-
* 새로 그리면 직접 쓴 값은
|
|
135
|
+
* 새로 그리면 직접 쓴 값은 오류 없이 사라진다. 겹은 모델을 그릴 때마다 다시 얹힌다.
|
|
136
136
|
*
|
|
137
137
|
* ── 돌고 있는 트윈에 어떻게 반영하나 ────────────────────────────────────────
|
|
138
138
|
* 미러는 **동작 중에** 새 구조를 받는다(현실은 멈추지 않는다). 시뮬레이션은 받지 않는다 — 조건이
|
|
139
139
|
* 바뀐 실험은 다른 실험이고, 커널이 그렇게 거절한다. 그때는 저장만 하고 **그 사실을 말한다**:
|
|
140
|
-
*
|
|
140
|
+
* 알리지 않고 성공으로 답하면 사용자는 지금 화면의 수가 새 선언으로 계산된 줄로 읽는다.
|
|
141
141
|
*/
|
|
142
142
|
@Directive('@privilege(category: "twin", privilege: "mutation", domainOwnerGranted: true, superUserGranted: true)')
|
|
143
143
|
@Mutation(returns => ScalarObject, {
|
|
@@ -165,7 +165,7 @@ export class TwinModelMutation {
|
|
|
165
165
|
if (!declarations?.length) return { ok: false, error: 'no declaration arrived — the declarations argument was empty' }
|
|
166
166
|
|
|
167
167
|
/*
|
|
168
|
-
* 검사부터 — 받지 않은 것을
|
|
168
|
+
* 검사부터 — 받지 않은 것을 알리지 않고 버리지 않는다(사용자는 값을 넣었다고 믿는다).
|
|
169
169
|
*
|
|
170
170
|
* 공정 이름은 **대조로만** 걸러진다(모델에 행이 없어도 성립하는 선언이라 다른 안전망이 없다). 아직
|
|
171
171
|
* 돌지도 않고 명세 행도 없는 트윈이면 목록이 `undefined` 이고, 그때는 받아 주되 답에 그 사실을 싣는다.
|