@things-factory/headless-twin 10.0.15 โ 10.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-server/engine/attention-digest.d.ts +4 -4
- package/dist-server/engine/attention-digest.js +7 -7
- package/dist-server/engine/attention-digest.js.map +1 -1
- package/dist-server/engine/canonical-ingest.d.ts +18 -82
- package/dist-server/engine/canonical-ingest.js +183 -18
- package/dist-server/engine/canonical-ingest.js.map +1 -1
- package/dist-server/engine/command-routing.js +1 -1
- package/dist-server/engine/command-routing.js.map +1 -1
- package/dist-server/engine/declared-stimulus.js +1 -1
- package/dist-server/engine/declared-stimulus.js.map +1 -1
- package/dist-server/engine/energy-topology.js +4 -4
- package/dist-server/engine/energy-topology.js.map +1 -1
- package/dist-server/engine/ingest-dedupe.d.ts +38 -0
- package/dist-server/engine/ingest-dedupe.js +145 -0
- package/dist-server/engine/ingest-dedupe.js.map +1 -0
- package/dist-server/engine/ingest-health.d.ts +90 -10
- package/dist-server/engine/ingest-health.js +125 -16
- package/dist-server/engine/ingest-health.js.map +1 -1
- package/dist-server/engine/integration-probes.d.ts +3 -3
- package/dist-server/engine/integration-probes.js +6 -6
- package/dist-server/engine/integration-probes.js.map +1 -1
- package/dist-server/engine/kpi-baseline.js +4 -4
- package/dist-server/engine/kpi-baseline.js.map +1 -1
- package/dist-server/engine/kpi-fold.d.ts +212 -14
- package/dist-server/engine/kpi-fold.js +374 -21
- package/dist-server/engine/kpi-fold.js.map +1 -1
- package/dist-server/engine/kpi-query.d.ts +11 -11
- package/dist-server/engine/kpi-query.js +281 -36
- package/dist-server/engine/kpi-query.js.map +1 -1
- package/dist-server/engine/live-feed-registry.d.ts +1 -1
- package/dist-server/engine/live-feed-registry.js +1 -1
- package/dist-server/engine/live-feed-registry.js.map +1 -1
- package/dist-server/engine/load-meter.d.ts +1 -1
- package/dist-server/engine/load-meter.js.map +1 -1
- package/dist-server/engine/local-declarations.d.ts +7 -7
- package/dist-server/engine/local-declarations.js +15 -14
- package/dist-server/engine/local-declarations.js.map +1 -1
- package/dist-server/engine/log.d.ts +1 -1
- package/dist-server/engine/log.js +1 -1
- package/dist-server/engine/log.js.map +1 -1
- package/dist-server/engine/measured-estimator.js +1 -1
- package/dist-server/engine/measured-estimator.js.map +1 -1
- package/dist-server/engine/measured-yield.js +1 -1
- package/dist-server/engine/measured-yield.js.map +1 -1
- package/dist-server/engine/model-basis.d.ts +1 -1
- package/dist-server/engine/model-basis.js +1 -1
- package/dist-server/engine/model-basis.js.map +1 -1
- package/dist-server/engine/model-gap.d.ts +3 -3
- package/dist-server/engine/model-gap.js +1 -1
- package/dist-server/engine/model-gap.js.map +1 -1
- package/dist-server/engine/model-vocabulary.js +3 -3
- package/dist-server/engine/model-vocabulary.js.map +1 -1
- package/dist-server/engine/oee-accumulator.d.ts +6 -5
- package/dist-server/engine/oee-accumulator.js +6 -5
- package/dist-server/engine/oee-accumulator.js.map +1 -1
- package/dist-server/engine/property-effects.js +2 -2
- package/dist-server/engine/property-effects.js.map +1 -1
- package/dist-server/engine/read-time.d.ts +22 -0
- package/dist-server/engine/read-time.js +81 -0
- package/dist-server/engine/read-time.js.map +1 -0
- package/dist-server/engine/restart-policy.js +1 -1
- package/dist-server/engine/restart-policy.js.map +1 -1
- package/dist-server/engine/runtime-key.js +1 -1
- package/dist-server/engine/runtime-key.js.map +1 -1
- package/dist-server/engine/spec-coverage.d.ts +2 -2
- package/dist-server/engine/spec-coverage.js +1 -1
- package/dist-server/engine/spec-coverage.js.map +1 -1
- package/dist-server/engine/stage-path.d.ts +4 -4
- package/dist-server/engine/stage-path.js +1 -1
- package/dist-server/engine/stage-path.js.map +1 -1
- package/dist-server/engine/state-axes.d.ts +1 -1
- package/dist-server/engine/state-axes.js +2 -2
- package/dist-server/engine/state-axes.js.map +1 -1
- package/dist-server/engine/travel-estimator.d.ts +2 -2
- package/dist-server/engine/travel-estimator.js +1 -1
- package/dist-server/engine/travel-estimator.js.map +1 -1
- package/dist-server/engine/twin-engine.d.ts +307 -54
- package/dist-server/engine/twin-engine.js +822 -196
- package/dist-server/engine/twin-engine.js.map +1 -1
- package/dist-server/engine/warm-start.d.ts +2 -2
- package/dist-server/engine/warm-start.js +5 -5
- package/dist-server/engine/warm-start.js.map +1 -1
- package/dist-server/index.js +1 -1
- package/dist-server/index.js.map +1 -1
- package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js +1 -1
- package/dist-server/migrations/1786000000000-RenameTwinInstanceBoardToModel.js.map +1 -1
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js +3 -3
- package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +1 -1
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js +2 -2
- package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +1 -1
- package/dist-server/migrations/1786300000000-IndexEventTypeByTime.d.ts +5 -0
- package/dist-server/migrations/1786300000000-IndexEventTypeByTime.js +54 -0
- package/dist-server/migrations/1786300000000-IndexEventTypeByTime.js.map +1 -0
- package/dist-server/migrations/1786400000000-IndexEventCreatedAt.d.ts +5 -0
- package/dist-server/migrations/1786400000000-IndexEventCreatedAt.js +44 -0
- package/dist-server/migrations/1786400000000-IndexEventCreatedAt.js.map +1 -0
- package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.d.ts +6 -0
- package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.js +84 -0
- package/dist-server/migrations/1786500000000-CreateTwinSubjectEvents.js.map +1 -0
- package/dist-server/migrations/index.js +7 -1
- package/dist-server/migrations/index.js.map +1 -1
- package/dist-server/routes.d.ts +1 -0
- package/dist-server/routes.js +69 -5
- package/dist-server/routes.js.map +1 -1
- package/dist-server/service/index.d.ts +2 -2
- package/dist-server/service/index.js +30 -24
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/reference/control-routing.d.ts +1 -1
- package/dist-server/service/reference/control-routing.js +1 -1
- package/dist-server/service/reference/control-routing.js.map +1 -1
- package/dist-server/service/reference/discovery-result.d.ts +2 -2
- package/dist-server/service/reference/discovery-result.js +3 -3
- package/dist-server/service/reference/discovery-result.js.map +1 -1
- package/dist-server/service/reference/hook-contract.d.ts +43 -0
- package/dist-server/service/reference/hook-contract.js +59 -0
- package/dist-server/service/reference/hook-contract.js.map +1 -0
- package/dist-server/service/reference/ingest-space.d.ts +1 -1
- package/dist-server/service/reference/ingest-space.js +4 -4
- package/dist-server/service/reference/ingest-space.js.map +1 -1
- package/dist-server/service/reference/knob-defaults.d.ts +1 -1
- package/dist-server/service/reference/knob-defaults.js +4 -4
- package/dist-server/service/reference/knob-defaults.js.map +1 -1
- package/dist-server/service/reference/reference-adapter.d.ts +116 -9
- package/dist-server/service/reference/reference-adapter.js +27 -0
- package/dist-server/service/reference/reference-adapter.js.map +1 -1
- package/dist-server/service/reference/reference-hook.d.ts +20 -0
- package/dist-server/service/reference/reference-hook.js +133 -0
- package/dist-server/service/reference/reference-hook.js.map +1 -0
- package/dist-server/service/reference/reference-live.d.ts +2 -2
- package/dist-server/service/reference/reference-live.js +76 -13
- package/dist-server/service/reference/reference-live.js.map +1 -1
- package/dist-server/service/reference/reference-master.d.ts +25 -16
- package/dist-server/service/reference/reference-master.js +35 -13
- package/dist-server/service/reference/reference-master.js.map +1 -1
- package/dist-server/service/reference/reference-resolver.d.ts +1 -1
- package/dist-server/service/reference/reference-resolver.js +12 -12
- package/dist-server/service/reference/reference-resolver.js.map +1 -1
- package/dist-server/service/reference/template-registry.d.ts +1 -1
- package/dist-server/service/reference/template-registry.js.map +1 -1
- package/dist-server/service/reference/twin-reference.d.ts +3 -3
- package/dist-server/service/reference/twin-reference.js.map +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.d.ts +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.js +1 -1
- package/dist-server/service/twin-attention/twin-attention-query.js.map +1 -1
- package/dist-server/service/twin-audit/command-audit.d.ts +1 -1
- package/dist-server/service/twin-audit/command-audit.js.map +1 -1
- package/dist-server/service/twin-audit/twin-audit-event.d.ts +1 -1
- package/dist-server/service/twin-audit/twin-audit-event.js.map +1 -1
- package/dist-server/service/twin-audit/twin-audit-query.js +1 -1
- package/dist-server/service/twin-audit/twin-audit-query.js.map +1 -1
- package/dist-server/service/twin-backfill/backfill-period-facts.d.ts +24 -0
- package/dist-server/service/twin-backfill/backfill-period-facts.js +96 -0
- package/dist-server/service/twin-backfill/backfill-period-facts.js.map +1 -0
- package/dist-server/service/twin-backfill/backfill-shape.d.ts +34 -0
- package/dist-server/service/twin-backfill/backfill-shape.js +75 -0
- package/dist-server/service/twin-backfill/backfill-shape.js.map +1 -0
- package/dist-server/service/twin-backfill/index.d.ts +2 -0
- package/dist-server/service/twin-backfill/index.js +6 -0
- package/dist-server/service/twin-backfill/index.js.map +1 -0
- package/dist-server/service/twin-backfill/twin-backfill-resolver.d.ts +10 -0
- package/dist-server/service/twin-backfill/twin-backfill-resolver.js +44 -0
- package/dist-server/service/twin-backfill/twin-backfill-resolver.js.map +1 -0
- package/dist-server/service/twin-control/twin-control-mutation.js +3 -3
- package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
- package/dist-server/service/twin-event/twin-event-keys.d.ts +1 -1
- package/dist-server/service/twin-event/twin-event-keys.js +2 -2
- package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
- package/dist-server/service/twin-event/twin-event-type.d.ts +1 -0
- package/dist-server/service/twin-event/twin-event-type.js +8 -1
- package/dist-server/service/twin-event/twin-event-type.js.map +1 -1
- package/dist-server/service/twin-event/twin-event.d.ts +2 -2
- package/dist-server/service/twin-event/twin-event.js +32 -4
- package/dist-server/service/twin-event/twin-event.js.map +1 -1
- package/dist-server/service/twin-forecast/forecast-metrics.js +1 -1
- package/dist-server/service/twin-forecast/forecast-metrics.js.map +1 -1
- package/dist-server/service/twin-forecast/gap-analytics.d.ts +1 -1
- package/dist-server/service/twin-forecast/gap-analytics.js.map +1 -1
- package/dist-server/service/twin-forecast/twin-forecast-query.js +29 -11
- package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.d.ts +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js +1 -1
- package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +1 -1
- package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
- package/dist-server/service/twin-journal/event-type-split-shape.d.ts +50 -0
- package/dist-server/service/twin-journal/event-type-split-shape.js +111 -0
- package/dist-server/service/twin-journal/event-type-split-shape.js.map +1 -0
- package/dist-server/service/twin-journal/event-type-split.d.ts +15 -0
- package/dist-server/service/twin-journal/event-type-split.js +102 -0
- package/dist-server/service/twin-journal/event-type-split.js.map +1 -0
- package/dist-server/service/twin-journal/journal-order.d.ts +15 -0
- package/dist-server/service/twin-journal/journal-order.js +17 -0
- package/dist-server/service/twin-journal/journal-order.js.map +1 -0
- package/dist-server/service/twin-journal/twin-journal-query.d.ts +5 -5
- package/dist-server/service/twin-journal/twin-journal-query.js +232 -21
- package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
- package/dist-server/service/twin-lifecycle/domain-catalog.js +2 -1
- package/dist-server/service/twin-lifecycle/domain-catalog.js.map +1 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +27 -1
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +59 -3
- package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.js +14 -1
- package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
- package/dist-server/service/twin-model/axis-journal-evidence.js +1 -1
- package/dist-server/service/twin-model/axis-journal-evidence.js.map +1 -1
- package/dist-server/service/twin-model/epcis-coverage.js +34 -3
- package/dist-server/service/twin-model/epcis-coverage.js.map +1 -1
- package/dist-server/service/twin-model/iec61850-coverage.js +1 -1
- package/dist-server/service/twin-model/iec61850-coverage.js.map +1 -1
- package/dist-server/service/twin-model/isa95-coverage.d.ts +12 -9
- package/dist-server/service/twin-model/isa95-coverage.js +33 -9
- package/dist-server/service/twin-model/isa95-coverage.js.map +1 -1
- package/dist-server/service/twin-model/item-ref.js +2 -2
- package/dist-server/service/twin-model/item-ref.js.map +1 -1
- package/dist-server/service/twin-model/name-index.d.ts +1 -1
- package/dist-server/service/twin-model/name-index.js +2 -2
- package/dist-server/service/twin-model/name-index.js.map +1 -1
- package/dist-server/service/twin-model/project-structure.d.ts +1 -1
- package/dist-server/service/twin-model/project-structure.js +7 -6
- package/dist-server/service/twin-model/project-structure.js.map +1 -1
- package/dist-server/service/twin-model/twin-equipment.d.ts +2 -2
- package/dist-server/service/twin-model/twin-equipment.js +3 -3
- package/dist-server/service/twin-model/twin-equipment.js.map +1 -1
- package/dist-server/service/twin-model/twin-lineage-query.js +16 -5
- package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-location.d.ts +1 -1
- package/dist-server/service/twin-model/twin-location.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-item-query.d.ts +3 -3
- package/dist-server/service/twin-model/twin-model-item-query.js +15 -15
- package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-mutation.d.ts +2 -2
- package/dist-server/service/twin-model/twin-model-mutation.js +4 -4
- package/dist-server/service/twin-model/twin-model-mutation.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-query.js +51 -30
- package/dist-server/service/twin-model/twin-model-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-model-tree-query.js +23 -1
- package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -1
- package/dist-server/service/twin-model/twin-operation.d.ts +1 -1
- package/dist-server/service/twin-model/twin-operation.js +1 -1
- package/dist-server/service/twin-model/twin-operation.js.map +1 -1
- package/dist-server/service/twin-space/move-space.js +2 -2
- package/dist-server/service/twin-space/move-space.js.map +1 -1
- package/dist-server/service/twin-space/representation-role.d.ts +2 -0
- package/dist-server/service/twin-space/representation-role.js +18 -0
- package/dist-server/service/twin-space/representation-role.js.map +1 -0
- package/dist-server/service/twin-space/space-integrity.d.ts +1 -1
- package/dist-server/service/twin-space/space-integrity.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-representation.d.ts +2 -0
- package/dist-server/service/twin-space/twin-space-representation.js +16 -0
- package/dist-server/service/twin-space/twin-space-representation.js.map +1 -1
- package/dist-server/service/twin-space/twin-space-resolver.d.ts +2 -2
- package/dist-server/service/twin-space/twin-space-resolver.js +37 -8
- package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
- package/dist-server/service/twin-structure/twin-structure.js +3 -3
- package/dist-server/service/twin-structure/twin-structure.js.map +1 -1
- package/dist-server/service/twin-subject/event-subjects.d.ts +43 -0
- package/dist-server/service/twin-subject/event-subjects.js +137 -0
- package/dist-server/service/twin-subject/event-subjects.js.map +1 -0
- package/dist-server/service/twin-subject/index.d.ts +9 -0
- package/dist-server/service/twin-subject/index.js +16 -0
- package/dist-server/service/twin-subject/index.js.map +1 -0
- package/dist-server/service/twin-subject/item-resolver.d.ts +10 -0
- package/dist-server/service/twin-subject/item-resolver.js +93 -0
- package/dist-server/service/twin-subject/item-resolver.js.map +1 -0
- package/dist-server/service/twin-subject/subject-query-shape.d.ts +22 -0
- package/dist-server/service/twin-subject/subject-query-shape.js +88 -0
- package/dist-server/service/twin-subject/subject-query-shape.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-backfill.d.ts +23 -0
- package/dist-server/service/twin-subject/twin-subject-backfill.js +159 -0
- package/dist-server/service/twin-subject/twin-subject-backfill.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-event.d.ts +14 -0
- package/dist-server/service/twin-subject/twin-subject-event.js +111 -0
- package/dist-server/service/twin-subject/twin-subject-event.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-fast-path.d.ts +39 -0
- package/dist-server/service/twin-subject/twin-subject-fast-path.js +295 -0
- package/dist-server/service/twin-subject/twin-subject-fast-path.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-query.d.ts +27 -0
- package/dist-server/service/twin-subject/twin-subject-query.js +232 -0
- package/dist-server/service/twin-subject/twin-subject-query.js.map +1 -0
- package/dist-server/service/twin-subject/twin-subject-writer.d.ts +27 -0
- package/dist-server/service/twin-subject/twin-subject-writer.js +166 -0
- package/dist-server/service/twin-subject/twin-subject-writer.js.map +1 -0
- package/dist-server/service/twin-target/twin-target-resolver.js +1 -1
- package/dist-server/service/twin-target/twin-target-resolver.js.map +1 -1
- package/dist-shared/entity-delta.d.ts +1 -1
- package/dist-shared/entity-delta.js +4 -4
- package/dist-shared/entity-delta.js.map +1 -1
- package/dist-shared/touched-items.js +2 -2
- package/dist-shared/touched-items.js.map +1 -1
- package/dist-shared/twin-level.js +1 -1
- package/dist-shared/twin-level.js.map +1 -1
- package/package.json +7 -6
- package/server/engine/attention-digest.ts +9 -9
- package/server/engine/canonical-ingest.ts +202 -87
- package/server/engine/command-routing.ts +1 -1
- package/server/engine/declared-stimulus.ts +1 -1
- package/server/engine/energy-topology.ts +2 -2
- package/server/engine/ingest-dedupe.ts +149 -0
- package/server/engine/ingest-health.ts +171 -22
- package/server/engine/integration-probes.ts +7 -7
- package/server/engine/kpi-baseline.ts +4 -4
- package/server/engine/kpi-fold.ts +592 -41
- package/server/engine/kpi-query.ts +307 -48
- package/server/engine/live-feed-registry.ts +1 -1
- package/server/engine/load-meter.ts +1 -1
- package/server/engine/local-declarations.ts +15 -14
- package/server/engine/log.ts +1 -1
- package/server/engine/measured-estimator.ts +1 -1
- package/server/engine/measured-yield.ts +1 -1
- package/server/engine/model-basis.ts +2 -2
- package/server/engine/model-gap.ts +3 -3
- package/server/engine/model-vocabulary.ts +2 -2
- package/server/engine/oee-accumulator.ts +8 -6
- package/server/engine/property-effects.ts +2 -2
- package/server/engine/read-time.ts +77 -0
- package/server/engine/restart-policy.ts +1 -1
- package/server/engine/runtime-key.ts +1 -1
- package/server/engine/spec-coverage.ts +3 -3
- package/server/engine/stage-path.ts +5 -5
- package/server/engine/state-axes.ts +2 -2
- package/server/engine/travel-estimator.ts +2 -2
- package/server/engine/twin-engine.ts +906 -205
- package/server/engine/warm-start.ts +6 -6
- package/server/index.ts +1 -1
- package/server/migrations/1786000000000-RenameTwinInstanceBoardToModel.ts +1 -1
- package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +3 -3
- package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +2 -2
- package/server/migrations/1786300000000-IndexEventTypeByTime.ts +48 -0
- package/server/migrations/1786400000000-IndexEventCreatedAt.ts +38 -0
- package/server/migrations/1786500000000-CreateTwinSubjectEvents.ts +93 -0
- package/server/migrations/index.ts +7 -1
- package/server/routes.ts +73 -5
- package/server/service/index.ts +7 -1
- package/server/service/reference/control-routing.ts +1 -1
- package/server/service/reference/discovery-result.ts +3 -3
- package/server/service/reference/hook-contract.ts +103 -0
- package/server/service/reference/ingest-space.ts +4 -4
- package/server/service/reference/knob-defaults.ts +4 -4
- package/server/service/reference/reference-adapter.ts +145 -10
- package/server/service/reference/reference-hook.ts +145 -0
- package/server/service/reference/reference-live.ts +87 -15
- package/server/service/reference/reference-master.ts +51 -20
- package/server/service/reference/reference-resolver.ts +11 -11
- package/server/service/reference/template-registry.ts +1 -1
- package/server/service/reference/twin-reference.ts +3 -3
- package/server/service/twin-attention/twin-attention-query.ts +1 -1
- package/server/service/twin-audit/command-audit.ts +1 -1
- package/server/service/twin-audit/twin-audit-event.ts +2 -2
- package/server/service/twin-audit/twin-audit-query.ts +1 -1
- package/server/service/twin-backfill/backfill-period-facts.ts +168 -0
- package/server/service/twin-backfill/backfill-shape.ts +86 -0
- package/server/service/twin-backfill/index.ts +3 -0
- package/server/service/twin-backfill/twin-backfill-resolver.ts +35 -0
- package/server/service/twin-control/twin-control-mutation.ts +2 -2
- package/server/service/twin-event/twin-event-keys.ts +2 -2
- package/server/service/twin-event/twin-event-type.ts +18 -1
- package/server/service/twin-event/twin-event.ts +32 -6
- package/server/service/twin-forecast/forecast-metrics.ts +1 -1
- package/server/service/twin-forecast/gap-analytics.ts +1 -1
- package/server/service/twin-forecast/twin-forecast-query.ts +30 -11
- package/server/service/twin-ingest-window/twin-ingest-window-query.ts +1 -1
- package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +1 -1
- package/server/service/twin-instance/twin-instance.ts +4 -4
- package/server/service/twin-journal/event-type-split-shape.ts +112 -0
- package/server/service/twin-journal/event-type-split.ts +144 -0
- package/server/service/twin-journal/journal-order.ts +20 -0
- package/server/service/twin-journal/twin-journal-query.ts +224 -20
- package/server/service/twin-lifecycle/domain-catalog.ts +2 -1
- package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +58 -4
- package/server/service/twin-metrics/twin-metrics-query.ts +14 -1
- package/server/service/twin-model/axis-journal-evidence.ts +1 -1
- package/server/service/twin-model/epcis-coverage.ts +34 -3
- package/server/service/twin-model/iec61850-coverage.ts +1 -1
- package/server/service/twin-model/isa95-coverage.ts +43 -16
- package/server/service/twin-model/item-ref.ts +2 -2
- package/server/service/twin-model/name-index.ts +2 -2
- package/server/service/twin-model/project-structure.ts +7 -6
- package/server/service/twin-model/twin-equipment.ts +16 -4
- package/server/service/twin-model/twin-lineage-query.ts +16 -5
- package/server/service/twin-model/twin-location.ts +1 -1
- package/server/service/twin-model/twin-model-item-query.ts +15 -15
- package/server/service/twin-model/twin-model-mutation.ts +4 -4
- package/server/service/twin-model/twin-model-query.ts +49 -28
- package/server/service/twin-model/twin-model-tree-query.ts +26 -2
- package/server/service/twin-model/twin-operation.ts +2 -2
- package/server/service/twin-space/move-space.ts +3 -3
- package/server/service/twin-space/representation-role.ts +15 -0
- package/server/service/twin-space/space-integrity.ts +1 -1
- package/server/service/twin-space/twin-space-representation.ts +37 -0
- package/server/service/twin-space/twin-space-resolver.ts +40 -8
- package/server/service/twin-structure/twin-structure.ts +3 -3
- package/server/service/twin-subject/event-subjects.ts +155 -0
- package/server/service/twin-subject/index.ts +10 -0
- package/server/service/twin-subject/item-resolver.ts +92 -0
- package/server/service/twin-subject/subject-query-shape.ts +84 -0
- package/server/service/twin-subject/twin-subject-backfill.ts +196 -0
- package/server/service/twin-subject/twin-subject-event.ts +101 -0
- package/server/service/twin-subject/twin-subject-fast-path.ts +346 -0
- package/server/service/twin-subject/twin-subject-query.ts +210 -0
- package/server/service/twin-subject/twin-subject-writer.ts +189 -0
- package/server/service/twin-target/twin-target-resolver.ts +1 -1
- package/shared/entity-delta.ts +4 -4
- package/shared/touched-items.ts +2 -2
- package/shared/twin-level.ts +1 -1
- package/test/adopt-structure-live.test.ts +3 -3
- package/test/aggregate-not-findone.test.ts +112 -0
- package/test/attention-digest.test.ts +6 -6
- package/test/axis-read.test.ts +6 -5
- package/test/backfill-shape.test.ts +89 -0
- package/test/boot-resume.test.ts +20 -7
- package/test/broadcast-cost-baseline.test.ts +2 -1
- package/test/broadcast-period.test.ts +2 -2
- package/test/broadcast-queue-overflow.test.ts +244 -0
- package/test/canonical-ingest-vocabularies.test.ts +259 -8
- package/test/canonical-quantity-door.test.ts +2 -2
- package/test/capability-mapping.test.ts +1 -1
- package/test/checkpoint-refuses-empty.test.ts +2 -2
- package/test/connector-capability-declaration.test.ts +88 -0
- package/test/contract-layer-guard.test.ts +48 -0
- package/test/control-capability.test.ts +1 -1
- package/test/cursor-stall-not-read-failure.test.ts +2 -2
- package/test/declaration-reaches-model.test.ts +7 -5
- package/test/declared-stimulus.test.ts +4 -4
- package/test/discovery-result.test.ts +2 -2
- package/test/entity-delta.test.ts +4 -4
- package/test/equipment-identity-reaches.test.ts +57 -0
- package/test/event-subjects.test.ts +147 -0
- package/test/event-time-column.test.ts +3 -3
- package/test/event-type-split.test.ts +155 -0
- package/test/fact-scope-wiring.test.ts +96 -0
- package/test/fold-gap-speaks.test.ts +53 -0
- package/test/forecast-metrics.test.ts +1 -1
- package/test/forecast-tuning.test.ts +1 -1
- package/test/generated-not-counted.test.ts +99 -0
- package/test/ingest-bench.test.ts +2 -1
- package/test/ingest-health-engine.test.ts +2 -2
- package/test/ingest-health-wiring.test.ts +7 -5
- package/test/ingest-health.test.ts +6 -6
- package/test/ingest-history.test.ts +2 -2
- package/test/ingest-idempotent.test.ts +132 -0
- package/test/ingest-space.test.ts +3 -3
- package/test/ingest-wiring-guard.test.ts +197 -0
- package/test/integration-probes.test.ts +3 -3
- package/test/integration-runner.test.ts +1 -1
- package/test/item-ref.test.ts +1 -1
- package/test/journal-order-axis.test.ts +80 -0
- package/test/journal-read-discipline.test.ts +16 -6
- package/test/journal-retention.test.ts +171 -29
- package/test/journal-sort-axis.test.ts +1 -1
- package/test/journal-write-door.test.ts +3 -3
- package/test/journal-write-trend.test.ts +1 -1
- package/test/kernel-kind-guard.test.ts +3 -3
- package/test/knob-defaults.test.ts +1 -1
- package/test/kpi-baseline-db.test.ts +2 -2
- package/test/kpi-fold.test.ts +266 -14
- package/test/kpi-query-bench.test.ts +3 -3
- package/test/live-cursor-wiring.test.ts +6 -6
- package/test/live-kernel-facts.test.ts +11 -11
- package/test/live-mirror-parity.test.ts +9 -6
- package/test/load-meter.test.ts +1 -1
- package/test/local-declarations.test.ts +13 -12
- package/test/log-stamp.test.ts +1 -1
- package/test/master-to-twin.test.ts +2 -2
- package/test/measured-yield.test.ts +2 -2
- package/test/merge-streams.test.ts +70 -0
- package/test/mirror-resumes-from-checkpoint.test.ts +13 -13
- package/test/model-basis.test.ts +2 -2
- package/test/model-gap.test.ts +4 -4
- package/test/model-vocabulary.test.ts +2 -2
- package/test/move-space.test.ts +1 -1
- package/test/oee-accumulator.test.ts +20 -5
- package/test/operational-vocabulary.test.ts +2 -2
- package/test/project-structure-db.test.ts +2 -2
- package/test/projection-reaches-screen.test.ts +7 -2
- package/test/projection-reads-declared.test.ts +109 -0
- package/test/property-effects.test.ts +10 -6
- package/test/read-failure-ledger.test.ts +106 -0
- package/test/read-failure-visible.test.ts +7 -7
- package/test/read-time.test.ts +118 -0
- package/test/reference-grounding.test.ts +1 -1
- package/test/reference-hook.test.ts +86 -0
- package/test/registry-key-guard.test.ts +1 -1
- package/test/rename-twin.test.ts +81 -0
- package/test/restart-policy.test.ts +3 -3
- package/test/resync-origin-site.test.ts +3 -3
- package/test/revision-axis.test.ts +14 -8
- package/test/runtime-key.test.ts +3 -3
- package/test/scale-twin-bench.test.ts +2 -1
- package/test/snapshot-freshness.test.ts +4 -4
- package/test/source-outcome-audit.test.ts +1 -1
- package/test/space-integrity.test.ts +1 -1
- package/test/space-representation.test.ts +66 -0
- package/test/space-scope-includes-stopped.test.ts +55 -0
- package/test/spec-coverage.test.ts +1 -1
- package/test/standard-coverage.test.ts +19 -21
- package/test/status-tally.test.ts +1 -1
- package/test/structure-revision-db.test.ts +7 -7
- package/test/subject-fast-path.test.ts +148 -0
- package/test/subject-read-model.test.ts +175 -0
- package/test/touched-items.test.ts +2 -2
- package/test/twin-audit.test.ts +1 -1
- package/test/twin-event-keys.test.ts +1 -1
- package/test/twin-model-item-db.test.ts +5 -5
- package/test/twin-model-tree-db.test.ts +35 -2
- package/test/twin-origin-resync.test.ts +1 -1
- package/test/vocabulary-guard.test.ts +1 -1
- package/test/warm-start-seam.test.ts +1 -1
- package/test/warm-start.test.ts +6 -6
- package/test/withheld-door.test.ts +2 -2
- package/test/yield-loop.test.ts +4 -4
- package/tsconfig.shared.tsbuildinfo +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isa95-coverage.js","sourceRoot":"","sources":["../../../server/service/twin-model/isa95-coverage.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * ISA-95 ์ ํฉ์ฑ ๊ธฐ์ค โ **ํ์ค์ด ์๊ตฌํ๋ ๊ฒ์ ๋ชฉ๋ก.**\n *\n * โโ ์ ์ด ํ์ผ์ด ํ์ํ๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ง๊ธ๊น์ง ํ๋ฉด์ \"์ฐ๋ฆฌ๊ฐ ๊ฐ์ง ์ถ\" ๋ง ๋ณด์๋ค. ๊ทธ๋ฌ๋ฉด ์ฑ์ด ๊ฒ์ ์ธ์ด์ง์ง๋ง **๋น ์ง ๊ฒ์ ์
์ ์๋ค** โ\n * ์๋ ๊ฒ์ ํ๋ฉด์ ์์ผ๋ฏ๋ก ์๋ฌด๋ ๊ทธ๊ฒ์ ๋ฌป์ง ์๋๋ค. ํ์ค ์ค์๋ \"์ฐ๋ฆฌ ์ถ์ ํ์ค ์ด๋ฆ์ ๋ถ์๋ค\"\n * ๊ฐ ์๋๋ผ **ํ์ค์ ๋ชฉ๋ก์ ๊ธฐ์ค์ผ๋ก ๋น ์ง ๊ฒ์ด ์๋ค**๋ ๋ง์ด์ด์ผ ํ๋ค. ๊ธฐ์ค์ด ์ฝ๋๋ก ์์ด์ผ ๊ทธ\n * ๋ฌธ์ฅ์ ๊ฒ์ฌํ ์ ์๋ค.\n *\n * โโ ์ธ ์ธต์์ ๋ณธ๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํ์ค ์ค์๋ ํ ์ธต์ ์ผ์ด ์๋๋ค. ๊ฐ๋
๋ง๋ค ์
์ ๋ฐ๋ก ๋ณธ๋ค:\n *\n * ยท `structure` โ **๋ฐ์ดํฐ๊ตฌ์กฐ**๊ฐ ์๋(์ปค๋ ์ถยทํธ์คํธ ํ์ ์ด ๊ฐ๋
์ ์๋ฆฌ๊ฐ ์๋)\n * ยท `behavior` โ **๊ธฐ๋ฅ**์ด ๊ทธ๊ฒ์ ์ฐ๋(์ปค๋์ด ๊ณํยท์งํยท์ง๊ณ์์ ์ค์ ๋ก ๋ค๋ฃจ๋)\n * ยท `surface` โ **UI ๋
ธ์ถ**์ด ์๋(์ฌ์ฉ์๊ฐ ๊ทธ๊ฒ์ ๋ณผ ์ ์๋)\n *\n * ์
์ ํฉ์น๋ฉด \"๊ตฌ์กฐ๋ ์๋๋ฐ ์๋ฌด๋ ์ ์ฐ๋ ์ปฌ๋ผ\" ๊ณผ \"์ปค๋์ ์ฐ๋๋ฐ ํ๋ฉด์ ์๋ ์ฌ์ค\" ์ด ๊ฐ์\n * ๊ฐ์ผ๋ก ๋ณด์ธ๋ค. ์ค์ ๋ก ์ด ํ๋ก์ ํธ์์ ๋ ๋ค ๋์๋ค(์ธ๋ ฅ ๋ช
์ธ๋ ๊ตฌ์กฐยท๊ธฐ๋ฅ์ด ์์์ง๋ง ํ๋ฉด์\n * ์์๊ณ , `properties` ๋ ๊ตฌ์กฐ๋ง ์๋ค).\n *\n * โโ ๊ฐ์ ๊ด์ธก์ด ์๋๋ผ ์ ์ธ์ด๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ฌ๊ธฐ ์ ํ ๊ฒ์ **์ฌ๋์ด ํ๋จํด ์ ์ ์ฌ์ค**์ด๋ค(์๋ ํ์ ์ด ์๋๋ค). ๊ทธ๋์ ํ๋ฆด ์ ์๊ณ , ํ๋ฆฌ๋ฉด\n * ์ฌ๊ธฐ๋ฅผ ๊ณ ์ณ์ผ ํ๋ค โ ํ๋ฉด์ ์ด ์ ์ธ์ ๊ทธ๋๋ก ๋ณด์ด๊ณ ์ง์ด๋ด์ง ์๋๋ค. ์๋์ผ๋ก ์ ์ ์๋ ๊ฒ\n * ํ๋๋ ์๋์ผ๋ก ํ๋ค: `axis` ๊ฐ ์ปค๋ ์ถ ๋ชฉ๋ก์ ์์ผ๋ฉด ๊ทธ๊ฒ์ **๊ตฌ์กฐ๊ฐ ์๋ ๊ฒ**์ด๋ค(์คํ ๋ฐฉ์ง).\n *\n * โโ ์ด ํ๊ฐ ์ปค๋์ ์๋ ์ด์ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ปค๋์ **๋ฐํ์ ๋ชจ๋ธ์ SSOT** ๋ค(๋ฌด์์ด ์๋๊ฐ). ์ด ํ๋ **์ฐธ์กฐ ๋ชจ๋ธ์ ๋ชฉ๋ก**์ด๋ค(๋ฌด์์ด ์์ด์ผ\n * ํ๋๊ฐ). ๋์ ๋ค๋ฅธ ์ข
๋ฅ์ ์ฌ์ค์ด๊ณ , ํ์๋ ์ปค๋์ ๋ฐฐํฌํ์ง ์๊ณ ๋ ๋์ด์ผ ํ๋ค.\n */\n\n/** ํ ์ธต์ ์ํ โ ์์ ยท ๋ถ๋ถ ยท ์์. \"๋ถ๋ถ\" ์ ๋๋ ์ด์ : ์ ๋ฐ ์๋ ๊ฒ์ ์๋ค๊ณ ํ๋ฉด ๊ธฐ์ค์ด ์ฃฝ๋๋ค. */\nexport type CoverageLevel = 'full' | 'partial' | 'none'\n\nexport interface Isa95Concept {\n /** ํ์ค์ด ๋ถ๋ฅด๋ ์ด๋ฆ โ ์ด ํ์ ํค๋ค(์ฐ๋ฆฌ ์ดํ๊ฐ ์๋๋ผ ํ์ค ์ดํ). */\n std: string\n /** ํ์ค์ ์ด๋ ๋ถ๋ถ์ธ๊ฐ โ Part 2(์์ ๋ชจ๋ธ) ยท Part 4(์ผ์ ยท์ค์ ) ๋ฑ. */\n part: string\n /** ์ฌ๋์ด ์ฝ๋ ์ด๋ฆ(i18n ํค). ํ๋ฉด์ด ๋ฒ์ญํ๋ค. */\n label: string\n /** ์ฐ๋ฆฌ ์ปค๋ ์ถ โ ์์ผ๋ฉด ๋ฐ์ดํฐ๊ตฌ์กฐ๊ฐ ์๋ ๊ฒ์ด๋ค. ์์ผ๋ฉด `null`. */\n axis: string | null\n /** ์ธ ์ธต์ ์ํ. `structure` ๋ `axis` ๋ก๋ ๊ฒ์ฆ๋๋ค. */\n structure: CoverageLevel\n behavior: CoverageLevel\n surface: CoverageLevel\n /** ์ ๊ทธ ์์ค์ธ์ง โ **๋ชจ๋ฅด๋ ๊ฒ์ ๊ฐ์ถ์ง ์๊ธฐ ์ํด** ํ ์ค๋ก ์ ๋๋ค(i18n ํค). */\n note?: string\n /**\n * ์๊ธฐ ์ถ์ด ์์ ๋ **์ด๋์ ๋ณด์ด๋** โ ๊ทธ ์ฌ์ค์ ๋ค๊ณ ์๋ ์ถ๋ค.\n *\n * ใ์ด๋์ใ์นธ์ด ๋ ๊ฐ์ง๋ฅผ ํฉ์ณ๊ณ ์์๋ค: *์์ง ์ถ์ด ์๋ค(๋ถ์ฑ)* ์ *์ถ์ผ ์ ์๋ค(์ค๊ณ)*. ๊ฐ์ฉ ๋ฅ๋ ฅ์\n * ๊ฐ์ฒด๊ฐ ์๋๋ผ ์์์ ์ง๊ธ ์ํ์ด๋ฏ๋ก ์ถ์ด ๋ ์ ์๋๋ฐ, ์ธ ์ธต์ด ๋ค ์์ ํ ์ค์ด \"๊ฐ๋
์ถ์ด ์์ต๋๋ค\"\n * ๋ผ๊ณ ๋ง ๋งํ๋ฉด **ํ๊ฐ ์ค์ค๋ก ๋ชจ์๋ ๋ง์ ํ๋ค**(๋ค ๋๋ค๋ฉด์ ์๋ค๊ณ ํ๋ค).\n *\n * ๊ทธ๋์ ์ถ์ผ ์ ์๋ ๊ฒ์ ๊ฐ ๊ณณ์ ๊ฐ๋ฆฌํจ๋ค. ์ฌ๊ธฐ๊ฐ ๋น์ด ์๊ณ ์ถ๋ ์์ผ๋ฉด ๊ทธ๊ฒ์ **์ง์ง ๋น์นธ**์ด๋ค.\n *\n * โโ โ
`surface` ์ ์ง์ ๋ง์ถ๋ค (2026-08-24 ์ค์ธก์ผ๋ก ๋ถ์) โโโโโโโโโโโโโโโโโ\n * ์ด ์นธ์ ใ๊ทธ ์ฌ์ค์ด ์ด๋ ์ถ์ **๋ด๊ฒจ ์๋**ใ๊ฐ ์๋๋ผ ใ**์ด๋์ ๋ณด์ด๋**ใ๋ค. ํ๋ฉด์ด ๊ทธ๊ฒ์\n * ใํด๋น ์ถ ํญ๋ชฉ์ ํ์๋ฉ๋๋คใ๋ก ์ฝ์ด ๋ด๋ฏ๋ก, ๋์ด ์ด๊ธ๋๋ฉด ํ๊ฐ ๊ฑฐ์ง์ ๋งํ๋ค.\n *\n * `surface: 'none'` ์ธ๋ฐ ์ฌ๊ธฐ๊ฐ ์ฐจ ์๋ค โ **๊ฑฐ์ง**. ์๋ ํ๋ฉด์ผ๋ก ์ฌ๋์ ๋ณด๋ธ๋ค\n * `surface` ๊ฐ ์๋๋ฐ ์ฌ๊ธฐ๊ฐ ๋น์ด ์๋ค โ **๊ณผ์**. ใ์ง์ง ๋น์นธใ์ผ๋ก ์ฝํ๋ค(์ ๊ท์น)\n *\n * ๊ฐ์ ๋ ์
์ ๊ทธ๋ ๊ฒ ํ๋ฆฌ๊ฒ ๋ฃ์๋ค: ์ ๊ฐ๋
๋(`TestResult`ยท`OperationsEvent`)์ ํ๋ฉด์ด ์๋๋ฐ\n * ๊ฐ ๊ณณ์ ์ ์๊ณ , `MaterialSublot` ์ ๋ฌผํ ์ด๋ฆ์ผ๋ก ๋ณด์ด๋๋ฐ ๊ฐ ๊ณณ์ ๋น์ ๋์๋ค.\n */\n shownOn?: string[]\n}\n\n/*\n * ๊ฐ์ฉ ๋ฅ๋ ฅ(2026-08-12, ์ปค๋ 0.6.8) โ **ํ์ ๊ณผ ์ด์ ๊ฐ ์ํ์ ์ค๋ ค ์จ๋ค**(`capability {available, reason}`).\n *\n * ์
๋ค ์์ ์ธ ๊ทผ๊ฑฐ: ์ํ๊ฐ ํ์ ์ ๋ค๊ณ ์ค๊ณ (์๋ฎฌยท๋ฏธ๋ฌ๊ฐ ๊ฐ์ ํจ์๋ก ํ์ํ๋ค), ๋ฐฐ์ ์ด ๊ฐ์ ํ์ ์\n * ์ฐ๊ณ , ๋ ํ๋ฉด์ด ๊ฐ์ ๋ฑ๋ง๋ก ๊ทธ ์ด์ ๋ฅผ ๋ณด์ธ๋ค(์์ ํญ ๋ฐฐ์ง ยท ์ธ์คํ์
๊ด์ธก ์ด).\n *\n * ์ ์ถ์ด ์๋๊ฐ โ ๊ฐ์ฉ ๋ฅ๋ ฅ์ ๊ฐ์ฒด๊ฐ ์๋๋ผ **์์์ ์ง๊ธ ์ํ**๋ค. ๊ฐ๋
์นด๋๋ก ์ธ์ฐ๋ฉด ์ฌ๋ยท์ค๋น์\n * ๋๋ํ ๋์ฌ \"๋ฅ๋ ฅ์ด ๋ช ๊ฐ์ธ๊ฐ\" ๋ฅผ ์ธ๊ฒ ๋๋๋ฐ, ๊ทธ๊ฑด ๋ฌผ์ ์ผ์ด ์๋๋ค.\n */\n\n/*\n * ์์ฐ ๋ฅ๋ ฅ(2026-08-13, ์ปค๋ 0.6.12) โ **๊ตฌ๊ฐ์ ์์ ํ์ค ์ข
๋ฅ๋ก ๊ตฌ๋ถํ๋ค.**\n *\n * `structure` ์์ : ๊ณ์ฝ์ด ๋ณด๊ณ ์๋ฅผ ๋ธ๋ค(`operationsCapabilityOf`) โ ๊ตฌ๊ฐ(StartTimeยทEndTime) ยท ํ์ค\n * ์ด๊ฑฐ๊ฐ(CommittedยทAvailableยทUnattainable) ยท ๊ณต์ ๋ณ ๋ถํด ยท ์ ์ฝํ๋ ์ถ. ๋ฑ๋ง์ B2MML ๋์กฐ ํ ํ์ค ๊ฒ์\n * ๊ทธ๋๋ก ์ด๋ค(์ฐ๋ฆฌ ๋ฑ๋ง์ ๋ง๋ค์ง ์์๋ค).\n * `behavior` ์์ : ์ฝ์ ์ ์ค๋์์, ๋ฌ์ฑ๋ถ๊ฐ๋ ์์ ํ์ (`capabilityOf`)์์ ์จ๋ค โ ๊ทธ๋ฆฌ๊ณ ๊ทธ ํ์ ์\n * ๋ฐฐ์ ์ด ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์ ํ ๋ฒ์ด๋ค. ํ์ค์ `Unattainable` ์ ์๊ฐ ๊ทธ ํ์ ๊ณผ ๊ฒน์น๋ค.\n * `surface` ์์ : ๋ ์๋ฆฌ์์ ๋ณด์ธ๋ค โ ์ฑ๊ณผ ํ๋ฉด์ด ํ์ฅ ์ ์ฒด์ \"์์ผ๋ก ๋ ๋ฐ์ ์ ์๋ ๋ชซ\" ์, ๊ณต์ \n * ์์ธ๊ฐ ๊ทธ ๊ณต์ ํ๋์ ๋ถํด(์ํยท์ฝ์ ยท๋ฌ์ฑ๋ถ๊ฐยท๊ฐ์ฉ)์ ์ ์ฝํ๋ ์ถ์ ๋ณด์ธ๋ค. ๋ ํ๋ฉด์ **๊ฐ์ ๋ฑ๋ง**์\n * ์ด๋ค(๊ฐ์ i18n ํค) โ ๊ฐ์ ์ฌ์ค์ ๋ค๋ฅด๊ฒ ๋ถ๋ฅด๋ฉด ์ด๋ ์ชฝ์ด ๋ง๋์ง ์๋ฌด๋ ๋ชจ๋ฅธ๋ค.\n *\n * ๋จ์ ๊ฒ โ ํ์ค์ **๊ฒ์๋(์ฝ์๋) ๋ฅ๋ ฅ**๋ ๋ด๋๋ค(๊ณ์ฐ์ด ์๋๋ผ ์ ์ธ). ๊ฐ์ ์ค์ ์์ค๊ฐ ์์ง\n * ์นจ๋ฌตํ๋ฏ๋ก ๋น ์ถ์ ๋จผ์ ๋ง๋ค์ง ์๋๋ค(์ํ ์ชฝ `workCalendar` ๋ฅผ ์ง์ด ์ด์ ์ ๊ฐ๋ค).\n *\n * ๊ณผ๊ฑฐ ๋ถํด(UsedยทUnused)๋ ์ด ๋ณด๊ณ ์์ ์๋ค โ ๊ทธ๊ฒ์ ์ค์ ์ด๊ณ ์ด๋ฏธ ๋ ๊ณณ์ ์๋ค(์ค๋น OEE ์ ๊ฐ๋/์ ํด,\n * ์ฑ๊ณผ ํ๋ฉด์ ๊ตฌ๊ฐ ๊ฐ๋๋ฅ ). ํ์ค์ด ๊ทธ ๋์ ๋ค๋ฅธ ์ข
๋ฅ๋ก ๋ถ๋ฅด๋ฏ๋ก **ํฉ์น์ง ์๋๋ค.**\n */\n\n/*\n * Part 2 โ ์์ ๋ชจ๋ธ. ๋ค ์์ ๊ฐ๊ฐ์ด **๋ฑ๊ธ/์ ์ โ ๊ฐ์ฒด** ์ด์ค๊ตฌ์กฐ๋ฅผ ๊ฐ๋ ๊ฒ์ด ์ด ๋ถ๋ถ์ ํต์ฌ์ด๊ณ ,\n * ๊ทธ ์ด์ค์ฑ์ด ์ด ํธ์์ ๋ผ๋์ด๊ธฐ๋ ํ๋ค.\n */\nconst PART2: Isa95Concept[] = [\n { std: 'PersonnelClass', part: '2', label: 'twin.isa95.PersonnelClass', axis: 'personnelClasses', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'Person', part: '2', label: 'twin.isa95.Person', axis: 'persons', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'PersonnelCapability', part: '2', label: 'twin.isa95.PersonnelCapability', axis: null, shownOn: ['persons'], structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.capability' },\n { std: 'EquipmentClass', part: '2', label: 'twin.isa95.EquipmentClass', axis: 'equipmentClasses', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'Equipment', part: '2', label: 'twin.isa95.Equipment', axis: 'equipment', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'EquipmentCapability', part: '2', label: 'twin.isa95.EquipmentCapability', axis: null, shownOn: ['equipment'], structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.capability' },\n { std: 'PhysicalAssetClass', part: '2', label: 'twin.isa95.PhysicalAssetClass', axis: 'assetClasses', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'PhysicalAsset', part: '2', label: 'twin.isa95.PhysicalAsset', axis: 'assets', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'MaterialClass', part: '2', label: 'twin.isa95.MaterialClass', axis: 'materialClasses', structure: 'full', behavior: 'partial', surface: 'full' },\n { std: 'MaterialDefinition', part: '2', label: 'twin.isa95.MaterialDefinition', axis: 'materialDefinitions', structure: 'full', behavior: 'full', surface: 'full' },\n /*\n * ๋กํธยท์๋ธ๋กํธ๋ ๊ฐ์ฒด ์ถ์ด ์๋๋ผ **๊ด์ธก**์ผ๋ก ์กด์ฌํ๋ค(EPCIS ๊ฐ์ฒด) โ ๊ตฌ์กฐ๋ ์ ๋์ด ๊ฐ๋๋ค.\n *\n * โโ 2026-08-24 ๋กํธ๊ฐ ์ํ ๊ฒฐ๊ณผ๋ฅผ ๋ค๊ฒ ๋๋ค (์ปค๋ 0.7.57) โโโโโโโโโโโโโโโโโ\n * `ItemState.testResults` ๋ก ใ์ด ๋กํธ๋ฅผ ์ธ ์ ์๋ใ์ **๊ทผ๊ฑฐ**๊ฐ ๋กํธ์ ์ค๋ฆฐ๋ค. ๊ทธ์ ์๋ ํ์ \n * (`disposition`)๋ง ์์๊ณ ใ์ ๊ทธ๋ ๊ฒ ํ์ ํ๋ใ๋ฅผ ๋์ง์ ์ ์์๋ค.\n *\n * **๊ตฌ์กฐ๋ฅผ `full` ๋ก ์ฌ๋ฆฌ์ง ์๋๋ค.** `MaterialLotType` ์๋ฌธ(B2MML-Material.xsd)์ด ๋๋ ๊ฒ ์ค\n * ์์ง ์๋ ๊ฒ์ด ์๋ค: `MaterialLotProperty`(์ํ์ด ์๋ ๋กํธ ์์ฑ โ ์์ฐ์งยทํฌ์ฅ ํํ) ยท\n * `TestSpecificationID`(๋กํธ๋ณ ๊ธฐ์ค ์ฐธ์กฐ โ ํ๋ชฉ ์ ์๊ฐ ๋์ ๋ตํ๋ฏ๋ก ๋์ง ์์๋ค) ยท `Status` ยท\n * `HierarchyScope` ยท `Version`. ์ฑ์ด ๊ฒ๋ง ์ธ๋ ๊ฒ์ด ์ด ํ์ ๊ท์จ์ด๋ค.\n */\n { std: 'MaterialLot', part: '2', label: 'twin.isa95.MaterialLot', axis: null, structure: 'partial', behavior: 'full', surface: 'partial', note: 'twin.isa95.note.lot' },\n /*\n * โโ 2026-08-24 ํ์ ์ ์ : `none` ์ด ์๋์๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ด ์ค์ ์
๋ค `none` ์ด์๋๋ฐ **ํ๊ฐ ์ฝ๋๋ณด๋ค ๋ค์ฒ์ ธ ์์๋ค.** ์ปค๋์ ์๋ธ๋กํธ๋ฅผ ๋ ๋ค:\n *\n * `ItemState.subLotId` ํ์ค `MaterialSubLot.ID` (๊ณ์ฝ์ด ๊ทธ๋ ๊ฒ ์ ๊ณ ์๋ค)\n * `subLotIdOf(class, location)` ๋น์ง๋ ฌ ๋กํธ๊ฐ ์๋ฆฌ๋ง๋ค ๋๋ ๋ ๊ทธ ๋ถ๋ถ์ ์ด๋ฆ์ ๋ง๋ ๋ค\n * `itemKeyOf(item)` **๊ฐ์ฒด์ ์ ์ฒด์ฑ์ด ์ด ๊ฐ์ด๋ค** โ `subLotId ?? epc`\n *\n * ๊ธฐ๋ฅ์ด `full` ์ธ ๊ทผ๊ฑฐ: ์ด ์ถ์ด ์์ผ๋ฉด ๊ฐ์ ๋กํธ๋ฅผ rack-1 ์ 100๊ฐยทrack-2 ์ 60๊ฐ ๊ด์ธกํ์ ๋\n * **๋ค์ ์จ ๊ด์ธก์ด ์์ ๋ฎ์ด 100๊ฐ๊ฐ ์กฐ์ฉํ ์ฌ๋ผ์ง๋ค**(ํฉ๊ณ 160 โ 60). ์ค์ ๋ก ๊ทธ ๊ฒฐํจ์ ์ด ์ถ์ผ๋ก\n * ๊ณ ์ณค๋ค. ์ฆ ์ฅ์์ด ์๋๋ผ ์ ์ฒด์ฑ์ ์งํฑํ๋ค.\n *\n * ๊ตฌ์กฐ๊ฐ `partial` ์ธ ์ด์ : ์๋ธ๋กํธ๋ ๋กํธ์ ๊ฐ์ ๋ชจ์์ด๊ณ (์ ์ฐธ์กฐ) ๊ทธ ๋กํธ๊ฐ `partial` ์ด๋ค.\n * ํ๋ฉด์ด `partial` ์ธ ์ด์ : ๊ฐ์ด ๋ฌผํ์ **์ด๋ฆ์ผ๋ก** ๋์จ๋ค(`twin-item` ์ line) โ ใ์ด ๋กํธ๊ฐ ์๋ฆฌ๋ง๋ค\n * ๋๋์ด ์๋คใ๋ฅผ ๋งํ๋ ์๋ฆฌ๋ ์์ง ์๋ค.\n *\n * ์ด ๋ถ๋ฅ(์ฝ๋์ ์๋๋ฐ ํ๊ฐ `none`)๋ ์๋์ผ๋ก ์กํ์ง ์๋๋ค โ ํ์ ๊ฐ๋๋ ๋ฐ๋ ๋ฐฉํฅ๋ง ๋ณธ๋ค\n * (์ถ์ด ์ฌ๋ผ์ง๋ฉด ๊ตฌ์กฐ๋ฅผ ๋ด๋ฆฐ๋ค). ๊ทธ๋์ ์ถ์ ๋๋ฆด ๋ ์ด ํ๋ฅผ ํจ๊ป ๋ณด๋ ๊ฒ์ด ๊ท์จ์ด๋ค.\n */\n { std: 'MaterialSublot', part: '2', label: 'twin.isa95.MaterialSublot', axis: null, shownOn: ['items'], structure: 'partial', behavior: 'full', surface: 'partial' },\n { std: 'ProcessSegment', part: '2', label: 'twin.isa95.ProcessSegment', axis: 'operations', structure: 'full', behavior: 'full', surface: 'full' },\n /*\n * ์์ฑ์ ์์๋ง๋ค ๋ถ๋ ํ์ฅ์ด๋ผ **์๊ธฐ ์ถ์ด ์๋๋ค** โ ๊ทธ๋์ `axis` ๋ ์์ง๋ง ๊ตฌ์กฐ๋ ์์ ํ๋ค:\n * ๊ณ์ฝ(`ResourceProperty`: ๊ฐยท๋ฐ์ดํฐํยท๋จ์ยทํ์ยท๋ฑ๊ธ์์ฑ)์ด ํ์ค์ ๊ทธ๋๋ก ๋ด๊ณ , ์ธ์ ์คํธยท์ํยท\n * ํ๋ฉด์ด ๊ทธ๊ฒ์ ํต๊ณผ์ํจ๋ค.\n *\n * ๊ธฐ๋ฅ์ **๋ถ๋ถ**์ด๋ค: ํธ์คํธ์ ์ฃผํ ์ถ์ ๊ธฐ๊ฐ `speed` ๋ฅผ ์ฝ์ด ์ด๋ ์๊ฐ์ ๋ง๋๋ ๊ฒ์ด ์ ์ผํ ์๋น์ฒ๋ค\n * (๋ค๋ฅธ ์์ฑ์ ์์ง ์๋ฌด๋ ์ฝ์ง ์๋๋ค). ๊ทธ ์ฌ์ค์ `full` ๋ก ์ฌ๋ฆฌ๋ฉด ํ๊ฐ ๊ฑฐ์ง์ด ๋๋ค.\n */\n { std: 'Property', part: '2', label: 'twin.isa95.Property', axis: null, structure: 'full', behavior: 'partial', surface: 'full', note: 'twin.isa95.note.property' },\n /*\n * **์๋ฆฌ์ ์์ ๊ด์ธก** โ 2026-08-24 ์ ์ค(์ปค๋ 0.7.56). ํ์ ์ด ๊ฐ๋
์ด ์์ ์์๋ค.\n *\n * ์ ์ด ์ถ์ด ํ์ํ๊ฐ: ํธ์์ ํ์ ๋์์ ๋ฌผ๊ฑด์ ์ํ์ด๊ณ , ๋ฌผ๊ฑด์ ์ํ๋ **์กฐ๊ฑด ์์ด ์ ํด์ง์ง\n * ์๋๋ค.** ใ์ด ๋กํธ๊ฐ ๋์ฅ์ค์ ์์๋คใ๊น์ง๋ง ์๋ ํธ์์ ๊ทธ ๋กํธ๊ฐ ๊ด์ฐฎ์๋์ง ๋งํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ \n * **์ด ์กฐ์ธ์ ํธ์๋ง ํ ์ ์๋ค** โ ๊ณ์ธก ์์คํ
์ ๋ฌผ๊ฑด์ ์๋ฆฌ ์ด๋ ฅ์ ๋ชจ๋ฅด๊ณ , ๋ฌผ๋ฅ ์์คํ
์ ์กฐ๊ฑด\n * ์ด๋ ฅ์ ๋ชจ๋ฅธ๋ค.\n *\n * ํ์ค ์ต์ปค: `OperationsEventType`(B2MML-OperationsEvent.xsd, ISA-95.00.02-2018) +\n * `OperationsRecordTemplateType`. ์ฐ๋ฆฌ๊ฐ ๋ ๊ฒ โ `EffectiveTimestamp` ยท `EffectiveEndDate` ยท\n * `RecordTimestamp` ยท `HierarchyScope`(์๋ฆฌ) ยท `Source` ยท ๊ฐ์ `ValueType` ์ผ๋ก **์ขํ๋ค**\n * (๋จ์ ์๋ ๋ฌผ๋ฆฌ๋์ ํ์ ์ ์ฌ๋ฃ๊ฐ ๋ชป ๋๋ค).\n *\n * ๋ถ๋ ์๋ฆฌ๊ฐ `HierarchyScope.EquipmentID` ์ธ ๊ฒ์ด ์ค์ํ๋ค โ ISA-95 ์์ ์ฅ์ ๊ณ์ธต์ด ๊ณง ์ค๋น\n * ๊ณ์ธต์ด๊ณ ๋์ฅ์ค์ `StorageZone` ์์ค์ ์ค๋น๋ค. `OperationalLocationType` ์๋ ์ด ์ถ์ด ์๋ค.\n *\n * ๊ตฌ์กฐ๊ฐ `partial`: ๋ดํฌ ์ ์ฒด(`ID`ยท`Description`ยท์ฌ๊ฑด ๋ถ๋ฅยท`OperationsRecord` ๊ตฌ์กฐ)๊ฐ ์๋๋ผ ๊ด์ธก\n * ํ๋๋ฅผ ๋ด๋ ๋ฐ ํ์ํ ์นธ๋ง ๋ ๋ค.\n * ๊ธฐ๋ฅ์ด `full`: ์ฌ๊ฑด ์ฑ๋(`location.measured`)์ด ์ํ๋ฅผ ๋ง๋ค๊ณ , ์ ์ธ๋ ๊ธฐ์ค์ผ๋ก ํ์ ํด\n * `observation-out-of-limit` ์ ํธ๋ฅผ ์ธ์ด๋ค.\n * ํ๋ฉด์ด `none`: ํด๋ผ์ด์ธํธ์ ์ด ์ถ์ ๊ทธ๋ฆฌ๋ ๊ณณ์ด ์๋ค(์ค์ธก 0๊ณณ).\n */\n { std: 'OperationsEvent', part: '2', label: 'twin.isa95.OperationsEvent', axis: null, structure: 'partial', behavior: 'full', surface: 'none' }\n]\n\n/*\n * Part 4 โ ์ผ์ ๊ณผ ์ค์ .\n *\n * **2026-08-11 ์ด์ ์๋ ์ด ๋ถ๋ถ์ด ๊ฑฐ์ ๋น์ด ์์๋ค.** ์ค๋ยท์์
์ ๋ฐํ์๊ณผ ์ ๋์ ์ค์ฌํ๋๋ฐ ์กฐํ\n * ๋ชจ๋ธ์ ์ถ์ด ์๋์๊ณ , ๊ทธ๋์ \"์ด ํธ์์ด ํ์ค์ ์ด๋๋ฅผ ์ฑ์ฐ๋\" ๋ผ๋ ์ง๋ฌธ์ ์ ๋ฐ๋ง ๋ตํ๋ค.\n *\n * ์ปค๋์ด ๊ณ์ฝ์ ๋ํ(`source: 'state'`) ๋ ์ถ์ด ์ถ๊ฐ๋์๋ค โ ์ด์ ์๊ตฌ(`orders`)์ ์๋ต(`tasks`)์ ๊ฐ๋
์ผ๋ก\n * ๊ฐ๋ฆฌ์ผ ๊ฑธ์ด ๋ค์ด๊ฐ ์ ์๋ค. ๋จ์ ๊ฒ์ **๊ณผ๊ฑฐ๋ก ๋ค์ ๊ณ์ฐํ๋ ๊ธธ**(์ ๋ ์ปค์ ํ์ด์ง)๊ณผ ๋ฅ๋ ฅยท๊ฒ์ฌ ๋ช
์ธ๋ค.\n */\nconst PART4: Isa95Concept[] = [\n { std: 'OperationsDefinition', part: '4', label: 'twin.isa95.OperationsDefinition', axis: 'productionSpec', structure: 'full', behavior: 'full', surface: 'partial', note: 'twin.isa95.note.opsdef' },\n /*\n * 2026-08-11 โ **์ถ์ด ์ถ๊ฐ๋์๋ค**(์ปค๋ 0.6.3 ยท `source: 'state'`). ์๊ตฌ๋ `orders`, ์๋ต์ `tasks` ๋ค.\n *\n * `structure` ๋ฅผ `full` ๋ก ์ฌ๋ฆฐ๋ค: ๋ด์ ์๋ฆฌ๊ฐ ๊ณ์ฝ์ ์๋ค(์ํ ๊ณ์ฝ + ์ถ ์ ์ธ). **ํ
์ด๋ธ ํฌ์์ด\n * ์๋ ๊ฒ์ ๊ฒฐ์์ด ์๋๋ค** โ ์ด ์ถ์ ์ ๋ณธ์ ์ ๋์ด๊ณ , ํฌ์ํ์ง ์๋ ๊ฒ์ด ๊ฒฐ์ ์ด๋ค(ADR-0032-D).\n *\n * `surface` ๋ `full` ์ด๋ค(๊ฐ์ ๋ ๋ ๋ฒ์งธ ๋จ๊ณ): ๋ชฉ๋กยท์์ธยท๊ด๊ณ์ ๋ํด **๊ณผ๊ฑฐ๋ก ๋ค์ ๊ณ์ฐํ๋ ๊ธธ**์ด ํ๋ฉด์\n * ์๋ค โ ์๊ฐ ์ปค์๋ฅผ ์ฎ๊ธฐ๋ฉด ๊ทธ ์์ ์ ์ฌ์ค์ด ๋์ค๊ณ , ๋ฌด์์ ๊ทผ๊ฑฐ๋ก ๋ตํ๋์ง๋ ํ๋ฉด์ด ๋งํ๋ค\n * (๋ผ์ด๋ธ=๊ถ์ ยท ์ ๋=ํ์ ยท ์ ์ ๋ฆฌ๋น์ ). ์ค์ธก: ์ด๋ฅธ ์๊ฐ 0๊ฑด ยท ํ๋ฃจ ๋ค 504๊ฑด.\n */\n { std: 'OperationsSchedule', part: '4', label: 'twin.isa95.OperationsSchedule', axis: 'orders', structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.schedule' },\n { std: 'OperationsPerformance', part: '4', label: 'twin.isa95.OperationsPerformance', axis: 'tasks', structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.performance' },\n { std: 'OperationsCapability', part: '4', label: 'twin.isa95.OperationsCapability', axis: null, shownOn: ['operations'], structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.opscapability' },\n /*\n * 2026-08-12 โ **์ถ์ด ์ถ๊ฐ๋์๋ค**(์ปค๋ 0.6.5). ์์ ์ํ์ด ๊ฐ๋ฆฌํค๋ ์ฐธ์กฐ์ ๋์์ด ์๊ฒผ๊ณ , ์๋ ๋ช
์ธ๋ฅผ\n * ๊ฐ๋ฆฌํค๋ฉด ์ ์ฑ์์ด ๋์ด์ง ์ฐธ์กฐ๋ก ์ผ๋ค.\n *\n * ๊ธฐ๋ฅ์ด **`partial` ๋ก ์ด์๋ฌ๋ค**(์ปค๋ 0.6.6): ๊ฒฐ๊ณผ(`TestResult`)๊ฐ ๊ณ์ฝ์ ๋ค์ด์ค๋ฉด์ ์ปค๋์ด ๋ฐฐ์ ์์\n * ๊ทธ๊ฒ์ ๋ณธ๋ค โ ๋ง๋ฃยท๋ถํฉ๊ฒฉ์ด๋ฉด ๊ทธ ์๊ฒฉ์ ์ฑ๋ฆฝํ์ง ์๋๋ค(์ค์ธก: ๋ง๋ฃ๋ ์ฉ์ ์ฌ๋ ์ฉ์ ์์
5๊ฑด ์ค ํ\n * ๋ฒ๋ ๋ฐฐ์ ๋์ง ์์๋ค).\n *\n * โโ 2026-08-24 ์ ๋ฌธ์ฅ ํ๋๊ฐ ๋ก์๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ใ**์ฌ๋๋ง ํ์ ํ๋ค**ใ๊ณ ์ ํ ์์๋ค. ์ง๊ธ์ ์๋๋ค โ `capabilityOfResource` ๊ฐ ์ค๋นยท์ฌ๋ยท์์ฐ\n * **์
๋ชจ๋**์ `requiredTests` ๋ฅผ ๊ฑธ๊ณ , ๊ทธ ๋ต์ด ๋ฐฐ์ ์ ๊ฐ์ฉ์ฑ ํํฐ๋ก ๋ค์ด๊ฐ๋ค. ๊ทธ๋ฆฌ๊ณ ํ์ ๋์์ด\n * ์์ ๋ฐ์ผ๋ก ๋์ด์ก๋ค: **์๋ฆฌ์ ์์ ๊ด์ธก**(`OperationsEvent` ์ค)๊ณผ **๋กํธ์ ์ํ ๊ฒฐ๊ณผ**\n * (`TestResult` ์ค)๋ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ํ์ ํ๋ค.\n *\n * ๋จ์ ๊ท์จ์ ํ๋๋ค: **๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด ํ์ ํ์ง ์๋๋ค**(์ ์ธํ ๊ฒ๋ง ์ ์ฝ์ด ๋๋ค โ ๊ฒฐ์์ด ์๋๋ผ ๊ท์จ).\n *\n * ๊ทธ๋ฆฌ๊ณ ๊ธฐ์ค์ **์ซ์ ํ๊ณ๋ ์ฐ๋ฆฌ๊ฐ ๋ํ ๊ฒ**์ด๋ค. ํ์ค `TestSpecificationCriteria.Expression` ์\n * ์์ ๋ฌธ์ฅ(`TextType`)์ด๊ณ , B2MML ์ผ๊ณฑ ํ์ผ์ `Minimum`ยท`Maximum`ยท`Tolerance` ๊ฐ ํ๋๋ ์๋ค\n * (์๋ฌธ ๋์กฐ). ๊ทธ๊ฒ ์์ด๋ ํ์ ํ ์ ์์ผ๋ฏ๋ก `limit: {minimum, maximum, uom}` ์ ๋ํ๊ณ , ๋ฐ๋ช
ํ\n * ์๋ฆฌ์์ ๊ณ์ฝ์ ์ ์๋ค. ์ปค๋์ `Expression` ์ **์ฝ์ง ์๋๋ค** โ ๋ฌธ๋ฒ์ด ์ ์๋์ง ์์์ผ๋ฏ๋ก\n * ํ์ฑํ๋ฉด ๊ทธ ์๊ฐ ๋ฐฉ์ธ์ด๋ค.\n */\n { std: 'TestSpecification', part: '4', label: 'twin.isa95.TestSpecification', axis: 'testSpecifications', structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.test' },\n /*\n * **์ํ ๊ฒฐ๊ณผ** โ 2026-08-24 ์ ์ค(์ปค๋ 0.7.57). ๊ธฐ์ค๋ง ์๊ณ ๊ฒฐ๊ณผ์ ์๋ฆฌ๊ฐ ํ์ ์์๋ค.\n *\n * ํ์ค `TestResultType`(B2MML-OperationsTest.xsd)์์ ์ฐ๋ฆฌ๊ฐ ๋ ๊ฒ:\n * `EvaluationDate`(at) ยท `Expiration`(expiresAt) ยท `TestableObjectID` ยท `PropertyMeasurement`\n * ยท `EvaluatedCriterionResult` โ **`result: 'pass'|'fail'` ๋ก ์ขํ๋ค**(ํ์ค์ ์ด๊ฑฐํ์ง ์๋๋ค)\n * ์์ง ์๋ ๊ฒ: `ID` ยท `Description` ยท `HierarchyScope` ยท `OperationsTestRequirementID` ยท\n * `TestResultChild`. ๊ทธ๋์ ๊ตฌ์กฐ๋ `partial` ์ด๋ค.\n *\n * ๊ธฐ๋ฅ์ด `partial` ์ธ ์ด์ ๋ฅผ ์ ํํ ์ ๋๋ค โ **์์์์๋ ๊ฒฐ์ ์ ๋ฐ๊พธ๊ณ ๋กํธ์์๋ ์์ง ๋ฐ๊พธ์ง\n * ์๋๋ค.** ๋ง๋ฃยท๋ถํฉ๊ฒฉ ์์์๋ ์์
์ด ๋ฐฐ์ ๋์ง ์์ง๋ง, ๋ถํฉ๊ฒฉ ๋กํธ๊ฐ ํ ๋น์์ ๋น ์ง๊ฑฐ๋ ์ฃผ์ ์ ํธ๋ฅผ\n * ์ธ์ฐ์ง๋ ์๋๋ค(๋ค๊ณ ยทํ์ ํ๊ณ ยท๋์ง์ ์๋ ์๋ค). ๊ทธ ์๋ฆฌ๋ฅผ `full` ๋ก ์ ์ผ๋ฉด ํ๊ฐ ๊ฑฐ์ง์ด ๋๋ค.\n *\n * ํ๋ฉด์ `none` ์ด๋ค โ ํด๋ผ์ด์ธํธ์ ์ด ์ถ์ ๊ทธ๋ฆฌ๋ ๊ณณ์ด ์๋ค(์ค์ธก: `operato-twin/client` ์ 0๊ณณ).\n */\n { std: 'TestResult', part: '4', label: 'twin.isa95.TestResult', axis: null, structure: 'partial', behavior: 'partial', surface: 'none' },\n { std: 'WorkMaster', part: '4', label: 'twin.isa95.WorkMaster', axis: 'recipes', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'WorkDirective', part: '4', label: 'twin.isa95.WorkDirective', axis: null, structure: 'none', behavior: 'none', surface: 'none' }\n]\n\n/** ํ์ค์ด ์๊ตฌํ๋ ๊ฒ ์ ๋ถ โ ์ด ๋ฐฐ์ด์ด ๊ณง ๊ธฐ์ค์ด๋ค. */\nexport const ISA95_CONCEPTS: Isa95Concept[] = [...PART2, ...PART4]\n\n/**\n * ์ ํฉ์ฑ ๋ณด๊ณ โ **์ฑ์ด ๊ฒ๊ณผ ๋น ์ง ๊ฒ์ ํจ๊ป.**\n *\n * `axis` ๋ฅผ ์ปค๋ ์ถ ๋ชฉ๋ก๊ณผ ๋ง์ถฐ ๋ณธ๋ค: ์ถ์ด ์๋ค๊ณ ์ ํ ์๋๋ฐ ์ปค๋์ ์์ผ๋ฉด ๊ทธ ์ ์ธ์ด ๋ก์ ๊ฒ์ด๋ฏ๋ก\n * **๊ตฌ์กฐ ์์์ผ๋ก ๋ฎ์ถ๊ณ ๊ทธ ์ฌ์ค์ ๋งํ๋ค**(์กฐ์ฉํ ํต๊ณผ์ํค๋ฉด ์ด ํ๊ฐ ๊ฑฐ์ง์ด ๋๋ค).\n */\n/**\n * ์ ์ธํ ์ถ์ ์ปค๋์ ์ถ ๋ชฉ๋ก๊ณผ ๋ง์ถ๋ค โ **์ด๊ธ๋ ๊ฒ์ ์กฐ์ฉํ ์ง์ฐ์ง ์๋๋ค.**\n *\n * ๋ ์๋ฆฌ๊ฐ ์ด๊ธ๋ ์ ์๋ค.\n * ยท `axis` โ ๊ทธ ๊ฐ๋
์์ ์ ๋ฌธ. ์ปค๋์ ์์ผ๋ฉด ๊ตฌ์กฐ๋ฅผ ใ์์ใ์ผ๋ก ๋ฎ์ถ๊ณ ๊ทธ ์ฌ์ค์ ๋งํ๋ค.\n * ยท `shownOn` โ ๊ทธ ์ฌ์ค์ ๋ค๊ณ ์๋ ๋ค๋ฅธ ์ถ. ์์ ์๋ ์๋ ์ถ์ **๋ง์์ด ๊ฑธ๋ฌ ๋๋ค.** ๊ทธ๋ฌ๋ฉด ๊ทธ ์ค์\n * ใ๊ฐ๋
์ถ์ด ์์ต๋๋คใ๋ก ๋ณด์ด๊ณ , ์ฌ๋์ ๊ทธ๊ฒ์ **์๋ ๊ทธ๋ฐ ๊ฒ**์ผ๋ก ์ฝ๋๋ค. ์ค์ ๋ก ๊ทธ ์ผ์ด ์์๋ค:\n * EPCIS ํ์ ์ผ๊ณฑ ์ค์ด ์ปค๋์ ์๋ ์ถ(`items`)์ ๊ธฐ๋๊ณ ์์๋๋ฐ, ๊ฒฝ๊ณ ๊ฐ ๋ฌ ๊ฒ์ ๋ ์ค๋ฟ์ด์๋ค.\n *\n * ๋ ์ค ํ๋๋ผ๋ ์ด๊ธ๋๋ฉด `axisMissing` ์ด๋ค โ ํ๊ฐ ์ค์ค๋ก ใ์ต์ ์ด ์๋๋คใ๋ผ๊ณ ๋งํ๊ฒ ํ๋ค.\n */\nexport function reconcileAxes(c: Isa95Concept, known: Set<string>): Isa95Concept & { axisMissing?: boolean } {\n const ownMissing = !!c.axis && !known.has(c.axis)\n const shownOn = c.shownOn?.filter(a => known.has(a))\n const lostShown = !!c.shownOn && (shownOn?.length ?? 0) !== c.shownOn.length\n const fixed = lostShown ? { ...c, shownOn } : c\n if (!ownMissing && !lostShown) return fixed\n /* ๊ตฌ์กฐ๋ฅผ ๋ฎ์ถ๋ ๊ฒ์ **์๊ธฐ ๋ฌธ์ด ์์ด์ง ๊ฒฝ์ฐ**๋ค โ ๋จ์ ์ถ์์ ๋ณด์ด๋ ๊ฒ์ ๊ตฌ์กฐ๊ฐ ์๋๋ผ ํ์์ ๋ฌธ์ ๋ค. */\n return ownMissing ? { ...fixed, structure: 'none' as CoverageLevel, axisMissing: true } : { ...fixed, axisMissing: true }\n}\n\nexport function isa95Coverage(axes: string[]): {\n model: string\n concepts: (Isa95Concept & { axisMissing?: boolean })[]\n totals: { concepts: number; structure: number; behavior: number; surface: number }\n} {\n const concepts = ISA95_CONCEPTS.map(c => reconcileAxes(c, new Set(axes)))\n /* ์ฑ์ด ์๋ `full` ๋ง ์ผ๋ค โ ๋ถ๋ถ์ ์ฑ์ด ๊ฒ์ผ๋ก ์ธ๋ฉด ๊ธฐ์ค์ด ์ค์ค๋ก๋ฅผ ์์ธ๋ค. */\n const count = (k: 'structure' | 'behavior' | 'surface') => concepts.filter(c => c[k] === 'full').length\n return {\n model: 'ISA-95',\n concepts,\n totals: { concepts: concepts.length, structure: count('structure'), behavior: count('behavior'), surface: count('surface') }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"isa95-coverage.js","sourceRoot":"","sources":["../../../server/service/twin-model/isa95-coverage.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * ISA-95 ์ ํฉ์ฑ ๊ธฐ์ค โ **ํ์ค์ด ์๊ตฌํ๋ ๊ฒ์ ๋ชฉ๋ก.**\n *\n * โโ ์ ์ด ํ์ผ์ด ํ์ํ๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ง๊ธ๊น์ง ํ๋ฉด์ \"์ฐ๋ฆฌ๊ฐ ๊ฐ์ง ์ถ\" ๋ง ๋ณด์๋ค. ๊ทธ๋ฌ๋ฉด ์ฑ์ด ๊ฒ์ ์ธ์ด์ง์ง๋ง **๋น ์ง ๊ฒ์ ์
์ ์๋ค** โ\n * ์๋ ๊ฒ์ ํ๋ฉด์ ์์ผ๋ฏ๋ก ์๋ฌด๋ ๊ทธ๊ฒ์ ๋ฌป์ง ์๋๋ค. ํ์ค ์ค์๋ \"์ฐ๋ฆฌ ์ถ์ ํ์ค ์ด๋ฆ์ ๋ถ์๋ค\"\n * ๊ฐ ์๋๋ผ **ํ์ค์ ๋ชฉ๋ก์ ๊ธฐ์ค์ผ๋ก ๋น ์ง ๊ฒ์ด ์๋ค**๋ ๋ง์ด์ด์ผ ํ๋ค. ๊ธฐ์ค์ด ์ฝ๋๋ก ์์ด์ผ ๊ทธ\n * ๋ฌธ์ฅ์ ๊ฒ์ฌํ ์ ์๋ค.\n *\n * โโ ์ธ ์ธต์์ ๋ณธ๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํ์ค ์ค์๋ ํ ์ธต์ ์ผ์ด ์๋๋ค. ๊ฐ๋
๋ง๋ค ์
์ ๋ฐ๋ก ๋ณธ๋ค:\n *\n * ยท `structure` โ **๋ฐ์ดํฐ๊ตฌ์กฐ**๊ฐ ์๋(์ปค๋ ์ถยทํธ์คํธ ํ์ ์ด ๊ฐ๋
์ ์๋ฆฌ๊ฐ ์๋)\n * ยท `behavior` โ **๊ธฐ๋ฅ**์ด ๊ทธ๊ฒ์ ์ฐ๋(์ปค๋์ด ๊ณํยท์งํยท์ง๊ณ์์ ์ค์ ๋ก ๋ค๋ฃจ๋)\n * ยท `surface` โ **UI ๋
ธ์ถ**์ด ์๋(์ฌ์ฉ์๊ฐ ๊ทธ๊ฒ์ ๋ณผ ์ ์๋)\n *\n * ์
์ ํฉ์น๋ฉด \"๊ตฌ์กฐ๋ ์๋๋ฐ ์๋ฌด๋ ์ ์ฐ๋ ์ปฌ๋ผ\" ๊ณผ \"์ปค๋์ ์ฐ๋๋ฐ ํ๋ฉด์ ์๋ ์ฌ์ค\" ์ด ๊ฐ์\n * ๊ฐ์ผ๋ก ๋ณด์ธ๋ค. ์ค์ ๋ก ์ด ํ๋ก์ ํธ์์ ๋ ๋ค ๋์๋ค(์ธ๋ ฅ ๋ช
์ธ๋ ๊ตฌ์กฐยท๊ธฐ๋ฅ์ด ์์์ง๋ง ํ๋ฉด์\n * ์์๊ณ , `properties` ๋ ๊ตฌ์กฐ๋ง ์๋ค).\n *\n * โโ ๊ฐ์ ๊ด์ธก์ด ์๋๋ผ ์ ์ธ์ด๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ฌ๊ธฐ ์ ํ ๊ฒ์ **์ฌ๋์ด ํ๋จํด ์ ์ ์ฌ์ค**์ด๋ค(์๋ ํ์ ์ด ์๋๋ค). ๊ทธ๋์ ํ๋ฆด ์ ์๊ณ , ํ๋ฆฌ๋ฉด\n * ์ฌ๊ธฐ๋ฅผ ๊ณ ์ณ์ผ ํ๋ค โ ํ๋ฉด์ ์ด ์ ์ธ์ ๊ทธ๋๋ก ๋ณด์ด๊ณ ์ง์ด๋ด์ง ์๋๋ค. ์๋์ผ๋ก ์ ์ ์๋ ๊ฒ\n * ํ๋๋ ์๋์ผ๋ก ํ๋ค: `axis` ๊ฐ ์ปค๋ ์ถ ๋ชฉ๋ก์ ์์ผ๋ฉด ๊ทธ๊ฒ์ **๊ตฌ์กฐ๊ฐ ์๋ ๊ฒ**์ด๋ค(์คํ ๋ฐฉ์ง).\n *\n * โโ ์ด ํ๊ฐ ์ปค๋์ ์๋ ์ด์ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ปค๋์ **๋ฐํ์ ๋ชจ๋ธ์ SSOT** ๋ค(๋ฌด์์ด ์๋๊ฐ). ์ด ํ๋ **์ฐธ์กฐ ๋ชจ๋ธ์ ๋ชฉ๋ก**์ด๋ค(๋ฌด์์ด ์์ด์ผ\n * ํ๋๊ฐ). ๋์ ๋ค๋ฅธ ์ข
๋ฅ์ ์ฌ์ค์ด๊ณ , ํ์๋ ์ปค๋์ ๋ฐฐํฌํ์ง ์๊ณ ๋ ๋์ด์ผ ํ๋ค.\n */\n\n/** ํ ์ธต์ ์ํ โ ์์ ยท ๋ถ๋ถ ยท ์์. \"๋ถ๋ถ\" ์ ๋๋ ์ด์ : ์ ๋ฐ ์๋ ๊ฒ์ ์๋ค๊ณ ํ๋ฉด ๊ธฐ์ค์ด ์ฃฝ๋๋ค. */\nexport type CoverageLevel = 'full' | 'partial' | 'none'\n\nexport interface Isa95Concept {\n /** ํ์ค์ด ๋ถ๋ฅด๋ ์ด๋ฆ โ ์ด ํ์ ํค๋ค(์ฐ๋ฆฌ ์ดํ๊ฐ ์๋๋ผ ํ์ค ์ดํ). */\n std: string\n /** ํ์ค์ ์ด๋ ๋ถ๋ถ์ธ๊ฐ โ Part 2(์์ ๋ชจ๋ธ) ยท Part 4(์ผ์ ยท์ค์ ) ๋ฑ. */\n part: string\n /** ์ฌ๋์ด ์ฝ๋ ์ด๋ฆ(i18n ํค). ํ๋ฉด์ด ๋ฒ์ญํ๋ค. */\n label: string\n /** ์ฐ๋ฆฌ ์ปค๋ ์ถ โ ์์ผ๋ฉด ๋ฐ์ดํฐ๊ตฌ์กฐ๊ฐ ์๋ ๊ฒ์ด๋ค. ์์ผ๋ฉด `null`. */\n axis: string | null\n /** ์ธ ์ธต์ ์ํ. `structure` ๋ `axis` ๋ก๋ ๊ฒ์ฆ๋๋ค. */\n structure: CoverageLevel\n behavior: CoverageLevel\n surface: CoverageLevel\n /** ์ ๊ทธ ์์ค์ธ์ง โ **๋ชจ๋ฅด๋ ๊ฒ์ ๊ฐ์ถ์ง ์๊ธฐ ์ํด** ํ ์ค๋ก ์ ๋๋ค(i18n ํค). */\n note?: string\n /**\n * ์๊ธฐ ์ถ์ด ์์ ๋ **์ด๋์ ๋ณด์ด๋** โ ๊ทธ ์ฌ์ค์ ๋ค๊ณ ์๋ ์ถ๋ค.\n *\n * ใ์ด๋์ใ์นธ์ด ๋ ๊ฐ์ง๋ฅผ ํฉ์ณ๊ณ ์์๋ค: *์์ง ์ถ์ด ์๋ค(๋ถ์ฑ)* ์ *์ถ์ผ ์ ์๋ค(์ค๊ณ)*. ๊ฐ์ฉ ๋ฅ๋ ฅ์\n * ๊ฐ์ฒด๊ฐ ์๋๋ผ ์์์ ์ง๊ธ ์ํ์ด๋ฏ๋ก ์ถ์ด ๋ ์ ์๋๋ฐ, ์ธ ์ธต์ด ๋ค ์์ ํ ์ค์ด \"๊ฐ๋
์ถ์ด ์์ต๋๋ค\"\n * ๋ผ๊ณ ๋ง ๋งํ๋ฉด **ํ๊ฐ ์ค์ค๋ก ๋ชจ์๋ ๋ง์ ํ๋ค**(๋ค ๋๋ค๋ฉด์ ์๋ค๊ณ ํ๋ค).\n *\n * ๊ทธ๋์ ์ถ์ผ ์ ์๋ ๊ฒ์ ๊ฐ ๊ณณ์ ๊ฐ๋ฆฌํจ๋ค. ์ฌ๊ธฐ๊ฐ ๋น์ด ์๊ณ ์ถ๋ ์์ผ๋ฉด ๊ทธ๊ฒ์ **์ง์ง ๋น์นธ**์ด๋ค.\n *\n * โโ โ
๋ป์ ๊ณ ์ณ ์ ๋๋ค (2026-08-24, ์ฌ์ฉ์ ์ง์ ) โโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํ๋ ์ด ์นธ์ ใ**์ด๋์ ๋ณด์ด๋**ใ๋ก ์ฝ๊ณ , ํ๋ฉด์ด ๊ทธ๊ฒ์ ใํด๋น ์ถ ํญ๋ชฉ์ ํ์๋ฉ๋๋คใ๋ผ๋ ๋ฌธ์ฅ์ผ๋ก\n * ๋๋ค. ๋ ๊ฐ์ง๊ฐ ์๋ชป์ด์๋ค.\n *\n * โ ๊ทธ ๋ฌธ์ฅ์ **ํ๊ตญ์ด๊ฐ ์๋์๋ค**(์ฌ์ฉ์ ์ง์ ). ๊ทธ๋ฆฌ๊ณ ์นฉ์ด ์ด๋ฏธ ๊ฐ ๊ณณ์ ๋ณด์ด๋ฏ๋ก **๊ตฐ๋๋๊ธฐ**๋ค.\n * โก ๋ป์ด ํ๋ ธ๋ค. ์ด ์นธ์ ใ**์ด๋์ ์ํ๋**ใ๋ค โ ๊ทธ ๊ฐ๋
์ด ์๊ธฐ ๋ชฉ๋ก์ ๊ฐ์ง ์๊ณ **์ด๋ ์ถ์ ์์\n * ๋ค์ด ์๋**. ํ๋ฉด์ ๊ทธ๋ ค์ง๋์ง๋ `surface` ๊ฐ ๋ฐ๋ก ๋ตํ๋ค. ๋์ ๋ค๋ฅธ ๋ฌผ์์ด๋ค.\n *\n * ๊ทธ๋์ **`surface` ์ ์ง์ ๋ง์ถ์ง ์๋๋ค.** ์๊ธฐ ์ถ์ด ์์ผ๋ฉด ์ธ์ ๋ ๊ฐ ๊ณณ์ ์ ๋๋ค โ ์์ง ๊ทธ๋ ค์ง์ง\n * ์๋ ๊ฐ๋
๋ **์ด๋์ ์ํ๋์ง๋ ์ฌ์ค**์ด๊ณ , ๊ทธ๊ฒ์ ๋น์ฐ๋ฉด ใ์ด๋์๋ ์๋ ๊ฒใ์ผ๋ก ์ฝํ๋ค.\n *\n * ์ฌ๊ธฐ๊ฐ ๋น์ด ์๊ณ ์ถ๋ ์์ผ๋ฉด ๊ทธ๊ฒ์ **์ง์ง ๋น์นธ**์ด๋ค(์ ๊ท์น).\n */\n shownOn?: string[]\n}\n\n/*\n * ๊ฐ์ฉ ๋ฅ๋ ฅ(2026-08-12, ์ปค๋ 0.6.8) โ **ํ์ ๊ณผ ์ด์ ๊ฐ ์ํ์ ์ค๋ ค ์จ๋ค**(`capability {available, reason}`).\n *\n * ์
๋ค ์์ ์ธ ๊ทผ๊ฑฐ: ์ํ๊ฐ ํ์ ์ ๋ค๊ณ ์ค๊ณ (์๋ฎฌยท๋ฏธ๋ฌ๊ฐ ๊ฐ์ ํจ์๋ก ํ์ํ๋ค), ๋ฐฐ์ ์ด ๊ฐ์ ํ์ ์\n * ์ฐ๊ณ , ๋ ํ๋ฉด์ด ๊ฐ์ ๋ฑ๋ง๋ก ๊ทธ ์ด์ ๋ฅผ ๋ณด์ธ๋ค(์์ ํญ ๋ฐฐ์ง ยท ์ธ์คํ์
๊ด์ธก ์ด).\n *\n * ์ ์ถ์ด ์๋๊ฐ โ ๊ฐ์ฉ ๋ฅ๋ ฅ์ ๊ฐ์ฒด๊ฐ ์๋๋ผ **์์์ ์ง๊ธ ์ํ**๋ค. ๊ฐ๋
์นด๋๋ก ์ธ์ฐ๋ฉด ์ฌ๋ยท์ค๋น์\n * ๋๋ํ ๋์ฌ \"๋ฅ๋ ฅ์ด ๋ช ๊ฐ์ธ๊ฐ\" ๋ฅผ ์ธ๊ฒ ๋๋๋ฐ, ๊ทธ๊ฑด ๋ฌผ์ ์ผ์ด ์๋๋ค.\n */\n\n/*\n * ์์ฐ ๋ฅ๋ ฅ(2026-08-13, ์ปค๋ 0.6.12) โ **๊ตฌ๊ฐ์ ์์ ํ์ค ์ข
๋ฅ๋ก ๊ตฌ๋ถํ๋ค.**\n *\n * `structure` ์์ : ๊ณ์ฝ์ด ๋ณด๊ณ ์๋ฅผ ๋ธ๋ค(`operationsCapabilityOf`) โ ๊ตฌ๊ฐ(StartTimeยทEndTime) ยท ํ์ค\n * ์ด๊ฑฐ๊ฐ(CommittedยทAvailableยทUnattainable) ยท ๊ณต์ ๋ณ ๋ถํด ยท ์ ์ฝํ๋ ์ถ. ๋ฑ๋ง์ B2MML ๋์กฐ ํ ํ์ค ๊ฒ์\n * ๊ทธ๋๋ก ์ด๋ค(์ฐ๋ฆฌ ๋ฑ๋ง์ ๋ง๋ค์ง ์์๋ค).\n * `behavior` ์์ : ์ฝ์ ์ ์ค๋์์, ๋ฌ์ฑ๋ถ๊ฐ๋ ์์ ํ์ (`capabilityOf`)์์ ์จ๋ค โ ๊ทธ๋ฆฌ๊ณ ๊ทธ ํ์ ์\n * ๋ฐฐ์ ์ด ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์ ํ ๋ฒ์ด๋ค. ํ์ค์ `Unattainable` ์ ์๊ฐ ๊ทธ ํ์ ๊ณผ ๊ฒน์น๋ค.\n * `surface` ์์ : ๋ ์๋ฆฌ์์ ๋ณด์ธ๋ค โ ์ฑ๊ณผ ํ๋ฉด์ด ํ์ฅ ์ ์ฒด์ \"์์ผ๋ก ๋ ๋ฐ์ ์ ์๋ ๋ชซ\" ์, ๊ณต์ \n * ์์ธ๊ฐ ๊ทธ ๊ณต์ ํ๋์ ๋ถํด(์ํยท์ฝ์ ยท๋ฌ์ฑ๋ถ๊ฐยท๊ฐ์ฉ)์ ์ ์ฝํ๋ ์ถ์ ๋ณด์ธ๋ค. ๋ ํ๋ฉด์ **๊ฐ์ ๋ฑ๋ง**์\n * ์ด๋ค(๊ฐ์ i18n ํค) โ ๊ฐ์ ์ฌ์ค์ ๋ค๋ฅด๊ฒ ๋ถ๋ฅด๋ฉด ์ด๋ ์ชฝ์ด ๋ง๋์ง ์๋ฌด๋ ๋ชจ๋ฅธ๋ค.\n *\n * ๋จ์ ๊ฒ โ ํ์ค์ **๊ฒ์๋(์ฝ์๋) ๋ฅ๋ ฅ**๋ ๋ด๋๋ค(๊ณ์ฐ์ด ์๋๋ผ ์ ์ธ). ๊ฐ์ ์ค์ ์์ค๊ฐ ์์ง\n * ์นจ๋ฌตํ๋ฏ๋ก ๋น ์ถ์ ๋จผ์ ๋ง๋ค์ง ์๋๋ค(์ํ ์ชฝ `workCalendar` ๋ฅผ ์ง์ด ์ด์ ์ ๊ฐ๋ค).\n *\n * ๊ณผ๊ฑฐ ๋ถํด(UsedยทUnused)๋ ์ด ๋ณด๊ณ ์์ ์๋ค โ ๊ทธ๊ฒ์ ์ค์ ์ด๊ณ ์ด๋ฏธ ๋ ๊ณณ์ ์๋ค(์ค๋น OEE ์ ๊ฐ๋/์ ํด,\n * ์ฑ๊ณผ ํ๋ฉด์ ๊ตฌ๊ฐ ๊ฐ๋๋ฅ ). ํ์ค์ด ๊ทธ ๋์ ๋ค๋ฅธ ์ข
๋ฅ๋ก ๋ถ๋ฅด๋ฏ๋ก **ํฉ์น์ง ์๋๋ค.**\n */\n\n/*\n * Part 2 โ ์์ ๋ชจ๋ธ. ๋ค ์์ ๊ฐ๊ฐ์ด **๋ฑ๊ธ/์ ์ โ ๊ฐ์ฒด** ์ด์ค๊ตฌ์กฐ๋ฅผ ๊ฐ๋ ๊ฒ์ด ์ด ๋ถ๋ถ์ ํต์ฌ์ด๊ณ ,\n * ๊ทธ ์ด์ค์ฑ์ด ์ด ํธ์์ ๋ผ๋์ด๊ธฐ๋ ํ๋ค.\n */\nconst PART2: Isa95Concept[] = [\n { std: 'PersonnelClass', part: '2', label: 'twin.isa95.PersonnelClass', axis: 'personnelClasses', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'Person', part: '2', label: 'twin.isa95.Person', axis: 'persons', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'PersonnelCapability', part: '2', label: 'twin.isa95.PersonnelCapability', axis: null, shownOn: ['persons'], structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.capability' },\n { std: 'EquipmentClass', part: '2', label: 'twin.isa95.EquipmentClass', axis: 'equipmentClasses', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'Equipment', part: '2', label: 'twin.isa95.Equipment', axis: 'equipment', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'EquipmentCapability', part: '2', label: 'twin.isa95.EquipmentCapability', axis: null, shownOn: ['equipment'], structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.capability' },\n { std: 'PhysicalAssetClass', part: '2', label: 'twin.isa95.PhysicalAssetClass', axis: 'assetClasses', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'PhysicalAsset', part: '2', label: 'twin.isa95.PhysicalAsset', axis: 'assets', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'MaterialClass', part: '2', label: 'twin.isa95.MaterialClass', axis: 'materialClasses', structure: 'full', behavior: 'partial', surface: 'full' },\n { std: 'MaterialDefinition', part: '2', label: 'twin.isa95.MaterialDefinition', axis: 'materialDefinitions', structure: 'full', behavior: 'full', surface: 'full' },\n /*\n * ๋กํธยท์๋ธ๋กํธ๋ ๊ฐ์ฒด ์ถ์ด ์๋๋ผ **๊ด์ธก**์ผ๋ก ์กด์ฌํ๋ค(EPCIS ๊ฐ์ฒด) โ ๊ตฌ์กฐ๋ ์ ๋์ด ๊ฐ๋๋ค.\n *\n * โโ 2026-08-24 ๋กํธ๊ฐ ์ํ ๊ฒฐ๊ณผ๋ฅผ ๋ค๊ฒ ๋๋ค (์ปค๋ 0.7.57) โโโโโโโโโโโโโโโโโ\n * `ItemState.testResults` ๋ก ใ์ด ๋กํธ๋ฅผ ์ธ ์ ์๋ใ์ **๊ทผ๊ฑฐ**๊ฐ ๋กํธ์ ์ค๋ฆฐ๋ค. ๊ทธ์ ์๋ ํ์ \n * (`disposition`)๋ง ์์๊ณ ใ์ ๊ทธ๋ ๊ฒ ํ์ ํ๋ใ๋ฅผ ๋์ง์ ์ ์์๋ค.\n *\n * **๊ตฌ์กฐ๋ฅผ `full` ๋ก ์ฌ๋ฆฌ์ง ์๋๋ค.** `MaterialLotType` ์๋ฌธ(B2MML-Material.xsd)์ด ๋๋ ๊ฒ ์ค\n * ์์ง ์๋ ๊ฒ์ด ์๋ค: `MaterialLotProperty`(์ํ์ด ์๋ ๋กํธ ์์ฑ โ ์์ฐ์งยทํฌ์ฅ ํํ) ยท\n * `TestSpecificationID`(๋กํธ๋ณ ๊ธฐ์ค ์ฐธ์กฐ โ ํ๋ชฉ ์ ์๊ฐ ๋์ ๋ตํ๋ฏ๋ก ๋์ง ์์๋ค) ยท `Status` ยท\n * `HierarchyScope` ยท `Version`. ์ฑ์ด ๊ฒ๋ง ์ธ๋ ๊ฒ์ด ์ด ํ์ ๊ท์จ์ด๋ค.\n */\n /*\n * โโ 2026-08-25 โ ๋ชฉ๋ก์ด ์์ด๊ธฐ๋ง ํ๋ ๊ฒ์ ๊ณ ์ณค๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ฐ๊ฒฐ๋ ์์คํ
์ ๋งค ์ฃผ๊ธฐ ํ์ฌ ์ฌ๊ณ ๋ฅผ ์ ๋ถ ๋ณด๋ด๋๋ฐ, ํธ์์ ๊ทธ๊ฒ์ ๋ฑ๋ฑ์ ๊ด์ธก์ผ๋ก ๋ฐ์ **๋ํ๊ธฐ๋ง\n * ํ๋ค.** ใ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ ๋ง๊ณ ๋ ์๋คใ๋ฅผ ๋ฐ๋ ๊ณณ์ด ์์ด์ ๋ชฉ๋ก์์ ๋น ์ง ์ค์ด ์์ํ ๋จ์๋ค.\n * ์ค์ธก: ์ค์ 1,704๊ฑด์ธ๋ฐ ํธ์์ด 10,038๊ฑด.\n *\n * ๊ทธ๋์ ์ด ์ค์ ใ๊ธฐ๋ฅ ์์ใ์ด์๋ค. **ํ์ฌ ์ฌ๊ณ ๋ฅผ ๋ง๊ฒ ์ ์งํ์ง ๋ชปํ๋ ์ํ๋ก ๊ทธ๋ ๊ฒ ์ ์ ์\n * ์๋ค.** ์ค๋ ใ์ด ๋ชฉ๋ก์ด ์ ๋ถ๋คใ๋ฅผ ๋ฐ๋ ๊ธธ์ ๋๊ณ (์ปค๋ 0.7.63), ์๋์ผ๋ก ์จ ์ฌ๊ณ ๋ ์์ด์ง ์\n * ์๊ฒ ํ๋ค. ์ด์ ์ฌ์ค์ด๋ค.\n */\n { std: 'MaterialLot', part: '2', label: 'twin.isa95.MaterialLot', axis: 'items', structure: 'partial', behavior: 'full', surface: 'partial', note: 'twin.isa95.note.lot' },\n /*\n * โโ 2026-08-24 ํ์ ์ ์ : `none` ์ด ์๋์๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ด ์ค์ ์
๋ค `none` ์ด์๋๋ฐ **ํ๊ฐ ์ฝ๋๋ณด๋ค ๋ค์ฒ์ ธ ์์๋ค.** ์ปค๋์ ์๋ธ๋กํธ๋ฅผ ๋ ๋ค:\n *\n * `ItemState.subLotId` ํ์ค `MaterialSubLot.ID` (๊ณ์ฝ์ด ๊ทธ๋ ๊ฒ ์ ๊ณ ์๋ค)\n * `subLotIdOf(class, location)` ๋น์ง๋ ฌ ๋กํธ๊ฐ ์๋ฆฌ๋ง๋ค ๋๋ ๋ ๊ทธ ๋ถ๋ถ์ ์ด๋ฆ์ ๋ง๋ ๋ค\n * `itemKeyOf(item)` **๊ฐ์ฒด์ ์ ์ฒด์ฑ์ด ์ด ๊ฐ์ด๋ค** โ `subLotId ?? epc`\n *\n * ๊ธฐ๋ฅ์ด `full` ์ธ ๊ทผ๊ฑฐ: ์ด ์ถ์ด ์์ผ๋ฉด ๊ฐ์ ๋กํธ๋ฅผ rack-1 ์ 100๊ฐยทrack-2 ์ 60๊ฐ ๊ด์ธกํ์ ๋\n * **๋ค์ ์จ ๊ด์ธก์ด ์์ ๋ฎ์ด 100๊ฐ๊ฐ ์ค๋ฅ ์์ด ์ฌ๋ผ์ง๋ค**(ํฉ๊ณ 160 โ 60). ์ค์ ๋ก ๊ทธ ๊ฒฐํจ์ ์ด ์ถ์ผ๋ก\n * ๊ณ ์ณค๋ค. ์ฆ ์ฅ์์ด ์๋๋ผ ์ ์ฒด์ฑ์ ์งํฑํ๋ค.\n *\n * ๊ตฌ์กฐ๊ฐ `partial` ์ธ ์ด์ : ์๋ธ๋กํธ๋ ๋กํธ์ ๊ฐ์ ๋ชจ์์ด๊ณ (์ ์ฐธ์กฐ) ๊ทธ ๋กํธ๊ฐ `partial` ์ด๋ค.\n * ํ๋ฉด์ด `partial` ์ธ ์ด์ : ๊ฐ์ด ๋ฌผํ์ **์ด๋ฆ์ผ๋ก** ๋์จ๋ค(`twin-item` ์ line) โ ใ์ด ๋กํธ๊ฐ ์๋ฆฌ๋ง๋ค\n * ๋๋์ด ์๋คใ๋ฅผ ๋งํ๋ ์๋ฆฌ๋ ์์ง ์๋ค.\n *\n * ์ด ๋ถ๋ฅ(์ฝ๋์ ์๋๋ฐ ํ๊ฐ `none`)๋ ์๋์ผ๋ก ์กํ์ง ์๋๋ค โ ํ์ ๊ฐ๋๋ ๋ฐ๋ ๋ฐฉํฅ๋ง ๋ณธ๋ค\n * (์ถ์ด ์ฌ๋ผ์ง๋ฉด ๊ตฌ์กฐ๋ฅผ ๋ด๋ฆฐ๋ค). ๊ทธ๋์ ์ถ์ ๋๋ฆด ๋ ์ด ํ๋ฅผ ํจ๊ป ๋ณด๋ ๊ฒ์ด ๊ท์จ์ด๋ค.\n */\n { std: 'MaterialSublot', part: '2', label: 'twin.isa95.MaterialSublot', axis: null, shownOn: ['items'], structure: 'partial', behavior: 'full', surface: 'partial' },\n { std: 'ProcessSegment', part: '2', label: 'twin.isa95.ProcessSegment', axis: 'operations', structure: 'full', behavior: 'full', surface: 'full' },\n /*\n * ์์ฑ์ ์์๋ง๋ค ๋ถ๋ ํ์ฅ์ด๋ผ **์๊ธฐ ์ถ์ด ์๋๋ค** โ ๊ทธ๋์ `axis` ๋ ์์ง๋ง ๊ตฌ์กฐ๋ ์์ ํ๋ค:\n * ๊ณ์ฝ(`ResourceProperty`: ๊ฐยท๋ฐ์ดํฐํยท๋จ์ยทํ์ยท๋ฑ๊ธ์์ฑ)์ด ํ์ค์ ๊ทธ๋๋ก ๋ด๊ณ , ์ธ์ ์คํธยท์ํยท\n * ํ๋ฉด์ด ๊ทธ๊ฒ์ ํต๊ณผ์ํจ๋ค.\n *\n * ๊ธฐ๋ฅ์ **๋ถ๋ถ**์ด๋ค: ํธ์คํธ์ ์ฃผํ ์ถ์ ๊ธฐ๊ฐ `speed` ๋ฅผ ์ฝ์ด ์ด๋ ์๊ฐ์ ๋ง๋๋ ๊ฒ์ด ์ ์ผํ ์๋น์ฒ๋ค\n * (๋ค๋ฅธ ์์ฑ์ ์์ง ์๋ฌด๋ ์ฝ์ง ์๋๋ค). ๊ทธ ์ฌ์ค์ `full` ๋ก ์ฌ๋ฆฌ๋ฉด ํ๊ฐ ๊ฑฐ์ง์ด ๋๋ค.\n */\n { std: 'Property', part: '2', label: 'twin.isa95.Property', axis: null, shownOn: ['equipment', 'persons', 'assets'], structure: 'full', behavior: 'partial', surface: 'full', note: 'twin.isa95.note.property' },\n /*\n * **์๋ฆฌ์ ์์ ๊ด์ธก** โ 2026-08-24 ์ ์ค(์ปค๋ 0.7.56). ํ์ ์ด ๊ฐ๋
์ด ์์ ์์๋ค.\n *\n * ์ ์ด ์ถ์ด ํ์ํ๊ฐ: ํธ์์ ํ์ ๋์์ ๋ฌผ๊ฑด์ ์ํ์ด๊ณ , ๋ฌผ๊ฑด์ ์ํ๋ **์กฐ๊ฑด ์์ด ์ ํด์ง์ง\n * ์๋๋ค.** ใ์ด ๋กํธ๊ฐ ๋์ฅ์ค์ ์์๋คใ๊น์ง๋ง ์๋ ํธ์์ ๊ทธ ๋กํธ๊ฐ ๊ด์ฐฎ์๋์ง ๋งํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ \n * **์ด ์กฐ์ธ์ ํธ์๋ง ํ ์ ์๋ค** โ ๊ณ์ธก ์์คํ
์ ๋ฌผ๊ฑด์ ์๋ฆฌ ์ด๋ ฅ์ ๋ชจ๋ฅด๊ณ , ๋ฌผ๋ฅ ์์คํ
์ ์กฐ๊ฑด\n * ์ด๋ ฅ์ ๋ชจ๋ฅธ๋ค.\n *\n * ํ์ค ์ต์ปค: `OperationsEventType`(B2MML-OperationsEvent.xsd, ISA-95.00.02-2018) +\n * `OperationsRecordTemplateType`. ์ฐ๋ฆฌ๊ฐ ๋ ๊ฒ โ `EffectiveTimestamp` ยท `EffectiveEndDate` ยท\n * `RecordTimestamp` ยท `HierarchyScope`(์๋ฆฌ) ยท `Source` ยท ๊ฐ์ `ValueType` ์ผ๋ก **์ขํ๋ค**\n * (๋จ์ ์๋ ๋ฌผ๋ฆฌ๋์ ํ์ ์ ์ฌ๋ฃ๊ฐ ๋ชป ๋๋ค).\n *\n * ๋ถ๋ ์๋ฆฌ๊ฐ `HierarchyScope.EquipmentID` ์ธ ๊ฒ์ด ์ค์ํ๋ค โ ISA-95 ์์ ์ฅ์ ๊ณ์ธต์ด ๊ณง ์ค๋น\n * ๊ณ์ธต์ด๊ณ ๋์ฅ์ค์ `StorageZone` ์์ค์ ์ค๋น๋ค. `OperationalLocationType` ์๋ ์ด ์ถ์ด ์๋ค.\n *\n * ๊ตฌ์กฐ๊ฐ `partial`: ๋ดํฌ ์ ์ฒด(`ID`ยท`Description`ยท์ฌ๊ฑด ๋ถ๋ฅยท`OperationsRecord` ๊ตฌ์กฐ)๊ฐ ์๋๋ผ ๊ด์ธก\n * ํ๋๋ฅผ ๋ด๋ ๋ฐ ํ์ํ ์นธ๋ง ๋ ๋ค. 2026-08-25 ์ ์ง๋ ๊ธฐ๋ก์ ๋ดํฌ๊ฐ ์ฌ๋์ด ์ ์ ๋ฌธ์ฅ์ ํจ๊ป\n * ๋๋ฅด๊ฒ ๋์ง๋ง(`CanonicalEnvelope.description`), ๊ทธ๊ฒ์ **๊ธฐ๋ก์ ๋จ๋ ๋ง**์ด๊ณ ์ด ํ์
์\n * `Description` ์นธ์ด ์๋๋ค โ ์ํ์ ๋ด๊ธฐ์ง ์์ผ๋ฏ๋ก ์ด ์ค์ ๋ฑ๊ธ์ ์ฌ๋ฆฌ์ง ์๋๋ค.\n * ๊ธฐ๋ฅ์ด `full`: ์ฌ๊ฑด ์ฑ๋(`location.measured`)์ด ์ํ๋ฅผ ๋ง๋ค๊ณ , ์ ์ธ๋ ๊ธฐ์ค์ผ๋ก ํ์ ํด\n * `observation-out-of-limit` ์ ํธ๋ฅผ ์ธ์ด๋ค.\n * ํ๋ฉด์ด `none`: ํด๋ผ์ด์ธํธ์ ์ด ์ถ์ ๊ทธ๋ฆฌ๋ ๊ณณ์ด ์๋ค(์ค์ธก 0๊ณณ).\n */\n /*\n * โโ 2026-08-25 โ ์ด ์ค์ด ์ค์ ๋ณด๋ค ๋๊ฒ ์ ํ ์์๋ค โโโโโโโโโโโโโโโโโโโโโโโโ\n * ใ๊ธฐ๋ฅ ์์ใ์ผ๋ก ์ ์ด ๋์๋ค. ์ปค๋์ด ๊ด์ธก์ ๋ฐ์ํ๊ณ ๊ธฐ์ค์ผ๋ก ํ๋จํ๋ ๊ฒ์ ์ฌ์ค์ด์์ผ๋ฏ๋ก\n * ๊ทธ๋ ๊ฒ ์ ์๋๋ฐ, **์ฐ๊ฒฐ๋ ์์คํ
์ด ๊ทธ ๊ฐ์ ๋ณด๋ผ ๊ธธ์ด ์์๋ค** โ ์ ์
๊ฒฝ๋ก๊ฐ `locationId` ๋ฅผ\n * ๋ณด์ง ์์ ใ์ด๋ ์ฌ์ค์ธ์ง ๋ชจ๋ฅธ๋คใ๋ก ๊ฑฐ๋ถํ๋ค.\n *\n * **์๋ฌด๋ ๋จน์ผ ์ ์๋ ๊ธฐ๋ฅ์ ๋์ํ๋ ๊ธฐ๋ฅ์ด ์๋๋ค.** ์ค๋ ๊ทธ ๊ฒฝ๋ก๋ฅผ ๋๊ณ (์ปค๋ 0.7.62),\n * ์ด์ ใ๊ธฐ๋ฅ ์์ใ์ด ์ฌ์ค์ด๋ค. ๊ทธ๋๊น์ง๋ ใ์ผ๋ถใ์์ด์ผ ํ๋ค.\n *\n * ๊ฐ์ ๋ถ๋ฅ๋ฅผ ์ค๋ ์ธ ๋ฒ ๋ง๋ฌ๋ค โ ํ๊ฐ **ํ ์ ์๋ ์ผ์ ๋ชป ํ๋ค๊ณ ** ์ ์ ๊ฒ์ด ์ฌ์ฏ ์ค์ด์๊ณ ,\n * ์ด๊ฒ์ ๋ฐ๋๋ก **๋ชป ํ๋ ์ผ์ ํ ์ ์๋ค๊ณ ** ์ ์ ๊ฒ์ด๋ค. ๋ค์ชฝ์ด ๋ ์ํํ๋ค.\n */\n { std: 'OperationsEvent', part: '2', label: 'twin.isa95.OperationsEvent', axis: null, shownOn: ['locations'], structure: 'partial', behavior: 'full', surface: 'none' }\n]\n\n/*\n * Part 4 โ ์ผ์ ๊ณผ ์ค์ .\n *\n * **2026-08-11 ์ด์ ์๋ ์ด ๋ถ๋ถ์ด ๊ฑฐ์ ๋น์ด ์์๋ค.** ์ค๋ยท์์
์ ๋ฐํ์๊ณผ ์ ๋์ ์ค์ฌํ๋๋ฐ ์กฐํ\n * ๋ชจ๋ธ์ ์ถ์ด ์๋์๊ณ , ๊ทธ๋์ \"์ด ํธ์์ด ํ์ค์ ์ด๋๋ฅผ ์ฑ์ฐ๋\" ๋ผ๋ ์ง๋ฌธ์ ์ ๋ฐ๋ง ๋ตํ๋ค.\n *\n * ์ปค๋์ด ๊ณ์ฝ์ ๋ํ(`source: 'state'`) ๋ ์ถ์ด ์ถ๊ฐ๋์๋ค โ ์ด์ ์๊ตฌ(`orders`)์ ์๋ต(`tasks`)์ ๊ฐ๋
์ผ๋ก\n * ๊ฐ๋ฆฌ์ผ ๊ฑธ์ด ๋ค์ด๊ฐ ์ ์๋ค. ๋จ์ ๊ฒ์ **๊ณผ๊ฑฐ๋ก ๋ค์ ๊ณ์ฐํ๋ ๊ธธ**(์ ๋ ์ปค์ ํ์ด์ง)๊ณผ ๋ฅ๋ ฅยท๊ฒ์ฌ ๋ช
์ธ๋ค.\n */\nconst PART4: Isa95Concept[] = [\n { std: 'OperationsDefinition', part: '4', label: 'twin.isa95.OperationsDefinition', axis: 'productionSpec', structure: 'full', behavior: 'full', surface: 'partial', note: 'twin.isa95.note.opsdef' },\n /*\n * 2026-08-11 โ **์ถ์ด ์ถ๊ฐ๋์๋ค**(์ปค๋ 0.6.3 ยท `source: 'state'`). ์๊ตฌ๋ `orders`, ์๋ต์ `tasks` ๋ค.\n *\n * `structure` ๋ฅผ `full` ๋ก ์ฌ๋ฆฐ๋ค: ๋ด์ ์๋ฆฌ๊ฐ ๊ณ์ฝ์ ์๋ค(์ํ ๊ณ์ฝ + ์ถ ์ ์ธ). **ํ
์ด๋ธ ํฌ์์ด\n * ์๋ ๊ฒ์ ๊ฒฐ์์ด ์๋๋ค** โ ์ด ์ถ์ ์ ๋ณธ์ ์ ๋์ด๊ณ , ํฌ์ํ์ง ์๋ ๊ฒ์ด ๊ฒฐ์ ์ด๋ค(ADR-0032-D).\n *\n * `surface` ๋ `full` ์ด๋ค(๊ฐ์ ๋ ๋ ๋ฒ์งธ ๋จ๊ณ): ๋ชฉ๋กยท์์ธยท๊ด๊ณ์ ๋ํด **๊ณผ๊ฑฐ๋ก ๋ค์ ๊ณ์ฐํ๋ ๊ธธ**์ด ํ๋ฉด์\n * ์๋ค โ ์๊ฐ ์ปค์๋ฅผ ์ฎ๊ธฐ๋ฉด ๊ทธ ์์ ์ ์ฌ์ค์ด ๋์ค๊ณ , ๋ฌด์์ ๊ทผ๊ฑฐ๋ก ๋ตํ๋์ง๋ ํ๋ฉด์ด ๋งํ๋ค\n * (๋ผ์ด๋ธ=๊ถ์ ยท ์ ๋=ํ์ ยท ๊ณ์ฐํ ๋ฆฌ๋น์ ). ์ค์ธก: ์ด๋ฅธ ์๊ฐ 0๊ฑด ยท ํ๋ฃจ ๋ค 504๊ฑด.\n */\n { std: 'OperationsSchedule', part: '4', label: 'twin.isa95.OperationsSchedule', axis: 'orders', structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.schedule' },\n { std: 'OperationsPerformance', part: '4', label: 'twin.isa95.OperationsPerformance', axis: 'tasks', structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.performance' },\n { std: 'OperationsCapability', part: '4', label: 'twin.isa95.OperationsCapability', axis: null, shownOn: ['operations'], structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.opscapability' },\n /*\n * 2026-08-12 โ **์ถ์ด ์ถ๊ฐ๋์๋ค**(์ปค๋ 0.6.5). ์์ ์ํ์ด ๊ฐ๋ฆฌํค๋ ์ฐธ์กฐ์ ๋์์ด ์๊ฒผ๊ณ , ์๋ ๋ช
์ธ๋ฅผ\n * ๊ฐ๋ฆฌํค๋ฉด ์ ์ฑ์์ด ๋์ด์ง ์ฐธ์กฐ๋ก ์ผ๋ค.\n *\n * ๊ธฐ๋ฅ์ด **`partial` ๋ก ์ด์๋ฌ๋ค**(์ปค๋ 0.6.6): ๊ฒฐ๊ณผ(`TestResult`)๊ฐ ๊ณ์ฝ์ ๋ค์ด์ค๋ฉด์ ์ปค๋์ด ๋ฐฐ์ ์์\n * ๊ทธ๊ฒ์ ๋ณธ๋ค โ ๋ง๋ฃยท๋ถํฉ๊ฒฉ์ด๋ฉด ๊ทธ ์๊ฒฉ์ ์ฑ๋ฆฝํ์ง ์๋๋ค(์ค์ธก: ๋ง๋ฃ๋ ์ฉ์ ์ฌ๋ ์ฉ์ ์์
5๊ฑด ์ค ํ\n * ๋ฒ๋ ๋ฐฐ์ ๋์ง ์์๋ค).\n *\n * โโ 2026-08-24 ์ ๋ฌธ์ฅ ํ๋๊ฐ ๋ก์๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ใ**์ฌ๋๋ง ํ์ ํ๋ค**ใ๊ณ ์ ํ ์์๋ค. ์ง๊ธ์ ์๋๋ค โ `capabilityOfResource` ๊ฐ ์ค๋นยท์ฌ๋ยท์์ฐ\n * **์
๋ชจ๋**์ `requiredTests` ๋ฅผ ๊ฑธ๊ณ , ๊ทธ ๋ต์ด ๋ฐฐ์ ์ ๊ฐ์ฉ์ฑ ํํฐ๋ก ๋ค์ด๊ฐ๋ค. ๊ทธ๋ฆฌ๊ณ ํ์ ๋์์ด\n * ์์ ๋ฐ์ผ๋ก ๋์ด์ก๋ค: **์๋ฆฌ์ ์์ ๊ด์ธก**(`OperationsEvent` ์ค)๊ณผ **๋กํธ์ ์ํ ๊ฒฐ๊ณผ**\n * (`TestResult` ์ค)๋ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ํ์ ํ๋ค.\n *\n * ๋จ์ ๊ท์จ์ ํ๋๋ค: **๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด ํ์ ํ์ง ์๋๋ค**(์ ์ธํ ๊ฒ๋ง ์ ์ฝ์ด ๋๋ค โ ๊ฒฐ์์ด ์๋๋ผ ๊ท์จ).\n *\n * ๊ทธ๋ฆฌ๊ณ ๊ธฐ์ค์ **์ซ์ ํ๊ณ๋ ์ฐ๋ฆฌ๊ฐ ๋ํ ๊ฒ**์ด๋ค. ํ์ค `TestSpecificationCriteria.Expression` ์\n * ์์ ๋ฌธ์ฅ(`TextType`)์ด๊ณ , B2MML ์ผ๊ณฑ ํ์ผ์ `Minimum`ยท`Maximum`ยท`Tolerance` ๊ฐ ํ๋๋ ์๋ค\n * (์๋ฌธ ๋์กฐ). ๊ทธ๊ฒ ์์ด๋ ํ์ ํ ์ ์์ผ๋ฏ๋ก `limit: {minimum, maximum, uom}` ์ ๋ํ๊ณ , ๋ฐ๋ช
ํ\n * ์๋ฆฌ์์ ๊ณ์ฝ์ ์ ์๋ค. ์ปค๋์ `Expression` ์ **์ฝ์ง ์๋๋ค** โ ๋ฌธ๋ฒ์ด ์ ์๋์ง ์์์ผ๋ฏ๋ก\n * ํ์ฑํ๋ฉด ๊ทธ ์๊ฐ ๋ฐฉ์ธ์ด๋ค.\n */\n { std: 'TestSpecification', part: '4', label: 'twin.isa95.TestSpecification', axis: 'testSpecifications', structure: 'full', behavior: 'full', surface: 'full', note: 'twin.isa95.note.test' },\n /*\n * **์ํ ๊ฒฐ๊ณผ** โ 2026-08-24 ์ ์ค(์ปค๋ 0.7.57). ๊ธฐ์ค๋ง ์๊ณ ๊ฒฐ๊ณผ์ ์๋ฆฌ๊ฐ ํ์ ์์๋ค.\n *\n * ํ์ค `TestResultType`(B2MML-OperationsTest.xsd)์์ ์ฐ๋ฆฌ๊ฐ ๋ ๊ฒ:\n * `EvaluationDate`(at) ยท `Expiration`(expiresAt) ยท `TestableObjectID` ยท `PropertyMeasurement`\n * ยท `EvaluatedCriterionResult` โ **`result: 'pass'|'fail'` ๋ก ์ขํ๋ค**(ํ์ค์ ์ด๊ฑฐํ์ง ์๋๋ค)\n * ์์ง ์๋ ๊ฒ: `ID` ยท `Description` ยท `HierarchyScope` ยท `OperationsTestRequirementID` ยท\n * `TestResultChild`. ๊ทธ๋์ ๊ตฌ์กฐ๋ `partial` ์ด๋ค.\n *\n * ๊ธฐ๋ฅ์ด `partial` ์ธ ์ด์ ๋ฅผ ์ ํํ ์ ๋๋ค โ **์์์์๋ ๊ฒฐ์ ์ ๋ฐ๊พธ๊ณ ๋กํธ์์๋ ์์ง ๋ฐ๊พธ์ง\n * ์๋๋ค.** ๋ง๋ฃยท๋ถํฉ๊ฒฉ ์์์๋ ์์
์ด ๋ฐฐ์ ๋์ง ์์ง๋ง, ๋ถํฉ๊ฒฉ ๋กํธ๊ฐ ํ ๋น์์ ๋น ์ง๊ฑฐ๋ ์ฃผ์ ์ ํธ๋ฅผ\n * ์ธ์ฐ์ง๋ ์๋๋ค(๋ค๊ณ ยทํ์ ํ๊ณ ยท๋์ง์ ์๋ ์๋ค). ๊ทธ ์๋ฆฌ๋ฅผ `full` ๋ก ์ ์ผ๋ฉด ํ๊ฐ ๊ฑฐ์ง์ด ๋๋ค.\n *\n * ํ๋ฉด์ `none` ์ด๋ค โ ํด๋ผ์ด์ธํธ์ ์ด ์ถ์ ๊ทธ๋ฆฌ๋ ๊ณณ์ด ์๋ค(์ค์ธก: `operato-twin/client` ์ 0๊ณณ).\n */\n { std: 'TestResult', part: '4', label: 'twin.isa95.TestResult', axis: null, shownOn: ['items'], structure: 'partial', behavior: 'partial', surface: 'none' },\n { std: 'WorkMaster', part: '4', label: 'twin.isa95.WorkMaster', axis: 'recipes', structure: 'full', behavior: 'full', surface: 'full' },\n { std: 'WorkDirective', part: '4', label: 'twin.isa95.WorkDirective', axis: null, structure: 'none', behavior: 'none', surface: 'none' }\n]\n\n/** ํ์ค์ด ์๊ตฌํ๋ ๊ฒ ์ ๋ถ โ ์ด ๋ฐฐ์ด์ด ๊ณง ๊ธฐ์ค์ด๋ค. */\nexport const ISA95_CONCEPTS: Isa95Concept[] = [...PART2, ...PART4]\n\n/**\n * ์ ํฉ์ฑ ๋ณด๊ณ โ **์ฑ์ด ๊ฒ๊ณผ ๋น ์ง ๊ฒ์ ํจ๊ป.**\n *\n * `axis` ๋ฅผ ์ปค๋ ์ถ ๋ชฉ๋ก๊ณผ ๋ง์ถฐ ๋ณธ๋ค: ์ถ์ด ์๋ค๊ณ ์ ํ ์๋๋ฐ ์ปค๋์ ์์ผ๋ฉด ๊ทธ ์ ์ธ์ด ๋ก์ ๊ฒ์ด๋ฏ๋ก\n * **๊ตฌ์กฐ ์์์ผ๋ก ๋ฎ์ถ๊ณ ๊ทธ ์ฌ์ค์ ๋งํ๋ค**(์๋ฆฌ์ง ์๊ณ ํต๊ณผ์ํค๋ฉด ์ด ํ๊ฐ ๊ฑฐ์ง์ด ๋๋ค).\n */\n/**\n * ์ ์ธํ ์ถ์ ์ปค๋์ ์ถ ๋ชฉ๋ก๊ณผ ๋ง์ถ๋ค โ **์ด๊ธ๋ ๊ฒ์ ์๋ฆฌ์ง ์๊ณ ์ง์ฐ์ง ์๋๋ค.**\n *\n * ๋ ์๋ฆฌ๊ฐ ์ด๊ธ๋ ์ ์๋ค.\n * ยท `axis` โ ๊ทธ ๊ฐ๋
์์ ์ ๋ฌธ. ์ปค๋์ ์์ผ๋ฉด ๊ตฌ์กฐ๋ฅผ ใ์์ใ์ผ๋ก ๋ฎ์ถ๊ณ ๊ทธ ์ฌ์ค์ ๋งํ๋ค.\n * ยท `shownOn` โ ๊ทธ ์ฌ์ค์ ๋ค๊ณ ์๋ ๋ค๋ฅธ ์ถ. ์์ ์๋ ์๋ ์ถ์ **๋ง์์ด ๊ฑธ๋ฌ ๋๋ค.** ๊ทธ๋ฌ๋ฉด ๊ทธ ์ค์\n * ใ๊ฐ๋
์ถ์ด ์์ต๋๋คใ๋ก ๋ณด์ด๊ณ , ์ฌ๋์ ๊ทธ๊ฒ์ **์๋ ๊ทธ๋ฐ ๊ฒ**์ผ๋ก ์ฝ๋๋ค. ์ค์ ๋ก ๊ทธ ์ผ์ด ์์๋ค:\n * EPCIS ํ์ ์ผ๊ณฑ ์ค์ด ์ปค๋์ ์๋ ์ถ(`items`)์ ๊ธฐ๋๊ณ ์์๋๋ฐ, ๊ฒฝ๊ณ ๊ฐ ๋ฌ ๊ฒ์ ๋ ์ค๋ฟ์ด์๋ค.\n *\n * ๋ ์ค ํ๋๋ผ๋ ์ด๊ธ๋๋ฉด `axisMissing` ์ด๋ค โ ํ๊ฐ ์ค์ค๋ก ใ์ต์ ์ด ์๋๋คใ๋ผ๊ณ ๋งํ๊ฒ ํ๋ค.\n */\nexport function reconcileAxes(c: Isa95Concept, known: Set<string>): Isa95Concept & { axisMissing?: boolean } {\n const ownMissing = !!c.axis && !known.has(c.axis)\n const shownOn = c.shownOn?.filter(a => known.has(a))\n const lostShown = !!c.shownOn && (shownOn?.length ?? 0) !== c.shownOn.length\n const fixed = lostShown ? { ...c, shownOn } : c\n if (!ownMissing && !lostShown) return fixed\n /* ๊ตฌ์กฐ๋ฅผ ๋ฎ์ถ๋ ๊ฒ์ **์๊ธฐ ๋ฌธ์ด ์์ด์ง ๊ฒฝ์ฐ**๋ค โ ๋จ์ ์ถ์์ ๋ณด์ด๋ ๊ฒ์ ๊ตฌ์กฐ๊ฐ ์๋๋ผ ํ์์ ๋ฌธ์ ๋ค. */\n return ownMissing ? { ...fixed, structure: 'none' as CoverageLevel, axisMissing: true } : { ...fixed, axisMissing: true }\n}\n\nexport function isa95Coverage(axes: string[]): {\n model: string\n concepts: (Isa95Concept & { axisMissing?: boolean })[]\n totals: { concepts: number; structure: number; behavior: number; surface: number }\n} {\n const concepts = ISA95_CONCEPTS.map(c => reconcileAxes(c, new Set(axes)))\n /* ์ฑ์ด ์๋ `full` ๋ง ์ผ๋ค โ ๋ถ๋ถ์ ์ฑ์ด ๊ฒ์ผ๋ก ์ธ๋ฉด ๊ธฐ์ค์ด ์ค์ค๋ก๋ฅผ ์์ธ๋ค. */\n const count = (k: 'structure' | 'behavior' | 'surface') => concepts.filter(c => c[k] === 'full').length\n return {\n model: 'ISA-95',\n concepts,\n totals: { concepts: concepts.length, structure: count('structure'), behavior: count('behavior'), surface: count('surface') }\n }\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/*
|
|
3
3
|
* **๊ฐ์ฒด์์ ํ๋ชฉ์ผ๋ก** โ ์ ์ฒด์ฑ ๋ชจ์์ด ํ๋๊ฐ ์๋๋ค (2026-08-23).
|
|
4
4
|
*
|
|
5
|
-
* โโ ๋ฌด์์ด
|
|
5
|
+
* โโ ๋ฌด์์ด ์๋ฆฌ์ง ์๊ณ ๋น์ด ์์๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
6
6
|
* ํ๋ฉด์ด ใ์ด ๊ฐ์ฒด๋ ์ ์ธ๋ ์์ฌ๊ฐ ์๋๋๋ค(๋ผ์ธ ๋ด๋ถ์ ์ค๊ฐ ์ฐ๋ฌผ์ผ ์ ์์ต๋๋ค)ใ๋ผ๊ณ ๋งํ๋๋ฐ, ๊ทธ
|
|
7
7
|
* ํ๋ชฉ์ ์๋ณธ์ ์ ์ธ์ ์ด๋ฆ๊น์ง ์์๋ค(ใ๋๋๊ทธ๋ฆฐ๋น์คใ). ๋์ ํ(`productionSpec.binding`)๋ ๋ฉ์ฉกํ๋ค.
|
|
8
8
|
*
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* https://โฆ/class/product-M0000438@M2R0001 โ null (๋ชจ๋ฅด๋ ๋ชจ์)
|
|
13
13
|
*
|
|
14
14
|
* ์น URI ๋ก ์ ์ฒด์ฑ์ ๋งํ๋ ์๋ณธ์์๋ ์ธ์ ๋ `null` ์ด ๋์๊ณ , ๊ทธ๋์ **๊ฐ์ฒด๋ฅผ ์์ฌ์ ์ด์ ์ ์์๋ค.**
|
|
15
|
-
* ๊ทธ ๊ฒฐ๊ณผ๊ฐ ํ๋ฉด ๋ ๊ณณ์์
|
|
15
|
+
* ๊ทธ ๊ฒฐ๊ณผ๊ฐ ํ๋ฉด ๋ ๊ณณ์์ ๋ค์ด์จ ๊ฒ์ด ์๋ ๋น์นธ์ด์๋ค(๊ณ๋ณด ์ ํฉ์ฑ ยท ์ค๋๊ฐ ๋ฌด์์ ๋ง๋๋). ใ์์ผ๋ฉด ๋ถ์ด์ง
|
|
16
16
|
* ์๋๋คใ๋ ๊ท์จ์ ์งํค๊ธฐ ๋๋ฌธ์ ์๋ฌด ์ค๋ฅ๋ ๋์ง ์์๋ค.
|
|
17
17
|
*
|
|
18
18
|
* โโ ๋ฌด์์ ๋๋ ค์ฃผ๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item-ref.js","sourceRoot":"","sources":["../../../server/service/twin-model/item-ref.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;;AAaH,8BAWC;AAaD,oDAaC;AAhDD;;;;;;;;;;GAUG;AACH,SAAgB,SAAS,CAAC,GAAY;IACpC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IACxC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IACpB,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnB,sEAAsE;IACtE,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC9C,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAA;IAE1B,iDAAiD;IACjD,OAAO,CAAC,CAAA;AACV,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,oBAAoB,CAAI,GAAkB,EAAE,QAAwB;IAClF,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAA;IAC1B,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC/B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IACrC,IAAI,GAAkB,CAAA;IACtB,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,SAAQ;QACvD,KAAK,EAAE,CAAA;QACP,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,SAAS,CAAA;QAC/B,GAAG,GAAG,KAAK,CAAA;IACb,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC","sourcesContent":["/*\n * **๊ฐ์ฒด์์ ํ๋ชฉ์ผ๋ก** โ ์ ์ฒด์ฑ ๋ชจ์์ด ํ๋๊ฐ ์๋๋ค (2026-08-23).\n *\n * โโ ๋ฌด์์ด
|
|
1
|
+
{"version":3,"file":"item-ref.js","sourceRoot":"","sources":["../../../server/service/twin-model/item-ref.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;;AAaH,8BAWC;AAaD,oDAaC;AAhDD;;;;;;;;;;GAUG;AACH,SAAgB,SAAS,CAAC,GAAY;IACpC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IACxC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IACpB,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnB,sEAAsE;IACtE,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC9C,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAA;IAE1B,iDAAiD;IACjD,OAAO,CAAC,CAAA;AACV,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,oBAAoB,CAAI,GAAkB,EAAE,QAAwB;IAClF,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAA;IAC1B,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC/B,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IACrC,IAAI,GAAkB,CAAA;IACtB,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAAE,SAAQ;QACvD,KAAK,EAAE,CAAA;QACP,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,SAAS,CAAA;QAC/B,GAAG,GAAG,KAAK,CAAA;IACb,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC","sourcesContent":["/*\n * **๊ฐ์ฒด์์ ํ๋ชฉ์ผ๋ก** โ ์ ์ฒด์ฑ ๋ชจ์์ด ํ๋๊ฐ ์๋๋ค (2026-08-23).\n *\n * โโ ๋ฌด์์ด ์๋ฆฌ์ง ์๊ณ ๋น์ด ์์๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํ๋ฉด์ด ใ์ด ๊ฐ์ฒด๋ ์ ์ธ๋ ์์ฌ๊ฐ ์๋๋๋ค(๋ผ์ธ ๋ด๋ถ์ ์ค๊ฐ ์ฐ๋ฌผ์ผ ์ ์์ต๋๋ค)ใ๋ผ๊ณ ๋งํ๋๋ฐ, ๊ทธ\n * ํ๋ชฉ์ ์๋ณธ์ ์ ์ธ์ ์ด๋ฆ๊น์ง ์์๋ค(ใ๋๋๊ทธ๋ฆฐ๋น์คใ). ๋์ ํ(`productionSpec.binding`)๋ ๋ฉ์ฉกํ๋ค.\n *\n * ์์ธ์ **๊ฐ์ฒด์์ ํ๋ชฉ์ ๊บผ๋ด๋ ๊ท์น**์ด์๋ค. ๊ทธ ๊ท์น์ด GS1 SGTIN URN ํ๋๋ง ์์๋ค.\n *\n * urn:epc:id:sgtin:0614141.077101.42 โ 077101 (์๋ ๋ชจ์)\n * https://โฆ/class/product-M0000438@M2R0001 โ null (๋ชจ๋ฅด๋ ๋ชจ์)\n *\n * ์น URI ๋ก ์ ์ฒด์ฑ์ ๋งํ๋ ์๋ณธ์์๋ ์ธ์ ๋ `null` ์ด ๋์๊ณ , ๊ทธ๋์ **๊ฐ์ฒด๋ฅผ ์์ฌ์ ์ด์ ์ ์์๋ค.**\n * ๊ทธ ๊ฒฐ๊ณผ๊ฐ ํ๋ฉด ๋ ๊ณณ์์ ๋ค์ด์จ ๊ฒ์ด ์๋ ๋น์นธ์ด์๋ค(๊ณ๋ณด ์ ํฉ์ฑ ยท ์ค๋๊ฐ ๋ฌด์์ ๋ง๋๋). ใ์์ผ๋ฉด ๋ถ์ด์ง\n * ์๋๋คใ๋ ๊ท์จ์ ์งํค๊ธฐ ๋๋ฌธ์ ์๋ฌด ์ค๋ฅ๋ ๋์ง ์์๋ค.\n *\n * โโ ๋ฌด์์ ๋๋ ค์ฃผ๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * **๊ทธ ํธ์์ ๋์ ํ๊ฐ ์ฐ๋ ๊ฒ๊ณผ ๊ฐ์ ๋ชจ์**์ด๋ค. ๋ ์ธ๊ณ๊ฐ ์๋ก ๋ค๋ฅธ ๊ฒ์ ๊ฐ์ผ๋ก ์ด๋ค.\n *\n * SGTIN ์ธ๊ณ binding ๊ฐ = ํ๋ชฉ ์ฐธ์กฐ ์ซ์(`077101`) โ ์ซ์๋ฅผ ๋๋ ค์ค๋ค\n * URI ์ธ๊ณ binding ๊ฐ = ํด๋์ค URI(`โฆ/product-Mโฆ`) โ ํด๋์ค URI ๋ฅผ ๋๋ ค์ค๋ค\n *\n * ๊ทธ๋์ ๋ ์ธ๊ณ๋ฅผ ํ ํจ์๊ฐ ๋ตํ๋ค โ ๋ถ๋ฅด๋ ์๋ฆฌ๊ฐ ์๋ณธ์ ์ ์ฒด์ฑ ๋ฐฉ์์ ์์ง ์์๋ ๋๋ค.\n *\n * โโ ๋ฌด์์ ์ง์ด๋ด์ง ์๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * **์ด๋ ๋ถํธ๊ฐ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋์ง ๋ชจ๋ฅธ๋ค.** ๊ทธ๊ฒ์ ์๋ณธ๋ง๋ค ๋ค๋ฅด๊ณ ์ปค๋ ๊ณ์ฝ์ด ์ ํ ์ ์ด ์๋ค โ ํ\n * ์๋ณธ(chef)์ด ์ฐ๋ `@` ๋ฅผ ๊ท์น์ผ๋ก ๊ตณํ๋ฉด ์ด ํ๋ฉด์ด ๊ทธ ๋ ๊ฑฐ์ ์์ ์๊ฒ ๋๋ค. ์๋ฅด๋ ํ๋จ์ ๊ทธ ํธ์์\n * **์ ์ธ**์ด ํ๊ณ (ยง`resolveByDeclaration`), ํ๋ณด๊ฐ ๋ ์ด์์ด๋ฉด ๋ตํ์ง ์๋๋ค. ์ง์์ผ๋ก ์ด์ผ๋ฉด ๋จ์\n * ๋ ์ํผ์ ๋น๊ตํ๊ฒ ๋๊ณ , ๊ทธ๊ฒ์ด ใ์ค๊ณ์ ๋ค๋ฅด๋คใ๋ ๊ฑฐ์ง ์ง๋จ์ด ๋๋ค.\n */\n\n/**\n * ๊ฐ์ฒด ์๋ณ์ โ **ํ๋ชฉ ์ฐธ์กฐ**. ๋์ ํ์ ๊ฐ๊ณผ ๋น๊ตํ ์ ์๋ ๋ชจ์์ผ๋ก ๋๋ ค์ค๋ค.\n *\n * SGTIN ์ ํ์ค์ด ์๋ฆฌ๋ฅผ ์ ํด ๋์์ผ๋ฏ๋ก ๊ทธ ์๋ฆฌ์์ ํ๋ชฉ ์ฐธ์กฐ๋ฅผ ๊บผ๋ธ๋ค. ๊ทธ ๋ฐ์ ๋ชจ์์ **์๋์ง\n * ์๋๋ค** โ ์ด๋ ๋ถํธ๊ฐ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋์ง๋ ์๋ณธ๋ง๋ค ๋ค๋ฅด๊ณ , ์ปค๋ ๊ณ์ฝ์ด ๊ทธ ๊ตฌ๋ถ์๋ฅผ ์ ํ ์ ์ด ์๋ค.\n * ์์ ์ด ์๋ฆฌ์ ใ`@` ๋ค๋ ๊ฐ์ฒด๋คใ๋ฅผ ๋ฃ์๋๋ฐ, ๊ทธ๊ฒ์ ํ ์๋ณธ(chef)์ ๋ชจ์์ ๊ท์น์ผ๋ก ๊ตณํ ๊ฒ์ด์๋ค.\n *\n * ๊ทธ๋์ ์๋ฅด๋ ์ผ์ ์ฌ๊ธฐ์ ํ์ง ์๊ณ , **๊ทธ ํธ์์ ์ ์ธ๊ณผ ๋น๊ตํด** ํ์ ํ๋ค(ยง`resolveByDeclaration`).\n * ์ ์ธ์ด ๋ต์ ์ฃผ์ง ๋ชปํ๋ฉด `null` ์ด๋ค โ ์ง์์ผ๋ก ์ด์ผ๋ฉด ๋จ์ ๋ ์ํผ์ ๋น๊ตํ๊ฒ ๋๊ณ , ๊ทธ๊ฒ์ด ใ์ค๊ณ์\n * ๋ค๋ฅด๋คใ๋ ๊ฑฐ์ง ์ง๋จ์ด ๋๋ค.\n */\nexport function itemRefOf(epc: unknown): string | null {\n if (typeof epc !== 'string') return null\n const s = epc.trim()\n if (!s) return null\n\n /* GS1 SGTIN โ ํ์ฌ ์ ๋์ฌ์ ์ผ๋ จ๋ฒํธ ์ฌ์ด์ ํ๋ชฉ ์ฐธ์กฐ. `idpat` ์ `*` ๋ ๊ฐ์ ์๋ฆฌ์์ ๊ฑธ๋ฆฐ๋ค. */\n const sgtin = /sgtin:[^.]+\\.([^.]+)\\./.exec(s)\n if (sgtin) return sgtin[1]\n\n /* ๊ทธ ๋ฐ์ ์ ์ฒด์ฑ(์น URI ๋ฑ)์ ๊ทธ๋๋ก ๋ธ๋ค โ ์๋ฅด๋ ํ๋จ์ ์ ์ธ์ด ํ๋ค. */\n return s\n}\n\n/**\n * ์ด ์๋ณ์๊ฐ ๊ฐ๋ฆฌํค๋ **์ ์ธ ํญ๋ชฉ**์ ์ฐพ๋๋ค โ ์๋ณธ์ ์ ์ฒด์ฑ ๊ดํ์ ์์ง ์๊ณ , ๊ตฌ๋ถ์๋ ๋ชจ๋ฅธ๋ค.\n *\n * ์ธ ๊ฐ์ง๋ฅผ ์ฐจ๋ก๋ก ๋ณธ๋ค. ์ด๋ ๋จ๊ณ๋ **ํ๋ณด๊ฐ ๋ ์ด์์ด๋ฉด ๋ตํ์ง ์๋๋ค**(๋ชจ๋ฅด๋ ๊ฒ์ด ํ๋ฆฐ ๋ต๋ณด๋ค ๋ซ๋ค).\n *\n * โ ๊ทธ๋๋ก ๊ฐ๋ค\n * โก ๊ด์ธก๋ ์๋ณ์๊ฐ ์ ์ธ์ **ํ์ฅ**ํ๋ค โ ๊ฐ์ฒด๋ ์๊ธฐ ํด๋์ค๋ก ์์ํ๋ค(`โฆ/product-M1` + ๊ฐ์ฒด ํ์)\n * โข ํ๋ฉด์ด **์งง๊ฒ ์ค์ธ** ์๋ณ์๋ฅผ ๊ฑด๋ธ๋ค โ ์ ์ธ์ด ๊ทธ๊ฒ์ผ๋ก ๋๋๋ค(`net/class/product-M1`)\n *\n * โกโข์ ๋ถํธ๋ฅผ ๋ชจ๋ฅธ๋ค. ๊ทธ๋์ ์๋ณธ์ด `@`ยท`#`ยท`/` ๋ฌด์์ ์ฐ๋ , ๋๋ ์๋ฌด๊ฒ๋ ์ฐ์ง ์๋ ๊ฐ์ ๊ท์น์ด ์ ๋ค.\n */\nexport function resolveByDeclaration<T>(ref: string | null, declared: Map<string, T>): T | undefined {\n if (!ref) return undefined\n const exact = declared.get(ref)\n if (exact !== undefined) return exact\n let hit: T | undefined\n let found = 0\n for (const [id, value] of declared) {\n if (!(ref.startsWith(id) || id.endsWith(ref))) continue\n found++\n if (found > 1) return undefined\n hit = value\n }\n return hit\n}\n"]}
|
|
@@ -5,7 +5,7 @@ export declare const at: (o: any, path: string) => any;
|
|
|
5
5
|
*
|
|
6
6
|
* ๋๋ฉ์ธ ๋ชจ์์ ์ฝ๋๊ฐ ์๋ ๊ฒ์ด ์๋๋ผ **์๋ณ์ ๊ด๋ก**๋ฅผ ์๋ ๊ฒ์ด๋ค. ํ๋ณด๋ฅผ ์์๋๋ก ๋ณด๊ณ ์ฒซ
|
|
7
7
|
* ๊ฐ์ ์ด๋ค. ํ๋๋ ์์ผ๋ฉด ๊ทธ ํญ๋ชฉ์ ๊ฐ๋ฆฌํฌ ์ ์์ผ๋ฏ๋ก `null` โ ๋ชฉ๋ก์์ ๋นผ์ง ์๊ณ **id ์์**์ผ๋ก
|
|
8
|
-
* ๋ธ๋ค(
|
|
8
|
+
* ๋ธ๋ค(์ค๋ฅ ์์ด ๋น ์ง๋ฉด ๊ฑด์๊ฐ ์ ๋ง๋๋ค).
|
|
9
9
|
*/
|
|
10
10
|
export declare const idOf: (o: any, info?: {
|
|
11
11
|
idField?: string | string[];
|
|
@@ -11,7 +11,7 @@ exports.namesFor = namesFor;
|
|
|
11
11
|
* ๋ ๋ฒ์ ๋ง๋ค๋ฉด ํ์ชฝ๋ง ๊ณ ์ณ์ง๋ฏ๋ก ํ ๊ณณ์ ๋๋ค(์ฌ๋ฐ๋ช
๊ธ์ง).
|
|
12
12
|
*/
|
|
13
13
|
/* ์ปค๋ ๋ฐํ์ ๋ก๋ โ ์ด๋ ์ถ์ด ์๋์ง๋ ์นดํ๋ก๊ทธ๊ฐ ์ ์ธํ๋ค(์ด ํ์ผ์ ๋๋ฉ์ธ ๋ชจ์์ ์์ง ์๋๋ค). */
|
|
14
|
-
const { TWIN_AXES, axisSource } = require('@operato/
|
|
14
|
+
const { TWIN_AXES, axisSource } = require('@operato/ops-contract');
|
|
15
15
|
/** `productionSpec.definition.recipes` ๊ฐ์ ๊ฒฝ๋ก๋ฅผ ๋ฌธ์์์ ๋ฐ๋ผ๊ฐ๋ค. */
|
|
16
16
|
const at = (o, path) => path.split('.').reduce((a, k) => (a == null ? undefined : a[k]), o);
|
|
17
17
|
exports.at = at;
|
|
@@ -20,7 +20,7 @@ exports.at = at;
|
|
|
20
20
|
*
|
|
21
21
|
* ๋๋ฉ์ธ ๋ชจ์์ ์ฝ๋๊ฐ ์๋ ๊ฒ์ด ์๋๋ผ **์๋ณ์ ๊ด๋ก**๋ฅผ ์๋ ๊ฒ์ด๋ค. ํ๋ณด๋ฅผ ์์๋๋ก ๋ณด๊ณ ์ฒซ
|
|
22
22
|
* ๊ฐ์ ์ด๋ค. ํ๋๋ ์์ผ๋ฉด ๊ทธ ํญ๋ชฉ์ ๊ฐ๋ฆฌํฌ ์ ์์ผ๋ฏ๋ก `null` โ ๋ชฉ๋ก์์ ๋นผ์ง ์๊ณ **id ์์**์ผ๋ก
|
|
23
|
-
* ๋ธ๋ค(
|
|
23
|
+
* ๋ธ๋ค(์ค๋ฅ ์์ด ๋น ์ง๋ฉด ๊ฑด์๊ฐ ์ ๋ง๋๋ค).
|
|
24
24
|
*/
|
|
25
25
|
const idOf = (o, info) => {
|
|
26
26
|
if (typeof o === 'string')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"name-index.js","sourceRoot":"","sources":["../../../server/service/twin-model/name-index.ts"],"names":[],"mappings":";;;AA0DA,8BAgBC;AASD,4BAUC;AA7FD;;;;;;GAMG;AACH,8DAA8D;AAC9D,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"name-index.js","sourceRoot":"","sources":["../../../server/service/twin-model/name-index.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * ํญ๋ชฉ์ **์ด๋ฆ**์ ๋ถ์ด๋ ์๋ฆฌ โ ํ๋ฉด์ด id ๋ง ๋ณด์ด์ง ์๊ฒ. (2026-08-22 ๊ณต์ฉ์ผ๋ก ์ฎ๊น)\n *\n * ์ด ๋์ ํญ๋ชฉ ์ง์ ์์ ์ฌ์ ์ผ๋ก ์์๋ค. ๊ทธ๋ฐ๋ฐ **์ ๊ฐ(BOM ๋๋ฌด) ํ๋ฉด๋ ๊ฐ์ ์ด๋ฆ์ด ํ์ํ๋ค** โ\n * ์ฌ์ฉ์๊ฐ ใ๊ฐ ๋
ธ๋์ ์๋ณ์๊ฐ ๋ฐ๋ณต๋์ด์ ์ดํด๊ฐ ์ด๋ ต๋ค. ์๋ณ์์ ์ด๋ฆ์ด ๋ณด์ด๋ฉดใ์ด๋ผ๊ณ ํ๋ค.\n * ๋ ๋ฒ์ ๋ง๋ค๋ฉด ํ์ชฝ๋ง ๊ณ ์ณ์ง๋ฏ๋ก ํ ๊ณณ์ ๋๋ค(์ฌ๋ฐ๋ช
๊ธ์ง).\n */\n/* ์ปค๋ ๋ฐํ์ ๋ก๋ โ ์ด๋ ์ถ์ด ์๋์ง๋ ์นดํ๋ก๊ทธ๊ฐ ์ ์ธํ๋ค(์ด ํ์ผ์ ๋๋ฉ์ธ ๋ชจ์์ ์์ง ์๋๋ค). */\nconst { TWIN_AXES, axisSource } = require('@operato/ops-contract')\n\n/** `productionSpec.definition.recipes` ๊ฐ์ ๊ฒฝ๋ก๋ฅผ ๋ฌธ์์์ ๋ฐ๋ผ๊ฐ๋ค. */\nexport const 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 */\nexport const idOf = (o: any, info?: { idField?: string | string[] }): string | null => {\n if (typeof o === 'string') return o\n /*\n * **๋ฌด์์ด ์ด ํญ๋ชฉ์ ๊ฐ๋ฆฌํค๋์ง๋ ์ ์ธ์ด ๋งํ๋ค**(ยง`TwinAxisInfo.idField`).\n *\n * ์์ ์๋ `id`ยท`key`ยท`gtin` ์ ์ง์ํ๋ค. ๊ทธ๋์ `id` ๊ฐ ์๋ ์ถ(์์ ๊ตฌ๊ฐ โ ์ ์ฒด์ฑ์ด ๊ตฌ๊ฐ ์์\n * ์๊ฐ์ด๋ค)์ ํญ๋ชฉ์ด ์ ๋ถ ใ์๋ณ์ ์์ โ ์ฐธ์กฐํ ์ ์๋ ํญ๋ชฉใ์ผ๋ก ๋ณด์๋ค. ๊ฐ์ ์ค์ฌํ๋๋ฐ\n * ๊ฐ๋ฆฌํฌ ์ ์๋ค๊ณ ๋งํ ๊ฒ์ด๋ค.\n */\n /*\n * ์ ์ธ์ด **์ฐจ๋ก**๋ฅผ ๋งํ ์ ์๋ค(2026-08-22) โ ์ ์ฒด์ฑ์ด ํ ์นธ์ผ๋ก ์ ํด์ง์ง ์๋ ์ถ์ด ์๋ค. ๋ฌผํ์ด\n * ๊ทธ๋ ๋ค: ์ง๋ ฌ ๋ฌผํ์ `epc` ๊ฐ ์ ์ผํ์ง๋ง ๋น์ง๋ ฌ ๋กํธ๊ฐ ์๋ฆฌ๋ง๋ค ๋๋๋ฉด `subLotId` ๊ฐ ๊ฐ์ฒด๋ฅผ\n * ๊ตฌ๋ณํ๋ค(๊ฐ์ ๋กํธ์ ๋ ๋ถ๋ถ์ ๊ฐ์ `epc` ๋ฅผ ๊ฐ๋๋ค). ์์์ ๊ฐ์ด ์๋ ์ฒซ ์นธ์ด ์ด๊ธด๋ค.\n */\n for (const f of info?.idField ? (Array.isArray(info.idField) ? info.idField : [info.idField]) : []) {\n const v = o?.[f]\n if (v !== undefined && v !== null) return String(v)\n }\n return o?.id ?? o?.key ?? o?.gtin ?? null\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 */\nexport function 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 *\n * ๋ชจ๋ธ ์ ์ฒด ํ๋ฅผ ๊ทธ๋๋ก ์ค์ผ๋ฉด ์๋ฆฌ๊ฐ 10๋ง์ธ ํ์ฅ์์ ๋ชฉ๋ก ํ ํ์ด์ง์ 10๋ง ์ค์ง๋ฆฌ ์ด๋ฆํ๊ฐ\n * ๋ฐ๋ผ์จ๋ค. ๋์จ ๊ฐ์ ๊ฑธ๋ฆฌ๋ ๊ฒ๋ง ์ฃ๋๋ค โ ๊ท๋ชจ์์ ์ฑ๋ฆฝํ๋ ์ ์ผํ ๋ฐฉ์์ด๋ค.\n */\nexport function 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"]}
|
|
@@ -2,7 +2,7 @@ export interface ProjectionReport {
|
|
|
2
2
|
locations: number;
|
|
3
3
|
equipment: number;
|
|
4
4
|
operations: number;
|
|
5
|
-
/** ์๋ฆฌ๋ฅผ ๋ชป ์ฐพ์ ๊ธฐ์ค ์๋ฆฌ๋ฅผ ๋น์ด ์ค๋น โ
|
|
5
|
+
/** ์๋ฆฌ๋ฅผ ๋ชป ์ฐพ์ ๊ธฐ์ค ์๋ฆฌ๋ฅผ ๋น์ด ์ค๋น โ **์๋ฆฌ์ง ์๊ณ ๋๊ธฐ์ง ์๋๋ค.** */
|
|
6
6
|
unresolvedHome: string[];
|
|
7
7
|
/** ๊ตฌ์ญ์ ๋ชป ์ฐพ์ ๋น์ด ์๋ฆฌ. ๊ตฌ์ญ์ model ๋ฐ(ํธ์คํธ ๊ฐ๋
)์ด๋ผ ์ด๊ธ๋ ์ ์๋ค. */
|
|
8
8
|
unresolvedArea: string[];
|
|
@@ -7,7 +7,7 @@ const twin_area_js_1 = require("../twin-space/twin-area.js");
|
|
|
7
7
|
const twin_location_js_1 = require("./twin-location.js");
|
|
8
8
|
const twin_equipment_js_1 = require("./twin-equipment.js");
|
|
9
9
|
const twin_operation_js_1 = require("./twin-operation.js");
|
|
10
|
-
const
|
|
10
|
+
const ops_contract_1 = require("@operato/ops-contract");
|
|
11
11
|
/**
|
|
12
12
|
* ์ด ํธ์์ ๊ตฌ์กฐ ํ์ **์๋ณธ ๊ทธ๋๋ก ๋ค์ ๊ทธ๋ฆฐ๋ค.**
|
|
13
13
|
*
|
|
@@ -24,7 +24,7 @@ async function projectStructure(domainId, instanceId, model, sourceRef) {
|
|
|
24
24
|
* ์ค์ธก(2026-08-18): ํ์ฅ ๊ฐ์ ๊ทธ ํ์ฅ์ ํธ์ ์ ๋ถ์ ์น๋ค๊ฐ ํ ํธ์์์ ํฌ์์ด ํฐ์ก๋ค. ์ฌ๋ผ์จ ๊ฒ์
|
|
25
25
|
* `SQLITE_CONSTRAINT: UNIQUE constraint failed: twin_equipment...` ๋ฟ์ด๋ผ **๋ฌด์์ด ์๋ชป๋๋์ง ์๋ฌด๋
|
|
26
26
|
* ์ ์ ์์๋ค.** ์์ธ์ ๊ทธ ๋ชจ๋ธ์ ์ค๋น `load-1` ์ด ๋ ๋ฒ ๋ค์ด ์๋ ๊ฒ์ด๋ค(id ๋ ํธ์ ์์์ ์ ์ผํด์ผ
|
|
27
|
-
* ํ๋ค).
|
|
27
|
+
* ํ๋ค). ์๋ฆฌ์ง ์๊ณ ํ๋๋ง ๋จ๊ธฐ์ง ์๋๋ค โ ๊ทธ๊ฒ์ ๋ชจ๋ธ๋ง ์ค๋ฅ๋ฅผ ๊ฐ์ถ๋ ์ผ์ด๊ณ , ์ด๋ ์ชฝ์ด ๋ง๋์ง ์ฐ๋ฆฌ๋
|
|
28
28
|
* ๋ชจ๋ฅธ๋ค.
|
|
29
29
|
*/
|
|
30
30
|
const dupOf = (list, what) => {
|
|
@@ -39,7 +39,7 @@ async function projectStructure(domainId, instanceId, model, sourceRef) {
|
|
|
39
39
|
}
|
|
40
40
|
return undefined;
|
|
41
41
|
};
|
|
42
|
-
const dupMsg = dupOf(model?.locations, 'locations') ?? dupOf((0,
|
|
42
|
+
const dupMsg = dupOf(model?.locations, 'locations') ?? dupOf((0, ops_contract_1.readBoardEquipment)(model), 'equipment');
|
|
43
43
|
if (dupMsg)
|
|
44
44
|
throw new Error(dupMsg);
|
|
45
45
|
const locRepo = (0, shell_1.getRepository)(twin_location_js_1.TwinLocation);
|
|
@@ -92,7 +92,7 @@ async function projectStructure(domainId, instanceId, model, sourceRef) {
|
|
|
92
92
|
parallelism: l.parallelism ?? null,
|
|
93
93
|
area: area ? { id: area.id } : null,
|
|
94
94
|
gs1Id: l.gs1Id ?? null,
|
|
95
|
-
/* ์๋ฆฌ์ ์์ฑ๋ ์ฎ๊ธด๋ค โ ์ฎ๊ธฐ์ง ์์ผ๋ฉด ๊ณ์ฝ์ ๋ ฅยท์๊ธ์ด ํญ๋ชฉ ํจ๋์์ ์ฌ๋ผ์ง๋ค(
|
|
95
|
+
/* ์๋ฆฌ์ ์์ฑ๋ ์ฎ๊ธด๋ค โ ์ฎ๊ธฐ์ง ์์ผ๋ฉด ๊ณ์ฝ์ ๋ ฅยท์๊ธ์ด ํญ๋ชฉ ํจ๋์์ ์ฌ๋ผ์ง๋ค(๋ค์ด์จ ๊ฒ์ด ์๋ ๋๋ฝ). */
|
|
96
96
|
properties: l.properties ?? null,
|
|
97
97
|
sourceRef,
|
|
98
98
|
ingestedAt
|
|
@@ -124,7 +124,8 @@ async function projectStructure(domainId, instanceId, model, sourceRef) {
|
|
|
124
124
|
homeLocation: home ? { id: home.id } : null,
|
|
125
125
|
mtbfMs: m.mtbfMs ?? null,
|
|
126
126
|
mttrMs: m.mttrMs ?? null,
|
|
127
|
-
|
|
127
|
+
/* ์ ์ธ๋ ์ ์ฒด์ฑ โ ์์ ์๋ ์ ์ธ์ ์๋ `gs1Id` ๋ฅผ ์ฝ์ด ์ด ์นธ์ด ๋ ๋น์ด ์์๋ค. */
|
|
128
|
+
identity: m.identity ?? null,
|
|
128
129
|
sourceRef,
|
|
129
130
|
ingestedAt
|
|
130
131
|
});
|
|
@@ -147,7 +148,7 @@ async function projectStructure(domainId, instanceId, model, sourceRef) {
|
|
|
147
148
|
intent: o.intent ?? null,
|
|
148
149
|
locationType: o.locationType ?? null,
|
|
149
150
|
resourceType: o.resourceType ?? null,
|
|
150
|
-
/* ์์์๊ฐ์ ISO 8601 ๋ฌธ์์ด์ด ์ ๋ณธ โ ๋ถ์ผ๋ก
|
|
151
|
+
/* ์์์๊ฐ์ ISO 8601 ๋ฌธ์์ด์ด ์ ๋ณธ โ ๋ถ์ผ๋ก ์ค์ด๋ฉด ์ด๊ฐ ์ค๋ฅ ์์ด ์ฌ๋ผ์ง๋ค. */
|
|
151
152
|
duration: o.duration ?? null,
|
|
152
153
|
variability: o.variability ?? null,
|
|
153
154
|
parameters: o.parameters ?? null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-structure.js","sourceRoot":"","sources":["../../../server/service/twin-model/project-structure.ts"],"names":[],"mappings":"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","sourcesContent":["import { getRepository } from '@things-factory/shell'\n\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinArea } from '../twin-space/twin-area.js'\nimport { TwinLocation } from './twin-location.js'\nimport { TwinEquipment } from './twin-equipment.js'\nimport { TwinOperation } from './twin-operation.js'\nimport { readBoardEquipment } from '@operato/twin-kernel'\n\n/*\n * ๊ตฌ์กฐ ํฌ์ โ `model`(์ปค๋ ์
๋ ฅ ๋ฌธ์) โ **ํ์ค ์ํฐํฐ ํ**(ADR-0032).\n *\n * โโ ์ ์ ๋ ๊ต์ฒด์ธ๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ด ํ๋ค์ **์๋ณธ์์ ์จ ์บ์**๋ค(ADR-0032-D). ์๋ณธ์ด ์ง์ค์ด๋ฏ๋ก diff ๋ก ์๋ผ๋ ๊ฒ๋ณด๋ค\n * **๋งค๋ฒ ๊ทธ๋๋ก ๋ค์ ๊ทธ๋ฆฌ๋ ๊ฒ**์ด ๋ง๋ค โ diff ๋ \"์ฐ๋ฆฌ ์ชฝ์ ๋จ๊ฒจ์ผ ํ ๊ฒ์ด ์๋ค\" ๋ ์ ์ ๋ฅผ\n * ๊น๊ณ , ๊ทธ ์ ์ ๊ฐ ์์ ์นจ๋ฒ์ ์์์ด๋ค.\n *\n * ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด ์๋ช
(`TwinStructure.signature`)์ด ๊ฐ์ ๋ ๊ฑด๋๋ฐ๋ ์ฅ์น๊ฐ ์ด๋ฏธ ์์ผ๋ฏ๋ก\n * ๊ทธ๊ฒ์ ์์ ๋๋ค. ์ฌ๊ธฐ์ diff ๋ฅผ ๋ฐ๋ช
ํ์ง ์๋๋ค.\n *\n * โโ ์์๊ฐ ์ค์ํ๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ค๋น๊ฐ ์๋ฆฌ๋ฅผ FK ๋ก ๊ฐ๋ฆฌํค๋ฏ๋ก **์๋ฆฌ๋ฅผ ๋จผ์ ** ๋ฃ๋๋ค. ์ง์ฐ๋ ๊ฒ์ ๋ฐ๋ ์์๋ค.\n * (์๋ฆฌ ์ญ์ ์ ์ค๋น์ `homeLocation` ์ `SET NULL` ์ด์ง๋ง, ์ ๋ ๊ต์ฒด์์๋ ๋ ๋ค ์ง์ด๋ค.)\n */\nexport interface ProjectionReport {\n locations: number\n equipment: number\n operations: number\n /** ์๋ฆฌ๋ฅผ ๋ชป ์ฐพ์ ๊ธฐ์ค ์๋ฆฌ๋ฅผ ๋น์ด ์ค๋น โ **์กฐ์ฉํ ๋๊ธฐ์ง ์๋๋ค.** */\n unresolvedHome: string[]\n /** ๊ตฌ์ญ์ ๋ชป ์ฐพ์ ๋น์ด ์๋ฆฌ. ๊ตฌ์ญ์ model ๋ฐ(ํธ์คํธ ๊ฐ๋
)์ด๋ผ ์ด๊ธ๋ ์ ์๋ค. */\n unresolvedArea: string[]\n}\n\n/**\n * ์ด ํธ์์ ๊ตฌ์กฐ ํ์ **์๋ณธ ๊ทธ๋๋ก ๋ค์ ๊ทธ๋ฆฐ๋ค.**\n *\n * `sourceRef` ๋ ์ด๋ ์๋ณธ์์ ์๋์ง๋ค(`ReferenceMaster.source` = instanceId). ์๋ ํ์\n * ๋ง๋ค ์ ์๋ค โ ์บ์๋ผ๋ ์ฌ์ค์ ๊ตฌ์กฐ๋ก ์งํจ๋ค.\n */\nexport async function projectStructure(domainId: string, instanceId: string, model: any, sourceRef: string): Promise<ProjectionReport> {\n const instance = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!instance) throw new Error(`cannot project structure: twin instance \"${instanceId}\" is not registered`)\n\n /*\n * **๊ฐ์ id ๊ฐ ๋์ด๋ฉด ๊ทธ ์ฌ์ค์ ๋งํ๋ค** โ ์ ์ฝ ์๋ฐ ๋ฌธ๊ตฌ๋ฅผ ์ฌ์ฉ์์๊ฒ ๋ณด์ด์ง ์๋๋ค.\n *\n * ์ค์ธก(2026-08-18): ํ์ฅ ๊ฐ์ ๊ทธ ํ์ฅ์ ํธ์ ์ ๋ถ์ ์น๋ค๊ฐ ํ ํธ์์์ ํฌ์์ด ํฐ์ก๋ค. ์ฌ๋ผ์จ ๊ฒ์\n * `SQLITE_CONSTRAINT: UNIQUE constraint failed: twin_equipment...` ๋ฟ์ด๋ผ **๋ฌด์์ด ์๋ชป๋๋์ง ์๋ฌด๋\n * ์ ์ ์์๋ค.** ์์ธ์ ๊ทธ ๋ชจ๋ธ์ ์ค๋น `load-1` ์ด ๋ ๋ฒ ๋ค์ด ์๋ ๊ฒ์ด๋ค(id ๋ ํธ์ ์์์ ์ ์ผํด์ผ\n * ํ๋ค). ์กฐ์ฉํ ํ๋๋ง ๋จ๊ธฐ์ง ์๋๋ค โ ๊ทธ๊ฒ์ ๋ชจ๋ธ๋ง ์ค๋ฅ๋ฅผ ๊ฐ์ถ๋ ์ผ์ด๊ณ , ์ด๋ ์ชฝ์ด ๋ง๋์ง ์ฐ๋ฆฌ๋\n * ๋ชจ๋ฅธ๋ค.\n */\n const dupOf = (list: any[] | undefined, what: string): string | undefined => {\n const seen = new Set<string>()\n for (const e of list ?? []) {\n const id = String(e?.id ?? '')\n if (!id) continue\n if (seen.has(id)) return `twin \"${instanceId}\" has two ${what} with id \"${id}\" โ ids must be unique within a twin, so the model cannot be projected`\n seen.add(id)\n }\n return undefined\n }\n const dupMsg = dupOf(model?.locations, 'locations') ?? dupOf(readBoardEquipment(model), 'equipment')\n if (dupMsg) throw new Error(dupMsg)\n\n const locRepo = getRepository(TwinLocation)\n const eqRepo = getRepository(TwinEquipment)\n const opRepo = getRepository(TwinOperation)\n const scope = { domain: { id: domainId } as any, instance: { id: instance.id } as any }\n const ingestedAt = new Date()\n\n /*\n * ์ ๋ ๊ต์ฒด โ ์ด ํ๋ค์ **์๋ณธ์์ ์จ ์บ์**์ด๋ฏ๋ก ๋งค๋ฒ ๊ทธ๋๋ก ๋ค์ ๊ทธ๋ฆฐ๋ค.\n * diff ๋ก ์๋ผ๋ ๊ฒ์ \"์ฐ๋ฆฌ ์ชฝ์ ๋จ๊ฒจ์ผ ํ ๊ฒ์ด ์๋ค\" ๋ ์ ์ ๋ฅผ ๊น๊ณ , ๊ทธ ์ ์ ๊ฐ ์์ ์นจ๋ฒ์ ์์์ด๋ค.\n *\n * **๊ด์ธก์ผ๋ก ์๋ ์์์ ์ฌ๊ธฐ ์ฐ์ง ์๋๋ค.** ์ปค๋์ ๋ง์คํฐ์ ์๋ ์ค๋น๋ ์ด๋ฒคํธ๋ก ์๊ฒ ๋์ง๋ง\n * (`observed-reducer` ์ `origin: 'observed'`), ๊ทธ๊ฒ์ ์ด ํ์ ๋ฐ์ด ๋ฃ์ผ๋ฉด **์ฐ๊ธฐ ๊ฒฝ๋ก๊ฐ ๋**์ด ๋๊ณ \n * ํฑ ๋ฃจํ์์ DB ๋ก ์ฐ๋ ๊ธธ์ด ์๊ธด๋ค(ADR-0032-D ์๋ฐ). ๊ทธ ์ฐจ์ด๋ **์กฐํ ์์ ์ ๋น๊ตํด ๋ณด๊ณ **ํ๋ค โ\n * ์จ๊ฒจ์ผ ํ ๋ถ์ผ์น๊ฐ ์๋๋ผ \"์๋ณธ์ด ๋ชจ๋ฅด๋ ์ค๋น๊ฐ ์คํ ์ค์ด๋ค\" ๋ ์ฌ์ค์ด๋ค.\n */\n await eqRepo.delete(scope)\n await opRepo.delete(scope)\n await locRepo.delete(scope)\n\n /* ๊ตฌ์ญ์ model ๋ฐ์ ์ฐ๋ค(ํธ์คํธ์ TwinArea). ์ด๋ฆ์ผ๋ก ์ฐพ์ FK ๋ฅผ ์๋๋ค. */\n const areas = await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any } })\n const areaOf = new Map(areas.map(a => [a.areaId, a]))\n const unresolvedArea: string[] = []\n\n /*\n * โโ ์ ๊ธฐ ์๋ฅ๋ฅผ ใ๊ตฌ์ญใ์ผ๋ก ์ฝ์ง ์๋๋ค (2026-08-18) โโโโโโโโโโโโโโโโโโโโโโโโ\n *\n * ์๋ฆฌ์ ๋ถ๋ชจ๊ฐ **๋ค๋ฅธ ์๋ฆฌ**์ผ ์ ์๋ค(๋ถ๊ธฐ์ ์๋ฅ๋ ์์ ์ด๋ค). ๊ทธ ๋ถ๋ชจ๋ฅผ ๊ตฌ์ญ ํ์์ ์ฐพ์ผ๋ฉด ๋น์ฐํ\n * ์๊ณ , ์์ ์๋ ๊ทธ๊ฒ์ ๋งค๋ฒ ใ๊ตฌ์ญ์ด ์ด ํธ์์ ์๋คใ๋ก ๊ฒฝ๊ณ ํ๋ค โ ์๋์ง ํธ์์ ์ธ์ ์คํธํ ๋๋ง๋ค\n * ๋ถ๊ธฐ ์๋งํผ ๊ฑฐ์ง ๊ฒฝ๋ณด๊ฐ ๋ฌ๋ค. ๊ฒฝ๋ณด๊ฐ ์์์ด ๋๋ฉด **์ฌ๋์ด ๊ฒฝ๋ณด ์์ฒด๋ฅผ ์ฝ์ง ์๊ฒ ๋๋ค.**\n *\n * ์๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ถ๋ชจ๋ ๊ณ์ธต(์๋ฆฌ โ ์๋ฆฌ)์ด๊ณ , ๊ตฌ์ญ์ model ๋ฐ์ ๋ค๋ฅธ ํ๋ค. ๊ทธ๋์ ๋ถ๋ชจ๊ฐ ์ด ๋ชจ๋ธ์\n * ์๋ฆฌ์ด๋ฉด ๊ตฌ์ญ ํด์์ **์๋ํ์ง ์๋๋ค**(์๋ ๊ฒ์ ๋ชป ์ฐพ์๋ค๊ณ ๋งํ์ง ์๋๋ค).\n */\n const locationIds = new Set((model?.locations ?? []).filter((l: any) => l?.id).map((l: any) => String(l.id)))\n\n const locations: TwinLocation[] = (model?.locations ?? [])\n .filter((l: any) => l?.id)\n .map((l: any) => {\n const parentIsLocation = l.parentId ? locationIds.has(String(l.parentId)) : false\n const area = l.parentId && !parentIsLocation ? areaOf.get(l.parentId) : undefined\n if (l.parentId && !parentIsLocation && !area) unresolvedArea.push(`${l.id}โ${l.parentId}`)\n return locRepo.create({\n ...scope,\n locationId: l.id,\n /* **์ด๋ฆ์ ์ฎ๊ธด๋ค.** ๋ฒ๋ฆฌ๊ณ ์์๋ค โ ๊ทธ๋์ ํ๋ฉด์ ์๋ฆฌ id ๋ง ๋จ์๋ค(ยงname ์ฃผ์ ์ฐธ์กฐ). */\n name: l.name ?? null,\n description: l.description ?? null,\n type: l.type,\n capacity: l.capacity ?? null,\n parallelism: l.parallelism ?? null,\n area: area ? ({ id: area.id } as any) : null,\n gs1Id: l.gs1Id ?? null,\n /* ์๋ฆฌ์ ์์ฑ๋ ์ฎ๊ธด๋ค โ ์ฎ๊ธฐ์ง ์์ผ๋ฉด ๊ณ์ฝ์ ๋ ฅยท์๊ธ์ด ํญ๋ชฉ ํจ๋์์ ์ฌ๋ผ์ง๋ค(์กฐ์ฉํ ๋๋ฝ). */\n properties: l.properties ?? null,\n sourceRef,\n ingestedAt\n } as any)\n })\n const savedLocations = locations.length ? await locRepo.save(locations, { chunk: 500 }) : []\n const locOf = new Map(savedLocations.map(l => [l.locationId, l]))\n\n const unresolvedHome: string[] = []\n const equipment: TwinEquipment[] = (model?.equipment ?? [])\n .filter((m: any) => m?.id)\n .map((m: any) => {\n const home = m.homeLocation ? locOf.get(m.homeLocation) : undefined\n /* ๋์ด์ง ๊ธฐ์ค ์๋ฆฌ๋ **์ด๋ฆ์ ๋๊ณ ** ๋ณด๊ณ ํ๋ค. ์์ ์๋ ํ๋ฉด์ด ๊ฒฝ๊ณ ํ ๋ฟ์ด์๊ณ \n ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ๋ค์ด์จ ๋ฐ์ดํฐ๋ ์๋ฌด๋ ์ ๋ดค๋ค. */\n if (m.homeLocation && !home) unresolvedHome.push(`${m.id}โ${m.homeLocation}`)\n return eqRepo.create({\n ...scope,\n equipmentId: m.id,\n name: m.name ?? null,\n description: m.description ?? null,\n kind: m.kind,\n /* ์์ฑ๋ ์ฎ๊ธด๋ค โ ํ์ ์๋ฆฌ๊ฐ ์์ด ํ๋ฆฌ๊ณ ์์๋ค(์๋น์ฒ๊ฐ ์ค์ ๋ก ์ฝ๋ ์ฌ์ค์ด๋ค: ์ฃผํ ์๋). */\n properties: m.properties ?? null,\n /* ์ํ ์ฐธ์กฐ๋ ํจ๊ป โ ํ๋ฆฌ๋ฉด ๋ช
์ธ ์ชฝ์์ \"๋๊ฐ ๋๋ฅผ ๊ฐ๋ฆฌํค๋\" ์ ์ด ์ค๋น๊ฐ ๋น ์ง๋ค. */\n testSpecificationIds: m.testSpecificationIds ?? null,\n /* ๊ฒฐ๊ณผ๊น์ง โ ์ฐธ์กฐ๋ง ์์ผ๋ฉด \"๋ฌด์์ผ๋ก ๊ฒ์ฆํ๋ค\" ๊น์ง๊ณ , ์๊ฒฉ ์ฑ๋ฆฝ์ ๊ฒฐ๊ณผ๊ฐ ๋งํ๋ค. */\n testResults: m.testResults ?? null,\n homeLocation: home ? ({ id: home.id } as any) : null,\n mtbfMs: m.mtbfMs ?? null,\n mttrMs: m.mttrMs ?? null,\n gs1Id: m.gs1Id ?? null,\n sourceRef,\n ingestedAt\n } as any)\n })\n if (equipment.length) await eqRepo.save(equipment, { chunk: 500 })\n\n const operations: TwinOperation[] = (model?.operations ?? [])\n .filter((o: any) => o?.key)\n .map((o: any, i: number) =>\n opRepo.create({\n ...scope,\n operationKey: o.key,\n /*\n * ๊ณต์ ์ ๋ง์คํฐ๊ฐ `label` ๋ก ๋งํ๋ค โ ํ์์๋ **๊ท์ฝ์ ์ด๋ฆ ํ๋๋ง** ๋๋ค.\n *\n * ํ๋์ `label` ์ปฌ๋ผ๋ ํจ๊ป ๋จ๊ฒจ ๋๋๋ ์กฐํ ํ๋ฉด์ \"์ด๋ฆ\" ์ด์ด **๋ ๊ฐ** ๋ด๋ค(๊ฐ์ ๊ฐ์ด\n * ๋ ๋ฒ). ์ดํ๋ฅผ ํ๋๋ก ํ๋ค๊ณ ํ๋ฉด์ ๋์ ๋จ๊ธฐ๋ฉด ๋ฐ๋์ ์ด๋ ๊ฒ ์์ด ๋์จ๋ค.\n */\n name: o.name ?? o.label ?? null,\n description: o.description ?? null,\n intent: o.intent ?? null,\n locationType: o.locationType ?? null,\n resourceType: o.resourceType ?? null,\n /* ์์์๊ฐ์ ISO 8601 ๋ฌธ์์ด์ด ์ ๋ณธ โ ๋ถ์ผ๋ก ์ ์ผ๋ฉด ์ด๊ฐ ์กฐ์ฉํ ์ฌ๋ผ์ง๋ค. */\n duration: o.duration ?? null,\n variability: o.variability ?? null,\n parameters: o.parameters ?? null,\n /* **๋ค ์์ ๋ช
์ธ๋ฅผ ํจ๊ป ์ฎ๊ธด๋ค.** ์
์ด ๋น ์ ธ ์์ด์ ์กฐํ ํ๋ฉด์ด \"์๋ณธ์ด ๋งํ ๊ฐ\" ์ด๋ผ ์ ๊ณ ๋\n ๋ท ์ค ํ๋๋ง ๋ณด์๋ค โ ์ฌ๋์ด ํ์ํ ๊ณต์ ์ ๋ณด๊ณ ์ฌ๋์ด ํ์ ์๋ค๊ณ ๊ฒฐ๋ก ๋ด๊ฒ ๋๋ค. */\n personnelSpecification: o.personnelSpecification ?? null,\n physicalAssetSpecification: o.physicalAssetSpecification ?? null,\n materialSpecification: o.materialSpecification ?? null,\n seq: i,\n sourceRef,\n ingestedAt\n } as any)\n )\n if (operations.length) await opRepo.save(operations, { chunk: 500 })\n\n return {\n locations: savedLocations.length,\n equipment: equipment.length,\n operations: operations.length,\n unresolvedHome,\n unresolvedArea\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"project-structure.js","sourceRoot":"","sources":["../../../server/service/twin-model/project-structure.ts"],"names":[],"mappings":";;AAwCA,4CA+JC;AAvMD,iDAAqD;AAErD,wEAAgE;AAChE,6DAAqD;AACrD,yDAAiD;AACjD,2DAAmD;AACnD,2DAAmD;AACnD,wDAA0D;AA2B1D;;;;;GAKG;AACI,KAAK,UAAU,gBAAgB,CAAC,QAAgB,EAAE,UAAkB,EAAE,KAAU,EAAE,SAAiB;IACxG,MAAM,QAAQ,GAAG,MAAM,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CAAA;IAC/G,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,UAAU,qBAAqB,CAAC,CAAA;IAE3G;;;;;;;;OAQG;IACH,MAAM,KAAK,GAAG,CAAC,IAAuB,EAAE,IAAY,EAAsB,EAAE;QAC1E,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,KAAK,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;YAC9B,IAAI,CAAC,EAAE;gBAAE,SAAQ;YACjB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,OAAO,SAAS,UAAU,aAAa,IAAI,aAAa,EAAE,wEAAwE,CAAA;YACpJ,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACd,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC,CAAA;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,IAAI,KAAK,CAAC,IAAA,iCAAkB,EAAC,KAAK,CAAC,EAAE,WAAW,CAAC,CAAA;IACpG,IAAI,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAA;IAEnC,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAC,+BAAY,CAAC,CAAA;IAC3C,MAAM,MAAM,GAAG,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAA;IAC3C,MAAM,MAAM,GAAG,IAAA,qBAAa,EAAC,iCAAa,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAS,EAAE,CAAA;IACvF,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAA;IAE7B;;;;;;;;OAQG;IACH,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAE3B,uDAAuD;IACvD,MAAM,KAAK,GAAG,MAAM,IAAA,qBAAa,EAAC,uBAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAS,EAAE,EAAE,CAAC,CAAA;IAChG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACrD,MAAM,cAAc,GAAa,EAAE,CAAA;IAEnC;;;;;;;;;OASG;IACH,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAE7G,MAAM,SAAS,GAAmB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;SACvD,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;SACzB,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE;QACd,MAAM,gBAAgB,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QACjF,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACjF,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,gBAAgB,IAAI,CAAC,IAAI;YAAE,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC1F,OAAO,OAAO,CAAC,MAAM,CAAC;YACpB,GAAG,KAAK;YACR,UAAU,EAAE,CAAC,CAAC,EAAE;YAChB,8DAA8D;YAC9D,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI;YACpB,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;YAClC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;YAC5B,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;YAClC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAU,CAAC,CAAC,CAAC,IAAI;YAC5C,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI;YACtB,gEAAgE;YAChE,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;YAChC,SAAS;YACT,UAAU;SACJ,CAAC,CAAA;IACX,CAAC,CAAC,CAAA;IACJ,MAAM,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC5F,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAEjE,MAAM,cAAc,GAAa,EAAE,CAAA;IACnC,MAAM,SAAS,GAAoB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;SACxD,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;SACzB,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE;QACd,MAAM,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACnE;uCAC+B;QAC/B,IAAI,CAAC,CAAC,YAAY,IAAI,CAAC,IAAI;YAAE,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC,CAAA;QAC7E,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,GAAG,KAAK;YACR,WAAW,EAAE,CAAC,CAAC,EAAE;YACjB,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI;YACpB,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;YAClC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,2DAA2D;YAC3D,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;YAChC,sDAAsD;YACtD,oBAAoB,EAAE,CAAC,CAAC,oBAAoB,IAAI,IAAI;YACpD,qDAAqD;YACrD,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;YAClC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAU,CAAC,CAAC,CAAC,IAAI;YACpD,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI;YACxB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI;YACxB,uDAAuD;YACvD,QAAQ,EAAG,CAAS,CAAC,QAAQ,IAAI,IAAI;YACrC,SAAS;YACT,UAAU;SACJ,CAAC,CAAA;IACX,CAAC,CAAC,CAAA;IACJ,IAAI,SAAS,CAAC,MAAM;QAAE,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IAElE,MAAM,UAAU,GAAoB,CAAC,KAAK,EAAE,UAAU,IAAI,EAAE,CAAC;SAC1D,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAM,EAAE,CAAS,EAAE,EAAE,CACzB,MAAM,CAAC,MAAM,CAAC;QACZ,GAAG,KAAK;QACR,YAAY,EAAE,CAAC,CAAC,GAAG;QACnB;;;;;WAKG;QACH,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI;QAC/B,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;QAClC,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI;QACxB,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI;QACpC,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI;QACpC,qDAAqD;QACrD,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;QAC5B,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;QAClC,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;QAChC;+DACuD;QACvD,sBAAsB,EAAE,CAAC,CAAC,sBAAsB,IAAI,IAAI;QACxD,0BAA0B,EAAE,CAAC,CAAC,0BAA0B,IAAI,IAAI;QAChE,qBAAqB,EAAE,CAAC,CAAC,qBAAqB,IAAI,IAAI;QACtD,GAAG,EAAE,CAAC;QACN,SAAS;QACT,UAAU;KACJ,CAAC,CACV,CAAA;IACH,IAAI,UAAU,CAAC,MAAM;QAAE,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IAEpE,OAAO;QACL,SAAS,EAAE,cAAc,CAAC,MAAM;QAChC,SAAS,EAAE,SAAS,CAAC,MAAM;QAC3B,UAAU,EAAE,UAAU,CAAC,MAAM;QAC7B,cAAc;QACd,cAAc;KACf,CAAA;AACH,CAAC","sourcesContent":["import { getRepository } from '@things-factory/shell'\n\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinArea } from '../twin-space/twin-area.js'\nimport { TwinLocation } from './twin-location.js'\nimport { TwinEquipment } from './twin-equipment.js'\nimport { TwinOperation } from './twin-operation.js'\nimport { readBoardEquipment } from '@operato/ops-contract'\n\n/*\n * ๊ตฌ์กฐ ํฌ์ โ `model`(์ปค๋ ์
๋ ฅ ๋ฌธ์) โ **ํ์ค ์ํฐํฐ ํ**(ADR-0032).\n *\n * โโ ์ ์ ๋ ๊ต์ฒด์ธ๊ฐ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ด ํ๋ค์ **์๋ณธ์์ ์จ ์บ์**๋ค(ADR-0032-D). ์๋ณธ์ด ์ง์ค์ด๋ฏ๋ก diff ๋ก ์๋ผ๋ ๊ฒ๋ณด๋ค\n * **๋งค๋ฒ ๊ทธ๋๋ก ๋ค์ ๊ทธ๋ฆฌ๋ ๊ฒ**์ด ๋ง๋ค โ diff ๋ \"์ฐ๋ฆฌ ์ชฝ์ ๋จ๊ฒจ์ผ ํ ๊ฒ์ด ์๋ค\" ๋ ์ ์ ๋ฅผ\n * ๊น๊ณ , ๊ทธ ์ ์ ๊ฐ ์์ ์นจ๋ฒ์ ์์์ด๋ค.\n *\n * ๊ท๋ชจ๊ฐ ์ปค์ง๋ฉด ์๋ช
(`TwinStructure.signature`)์ด ๊ฐ์ ๋ ๊ฑด๋๋ฐ๋ ์ฅ์น๊ฐ ์ด๋ฏธ ์์ผ๋ฏ๋ก\n * ๊ทธ๊ฒ์ ์์ ๋๋ค. ์ฌ๊ธฐ์ diff ๋ฅผ ๋ฐ๋ช
ํ์ง ์๋๋ค.\n *\n * โโ ์์๊ฐ ์ค์ํ๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ์ค๋น๊ฐ ์๋ฆฌ๋ฅผ FK ๋ก ๊ฐ๋ฆฌํค๋ฏ๋ก **์๋ฆฌ๋ฅผ ๋จผ์ ** ๋ฃ๋๋ค. ์ง์ฐ๋ ๊ฒ์ ๋ฐ๋ ์์๋ค.\n * (์๋ฆฌ ์ญ์ ์ ์ค๋น์ `homeLocation` ์ `SET NULL` ์ด์ง๋ง, ์ ๋ ๊ต์ฒด์์๋ ๋ ๋ค ์ง์ด๋ค.)\n */\nexport interface ProjectionReport {\n locations: number\n equipment: number\n operations: number\n /** ์๋ฆฌ๋ฅผ ๋ชป ์ฐพ์ ๊ธฐ์ค ์๋ฆฌ๋ฅผ ๋น์ด ์ค๋น โ **์๋ฆฌ์ง ์๊ณ ๋๊ธฐ์ง ์๋๋ค.** */\n unresolvedHome: string[]\n /** ๊ตฌ์ญ์ ๋ชป ์ฐพ์ ๋น์ด ์๋ฆฌ. ๊ตฌ์ญ์ model ๋ฐ(ํธ์คํธ ๊ฐ๋
)์ด๋ผ ์ด๊ธ๋ ์ ์๋ค. */\n unresolvedArea: string[]\n}\n\n/**\n * ์ด ํธ์์ ๊ตฌ์กฐ ํ์ **์๋ณธ ๊ทธ๋๋ก ๋ค์ ๊ทธ๋ฆฐ๋ค.**\n *\n * `sourceRef` ๋ ์ด๋ ์๋ณธ์์ ์๋์ง๋ค(`ReferenceMaster.source` = instanceId). ์๋ ํ์\n * ๋ง๋ค ์ ์๋ค โ ์บ์๋ผ๋ ์ฌ์ค์ ๊ตฌ์กฐ๋ก ์งํจ๋ค.\n */\nexport async function projectStructure(domainId: string, instanceId: string, model: any, sourceRef: string): Promise<ProjectionReport> {\n const instance = await getRepository(TwinInstance).findOne({ where: { domain: { id: domainId }, instanceId } })\n if (!instance) throw new Error(`cannot project structure: twin instance \"${instanceId}\" is not registered`)\n\n /*\n * **๊ฐ์ id ๊ฐ ๋์ด๋ฉด ๊ทธ ์ฌ์ค์ ๋งํ๋ค** โ ์ ์ฝ ์๋ฐ ๋ฌธ๊ตฌ๋ฅผ ์ฌ์ฉ์์๊ฒ ๋ณด์ด์ง ์๋๋ค.\n *\n * ์ค์ธก(2026-08-18): ํ์ฅ ๊ฐ์ ๊ทธ ํ์ฅ์ ํธ์ ์ ๋ถ์ ์น๋ค๊ฐ ํ ํธ์์์ ํฌ์์ด ํฐ์ก๋ค. ์ฌ๋ผ์จ ๊ฒ์\n * `SQLITE_CONSTRAINT: UNIQUE constraint failed: twin_equipment...` ๋ฟ์ด๋ผ **๋ฌด์์ด ์๋ชป๋๋์ง ์๋ฌด๋\n * ์ ์ ์์๋ค.** ์์ธ์ ๊ทธ ๋ชจ๋ธ์ ์ค๋น `load-1` ์ด ๋ ๋ฒ ๋ค์ด ์๋ ๊ฒ์ด๋ค(id ๋ ํธ์ ์์์ ์ ์ผํด์ผ\n * ํ๋ค). ์๋ฆฌ์ง ์๊ณ ํ๋๋ง ๋จ๊ธฐ์ง ์๋๋ค โ ๊ทธ๊ฒ์ ๋ชจ๋ธ๋ง ์ค๋ฅ๋ฅผ ๊ฐ์ถ๋ ์ผ์ด๊ณ , ์ด๋ ์ชฝ์ด ๋ง๋์ง ์ฐ๋ฆฌ๋\n * ๋ชจ๋ฅธ๋ค.\n */\n const dupOf = (list: any[] | undefined, what: string): string | undefined => {\n const seen = new Set<string>()\n for (const e of list ?? []) {\n const id = String(e?.id ?? '')\n if (!id) continue\n if (seen.has(id)) return `twin \"${instanceId}\" has two ${what} with id \"${id}\" โ ids must be unique within a twin, so the model cannot be projected`\n seen.add(id)\n }\n return undefined\n }\n const dupMsg = dupOf(model?.locations, 'locations') ?? dupOf(readBoardEquipment(model), 'equipment')\n if (dupMsg) throw new Error(dupMsg)\n\n const locRepo = getRepository(TwinLocation)\n const eqRepo = getRepository(TwinEquipment)\n const opRepo = getRepository(TwinOperation)\n const scope = { domain: { id: domainId } as any, instance: { id: instance.id } as any }\n const ingestedAt = new Date()\n\n /*\n * ์ ๋ ๊ต์ฒด โ ์ด ํ๋ค์ **์๋ณธ์์ ์จ ์บ์**์ด๋ฏ๋ก ๋งค๋ฒ ๊ทธ๋๋ก ๋ค์ ๊ทธ๋ฆฐ๋ค.\n * diff ๋ก ์๋ผ๋ ๊ฒ์ \"์ฐ๋ฆฌ ์ชฝ์ ๋จ๊ฒจ์ผ ํ ๊ฒ์ด ์๋ค\" ๋ ์ ์ ๋ฅผ ๊น๊ณ , ๊ทธ ์ ์ ๊ฐ ์์ ์นจ๋ฒ์ ์์์ด๋ค.\n *\n * **๊ด์ธก์ผ๋ก ์๋ ์์์ ์ฌ๊ธฐ ์ฐ์ง ์๋๋ค.** ์ปค๋์ ๋ง์คํฐ์ ์๋ ์ค๋น๋ ์ด๋ฒคํธ๋ก ์๊ฒ ๋์ง๋ง\n * (`observed-reducer` ์ `origin: 'observed'`), ๊ทธ๊ฒ์ ์ด ํ์ ๋ฐ์ด ๋ฃ์ผ๋ฉด **์ฐ๊ธฐ ๊ฒฝ๋ก๊ฐ ๋**์ด ๋๊ณ \n * ํฑ ๋ฃจํ์์ DB ๋ก ์ฐ๋ ๊ธธ์ด ์๊ธด๋ค(ADR-0032-D ์๋ฐ). ๊ทธ ์ฐจ์ด๋ **์กฐํ ์์ ์ ๋น๊ตํด ๋ณด๊ณ **ํ๋ค โ\n * ์จ๊ฒจ์ผ ํ ๋ถ์ผ์น๊ฐ ์๋๋ผ \"์๋ณธ์ด ๋ชจ๋ฅด๋ ์ค๋น๊ฐ ์คํ ์ค์ด๋ค\" ๋ ์ฌ์ค์ด๋ค.\n */\n await eqRepo.delete(scope)\n await opRepo.delete(scope)\n await locRepo.delete(scope)\n\n /* ๊ตฌ์ญ์ model ๋ฐ์ ์ฐ๋ค(ํธ์คํธ์ TwinArea). ์ด๋ฆ์ผ๋ก ์ฐพ์ FK ๋ฅผ ์๋๋ค. */\n const areas = await getRepository(TwinArea).find({ where: { domain: { id: domainId } as any } })\n const areaOf = new Map(areas.map(a => [a.areaId, a]))\n const unresolvedArea: string[] = []\n\n /*\n * โโ ์ ๊ธฐ ์๋ฅ๋ฅผ ใ๊ตฌ์ญใ์ผ๋ก ์ฝ์ง ์๋๋ค (2026-08-18) โโโโโโโโโโโโโโโโโโโโโโโโ\n *\n * ์๋ฆฌ์ ๋ถ๋ชจ๊ฐ **๋ค๋ฅธ ์๋ฆฌ**์ผ ์ ์๋ค(๋ถ๊ธฐ์ ์๋ฅ๋ ์์ ์ด๋ค). ๊ทธ ๋ถ๋ชจ๋ฅผ ๊ตฌ์ญ ํ์์ ์ฐพ์ผ๋ฉด ๋น์ฐํ\n * ์๊ณ , ์์ ์๋ ๊ทธ๊ฒ์ ๋งค๋ฒ ใ๊ตฌ์ญ์ด ์ด ํธ์์ ์๋คใ๋ก ๊ฒฝ๊ณ ํ๋ค โ ์๋์ง ํธ์์ ์ธ์ ์คํธํ ๋๋ง๋ค\n * ๋ถ๊ธฐ ์๋งํผ ๊ฑฐ์ง ๊ฒฝ๋ณด๊ฐ ๋ฌ๋ค. ๊ฒฝ๋ณด๊ฐ ์์์ด ๋๋ฉด **์ฌ๋์ด ๊ฒฝ๋ณด ์์ฒด๋ฅผ ์ฝ์ง ์๊ฒ ๋๋ค.**\n *\n * ์๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ถ๋ชจ๋ ๊ณ์ธต(์๋ฆฌ โ ์๋ฆฌ)์ด๊ณ , ๊ตฌ์ญ์ model ๋ฐ์ ๋ค๋ฅธ ํ๋ค. ๊ทธ๋์ ๋ถ๋ชจ๊ฐ ์ด ๋ชจ๋ธ์\n * ์๋ฆฌ์ด๋ฉด ๊ตฌ์ญ ํด์์ **์๋ํ์ง ์๋๋ค**(์๋ ๊ฒ์ ๋ชป ์ฐพ์๋ค๊ณ ๋งํ์ง ์๋๋ค).\n */\n const locationIds = new Set((model?.locations ?? []).filter((l: any) => l?.id).map((l: any) => String(l.id)))\n\n const locations: TwinLocation[] = (model?.locations ?? [])\n .filter((l: any) => l?.id)\n .map((l: any) => {\n const parentIsLocation = l.parentId ? locationIds.has(String(l.parentId)) : false\n const area = l.parentId && !parentIsLocation ? areaOf.get(l.parentId) : undefined\n if (l.parentId && !parentIsLocation && !area) unresolvedArea.push(`${l.id}โ${l.parentId}`)\n return locRepo.create({\n ...scope,\n locationId: l.id,\n /* **์ด๋ฆ์ ์ฎ๊ธด๋ค.** ๋ฒ๋ฆฌ๊ณ ์์๋ค โ ๊ทธ๋์ ํ๋ฉด์ ์๋ฆฌ id ๋ง ๋จ์๋ค(ยงname ์ฃผ์ ์ฐธ์กฐ). */\n name: l.name ?? null,\n description: l.description ?? null,\n type: l.type,\n capacity: l.capacity ?? null,\n parallelism: l.parallelism ?? null,\n area: area ? ({ id: area.id } as any) : null,\n gs1Id: l.gs1Id ?? null,\n /* ์๋ฆฌ์ ์์ฑ๋ ์ฎ๊ธด๋ค โ ์ฎ๊ธฐ์ง ์์ผ๋ฉด ๊ณ์ฝ์ ๋ ฅยท์๊ธ์ด ํญ๋ชฉ ํจ๋์์ ์ฌ๋ผ์ง๋ค(๋ค์ด์จ ๊ฒ์ด ์๋ ๋๋ฝ). */\n properties: l.properties ?? null,\n sourceRef,\n ingestedAt\n } as any)\n })\n const savedLocations = locations.length ? await locRepo.save(locations, { chunk: 500 }) : []\n const locOf = new Map(savedLocations.map(l => [l.locationId, l]))\n\n const unresolvedHome: string[] = []\n const equipment: TwinEquipment[] = (model?.equipment ?? [])\n .filter((m: any) => m?.id)\n .map((m: any) => {\n const home = m.homeLocation ? locOf.get(m.homeLocation) : undefined\n /* ๋์ด์ง ๊ธฐ์ค ์๋ฆฌ๋ **์ด๋ฆ์ ๋๊ณ ** ๋ณด๊ณ ํ๋ค. ์์ ์๋ ํ๋ฉด์ด ๊ฒฝ๊ณ ํ ๋ฟ์ด์๊ณ \n ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ๋ค์ด์จ ๋ฐ์ดํฐ๋ ์๋ฌด๋ ์ ๋ดค๋ค. */\n if (m.homeLocation && !home) unresolvedHome.push(`${m.id}โ${m.homeLocation}`)\n return eqRepo.create({\n ...scope,\n equipmentId: m.id,\n name: m.name ?? null,\n description: m.description ?? null,\n kind: m.kind,\n /* ์์ฑ๋ ์ฎ๊ธด๋ค โ ํ์ ์๋ฆฌ๊ฐ ์์ด ํ๋ฆฌ๊ณ ์์๋ค(์๋น์ฒ๊ฐ ์ค์ ๋ก ์ฝ๋ ์ฌ์ค์ด๋ค: ์ฃผํ ์๋). */\n properties: m.properties ?? null,\n /* ์ํ ์ฐธ์กฐ๋ ํจ๊ป โ ํ๋ฆฌ๋ฉด ๋ช
์ธ ์ชฝ์์ \"๋๊ฐ ๋๋ฅผ ๊ฐ๋ฆฌํค๋\" ์ ์ด ์ค๋น๊ฐ ๋น ์ง๋ค. */\n testSpecificationIds: m.testSpecificationIds ?? null,\n /* ๊ฒฐ๊ณผ๊น์ง โ ์ฐธ์กฐ๋ง ์์ผ๋ฉด \"๋ฌด์์ผ๋ก ๊ฒ์ฆํ๋ค\" ๊น์ง๊ณ , ์๊ฒฉ ์ฑ๋ฆฝ์ ๊ฒฐ๊ณผ๊ฐ ๋งํ๋ค. */\n testResults: m.testResults ?? null,\n homeLocation: home ? ({ id: home.id } as any) : null,\n mtbfMs: m.mtbfMs ?? null,\n mttrMs: m.mttrMs ?? null,\n /* ์ ์ธ๋ ์ ์ฒด์ฑ โ ์์ ์๋ ์ ์ธ์ ์๋ `gs1Id` ๋ฅผ ์ฝ์ด ์ด ์นธ์ด ๋ ๋น์ด ์์๋ค. */\n identity: (m as any).identity ?? null,\n sourceRef,\n ingestedAt\n } as any)\n })\n if (equipment.length) await eqRepo.save(equipment, { chunk: 500 })\n\n const operations: TwinOperation[] = (model?.operations ?? [])\n .filter((o: any) => o?.key)\n .map((o: any, i: number) =>\n opRepo.create({\n ...scope,\n operationKey: o.key,\n /*\n * ๊ณต์ ์ ๋ง์คํฐ๊ฐ `label` ๋ก ๋งํ๋ค โ ํ์์๋ **๊ท์ฝ์ ์ด๋ฆ ํ๋๋ง** ๋๋ค.\n *\n * ํ๋์ `label` ์ปฌ๋ผ๋ ํจ๊ป ๋จ๊ฒจ ๋๋๋ ์กฐํ ํ๋ฉด์ \"์ด๋ฆ\" ์ด์ด **๋ ๊ฐ** ๋ด๋ค(๊ฐ์ ๊ฐ์ด\n * ๋ ๋ฒ). ์ดํ๋ฅผ ํ๋๋ก ํ๋ค๊ณ ํ๋ฉด์ ๋์ ๋จ๊ธฐ๋ฉด ๋ฐ๋์ ์ด๋ ๊ฒ ์์ด ๋์จ๋ค.\n */\n name: o.name ?? o.label ?? null,\n description: o.description ?? null,\n intent: o.intent ?? null,\n locationType: o.locationType ?? null,\n resourceType: o.resourceType ?? null,\n /* ์์์๊ฐ์ ISO 8601 ๋ฌธ์์ด์ด ์ ๋ณธ โ ๋ถ์ผ๋ก ์ค์ด๋ฉด ์ด๊ฐ ์ค๋ฅ ์์ด ์ฌ๋ผ์ง๋ค. */\n duration: o.duration ?? null,\n variability: o.variability ?? null,\n parameters: o.parameters ?? null,\n /* **๋ค ์์ ๋ช
์ธ๋ฅผ ํจ๊ป ์ฎ๊ธด๋ค.** ์
์ด ๋น ์ ธ ์์ด์ ์กฐํ ํ๋ฉด์ด \"์๋ณธ์ด ๋งํ ๊ฐ\" ์ด๋ผ ์ ๊ณ ๋\n ๋ท ์ค ํ๋๋ง ๋ณด์๋ค โ ์ฌ๋์ด ํ์ํ ๊ณต์ ์ ๋ณด๊ณ ์ฌ๋์ด ํ์ ์๋ค๊ณ ๊ฒฐ๋ก ๋ด๊ฒ ๋๋ค. */\n personnelSpecification: o.personnelSpecification ?? null,\n physicalAssetSpecification: o.physicalAssetSpecification ?? null,\n materialSpecification: o.materialSpecification ?? null,\n seq: i,\n sourceRef,\n ingestedAt\n } as any)\n )\n if (operations.length) await opRepo.save(operations, { chunk: 500 })\n\n return {\n locations: savedLocations.length,\n equipment: equipment.length,\n operations: operations.length,\n unresolvedHome,\n unresolvedArea\n }\n}\n"]}
|
|
@@ -45,7 +45,7 @@ export declare class TwinEquipment {
|
|
|
45
45
|
* ๊ทธ ์ํ๋ค์ **๊ฒฐ๊ณผ** โ ์๊ฒฉ์ด ์ฑ๋ฆฝํ๋์ง๋ ์ด๊ฒ์ด ๋งํ๋ค.
|
|
46
46
|
*
|
|
47
47
|
* ์ฐธ์กฐ๋ง ์์ผ๋ฉด "๋ฌด์์ผ๋ก ๊ฒ์ฆํ๋ค" ๊น์ง๋ค. ์ค๋ ์ด ์ ์ฅ์์์ ๋ค ๋ฒ ๋์จ ๊ฒฐ์๊ณผ ๊ฐ์ ๋ถ๋ฅ์ด๋ฏ๋ก
|
|
48
|
-
* ํ์ ์๋ฆฌ๋ฅผ ํจ๊ป ๋ง๋ ๋ค โ ๋ชจ๋ธ์๋ ์๋๋ฐ ํ์ ์์ผ๋ฉด ํ๋ฉด์ด
|
|
48
|
+
* ํ์ ์๋ฆฌ๋ฅผ ํจ๊ป ๋ง๋ ๋ค โ ๋ชจ๋ธ์๋ ์๋๋ฐ ํ์ ์์ผ๋ฉด ํ๋ฉด์ด ์๋ฆฌ์ง ์๊ณ ์๋๋ค.
|
|
49
49
|
*/
|
|
50
50
|
testResults?: any;
|
|
51
51
|
/**
|
|
@@ -56,7 +56,7 @@ export declare class TwinEquipment {
|
|
|
56
56
|
homeLocationRowId?: string;
|
|
57
57
|
mtbfMs?: number;
|
|
58
58
|
mttrMs?: number;
|
|
59
|
-
|
|
59
|
+
identity?: string;
|
|
60
60
|
sourceRef: string;
|
|
61
61
|
ingestedAt: Date;
|
|
62
62
|
createdAt?: Date;
|
|
@@ -15,7 +15,7 @@ const twin_location_js_1 = require("./twin-location.js");
|
|
|
15
15
|
*
|
|
16
16
|
* โโ ํ
์ด๋ธ ์ด๋ฆ์ ๋ช
์ํ๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
17
17
|
* `equipment` ๋ ์์ด์์ **๋ถ๊ฐ์ฐ**์ด๋ผ ์๋ ๋ณต์ํ๊ฐ ๋ค๋ฅธ ํ๋ค๊ณผ ๊ท์น์ด ์ด๊ธ๋๋ค
|
|
18
|
-
* (`twin_locations` ์ธ๋ฐ `twin_equipment`).
|
|
18
|
+
* (`twin_locations` ์ธ๋ฐ `twin_equipment`). ๋ค์ด์จ ๊ฒ์ด ์๋ ๋น์ผ๊ด์ ๋์ค์ "์ ์ด๊ฒ๋ง ๋ค๋ฅด์ง" ๋ฅผ
|
|
19
19
|
* ๋ง๋ค๋ฏ๋ก ์ด๋ฆ์ ๊ณ ์ ํ๋ค(ADR-0032-I).
|
|
20
20
|
*/
|
|
21
21
|
let TwinEquipment = class TwinEquipment {
|
|
@@ -100,9 +100,9 @@ tslib_1.__decorate([
|
|
|
100
100
|
], TwinEquipment.prototype, "mttrMs", void 0);
|
|
101
101
|
tslib_1.__decorate([
|
|
102
102
|
(0, typeorm_1.Column)({ nullable: true }),
|
|
103
|
-
(0, type_graphql_1.Field)({ nullable: true, description: '
|
|
103
|
+
(0, type_graphql_1.Field)({ nullable: true, description: 'Declared global identity of this equipment (TwinModelDef.equipment[].identity). Not necessarily a GS1 key.' }),
|
|
104
104
|
tslib_1.__metadata("design:type", String)
|
|
105
|
-
], TwinEquipment.prototype, "
|
|
105
|
+
], TwinEquipment.prototype, "identity", void 0);
|
|
106
106
|
tslib_1.__decorate([
|
|
107
107
|
(0, typeorm_1.Column)(),
|
|
108
108
|
(0, type_graphql_1.Field)({ description: 'Which reference (source system) this row came from. Required.' }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"twin-equipment.js","sourceRoot":"","sources":["../../../server/service/twin-model/twin-equipment.ts"],"names":[],"mappings":"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","sourcesContent":["import { CreateDateColumn, Entity, Index, Column, RelationId, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'\nimport { ObjectType, Field, ID, Int } from 'type-graphql'\n\nimport { Domain, ScalarObject } from '@things-factory/shell'\n\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinLocation } from './twin-location.js'\n\n/*\n * TwinEquipment โ ์ด ํธ์์ด ๋ฐ์ํ๋ **์ค๋น**. ISA-95 `Equipment` / ISO 55000 `Asset` / EPCIS `GIAI`.\n *\n * ์๋ฆฌ์ ๊ฐ์ ๊ท์จ์ ๋ฐ๋ฅธ๋ค(`twin-location.ts` ๋จธ๋ฆฌ๋ง) โ ์ด๊ฒ๋ **์๋ณธ์์ ์จ ์บ์**์ด๊ณ ,\n * `sourceRef`ยท`ingestedAt` ์ด ํ์์ด๋ฉฐ, ์ฐ๊ธฐ ๊ฒฝ๋ก๋ ์ธ์ ์คํธ ํ๋๋ค.\n *\n * โโ ํ
์ด๋ธ ์ด๋ฆ์ ๋ช
์ํ๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * `equipment` ๋ ์์ด์์ **๋ถ๊ฐ์ฐ**์ด๋ผ ์๋ ๋ณต์ํ๊ฐ ๋ค๋ฅธ ํ๋ค๊ณผ ๊ท์น์ด ์ด๊ธ๋๋ค\n * (`twin_locations` ์ธ๋ฐ `twin_equipment`). ์กฐ์ฉํ ๋น์ผ๊ด์ ๋์ค์ \"์ ์ด๊ฒ๋ง ๋ค๋ฅด์ง\" ๋ฅผ\n * ๋ง๋ค๋ฏ๋ก ์ด๋ฆ์ ๊ณ ์ ํ๋ค(ADR-0032-I).\n */\n@Entity({ name: 'twin_equipment' })\n@Index('ix_twin_equipment_0', (e: TwinEquipment) => [e.domain, e.instance, e.equipmentId], { unique: true })\n/* ์ข
๋ฅ๋ก ์ขํ ๋ณด๊ธฐ โ ๊ณต์ ์ด `resourceType` ์ผ๋ก ์ข
๋ฅ๋ฅผ ๊ฐ๋ฆฌํค๋ฏ๋ก ์ฆ์ ์ง์๋ค. */\n@Index('ix_twin_equipment_1', (e: TwinEquipment) => [e.domain, e.instance, e.kind])\n@ObjectType({ description: 'Equipment reflected into the twin (ISA-95 Equipment / ISO 55000 Asset). Projected from the source; never authored here.' })\nexport class TwinEquipment {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'Owning tenant domain.' })\n domain?: Domain\n\n @RelationId((e: TwinEquipment) => e.domain)\n domainId?: string\n\n @ManyToOne(type => TwinInstance, { onDelete: 'CASCADE' })\n @Field(type => TwinInstance, { nullable: true, description: 'Owning twin instance.' })\n instance?: TwinInstance\n\n @RelationId((e: TwinEquipment) => e.instance)\n instanceRowId?: string\n\n /** ์ปค๋ ๊ณ์ฝ์ `TwinModelDef.equipment[].id` ๊ทธ๋๋ก. */\n @Column()\n @Field({ description: 'Equipment id as declared by the source (kernel TwinModelDef.equipment[].id).' })\n equipmentId: string\n\n /**\n * **์ฌ๋์ด ๋ถ๋ฅด๋ ์ด๋ฆ** โ ํ๋ ์์ํฌ ์ํฐํฐ ๊ท์ฝ์ `name`/`description`.\n *\n * โโ ์ ์ด๊ฒ์ด ๋น ์ ธ ์์๊ณ , ๋ฌด์์ด ๋ง๊ฐ์ก๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํฌ์์ด ๋ง์คํฐ์ `name` ์ ๋ฒ๋ฆฌ๊ณ ์์๋ค. ๊ทธ๋์ ํ์๋ id ๋ง ๋จ๊ณ , ํ๋ฉด์ ์ด๋ฆ์ ๋ง๋ค ์ฌ๋ฃ๊ฐ\n * ์์ด `cut-station` ์ ๊ทธ๋๋ก ์ฐ์๋ค โ ๊ทธ ๊ฒฐํจ์ด ๋ชฉ๋กยทํยท๊ด๊ณ ๊ทธ๋ฆผ๋ง๋ค ๋ฐ๋ก ๋ํ๋์ ํ๋ฉด์\n * ํ๋์ฉ ๊ณ ์น๊ฒ ๋ง๋ค์๋ค. ํ๋ฉด์ ๋ฌธ์ ๊ฐ ์๋๋ผ **ํ์ ์ด๋ฆ์ด ์๋ ๋ฌธ์ **๋ค.\n *\n * ์๋ณธ์ด ์ด๋ฆ์ ๋งํ์ง ์์ผ๋ฉด ๋น์ด๋ค(id ๋ฅผ ์ด๋ฆ์ผ๋ก ๋ฒ ๋ผ์ง ์๋๋ค โ ๊ทธ๋ฌ๋ฉด \"์ด๋ฆ์ด ์๋ค\" ๋\n * ๊ฑฐ์ง์ด ๋๊ณ , ํ๋ฉด์ด ์ด๋ฆ ์์์ ์์๋ณผ ์ ์๊ฒ ๋๋ค).\n */\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Human name as declared by the source. Empty when the source does not name it (never copied from the id).' })\n name?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Longer description when the source provides one.' })\n description?: string\n\n /** ์ปค๋ ์นดํ๋ก๊ทธ์ ์ค๋น ์ข
๋ฅ ํค(`forklift`ยท`welder`โฆ). FK ์๋ โ ์นดํ๋ก๊ทธ๋ ์ปค๋ SSOT. */\n @Column()\n @Field({ description: 'Equipment kind key from the kernel catalog (not an FK โ the catalog is the kernel SSOT).' })\n kind: string\n\n /**\n * ์์ ์์ฑ โ **ISA-95 `Property`**(๊ฐยท๋ฐ์ดํฐํยท๋จ์ยทํ์ ์์ฑ).\n *\n * ๋ชจ๋ธ์๋ ์๋๋ฐ ํ์ ์๋ฆฌ๊ฐ ์์ด ํฌ์์ด ํ๋ฆฌ๊ณ ์์๋ค. ๊ทธ๋ฌ๋ฉด ์กฐํ ํ๋ฉด์ \"์๋ณธ์ด ๋งํ ๊ฐ\" ์ด๋ผ\n * ์ ๊ณ ๋ ์์ฑ์ ๋ณด์ด์ง ๋ชปํ๋ค โ ์ด๋ฆ์ด ๊ฐ์ ์์ผ๋ก ์ฌ๋ผ์ก๋ ๊ฒ๊ณผ ๊ฐ์ ๋ถ๋ฅ๋ค(2026-08-11).\n *\n * ์๋น์ฒ๊ฐ ์ค์ ๋ก ์ฝ๋ ์ฌ์ค์ด๋ค: ์ฃผํ ์ถ์ ๊ธฐ๊ฐ `speed` ๋ก ์ด๋ ์๊ฐ์ ๋ง๋ ๋ค. ๋จ์๊ฐ ๊ฐ ์์ ๋ถ์ด\n * ์์ด์ผ ๋ป์ด ์๋ฏ๋ก **๋ชจ์ ๊ทธ๋๋ก** ๋ด๋๋ค(๋ฌธ์์ด ๊ฐ + `uom` + `dataType`).\n */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => ScalarObject, { nullable: true, description: 'Resource properties as declared by the source (ISA-95 Property: value + dataType + unit of measure, optional children).' })\n properties?: any\n\n /**\n * ์ด ์ค๋น์ ์ ๊ฒฉ์ ๊ฒ์ฆํ **์ํ ๋ช
์ธ๋ค** โ ํ์ค `TestSpecificationID`(`maxOccurs=\"unbounded\"`).\n *\n * ์ฐธ์กฐ๋ง ๋ด๋๋ค(๋์์ `testSpecifications` ์ถ). ์์ฑ๊ณผ **๊ฐ์ ๋ถ๋ฅ์ ๊ฒฐ์**์ด์๋ค: ๋ชจ๋ธ์๋ ์๋๋ฐ\n * ํ์ ์๋ฆฌ๊ฐ ์์ด ํฌ์์ด ํ๋ ธ๊ณ , ๊ทธ๋์ ๋ช
์ธ ์ชฝ์์ \"๋๊ฐ ๋๋ฅผ ๊ฐ๋ฆฌํค๋\" ๋ฅผ ๋ฌผ์ผ๋ฉด ์ค๋น๊ฐ ๋น ์ก๋ค.\n */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => [String], { nullable: true, description: 'Test specifications that verified this equipment (ISA-95 TestSpecificationID, unbounded). References only โ the specifications themselves live on the testSpecifications axis.' })\n testSpecificationIds?: string[]\n\n /**\n * ๊ทธ ์ํ๋ค์ **๊ฒฐ๊ณผ** โ ์๊ฒฉ์ด ์ฑ๋ฆฝํ๋์ง๋ ์ด๊ฒ์ด ๋งํ๋ค.\n *\n * ์ฐธ์กฐ๋ง ์์ผ๋ฉด \"๋ฌด์์ผ๋ก ๊ฒ์ฆํ๋ค\" ๊น์ง๋ค. ์ค๋ ์ด ์ ์ฅ์์์ ๋ค ๋ฒ ๋์จ ๊ฒฐ์๊ณผ ๊ฐ์ ๋ถ๋ฅ์ด๋ฏ๋ก\n * ํ์ ์๋ฆฌ๋ฅผ ํจ๊ป ๋ง๋ ๋ค โ ๋ชจ๋ธ์๋ ์๋๋ฐ ํ์ ์์ผ๋ฉด ํ๋ฉด์ด ์กฐ์ฉํ ์๋๋ค.\n */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => ScalarObject, { nullable: true, description: 'Results of those tests (pass/fail with dates). Declared by the source โ the twin does not produce them.' })\n testResults?: any\n\n /**\n * ๊ธฐ์ค ์๋ฆฌ โ **์ค์ FK**. ์์ ์๋ `homeLocation` ๋ฌธ์์ด์ด๋ผ ๋์ด์ง ์ฐธ์กฐ๋ฅผ ํ๋ฉด์ด ๊ฒฝ๊ณ ํ๊ณ \n * (`brokenHomeRefs`), ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ๋ค์ด์ค๋ ๋ฐ์ดํฐ๋ ์๋ฌด๋ ์ ๋ดค๋ค. ์ด์ DB ๊ฐ ๋ง๋๋ค.\n */\n @ManyToOne(type => TwinLocation, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => TwinLocation, { nullable: true, description: 'Home location this equipment belongs to.' })\n homeLocation?: TwinLocation\n\n @RelationId((e: TwinEquipment) => e.homeLocation)\n homeLocationRowId?: string\n\n /*\n * ๊ณ ์ฅ ๋ชจ๋ธ โ ์๋ณธ์ด ์ ์ธํ ๋๋ง ์๋ค. ์์ผ๋ฉด ๊ณ ์ฅ ์๋ ์ค๋น๋ก ๋์ํ๋ค(์ปค๋ ๊ณ์ฝ).\n * **๊ด์ธก(๊ฐ๋๋ฅ )์ ์ฌ๊ธฐ ๋์ง ์๋๋ค** โ ๊ทธ๊ฑด ํธ์์ด ์ ๋์์ ๋ง๋ ๊ฒ์ด๋ผ ์ฑ์ง์ด ๋ค๋ฅด๊ณ ,\n * ์ด ํ๋ ์๋ณธ์์ ์ฌ์์ฑ ๊ฐ๋ฅํด์ผ ํ๋ค(ADR-0032-D).\n */\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true, description: 'Declared mean time between failures in ms. Absent = no failure model.' })\n mtbfMs?: number\n\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true, description: 'Declared mean time to repair in ms.' })\n mttrMs?: number\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'GS1 identifier supplied by the source (e.g. GIAI).' })\n gs1Id?: string\n\n /* โโ ์บ์๋ผ๋ ์ฌ์ค์ ๊ตฌ์กฐ๋ก (ADR-0032-D) โโ */\n @Column()\n @Field({ description: 'Which reference (source system) this row came from. Required.' })\n sourceRef: string\n\n /*\n * **ํ์
์ด๋ฆ์ ์ ์ง ์๋๋ค** (2026-08-19 Postgres ๋ถํ
์คํจ๋ก ๊ณ ์นจ).\n *\n * `datetime` ์ sqliteยทMySQL ์ ์ด๋ฆ์ด๊ณ Postgres ๋ `timestamp` ๋ง ์๋ค โ ๊ฑฐ๊พธ๋ก `timestamp` ๋\n * sqlite ๊ฐ ๋ชจ๋ฅธ๋ค. **๋ค์ฏ ๋๋ผ์ด๋ฒ์ ๋ค ํตํ๋ ์ด๋ฆ์ด ์๋ค.** ๊ทธ๋์ ์ด๋ฆ ๊ณ ๋ฅด๋ ์ผ์ TypeORM ์\n * ๋งก๊ธด๋ค(`emitDecoratorMetadata` ๊ฐ ์ผ์ ธ ์์ด `Date` ์์ ๋๋ผ์ด๋ฒ๋ณ ํ์
์ ๊ณ ๋ฅธ๋ค).\n */\n @Column()\n @Field({ description: 'When this row was projected from the source.' })\n ingestedAt: Date\n\n @CreateDateColumn()\n @Field({ nullable: true })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true })\n updatedAt?: Date\n}\n"]}
|
|
1
|
+
{"version":3,"file":"twin-equipment.js","sourceRoot":"","sources":["../../../server/service/twin-model/twin-equipment.ts"],"names":[],"mappings":"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","sourcesContent":["import { CreateDateColumn, Entity, Index, Column, RelationId, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'\nimport { ObjectType, Field, ID, Int } from 'type-graphql'\n\nimport { Domain, ScalarObject } from '@things-factory/shell'\n\nimport { TwinInstance } from '../twin-instance/twin-instance.js'\nimport { TwinLocation } from './twin-location.js'\n\n/*\n * TwinEquipment โ ์ด ํธ์์ด ๋ฐ์ํ๋ **์ค๋น**. ISA-95 `Equipment` / ISO 55000 `Asset` / EPCIS `GIAI`.\n *\n * ์๋ฆฌ์ ๊ฐ์ ๊ท์จ์ ๋ฐ๋ฅธ๋ค(`twin-location.ts` ๋จธ๋ฆฌ๋ง) โ ์ด๊ฒ๋ **์๋ณธ์์ ์จ ์บ์**์ด๊ณ ,\n * `sourceRef`ยท`ingestedAt` ์ด ํ์์ด๋ฉฐ, ์ฐ๊ธฐ ๊ฒฝ๋ก๋ ์ธ์ ์คํธ ํ๋๋ค.\n *\n * โโ ํ
์ด๋ธ ์ด๋ฆ์ ๋ช
์ํ๋ค โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * `equipment` ๋ ์์ด์์ **๋ถ๊ฐ์ฐ**์ด๋ผ ์๋ ๋ณต์ํ๊ฐ ๋ค๋ฅธ ํ๋ค๊ณผ ๊ท์น์ด ์ด๊ธ๋๋ค\n * (`twin_locations` ์ธ๋ฐ `twin_equipment`). ๋ค์ด์จ ๊ฒ์ด ์๋ ๋น์ผ๊ด์ ๋์ค์ \"์ ์ด๊ฒ๋ง ๋ค๋ฅด์ง\" ๋ฅผ\n * ๋ง๋ค๋ฏ๋ก ์ด๋ฆ์ ๊ณ ์ ํ๋ค(ADR-0032-I).\n */\n@Entity({ name: 'twin_equipment' })\n@Index('ix_twin_equipment_0', (e: TwinEquipment) => [e.domain, e.instance, e.equipmentId], { unique: true })\n/* ์ข
๋ฅ๋ก ์ขํ ๋ณด๊ธฐ โ ๊ณต์ ์ด `resourceType` ์ผ๋ก ์ข
๋ฅ๋ฅผ ๊ฐ๋ฆฌํค๋ฏ๋ก ์ฆ์ ์ง์๋ค. */\n@Index('ix_twin_equipment_1', (e: TwinEquipment) => [e.domain, e.instance, e.kind])\n@ObjectType({ description: 'Equipment reflected into the twin (ISA-95 Equipment / ISO 55000 Asset). Projected from the source; never authored here.' })\nexport class TwinEquipment {\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain, { nullable: true, description: 'Owning tenant domain.' })\n domain?: Domain\n\n @RelationId((e: TwinEquipment) => e.domain)\n domainId?: string\n\n @ManyToOne(type => TwinInstance, { onDelete: 'CASCADE' })\n @Field(type => TwinInstance, { nullable: true, description: 'Owning twin instance.' })\n instance?: TwinInstance\n\n @RelationId((e: TwinEquipment) => e.instance)\n instanceRowId?: string\n\n /** ์ปค๋ ๊ณ์ฝ์ `TwinModelDef.equipment[].id` ๊ทธ๋๋ก. */\n @Column()\n @Field({ description: 'Equipment id as declared by the source (kernel TwinModelDef.equipment[].id).' })\n equipmentId: string\n\n /**\n * **์ฌ๋์ด ๋ถ๋ฅด๋ ์ด๋ฆ** โ ํ๋ ์์ํฌ ์ํฐํฐ ๊ท์ฝ์ `name`/`description`.\n *\n * โโ ์ ์ด๊ฒ์ด ๋น ์ ธ ์์๊ณ , ๋ฌด์์ด ๋ง๊ฐ์ก๋ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n * ํฌ์์ด ๋ง์คํฐ์ `name` ์ ๋ฒ๋ฆฌ๊ณ ์์๋ค. ๊ทธ๋์ ํ์๋ id ๋ง ๋จ๊ณ , ํ๋ฉด์ ์ด๋ฆ์ ๋ง๋ค ์ฌ๋ฃ๊ฐ\n * ์์ด `cut-station` ์ ๊ทธ๋๋ก ์ฐ์๋ค โ ๊ทธ ๊ฒฐํจ์ด ๋ชฉ๋กยทํยท๊ด๊ณ ๊ทธ๋ฆผ๋ง๋ค ๋ฐ๋ก ๋ํ๋์ ํ๋ฉด์\n * ํ๋์ฉ ๊ณ ์น๊ฒ ๋ง๋ค์๋ค. ํ๋ฉด์ ๋ฌธ์ ๊ฐ ์๋๋ผ **ํ์ ์ด๋ฆ์ด ์๋ ๋ฌธ์ **๋ค.\n *\n * ์๋ณธ์ด ์ด๋ฆ์ ๋งํ์ง ์์ผ๋ฉด ๋น์ด๋ค(id ๋ฅผ ์ด๋ฆ์ผ๋ก ๋ฒ ๋ผ์ง ์๋๋ค โ ๊ทธ๋ฌ๋ฉด \"์ด๋ฆ์ด ์๋ค\" ๋\n * ๊ฑฐ์ง์ด ๋๊ณ , ํ๋ฉด์ด ์ด๋ฆ ์์์ ์์๋ณผ ์ ์๊ฒ ๋๋ค).\n */\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Human name as declared by the source. Empty when the source does not name it (never copied from the id).' })\n name?: string\n\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Longer description when the source provides one.' })\n description?: string\n\n /** ์ปค๋ ์นดํ๋ก๊ทธ์ ์ค๋น ์ข
๋ฅ ํค(`forklift`ยท`welder`โฆ). FK ์๋ โ ์นดํ๋ก๊ทธ๋ ์ปค๋ SSOT. */\n @Column()\n @Field({ description: 'Equipment kind key from the kernel catalog (not an FK โ the catalog is the kernel SSOT).' })\n kind: string\n\n /**\n * ์์ ์์ฑ โ **ISA-95 `Property`**(๊ฐยท๋ฐ์ดํฐํยท๋จ์ยทํ์ ์์ฑ).\n *\n * ๋ชจ๋ธ์๋ ์๋๋ฐ ํ์ ์๋ฆฌ๊ฐ ์์ด ํฌ์์ด ํ๋ฆฌ๊ณ ์์๋ค. ๊ทธ๋ฌ๋ฉด ์กฐํ ํ๋ฉด์ \"์๋ณธ์ด ๋งํ ๊ฐ\" ์ด๋ผ\n * ์ ๊ณ ๋ ์์ฑ์ ๋ณด์ด์ง ๋ชปํ๋ค โ ์ด๋ฆ์ด ๊ฐ์ ์์ผ๋ก ์ฌ๋ผ์ก๋ ๊ฒ๊ณผ ๊ฐ์ ๋ถ๋ฅ๋ค(2026-08-11).\n *\n * ์๋น์ฒ๊ฐ ์ค์ ๋ก ์ฝ๋ ์ฌ์ค์ด๋ค: ์ฃผํ ์ถ์ ๊ธฐ๊ฐ `speed` ๋ก ์ด๋ ์๊ฐ์ ๋ง๋ ๋ค. ๋จ์๊ฐ ๊ฐ ์์ ๋ถ์ด\n * ์์ด์ผ ๋ป์ด ์๋ฏ๋ก **๋ชจ์ ๊ทธ๋๋ก** ๋ด๋๋ค(๋ฌธ์์ด ๊ฐ + `uom` + `dataType`).\n */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => ScalarObject, { nullable: true, description: 'Resource properties as declared by the source (ISA-95 Property: value + dataType + unit of measure, optional children).' })\n properties?: any\n\n /**\n * ์ด ์ค๋น์ ์ ๊ฒฉ์ ๊ฒ์ฆํ **์ํ ๋ช
์ธ๋ค** โ ํ์ค `TestSpecificationID`(`maxOccurs=\"unbounded\"`).\n *\n * ์ฐธ์กฐ๋ง ๋ด๋๋ค(๋์์ `testSpecifications` ์ถ). ์์ฑ๊ณผ **๊ฐ์ ๋ถ๋ฅ์ ๊ฒฐ์**์ด์๋ค: ๋ชจ๋ธ์๋ ์๋๋ฐ\n * ํ์ ์๋ฆฌ๊ฐ ์์ด ํฌ์์ด ํ๋ ธ๊ณ , ๊ทธ๋์ ๋ช
์ธ ์ชฝ์์ \"๋๊ฐ ๋๋ฅผ ๊ฐ๋ฆฌํค๋\" ๋ฅผ ๋ฌผ์ผ๋ฉด ์ค๋น๊ฐ ๋น ์ก๋ค.\n */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => [String], { nullable: true, description: 'Test specifications that verified this equipment (ISA-95 TestSpecificationID, unbounded). References only โ the specifications themselves live on the testSpecifications axis.' })\n testSpecificationIds?: string[]\n\n /**\n * ๊ทธ ์ํ๋ค์ **๊ฒฐ๊ณผ** โ ์๊ฒฉ์ด ์ฑ๋ฆฝํ๋์ง๋ ์ด๊ฒ์ด ๋งํ๋ค.\n *\n * ์ฐธ์กฐ๋ง ์์ผ๋ฉด \"๋ฌด์์ผ๋ก ๊ฒ์ฆํ๋ค\" ๊น์ง๋ค. ์ค๋ ์ด ์ ์ฅ์์์ ๋ค ๋ฒ ๋์จ ๊ฒฐ์๊ณผ ๊ฐ์ ๋ถ๋ฅ์ด๋ฏ๋ก\n * ํ์ ์๋ฆฌ๋ฅผ ํจ๊ป ๋ง๋ ๋ค โ ๋ชจ๋ธ์๋ ์๋๋ฐ ํ์ ์์ผ๋ฉด ํ๋ฉด์ด ์๋ฆฌ์ง ์๊ณ ์๋๋ค.\n */\n @Column({ type: 'simple-json', nullable: true })\n @Field(type => ScalarObject, { nullable: true, description: 'Results of those tests (pass/fail with dates). Declared by the source โ the twin does not produce them.' })\n testResults?: any\n\n /**\n * ๊ธฐ์ค ์๋ฆฌ โ **์ค์ FK**. ์์ ์๋ `homeLocation` ๋ฌธ์์ด์ด๋ผ ๋์ด์ง ์ฐธ์กฐ๋ฅผ ํ๋ฉด์ด ๊ฒฝ๊ณ ํ๊ณ \n * (`brokenHomeRefs`), ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ๋ค์ด์ค๋ ๋ฐ์ดํฐ๋ ์๋ฌด๋ ์ ๋ดค๋ค. ์ด์ DB ๊ฐ ๋ง๋๋ค.\n */\n @ManyToOne(type => TwinLocation, { nullable: true, onDelete: 'SET NULL' })\n @Field(type => TwinLocation, { nullable: true, description: 'Home location this equipment belongs to.' })\n homeLocation?: TwinLocation\n\n @RelationId((e: TwinEquipment) => e.homeLocation)\n homeLocationRowId?: string\n\n /*\n * ๊ณ ์ฅ ๋ชจ๋ธ โ ์๋ณธ์ด ์ ์ธํ ๋๋ง ์๋ค. ์์ผ๋ฉด ๊ณ ์ฅ ์๋ ์ค๋น๋ก ๋์ํ๋ค(์ปค๋ ๊ณ์ฝ).\n * **๊ด์ธก(๊ฐ๋๋ฅ )์ ์ฌ๊ธฐ ๋์ง ์๋๋ค** โ ๊ทธ๊ฑด ํธ์์ด ์ ๋์์ ๋ง๋ ๊ฒ์ด๋ผ ์ฑ์ง์ด ๋ค๋ฅด๊ณ ,\n * ์ด ํ๋ ์๋ณธ์์ ์ฌ์์ฑ ๊ฐ๋ฅํด์ผ ํ๋ค(ADR-0032-D).\n */\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true, description: 'Declared mean time between failures in ms. Absent = no failure model.' })\n mtbfMs?: number\n\n @Column({ type: 'int', nullable: true })\n @Field(type => Int, { nullable: true, description: 'Declared mean time to repair in ms.' })\n mttrMs?: number\n\n /*\n * โโ **์ ์ธ๋ ์ค๋น ์ ์ฒด์ฑ** (2026-08-30) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n *\n * ์์ ์ด๋ฆ์ `gs1Id` ์๊ณ , ํฌ์์ด ์ ์ธ์ `m.gs1Id` ๋ฅผ ์ฝ์๋ค. **๊ทธ๋ฐ ํ๋๊ฐ ์ ์ธ์ ์๋ค** โ ๊ทธ๋์\n * ์ด ์นธ์ ์ผ๊ณฑ ๋ ๋ชจ๋ ์์ํ ๋น์ด ์์๋ค. ์๋ฆฌ๋ ์๊ณ ๊ธธ์ด ์์๋ค.\n *\n * ๊ทธ ์ฌ์ด ์ปค๋์ `TwinModelDef.equipment[].identity` ๋ฅผ ์ด์์ผ๋ฏ๋ก ์ดํ๊ฐ ๋ ๋ฒ์ด ๋๋ค. ํ๋๋ก\n * ํฉ์น๋ค. ์ด๋ฆ์ `identity` ๋ก ๋๋ ์ด์ ๋ **GS1 ํค๊ฐ ์๋ ์ ์ฒด์ฑ์ด ์ ์**์ด๊ธฐ ๋๋ฌธ์ด๋ค โ\n * ์ค์ธกํ ๊ฐ์ ์ธ๋ฒํฐ์ ํ๋์จ์ด ์๋ณ์(`ES100000007d8d061d-1`)์ด๊ณ GS1 ํค๊ฐ ์๋๋ค.\n *\n * ์๋ฆฌ(`twin_location`)์ `gs1Id` ๋ ๊ทธ๋๋ก ๋๋ค. ๊ทธ์ชฝ์ ์ค์ ๋ก SGLN ์ด ์จ๋ค.\n */\n @Column({ nullable: true })\n @Field({ nullable: true, description: 'Declared global identity of this equipment (TwinModelDef.equipment[].identity). Not necessarily a GS1 key.' })\n identity?: string\n\n /* โโ ์บ์๋ผ๋ ์ฌ์ค์ ๊ตฌ์กฐ๋ก (ADR-0032-D) โโ */\n @Column()\n @Field({ description: 'Which reference (source system) this row came from. Required.' })\n sourceRef: string\n\n /*\n * **ํ์
์ด๋ฆ์ ์ ์ง ์๋๋ค** (2026-08-19 Postgres ๋ถํ
์คํจ๋ก ๊ณ ์นจ).\n *\n * `datetime` ์ sqliteยทMySQL ์ ์ด๋ฆ์ด๊ณ Postgres ๋ `timestamp` ๋ง ์๋ค โ ๊ฑฐ๊พธ๋ก `timestamp` ๋\n * sqlite ๊ฐ ๋ชจ๋ฅธ๋ค. **๋ค์ฏ ๋๋ผ์ด๋ฒ์ ๋ค ํตํ๋ ์ด๋ฆ์ด ์๋ค.** ๊ทธ๋์ ์ด๋ฆ ๊ณ ๋ฅด๋ ์ผ์ TypeORM ์\n * ๋งก๊ธด๋ค(`emitDecoratorMetadata` ๊ฐ ์ผ์ ธ ์์ด `Date` ์์ ๋๋ผ์ด๋ฒ๋ณ ํ์
์ ๊ณ ๋ฅธ๋ค).\n */\n @Column()\n @Field({ description: 'When this row was projected from the source.' })\n ingestedAt: Date\n\n @CreateDateColumn()\n @Field({ nullable: true })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true })\n updatedAt?: Date\n}\n"]}
|
|
@@ -37,11 +37,22 @@ let TwinLineageQuery = class TwinLineageQuery {
|
|
|
37
37
|
* ๋ณํ ์ด๋ฒคํธ๋ง ์ฝ๋๋ค. **์ต์ ๋ถํฐ** ์ฝ๋๋ค โ ๊ณ๋ณด๋ฅผ ๋ฌป๋ ๊ฐ์ฒด๋ ๋๊ฐ ์ต๊ทผ์ ๋ง๋ค์ด์ง ๊ฒ์ด๊ณ ,
|
|
38
38
|
* ์ฐฝ์ ๋๊ฒจ ์๋ฆด ๋ ์๋ ์ชฝ์ด ์ค๋๋ ๊ฒ์ด์ด์ผ ๋ ์ํ๋ค.
|
|
39
39
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
/*
|
|
41
|
+
* ๊ด๊ณ๋ฅผ **์ปฌ๋ผ์ผ๋ก** ๋ฌป๋๋ค (2026-08-28). `find({ where: { domain: { id } } })` ์ ๊ด๊ณ๋ฅผ ๊ฐ์ง
|
|
42
|
+
* ์ํฐํฐ์์ ๋ ๋จ๊ณ ์ง์๊ฐ ๋๊ณ **์์ชฝ์ ์ํ์ด ์๋ค** โ `take` ๊ฐ ์์ด๋ ์กฐ๊ฑด์ ๋ง๋ ํ์ ์ ๋ถ
|
|
43
|
+
* ๋ง๋ ๋ค ๋ฐ์์ ์๋ฅธ๋ค. ๋ณํ ์ฌ๊ฑด์ด ์ ์ ํธ์์์๋ ํ๊ฐ ์ ๋์ง๋ง, ๋ณํ์ ๋ง์ด ๋ด๋ ํธ์์์๋
|
|
44
|
+
* ์ด ํ ๋ฒ์ด ๊ทธ ์ข
๋ฅ ์ ์ฒด๋ฅผ ๋ง๋ ๋ค. ์ง์ ๋น๋๋ก ๋ฌผ์ผ๋ฉด ์ํ์ด ์์ชฝ์ ๊ฑธ๋ฆฐ๋ค.
|
|
45
|
+
*
|
|
46
|
+
* ์ข
๋ฅ๊ฐ ์ ํ์ผ์น์ด๋ฏ๋ก `(domain, instance, event_type, event_time)` ์์ธ์ด ์๊ฐ ์์๊น์ง ์ค๋ค.
|
|
47
|
+
*/
|
|
48
|
+
const rows = await (0, shell_1.getRepository)(twin_event_js_1.TwinEvent)
|
|
49
|
+
.createQueryBuilder('e')
|
|
50
|
+
.where('e.domain = :domainId', { domainId })
|
|
51
|
+
.andWhere('e.instanceId = :instanceId', { instanceId })
|
|
52
|
+
.andWhere('e.eventType = :eventType', { eventType: 'epcis.TransformationEvent' })
|
|
53
|
+
.orderBy('e.eventTime', 'DESC')
|
|
54
|
+
.limit(windowCap)
|
|
55
|
+
.getMany();
|
|
45
56
|
const truncated = rows.length >= windowCap;
|
|
46
57
|
/* ์ฐ์ถ โ ๊ทธ ๋ณํ. ํ ๊ฐ์ฒด๋ ํ ๋ฒ๋ง ๋ง๋ค์ด์ง์ง๋ง, ๋ฐ์ดํฐ๊ฐ ๊ทธ๋ ์ง ์์ ์ ์์ผ๋ฏ๋ก ๋ชฉ๋ก์ผ๋ก ๋ ๋ค. */
|
|
47
58
|
const madeBy = new Map();
|