@things-factory/headless-twin 10.0.11 → 10.0.13
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/canonical-ingest.d.ts +81 -3
- package/dist-server/engine/canonical-ingest.js +89 -10
- 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.d.ts +43 -0
- package/dist-server/engine/declared-stimulus.js +57 -0
- package/dist-server/engine/declared-stimulus.js.map +1 -0
- package/dist-server/engine/index.d.ts +5 -0
- package/dist-server/engine/index.js +6 -0
- package/dist-server/engine/index.js.map +1 -1
- package/dist-server/engine/ingest-health.d.ts +335 -0
- package/dist-server/engine/ingest-health.js +434 -0
- package/dist-server/engine/ingest-health.js.map +1 -0
- package/dist-server/engine/integration-coverage.d.ts +76 -0
- package/dist-server/engine/integration-coverage.js +73 -0
- package/dist-server/engine/integration-coverage.js.map +1 -0
- package/dist-server/engine/integration-probes.d.ts +65 -0
- package/dist-server/engine/integration-probes.js +100 -0
- package/dist-server/engine/integration-probes.js.map +1 -0
- package/dist-server/engine/integration-runner.d.ts +45 -0
- package/dist-server/engine/integration-runner.js +59 -0
- package/dist-server/engine/integration-runner.js.map +1 -0
- package/dist-server/engine/integration-target-profile.d.ts +57 -0
- package/dist-server/engine/integration-target-profile.js +79 -0
- package/dist-server/engine/integration-target-profile.js.map +1 -0
- package/dist-server/engine/kpi-fold.d.ts +39 -0
- package/dist-server/engine/kpi-fold.js +68 -5
- package/dist-server/engine/kpi-fold.js.map +1 -1
- package/dist-server/engine/kpi-query.d.ts +3 -3
- package/dist-server/engine/kpi-query.js +132 -18
- 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 +3 -17
- 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 +12 -3
- package/dist-server/engine/load-meter.js.map +1 -1
- package/dist-server/engine/local-declarations.d.ts +3 -6
- package/dist-server/engine/local-declarations.js +97 -16
- package/dist-server/engine/local-declarations.js.map +1 -1
- package/dist-server/engine/log.d.ts +18 -0
- package/dist-server/engine/log.js +80 -0
- package/dist-server/engine/log.js.map +1 -0
- package/dist-server/engine/loop-lag.d.ts +54 -0
- package/dist-server/engine/loop-lag.js +87 -0
- package/dist-server/engine/loop-lag.js.map +1 -0
- package/dist-server/engine/measured-yield.d.ts +42 -0
- package/dist-server/engine/measured-yield.js +75 -0
- package/dist-server/engine/measured-yield.js.map +1 -0
- package/dist-server/engine/model-gap.d.ts +108 -0
- package/dist-server/engine/model-gap.js +95 -0
- package/dist-server/engine/model-gap.js.map +1 -0
- package/dist-server/engine/operation-basis.d.ts +16 -0
- package/dist-server/engine/operation-basis.js +20 -2
- package/dist-server/engine/operation-basis.js.map +1 -1
- package/dist-server/engine/property-effects.js +17 -0
- package/dist-server/engine/property-effects.js.map +1 -1
- package/dist-server/engine/restart-policy.d.ts +13 -0
- package/dist-server/engine/restart-policy.js +52 -0
- package/dist-server/engine/restart-policy.js.map +1 -0
- 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 +8 -0
- package/dist-server/engine/spec-coverage.js +3 -1
- package/dist-server/engine/spec-coverage.js.map +1 -1
- package/dist-server/engine/stage-path.d.ts +83 -0
- package/dist-server/engine/stage-path.js +118 -0
- package/dist-server/engine/stage-path.js.map +1 -0
- package/dist-server/engine/twin-engine.d.ts +400 -31
- package/dist-server/engine/twin-engine.js +1198 -187
- package/dist-server/engine/twin-engine.js.map +1 -1
- package/dist-server/index.js +35 -3
- package/dist-server/index.js.map +1 -1
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.d.ts +5 -0
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js +58 -0
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +1 -0
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.d.ts +5 -0
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js +55 -0
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +1 -0
- package/dist-server/migrations/index.js +7 -1
- package/dist-server/migrations/index.js.map +1 -1
- package/dist-server/service/index.d.ts +5 -2
- package/dist-server/service/index.js +18 -7
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/reference/control-routing.d.ts +14 -0
- package/dist-server/service/reference/control-routing.js +64 -0
- package/dist-server/service/reference/control-routing.js.map +1 -0
- package/dist-server/service/reference/discovery-result.d.ts +1 -1
- package/dist-server/service/reference/discovery-result.js +1 -1
- package/dist-server/service/reference/discovery-result.js.map +1 -1
- package/dist-server/service/reference/index.d.ts +5 -1
- package/dist-server/service/reference/index.js +8 -1
- package/dist-server/service/reference/index.js.map +1 -1
- package/dist-server/service/reference/reference-adapter.d.ts +251 -3
- package/dist-server/service/reference/reference-adapter.js +43 -1
- package/dist-server/service/reference/reference-adapter.js.map +1 -1
- package/dist-server/service/reference/reference-assessment.d.ts +68 -0
- package/dist-server/service/reference/reference-assessment.js +136 -0
- package/dist-server/service/reference/reference-assessment.js.map +1 -0
- package/dist-server/service/reference/reference-live.d.ts +12 -1
- package/dist-server/service/reference/reference-live.js +119 -14
- package/dist-server/service/reference/reference-live.js.map +1 -1
- package/dist-server/service/reference/reference-master.d.ts +47 -1
- package/dist-server/service/reference/reference-master.js +34 -4
- package/dist-server/service/reference/reference-master.js.map +1 -1
- package/dist-server/service/reference/reference-probe.d.ts +92 -0
- package/dist-server/service/reference/reference-probe.js +186 -0
- package/dist-server/service/reference/reference-probe.js.map +1 -0
- package/dist-server/service/reference/reference-progress-subscription.d.ts +17 -0
- package/dist-server/service/reference/reference-progress-subscription.js +94 -0
- package/dist-server/service/reference/reference-progress-subscription.js.map +1 -0
- package/dist-server/service/reference/reference-progress.d.ts +38 -0
- package/dist-server/service/reference/reference-progress.js +71 -0
- package/dist-server/service/reference/reference-progress.js.map +1 -0
- package/dist-server/service/reference/reference-resolver.d.ts +3 -3
- package/dist-server/service/reference/reference-resolver.js +242 -58
- package/dist-server/service/reference/reference-resolver.js.map +1 -1
- package/dist-server/service/reference/twin-reference.d.ts +32 -0
- package/dist-server/service/reference/twin-reference.js +10 -0
- package/dist-server/service/reference/twin-reference.js.map +1 -1
- package/dist-server/service/twin-audit/command-audit.d.ts +34 -0
- package/dist-server/service/twin-audit/command-audit.js +15 -1
- package/dist-server/service/twin-audit/command-audit.js.map +1 -1
- package/dist-server/service/twin-audit/twin-audit-event.d.ts +3 -0
- package/dist-server/service/twin-audit/twin-audit-event.js +10 -0
- package/dist-server/service/twin-audit/twin-audit-event.js.map +1 -1
- package/dist-server/service/twin-control/twin-control-mutation.d.ts +15 -2
- package/dist-server/service/twin-control/twin-control-mutation.js +88 -36
- package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
- package/dist-server/service/twin-event/journal-count.d.ts +21 -0
- package/dist-server/service/twin-event/journal-count.js +26 -0
- package/dist-server/service/twin-event/journal-count.js.map +1 -0
- package/dist-server/service/twin-event/twin-event-keys.d.ts +9 -0
- package/dist-server/service/twin-event/twin-event-keys.js +15 -18
- package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
- package/dist-server/service/twin-event/twin-event-type.d.ts +3 -1
- package/dist-server/service/twin-event/twin-event-type.js +18 -1
- package/dist-server/service/twin-event/twin-event-type.js.map +1 -1
- package/dist-server/service/twin-event/twin-event.d.ts +1 -0
- package/dist-server/service/twin-event/twin-event.js +9 -1
- package/dist-server/service/twin-event/twin-event.js.map +1 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js +2 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
- package/dist-server/service/twin-ingest-window/index.d.ts +5 -0
- package/dist-server/service/twin-ingest-window/index.js +10 -0
- package/dist-server/service/twin-ingest-window/index.js.map +1 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.d.ts +12 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js +123 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +1 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.d.ts +1 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js +51 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +1 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window.d.ts +16 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window.js +108 -0
- package/dist-server/service/twin-ingest-window/twin-ingest-window.js.map +1 -0
- package/dist-server/service/twin-instance/twin-instance.d.ts +1 -1
- package/dist-server/service/twin-instance/twin-instance.js +2 -2
- package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
- package/dist-server/service/twin-journal/twin-journal-query.js +58 -5
- package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +14 -0
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +74 -3
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.d.ts +1 -0
- package/dist-server/service/twin-metrics/twin-metrics-query.js +78 -3
- package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
- package/dist-server/service/twin-model/axis-journal-evidence.d.ts +2 -0
- package/dist-server/service/twin-model/axis-journal-evidence.js +89 -0
- package/dist-server/service/twin-model/axis-journal-evidence.js.map +1 -0
- package/dist-server/service/twin-model/epcis-coverage.d.ts +1 -1
- package/dist-server/service/twin-model/epcis-coverage.js +19 -7
- package/dist-server/service/twin-model/epcis-coverage.js.map +1 -1
- package/dist-server/service/twin-model/iec61850-coverage.d.ts +1 -1
- package/dist-server/service/twin-model/iec61850-coverage.js +18 -7
- package/dist-server/service/twin-model/iec61850-coverage.js.map +1 -1
- package/dist-server/service/twin-model/isa95-coverage.d.ts +14 -0
- package/dist-server/service/twin-model/isa95-coverage.js +23 -9
- package/dist-server/service/twin-model/isa95-coverage.js.map +1 -1
- package/dist-server/service/twin-model/item-ref.d.ts +24 -0
- package/dist-server/service/twin-model/item-ref.js +88 -0
- package/dist-server/service/twin-model/item-ref.js.map +1 -0
- package/dist-server/service/twin-model/name-index.d.ts +36 -0
- package/dist-server/service/twin-model/name-index.js +116 -0
- package/dist-server/service/twin-model/name-index.js.map +1 -0
- package/dist-server/service/twin-model/project-structure.js +1 -1
- package/dist-server/service/twin-model/project-structure.js.map +1 -1
- package/dist-server/service/twin-model/status-tally.d.ts +9 -0
- package/dist-server/service/twin-model/status-tally.js +37 -0
- package/dist-server/service/twin-model/status-tally.js.map +1 -0
- package/dist-server/service/twin-model/twin-lineage-query.js +40 -12
- package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-item-query.js +38 -39
- package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-query.js +157 -5
- package/dist-server/service/twin-model/twin-model-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-tree-query.js +7 -0
- package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -1
- package/dist-server/service/twin-readiness/index.d.ts +2 -0
- package/dist-server/service/twin-readiness/index.js +6 -0
- package/dist-server/service/twin-readiness/index.js.map +1 -0
- package/dist-server/service/twin-readiness/twin-readiness-query.d.ts +3 -0
- package/dist-server/service/twin-readiness/twin-readiness-query.js +103 -0
- package/dist-server/service/twin-readiness/twin-readiness-query.js.map +1 -0
- package/dist-server/service/twin-space/twin-space-resolver.d.ts +2 -2
- package/dist-server/service/twin-space/twin-space-resolver.js +5 -4
- package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
- package/dist-shared/entity-delta.d.ts +23 -3
- package/dist-shared/entity-delta.js +12 -8
- package/dist-shared/entity-delta.js.map +1 -1
- package/dist-shared/kpi-broadcast.js +1 -1
- package/dist-shared/kpi-broadcast.js.map +1 -1
- package/dist-shared/touched-items.d.ts +7 -0
- package/dist-shared/touched-items.js +80 -0
- package/dist-shared/touched-items.js.map +1 -0
- package/package.json +7 -7
- package/server/engine/canonical-ingest.ts +164 -15
- package/server/engine/command-routing.ts +1 -1
- package/server/engine/declared-stimulus.ts +66 -0
- package/server/engine/index.ts +6 -0
- package/server/engine/ingest-health.ts +704 -0
- package/server/engine/integration-coverage.ts +147 -0
- package/server/engine/integration-probes.ts +144 -0
- package/server/engine/integration-runner.ts +95 -0
- package/server/engine/integration-target-profile.ts +103 -0
- package/server/engine/kpi-fold.ts +101 -5
- package/server/engine/kpi-query.ts +137 -23
- package/server/engine/live-feed-registry.ts +4 -3
- package/server/engine/load-meter.ts +12 -3
- package/server/engine/local-declarations.ts +97 -19
- package/server/engine/log.ts +72 -0
- package/server/engine/loop-lag.ts +120 -0
- package/server/engine/measured-yield.ts +89 -0
- package/server/engine/model-gap.ts +168 -0
- package/server/engine/operation-basis.ts +33 -2
- package/server/engine/property-effects.ts +17 -0
- package/server/engine/restart-policy.ts +55 -0
- package/server/engine/runtime-key.ts +1 -1
- package/server/engine/spec-coverage.ts +23 -3
- package/server/engine/stage-path.ts +172 -0
- package/server/engine/twin-engine.ts +1318 -186
- package/server/index.ts +36 -3
- package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +54 -0
- package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +53 -0
- package/server/migrations/index.ts +7 -1
- package/server/service/index.ts +11 -0
- package/server/service/reference/control-routing.ts +62 -0
- package/server/service/reference/discovery-result.ts +1 -1
- package/server/service/reference/index.ts +7 -1
- package/server/service/reference/reference-adapter.ts +275 -5
- package/server/service/reference/reference-assessment.ts +215 -0
- package/server/service/reference/reference-live.ts +126 -14
- package/server/service/reference/reference-master.ts +64 -4
- package/server/service/reference/reference-probe.ts +264 -0
- package/server/service/reference/reference-progress-subscription.ts +73 -0
- package/server/service/reference/reference-progress.ts +95 -0
- package/server/service/reference/reference-resolver.ts +246 -19
- package/server/service/reference/twin-reference.ts +39 -1
- package/server/service/twin-audit/command-audit.ts +34 -1
- package/server/service/twin-audit/twin-audit-event.ts +20 -0
- package/server/service/twin-control/twin-control-mutation.ts +78 -30
- package/server/service/twin-event/journal-count.ts +53 -0
- package/server/service/twin-event/twin-event-keys.ts +16 -1
- package/server/service/twin-event/twin-event-type.ts +26 -2
- package/server/service/twin-event/twin-event.ts +7 -0
- package/server/service/twin-forecast/twin-forecast-query.ts +2 -1
- package/server/service/twin-ingest-window/index.ts +7 -0
- package/server/service/twin-ingest-window/twin-ingest-window-query.ts +125 -0
- package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +57 -0
- package/server/service/twin-ingest-window/twin-ingest-window.ts +113 -0
- package/server/service/twin-instance/twin-instance.ts +16 -10
- package/server/service/twin-journal/twin-journal-query.ts +59 -5
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +79 -4
- package/server/service/twin-metrics/twin-metrics-query.ts +81 -3
- package/server/service/twin-model/axis-journal-evidence.ts +57 -0
- package/server/service/twin-model/epcis-coverage.ts +2 -8
- package/server/service/twin-model/iec61850-coverage.ts +2 -8
- package/server/service/twin-model/isa95-coverage.ts +22 -9
- package/server/service/twin-model/item-ref.ts +80 -0
- package/server/service/twin-model/name-index.ts +94 -0
- package/server/service/twin-model/project-structure.ts +1 -1
- package/server/service/twin-model/status-tally.ts +37 -0
- package/server/service/twin-model/twin-lineage-query.ts +38 -9
- package/server/service/twin-model/twin-model-item-query.ts +26 -27
- package/server/service/twin-model/twin-model-query.ts +156 -5
- package/server/service/twin-model/twin-model-tree-query.ts +7 -0
- package/server/service/twin-readiness/index.ts +3 -0
- package/server/service/twin-readiness/twin-readiness-query.ts +96 -0
- package/server/service/twin-space/twin-space-resolver.ts +5 -4
- package/shared/entity-delta.ts +31 -7
- package/shared/kpi-broadcast.ts +1 -1
- package/shared/touched-items.ts +73 -0
- package/test/adopt-structure-live.test.ts +7 -7
- package/test/axis-journal-evidence.test.ts +71 -0
- package/test/axis-read.test.ts +101 -1
- package/test/boot-resume.test.ts +93 -27
- package/test/broadcast-cost-baseline.test.ts +200 -0
- package/test/broadcast-period.test.ts +58 -0
- package/test/canonical-ingest-vocabularies.test.ts +36 -1
- package/test/canonical-quantity-door.test.ts +61 -0
- package/test/command-routing.test.ts +1 -1
- package/test/control-capability.test.ts +103 -0
- package/test/declared-location-types.test.ts +89 -0
- package/test/declared-stimulus.test.ts +88 -0
- package/test/discovery-result.test.ts +1 -1
- package/test/duration-estimators.test.ts +1 -1
- package/test/entity-delta.test.ts +2 -2
- package/test/ingest-bench.test.ts +3 -3
- package/test/ingest-health-engine.test.ts +248 -0
- package/test/ingest-health-wiring.test.ts +119 -0
- package/test/ingest-health.test.ts +306 -0
- package/test/ingest-history.test.ts +247 -0
- package/test/ingest-running-guard.test.ts +5 -5
- package/test/instance-cache-lifecycle.test.ts +1 -1
- package/test/integration-probes.test.ts +103 -0
- package/test/integration-runner.test.ts +95 -0
- package/test/item-ref.test.ts +78 -0
- package/test/journal-read-discipline.test.ts +177 -0
- package/test/journal-retention.test.ts +133 -0
- package/test/journal-sort-axis.test.ts +142 -0
- package/test/journal-write-door.test.ts +110 -0
- package/test/journal-write-trend.test.ts +115 -0
- package/test/kernel-kind-guard.test.ts +4 -4
- package/test/kpi-baseline-db.test.ts +1 -1
- package/test/kpi-fold.test.ts +90 -3
- package/test/kpi-query-bench.test.ts +3 -3
- package/test/lineage-survives-restart.test.ts +20 -4
- package/test/live-cursor-wiring.test.ts +87 -0
- package/test/live-feed-registry.test.ts +15 -7
- package/test/live-kernel-facts.test.ts +7 -7
- package/test/live-mirror-parity.test.ts +6 -0
- package/test/load-meter.test.ts +29 -15
- package/test/local-declarations.test.ts +109 -2
- package/test/log-stamp.test.ts +59 -0
- package/test/loop-lag.test.ts +82 -0
- package/test/measured-yield.test.ts +90 -0
- package/test/model-gap.test.ts +153 -0
- package/test/oee-accumulator.test.ts +4 -0
- package/test/operation-basis.test.ts +28 -1
- package/test/operational-vocabulary.test.ts +108 -0
- package/test/operations-capability-db.test.ts +4 -4
- package/test/project-structure-db.test.ts +1 -1
- package/test/projection-reaches-screen.test.ts +1 -1
- package/test/property-effects.test.ts +28 -0
- package/test/read-failure-visible.test.ts +145 -0
- package/test/reference-grounding.test.ts +70 -0
- package/test/resolve-ts-siblings.mjs +52 -0
- package/test/restart-policy.test.ts +111 -0
- package/test/resync-origin-site.test.ts +7 -1
- package/test/revision-axis.test.ts +93 -0
- package/test/runtime-key.test.ts +2 -2
- package/test/scale-twin-bench.test.ts +2 -2
- package/test/source-outcome-audit.test.ts +104 -0
- package/test/spec-coverage.test.ts +1 -1
- package/test/stage-path.test.ts +95 -0
- package/test/standard-coverage.test.ts +15 -3
- package/test/status-tally.test.ts +55 -0
- package/test/structure-revision-db.test.ts +31 -27
- package/test/tenant-registry-db.test.ts +3 -3
- package/test/time-range.test.ts +152 -0
- package/test/touched-items.test.ts +61 -0
- package/test/twin-event-keys.test.ts +10 -2
- package/test/twin-model-item-db.test.ts +5 -3
- package/test/twin-model-tree-db.test.ts +7 -7
- package/test/twin-origin-resync.test.ts +4 -4
- package/test/warm-start-seam.test.ts +4 -0
- package/test/yield-loop.test.ts +199 -0
- package/tsconfig.shared.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"twin-model-item-query.js","sourceRoot":"","sources":["../../../server/service/twin-model/twin-model-item-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Int, Query, Resolver } from 'type-graphql'\n\nimport { ScalarObject, getRepository } from '@things-factory/shell'\n\nimport { TwinEngine } from '../../engine/index.js'\nimport { unwrapState } from '../../engine/warm-start.js'\nimport { propertyEffectsOf } from '../../engine/property-effects.js'\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinLocation } from './twin-location.js'\nimport { TwinEquipment } from './twin-equipment.js'\nimport { TwinOperation } from './twin-operation.js'\nimport { TwinArea } from '../twin-space/twin-area.js'\n\n/* 커널 런타임 로드 — 축·관계·속성 선언의 SSOT. 이 파일은 도메인 모양을 알지 않는다. */\nconst { TWIN_AXES, TWIN_RELATIONS, axisInfo, axisSource, documentPath, relationsFrom, relationsTo, propertiesOf } = require('@operato/twin-kernel')\n\n/**\n * 축 → 그 축이 이미 **행으로 옮겨졌나**, 그리고 행의 어느 컬럼이 id 인가.\n *\n * 옮겨진 축은 **DB 가 페이징하고 센다.** 아직인 축은 문서 배열을 읽어야 하고, 그 차이를 응답이\n * `basis` 로 밝힌다 — 밝히지 않으면 \"이 축은 검색이 되는데 저 축은 왜 느린가\" 를 아무도 설명할 수 없다.\n */\nconst ROW_BACKED: Record<string, { entity: any; idColumn: string; order: any }> = {\n locations: { entity: TwinLocation, idColumn: 'locationId', order: { locationId: 'ASC' } },\n equipment: { entity: TwinEquipment, idColumn: 'equipmentId', order: { equipmentId: 'ASC' } },\n operations: { entity: TwinOperation, idColumn: 'operationKey', order: { seq: 'ASC' } }\n}\n\n/** `productionSpec.definition.recipes` 같은 경로를 문서에서 따라간다. */\nconst at = (o: any, path: string) => path.split('.').reduce((a: any, k: string) => (a == null ? undefined : a[k]), o)\n\n/**\n * 문서 항목의 **식별자** — 축마다 이름이 다르다(자리는 `id`, 공정은 `key`, 레시피도 `key`).\n *\n * 도메인 모양을 코드가 아는 것이 아니라 **식별자 관례**를 아는 것이다. 후보를 순서대로 보고 첫\n * 값을 쓴다. 하나도 없으면 그 항목은 가리킬 수 없으므로 `null` — 목록에서 빼지 않고 **id 없음**으로\n * 낸다(조용히 빠지면 건수가 안 맞는다).\n */\nconst idOf = (o: any): string | null => (typeof o === 'string' ? o : o?.id ?? o?.key ?? o?.gtin ?? null)\n\n/** 검색 — 항목의 값 어디든 걸리면 맞는 것으로 본다. 축마다 검색 컬럼을 정해 두면 축이 늘 때마다 여기를 고쳐야 한다. */\nfunction matches(o: any, q: string): boolean {\n if (!q) return true\n const needle = q.toLowerCase()\n const walk = (v: any, depth: number): boolean => {\n if (v == null || depth > 3) return false\n if (typeof v === 'string' || typeof v === 'number') return String(v).toLowerCase().includes(needle)\n if (Array.isArray(v)) return v.some(x => walk(x, depth + 1))\n if (typeof v === 'object') return Object.values(v).some(x => walk(x, depth + 1))\n return false\n }\n return walk(o, 0)\n}\n\n/**\n * 항목 조회 — **개념 안의 목록**(③)과 **항목 하나의 상세**(④).\n *\n * ── 이 파일이 도메인을 알지 않는다 ─────────────────────────────────────────────\n * 어느 축이 있고 무엇을 가리키는지는 **커널 카탈로그가 선언**한다(`TWIN_AXES`·`TWIN_RELATIONS`).\n * 그래서 야드의 도크도어나 에너지의 계량기가 늘어도 여기 손댈 것이 없다(ADR-0031). 이 파일에\n * 도메인 이름이 한 번도 나오지 않는 것이 그 증거다.\n *\n * ── 조용히 자르지 않는다 ──────────────────────────────────────────────────────\n * 목록은 항상 **총 건수**와 함께 온다. 그리고 어떻게 셌는지(`basis`)를 밝힌다 — 행이면 DB 가\n * 페이징했고, 문서면 서버가 문서를 통째로 읽어 잘라 냈다. 후자는 규모에서 한계가 되므로 그 사실이\n * 화면에 드러나야 이주 압력이 살아 있다.\n */\n@Resolver()\nexport class TwinModelItemQuery {\n @Query(returns => ScalarObject, {\n nullable: true,\n description:\n 'Page through the items of one standard concept in a twin. Always returns the total and how it was counted (rows = the database paged it, document = the server read the whole document and sliced).'\n })\n async twinModelEntities(\n @Arg('instanceId') instanceId: string,\n @Arg('axis') axis: string,\n @Ctx() context: ResolverContext,\n @Arg('search', { nullable: true }) search?: string,\n @Arg('offset', type => Int, { nullable: true }) offset?: number,\n @Arg('limit', type => Int, { nullable: true }) limit?: number,\n /**\n * 어느 시각의 사실인가 — **관측 축에만 뜻이 있다.**\n *\n * 선언 축은 시간축이 없다(그 시점의 선언은 구조 리비전이 답한다). 그래서 문서 축에 이 값을 주면\n * 쓰지 않는다 — 무시했다는 사실은 응답의 `basis` 가 말한다(`document`).\n */\n @Arg('untilTime', { nullable: true }) untilTime?: string\n ): Promise<any | null> {\n const domainId = context.state.domain.id\n const info = axisInfo(axis)\n /* 모르는 축은 **거절한다.** 빈 목록으로 답하면 \"이 개념은 비어 있다\" 로 읽히고, 오타 하나가\n \"우리 트윈에는 그게 없다\" 는 결론으로 굳는다. */\n if (!info) throw new Error(`unknown concept axis: \"${axis}\" — the kernel catalog does not declare it`)\n\n const inst = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return null\n\n const take = Math.min(Math.max(limit ?? 50, 1), 200)\n const skip = Math.max(offset ?? 0, 0)\n const q = (search ?? '').trim()\n /* 시각 커서는 시간축을 가진 축만 쓴다(`historical`) — 선언 축에서는 뜻이 없다. */\n const at_ = axisInfo(axis)?.historical ? untilTime || null : null\n const row = ROW_BACKED[axis]\n\n if (row && !q) {\n /* 검색어가 없으면 **DB 가 페이징한다** — 이것이 규모에서 유일하게 성립하는 길이다. */\n const repo = getRepository(row.entity)\n const where = { domain: { id: domainId } as any, instance: { id: inst.id } as any }\n const [rows, total] = await repo.findAndCount({ where, order: row.order, skip, take })\n return {\n axis,\n label: info.label,\n basis: 'rows',\n total,\n offset: skip,\n /* 목록도 등급 이름을 쓴다 — 목록 칸에 `assembler-op` 이 그대로 서면 목록이 제 일을 못 한다. */\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n items: rows.map((r: any) => this.rowItem(axis, r))\n }\n }\n\n if (row && q) {\n /*\n * 검색은 아직 DB 로 내리지 않았다. **그 사실을 밝힌다**(`basis: 'rows-scanned'`) —\n * 흉내로 덮으면 규모가 오는 날까지 아무도 이 한계를 모른다. 훑는 건수를 상한으로 막고,\n * 상한에 닿았으면 잘렸다고 말한다(조용히 자르지 않는다).\n */\n const SCAN_MAX = 5000\n const repo = getRepository(row.entity)\n const where = { domain: { id: domainId } as any, instance: { id: inst.id } as any }\n const rows = await repo.find({ where, order: row.order, take: SCAN_MAX })\n const hit = rows.filter((r: any) => matches(this.rowItem(axis, r), q))\n return {\n axis,\n label: info.label,\n basis: 'rows-scanned',\n total: hit.length,\n offset: skip,\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n scanned: rows.length,\n truncated: rows.length >= SCAN_MAX,\n ...(() => {\n const items = hit.slice(skip, skip + take).map((r: any) => this.rowItem(axis, r))\n return { items, names: this.namesFor(items, this.nameIndex(inst.model ?? {})) }\n })()\n }\n }\n\n /*\n * **선언이 아닌 축** — 일정·실적(ISA-95 Part 4). 이 축의 집은 트윈 모델이 아니라 **커널 상태**다\n * (커널이 `source: 'state'` 로 선언한다).\n *\n * ── 멈춘 트윈은 0 이 아니다 ──────────────────────────────────────────────────\n * 커널이 동작하지 않으면 관측이 **없다**. 그때 빈 목록을 내면 \"작업이 0 건\" 으로 읽히고, 그건\n * 거짓이다 — 이 화면이 관측 열에서 내내 지켜 온 구분(관측 없음 ≠ 0)을 목록에서도 지킨다.\n *\n * ── 규모 ────────────────────────────────────────────────────────────────────\n * 상태 배열은 지금의 사실만 담아 유한하다(진행 중 오더·작업). 과거까지 세는 것은 저널의 일이고\n * 커서 페이징이 필요하다 — 그건 `historical` 축의 후속이며, 여기서 흉내내지 않는다.\n */\n if (axisSource(axis) === 'state') {\n /* 봉투를 벗긴다 — `{revision, state}` 안에 축이 있다. 그리고 **실행 중일 때만** 관측이다. */\n /*\n * **라이브는 권위, 히스토리는 파생.**\n *\n * 지금 도는 커널의 상태가 이 축의 진실이다. 그런데 커널이 멈춰 있거나 사용자가 **과거 시각**을\n * 물으면 답할 것이 없어진다 — 그때 저널을 그 시점까지 접어 답한다(`recover`). 둘은 같은 모양이지만\n * **성질이 다르므로 `basis` 로 구별해 낸다**: 파생을 권위처럼 내면 다시 계산한 값을 보고 \"지금 이렇다\"\n * 로 읽게 된다.\n *\n * 규모: 접기 비용은 이벤트 수에 비례한다. 감추지 않고 **어느 리비전까지 접었는지 함께 낸다** —\n * 이 화면이 목록마다 `basis` 를 밝혀 온 규율 그대로다.\n */\n const live = TwinEngine.isRunning(domainId, instanceId) && !at_\n let snap = live ? unwrapState(TwinEngine.snapshot(domainId, instanceId)) : null\n let folded: number | undefined\n if (!snap) {\n try {\n const rec = await TwinEngine.recover(domainId, instanceId, undefined, at_ ?? undefined)\n snap = unwrapState(rec)\n folded = Number((rec as any)?.revision) || undefined\n } catch {\n /* 다시 계산할 것이 없다(모델도 저널도 없다) — 없는 것을 0 으로 메우지 않는다. */\n snap = null\n }\n }\n if (!snap) {\n return { axis, label: info.label, basis: 'state', total: null, observed: false, offset: skip, items: [] }\n }\n const bucket = (snap as any)[axis]\n const list: any[] = Array.isArray(bucket) ? bucket : []\n const hitState = q ? list.filter(o => matches(o, q)) : list\n const items = hitState\n .slice(skip, skip + take)\n .map(o => ({ id: idOf(o), fields: this.withOrderMaterial(axis, inst.model ?? {}, o) }))\n return {\n axis,\n label: info.label,\n /* 권위(라이브)와 파생(저널)을 구별해 낸다 — 화면이 이 낱말을 그대로 보인다. */\n basis: live ? 'state' : 'journal',\n ...(folded != null ? { foldedRevision: folded } : {}),\n ...(at_ ? { at: at_ } : {}),\n observed: true,\n total: hitState.length,\n offset: skip,\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n items,\n names: this.namesFor(items, this.nameIndex(inst.model ?? {}))\n }\n }\n\n /* 아직 문서 안에 사는 축 — 문서를 읽어 자른다. 규모 한계를 `basis` 로 드러낸다. */\n const raw = at(inst.model ?? {}, documentPath(axis))\n const all = Array.isArray(raw) ? raw : raw ? [raw] : []\n const hit = q ? all.filter(o => matches(o, q)) : all\n return {\n axis,\n label: info.label,\n basis: 'document',\n total: hit.length,\n offset: skip,\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n ...(() => {\n /*\n * **한 벌뿐인 선언은 축 이름이 곧 식별자다.**\n *\n * `productionSpec` 처럼 문서에 객체 하나로 있는 축은 `id`/`key` 가 없다. 그것을 그대로\n * 목록에 실으면 \"식별자 없음 — 가리킬 수 없습니다\" 라는 줄 하나가 뜨고, 정작 그 선언을\n * 열어 볼 방법이 없다. 하나뿐인 것은 축 자신으로 가리킨다(상세도 같은 규칙으로 찾는다).\n */\n const singular = !Array.isArray(raw) && !!raw\n const items = hit\n .slice(skip, skip + take)\n .map(o => ({ id: idOf(o) ?? (singular ? axis : null), fields: this.withBinding(axis, inst.model ?? {}, o) }))\n return { items, names: this.namesFor(items, this.nameIndex(inst.model ?? {})), singular }\n })()\n }\n }\n\n /**\n * 행에서 **내부 배관을 걷어낸다** — 사용자가 볼 것은 현장의 사실이지 우리 스키마가 아니다.\n *\n * 손으로 목록을 두지 않는다. 관계와 그 조인 컬럼이 무엇인지는 **엔티티 메타데이터**가 알고,\n * 표로 두면 컬럼이 늘 때마다 여기를 고쳐야 하며 잊으면 그대로 새어 나간다 — 실제로\n * `domainId`·`instanceRowId` 같은 내부 UUID 가 화면까지 갔다.\n *\n * 식별자도 뺀다: 항목 자신의 id 는 이미 `id`/`itemId` 로 나가므로 두 번 보일 이유가 없다.\n */\n private strip(entityClass: any, idColumn: string, r: any): any {\n const meta = getRepository(entityClass).metadata\n const hidden = new Set<string>(['id', 'createdAt', 'updatedAt', 'creator', 'updater', 'creatorId', 'updaterId', idColumn])\n for (const rel of meta.relations) {\n hidden.add(rel.propertyName)\n for (const jc of rel.joinColumns) hidden.add(jc.propertyName)\n }\n /* `@RelationId` 로 승격한 내부 UUID(`domainId`·`instanceRowId`·`areaRowId`) — 관계 목록에는 없고\n 여기에만 있다. 이 한 줄이 없어서 실제로 화면까지 샜다. */\n for (const rid of meta.relationIds) hidden.add(rid.propertyName)\n const out: any = {}\n for (const [k, v] of Object.entries(r)) if (!hidden.has(k)) out[k] = v\n return out\n }\n\n\n /**\n * **자재는 자기 GS1 품목 참조를 안다** — 읽기 경계에서 이어 붙인다.\n *\n * 정본은 `productionSpec.binding` 하나다(커널이 EPC↔자재를 그 표로 잇는다). 그런데 그 사실은\n * **자재마다의 속성**이다: 이 자재가 GS1 품목 몇 번인가, 그래서 개체로 추적되는가(= 계보를 비교할\n * 수 있는가). 자재 목록에 그것이 없으면 자재는 자기 정체를 모르고, 사용자는 그 사실을 딴 축에서\n * 찾아야 한다.\n *\n * 그래서 **저장은 한 곳(binding), 표시는 읽는 자리에서 이어 붙임** — 이름표와 같은 방식이다.\n * 값을 복제해 두면 두 곳이 어긋나고, 어긋난 쪽을 아무도 모른다.\n */\n private withBinding(axis: string, model: any, fields: any): any {\n if (axis !== 'materials' || !fields || typeof fields !== 'object') return fields\n const binding: Record<string, string> = model?.productionSpec?.binding ?? {}\n const ref = binding[fields.key ?? fields.id]\n /* 없으면 키를 만들지 않는다 — 빈 값이 있는 것과 선언되지 않은 것은 다르다. */\n return ref ? { ...fields, gs1Ref: ref } : fields\n }\n\n /**\n * **오더가 무엇을 만드나** — GS1 품목 참조를 자재로 다시 계산해 붙인다.\n *\n * 커널의 오더는 품목을 GS1 으로 말한다(`urn:epc:idpat:sgtin:0614141.078101.*`). 사람에게 그 문자열은\n * 아무 뜻이 없고, 그 품목의 이름은 **자재 선언**이 갖고 있다. 둘을 잇는 것은 `productionSpec.binding`\n * (자재 키 → 품목 참조)이므로 **역방향으로 다시 계산한다.**\n *\n * 정본은 그대로 둔다: `gtin` 은 커널이 말한 값이고, 여기서 더하는 것은 **자재 키 하나**다(그 이름은\n * 이름표가 붙인다 — 값을 복제하지 않는다). 다시 계산하지 못하면 아무것도 더하지 않는다: 짐작으로 이으면\n * \"이 오더는 저것을 만든다\" 는 거짓이 되고, 그건 모르는 것보다 나쁘다.\n */\n private withOrderMaterial(axis: string, model: any, fields: any): any {\n if (axis !== 'orders' || !fields || typeof fields !== 'object') return fields\n const binding: Record<string, string> = model?.productionSpec?.binding ?? {}\n const refToMaterial = new Map(Object.entries(binding).map(([mat, r]) => [String(r), mat]))\n /* 단일 품목 작업지시는 `gtin`, 여러 품목이면 라인마다 말한다 — 첫 라인으로 대표하지 않는다. */\n const refOf = (v: unknown): string | null => {\n const m = typeof v === 'string' ? /sgtin:[^.]+\\.([^.]+)\\./.exec(v) : null\n return m ? m[1] : null\n }\n const mat = refToMaterial.get(String(refOf(fields.gtin) ?? ''))\n if (mat) return { ...fields, material: mat }\n const lineMats = (fields.lines ?? [])\n .map((l: any) => refToMaterial.get(String(refOf(l?.gtin) ?? '')))\n .filter(Boolean)\n return lineMats.length ? { ...fields, materials: [...new Set(lineMats)] } : fields\n }\n\n /** 행 하나 → 목록 항목. 컬럼 이름을 화면이 알지 않아도 되게 `id` + 나머지로 낸다. */\n private rowItem(axis: string, r: any): any {\n const { entity, idColumn } = ROW_BACKED[axis]\n return { id: r[idColumn], fields: this.strip(entity, idColumn, r) }\n }\n\n @Query(returns => ScalarObject, {\n nullable: true,\n description:\n 'One item of a standard concept: what the source declared, what the twin observed, what it links to and is linked from (declared relations, both directions), and where it came from. Never invents a value for a field the source did not provide.'\n })\n async twinModelItem(\n @Arg('instanceId') instanceId: string,\n @Arg('axis') axis: string,\n @Arg('itemId') itemId: string,\n @Ctx() context: ResolverContext\n ): Promise<any | null> {\n const domainId = context.state.domain.id\n const info = axisInfo(axis)\n if (!info) throw new Error(`unknown concept axis: \"${axis}\" — the kernel catalog does not declare it`)\n\n const inst = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return null\n\n const model = inst.model ?? {}\n const row = ROW_BACKED[axis]\n let declared: any = null\n let provenance: any = null\n\n /*\n * **관측 축의 상세** — 일정·실적은 상태에서 찾는다. 커널이 멈춰 있으면 항목이 아니라 **모른다**를\n * 낸다(그 트윈에 그 오더가 없다는 뜻이 아니다 — 지금 관측이 없다는 뜻이다).\n */\n if (axisSource(axis) === 'state') {\n /*\n * 동작하지 않으면 **목록과 같은 길로 저널을 접는다.**\n *\n * 목록만 접고 상세는 안 접었더니, 목록에는 472건이 보이는데 그 줄을 열면 \"자기 속성이 없습니다\"\n * 가 나왔다 — 한 화면에서 두 답이 갈리면 어느 쪽이 맞는지 사용자가 알 수 없다.\n */\n const liveItem = TwinEngine.isRunning(domainId, instanceId)\n let snap = liveItem ? unwrapState(TwinEngine.snapshot(domainId, instanceId)) : null\n if (!snap) {\n try {\n snap = unwrapState(await TwinEngine.recover(domainId, instanceId))\n } catch {\n /* 다시 계산할 것이 없다 — 아래에서 \"모른다\" 를 낸다(0 으로 메우지 않는다). */\n }\n }\n const bucket = snap ? (snap as any)[axis] : null\n const found = Array.isArray(bucket) ? bucket.find((o: any) => idOf(o) === itemId) : undefined\n if (!snap || !found) {\n return {\n instanceId, axis, label: info.label, itemId,\n identity: { standardClass: info.standardClass ?? null, typeRole: info.typeRole ?? null, kind: info.kind, gs1Scheme: info.gs1Scheme ?? null },\n declared: null, observed: found ?? null, observedOnly: true,\n basis: liveItem ? 'state' : 'journal', observedBasis: liveItem ? 'state' : 'journal', observing: liveItem,\n links: { out: [], incoming: [] }, properties: propertiesOf(axis).map((pr: any) => ({ key: pr.key, label: pr.label, kind: pr.kind, uom: pr.uom ?? null, observedBy: pr.observedBy ?? null })),\n /* 어떤 속성이 **효과가 있나** — 등록부가 말한다(§property-effects). 없는 것은 표시만 된다. */\n propertyEffects: propertyEffectsOf(axis),\n names: {}, provenance: { basis: 'state' }\n }\n }\n const names = this.namesFor([{ id: itemId, fields: found }], this.nameIndex(inst.model ?? {}))\n return {\n instanceId, axis, label: info.label, itemId,\n identity: { standardClass: info.standardClass ?? null, typeRole: info.typeRole ?? null, kind: info.kind, gs1Scheme: info.gs1Scheme ?? null },\n /*\n * **선언이 없는 축이다.** 두 열 중 왼쪽이 비는 것이 정상이고, 그 사실을 값으로 말한다\n * (`observedOnly`) — 빈 열을 \"원본이 침묵했다\" 로 읽으면 안 된다. 원본은 애초에 이 축을\n * 선언하지 않는다.\n */\n declared: null,\n observed: this.withOrderMaterial(axis, inst.model ?? {}, found),\n observedOnly: true,\n basis: liveItem ? 'state' : 'journal',\n /* 관측 열의 근거는 **한 이름으로** 낸다 — 두 이름을 두면 화면이 한쪽을 잊는다. */\n observedBasis: liveItem ? 'state' : 'journal',\n observing: liveItem,\n properties: propertiesOf(axis).map((pr: any) => ({ key: pr.key, label: pr.label, kind: pr.kind, uom: pr.uom ?? null, observedBy: pr.observedBy ?? null })),\n /* 어떤 속성이 **효과가 있나** — 등록부가 말한다(§property-effects). 없는 것은 표시만 된다. */\n propertyEffects: propertyEffectsOf(axis),\n links: await this.linksOf(domainId, inst, axis, itemId, found),\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n names,\n provenance: { basis: liveItem ? 'state' : 'journal' }\n }\n }\n\n if (row) {\n const found: any = await getRepository(row.entity).findOne({\n where: { domain: { id: domainId } as any, instance: { id: inst.id } as any, [row.idColumn]: itemId } as any\n })\n if (found) {\n const { sourceRef, ingestedAt, ...rest } = this.strip(row.entity, row.idColumn, found)\n declared = rest\n /* 출처는 속성이 아니라 **근거**다 — 두 열이 아니라 아래 근거 묶음으로 간다. */\n provenance = { sourceRef, ingestedAt, basis: 'rows' }\n }\n }\n\n /*\n * 행에 없으면 문서를 본다 — **투영이 낡은 트윈에서도 항목을 볼 수 있어야 한다.** 행만 보고\n * \"없다\" 고 답하면, 문서에는 있는 자리가 화면에서 사라진다(이 프로젝트가 내내 잡아 온 부류).\n */\n if (!declared) {\n const raw = at(model, info.path)\n const all = Array.isArray(raw) ? raw : raw ? [raw] : []\n /* 한 벌뿐인 선언은 축 이름으로 찾는다 — 목록이 그 이름으로 가리켰기 때문이다. */\n const found = all.find(o => idOf(o) === itemId) ?? (!Array.isArray(raw) && raw && itemId === axis ? raw : undefined)\n if (found) {\n declared = typeof found === 'string' ? { id: found } : this.withBinding(axis, model, found)\n provenance = { basis: 'document' }\n }\n }\n\n /* 선언에도 문서에도 없다 — 그런데 **관측에는 있을 수 있다**(원본이 모르는 자원). 그 경우도\n 항목으로 열려야 한다. 둘 다 없으면 진짜로 없는 것이므로 `null`. */\n const seen = await this.observedOf(domainId, instanceId, axis, itemId)\n const observed = 'value' in seen ? seen.value : null\n if (!declared && !observed) return null\n\n /* 이웃을 먼저 구한다 — 이름표가 이웃의 id 까지 덮으려면 반환 전에 손에 있어야 한다. */\n const links = await this.linksOf(domainId, inst, axis, itemId)\n\n /*\n * **구역 이름은 모델에 없다** — 구역은 호스트 개념이고(`TwinArea`), 인제스트가 모델에서 갈라\n * 공간 쪽으로 보낸다. 그래서 모델만 조회하는 이름표에는 `a-floor` 의 이름이 없고, 관계 그림에 그 id 가\n * 그대로 섰다. 그 행에서 가져와 이름표에 합친다(이 트윈의 공간 것만).\n */\n const areaNames: Record<string, string> = {}\n if (inst.spaceId) {\n const areas = await getRepository(TwinArea)\n .find({ where: { domain: { id: domainId } as any, space: { spaceId: inst.spaceId } as any } as any })\n .catch(() => [] as any[])\n for (const a of areas as any[]) if (a?.areaId && a?.name) areaNames[a.areaId] = a.name\n }\n\n return {\n instanceId,\n axis,\n label: info.label,\n itemId,\n /* 정체 — 표준 클래스·식별 스킴은 전부 카탈로그 선언에서 온다. */\n identity: {\n standardClass: info.standardClass ?? null,\n typeRole: info.typeRole ?? null,\n kind: info.kind,\n gs1Scheme: info.gs1Scheme ?? null\n },\n /*\n * **그릇인가** — 문서에 객체 하나로 있는 축(`productionSpec`)인지.\n *\n * `kind` 로는 갈리지 않는다: 커널은 라우트·레시피·공정도 `spec` 이라 부른다(같은 선언 부류라는\n * 뜻). 화면이 `kind` 로 갈랐더니 **라우트 상세가 그릇 틀로 그려져** 가장 중요한 정보(공정 순서)가\n * 개수 칩 하나로 줄어들었다. 그릇인지 아닌지는 모양이 말한다.\n */\n container:\n axisSource(axis) === 'document' && !Array.isArray(at(model, info.path)) && at(model, info.path) != null,\n /* 두 열 — 원본이 말한 값, 트윈이 관측한 값. 한쪽이 없으면 **없다고 낸다**(0 으로 메우지 않는다). */\n declared,\n observed,\n /*\n * 관측 열이 **자기 근거를 말한다** — 목록의 그 낱말 그대로(`state`=라이브 권위, `journal`=다시 계산한\n * 파생). 없으면 비교하지 못한 것이다. 파생이면 몇 번째 리비전까지 접었는지 함께 낸다.\n */\n ...('value' in seen\n ? { observedBasis: seen.basis, ...(seen.foldedRevision != null ? { observedRevision: seen.foldedRevision } : {}) }\n : { observedAbsence: seen.absence }),\n /* 선언된 속성 — 어느 관측 축에서 오는지도 함께(카탈로그가 말한 대로). */\n properties: propertiesOf(axis).map((p: any) => ({ key: p.key, label: p.label, kind: p.kind, uom: p.uom ?? null, observedBy: p.observedBy ?? null })),\n /*\n * **효과가 있는 속성과 표시만 되는 속성은 다르다.** 속성은 열려 있어 아무 사실이나 실어 보낼 수\n * 있지만, 값이 계산을 바꾸려면 그 규칙을 코드가 알아야 한다. 지금 무엇이 그런지 화면이 말할 수\n * 있게 등록부를 함께 낸다 — 사용자가 넣고 나서 아무 일도 안 일어나는 이유를 알 수 있게.\n */\n propertyEffects: propertyEffectsOf(axis),\n links,\n /*\n * **등급 이름은 등급이 갖고 있다.** 공정은 자격을 등급 id 로만 요구하므로(표준이 그렇다),\n * 그 id 를 그대로 화면에 내면 `assembler-op` 이 사용자에게 간다. 등급의 표시명은 등급 선언의\n * `description`(i18n 키)에 있고 그것은 **다른 축**이다 — 화면이 축을 하나 더 읽지 않아도 되게\n * 여기서 이어 붙인다(서버는 이미 모델을 손에 들고 있다).\n */\n resourceClassLabels: this.classLabels(model),\n /*\n * **공정이면 그 공정의 능력도 함께 낸다** — ISA-95 Part 4 `OperationsCapability`.\n *\n * 공정 상세에서 사람이 묻는 것은 \"이 공정이 지금 얼마나 더 할 수 있나\" 이고, 그 답은 명세만\n * 봐서는 안 나온다(약정과 지금 못 쓰는 자원을 빼야 한다). 화면이 축을 하나 더 읽지 않게\n * 여기서 이어 붙인다 — 이름표·등급 라벨을 붙이는 것과 같은 이유다.\n */\n ...(await this.capabilityOfOperation(domainId, instanceId, axis, itemId)),\n /*\n * 상세도 같은 표를 쓴다 — 목록과 상세가 같은 이름으로 말해야 사용자가 같은 것으로 읽는다.\n *\n * **이웃의 이름도 함께 싣는다.** 관계 그림의 이웃은 대개 *들어오는* 링크(이 자리를 기준 자리로\n * 삼는 설비·사람)라, 이 항목 자신의 필드에는 그 id 가 없다 — 필드만 훑으면 그림이 id 로 채워진다.\n */\n names: this.namesFor(\n [{ id: itemId, fields: declared }, { fields: observed }, { fields: links }],\n { ...this.nameIndex(model), ...areaNames }\n ),\n provenance\n }\n }\n\n /**\n * **id → 이름**, 모든 축을 한 표로.\n *\n * ── 왜 이 표가 필요한가 ──────────────────────────────────────────────────────\n * 행은 다른 것을 **id 로** 가리킨다(사람의 `personnelClassIds`, 설비의 `homeLocationId`, 공정의\n * `locationType`). 그 id 의 이름은 **가리켜진 축의 행**에 있으므로, 화면이 그것을 알려면 축을\n * 하나씩 더 읽어야 한다 — 그래서 지금까지 표면마다 그냥 id 를 찍었다(`cutter-op`, `cut-station`).\n * 표면을 하나씩 고치는 것은 끝이 없다: 새 화면은 처음부터 다시 id 를 찍는다.\n *\n * 그래서 **서버가 붙인다.** 서버는 이미 모델을 손에 들고 있고, 어느 축이 있는지는 커널 카탈로그가\n * 선언한다(`TWIN_AXES`) — 도메인이 늘어도 이 함수는 그대로다.\n *\n * 값은 그 항목이 **자기 이름이라고 말한 것**이다(`name`·`label`·`description`). 그중 어떤 것은\n * i18n 키이므로(등급의 `description`) 번역은 화면의 일로 남긴다. 이름이 없으면 표에 넣지 않는다 —\n * 없는 것을 지어내지 않고, 그 경우 화면은 id 를 그대로 보인다.\n */\n private nameIndex(model: any): Record<string, string> {\n const out: Record<string, string> = {}\n for (const info of TWIN_AXES as any[]) {\n /* 관측 축(상태·저널)은 문서에 없다 — 경로가 없는 축을 읽으면 모델 루트를 훑는다. */\n if (axisSource(info.axis) !== 'document') continue\n const raw = at(model ?? {}, info.path)\n const list = Array.isArray(raw) ? raw : raw ? [raw] : []\n for (const o of list) {\n const id = idOf(o)\n if (!id || typeof o !== 'object') continue\n const label = o.name ?? o.label ?? o.description\n /* 이름이 id 와 같으면 표에 넣지 않는다 — 같은 값을 두 번 보이는 셈이다. */\n if (typeof label === 'string' && label && label !== id && !out[id]) out[id] = label\n }\n }\n return out\n }\n\n /**\n * 이 응답이 **실제로 가리킨 것만** 골라 낸다.\n *\n * 모델 전체 표를 그대로 실으면 자리가 10만인 현장에서 목록 한 페이지에 10만 줄짜리 이름표가\n * 따라온다. 나온 값에 걸리는 것만 싣는다 — 규모에서 성립하는 유일한 방식이다.\n */\n private namesFor(rows: any[], index: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {}\n const take = (v: any, depth: number): void => {\n if (v == null || depth > 4) return\n if (typeof v === 'string') { if (index[v]) out[v] = index[v]; return }\n if (Array.isArray(v)) { for (const x of v) take(x, depth + 1); return }\n if (typeof v === 'object') for (const x of Object.values(v)) take(x, depth + 1)\n }\n for (const r of rows) { take(r?.fields ?? r, 0); if (typeof r?.id === 'string' && index[r.id]) out[r.id] = index[r.id] }\n return out\n }\n\n /** 등급 id → 표시명 키. 인원·설비·자산·품목 등급을 한 표로 — 어느 자원이든 같은 방식으로 요구된다. */\n private classLabels(model: any): Record<string, string> {\n const out: Record<string, string> = {}\n for (const key of ['personnelClasses', 'equipmentClasses', 'assetClasses', 'materialClasses'])\n /* 표시명은 `name` 이 정본이다 — 옛 모델는 `description` 에 담고 있어 둘 다 본다(읽기 경계 하나). */\n for (const c of (model?.[key] ?? []) as any[]) if (c?.id && (c.name || c.description)) out[c.id] = c.name || c.description\n return out\n }\n\n /**\n * 관측이 본 이 항목 — 커널이 실행 중일 때만. **실행 중이 아니면 `null` 이지 빈 객체가 아니다**\n * (관측이 없는 것과 비교하지 못한 것은 다르다).\n */\n /**\n * 이 공정의 **생산 능력** — 공정 축 항목에만 붙는다.\n *\n * 구간은 **앞으로 24시간**이다. 표준의 약정·가용은 *앞으로 쓸* 용량이므로 지난 구간을 두고 말하면\n * 뜻이 없고, 이 화면에는 사용자가 고른 창이 없다. 그래서 하루를 쓰고 **그 사실을 값과 함께 낸다**\n * (화면이 라벨로 말한다) — 어느 구간의 값인지 모르면 능력은 읽을 수 없다.\n *\n * **수요를 지어내지 않는다.** 여기서 내는 값(상한·약정·달성불가·가용·제약하는 축)은 전부 공급 쪽이다 —\n * 자원 수·사이클·가동률에서 나온다. 수요는 `ok`·병목·하루 상한에만 쓰이고 그것들은 내지 않으므로,\n * 계산에 넘기는 수요 `1` 은 결과에 새지 않는다(성과 화면은 사용자가 걸어 둔 목표를 쓴다 — 그 화면은\n * \"목표를 낼 수 있나\" 에 답하고 여기서는 \"얼마나 더 할 수 있나\" 에 답한다).\n *\n * 안 실행 중이면 붙이지 않는다 — 능력은 지금 자원의 사실에서 나오고, 없는 것을 지어내지 않는다.\n */\n private async capabilityOfOperation(\n domainId: string,\n instanceId: string,\n axis: string,\n itemId: string\n ): Promise<{ capability?: any } > {\n if (axis !== 'operations') return {}\n if (!TwinEngine.isRunning(domainId, instanceId)) return {}\n const from = new Date()\n const to = new Date(from.getTime() + 24 * 3_600_000)\n const monday = Date.UTC(from.getUTCFullYear(), from.getUTCMonth(), from.getUTCDate() - ((from.getUTCDay() + 6) % 7))\n try {\n const rows = await TwinEngine.operationsCapability(\n domainId,\n { instanceId },\n 1,\n monday,\n { fromTime: from.toISOString(), toTime: to.toISOString() }\n )\n const report = rows.find((r: any) => r.instanceId === instanceId)?.report\n const entry = report?.perOperation?.find((o: any) => o.operation === itemId)\n if (!entry) return {}\n /* 병목·상한은 **넣지 않는다** — 그 둘만 수요에 달려 있고, 여기서는 수요를 모른다. */\n return { capability: { window: report.window, operationsType: report.operationsType, ...entry } }\n } catch {\n /* 능력을 못 냈다고 상세가 안 열릴 이유는 없다 — 없으면 없는 대로 낸다(화면이 그 줄을 안 그린다). */\n return {}\n }\n }\n\n /**\n * 이 항목을 트윈이 **관측한 값** — 그리고 **무엇을 근거로** 아는지.\n *\n * 봉투를 푸는 것을 빠뜨려서(`unwrapState`) 문서 축의 관측 열이 통째로 비어 있던 자리다(사람을 열면\n * 트윈이 아는 것이 전부 `—` 였다).\n *\n * 근거를 값과 함께 낸다 — 목록이 오래 해 온 그대로다(§twinModelItemList). 라이브(권위)와 저널\n * 폴드(파생)는 **같은 모양의 객체**라서, 근거가 없으면 다시 계산한 값을 \"지금 이렇다\" 로 읽는다. 근거를\n * 실을 자리가 없던 동안에는 멈춘 트윈의 저널을 아예 접지 않고 `—` 로 두는 편이 정직했다. 이제\n * 자리가 있으니 접는다 — 멈춘 트윈에도 마지막으로 알던 사실이 있고, 그것을 감출 이유는 없다.\n *\n * 다시 계산할 것이 없으면(모델도 저널도 없다) `null` 이다 — **없는 것과 비교하지 못한 것은 다르다.**\n */\n private async observedOf(\n domainId: string,\n instanceId: string,\n axis: string,\n itemId: string\n ): Promise<{ value: any; basis: 'state' | 'journal'; foldedRevision?: number } | { absence: 'not-running' | 'not-observed' }> {\n const live = TwinEngine.isRunning(domainId, instanceId)\n let state: any = null\n let folded: number | undefined\n if (live) {\n state = unwrapState(TwinEngine.snapshot(domainId, instanceId))\n } else {\n try {\n const rec = await TwinEngine.recover(domainId, instanceId)\n folded = Number((rec as any)?.revision) || undefined\n /*\n * **이벤트를 하나도 접지 않은 폴드는 관측이 아니다.** 저널이 비어도 복원은 선언을 다시 투영한\n * 기준선을 돌려준다 — 그것을 \"트윈이 관측한 값\" 열에 실으면 **선언이 관측으로 위장한다**\n * (원본이 말한 값이 오른쪽에도 똑같이 앉아, 견준 것처럼 보인다). 접은 것이 없으면 없다고 한다.\n */\n if (folded == null) return { absence: 'not-running' as const }\n state = unwrapState(rec)\n } catch {\n return { absence: 'not-running' as const }\n }\n }\n const bucket = state ? (state as any)[axis] : null\n /*\n * **왜 관측이 없는지 말한다.** 예전에는 그냥 `null` 이었고 화면은 그것을 \"트윈이 실행 중이지 않아\"\n * 로 읽었다 — 실행 중인데도 그렇게 말했다(공정 상세에서 관측됨). 공정·레시피처럼 **관측 축이\n * 아닌 것**은 트윈이 돌든 말든 관측이 없다. 이유가 다르면 화면이 다르게 말해야 한다.\n */\n if (!Array.isArray(bucket)) return { absence: 'not-observed' as const }\n const value = bucket.find((x: any) => x?.id === itemId)\n if (!value) return { absence: 'not-observed' as const }\n return { value, basis: live ? 'state' : 'journal', ...(folded != null ? { foldedRevision: folded } : {}) }\n }\n\n /**\n * 이어진 것 — **양방향.** 선언된 관계(`TWIN_RELATIONS`)만 따라간다.\n *\n * 관계를 코드가 알지 않으므로 도메인이 늘어도 여기 손댈 것이 없다. 대신 **선언에 없는 관계는\n * 그리지 않는다** — 지도에 없는 길을 그리는 것보다 없다고 두는 것이 정직하다.\n *\n * 들어오는 쪽(누가 나를 가리키나)은 그 축의 항목을 살펴야 안다. 규모 규율상 **깊이 1 · 방향별\n * 상한**이고, 넘치면 몇이 더 있는지 말한다(목록으로 보낼 수 있게).\n */\n private async linksOf(\n domainId: string,\n inst: any,\n axis: string,\n itemId: string,\n /*\n * 이 항목 자신 — **상태 축은 문서에서 찾을 수 없다.** 부르는 쪽이 이미 손에 들고 있으므로 넘겨\n * 받는다. 없으면 예전처럼 문서에서 찾는다(문서 축의 거동은 그대로).\n */\n self0?: any\n ): Promise<any> {\n const NEIGHBOR_MAX = 20\n const model = inst.model ?? {}\n\n /*\n * 관측 축의 항목들 — **한 번만** 읽는다(관계마다 다시 접으면 저널을 여러 번 접는다).\n * 라이브가 있으면 그것, 없으면 저널 폴드. 없으면 빈 배열(없는 것을 지어내지 않는다).\n */\n let observedState: any\n let observedLoaded = false\n const observedBucket = async (a: string): Promise<any[]> => {\n if (!observedLoaded) {\n observedLoaded = true\n try {\n observedState = TwinEngine.isRunning(domainId, inst.instanceId)\n ? unwrapState(TwinEngine.snapshot(domainId, inst.instanceId))\n : unwrapState(await TwinEngine.recover(domainId, inst.instanceId))\n } catch {\n observedState = null\n }\n }\n const b = observedState ? (observedState as any)[a] : null\n return Array.isArray(b) ? b : []\n }\n\n /*\n * **관계는 선언 어휘로 푼다** — 문서에서 이 항목을 찾아 그것을 본다.\n *\n * 관계 선언의 필드 이름(`locations.parentId`)은 **원본 문서의 어휘**다. 행은 같은 사실을 자기\n * 컬럼 이름으로 담는다(자리의 구역은 `area` FK). 행을 보고 `parentId` 를 찾으면 늘 비어서\n * \"이어진 것이 없다\" 로 조용히 답한다 — 실제로 그랬다.\n *\n * 어느 쪽이 정본인가로 구분하면 답이 분명하다: 관계를 선언한 어휘가 문서 어휘이므로 **문서에서\n * 푼다.** 행에만 있고 문서에 없는 항목(있을 수 있다)은 이어진 것이 비지만, 그것은 사실이다.\n */\n const axisPath = axisSource(axis) === 'document' ? axisInfo(axis)?.path : undefined\n const rawSelf = axisPath ? at(model, axisPath) : undefined\n const selfAll = Array.isArray(rawSelf) ? rawSelf : rawSelf ? [rawSelf] : []\n const self = self0 ?? selfAll.find((o: any) => idOf(o) === itemId)\n\n /* 나가는 쪽 — 내 필드가 가리키는 것. 선언이 필드 이름을 알려 준다. */\n const out = relationsFrom(axis).map((r: any) => {\n const raw = self ? this.fieldValue(self, r.field) : []\n const ids = raw.filter((v: any) => v != null).map(String)\n return {\n via: r.via,\n field: r.field,\n optional: !!r.optional,\n /* 대상이 축이면 그 축의 항목으로 갈 수 있다. 타입·외부(구역)면 **갈 곳이 다르다** —\n 화면이 링크를 만들지 말지 알아야 하므로 대상 종류를 그대로 낸다(막다른 링크 금지). */\n target: r.target,\n ids: ids.slice(0, NEIGHBOR_MAX),\n total: ids.length\n }\n }).filter((l: any) => l.total > 0)\n\n /* 들어오는 쪽 — 나를 가리키는 항목들. 그 축이 행이면 DB 가 세고, 문서면 문서를 전수 조회한다. */\n const incoming: any[] = []\n for (const r of relationsTo(axis)) {\n const fromInfo = axisInfo(r.from)\n if (!fromInfo) continue\n const hits: string[] = []\n const row = ROW_BACKED[r.from]\n if (row) {\n const repo = getRepository(row.entity)\n /*\n * **FK 는 부르지 않으면 오지 않는다.** 관계 필드를 로딩하지 않고 조회하면 값이 늘 `undefined`\n * 라서 \"나를 가리키는 것이 하나도 없다\" 로 조용히 답한다 — 실제로 그랬다(설비 둘이 이 자리를\n * 기준으로 삼는데 이웃이 비어 있었다).\n *\n * 어느 필드가 관계인지는 **엔티티 메타데이터**가 안다. 축마다 표를 두면 축이 늘 때마다\n * 여기를 고쳐야 하고, 고치는 것을 잊으면 같은 침묵이 다시 생긴다.\n */\n const relationNames = new Set(repo.metadata.relations.map(rel => rel.propertyName))\n const field = r.field.replace(/\\[\\]$/, '').split('.')[0]\n const rows: any[] = await repo.find({\n where: { domain: { id: domainId } as any, instance: { id: inst.id } as any },\n ...(relationNames.has(field) ? { relations: [field] } : {}),\n take: 5000\n })\n for (const x of rows) {\n /* 행에서는 관계가 FK 객체이거나 컬럼이다 — 이름 후보를 순서대로 본다. */\n const v = this.relationValueOfRow(x, r.field, axis)\n if (v.includes(itemId)) hits.push(x[row.idColumn])\n }\n } else {\n /*\n * 들어오는 쪽을 훑는다 — **어디를 훑을지는 그 축의 `source` 가 정한다.**\n *\n * 문서 축은 모델에서, 관측 축은 **상태에서** 훑는다(작업 → 이 오더, 작업 → 이 자리). 한동안\n * 관측 축을 건너뛰었더니 오더 상세가 \"닿는 관계가 없습니다\" 라고 답했다 — `tasks.orderId` 를\n * 선언해 두고도 그 관계를 그리지 않은 것이다. 선언한 것을 그리지 않으면 선언이 거짓이 된다.\n *\n * 규모: 상태는 지금의 사실만 담아 유한하고, 상한과 총계는 문서 축과 같은 규율을 쓴다\n * (넘치면 몇이 더 있는지 말한다). 저널 전체를 전수 조회하는 일은 여기서 하지 않는다.\n */\n const raw =\n axisSource(r.from) === 'document' ? at(model, fromInfo.path) : (await observedBucket(r.from))\n const all = Array.isArray(raw) ? raw : raw ? [raw] : []\n for (const x of all) if (this.fieldValue(x, r.field).map(String).includes(itemId)) {\n const id = idOf(x)\n if (id) hits.push(id)\n }\n }\n if (hits.length) incoming.push({ via: r.via, from: r.from, field: r.field, ids: hits.slice(0, NEIGHBOR_MAX), total: hits.length })\n }\n\n return { out, incoming }\n }\n\n /**\n * 선언 필드 경로 → 값들. `inputs[].material` 처럼 **배열을 지나는 경로**를 다룬다.\n * 배열 표기(`[]`)가 관계 선언의 문법이므로 그것을 따르는 것이 곧 선언을 존중하는 것이다.\n */\n private fieldValue(obj: any, field: string): any[] {\n let cur: any[] = [obj]\n for (const seg of field.split('.')) {\n const isArray = seg.endsWith('[]')\n const key = isArray ? seg.slice(0, -2) : seg\n const next: any[] = []\n for (const c of cur) {\n if (c == null) continue\n const v = c[key]\n if (v == null) continue\n if (Array.isArray(v)) next.push(...v)\n else next.push(v)\n }\n cur = next\n }\n return cur.map(v => (typeof v === 'object' && v !== null ? idOf(v) ?? v : v)).filter(v => v != null)\n }\n\n /**\n * 행에서 관계 값을 꺼낸다 — FK 는 객체(관계 미로딩이면 없음)이고 문서 필드명과 컬럼명이 다를 수 있다.\n *\n * 여기서 컬럼 이름을 **축마다 표로 두지 않는다.** 후보를 순서대로 보는 편이 축이 늘 때 고칠 것이\n * 없다: 관계 필드 이름 그대로 · 그 이름의 FK 객체의 id 컬럼.\n */\n private relationValueOfRow(rowObj: any, field: string, targetAxis: string): string[] {\n const key = field.replace(/\\[\\]$/, '').split('.')[0]\n const v = rowObj[key]\n if (v == null) return []\n if (typeof v === 'string') return [v]\n if (Array.isArray(v)) return v.map(x => (typeof x === 'string' ? x : idOf(x) ?? '')).filter(Boolean)\n /* FK 객체 — 대상 축의 id 컬럼으로 읽는다(관계를 로딩하지 않았으면 값이 없고, 그것도 사실이다). */\n const idCol = ROW_BACKED[targetAxis]?.idColumn\n const got = idCol ? v[idCol] : idOf(v)\n return got ? [String(got)] : []\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"twin-model-item-query.js","sourceRoot":"","sources":["../../../server/service/twin-model/twin-model-item-query.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Int, Query, Resolver } from 'type-graphql'\n\nimport { ScalarObject, getRepository } from '@things-factory/shell'\n\nimport { itemRefOf } from './item-ref.js'\n\nimport { TwinEngine } from '../../engine/index.js'\nimport { unwrapState } from '../../engine/warm-start.js'\nimport { propertyEffectsOf } from '../../engine/property-effects.js'\n/* 축이 사는 자리를 읽는 **한 곳** — 카드(`twin-model-query`)와 같은 규칙을 쓴다. */\nimport { axisValueOf } from '@things-factory/headless-twin/dist-shared/axis-read.js'\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinLocation } from './twin-location.js'\nimport { TwinEquipment } from './twin-equipment.js'\nimport { TwinOperation } from './twin-operation.js'\nimport { TwinArea } from '../twin-space/twin-area.js'\nimport { at, idOf, nameIndex, namesFor } from './name-index.js'\n\n/* 커널 런타임 로드 — 축·관계·속성 선언의 SSOT. 이 파일은 도메인 모양을 알지 않는다. */\nconst { TWIN_AXES, TWIN_RELATIONS, axisInfo, axisSource, documentPath, relationsFrom, relationsTo, propertiesOf } = require('@operato/twin-kernel')\n\n/**\n * 축 → 그 축이 이미 **행으로 옮겨졌나**, 그리고 행의 어느 컬럼이 id 인가.\n *\n * 옮겨진 축은 **DB 가 페이징하고 센다.** 아직인 축은 문서 배열을 읽어야 하고, 그 차이를 응답이\n * `basis` 로 밝힌다 — 밝히지 않으면 \"이 축은 검색이 되는데 저 축은 왜 느린가\" 를 아무도 설명할 수 없다.\n */\nconst ROW_BACKED: Record<string, { entity: any; idColumn: string; order: any }> = {\n locations: { entity: TwinLocation, idColumn: 'locationId', order: { locationId: 'ASC' } },\n equipment: { entity: TwinEquipment, idColumn: 'equipmentId', order: { equipmentId: 'ASC' } },\n operations: { entity: TwinOperation, idColumn: 'operationKey', order: { seq: 'ASC' } }\n}\n\n\n/** 검색 — 항목의 값 어디든 걸리면 맞는 것으로 본다. 축마다 검색 컬럼을 정해 두면 축이 늘 때마다 여기를 고쳐야 한다. */\nfunction matches(o: any, q: string): boolean {\n if (!q) return true\n const needle = q.toLowerCase()\n const walk = (v: any, depth: number): boolean => {\n if (v == null || depth > 3) return false\n if (typeof v === 'string' || typeof v === 'number') return String(v).toLowerCase().includes(needle)\n if (Array.isArray(v)) return v.some(x => walk(x, depth + 1))\n if (typeof v === 'object') return Object.values(v).some(x => walk(x, depth + 1))\n return false\n }\n return walk(o, 0)\n}\n\n/**\n * 항목 조회 — **개념 안의 목록**(③)과 **항목 하나의 상세**(④).\n *\n * ── 이 파일이 도메인을 알지 않는다 ─────────────────────────────────────────────\n * 어느 축이 있고 무엇을 가리키는지는 **커널 카탈로그가 선언**한다(`TWIN_AXES`·`TWIN_RELATIONS`).\n * 그래서 야드의 도크도어나 에너지의 계량기가 늘어도 여기 손댈 것이 없다(ADR-0031). 이 파일에\n * 도메인 이름이 한 번도 나오지 않는 것이 그 증거다.\n *\n * ── 조용히 자르지 않는다 ──────────────────────────────────────────────────────\n * 목록은 항상 **총 건수**와 함께 온다. 그리고 어떻게 셌는지(`basis`)를 밝힌다 — 행이면 DB 가\n * 페이징했고, 문서면 서버가 문서를 통째로 읽어 잘라 냈다. 후자는 규모에서 한계가 되므로 그 사실이\n * 화면에 드러나야 이주 압력이 살아 있다.\n */\n@Resolver()\nexport class TwinModelItemQuery {\n @Query(returns => ScalarObject, {\n nullable: true,\n description:\n 'Page through the items of one standard concept in a twin. Always returns the total and how it was counted (rows = the database paged it, document = the server read the whole document and sliced).'\n })\n async twinModelEntities(\n @Arg('instanceId') instanceId: string,\n @Arg('axis') axis: string,\n @Ctx() context: ResolverContext,\n @Arg('search', { nullable: true }) search?: string,\n @Arg('offset', type => Int, { nullable: true }) offset?: number,\n @Arg('limit', type => Int, { nullable: true }) limit?: number,\n /**\n * 어느 시각의 사실인가 — **관측 축에만 뜻이 있다.**\n *\n * 선언 축은 시간축이 없다(그 시점의 선언은 구조 리비전이 답한다). 그래서 문서 축에 이 값을 주면\n * 쓰지 않는다 — 무시했다는 사실은 응답의 `basis` 가 말한다(`document`).\n */\n @Arg('untilTime', { nullable: true }) untilTime?: string\n ): Promise<any | null> {\n const domainId = context.state.domain.id\n const info = axisInfo(axis)\n /* 모르는 축은 **거절한다.** 빈 목록으로 답하면 \"이 개념은 비어 있다\" 로 읽히고, 오타 하나가\n \"우리 트윈에는 그게 없다\" 는 결론으로 굳는다. */\n if (!info) throw new Error(`unknown concept axis: \"${axis}\" — the kernel catalog does not declare it`)\n\n const inst = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return null\n\n const take = Math.min(Math.max(limit ?? 50, 1), 200)\n const skip = Math.max(offset ?? 0, 0)\n const q = (search ?? '').trim()\n /* 시각 커서는 시간축을 가진 축만 쓴다(`historical`) — 선언 축에서는 뜻이 없다. */\n const at_ = axisInfo(axis)?.historical ? untilTime || null : null\n const row = ROW_BACKED[axis]\n\n if (row && !q) {\n /* 검색어가 없으면 **DB 가 페이징한다** — 이것이 규모에서 유일하게 성립하는 길이다. */\n const repo = getRepository(row.entity)\n const where = { domain: { id: domainId } as any, instance: { id: inst.id } as any }\n const [rows, total] = await repo.findAndCount({ where, order: row.order, skip, take })\n return {\n axis,\n label: info.label,\n basis: 'rows',\n total,\n offset: skip,\n /* 목록도 등급 이름을 쓴다 — 목록 칸에 `assembler-op` 이 그대로 서면 목록이 제 일을 못 한다. */\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n items: rows.map((r: any) => this.rowItem(axis, r))\n }\n }\n\n if (row && q) {\n /*\n * 검색은 아직 DB 로 내리지 않았다. **그 사실을 밝힌다**(`basis: 'rows-scanned'`) —\n * 흉내로 덮으면 규모가 오는 날까지 아무도 이 한계를 모른다. 훑는 건수를 상한으로 막고,\n * 상한에 닿았으면 잘렸다고 말한다(조용히 자르지 않는다).\n */\n const SCAN_MAX = 5000\n const repo = getRepository(row.entity)\n const where = { domain: { id: domainId } as any, instance: { id: inst.id } as any }\n const rows = await repo.find({ where, order: row.order, take: SCAN_MAX })\n const hit = rows.filter((r: any) => matches(this.rowItem(axis, r), q))\n return {\n axis,\n label: info.label,\n basis: 'rows-scanned',\n total: hit.length,\n offset: skip,\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n scanned: rows.length,\n truncated: rows.length >= SCAN_MAX,\n ...(() => {\n const items = hit.slice(skip, skip + take).map((r: any) => this.rowItem(axis, r))\n return { items, names: namesFor(items, nameIndex(inst.model ?? {})) }\n })()\n }\n }\n\n /*\n * **선언이 아닌 축** — 일정·실적(ISA-95 Part 4). 이 축의 집은 트윈 모델이 아니라 **커널 상태**다\n * (커널이 `source: 'state'` 로 선언한다).\n *\n * ── 멈춘 트윈은 0 이 아니다 ──────────────────────────────────────────────────\n * 커널이 동작하지 않으면 관측이 **없다**. 그때 빈 목록을 내면 \"작업이 0 건\" 으로 읽히고, 그건\n * 거짓이다 — 이 화면이 관측 열에서 내내 지켜 온 구분(관측 없음 ≠ 0)을 목록에서도 지킨다.\n *\n * ── 규모 ────────────────────────────────────────────────────────────────────\n * 상태 배열은 지금의 사실만 담아 유한하다(진행 중 오더·작업). 과거까지 세는 것은 저널의 일이고\n * 커서 페이징이 필요하다 — 그건 `historical` 축의 후속이며, 여기서 흉내내지 않는다.\n */\n if (axisSource(axis) === 'state') {\n /* 봉투를 벗긴다 — `{revision, state}` 안에 축이 있다. 그리고 **실행 중일 때만** 관측이다. */\n /*\n * **라이브는 권위, 히스토리는 파생.**\n *\n * 지금 도는 커널의 상태가 이 축의 진실이다. 그런데 커널이 멈춰 있거나 사용자가 **과거 시각**을\n * 물으면 답할 것이 없어진다 — 그때 저널을 그 시점까지 접어 답한다(`recover`). 둘은 같은 모양이지만\n * **성질이 다르므로 `basis` 로 구별해 낸다**: 파생을 권위처럼 내면 다시 계산한 값을 보고 \"지금 이렇다\"\n * 로 읽게 된다.\n *\n * 규모: 접기 비용은 이벤트 수에 비례한다. 감추지 않고 **어느 리비전까지 접었는지 함께 낸다** —\n * 이 화면이 목록마다 `basis` 를 밝혀 온 규율 그대로다.\n */\n const live = TwinEngine.isRunning(domainId, instanceId) && !at_\n let snap = live ? unwrapState(TwinEngine.snapshot(domainId, instanceId)) : null\n let folded: number | undefined\n if (!snap) {\n try {\n const rec = await TwinEngine.recover(domainId, instanceId, undefined, at_ ?? undefined)\n snap = unwrapState(rec)\n folded = Number((rec as any)?.revision) || undefined\n } catch {\n /* 다시 계산할 것이 없다(모델도 저널도 없다) — 없는 것을 0 으로 메우지 않는다. */\n snap = null\n }\n }\n if (!snap) {\n return { axis, label: info.label, basis: 'state', total: null, observed: false, offset: skip, items: [] }\n }\n /* 축이 사는 자리는 **커널 선언이 말한다**(`path`) — 축 이름으로만 읽으면 중첩된 축이 언제나\n 비어 보인다. 카드는 `axisValueOf` 로 읽는데 여기가 그 규칙을 지나지 않아, 「42」를 센 개념의\n 목록이 「0건」으로 나왔다(에너지의 수요 구간). 규칙의 집은 `axisValueOf` 하나다. */\n const bucket = axisValueOf(snap, info)\n const list: any[] = Array.isArray(bucket) ? bucket : []\n const hitState = q ? list.filter(o => matches(o, q)) : list\n const items = hitState\n .slice(skip, skip + take)\n .map(o => ({ id: idOf(o, info), fields: this.withOrderMaterial(axis, inst.model ?? {}, o) }))\n return {\n axis,\n label: info.label,\n /* 권위(라이브)와 파생(저널)을 구별해 낸다 — 화면이 이 낱말을 그대로 보인다. */\n basis: live ? 'state' : 'journal',\n ...(folded != null ? { foldedRevision: folded } : {}),\n ...(at_ ? { at: at_ } : {}),\n observed: true,\n total: hitState.length,\n offset: skip,\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n items,\n names: namesFor(items, nameIndex(inst.model ?? {}))\n }\n }\n\n /* 아직 문서 안에 사는 축 — 문서를 읽어 자른다. 규모 한계를 `basis` 로 드러낸다. */\n const raw = at(inst.model ?? {}, documentPath(axis))\n const all = Array.isArray(raw) ? raw : raw ? [raw] : []\n const hit = q ? all.filter(o => matches(o, q)) : all\n return {\n axis,\n label: info.label,\n basis: 'document',\n total: hit.length,\n offset: skip,\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n ...(() => {\n /*\n * **한 벌뿐인 선언은 축 이름이 곧 식별자다.**\n *\n * `productionSpec` 처럼 문서에 객체 하나로 있는 축은 `id`/`key` 가 없다. 그것을 그대로\n * 목록에 실으면 \"식별자 없음 — 가리킬 수 없습니다\" 라는 줄 하나가 뜨고, 정작 그 선언을\n * 열어 볼 방법이 없다. 하나뿐인 것은 축 자신으로 가리킨다(상세도 같은 규칙으로 찾는다).\n */\n const singular = !Array.isArray(raw) && !!raw\n const items = hit\n .slice(skip, skip + take)\n .map(o => ({ id: idOf(o) ?? (singular ? axis : null), fields: this.withBinding(axis, inst.model ?? {}, o) }))\n return { items, names: namesFor(items, nameIndex(inst.model ?? {})), singular }\n })()\n }\n }\n\n /**\n * 행에서 **내부 배관을 걷어낸다** — 사용자가 볼 것은 현장의 사실이지 우리 스키마가 아니다.\n *\n * 손으로 목록을 두지 않는다. 관계와 그 조인 컬럼이 무엇인지는 **엔티티 메타데이터**가 알고,\n * 표로 두면 컬럼이 늘 때마다 여기를 고쳐야 하며 잊으면 그대로 새어 나간다 — 실제로\n * `domainId`·`instanceRowId` 같은 내부 UUID 가 화면까지 갔다.\n *\n * 식별자도 뺀다: 항목 자신의 id 는 이미 `id`/`itemId` 로 나가므로 두 번 보일 이유가 없다.\n */\n private strip(entityClass: any, idColumn: string, r: any): any {\n const meta = getRepository(entityClass).metadata\n const hidden = new Set<string>(['id', 'createdAt', 'updatedAt', 'creator', 'updater', 'creatorId', 'updaterId', idColumn])\n for (const rel of meta.relations) {\n hidden.add(rel.propertyName)\n for (const jc of rel.joinColumns) hidden.add(jc.propertyName)\n }\n /* `@RelationId` 로 승격한 내부 UUID(`domainId`·`instanceRowId`·`areaRowId`) — 관계 목록에는 없고\n 여기에만 있다. 이 한 줄이 없어서 실제로 화면까지 샜다. */\n for (const rid of meta.relationIds) hidden.add(rid.propertyName)\n const out: any = {}\n for (const [k, v] of Object.entries(r)) if (!hidden.has(k)) out[k] = v\n return out\n }\n\n\n /**\n * **자재는 자기 GS1 품목 참조를 안다** — 읽기 경계에서 이어 붙인다.\n *\n * 정본은 `productionSpec.binding` 하나다(커널이 EPC↔자재를 그 표로 잇는다). 그런데 그 사실은\n * **자재마다의 속성**이다: 이 자재가 GS1 품목 몇 번인가, 그래서 개체로 추적되는가(= 계보를 비교할\n * 수 있는가). 자재 목록에 그것이 없으면 자재는 자기 정체를 모르고, 사용자는 그 사실을 딴 축에서\n * 찾아야 한다.\n *\n * 그래서 **저장은 한 곳(binding), 표시는 읽는 자리에서 이어 붙임** — 이름표와 같은 방식이다.\n * 값을 복제해 두면 두 곳이 어긋나고, 어긋난 쪽을 아무도 모른다.\n */\n private withBinding(axis: string, model: any, fields: any): any {\n if (axis !== 'materials' || !fields || typeof fields !== 'object') return fields\n const binding: Record<string, string> = model?.productionSpec?.binding ?? {}\n const ref = binding[fields.key ?? fields.id]\n /* 없으면 키를 만들지 않는다 — 빈 값이 있는 것과 선언되지 않은 것은 다르다. */\n return ref ? { ...fields, gs1Ref: ref } : fields\n }\n\n /**\n * **오더가 무엇을 만드나** — GS1 품목 참조를 자재로 다시 계산해 붙인다.\n *\n * 커널의 오더는 품목을 GS1 으로 말한다(`urn:epc:idpat:sgtin:0614141.078101.*`). 사람에게 그 문자열은\n * 아무 뜻이 없고, 그 품목의 이름은 **자재 선언**이 갖고 있다. 둘을 잇는 것은 `productionSpec.binding`\n * (자재 키 → 품목 참조)이므로 **역방향으로 다시 계산한다.**\n *\n * 정본은 그대로 둔다: `gtin` 은 커널이 말한 값이고, 여기서 더하는 것은 **자재 키 하나**다(그 이름은\n * 이름표가 붙인다 — 값을 복제하지 않는다). 다시 계산하지 못하면 아무것도 더하지 않는다: 짐작으로 이으면\n * \"이 오더는 저것을 만든다\" 는 거짓이 되고, 그건 모르는 것보다 나쁘다.\n */\n private withOrderMaterial(axis: string, model: any, fields: any): any {\n if (axis !== 'orders' || !fields || typeof fields !== 'object') return fields\n const binding: Record<string, string> = model?.productionSpec?.binding ?? {}\n const refToMaterial = new Map(Object.entries(binding).map(([mat, r]) => [String(r), mat]))\n /* 단일 품목 작업지시는 `gtin`, 여러 품목이면 라인마다 말한다 — 첫 라인으로 대표하지 않는다. */\n /* 정체성 모양은 하나가 아니다 — 규칙의 집은 `item-ref` 하나다(웹 URI 원본에서 이 자리가 언제나\n 빈칸이었다). */\n const refOf = itemRefOf\n const mat = refToMaterial.get(String(refOf(fields.gtin) ?? ''))\n if (mat) return { ...fields, material: mat }\n const lineMats = (fields.lines ?? [])\n .map((l: any) => refToMaterial.get(String(refOf(l?.gtin) ?? '')))\n .filter(Boolean)\n return lineMats.length ? { ...fields, materials: [...new Set(lineMats)] } : fields\n }\n\n /** 행 하나 → 목록 항목. 컬럼 이름을 화면이 알지 않아도 되게 `id` + 나머지로 낸다. */\n private rowItem(axis: string, r: any): any {\n const { entity, idColumn } = ROW_BACKED[axis]\n return { id: r[idColumn], fields: this.strip(entity, idColumn, r) }\n }\n\n @Query(returns => ScalarObject, {\n nullable: true,\n description:\n 'One item of a standard concept: what the source declared, what the twin observed, what it links to and is linked from (declared relations, both directions), and where it came from. Never invents a value for a field the source did not provide.'\n })\n async twinModelItem(\n @Arg('instanceId') instanceId: string,\n @Arg('axis') axis: string,\n @Arg('itemId') itemId: string,\n @Ctx() context: ResolverContext\n ): Promise<any | null> {\n const domainId = context.state.domain.id\n const info = axisInfo(axis)\n if (!info) throw new Error(`unknown concept axis: \"${axis}\" — the kernel catalog does not declare it`)\n\n const inst = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!inst) return null\n\n const model = inst.model ?? {}\n const row = ROW_BACKED[axis]\n let declared: any = null\n let provenance: any = null\n\n /*\n * **관측 축의 상세** — 일정·실적은 상태에서 찾는다. 커널이 멈춰 있으면 항목이 아니라 **모른다**를\n * 낸다(그 트윈에 그 오더가 없다는 뜻이 아니다 — 지금 관측이 없다는 뜻이다).\n */\n if (axisSource(axis) === 'state') {\n /*\n * 동작하지 않으면 **목록과 같은 길로 저널을 접는다.**\n *\n * 목록만 접고 상세는 안 접었더니, 목록에는 472건이 보이는데 그 줄을 열면 \"자기 속성이 없습니다\"\n * 가 나왔다 — 한 화면에서 두 답이 갈리면 어느 쪽이 맞는지 사용자가 알 수 없다.\n */\n const liveItem = TwinEngine.isRunning(domainId, instanceId)\n let snap = liveItem ? unwrapState(TwinEngine.snapshot(domainId, instanceId)) : null\n if (!snap) {\n try {\n snap = unwrapState(await TwinEngine.recover(domainId, instanceId))\n } catch {\n /* 다시 계산할 것이 없다 — 아래에서 \"모른다\" 를 낸다(0 으로 메우지 않는다). */\n }\n }\n /* 같은 규칙 — 축 이름이 아니라 선언된 자리에서 읽는다(§axisValueOf). */\n const bucket = snap ? axisValueOf(snap, info) : null\n const found = Array.isArray(bucket) ? bucket.find((o: any) => idOf(o, info) === itemId) : undefined\n if (!snap || !found) {\n return {\n instanceId, axis, label: info.label, itemId,\n identity: { standardClass: info.standardClass ?? null, typeRole: info.typeRole ?? null, kind: info.kind, gs1Scheme: info.gs1Scheme ?? null },\n declared: null, observed: found ?? null, observedOnly: true,\n basis: liveItem ? 'state' : 'journal', observedBasis: liveItem ? 'state' : 'journal', observing: liveItem,\n links: { out: [], incoming: [] }, properties: propertiesOf(axis).map((pr: any) => ({ key: pr.key, label: pr.label, kind: pr.kind, uom: pr.uom ?? null, observedBy: pr.observedBy ?? null })),\n /* 어떤 속성이 **효과가 있나** — 등록부가 말한다(§property-effects). 없는 것은 표시만 된다. */\n propertyEffects: propertyEffectsOf(axis),\n names: {}, provenance: { basis: 'state' }\n }\n }\n const names = namesFor([{ id: itemId, fields: found }], nameIndex(inst.model ?? {}))\n return {\n instanceId, axis, label: info.label, itemId,\n identity: { standardClass: info.standardClass ?? null, typeRole: info.typeRole ?? null, kind: info.kind, gs1Scheme: info.gs1Scheme ?? null },\n /*\n * **선언이 없는 축이다.** 두 열 중 왼쪽이 비는 것이 정상이고, 그 사실을 값으로 말한다\n * (`observedOnly`) — 빈 열을 \"원본이 침묵했다\" 로 읽으면 안 된다. 원본은 애초에 이 축을\n * 선언하지 않는다.\n */\n declared: null,\n observed: this.withOrderMaterial(axis, inst.model ?? {}, found),\n observedOnly: true,\n basis: liveItem ? 'state' : 'journal',\n /* 관측 열의 근거는 **한 이름으로** 낸다 — 두 이름을 두면 화면이 한쪽을 잊는다. */\n observedBasis: liveItem ? 'state' : 'journal',\n observing: liveItem,\n properties: propertiesOf(axis).map((pr: any) => ({ key: pr.key, label: pr.label, kind: pr.kind, uom: pr.uom ?? null, observedBy: pr.observedBy ?? null })),\n /* 어떤 속성이 **효과가 있나** — 등록부가 말한다(§property-effects). 없는 것은 표시만 된다. */\n propertyEffects: propertyEffectsOf(axis),\n links: await this.linksOf(domainId, inst, axis, itemId, found),\n resourceClassLabels: this.classLabels(inst.model ?? {}),\n names,\n provenance: { basis: liveItem ? 'state' : 'journal' }\n }\n }\n\n if (row) {\n const found: any = await getRepository(row.entity).findOne({\n where: { domain: { id: domainId } as any, instance: { id: inst.id } as any, [row.idColumn]: itemId } as any\n })\n if (found) {\n const { sourceRef, ingestedAt, ...rest } = this.strip(row.entity, row.idColumn, found)\n declared = rest\n /* 출처는 속성이 아니라 **근거**다 — 두 열이 아니라 아래 근거 묶음으로 간다. */\n provenance = { sourceRef, ingestedAt, basis: 'rows' }\n }\n }\n\n /*\n * 행에 없으면 문서를 본다 — **투영이 낡은 트윈에서도 항목을 볼 수 있어야 한다.** 행만 보고\n * \"없다\" 고 답하면, 문서에는 있는 자리가 화면에서 사라진다(이 프로젝트가 내내 잡아 온 부류).\n */\n if (!declared) {\n const raw = at(model, info.path)\n const all = Array.isArray(raw) ? raw : raw ? [raw] : []\n /* 한 벌뿐인 선언은 축 이름으로 찾는다 — 목록이 그 이름으로 가리켰기 때문이다. */\n const found = all.find(o => idOf(o) === itemId) ?? (!Array.isArray(raw) && raw && itemId === axis ? raw : undefined)\n if (found) {\n declared = typeof found === 'string' ? { id: found } : this.withBinding(axis, model, found)\n provenance = { basis: 'document' }\n }\n }\n\n /* 선언에도 문서에도 없다 — 그런데 **관측에는 있을 수 있다**(원본이 모르는 자원). 그 경우도\n 항목으로 열려야 한다. 둘 다 없으면 진짜로 없는 것이므로 `null`. */\n const seen = await this.observedOf(domainId, instanceId, axis, itemId)\n const observed = 'value' in seen ? seen.value : null\n if (!declared && !observed) return null\n\n /* 이웃을 먼저 구한다 — 이름표가 이웃의 id 까지 덮으려면 반환 전에 손에 있어야 한다. */\n const links = await this.linksOf(domainId, inst, axis, itemId)\n\n /*\n * **구역 이름은 모델에 없다** — 구역은 호스트 개념이고(`TwinArea`), 인제스트가 모델에서 갈라\n * 공간 쪽으로 보낸다. 그래서 모델만 조회하는 이름표에는 `a-floor` 의 이름이 없고, 관계 그림에 그 id 가\n * 그대로 섰다. 그 행에서 가져와 이름표에 합친다(이 트윈의 공간 것만).\n */\n const areaNames: Record<string, string> = {}\n if (inst.spaceId) {\n const areas = await getRepository(TwinArea)\n .find({ where: { domain: { id: domainId } as any, space: { spaceId: inst.spaceId } as any } as any })\n .catch(() => [] as any[])\n for (const a of areas as any[]) if (a?.areaId && a?.name) areaNames[a.areaId] = a.name\n }\n\n return {\n instanceId,\n axis,\n label: info.label,\n itemId,\n /* 정체 — 표준 클래스·식별 스킴은 전부 카탈로그 선언에서 온다. */\n identity: {\n standardClass: info.standardClass ?? null,\n typeRole: info.typeRole ?? null,\n kind: info.kind,\n gs1Scheme: info.gs1Scheme ?? null\n },\n /*\n * **그릇인가** — 문서에 객체 하나로 있는 축(`productionSpec`)인지.\n *\n * `kind` 로는 갈리지 않는다: 커널은 라우트·레시피·공정도 `spec` 이라 부른다(같은 선언 부류라는\n * 뜻). 화면이 `kind` 로 갈랐더니 **라우트 상세가 그릇 틀로 그려져** 가장 중요한 정보(공정 순서)가\n * 개수 칩 하나로 줄어들었다. 그릇인지 아닌지는 모양이 말한다.\n */\n container:\n axisSource(axis) === 'document' && !Array.isArray(at(model, info.path)) && at(model, info.path) != null,\n /* 두 열 — 원본이 말한 값, 트윈이 관측한 값. 한쪽이 없으면 **없다고 낸다**(0 으로 메우지 않는다). */\n declared,\n observed,\n /*\n * 관측 열이 **자기 근거를 말한다** — 목록의 그 낱말 그대로(`state`=라이브 권위, `journal`=다시 계산한\n * 파생). 없으면 비교하지 못한 것이다. 파생이면 몇 번째 리비전까지 접었는지 함께 낸다.\n */\n ...('value' in seen\n ? { observedBasis: seen.basis, ...(seen.foldedRevision != null ? { observedRevision: seen.foldedRevision } : {}) }\n : { observedAbsence: seen.absence }),\n /* 선언된 속성 — 어느 관측 축에서 오는지도 함께(카탈로그가 말한 대로). */\n properties: propertiesOf(axis).map((p: any) => ({ key: p.key, label: p.label, kind: p.kind, uom: p.uom ?? null, observedBy: p.observedBy ?? null })),\n /*\n * **효과가 있는 속성과 표시만 되는 속성은 다르다.** 속성은 열려 있어 아무 사실이나 실어 보낼 수\n * 있지만, 값이 계산을 바꾸려면 그 규칙을 코드가 알아야 한다. 지금 무엇이 그런지 화면이 말할 수\n * 있게 등록부를 함께 낸다 — 사용자가 넣고 나서 아무 일도 안 일어나는 이유를 알 수 있게.\n */\n propertyEffects: propertyEffectsOf(axis),\n links,\n /*\n * **등급 이름은 등급이 갖고 있다.** 공정은 자격을 등급 id 로만 요구하므로(표준이 그렇다),\n * 그 id 를 그대로 화면에 내면 `assembler-op` 이 사용자에게 간다. 등급의 표시명은 등급 선언의\n * `description`(i18n 키)에 있고 그것은 **다른 축**이다 — 화면이 축을 하나 더 읽지 않아도 되게\n * 여기서 이어 붙인다(서버는 이미 모델을 손에 들고 있다).\n */\n resourceClassLabels: this.classLabels(model),\n /*\n * **공정이면 그 공정의 능력도 함께 낸다** — ISA-95 Part 4 `OperationsCapability`.\n *\n * 공정 상세에서 사람이 묻는 것은 \"이 공정이 지금 얼마나 더 할 수 있나\" 이고, 그 답은 명세만\n * 봐서는 안 나온다(약정과 지금 못 쓰는 자원을 빼야 한다). 화면이 축을 하나 더 읽지 않게\n * 여기서 이어 붙인다 — 이름표·등급 라벨을 붙이는 것과 같은 이유다.\n */\n ...(await this.capabilityOfOperation(domainId, instanceId, axis, itemId)),\n /*\n * 상세도 같은 표를 쓴다 — 목록과 상세가 같은 이름으로 말해야 사용자가 같은 것으로 읽는다.\n *\n * **이웃의 이름도 함께 싣는다.** 관계 그림의 이웃은 대개 *들어오는* 링크(이 자리를 기준 자리로\n * 삼는 설비·사람)라, 이 항목 자신의 필드에는 그 id 가 없다 — 필드만 훑으면 그림이 id 로 채워진다.\n */\n names: namesFor(\n [{ id: itemId, fields: declared }, { fields: observed }, { fields: links }],\n { ...nameIndex(model), ...areaNames }\n ),\n provenance\n }\n }\n\n /**\n * **id → 이름**, 모든 축을 한 표로.\n *\n * ── 왜 이 표가 필요한가 ──────────────────────────────────────────────────────\n * 행은 다른 것을 **id 로** 가리킨다(사람의 `personnelClassIds`, 설비의 `homeLocationId`, 공정의\n * `locationType`). 그 id 의 이름은 **가리켜진 축의 행**에 있으므로, 화면이 그것을 알려면 축을\n * 하나씩 더 읽어야 한다 — 그래서 지금까지 표면마다 그냥 id 를 찍었다(`cutter-op`, `cut-station`).\n * 표면을 하나씩 고치는 것은 끝이 없다: 새 화면은 처음부터 다시 id 를 찍는다.\n *\n * 그래서 **서버가 붙인다.** 서버는 이미 모델을 손에 들고 있고, 어느 축이 있는지는 커널 카탈로그가\n * 선언한다(`TWIN_AXES`) — 도메인이 늘어도 이 함수는 그대로다.\n *\n * 값은 그 항목이 **자기 이름이라고 말한 것**이다(`name`·`label`·`description`). 그중 어떤 것은\n * i18n 키이므로(등급의 `description`) 번역은 화면의 일로 남긴다. 이름이 없으면 표에 넣지 않는다 —\n * 없는 것을 지어내지 않고, 그 경우 화면은 id 를 그대로 보인다.\n */\n private nameIndex(model: any): Record<string, string> {\n const out: Record<string, string> = {}\n for (const info of TWIN_AXES as any[]) {\n /* 관측 축(상태·저널)은 문서에 없다 — 경로가 없는 축을 읽으면 모델 루트를 훑는다. */\n if (axisSource(info.axis) !== 'document') continue\n const raw = at(model ?? {}, info.path)\n const list = Array.isArray(raw) ? raw : raw ? [raw] : []\n for (const o of list) {\n const id = idOf(o)\n if (!id || typeof o !== 'object') continue\n const label = o.name ?? o.label ?? o.description\n /* 이름이 id 와 같으면 표에 넣지 않는다 — 같은 값을 두 번 보이는 셈이다. */\n if (typeof label === 'string' && label && label !== id && !out[id]) out[id] = label\n }\n }\n return out\n }\n\n /**\n * 이 응답이 **실제로 가리킨 것만** 골라 낸다.\n *\n * 모델 전체 표를 그대로 실으면 자리가 10만인 현장에서 목록 한 페이지에 10만 줄짜리 이름표가\n * 따라온다. 나온 값에 걸리는 것만 싣는다 — 규모에서 성립하는 유일한 방식이다.\n */\n private namesFor(rows: any[], index: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {}\n const take = (v: any, depth: number): void => {\n if (v == null || depth > 4) return\n if (typeof v === 'string') { if (index[v]) out[v] = index[v]; return }\n if (Array.isArray(v)) { for (const x of v) take(x, depth + 1); return }\n if (typeof v === 'object') for (const x of Object.values(v)) take(x, depth + 1)\n }\n for (const r of rows) { take(r?.fields ?? r, 0); if (typeof r?.id === 'string' && index[r.id]) out[r.id] = index[r.id] }\n return out\n }\n\n /** 등급 id → 표시명 키. 인원·설비·자산·품목 등급을 한 표로 — 어느 자원이든 같은 방식으로 요구된다. */\n private classLabels(model: any): Record<string, string> {\n const out: Record<string, string> = {}\n for (const key of ['personnelClasses', 'equipmentClasses', 'assetClasses', 'materialClasses'])\n /* 표시명은 `name` 이 정본이다 — 옛 모델는 `description` 에 담고 있어 둘 다 본다(읽기 경계 하나). */\n for (const c of (model?.[key] ?? []) as any[]) if (c?.id && (c.name || c.description)) out[c.id] = c.name || c.description\n return out\n }\n\n /**\n * 관측이 본 이 항목 — 커널이 실행 중일 때만. **실행 중이 아니면 `null` 이지 빈 객체가 아니다**\n * (관측이 없는 것과 비교하지 못한 것은 다르다).\n */\n /**\n * 이 공정의 **생산 능력** — 공정 축 항목에만 붙는다.\n *\n * 구간은 **앞으로 24시간**이다. 표준의 약정·가용은 *앞으로 쓸* 용량이므로 지난 구간을 두고 말하면\n * 뜻이 없고, 이 화면에는 사용자가 고른 창이 없다. 그래서 하루를 쓰고 **그 사실을 값과 함께 낸다**\n * (화면이 라벨로 말한다) — 어느 구간의 값인지 모르면 능력은 읽을 수 없다.\n *\n * **수요를 지어내지 않는다.** 여기서 내는 값(상한·약정·달성불가·가용·제약하는 축)은 전부 공급 쪽이다 —\n * 자원 수·사이클·가동률에서 나온다. 수요는 `ok`·병목·하루 상한에만 쓰이고 그것들은 내지 않으므로,\n * 계산에 넘기는 수요 `1` 은 결과에 새지 않는다(성과 화면은 사용자가 걸어 둔 목표를 쓴다 — 그 화면은\n * \"목표를 낼 수 있나\" 에 답하고 여기서는 \"얼마나 더 할 수 있나\" 에 답한다).\n *\n * 안 실행 중이면 붙이지 않는다 — 능력은 지금 자원의 사실에서 나오고, 없는 것을 지어내지 않는다.\n */\n private async capabilityOfOperation(\n domainId: string,\n instanceId: string,\n axis: string,\n itemId: string\n ): Promise<{ capability?: any } > {\n if (axis !== 'operations') return {}\n if (!TwinEngine.isRunning(domainId, instanceId)) return {}\n const from = new Date()\n const to = new Date(from.getTime() + 24 * 3_600_000)\n const monday = Date.UTC(from.getUTCFullYear(), from.getUTCMonth(), from.getUTCDate() - ((from.getUTCDay() + 6) % 7))\n try {\n const rows = await TwinEngine.operationsCapability(\n domainId,\n { instanceId },\n 1,\n monday,\n { fromTime: from.toISOString(), toTime: to.toISOString() }\n )\n const report = rows.find((r: any) => r.instanceId === instanceId)?.report\n const entry = report?.perOperation?.find((o: any) => o.operation === itemId)\n if (!entry) return {}\n /* 병목·상한은 **넣지 않는다** — 그 둘만 수요에 달려 있고, 여기서는 수요를 모른다. */\n return { capability: { window: report.window, operationsType: report.operationsType, ...entry } }\n } catch {\n /* 능력을 못 냈다고 상세가 안 열릴 이유는 없다 — 없으면 없는 대로 낸다(화면이 그 줄을 안 그린다). */\n return {}\n }\n }\n\n /**\n * 이 항목을 트윈이 **관측한 값** — 그리고 **무엇을 근거로** 아는지.\n *\n * 봉투를 푸는 것을 빠뜨려서(`unwrapState`) 문서 축의 관측 열이 통째로 비어 있던 자리다(사람을 열면\n * 트윈이 아는 것이 전부 `—` 였다).\n *\n * 근거를 값과 함께 낸다 — 목록이 오래 해 온 그대로다(§twinModelItemList). 라이브(권위)와 저널\n * 폴드(파생)는 **같은 모양의 객체**라서, 근거가 없으면 다시 계산한 값을 \"지금 이렇다\" 로 읽는다. 근거를\n * 실을 자리가 없던 동안에는 멈춘 트윈의 저널을 아예 접지 않고 `—` 로 두는 편이 정직했다. 이제\n * 자리가 있으니 접는다 — 멈춘 트윈에도 마지막으로 알던 사실이 있고, 그것을 감출 이유는 없다.\n *\n * 다시 계산할 것이 없으면(모델도 저널도 없다) `null` 이다 — **없는 것과 비교하지 못한 것은 다르다.**\n */\n private async observedOf(\n domainId: string,\n instanceId: string,\n axis: string,\n itemId: string\n ): Promise<{ value: any; basis: 'state' | 'journal'; foldedRevision?: number } | { absence: 'not-running' | 'not-observed' }> {\n const live = TwinEngine.isRunning(domainId, instanceId)\n let state: any = null\n let folded: number | undefined\n if (live) {\n state = unwrapState(TwinEngine.snapshot(domainId, instanceId))\n } else {\n try {\n const rec = await TwinEngine.recover(domainId, instanceId)\n folded = Number((rec as any)?.revision) || undefined\n /*\n * **이벤트를 하나도 접지 않은 폴드는 관측이 아니다.** 저널이 비어도 복원은 선언을 다시 투영한\n * 기준선을 돌려준다 — 그것을 \"트윈이 관측한 값\" 열에 실으면 **선언이 관측으로 위장한다**\n * (원본이 말한 값이 오른쪽에도 똑같이 앉아, 견준 것처럼 보인다). 접은 것이 없으면 없다고 한다.\n */\n if (folded == null) return { absence: 'not-running' as const }\n state = unwrapState(rec)\n } catch {\n return { absence: 'not-running' as const }\n }\n }\n /* 같은 규칙 — 선언된 자리에서 읽는다. 축 이름으로 읽으면 중첩된 축이 언제나 「관측 없음」이 된다. */\n const bucket = state ? axisValueOf(state, axisInfo(axis) ?? { axis }) : null\n /*\n * **왜 관측이 없는지 말한다.** 예전에는 그냥 `null` 이었고 화면은 그것을 \"트윈이 실행 중이지 않아\"\n * 로 읽었다 — 실행 중인데도 그렇게 말했다(공정 상세에서 관측됨). 공정·레시피처럼 **관측 축이\n * 아닌 것**은 트윈이 돌든 말든 관측이 없다. 이유가 다르면 화면이 다르게 말해야 한다.\n */\n if (!Array.isArray(bucket)) return { absence: 'not-observed' as const }\n /* 같은 규칙 — 선언이 말하는 자리로 찾는다. `id` 로만 찾으면 수요 구간을 열 수 없다. */\n const value = bucket.find((x: any) => idOf(x, axisInfo(axis)) === itemId)\n if (!value) return { absence: 'not-observed' as const }\n return { value, basis: live ? 'state' : 'journal', ...(folded != null ? { foldedRevision: folded } : {}) }\n }\n\n /**\n * 이어진 것 — **양방향.** 선언된 관계(`TWIN_RELATIONS`)만 따라간다.\n *\n * 관계를 코드가 알지 않으므로 도메인이 늘어도 여기 손댈 것이 없다. 대신 **선언에 없는 관계는\n * 그리지 않는다** — 지도에 없는 길을 그리는 것보다 없다고 두는 것이 정직하다.\n *\n * 들어오는 쪽(누가 나를 가리키나)은 그 축의 항목을 살펴야 안다. 규모 규율상 **깊이 1 · 방향별\n * 상한**이고, 넘치면 몇이 더 있는지 말한다(목록으로 보낼 수 있게).\n */\n private async linksOf(\n domainId: string,\n inst: any,\n axis: string,\n itemId: string,\n /*\n * 이 항목 자신 — **상태 축은 문서에서 찾을 수 없다.** 부르는 쪽이 이미 손에 들고 있으므로 넘겨\n * 받는다. 없으면 예전처럼 문서에서 찾는다(문서 축의 거동은 그대로).\n */\n self0?: any\n ): Promise<any> {\n const NEIGHBOR_MAX = 20\n const model = inst.model ?? {}\n\n /*\n * 관측 축의 항목들 — **한 번만** 읽는다(관계마다 다시 접으면 저널을 여러 번 접는다).\n * 라이브가 있으면 그것, 없으면 저널 폴드. 없으면 빈 배열(없는 것을 지어내지 않는다).\n */\n let observedState: any\n let observedLoaded = false\n const observedBucket = async (a: string): Promise<any[]> => {\n if (!observedLoaded) {\n observedLoaded = true\n try {\n observedState = TwinEngine.isRunning(domainId, inst.instanceId)\n ? unwrapState(TwinEngine.snapshot(domainId, inst.instanceId))\n : unwrapState(await TwinEngine.recover(domainId, inst.instanceId))\n } catch {\n observedState = null\n }\n }\n const b = observedState ? (observedState as any)[a] : null\n return Array.isArray(b) ? b : []\n }\n\n /*\n * **관계는 선언 어휘로 푼다** — 문서에서 이 항목을 찾아 그것을 본다.\n *\n * 관계 선언의 필드 이름(`locations.parentId`)은 **원본 문서의 어휘**다. 행은 같은 사실을 자기\n * 컬럼 이름으로 담는다(자리의 구역은 `area` FK). 행을 보고 `parentId` 를 찾으면 늘 비어서\n * \"이어진 것이 없다\" 로 조용히 답한다 — 실제로 그랬다.\n *\n * 어느 쪽이 정본인가로 구분하면 답이 분명하다: 관계를 선언한 어휘가 문서 어휘이므로 **문서에서\n * 푼다.** 행에만 있고 문서에 없는 항목(있을 수 있다)은 이어진 것이 비지만, 그것은 사실이다.\n */\n const axisPath = axisSource(axis) === 'document' ? axisInfo(axis)?.path : undefined\n const rawSelf = axisPath ? at(model, axisPath) : undefined\n const selfAll = Array.isArray(rawSelf) ? rawSelf : rawSelf ? [rawSelf] : []\n const self = self0 ?? selfAll.find((o: any) => idOf(o) === itemId)\n\n /* 나가는 쪽 — 내 필드가 가리키는 것. 선언이 필드 이름을 알려 준다. */\n const out = relationsFrom(axis).map((r: any) => {\n const raw = self ? this.fieldValue(self, r.field) : []\n const ids = raw.filter((v: any) => v != null).map(String)\n return {\n via: r.via,\n field: r.field,\n optional: !!r.optional,\n /* 대상이 축이면 그 축의 항목으로 갈 수 있다. 타입·외부(구역)면 **갈 곳이 다르다** —\n 화면이 링크를 만들지 말지 알아야 하므로 대상 종류를 그대로 낸다(막다른 링크 금지). */\n target: r.target,\n ids: ids.slice(0, NEIGHBOR_MAX),\n total: ids.length\n }\n }).filter((l: any) => l.total > 0)\n\n /* 들어오는 쪽 — 나를 가리키는 항목들. 그 축이 행이면 DB 가 세고, 문서면 문서를 전수 조회한다. */\n const incoming: any[] = []\n for (const r of relationsTo(axis)) {\n const fromInfo = axisInfo(r.from)\n if (!fromInfo) continue\n const hits: string[] = []\n const row = ROW_BACKED[r.from]\n if (row) {\n const repo = getRepository(row.entity)\n /*\n * **FK 는 부르지 않으면 오지 않는다.** 관계 필드를 로딩하지 않고 조회하면 값이 늘 `undefined`\n * 라서 \"나를 가리키는 것이 하나도 없다\" 로 조용히 답한다 — 실제로 그랬다(설비 둘이 이 자리를\n * 기준으로 삼는데 이웃이 비어 있었다).\n *\n * 어느 필드가 관계인지는 **엔티티 메타데이터**가 안다. 축마다 표를 두면 축이 늘 때마다\n * 여기를 고쳐야 하고, 고치는 것을 잊으면 같은 침묵이 다시 생긴다.\n */\n const relationNames = new Set(repo.metadata.relations.map(rel => rel.propertyName))\n const field = r.field.replace(/\\[\\]$/, '').split('.')[0]\n const rows: any[] = await repo.find({\n where: { domain: { id: domainId } as any, instance: { id: inst.id } as any },\n ...(relationNames.has(field) ? { relations: [field] } : {}),\n take: 5000\n })\n for (const x of rows) {\n /* 행에서는 관계가 FK 객체이거나 컬럼이다 — 이름 후보를 순서대로 본다. */\n const v = this.relationValueOfRow(x, r.field, axis)\n if (v.includes(itemId)) hits.push(x[row.idColumn])\n }\n } else {\n /*\n * 들어오는 쪽을 훑는다 — **어디를 훑을지는 그 축의 `source` 가 정한다.**\n *\n * 문서 축은 모델에서, 관측 축은 **상태에서** 훑는다(작업 → 이 오더, 작업 → 이 자리). 한동안\n * 관측 축을 건너뛰었더니 오더 상세가 \"닿는 관계가 없습니다\" 라고 답했다 — `tasks.orderId` 를\n * 선언해 두고도 그 관계를 그리지 않은 것이다. 선언한 것을 그리지 않으면 선언이 거짓이 된다.\n *\n * 규모: 상태는 지금의 사실만 담아 유한하고, 상한과 총계는 문서 축과 같은 규율을 쓴다\n * (넘치면 몇이 더 있는지 말한다). 저널 전체를 전수 조회하는 일은 여기서 하지 않는다.\n */\n const raw =\n axisSource(r.from) === 'document' ? at(model, fromInfo.path) : (await observedBucket(r.from))\n const all = Array.isArray(raw) ? raw : raw ? [raw] : []\n for (const x of all) if (this.fieldValue(x, r.field).map(String).includes(itemId)) {\n const id = idOf(x)\n if (id) hits.push(id)\n }\n }\n if (hits.length) incoming.push({ via: r.via, from: r.from, field: r.field, ids: hits.slice(0, NEIGHBOR_MAX), total: hits.length })\n }\n\n return { out, incoming }\n }\n\n /**\n * 선언 필드 경로 → 값들. `inputs[].material` 처럼 **배열을 지나는 경로**를 다룬다.\n * 배열 표기(`[]`)가 관계 선언의 문법이므로 그것을 따르는 것이 곧 선언을 존중하는 것이다.\n */\n private fieldValue(obj: any, field: string): any[] {\n let cur: any[] = [obj]\n for (const seg of field.split('.')) {\n const isArray = seg.endsWith('[]')\n const key = isArray ? seg.slice(0, -2) : seg\n const next: any[] = []\n for (const c of cur) {\n if (c == null) continue\n const v = c[key]\n if (v == null) continue\n if (Array.isArray(v)) next.push(...v)\n else next.push(v)\n }\n cur = next\n }\n return cur.map(v => (typeof v === 'object' && v !== null ? idOf(v) ?? v : v)).filter(v => v != null)\n }\n\n /**\n * 행에서 관계 값을 꺼낸다 — FK 는 객체(관계 미로딩이면 없음)이고 문서 필드명과 컬럼명이 다를 수 있다.\n *\n * 여기서 컬럼 이름을 **축마다 표로 두지 않는다.** 후보를 순서대로 보는 편이 축이 늘 때 고칠 것이\n * 없다: 관계 필드 이름 그대로 · 그 이름의 FK 객체의 id 컬럼.\n */\n private relationValueOfRow(rowObj: any, field: string, targetAxis: string): string[] {\n const key = field.replace(/\\[\\]$/, '').split('.')[0]\n const v = rowObj[key]\n if (v == null) return []\n if (typeof v === 'string') return [v]\n if (Array.isArray(v)) return v.map(x => (typeof x === 'string' ? x : idOf(x) ?? '')).filter(Boolean)\n /* FK 객체 — 대상 축의 id 컬럼으로 읽는다(관계를 로딩하지 않았으면 값이 없고, 그것도 사실이다). */\n const idCol = ROW_BACKED[targetAxis]?.idColumn\n const got = idCol ? v[idCol] : idOf(v)\n return got ? [String(got)] : []\n }\n}\n"]}
|
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TwinModelQuery = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const axis_journal_evidence_js_1 = require("./axis-journal-evidence.js");
|
|
6
|
+
const status_tally_js_1 = require("./status-tally.js");
|
|
7
|
+
const twin_event_js_1 = require("../twin-event/twin-event.js");
|
|
5
8
|
const type_graphql_1 = require("type-graphql");
|
|
6
9
|
const shell_1 = require("@things-factory/shell");
|
|
7
10
|
const index_js_1 = require("../../engine/index.js");
|
|
11
|
+
const model_gap_js_1 = require("../../engine/model-gap.js");
|
|
8
12
|
const twin_kernel_1 = require("@operato/twin-kernel");
|
|
9
13
|
const twin_instance_js_1 = require("../twin-instance/twin-instance.js");
|
|
10
14
|
const twin_space_js_1 = require("../twin-space/twin-space.js");
|
|
@@ -97,6 +101,26 @@ function valuesAt(obj, field) {
|
|
|
97
101
|
return cur.filter(v => v != null);
|
|
98
102
|
}
|
|
99
103
|
const idOf = (o) => (typeof o === 'string' ? o : o?.id ?? o?.key ?? o?.gtin ?? null);
|
|
104
|
+
/** 상태가 빈 축의 이유 — 저널에 그 사실이 있으면 그렇게 말한다. 판단할 수 없으면 예전 그대로. */
|
|
105
|
+
async function emptyStateReason(domainId, instanceId, axis) {
|
|
106
|
+
try {
|
|
107
|
+
const seen = await (0, axis_journal_evidence_js_1.axisSeenInJournal)((0, shell_1.getRepository)(twin_event_js_1.TwinEvent), { domain: { id: domainId }, instanceId }, axis);
|
|
108
|
+
/* 판단할 수 없는 축(`null`)은 예전 답을 그대로 쓴다 — 모르는 것을 새 사실로 만들지 않는다. */
|
|
109
|
+
return seen ? 'observed-not-in-state' : 'none-yet';
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
/* 저널을 못 읽었다고 카드가 없는 말을 하지는 않는다. */
|
|
113
|
+
return 'none-yet';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* 되세운 상태를 담아 둔다 — **열쇠에 저널 끝 리비전이 들어 있어** 새 사건이 오면 저절로 낡는다.
|
|
118
|
+
*
|
|
119
|
+
* 접기는 저널 전체를 훑는 일이라(리비전 12만에서 2~3초) 모델 화면을 열 때마다 그 값을 낼 수 없다.
|
|
120
|
+
* 프로세스 안에만 두고 몇 개만 남긴다 — 다시 뜨면 다시 접는다(정확함이 캐시보다 앞선다).
|
|
121
|
+
*/
|
|
122
|
+
const RECALL_CACHE = new Map();
|
|
123
|
+
const RECALL_CACHE_MAX = 8;
|
|
100
124
|
let TwinModelQuery = class TwinModelQuery {
|
|
101
125
|
/**
|
|
102
126
|
* 이 선이 **얼마나 이어져 있나** — 그리고 **얼마나 끊겨 있나.**
|
|
@@ -184,6 +208,62 @@ let TwinModelQuery = class TwinModelQuery {
|
|
|
184
208
|
}
|
|
185
209
|
return { snap, folded, observing };
|
|
186
210
|
})());
|
|
211
|
+
/*
|
|
212
|
+
* ── **라이브가 잊은 것을 저널이 안다** (2026-08-23) ─────────────────────────
|
|
213
|
+
*
|
|
214
|
+
* 미러의 관측은 메모리에만 산다. 재기동하면 빈 채로 시작하고, 원본이 다시 말해 줄 때 채워진다 —
|
|
215
|
+
* 그런데 읽기 커서가 정직해진 뒤로는 원본이 **지난 것을 다시 말하지 않는다.** 그래서 재고 741건이
|
|
216
|
+
* 저널에 있는데 화면은 「0」을 보였다. 사용자가 「재고현황이 없다」고 물은 자리가 이것이다.
|
|
217
|
+
*
|
|
218
|
+
* 그 0 은 사실이 아니라 **우리가 잊은 것**이다. 저널을 접으면 그대로 되살아난다(실측: 리비전
|
|
219
|
+
* 97,689 을 2.4초에 접어 물품 741 · 작업 9,145 · 지시 2,856).
|
|
220
|
+
*
|
|
221
|
+
* ── 그래서 접는다. 다만 **언제 들은 값인지 함께 낸다** ──────────────────────
|
|
222
|
+
* 저널을 접는 것은 **원천이 우리에게 말한 것을 다시 세우는 일**이지, 없는 값을 심는 일이 아니다.
|
|
223
|
+
* 그러나 물품·재고처럼 **절대값인 축**은 우리가 못 듣는 사이 떠났을 수 있다 — 그래서 값과 함께
|
|
224
|
+
* `heardAt`(그 접기의 시계)을 낸다. 사용자가 신선도를 스스로 판정할 수 있어야 하고, 화면은 그것을
|
|
225
|
+
* 값 옆에 적는다. 시각 없이 수만 내면 낡은 값을 지금으로 읽는다.
|
|
226
|
+
*
|
|
227
|
+
* 접는 조건을 좁게 둔다: **관측 축이 비어 있고, 저널에 그 축의 사실이 있을 때만**(그 판정은 색인
|
|
228
|
+
* 한 줄이다). 그리고 한 요청에 **한 번만** 접는다 — 위 `stateOnce` 와 같은 규율이다.
|
|
229
|
+
*/
|
|
230
|
+
let journalPromise = null;
|
|
231
|
+
const journalOnce = () => (journalPromise ??= (async () => {
|
|
232
|
+
try {
|
|
233
|
+
const tip = await (0, shell_1.getRepository)(twin_event_js_1.TwinEvent).findOne({
|
|
234
|
+
where: { domain: { id: domainId }, instanceId },
|
|
235
|
+
order: { revision: 'DESC' }
|
|
236
|
+
});
|
|
237
|
+
if (!tip?.revision)
|
|
238
|
+
return null;
|
|
239
|
+
/*
|
|
240
|
+
* **한 번 접은 것을 다시 접지 않는다.** 접기는 저널 전체를 훑는 일이다(리비전 12만에서 2~3초).
|
|
241
|
+
* 이 화면은 사람이 여러 번 들어오는 자리이므로 그대로 두면 매번 그 값을 낸다 — 그리고 저널이
|
|
242
|
+
* 수백만 행이 되면 그 비용이 화면을 못 쓰게 만든다.
|
|
243
|
+
*
|
|
244
|
+
* 열쇠에 **저널 끝의 리비전**을 넣는다: 새 사건이 오면 열쇠가 달라지므로 캐시가 저절로 낡는다
|
|
245
|
+
* (캐시가 사실을 이기지 않는다). 프로세스 안에만 두고 몇 개만 남긴다.
|
|
246
|
+
*/
|
|
247
|
+
const key = `${domainId}:${instanceId}:${tip.revision}`;
|
|
248
|
+
const hit = RECALL_CACHE.get(key);
|
|
249
|
+
if (hit)
|
|
250
|
+
return hit;
|
|
251
|
+
const snap = (0, warm_start_js_1.unwrapState)(await index_js_1.TwinEngine.recover(domainId, instanceId, tip.revision));
|
|
252
|
+
if (!snap)
|
|
253
|
+
return null;
|
|
254
|
+
/* 그 접기의 시계가 「언제 들은 값인가」다. 없으면 저널 끝의 사건 시각으로 답한다. */
|
|
255
|
+
const out = { snap, heardAt: snap.nowTime ?? tip.eventTime ?? null };
|
|
256
|
+
RECALL_CACHE.set(key, out);
|
|
257
|
+
/* 오래된 열쇠부터 버린다 — 트윈 몇 개를 번갈아 봐도 메모리가 자라지 않게. */
|
|
258
|
+
while (RECALL_CACHE.size > RECALL_CACHE_MAX)
|
|
259
|
+
RECALL_CACHE.delete(RECALL_CACHE.keys().next().value);
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
/* 접지 못했으면 아무 말도 만들지 않는다 — 라이브가 말한 것을 그대로 둔다. */
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
})());
|
|
187
267
|
const concepts = await Promise.all(TWIN_AXES.map(async (a) => {
|
|
188
268
|
/*
|
|
189
269
|
* **이 종류에 없는 개념인가** — 「아직 없음」과 「해당 없음」은 다른 말이다.
|
|
@@ -205,6 +285,17 @@ let TwinModelQuery = class TwinModelQuery {
|
|
|
205
285
|
count: null,
|
|
206
286
|
notApplicable: true,
|
|
207
287
|
emptyBecause: 'not-applicable',
|
|
288
|
+
/*
|
|
289
|
+
* **그 개념의 성질** — 선언인가 관측인가 (2026-08-22).
|
|
290
|
+
*
|
|
291
|
+
* `basis` 와 다르다: `basis` 는 「이 값이 어디서 왔나」이고 트윈마다·시점마다 달라진다(같은
|
|
292
|
+
* 축이 한 트윈에서 `journal`, 다른 트윈에서 `state` 로 온다). 그것으로 묶으면 같은 축이 화면
|
|
293
|
+
* 마다 다른 묶음에 들어간다. `source` 는 트윈과 무관하게 고정이므로 묶는 축이 된다.
|
|
294
|
+
*
|
|
295
|
+
* 화면이 축 이름을 열거하지 않아도 되고, 축이 늘면 자동으로 맞는 묶음에 들어간다 —
|
|
296
|
+
* 카탈로그가 정본이다.
|
|
297
|
+
*/
|
|
298
|
+
source: axisSource(a.axis),
|
|
208
299
|
basis: 'declaration'
|
|
209
300
|
};
|
|
210
301
|
}
|
|
@@ -238,6 +329,15 @@ let TwinModelQuery = class TwinModelQuery {
|
|
|
238
329
|
* 0 으로 내면 "작업이 없는 공장" 으로 읽히고, 그건 거짓이다(관측이 없는 것과 0 건은 다르다).
|
|
239
330
|
* 이 화면이 관측 열에서 내내 지켜 온 구분을 카드에서도 지킨다.
|
|
240
331
|
*/
|
|
332
|
+
/*
|
|
333
|
+
* **「아직 없다」와 「왔는데 상태에 없다」는 다른 사실이다** (2026-08-22).
|
|
334
|
+
*
|
|
335
|
+
* 화면이 「작업 — 아직 하나도 없습니다」라고 말했는데 저널에는 `task.status` 5,786건이 있었고
|
|
336
|
+
* 마지막 상태가 `in-progress` 였다(원인은 커널의 내보내기였고 그 레인에 넘겼다). 카드가 단정한
|
|
337
|
+
* 탓에 사용자가 그 차이를 직접 조사해야 했다 — 화면이 아는 것을 말하지 않은 자리다.
|
|
338
|
+
*
|
|
339
|
+
* 그래서 상태가 빈 축은 저널을 **한 건만** 물어본다(색인 한 줄, `journal-count` 의 문).
|
|
340
|
+
*/
|
|
241
341
|
if (axisSource(a.axis) === 'state') {
|
|
242
342
|
/* 스냅샷은 `{revision, state}` 봉투다 — 벗기지 않으면 축이 한 겹 안에 있어 언제나 `null` 이
|
|
243
343
|
된다(커널은 도는데 카드가 "모름" 으로 보였다). 벗기는 규칙의 집은 `warm-start` 하나다. */
|
|
@@ -250,7 +350,25 @@ let TwinModelQuery = class TwinModelQuery {
|
|
|
250
350
|
const { snap, folded, observing } = await stateOnce();
|
|
251
351
|
/* 축이 사는 자리는 **커널 선언이 말한다**(`path`) — 축 이름으로만 읽으면 중첩된 축이
|
|
252
352
|
언제나 「관측 없음」이 된다(에너지의 수요 구간이 그렇다). 규칙은 `axisValueOf` 한 곳. */
|
|
253
|
-
|
|
353
|
+
let bucket = snap ? (0, axis_read_js_1.axisValueOf)(snap, a) ?? null : null;
|
|
354
|
+
let heardAt = null;
|
|
355
|
+
let fromJournal = false;
|
|
356
|
+
/*
|
|
357
|
+
* 라이브가 잊은 축은 **저널에서 되세운다**(§`journalOnce`). 그 축의 사실이 저널에 있을 때만
|
|
358
|
+
* 접고, 값과 함께 「언제 들은 값인가」를 낸다 — 시각 없이 수만 내면 낡은 값을 지금으로 읽는다.
|
|
359
|
+
*/
|
|
360
|
+
if (!folded && Array.isArray(bucket) && bucket.length === 0) {
|
|
361
|
+
const seen = await (0, axis_journal_evidence_js_1.axisSeenInJournal)((0, shell_1.getRepository)(twin_event_js_1.TwinEvent), { domain: { id: domainId }, instanceId }, a.axis).catch(() => null);
|
|
362
|
+
if (seen) {
|
|
363
|
+
const j = await journalOnce();
|
|
364
|
+
const jb = j?.snap ? (0, axis_read_js_1.axisValueOf)(j.snap, a) ?? null : null;
|
|
365
|
+
if (Array.isArray(jb) && jb.length) {
|
|
366
|
+
bucket = jb;
|
|
367
|
+
heardAt = j?.heardAt ?? null;
|
|
368
|
+
fromJournal = true;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
254
372
|
return {
|
|
255
373
|
axis: a.axis,
|
|
256
374
|
label: a.label,
|
|
@@ -259,13 +377,34 @@ let TwinModelQuery = class TwinModelQuery {
|
|
|
259
377
|
standardClass: a.standardClass,
|
|
260
378
|
typeRole: a.typeRole ?? null,
|
|
261
379
|
count: Array.isArray(bucket) ? bucket.length : null,
|
|
380
|
+
/*
|
|
381
|
+
* **수 하나가 뜻을 바꾸는 자리** (2026-08-23).
|
|
382
|
+
*
|
|
383
|
+
* 미러가 완료된 작업까지 상태에 들고 있게 되면서 「작업 2,820」이 되었다. 이 카드는 상태의
|
|
384
|
+
* 인구조사이므로 그 수가 맞다 — 그런데 사람은 그것을 「지금 할 일 2,820건」으로 읽는다.
|
|
385
|
+
* 수를 줄여 거짓으로 만드는 대신 **무엇으로 이루어진 수인지** 함께 낸다.
|
|
386
|
+
*
|
|
387
|
+
* 낱말은 커널의 것을 그대로 쓴다(`created`·`assigned`·`in-progress`·`completed`). 화면이
|
|
388
|
+
* 라벨을 입히고, 없으면 낱말이 그대로 보여 누락이 드러난다.
|
|
389
|
+
*/
|
|
390
|
+
...(0, status_tally_js_1.statusTally)(bucket),
|
|
262
391
|
/*
|
|
263
392
|
* **비었으면 왜 비었는지 말한다.** 0 과 `null` 만 내면 화면은 "없다" 까지만 말하고, 사용자는
|
|
264
393
|
* "안 적어 놨나 · 아직 안 일어났나 · 못 세었나" 를 구별할 수 없다. 이 화면이 관측 열에서
|
|
265
394
|
* 내내 지켜 온 구분(§observedAbsence)을 카드에서도 지킨다.
|
|
266
395
|
*/
|
|
267
|
-
...(Array.isArray(bucket)
|
|
268
|
-
|
|
396
|
+
...(Array.isArray(bucket)
|
|
397
|
+
? bucket.length
|
|
398
|
+
? {}
|
|
399
|
+
: { emptyBecause: await emptyStateReason(domainId, instanceId, a.axis) }
|
|
400
|
+
: { emptyBecause: 'not-observed' }),
|
|
401
|
+
source: axisSource(a.axis),
|
|
402
|
+
basis: folded || fromJournal ? 'journal' : 'state',
|
|
403
|
+
/*
|
|
404
|
+
* **언제 들은 값인가** — 저널에서 되세운 축만 갖는다. 라이브가 답한 축은 지금이므로 없다.
|
|
405
|
+
* 이 값이 없으면 화면이 낡은 수를 지금으로 읽는다(그 구별이 이 카드의 전부다).
|
|
406
|
+
*/
|
|
407
|
+
...(fromJournal && heardAt ? { heardAt, recalled: true } : {}),
|
|
269
408
|
observing,
|
|
270
409
|
/* 선언이 아니라 관측인 축 — 화면이 "원본이 침묵했다" 로 읽지 않게 사실로 말한다. */
|
|
271
410
|
observedOnly: true,
|
|
@@ -295,6 +434,7 @@ let TwinModelQuery = class TwinModelQuery {
|
|
|
295
434
|
emptyBecause: entity && inDocument > 0 ? 'not-projected' : raw == null ? 'not-declared' : 'declared-empty'
|
|
296
435
|
}),
|
|
297
436
|
/* 'rows' = DB 가 셌다(질의 가능) · 'document' = 문서를 세었다(아직 이주 전). */
|
|
437
|
+
source: axisSource(a.axis),
|
|
298
438
|
basis: entity ? 'rows' : 'document',
|
|
299
439
|
...(entity ? { documentCount: inDocument, stale } : {}),
|
|
300
440
|
/* 표준 투영이 없는 축은 **숨기지 않고** 그 사실을 낸다(ADR-0031). */
|
|
@@ -313,12 +453,24 @@ let TwinModelQuery = class TwinModelQuery {
|
|
|
313
453
|
* 트윈이 안 실행 중이면 비교할 상대가 없다 — 그때는 `null` 이다(0 이 아니다. 없는 것과
|
|
314
454
|
* 세어 보지 못한 것은 다르다).
|
|
315
455
|
*/
|
|
456
|
+
/*
|
|
457
|
+
* 도출은 **한 벌**이다(`engine/model-gap.ts`). 예전에는 이 자리에 인라인으로 있었는데, 같은 사실을
|
|
458
|
+
* 「현장과 맞춰지고 있나」 화면도 물어야 해서 두 곳이 다른 수를 말할 위험이 생겼다.
|
|
459
|
+
*
|
|
460
|
+
* 이 화면은 **전체 목록**이 필요하다(인스펙션이니까). 그래서 상한 없는 원본을 여기서 만들고,
|
|
461
|
+
* 상한이 걸린 요약은 `modelGapOf` 가 답한다 — 같은 판정(`origin === 'observed'`)을 쓴다.
|
|
462
|
+
*/
|
|
316
463
|
const snap = index_js_1.TwinEngine.snapshot(domainId, instanceId);
|
|
464
|
+
const gap = (0, model_gap_js_1.modelGapOf)(snap);
|
|
317
465
|
const observedOnly = snap
|
|
318
466
|
? {
|
|
319
467
|
equipment: (snap.equipment ?? []).filter((e) => e?.origin === 'observed').map((e) => e.id),
|
|
320
468
|
locations: (snap.locations ?? []).filter((l) => l?.origin === 'observed').map((l) => l.id),
|
|
321
|
-
persons: (snap.persons ?? []).filter((p) => p?.origin === 'observed').map((p) => p.id)
|
|
469
|
+
persons: (snap.persons ?? []).filter((p) => p?.origin === 'observed').map((p) => p.id),
|
|
470
|
+
/* 커널이 담을 줄 몰라 세어 둔 사건·모르는 설비 보고 — 인스펙션이 이미 물을 자리다. */
|
|
471
|
+
unhandled: gap?.unhandled ?? [],
|
|
472
|
+
unknownEquipmentReports: gap?.unknownEquipmentReports ?? null,
|
|
473
|
+
notCovered: gap?.notCovered ?? []
|
|
322
474
|
}
|
|
323
475
|
: null;
|
|
324
476
|
/* 지도의 선 — 선언된 관계 중 **양끝이 이 트윈에 실재하는 것만**. 없는 선을 그리지 않는다. */
|
|
@@ -361,7 +513,7 @@ let TwinModelQuery = class TwinModelQuery {
|
|
|
361
513
|
})(),
|
|
362
514
|
description: inst.description ?? null,
|
|
363
515
|
kind: inst.kind,
|
|
364
|
-
|
|
516
|
+
restartPolicy: inst.restartPolicy,
|
|
365
517
|
source: ref
|
|
366
518
|
? { referenceId: ref.source, adapterType: ref.adapterType, status: ref.status, lastSyncedAt: ref.lastSyncedAt }
|
|
367
519
|
: null,
|