@things-factory/ops-master 10.1.248 → 10.1.249
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-client/bootstrap.d.ts +19 -0
- package/dist-client/bootstrap.js +66 -0
- package/dist-client/bootstrap.js.map +1 -0
- package/dist-client/index.d.ts +17 -0
- package/dist-client/index.js +21 -0
- package/dist-client/index.js.map +1 -0
- package/dist-client/master-change-approval.d.ts +14 -0
- package/dist-client/master-change-approval.js +36 -0
- package/dist-client/master-change-approval.js.map +1 -0
- package/dist-client/master-change-policy-axes.d.ts +37 -0
- package/dist-client/master-change-policy-axes.js +29 -0
- package/dist-client/master-change-policy-axes.js.map +1 -0
- package/dist-client/master-change-policy-panel.d.ts +59 -0
- package/dist-client/master-change-policy-panel.js +454 -0
- package/dist-client/master-change-policy-panel.js.map +1 -0
- package/dist-client/master-change-providers.d.ts +4 -0
- package/dist-client/master-change-providers.js +91 -0
- package/dist-client/master-change-providers.js.map +1 -0
- package/dist-client/pages/master/applied-when-dialog.d.ts +48 -0
- package/dist-client/pages/master/applied-when-dialog.js +137 -0
- package/dist-client/pages/master/applied-when-dialog.js.map +1 -0
- package/dist-client/pages/master/assignment-fields.d.ts +27 -0
- package/dist-client/pages/master/assignment-fields.js +62 -0
- package/dist-client/pages/master/assignment-fields.js.map +1 -0
- package/dist-client/pages/master/equipment-class.d.ts +12 -0
- package/dist-client/pages/master/equipment-class.js +42 -0
- package/dist-client/pages/master/equipment-class.js.map +1 -0
- package/dist-client/pages/master/equipment.d.ts +12 -0
- package/dist-client/pages/master/equipment.js +58 -0
- package/dist-client/pages/master/equipment.js.map +1 -0
- package/dist-client/pages/master/grist-iso-duration.d.ts +20 -0
- package/dist-client/pages/master/grist-iso-duration.js +70 -0
- package/dist-client/pages/master/grist-iso-duration.js.map +1 -0
- package/dist-client/pages/master/grist-reference.d.ts +91 -0
- package/dist-client/pages/master/grist-reference.js +419 -0
- package/dist-client/pages/master/grist-reference.js.map +1 -0
- package/dist-client/pages/master/import-rows.d.ts +35 -0
- package/dist-client/pages/master/import-rows.js +66 -0
- package/dist-client/pages/master/import-rows.js.map +1 -0
- package/dist-client/pages/master/iso-duration.d.ts +34 -0
- package/dist-client/pages/master/iso-duration.js +76 -0
- package/dist-client/pages/master/iso-duration.js.map +1 -0
- package/dist-client/pages/master/master-options.d.ts +40 -0
- package/dist-client/pages/master/master-options.js +54 -0
- package/dist-client/pages/master/master-options.js.map +1 -0
- package/dist-client/pages/master/master-page-base.d.ts +369 -0
- package/dist-client/pages/master/master-page-base.js +657 -0
- package/dist-client/pages/master/master-page-base.js.map +1 -0
- package/dist-client/pages/master/material-class.d.ts +12 -0
- package/dist-client/pages/master/material-class.js +42 -0
- package/dist-client/pages/master/material-class.js.map +1 -0
- package/dist-client/pages/master/material-definition.d.ts +5 -0
- package/dist-client/pages/master/material-definition.js +14 -0
- package/dist-client/pages/master/material-definition.js.map +1 -0
- package/dist-client/pages/master/material-revision-fields.d.ts +2 -0
- package/dist-client/pages/master/material-revision-fields.js +43 -0
- package/dist-client/pages/master/material-revision-fields.js.map +1 -0
- package/dist-client/pages/master/operation-definition.d.ts +12 -0
- package/dist-client/pages/master/operation-definition.js +49 -0
- package/dist-client/pages/master/operation-definition.js.map +1 -0
- package/dist-client/pages/master/operational-location.d.ts +84 -0
- package/dist-client/pages/master/operational-location.js +432 -0
- package/dist-client/pages/master/operational-location.js.map +1 -0
- package/dist-client/pages/master/person.d.ts +12 -0
- package/dist-client/pages/master/person.js +41 -0
- package/dist-client/pages/master/person.js.map +1 -0
- package/dist-client/pages/master/personnel-class.d.ts +12 -0
- package/dist-client/pages/master/personnel-class.js +43 -0
- package/dist-client/pages/master/personnel-class.js.map +1 -0
- package/dist-client/pages/master/physical-asset-class.d.ts +12 -0
- package/dist-client/pages/master/physical-asset-class.js +40 -0
- package/dist-client/pages/master/physical-asset-class.js.map +1 -0
- package/dist-client/pages/master/physical-asset.d.ts +12 -0
- package/dist-client/pages/master/physical-asset.js +41 -0
- package/dist-client/pages/master/physical-asset.js.map +1 -0
- package/dist-client/pages/master/recipe-definition.d.ts +5 -0
- package/dist-client/pages/master/recipe-definition.js +14 -0
- package/dist-client/pages/master/recipe-definition.js.map +1 -0
- package/dist-client/pages/master/reference-targets.d.ts +42 -0
- package/dist-client/pages/master/reference-targets.js +82 -0
- package/dist-client/pages/master/reference-targets.js.map +1 -0
- package/dist-client/pages/master/revision-comparison.d.ts +49 -0
- package/dist-client/pages/master/revision-comparison.js +560 -0
- package/dist-client/pages/master/revision-comparison.js.map +1 -0
- package/dist-client/pages/master/revision-view.d.ts +34 -0
- package/dist-client/pages/master/revision-view.js +145 -0
- package/dist-client/pages/master/revision-view.js.map +1 -0
- package/dist-client/pages/master/revision-workspace.d.ts +50 -0
- package/dist-client/pages/master/revision-workspace.js +763 -0
- package/dist-client/pages/master/revision-workspace.js.map +1 -0
- package/dist-client/pages/master/route-definition.d.ts +19 -0
- package/dist-client/pages/master/route-definition.js +40 -0
- package/dist-client/pages/master/route-definition.js.map +1 -0
- package/dist-client/pages/master/stop-reason.d.ts +12 -0
- package/dist-client/pages/master/stop-reason.js +48 -0
- package/dist-client/pages/master/stop-reason.js.map +1 -0
- package/dist-client/pages/master/test-specification.d.ts +5 -0
- package/dist-client/pages/master/test-specification.js +14 -0
- package/dist-client/pages/master/test-specification.js.map +1 -0
- package/dist-client/pages/master-axes.d.ts +24 -0
- package/dist-client/pages/master-axes.js +39 -0
- package/dist-client/pages/master-axes.js.map +1 -0
- package/dist-client/route.d.ts +1 -0
- package/dist-client/route.js +81 -0
- package/dist-client/route.js.map +1 -0
- package/dist-client/tsconfig.tsbuildinfo +1 -0
- package/dist-server/index.d.ts +1 -0
- package/dist-server/index.js +19 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/service/ai-entry/master-entry-rules.d.ts +175 -0
- package/dist-server/service/ai-entry/master-entry-rules.js +302 -0
- package/dist-server/service/ai-entry/master-entry-rules.js.map +1 -0
- package/dist-server/service/ai-entry/master-entry-targets.d.ts +23 -0
- package/dist-server/service/ai-entry/master-entry-targets.js +293 -0
- package/dist-server/service/ai-entry/master-entry-targets.js.map +1 -0
- package/dist-server/service/approval-route.d.ts +37 -0
- package/dist-server/service/approval-route.js +34 -0
- package/dist-server/service/approval-route.js.map +1 -0
- package/dist-server/service/asset/asset-lifecycle.d.ts +106 -0
- package/dist-server/service/asset/asset-lifecycle.js +126 -0
- package/dist-server/service/asset/asset-lifecycle.js.map +1 -0
- package/dist-server/service/asset/asset-master-resolver.d.ts +53 -0
- package/dist-server/service/asset/asset-master-resolver.js +185 -0
- package/dist-server/service/asset/asset-master-resolver.js.map +1 -0
- package/dist-server/service/asset/asset-master.d.ts +21 -0
- package/dist-server/service/asset/asset-master.js +25 -0
- package/dist-server/service/asset/asset-master.js.map +1 -0
- package/dist-server/service/asset/asset-query.d.ts +16 -0
- package/dist-server/service/asset/asset-query.js +72 -0
- package/dist-server/service/asset/asset-query.js.map +1 -0
- package/dist-server/service/asset/index.d.ts +6 -0
- package/dist-server/service/asset/index.js +10 -0
- package/dist-server/service/asset/index.js.map +1 -0
- package/dist-server/service/asset/physical-asset-class.d.ts +34 -0
- package/dist-server/service/asset/physical-asset-class.js +104 -0
- package/dist-server/service/asset/physical-asset-class.js.map +1 -0
- package/dist-server/service/asset/physical-asset.d.ts +66 -0
- package/dist-server/service/asset/physical-asset.js +123 -0
- package/dist-server/service/asset/physical-asset.js.map +1 -0
- package/dist-server/service/assignment/applied-when.d.ts +24 -0
- package/dist-server/service/assignment/applied-when.js +16 -0
- package/dist-server/service/assignment/applied-when.js.map +1 -0
- package/dist-server/service/assignment/assignment-history.d.ts +92 -0
- package/dist-server/service/assignment/assignment-history.js +289 -0
- package/dist-server/service/assignment/assignment-history.js.map +1 -0
- package/dist-server/service/assignment/assignment-write.d.ts +42 -0
- package/dist-server/service/assignment/assignment-write.js +101 -0
- package/dist-server/service/assignment/assignment-write.js.map +1 -0
- package/dist-server/service/assignment/master-value-claim.d.ts +135 -0
- package/dist-server/service/assignment/master-value-claim.js +174 -0
- package/dist-server/service/assignment/master-value-claim.js.map +1 -0
- package/dist-server/service/equipment/equipment-class.d.ts +34 -0
- package/dist-server/service/equipment/equipment-class.js +104 -0
- package/dist-server/service/equipment/equipment-class.js.map +1 -0
- package/dist-server/service/equipment/equipment-master-resolver.d.ts +77 -0
- package/dist-server/service/equipment/equipment-master-resolver.js +266 -0
- package/dist-server/service/equipment/equipment-master-resolver.js.map +1 -0
- package/dist-server/service/equipment/equipment-master.d.ts +30 -0
- package/dist-server/service/equipment/equipment-master.js +53 -0
- package/dist-server/service/equipment/equipment-master.js.map +1 -0
- package/dist-server/service/equipment/equipment-query.d.ts +16 -0
- package/dist-server/service/equipment/equipment-query.js +72 -0
- package/dist-server/service/equipment/equipment-query.js.map +1 -0
- package/dist-server/service/equipment/equipment.d.ts +71 -0
- package/dist-server/service/equipment/equipment.js +138 -0
- package/dist-server/service/equipment/equipment.js.map +1 -0
- package/dist-server/service/equipment/index.d.ts +8 -0
- package/dist-server/service/equipment/index.js +12 -0
- package/dist-server/service/equipment/index.js.map +1 -0
- package/dist-server/service/equipment/state-period-rules.d.ts +95 -0
- package/dist-server/service/equipment/state-period-rules.js +122 -0
- package/dist-server/service/equipment/state-period-rules.js.map +1 -0
- package/dist-server/service/equipment/stop-reason-query.d.ts +11 -0
- package/dist-server/service/equipment/stop-reason-query.js +39 -0
- package/dist-server/service/equipment/stop-reason-query.js.map +1 -0
- package/dist-server/service/equipment/stop-reason.d.ts +58 -0
- package/dist-server/service/equipment/stop-reason.js +114 -0
- package/dist-server/service/equipment/stop-reason.js.map +1 -0
- package/dist-server/service/index.d.ts +82 -0
- package/dist-server/service/index.js +145 -0
- package/dist-server/service/index.js.map +1 -0
- package/dist-server/service/location/index.d.ts +5 -0
- package/dist-server/service/location/index.js +9 -0
- package/dist-server/service/location/index.js.map +1 -0
- package/dist-server/service/location/location-master-resolver.d.ts +60 -0
- package/dist-server/service/location/location-master-resolver.js +313 -0
- package/dist-server/service/location/location-master-resolver.js.map +1 -0
- package/dist-server/service/location/location-master.d.ts +26 -0
- package/dist-server/service/location/location-master.js +28 -0
- package/dist-server/service/location/location-master.js.map +1 -0
- package/dist-server/service/location/location-query.d.ts +15 -0
- package/dist-server/service/location/location-query.js +56 -0
- package/dist-server/service/location/location-query.js.map +1 -0
- package/dist-server/service/location/operational-location.d.ts +116 -0
- package/dist-server/service/location/operational-location.js +157 -0
- package/dist-server/service/location/operational-location.js.map +1 -0
- package/dist-server/service/master-axis.d.ts +40 -0
- package/dist-server/service/master-axis.js +57 -0
- package/dist-server/service/master-axis.js.map +1 -0
- package/dist-server/service/master-change-approval/approval-input.d.ts +17 -0
- package/dist-server/service/master-change-approval/approval-input.js +35 -0
- package/dist-server/service/master-change-approval/approval-input.js.map +1 -0
- package/dist-server/service/master-change-approval/builtin-axes.d.ts +4 -0
- package/dist-server/service/master-change-approval/builtin-axes.js +96 -0
- package/dist-server/service/master-change-approval/builtin-axes.js.map +1 -0
- package/dist-server/service/master-change-approval/index.d.ts +14 -0
- package/dist-server/service/master-change-approval/index.js +37 -0
- package/dist-server/service/master-change-approval/index.js.map +1 -0
- package/dist-server/service/master-change-approval/master-change-axis.d.ts +54 -0
- package/dist-server/service/master-change-approval/master-change-axis.js +17 -0
- package/dist-server/service/master-change-approval/master-change-axis.js.map +1 -0
- package/dist-server/service/master-change-approval/master-change-flow.d.ts +65 -0
- package/dist-server/service/master-change-approval/master-change-flow.js +125 -0
- package/dist-server/service/master-change-approval/master-change-flow.js.map +1 -0
- package/dist-server/service/master-change-approval/master-change-resolver.d.ts +18 -0
- package/dist-server/service/master-change-approval/master-change-resolver.js +58 -0
- package/dist-server/service/master-change-approval/master-change-resolver.js.map +1 -0
- package/dist-server/service/master-change-policy.d.ts +122 -0
- package/dist-server/service/master-change-policy.js +304 -0
- package/dist-server/service/master-change-policy.js.map +1 -0
- package/dist-server/service/master-conformance-resolver.d.ts +34 -0
- package/dist-server/service/master-conformance-resolver.js +153 -0
- package/dist-server/service/master-conformance-resolver.js.map +1 -0
- package/dist-server/service/master-conformance.d.ts +80 -0
- package/dist-server/service/master-conformance.js +266 -0
- package/dist-server/service/master-conformance.js.map +1 -0
- package/dist-server/service/master-crud.d.ts +55 -0
- package/dist-server/service/master-crud.js +93 -0
- package/dist-server/service/master-crud.js.map +1 -0
- package/dist-server/service/master-list.d.ts +12 -0
- package/dist-server/service/master-list.js +30 -0
- package/dist-server/service/master-list.js.map +1 -0
- package/dist-server/service/master-page-query.d.ts +33 -0
- package/dist-server/service/master-page-query.js +55 -0
- package/dist-server/service/master-page-query.js.map +1 -0
- package/dist-server/service/master-page.d.ts +85 -0
- package/dist-server/service/master-page.js +104 -0
- package/dist-server/service/master-page.js.map +1 -0
- package/dist-server/service/material/index.d.ts +7 -0
- package/dist-server/service/material/index.js +12 -0
- package/dist-server/service/material/index.js.map +1 -0
- package/dist-server/service/material/material-axis-status.d.ts +8 -0
- package/dist-server/service/material/material-axis-status.js +19 -0
- package/dist-server/service/material/material-axis-status.js.map +1 -0
- package/dist-server/service/material/material-class.d.ts +34 -0
- package/dist-server/service/material/material-class.js +104 -0
- package/dist-server/service/material/material-class.js.map +1 -0
- package/dist-server/service/material/material-definition.d.ts +45 -0
- package/dist-server/service/material/material-definition.js +125 -0
- package/dist-server/service/material/material-definition.js.map +1 -0
- package/dist-server/service/material/material-effective-list.d.ts +39 -0
- package/dist-server/service/material/material-effective-list.js +54 -0
- package/dist-server/service/material/material-effective-list.js.map +1 -0
- package/dist-server/service/material/material-master-resolver.d.ts +106 -0
- package/dist-server/service/material/material-master-resolver.js +351 -0
- package/dist-server/service/material/material-master-resolver.js.map +1 -0
- package/dist-server/service/material/material-master.d.ts +9 -0
- package/dist-server/service/material/material-master.js +24 -0
- package/dist-server/service/material/material-master.js.map +1 -0
- package/dist-server/service/material/material-query.d.ts +16 -0
- package/dist-server/service/material/material-query.js +79 -0
- package/dist-server/service/material/material-query.js.map +1 -0
- package/dist-server/service/material/material-revision-content.d.ts +10 -0
- package/dist-server/service/material/material-revision-content.js +92 -0
- package/dist-server/service/material/material-revision-content.js.map +1 -0
- package/dist-server/service/material/material-revision-resolver.d.ts +60 -0
- package/dist-server/service/material/material-revision-resolver.js +96 -0
- package/dist-server/service/material/material-revision-resolver.js.map +1 -0
- package/dist-server/service/material/material-revision-service.d.ts +179 -0
- package/dist-server/service/material/material-revision-service.js +687 -0
- package/dist-server/service/material/material-revision-service.js.map +1 -0
- package/dist-server/service/material/material-revision.d.ts +86 -0
- package/dist-server/service/material/material-revision.js +339 -0
- package/dist-server/service/material/material-revision.js.map +1 -0
- package/dist-server/service/material/recipe-index.d.ts +23 -0
- package/dist-server/service/material/recipe-index.js +44 -0
- package/dist-server/service/material/recipe-index.js.map +1 -0
- package/dist-server/service/operation/index.d.ts +6 -0
- package/dist-server/service/operation/index.js +10 -0
- package/dist-server/service/operation/index.js.map +1 -0
- package/dist-server/service/operation/operation-definition.d.ts +52 -0
- package/dist-server/service/operation/operation-definition.js +143 -0
- package/dist-server/service/operation/operation-definition.js.map +1 -0
- package/dist-server/service/operation/operation-master-resolver.d.ts +52 -0
- package/dist-server/service/operation/operation-master-resolver.js +187 -0
- package/dist-server/service/operation/operation-master-resolver.js.map +1 -0
- package/dist-server/service/operation/operation-master.d.ts +21 -0
- package/dist-server/service/operation/operation-master.js +28 -0
- package/dist-server/service/operation/operation-master.js.map +1 -0
- package/dist-server/service/operation/operation-query.d.ts +15 -0
- package/dist-server/service/operation/operation-query.js +56 -0
- package/dist-server/service/operation/operation-query.js.map +1 -0
- package/dist-server/service/operation/operation-readiness-resolver.d.ts +39 -0
- package/dist-server/service/operation/operation-readiness-resolver.js +111 -0
- package/dist-server/service/operation/operation-readiness-resolver.js.map +1 -0
- package/dist-server/service/operation/operation-readiness.d.ts +34 -0
- package/dist-server/service/operation/operation-readiness.js +133 -0
- package/dist-server/service/operation/operation-readiness.js.map +1 -0
- package/dist-server/service/personnel/index.d.ts +6 -0
- package/dist-server/service/personnel/index.js +10 -0
- package/dist-server/service/personnel/index.js.map +1 -0
- package/dist-server/service/personnel/person.d.ts +51 -0
- package/dist-server/service/personnel/person.js +119 -0
- package/dist-server/service/personnel/person.js.map +1 -0
- package/dist-server/service/personnel/personnel-class-readiness.d.ts +22 -0
- package/dist-server/service/personnel/personnel-class-readiness.js +98 -0
- package/dist-server/service/personnel/personnel-class-readiness.js.map +1 -0
- package/dist-server/service/personnel/personnel-class.d.ts +54 -0
- package/dist-server/service/personnel/personnel-class.js +114 -0
- package/dist-server/service/personnel/personnel-class.js.map +1 -0
- package/dist-server/service/personnel/personnel-master-resolver.d.ts +53 -0
- package/dist-server/service/personnel/personnel-master-resolver.js +187 -0
- package/dist-server/service/personnel/personnel-master-resolver.js.map +1 -0
- package/dist-server/service/personnel/personnel-master.d.ts +39 -0
- package/dist-server/service/personnel/personnel-master.js +34 -0
- package/dist-server/service/personnel/personnel-master.js.map +1 -0
- package/dist-server/service/personnel/personnel-query.d.ts +29 -0
- package/dist-server/service/personnel/personnel-query.js +79 -0
- package/dist-server/service/personnel/personnel-query.js.map +1 -0
- package/dist-server/service/personnel/qualification.d.ts +104 -0
- package/dist-server/service/personnel/qualification.js +147 -0
- package/dist-server/service/personnel/qualification.js.map +1 -0
- package/dist-server/service/quality/index.d.ts +4 -0
- package/dist-server/service/quality/index.js +8 -0
- package/dist-server/service/quality/index.js.map +1 -0
- package/dist-server/service/quality/nonconformance-cause-resolver.d.ts +12 -0
- package/dist-server/service/quality/nonconformance-cause-resolver.js +60 -0
- package/dist-server/service/quality/nonconformance-cause-resolver.js.map +1 -0
- package/dist-server/service/quality/nonconformance-cause.d.ts +20 -0
- package/dist-server/service/quality/nonconformance-cause.js +90 -0
- package/dist-server/service/quality/nonconformance-cause.js.map +1 -0
- package/dist-server/service/recipe/index.d.ts +10 -0
- package/dist-server/service/recipe/index.js +16 -0
- package/dist-server/service/recipe/index.js.map +1 -0
- package/dist-server/service/recipe/recipe-definition.d.ts +75 -0
- package/dist-server/service/recipe/recipe-definition.js +143 -0
- package/dist-server/service/recipe/recipe-definition.js.map +1 -0
- package/dist-server/service/recipe/recipe-effective-list.d.ts +49 -0
- package/dist-server/service/recipe/recipe-effective-list.js +96 -0
- package/dist-server/service/recipe/recipe-effective-list.js.map +1 -0
- package/dist-server/service/recipe/recipe-master-resolver.d.ts +28 -0
- package/dist-server/service/recipe/recipe-master-resolver.js +128 -0
- package/dist-server/service/recipe/recipe-master-resolver.js.map +1 -0
- package/dist-server/service/recipe/recipe-master.d.ts +37 -0
- package/dist-server/service/recipe/recipe-master.js +47 -0
- package/dist-server/service/recipe/recipe-master.js.map +1 -0
- package/dist-server/service/recipe/recipe-query.d.ts +21 -0
- package/dist-server/service/recipe/recipe-query.js +82 -0
- package/dist-server/service/recipe/recipe-query.js.map +1 -0
- package/dist-server/service/recipe/recipe-revision-content.d.ts +32 -0
- package/dist-server/service/recipe/recipe-revision-content.js +70 -0
- package/dist-server/service/recipe/recipe-revision-content.js.map +1 -0
- package/dist-server/service/recipe/recipe-revision-line.d.ts +30 -0
- package/dist-server/service/recipe/recipe-revision-line.js +95 -0
- package/dist-server/service/recipe/recipe-revision-line.js.map +1 -0
- package/dist-server/service/recipe/recipe-revision-resolver.d.ts +65 -0
- package/dist-server/service/recipe/recipe-revision-resolver.js +96 -0
- package/dist-server/service/recipe/recipe-revision-resolver.js.map +1 -0
- package/dist-server/service/recipe/recipe-revision-service.d.ts +183 -0
- package/dist-server/service/recipe/recipe-revision-service.js +754 -0
- package/dist-server/service/recipe/recipe-revision-service.js.map +1 -0
- package/dist-server/service/recipe/recipe-revision.d.ts +102 -0
- package/dist-server/service/recipe/recipe-revision.js +373 -0
- package/dist-server/service/recipe/recipe-revision.js.map +1 -0
- package/dist-server/service/recipe/route-definition.d.ts +51 -0
- package/dist-server/service/recipe/route-definition.js +114 -0
- package/dist-server/service/recipe/route-definition.js.map +1 -0
- package/dist-server/service/resource/class-lineage.d.ts +46 -0
- package/dist-server/service/resource/class-lineage.js +80 -0
- package/dist-server/service/resource/class-lineage.js.map +1 -0
- package/dist-server/service/resource/class-members.d.ts +36 -0
- package/dist-server/service/resource/class-members.js +59 -0
- package/dist-server/service/resource/class-members.js.map +1 -0
- package/dist-server/service/resource/referrers.d.ts +54 -0
- package/dist-server/service/resource/referrers.js +99 -0
- package/dist-server/service/resource/referrers.js.map +1 -0
- package/dist-server/service/resource/resource-class.d.ts +25 -0
- package/dist-server/service/resource/resource-class.js +29 -0
- package/dist-server/service/resource/resource-class.js.map +1 -0
- package/dist-server/service/revision-baseline.d.ts +71 -0
- package/dist-server/service/revision-baseline.js +87 -0
- package/dist-server/service/revision-baseline.js.map +1 -0
- package/dist-server/service/row-lock.d.ts +22 -0
- package/dist-server/service/row-lock.js +31 -0
- package/dist-server/service/row-lock.js.map +1 -0
- package/dist-server/service/status/axis-stamp.d.ts +16 -0
- package/dist-server/service/status/axis-stamp.js +22 -0
- package/dist-server/service/status/axis-stamp.js.map +1 -0
- package/dist-server/service/status/index.d.ts +3 -0
- package/dist-server/service/status/index.js +7 -0
- package/dist-server/service/status/index.js.map +1 -0
- package/dist-server/service/status/master-status.d.ts +38 -0
- package/dist-server/service/status/master-status.js +129 -0
- package/dist-server/service/status/master-status.js.map +1 -0
- package/dist-server/service/test-spec/criteria-check.d.ts +53 -0
- package/dist-server/service/test-spec/criteria-check.js +142 -0
- package/dist-server/service/test-spec/criteria-check.js.map +1 -0
- package/dist-server/service/test-spec/criteria-rows.d.ts +89 -0
- package/dist-server/service/test-spec/criteria-rows.js +139 -0
- package/dist-server/service/test-spec/criteria-rows.js.map +1 -0
- package/dist-server/service/test-spec/index.d.ts +6 -0
- package/dist-server/service/test-spec/index.js +11 -0
- package/dist-server/service/test-spec/index.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-effective-list.d.ts +34 -0
- package/dist-server/service/test-spec/test-spec-effective-list.js +42 -0
- package/dist-server/service/test-spec/test-spec-effective-list.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-master-resolver.d.ts +44 -0
- package/dist-server/service/test-spec/test-spec-master-resolver.js +144 -0
- package/dist-server/service/test-spec/test-spec-master-resolver.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-master.d.ts +6 -0
- package/dist-server/service/test-spec/test-spec-master.js +18 -0
- package/dist-server/service/test-spec/test-spec-master.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-query.d.ts +15 -0
- package/dist-server/service/test-spec/test-spec-query.js +61 -0
- package/dist-server/service/test-spec/test-spec-query.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-revision-resolver.d.ts +59 -0
- package/dist-server/service/test-spec/test-spec-revision-resolver.js +96 -0
- package/dist-server/service/test-spec/test-spec-revision-resolver.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-revision-service.d.ts +178 -0
- package/dist-server/service/test-spec/test-spec-revision-service.js +685 -0
- package/dist-server/service/test-spec/test-spec-revision-service.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-revision.d.ts +86 -0
- package/dist-server/service/test-spec/test-spec-revision.js +334 -0
- package/dist-server/service/test-spec/test-spec-revision.js.map +1 -0
- package/dist-server/service/test-spec/test-specification.d.ts +47 -0
- package/dist-server/service/test-spec/test-specification.js +119 -0
- package/dist-server/service/test-spec/test-specification.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RecipeDefinition = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const typeorm_1 = require("typeorm");
|
|
6
|
+
const type_graphql_1 = require("type-graphql");
|
|
7
|
+
const shell_1 = require("@things-factory/shell");
|
|
8
|
+
const auth_base_1 = require("@things-factory/auth-base");
|
|
9
|
+
/**
|
|
10
|
+
* 레시피 — **무엇으로 무엇을 만드나**. 커널 `RecipeDef` 와 같은 모양이다.
|
|
11
|
+
*
|
|
12
|
+
* ── 이 자리가 답하는 것 ──────────────────────────────────────────────────
|
|
13
|
+
* 「이 품목은 무엇으로 만드나」와 「이 품목을 만드는 것은 어느 레시피인가」다. 둘째가 MES 가 물어야 했던
|
|
14
|
+
* 것인데 물을 곳이 없었다.
|
|
15
|
+
*
|
|
16
|
+
* ── 품목에 지시서를 달지 않는 이유 ───────────────────────────────────────
|
|
17
|
+
* ISA-95 에는 자재 명세가 붙는 자리가 둘이고 뜻이 다르다(§`RecipePart.operation`).
|
|
18
|
+
*
|
|
19
|
+
* · `ProcessSegment` — 그 자리가 **할 수 있는 일**. 품목에 매이지 않는다 → `OperationDefinition`
|
|
20
|
+
* · `OperationsSegment` — 그 **품목을 만드는 절차**의 한 단계. 품목에 매인다 → **레시피가 그 범위다**
|
|
21
|
+
*
|
|
22
|
+
* 그래서 품목→지시서를 이으려면 그 사이에 레시피가 있어야 한다. 공정에 품목을 붙이면 범주 오류이고,
|
|
23
|
+
* 실 데이터가 그 크기를 보였다 — 「배합」에 품목별 BOM 을 붙이면 배합을 지나는 **모든** 로트가 자재
|
|
24
|
+
* 631종 36톤을 먹는다.
|
|
25
|
+
*
|
|
26
|
+
* ── 같은 품목에 레시피가 둘일 수 있다 ────────────────────────────────────
|
|
27
|
+
* 대체 레시피가 정상이다(첫 실 연동에서 라우팅이 둘 이상인 레시피가 306/471). 그래서 **품목이 레시피를
|
|
28
|
+
* 가리키지 않고 레시피가 품목을 가리킨다** — 품목은 하나를 고를 수 없다.
|
|
29
|
+
*/
|
|
30
|
+
let RecipeDefinition = class RecipeDefinition {
|
|
31
|
+
};
|
|
32
|
+
exports.RecipeDefinition = RecipeDefinition;
|
|
33
|
+
tslib_1.__decorate([
|
|
34
|
+
(0, type_graphql_1.Field)(() => type_graphql_1.Int, { nullable: true }),
|
|
35
|
+
tslib_1.__metadata("design:type", Number)
|
|
36
|
+
], RecipeDefinition.prototype, "revisionNumber", void 0);
|
|
37
|
+
tslib_1.__decorate([
|
|
38
|
+
(0, typeorm_1.Column)('int', { default: 0 }),
|
|
39
|
+
tslib_1.__metadata("design:type", Number)
|
|
40
|
+
], RecipeDefinition.prototype, "planGeneration", void 0);
|
|
41
|
+
tslib_1.__decorate([
|
|
42
|
+
(0, typeorm_1.Column)('int', { default: 0 }),
|
|
43
|
+
tslib_1.__metadata("design:type", Number)
|
|
44
|
+
], RecipeDefinition.prototype, "revisionLock", void 0);
|
|
45
|
+
tslib_1.__decorate([
|
|
46
|
+
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
|
47
|
+
(0, type_graphql_1.Field)(type => type_graphql_1.ID),
|
|
48
|
+
tslib_1.__metadata("design:type", String)
|
|
49
|
+
], RecipeDefinition.prototype, "id", void 0);
|
|
50
|
+
tslib_1.__decorate([
|
|
51
|
+
(0, typeorm_1.ManyToOne)(type => shell_1.Domain),
|
|
52
|
+
(0, type_graphql_1.Field)(type => shell_1.Domain),
|
|
53
|
+
tslib_1.__metadata("design:type", shell_1.Domain)
|
|
54
|
+
], RecipeDefinition.prototype, "domain", void 0);
|
|
55
|
+
tslib_1.__decorate([
|
|
56
|
+
(0, typeorm_1.RelationId)((recipe) => recipe.domain),
|
|
57
|
+
tslib_1.__metadata("design:type", String)
|
|
58
|
+
], RecipeDefinition.prototype, "domainId", void 0);
|
|
59
|
+
tslib_1.__decorate([
|
|
60
|
+
(0, typeorm_1.Column)(),
|
|
61
|
+
(0, type_graphql_1.Field)(),
|
|
62
|
+
tslib_1.__metadata("design:type", String)
|
|
63
|
+
], RecipeDefinition.prototype, "name", void 0);
|
|
64
|
+
tslib_1.__decorate([
|
|
65
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
66
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
67
|
+
tslib_1.__metadata("design:type", String)
|
|
68
|
+
], RecipeDefinition.prototype, "description", void 0);
|
|
69
|
+
tslib_1.__decorate([
|
|
70
|
+
(0, typeorm_1.Column)(),
|
|
71
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
72
|
+
tslib_1.__metadata("design:type", String)
|
|
73
|
+
], RecipeDefinition.prototype, "materialDefinitionName", void 0);
|
|
74
|
+
tslib_1.__decorate([
|
|
75
|
+
(0, typeorm_1.Column)({ type: 'simple-json' }),
|
|
76
|
+
(0, type_graphql_1.Field)(type => shell_1.ScalarObject, { description: 'RecipePart[] — material · qty · operation?' }),
|
|
77
|
+
tslib_1.__metadata("design:type", Array)
|
|
78
|
+
], RecipeDefinition.prototype, "inputs", void 0);
|
|
79
|
+
tslib_1.__decorate([
|
|
80
|
+
(0, typeorm_1.Column)({ type: 'simple-json' }),
|
|
81
|
+
(0, type_graphql_1.Field)(type => shell_1.ScalarObject, { description: 'RecipePart[]' }),
|
|
82
|
+
tslib_1.__metadata("design:type", Array)
|
|
83
|
+
], RecipeDefinition.prototype, "outputs", void 0);
|
|
84
|
+
tslib_1.__decorate([
|
|
85
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
86
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
87
|
+
tslib_1.__metadata("design:type", String)
|
|
88
|
+
], RecipeDefinition.prototype, "route", void 0);
|
|
89
|
+
tslib_1.__decorate([
|
|
90
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
91
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
92
|
+
tslib_1.__metadata("design:type", Date
|
|
93
|
+
/**
|
|
94
|
+
* 언제까지 유효한가 — 표준 `EffectiveEndDate`.
|
|
95
|
+
*
|
|
96
|
+
* **개정할 때 행을 고치지 않고 이 칸을 채우고 새 행을 세운다.** 고치면 그 레시피로 만든 지난 실적이
|
|
97
|
+
* 어느 배합으로 만든 것인지 잃는다.
|
|
98
|
+
*/
|
|
99
|
+
)
|
|
100
|
+
], RecipeDefinition.prototype, "effectiveStart", void 0);
|
|
101
|
+
tslib_1.__decorate([
|
|
102
|
+
(0, typeorm_1.Column)({ nullable: true }),
|
|
103
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
104
|
+
tslib_1.__metadata("design:type", Date)
|
|
105
|
+
], RecipeDefinition.prototype, "effectiveEnd", void 0);
|
|
106
|
+
tslib_1.__decorate([
|
|
107
|
+
(0, typeorm_1.CreateDateColumn)(),
|
|
108
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
109
|
+
tslib_1.__metadata("design:type", Date)
|
|
110
|
+
], RecipeDefinition.prototype, "createdAt", void 0);
|
|
111
|
+
tslib_1.__decorate([
|
|
112
|
+
(0, typeorm_1.UpdateDateColumn)(),
|
|
113
|
+
(0, type_graphql_1.Field)({ nullable: true }),
|
|
114
|
+
tslib_1.__metadata("design:type", Date)
|
|
115
|
+
], RecipeDefinition.prototype, "updatedAt", void 0);
|
|
116
|
+
tslib_1.__decorate([
|
|
117
|
+
(0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
|
|
118
|
+
(0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true }),
|
|
119
|
+
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
120
|
+
], RecipeDefinition.prototype, "creator", void 0);
|
|
121
|
+
tslib_1.__decorate([
|
|
122
|
+
(0, typeorm_1.RelationId)((recipe) => recipe.creator),
|
|
123
|
+
tslib_1.__metadata("design:type", String)
|
|
124
|
+
], RecipeDefinition.prototype, "creatorId", void 0);
|
|
125
|
+
tslib_1.__decorate([
|
|
126
|
+
(0, typeorm_1.ManyToOne)(type => auth_base_1.User, { nullable: true }),
|
|
127
|
+
(0, type_graphql_1.Field)(type => auth_base_1.User, { nullable: true }),
|
|
128
|
+
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
129
|
+
], RecipeDefinition.prototype, "updater", void 0);
|
|
130
|
+
tslib_1.__decorate([
|
|
131
|
+
(0, typeorm_1.RelationId)((recipe) => recipe.updater),
|
|
132
|
+
tslib_1.__metadata("design:type", String)
|
|
133
|
+
], RecipeDefinition.prototype, "updaterId", void 0);
|
|
134
|
+
exports.RecipeDefinition = RecipeDefinition = tslib_1.__decorate([
|
|
135
|
+
(0, typeorm_1.Entity)({ name: 'ops_recipe_definition' }),
|
|
136
|
+
(0, typeorm_1.Index)('ix_ops_recipe_domain_identity', ['domain', 'id'], { unique: true }),
|
|
137
|
+
(0, typeorm_1.Index)('ix_ops_recipe_definition_0', (recipe) => [recipe.domain, recipe.name], { unique: true })
|
|
138
|
+
/* 「이 품목을 만드는 레시피」로 묻는 질의가 이 축으로 온다 — MES 가 지시를 받을 때마다 부른다. */
|
|
139
|
+
,
|
|
140
|
+
(0, typeorm_1.Index)('ix_ops_recipe_definition_1', (recipe) => [recipe.domain, recipe.materialDefinitionName]),
|
|
141
|
+
(0, type_graphql_1.ObjectType)({ description: 'Recipe — what a material is made of and through which route (kernel RecipeDef).' })
|
|
142
|
+
], RecipeDefinition);
|
|
143
|
+
//# sourceMappingURL=recipe-definition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe-definition.js","sourceRoot":"","sources":["../../../server/service/recipe/recipe-definition.ts"],"names":[],"mappings":"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","sourcesContent":["import { Column, CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, RelationId, UpdateDateColumn } from 'typeorm'\nimport { Field, ID, Int, ObjectType } from 'type-graphql'\n\nimport { Domain, ScalarObject } from '@things-factory/shell'\nimport { User } from '@things-factory/auth-base'\n\n/**\n * 레시피 — **무엇으로 무엇을 만드나**. 커널 `RecipeDef` 와 같은 모양이다.\n *\n * ── 이 자리가 답하는 것 ──────────────────────────────────────────────────\n * 「이 품목은 무엇으로 만드나」와 「이 품목을 만드는 것은 어느 레시피인가」다. 둘째가 MES 가 물어야 했던\n * 것인데 물을 곳이 없었다.\n *\n * ── 품목에 지시서를 달지 않는 이유 ───────────────────────────────────────\n * ISA-95 에는 자재 명세가 붙는 자리가 둘이고 뜻이 다르다(§`RecipePart.operation`).\n *\n * · `ProcessSegment` — 그 자리가 **할 수 있는 일**. 품목에 매이지 않는다 → `OperationDefinition`\n * · `OperationsSegment` — 그 **품목을 만드는 절차**의 한 단계. 품목에 매인다 → **레시피가 그 범위다**\n *\n * 그래서 품목→지시서를 이으려면 그 사이에 레시피가 있어야 한다. 공정에 품목을 붙이면 범주 오류이고,\n * 실 데이터가 그 크기를 보였다 — 「배합」에 품목별 BOM 을 붙이면 배합을 지나는 **모든** 로트가 자재\n * 631종 36톤을 먹는다.\n *\n * ── 같은 품목에 레시피가 둘일 수 있다 ────────────────────────────────────\n * 대체 레시피가 정상이다(첫 실 연동에서 라우팅이 둘 이상인 레시피가 306/471). 그래서 **품목이 레시피를\n * 가리키지 않고 레시피가 품목을 가리킨다** — 품목은 하나를 고를 수 없다.\n */\n@Entity({ name: 'ops_recipe_definition' })\n@Index('ix_ops_recipe_domain_identity', ['domain', 'id'], { unique: true })\n@Index('ix_ops_recipe_definition_0', (recipe: RecipeDefinition) => [recipe.domain, recipe.name], { unique: true })\n/* 「이 품목을 만드는 레시피」로 묻는 질의가 이 축으로 온다 — MES 가 지시를 받을 때마다 부른다. */\n@Index('ix_ops_recipe_definition_1', (recipe: RecipeDefinition) => [recipe.domain, recipe.materialDefinitionName])\n@ObjectType({ description: 'Recipe — what a material is made of and through which route (kernel RecipeDef).' })\nexport class RecipeDefinition {\n /** Read projection of the effective revision, not a mutable identity column. */\n @Field(() => Int, { nullable: true })\n revisionNumber?: number\n @Column('int', { default: 0 }) planGeneration: number\n @Column('int', { default: 0 }) revisionLock: number\n @PrimaryGeneratedColumn('uuid')\n @Field(type => ID)\n readonly id: string\n\n @ManyToOne(type => Domain)\n @Field(type => Domain)\n domain?: Domain\n\n @RelationId((recipe: RecipeDefinition) => recipe.domain)\n domainId?: string\n\n /** 레시피 키 — 오더의 `recipeKey` 가 이 값을 가리킨다(커널 `RecipeDef.key`). */\n @Column()\n @Field()\n name: string\n\n @Column({ nullable: true })\n @Field({ nullable: true })\n description?: string\n\n /**\n * **무엇을 만드나** — `MaterialDefinition.name`.\n *\n * `outputs` 안에도 있지만 이 칸을 따로 둔다. 「이 품목을 만드는 레시피」를 JSON 안을 뒤져 찾으면\n * 다섯 드라이버에서 색인이 서지 않고, 그 질의는 MES 가 지시를 받을 때마다 부른다.\n *\n * 산출이 여럿인 레시피(부산물)에서는 **주 산출**을 적는다. 나머지는 `outputs` 가 든다.\n */\n @Column()\n @Field({ nullable: true })\n materialDefinitionName: string\n\n /**\n * 투입 — 커널 `RecipePart[]`(`material` · `qty` · `operation?`).\n *\n * `operation` 은 **이 투입이 들어가는 공정**이다. 없으면 오더 착수에 확보한다. 그 태그가 여기 있는\n * 이유는 품목별 소요가 사는 자리가 레시피이기 때문이다.\n */\n @Column({ type: 'simple-json' })\n @Field(type => ScalarObject, { description: 'RecipePart[] — material · qty · operation?' })\n inputs: Record<string, unknown>[]\n\n /** 산출 — 커널 `RecipePart[]`. 부산물이 있으면 여기 함께 든다. */\n @Column({ type: 'simple-json' })\n @Field(type => ScalarObject, { description: 'RecipePart[]' })\n outputs: Record<string, unknown>[]\n\n /**\n * 이 산출물을 만드는 공정 라우팅 — `RouteDefinition.name`(커널 `RecipeDef.route`).\n *\n * 순서는 라우팅이 소유하고 레시피는 그것을 가리킨다. 레시피에 단계 목록을 또 두면 두 목록이 어긋날 수\n * 있고, 어긋났을 때 어느 쪽이 맞는지 말할 근거가 없다.\n */\n @Column({ nullable: true })\n @Field({ nullable: true })\n route?: string\n\n /** 언제부터 유효한가 — 표준 `EffectiveStartDate`. */\n @Column({ nullable: true })\n @Field({ nullable: true })\n effectiveStart?: Date\n\n /**\n * 언제까지 유효한가 — 표준 `EffectiveEndDate`.\n *\n * **개정할 때 행을 고치지 않고 이 칸을 채우고 새 행을 세운다.** 고치면 그 레시피로 만든 지난 실적이\n * 어느 배합으로 만든 것인지 잃는다.\n */\n @Column({ nullable: true })\n @Field({ nullable: true })\n effectiveEnd?: Date\n\n @CreateDateColumn()\n @Field({ nullable: true })\n createdAt?: Date\n\n @UpdateDateColumn()\n @Field({ nullable: true })\n updatedAt?: Date\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n creator?: User\n\n @RelationId((recipe: RecipeDefinition) => recipe.creator)\n creatorId?: string\n\n @ManyToOne(type => User, { nullable: true })\n @Field(type => User, { nullable: true })\n updater?: User\n\n @RelationId((recipe: RecipeDefinition) => recipe.updater)\n updaterId?: string\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { EntityManager } from 'typeorm';
|
|
2
|
+
import { Domain, ListParam } from '@things-factory/shell';
|
|
3
|
+
import { RecipeDefinition } from './recipe-definition';
|
|
4
|
+
/** Filter, sort, paginate and display the same time projection. No per-row resolution queries. */
|
|
5
|
+
export declare function listEffectiveRecipes(manager: EntityManager, domain: Domain, params: ListParam, at?: Date): Promise<{
|
|
6
|
+
items: (RecipeDefinition & {
|
|
7
|
+
revisionNumber?: number;
|
|
8
|
+
planGeneration: number;
|
|
9
|
+
revisionLock: number;
|
|
10
|
+
id: string;
|
|
11
|
+
domain?: Domain;
|
|
12
|
+
domainId?: string;
|
|
13
|
+
name: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
materialDefinitionName: string;
|
|
16
|
+
inputs: Record<string, unknown>[];
|
|
17
|
+
outputs: Record<string, unknown>[];
|
|
18
|
+
route?: string;
|
|
19
|
+
effectiveStart?: Date;
|
|
20
|
+
effectiveEnd?: Date;
|
|
21
|
+
createdAt?: Date;
|
|
22
|
+
updatedAt?: Date;
|
|
23
|
+
creator?: import("@things-factory/auth-base").User;
|
|
24
|
+
creatorId?: string;
|
|
25
|
+
updater?: import("@things-factory/auth-base").User;
|
|
26
|
+
updaterId?: string;
|
|
27
|
+
} & {
|
|
28
|
+
description: string;
|
|
29
|
+
revisionNumber: number;
|
|
30
|
+
materialDefinitionName: string;
|
|
31
|
+
route: string;
|
|
32
|
+
inputs: Record<string, unknown>[];
|
|
33
|
+
outputs: Record<string, unknown>[];
|
|
34
|
+
effectiveStart: Date;
|
|
35
|
+
effectiveEnd: Date;
|
|
36
|
+
})[];
|
|
37
|
+
total: number;
|
|
38
|
+
}>;
|
|
39
|
+
/** Candidate selection retains future/expired declarations so callers can explain why a choice is unavailable.
|
|
40
|
+
* One joined read; no per-order or per-recipe resolution queries. Payload rows are not loaded here.
|
|
41
|
+
*/
|
|
42
|
+
export declare function recipeChoicesAt(manager: EntityManager, domainId: string, materialNames: string[], at?: Date): Promise<{
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
materialDefinitionName: string;
|
|
46
|
+
route: string | undefined;
|
|
47
|
+
effectiveStart: Date;
|
|
48
|
+
effectiveEnd: Date | undefined;
|
|
49
|
+
}[]>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listEffectiveRecipes = listEffectiveRecipes;
|
|
4
|
+
exports.recipeChoicesAt = recipeChoicesAt;
|
|
5
|
+
const typeorm_1 = require("typeorm");
|
|
6
|
+
const shell_1 = require("@things-factory/shell");
|
|
7
|
+
const recipe_definition_1 = require("./recipe-definition");
|
|
8
|
+
const recipe_revision_1 = require("./recipe-revision");
|
|
9
|
+
const recipe_revision_line_1 = require("./recipe-revision-line");
|
|
10
|
+
/** Filter, sort, paginate and display the same time projection. No per-row resolution queries. */
|
|
11
|
+
async function listEffectiveRecipes(manager, domain, params, at = new Date()) {
|
|
12
|
+
const query = (0, shell_1.getQueryBuilderFromListParams)({
|
|
13
|
+
repository: manager.getRepository(recipe_definition_1.RecipeDefinition),
|
|
14
|
+
domain,
|
|
15
|
+
params,
|
|
16
|
+
alias: 'recipe',
|
|
17
|
+
searchables: ['name', 'description'],
|
|
18
|
+
sortables: ['id', 'name', 'revisionNumber', 'description', 'effectiveStart', 'effectiveEnd', 'createdAt', 'updatedAt'],
|
|
19
|
+
columnExpressions: {
|
|
20
|
+
revisionNumber: 'revision.revisionNumber',
|
|
21
|
+
description: 'revision.description',
|
|
22
|
+
materialDefinitionName: 'revision.materialDefinitionName',
|
|
23
|
+
route: 'revision.route',
|
|
24
|
+
effectiveStart: 'segment.validFrom',
|
|
25
|
+
effectiveEnd: 'segment.validTo'
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
query
|
|
29
|
+
.leftJoin(recipe_revision_1.RecipePlan, 'plan', 'plan.recipe_id = recipe.id AND plan.domain_id = recipe.domain_id AND plan.generation = recipe.plan_generation')
|
|
30
|
+
.leftJoinAndMapOne('recipe.selectedSegment', recipe_revision_1.RecipeSegment, 'segment', 'segment.plan_id = plan.id AND segment.validFrom <= :at AND (segment.validTo IS NULL OR segment.validTo > :at)', { at })
|
|
31
|
+
.leftJoinAndMapOne('recipe.selectedRevision', recipe_revision_1.RecipeRevision, 'revision', 'revision.id = segment.revision_id');
|
|
32
|
+
const [rows, total] = await query.getManyAndCount();
|
|
33
|
+
const revisionIds = rows.flatMap(row => row.selectedRevision ? [row.selectedRevision.id] : []);
|
|
34
|
+
const [inputs, outputs] = revisionIds.length ? await Promise.all([
|
|
35
|
+
manager.find(recipe_revision_line_1.RecipeRevisionInput, { where: { domain: { id: domain.id }, revision: { id: (0, typeorm_1.In)(revisionIds) } }, order: { position: 'ASC' } }),
|
|
36
|
+
manager.find(recipe_revision_line_1.RecipeRevisionOutput, { where: { domain: { id: domain.id }, revision: { id: (0, typeorm_1.In)(revisionIds) } }, order: { position: 'ASC' } })
|
|
37
|
+
]) : [[], []];
|
|
38
|
+
const group = (lines) => {
|
|
39
|
+
const result = new Map();
|
|
40
|
+
for (const line of lines) {
|
|
41
|
+
const bucket = result.get(line.revisionId) ?? [];
|
|
42
|
+
bucket.push({ lineKey: line.lineKey, material: line.material, qty: line.qty,
|
|
43
|
+
...('operation' in line && line.operation ? { operation: line.operation } : {}) });
|
|
44
|
+
result.set(line.revisionId, bucket);
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
const inputsByRevision = group(inputs), outputsByRevision = group(outputs);
|
|
49
|
+
const items = rows.map(row => {
|
|
50
|
+
const { selectedRevision, selectedSegment, ...identity } = row;
|
|
51
|
+
return Object.assign(new recipe_definition_1.RecipeDefinition(), identity, {
|
|
52
|
+
description: selectedRevision?.description ?? null,
|
|
53
|
+
revisionNumber: selectedRevision?.revisionNumber ?? null,
|
|
54
|
+
materialDefinitionName: selectedRevision?.materialDefinitionName ?? null,
|
|
55
|
+
route: selectedRevision?.route ?? null,
|
|
56
|
+
inputs: inputsByRevision.get(selectedRevision?.id) ?? [],
|
|
57
|
+
outputs: outputsByRevision.get(selectedRevision?.id) ?? [],
|
|
58
|
+
effectiveStart: selectedSegment?.validFrom ?? null,
|
|
59
|
+
effectiveEnd: selectedSegment?.validTo ?? null
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
return { items, total };
|
|
63
|
+
}
|
|
64
|
+
/** Candidate selection retains future/expired declarations so callers can explain why a choice is unavailable.
|
|
65
|
+
* One joined read; no per-order or per-recipe resolution queries. Payload rows are not loaded here.
|
|
66
|
+
*/
|
|
67
|
+
async function recipeChoicesAt(manager, domainId, materialNames, at = new Date()) {
|
|
68
|
+
if (!materialNames.length)
|
|
69
|
+
return [];
|
|
70
|
+
const rows = await manager.createQueryBuilder(recipe_definition_1.RecipeDefinition, 'recipe')
|
|
71
|
+
.innerJoin(recipe_revision_1.RecipePlan, 'plan', 'plan.recipe_id = recipe.id AND plan.domain_id = recipe.domain_id AND plan.generation = recipe.plan_generation')
|
|
72
|
+
.innerJoin(recipe_revision_1.RecipeSegment, 'segment', 'segment.plan_id = plan.id')
|
|
73
|
+
.innerJoin(recipe_revision_1.RecipeRevision, 'revision', 'revision.id = segment.revision_id')
|
|
74
|
+
.where('recipe.domain_id = :domainId', { domainId })
|
|
75
|
+
.select('recipe.id', 'id').addSelect('recipe.name', 'name')
|
|
76
|
+
.addSelect('revision.materialDefinitionName', 'materialDefinitionName').addSelect('revision.route', 'route')
|
|
77
|
+
.addSelect('segment.validFrom', 'validFrom').addSelect('segment.validTo', 'validTo')
|
|
78
|
+
.getRawMany();
|
|
79
|
+
const byRecipe = new Map();
|
|
80
|
+
for (const row of rows) {
|
|
81
|
+
// Driver raw dates may be SQLite's UTC "YYYY-MM-DD HH:mm:ss.sss" representation.
|
|
82
|
+
const date = (value) => value instanceof Date ? value : new Date(/(?:Z|[+-]\d\d:\d\d)$/.test(value) ? value : value.replace(' ', 'T') + 'Z');
|
|
83
|
+
row.effectiveStart = date(row.validFrom);
|
|
84
|
+
row.effectiveEnd = row.validTo ? date(row.validTo) : undefined;
|
|
85
|
+
const group = byRecipe.get(row.id) ?? [];
|
|
86
|
+
group.push(row);
|
|
87
|
+
byRecipe.set(row.id, group);
|
|
88
|
+
}
|
|
89
|
+
const rank = (row) => row.effectiveStart > at ? 1 : row.effectiveEnd && row.effectiveEnd <= at ? 2 : 0;
|
|
90
|
+
return [...byRecipe.values()].map(group => group.sort((a, b) => rank(a) - rank(b) ||
|
|
91
|
+
(rank(a) === 1 ? a.effectiveStart - b.effectiveStart : b.effectiveStart - a.effectiveStart))[0])
|
|
92
|
+
.filter(row => materialNames.includes(row.materialDefinitionName))
|
|
93
|
+
.map(row => ({ id: row.id, name: row.name, materialDefinitionName: row.materialDefinitionName,
|
|
94
|
+
route: row.route, effectiveStart: row.effectiveStart, effectiveEnd: row.effectiveEnd }));
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=recipe-effective-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe-effective-list.js","sourceRoot":"","sources":["../../../server/service/recipe/recipe-effective-list.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager, In } from 'typeorm'\nimport { Domain, getQueryBuilderFromListParams, ListParam } from '@things-factory/shell'\nimport { RecipeDefinition } from './recipe-definition'\nimport { RecipePlan, RecipeRevision, RecipeSegment } from './recipe-revision'\n\nimport { RecipeRevisionInput, RecipeRevisionOutput } from './recipe-revision-line'\n\ntype EffectiveRow = RecipeDefinition & {\n selectedRevision?: RecipeRevision\n selectedSegment?: RecipeSegment\n}\n\n/** Filter, sort, paginate and display the same time projection. No per-row resolution queries. */\nexport async function listEffectiveRecipes(\n manager: EntityManager,\n domain: Domain,\n params: ListParam,\n at = new Date()\n) {\n const query = getQueryBuilderFromListParams({\n repository: manager.getRepository(RecipeDefinition),\n domain,\n params,\n alias: 'recipe',\n searchables: ['name', 'description'],\n sortables: ['id', 'name', 'revisionNumber', 'description', 'effectiveStart', 'effectiveEnd', 'createdAt', 'updatedAt'],\n columnExpressions: {\n revisionNumber: 'revision.revisionNumber',\n description: 'revision.description',\n materialDefinitionName: 'revision.materialDefinitionName',\n route: 'revision.route',\n effectiveStart: 'segment.validFrom',\n effectiveEnd: 'segment.validTo'\n }\n })\n query\n .leftJoin(\n RecipePlan,\n 'plan',\n 'plan.recipe_id = recipe.id AND plan.domain_id = recipe.domain_id AND plan.generation = recipe.plan_generation'\n )\n .leftJoinAndMapOne(\n 'recipe.selectedSegment',\n RecipeSegment,\n 'segment',\n 'segment.plan_id = plan.id AND segment.validFrom <= :at AND (segment.validTo IS NULL OR segment.validTo > :at)',\n { at }\n )\n .leftJoinAndMapOne(\n 'recipe.selectedRevision',\n RecipeRevision,\n 'revision',\n 'revision.id = segment.revision_id'\n )\n const [rows, total] = await query.getManyAndCount()\n const revisionIds = (rows as EffectiveRow[]).flatMap(row => row.selectedRevision ? [row.selectedRevision.id] : [])\n const [inputs, outputs] = revisionIds.length ? await Promise.all([\n manager.find(RecipeRevisionInput, { where: { domain: { id: domain.id }, revision: { id: In(revisionIds) } }, order: { position: 'ASC' } }),\n manager.find(RecipeRevisionOutput, { where: { domain: { id: domain.id }, revision: { id: In(revisionIds) } }, order: { position: 'ASC' } })\n ]) : [[], []]\n const group = (lines: (RecipeRevisionInput | RecipeRevisionOutput)[]) => {\n const result = new Map<string, Record<string, unknown>[]>()\n for (const line of lines) {\n const bucket = result.get(line.revisionId) ?? []\n bucket.push({ lineKey: line.lineKey, material: line.material, qty: line.qty,\n ...('operation' in line && line.operation ? { operation: line.operation } : {}) })\n result.set(line.revisionId, bucket)\n }\n return result\n }\n const inputsByRevision = group(inputs), outputsByRevision = group(outputs)\n const items = (rows as EffectiveRow[]).map(row => {\n const { selectedRevision, selectedSegment, ...identity } = row\n return Object.assign(new RecipeDefinition(), identity, {\n description: selectedRevision?.description ?? null,\n revisionNumber: selectedRevision?.revisionNumber ?? null,\n materialDefinitionName: selectedRevision?.materialDefinitionName ?? null,\n route: selectedRevision?.route ?? null,\n inputs: inputsByRevision.get(selectedRevision?.id) ?? [],\n outputs: outputsByRevision.get(selectedRevision?.id) ?? [],\n effectiveStart: selectedSegment?.validFrom ?? null,\n effectiveEnd: selectedSegment?.validTo ?? null\n })\n })\n return { items, total }\n}\n\n/** Candidate selection retains future/expired declarations so callers can explain why a choice is unavailable.\n * One joined read; no per-order or per-recipe resolution queries. Payload rows are not loaded here.\n */\nexport async function recipeChoicesAt(manager: EntityManager, domainId: string, materialNames: string[], at = new Date()) {\n if (!materialNames.length) return []\n const rows = await manager.createQueryBuilder(RecipeDefinition, 'recipe')\n .innerJoin(RecipePlan, 'plan', 'plan.recipe_id = recipe.id AND plan.domain_id = recipe.domain_id AND plan.generation = recipe.plan_generation')\n .innerJoin(RecipeSegment, 'segment', 'segment.plan_id = plan.id')\n .innerJoin(RecipeRevision, 'revision', 'revision.id = segment.revision_id')\n .where('recipe.domain_id = :domainId', { domainId })\n .select('recipe.id', 'id').addSelect('recipe.name', 'name')\n .addSelect('revision.materialDefinitionName', 'materialDefinitionName').addSelect('revision.route', 'route')\n .addSelect('segment.validFrom', 'validFrom').addSelect('segment.validTo', 'validTo')\n .getRawMany()\n const byRecipe = new Map<string, typeof rows>()\n for (const row of rows) {\n // Driver raw dates may be SQLite's UTC \"YYYY-MM-DD HH:mm:ss.sss\" representation.\n const date = (value: string | Date) => value instanceof Date ? value : new Date(/(?:Z|[+-]\\d\\d:\\d\\d)$/.test(value) ? value : value.replace(' ', 'T') + 'Z')\n row.effectiveStart = date(row.validFrom)\n row.effectiveEnd = row.validTo ? date(row.validTo) : undefined\n const group = byRecipe.get(row.id) ?? []\n group.push(row); byRecipe.set(row.id, group)\n }\n const rank = (row: any) => row.effectiveStart > at ? 1 : row.effectiveEnd && row.effectiveEnd <= at ? 2 : 0\n return [...byRecipe.values()].map(group => group.sort((a,b) => rank(a)-rank(b) ||\n (rank(a) === 1 ? a.effectiveStart-b.effectiveStart : b.effectiveStart-a.effectiveStart))[0])\n .filter(row => materialNames.includes(row.materialDefinitionName))\n .map(row => ({ id: row.id as string, name: row.name as string, materialDefinitionName: row.materialDefinitionName as string,\n route: row.route as string | undefined, effectiveStart: row.effectiveStart as Date, effectiveEnd: row.effectiveEnd as Date | undefined }))\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ListParam } from '@things-factory/shell';
|
|
2
|
+
import { MasterPatch } from '../master-crud';
|
|
3
|
+
import { RecipeDefinition } from './recipe-definition';
|
|
4
|
+
import { RouteDefinition } from './route-definition';
|
|
5
|
+
/**
|
|
6
|
+
* 레시피·라우팅 축을 채우고 고친다.
|
|
7
|
+
*
|
|
8
|
+
* 규칙은 `master-crud.ts` 한 곳에 있다. 여기는 축의 이름만 붙인다 — 다른 열셋과 같은 모양이다.
|
|
9
|
+
*
|
|
10
|
+
* **개정할 때 행을 고치지 않고 유효 기간의 끝을 채운다.** 고치면 그 레시피로 만든 지난 실적이 어느
|
|
11
|
+
* 배합으로 만든 것인지 잃는다.
|
|
12
|
+
*/
|
|
13
|
+
export declare class RecipeDefinitionList {
|
|
14
|
+
items: RecipeDefinition[];
|
|
15
|
+
total: number;
|
|
16
|
+
}
|
|
17
|
+
export declare class RouteDefinitionList {
|
|
18
|
+
items: RouteDefinition[];
|
|
19
|
+
total: number;
|
|
20
|
+
}
|
|
21
|
+
export declare class RecipeDefinitionResolver {
|
|
22
|
+
recipeDefinitions(params: ListParam, context: ResolverContext): Promise<RecipeDefinitionList>;
|
|
23
|
+
updateMultipleRecipeDefinition(patches: MasterPatch[], context: ResolverContext): Promise<RecipeDefinition[]>;
|
|
24
|
+
}
|
|
25
|
+
export declare class RouteDefinitionResolver {
|
|
26
|
+
routeDefinitions(params: ListParam, context: ResolverContext): Promise<RouteDefinitionList>;
|
|
27
|
+
updateMultipleRouteDefinition(patches: MasterPatch[], context: ResolverContext): Promise<RouteDefinition[]>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RouteDefinitionResolver = exports.RecipeDefinitionResolver = exports.RouteDefinitionList = exports.RecipeDefinitionList = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const type_graphql_1 = require("type-graphql");
|
|
6
|
+
const shell_1 = require("@things-factory/shell");
|
|
7
|
+
const type_graphql_2 = require("type-graphql");
|
|
8
|
+
const shell_2 = require("@things-factory/shell");
|
|
9
|
+
const master_crud_1 = require("../master-crud");
|
|
10
|
+
const master_axis_1 = require("../master-axis");
|
|
11
|
+
const master_list_1 = require("../master-list");
|
|
12
|
+
const recipe_definition_1 = require("./recipe-definition");
|
|
13
|
+
const route_definition_1 = require("./route-definition");
|
|
14
|
+
/**
|
|
15
|
+
* 레시피·라우팅 축을 채우고 고친다.
|
|
16
|
+
*
|
|
17
|
+
* 규칙은 `master-crud.ts` 한 곳에 있다. 여기는 축의 이름만 붙인다 — 다른 열셋과 같은 모양이다.
|
|
18
|
+
*
|
|
19
|
+
* **개정할 때 행을 고치지 않고 유효 기간의 끝을 채운다.** 고치면 그 레시피로 만든 지난 실적이 어느
|
|
20
|
+
* 배합으로 만든 것인지 잃는다.
|
|
21
|
+
*/
|
|
22
|
+
let RecipeDefinitionList = class RecipeDefinitionList {
|
|
23
|
+
};
|
|
24
|
+
exports.RecipeDefinitionList = RecipeDefinitionList;
|
|
25
|
+
tslib_1.__decorate([
|
|
26
|
+
(0, type_graphql_2.Field)(type => [recipe_definition_1.RecipeDefinition]),
|
|
27
|
+
tslib_1.__metadata("design:type", Array)
|
|
28
|
+
], RecipeDefinitionList.prototype, "items", void 0);
|
|
29
|
+
tslib_1.__decorate([
|
|
30
|
+
(0, type_graphql_2.Field)(type => type_graphql_2.Int),
|
|
31
|
+
tslib_1.__metadata("design:type", Number)
|
|
32
|
+
], RecipeDefinitionList.prototype, "total", void 0);
|
|
33
|
+
exports.RecipeDefinitionList = RecipeDefinitionList = tslib_1.__decorate([
|
|
34
|
+
(0, type_graphql_2.ObjectType)({ description: 'A page of recipe definitions' })
|
|
35
|
+
], RecipeDefinitionList);
|
|
36
|
+
let RouteDefinitionList = class RouteDefinitionList {
|
|
37
|
+
};
|
|
38
|
+
exports.RouteDefinitionList = RouteDefinitionList;
|
|
39
|
+
tslib_1.__decorate([
|
|
40
|
+
(0, type_graphql_2.Field)(type => [route_definition_1.RouteDefinition]),
|
|
41
|
+
tslib_1.__metadata("design:type", Array)
|
|
42
|
+
], RouteDefinitionList.prototype, "items", void 0);
|
|
43
|
+
tslib_1.__decorate([
|
|
44
|
+
(0, type_graphql_2.Field)(type => type_graphql_2.Int),
|
|
45
|
+
tslib_1.__metadata("design:type", Number)
|
|
46
|
+
], RouteDefinitionList.prototype, "total", void 0);
|
|
47
|
+
exports.RouteDefinitionList = RouteDefinitionList = tslib_1.__decorate([
|
|
48
|
+
(0, type_graphql_2.ObjectType)({ description: 'A page of route definitions' })
|
|
49
|
+
], RouteDefinitionList);
|
|
50
|
+
let RecipeDefinitionResolver = class RecipeDefinitionResolver {
|
|
51
|
+
async recipeDefinitions(params, context) {
|
|
52
|
+
const { domain } = context.state;
|
|
53
|
+
const { items, total } = await (0, master_list_1.listMaster)('recipeDefinition', params, domain);
|
|
54
|
+
return { items: items, total };
|
|
55
|
+
}
|
|
56
|
+
async updateMultipleRecipeDefinition(patches, context) {
|
|
57
|
+
const { domain, user, tx } = context.state;
|
|
58
|
+
const axis = (0, master_axis_1.masterAxisOf)('recipeDefinition');
|
|
59
|
+
const saved = await (0, master_crud_1.saveMasterPatches)(tx, domain, axis.entity, patches, user, {
|
|
60
|
+
hasEffectivePeriod: axis.hasEffectivePeriod
|
|
61
|
+
});
|
|
62
|
+
return saved;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
exports.RecipeDefinitionResolver = RecipeDefinitionResolver;
|
|
66
|
+
tslib_1.__decorate([
|
|
67
|
+
(0, type_graphql_2.Directive)('@privilege(category: "ops-master", privilege: "query", domainOwnerGranted: true)'),
|
|
68
|
+
(0, type_graphql_2.Query)(returns => RecipeDefinitionList, { description: 'To fetch recipe definitions' }),
|
|
69
|
+
tslib_1.__param(0, (0, type_graphql_2.Args)(type => shell_2.ListParam)),
|
|
70
|
+
tslib_1.__param(1, (0, type_graphql_2.Ctx)()),
|
|
71
|
+
tslib_1.__metadata("design:type", Function),
|
|
72
|
+
tslib_1.__metadata("design:paramtypes", [shell_2.ListParam, Object]),
|
|
73
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
74
|
+
], RecipeDefinitionResolver.prototype, "recipeDefinitions", null);
|
|
75
|
+
tslib_1.__decorate([
|
|
76
|
+
(0, type_graphql_2.Directive)('@privilege(category: "ops-master", privilege: "mutation", domainOwnerGranted: true)'),
|
|
77
|
+
(0, type_graphql_2.Directive)('@transaction'),
|
|
78
|
+
(0, type_graphql_2.Mutation)(returns => [recipe_definition_1.RecipeDefinition], { description: 'To create, change or retire recipe definitions' }),
|
|
79
|
+
tslib_1.__param(0, (0, type_graphql_2.Arg)('patches', type => [shell_2.ScalarObject])),
|
|
80
|
+
tslib_1.__param(1, (0, type_graphql_2.Ctx)()),
|
|
81
|
+
tslib_1.__metadata("design:type", Function),
|
|
82
|
+
tslib_1.__metadata("design:paramtypes", [Array, Object]),
|
|
83
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
84
|
+
], RecipeDefinitionResolver.prototype, "updateMultipleRecipeDefinition", null);
|
|
85
|
+
exports.RecipeDefinitionResolver = RecipeDefinitionResolver = tslib_1.__decorate([
|
|
86
|
+
(0, type_graphql_2.Resolver)(recipe_definition_1.RecipeDefinition),
|
|
87
|
+
(0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
|
|
88
|
+
], RecipeDefinitionResolver);
|
|
89
|
+
let RouteDefinitionResolver = class RouteDefinitionResolver {
|
|
90
|
+
async routeDefinitions(params, context) {
|
|
91
|
+
const { domain } = context.state;
|
|
92
|
+
const { items, total } = await (0, master_list_1.listMaster)('routeDefinition', params, domain);
|
|
93
|
+
return { items: items, total };
|
|
94
|
+
}
|
|
95
|
+
async updateMultipleRouteDefinition(patches, context) {
|
|
96
|
+
const { domain, user, tx } = context.state;
|
|
97
|
+
const axis = (0, master_axis_1.masterAxisOf)('routeDefinition');
|
|
98
|
+
const saved = await (0, master_crud_1.saveMasterPatches)(tx, domain, axis.entity, patches, user, {
|
|
99
|
+
hasEffectivePeriod: axis.hasEffectivePeriod
|
|
100
|
+
});
|
|
101
|
+
return saved;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
exports.RouteDefinitionResolver = RouteDefinitionResolver;
|
|
105
|
+
tslib_1.__decorate([
|
|
106
|
+
(0, type_graphql_2.Directive)('@privilege(category: "ops-master", privilege: "query", domainOwnerGranted: true)'),
|
|
107
|
+
(0, type_graphql_2.Query)(returns => RouteDefinitionList, { description: 'To fetch route definitions' }),
|
|
108
|
+
tslib_1.__param(0, (0, type_graphql_2.Args)(type => shell_2.ListParam)),
|
|
109
|
+
tslib_1.__param(1, (0, type_graphql_2.Ctx)()),
|
|
110
|
+
tslib_1.__metadata("design:type", Function),
|
|
111
|
+
tslib_1.__metadata("design:paramtypes", [shell_2.ListParam, Object]),
|
|
112
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
113
|
+
], RouteDefinitionResolver.prototype, "routeDefinitions", null);
|
|
114
|
+
tslib_1.__decorate([
|
|
115
|
+
(0, type_graphql_2.Directive)('@privilege(category: "ops-master", privilege: "mutation", domainOwnerGranted: true)'),
|
|
116
|
+
(0, type_graphql_2.Directive)('@transaction'),
|
|
117
|
+
(0, type_graphql_2.Mutation)(returns => [route_definition_1.RouteDefinition], { description: 'To create, change or retire route definitions' }),
|
|
118
|
+
tslib_1.__param(0, (0, type_graphql_2.Arg)('patches', type => [shell_2.ScalarObject])),
|
|
119
|
+
tslib_1.__param(1, (0, type_graphql_2.Ctx)()),
|
|
120
|
+
tslib_1.__metadata("design:type", Function),
|
|
121
|
+
tslib_1.__metadata("design:paramtypes", [Array, Object]),
|
|
122
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
123
|
+
], RouteDefinitionResolver.prototype, "updateMultipleRouteDefinition", null);
|
|
124
|
+
exports.RouteDefinitionResolver = RouteDefinitionResolver = tslib_1.__decorate([
|
|
125
|
+
(0, type_graphql_2.Resolver)(route_definition_1.RouteDefinition),
|
|
126
|
+
(0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
|
|
127
|
+
], RouteDefinitionResolver);
|
|
128
|
+
//# sourceMappingURL=recipe-master-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe-master-resolver.js","sourceRoot":"","sources":["../../../server/service/recipe/recipe-master-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { UseMiddleware } from 'type-graphql'\nimport { SpeakRefusals } from '@things-factory/shell'\nimport { Args, Arg, Ctx, Directive, Int, Mutation, ObjectType, Field, Query, Resolver } from 'type-graphql'\n\nimport { ListParam, ScalarObject } from '@things-factory/shell'\n\nimport { MasterPatch, saveMasterPatches } from '../master-crud'\nimport { masterAxisOf } from '../master-axis'\nimport { listMaster } from '../master-list'\nimport { RecipeDefinition } from './recipe-definition'\nimport { RouteDefinition } from './route-definition'\n\n/**\n * 레시피·라우팅 축을 채우고 고친다.\n *\n * 규칙은 `master-crud.ts` 한 곳에 있다. 여기는 축의 이름만 붙인다 — 다른 열셋과 같은 모양이다.\n *\n * **개정할 때 행을 고치지 않고 유효 기간의 끝을 채운다.** 고치면 그 레시피로 만든 지난 실적이 어느\n * 배합으로 만든 것인지 잃는다.\n */\n\n@ObjectType({ description: 'A page of recipe definitions' })\nexport class RecipeDefinitionList {\n @Field(type => [RecipeDefinition])\n items: RecipeDefinition[]\n\n @Field(type => Int)\n total: number\n}\n\n@ObjectType({ description: 'A page of route definitions' })\nexport class RouteDefinitionList {\n @Field(type => [RouteDefinition])\n items: RouteDefinition[]\n\n @Field(type => Int)\n total: number\n}\n\n@Resolver(RecipeDefinition)\n@UseMiddleware(SpeakRefusals)\nexport class RecipeDefinitionResolver {\n @Directive('@privilege(category: \"ops-master\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => RecipeDefinitionList, { description: 'To fetch recipe definitions' })\n async recipeDefinitions(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<RecipeDefinitionList> {\n const { domain } = context.state\n const { items, total } = await listMaster('recipeDefinition', params, domain)\n\n return { items: items as RecipeDefinition[], total }\n }\n\n @Directive('@privilege(category: \"ops-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => [RecipeDefinition], { description: 'To create, change or retire recipe definitions' })\n async updateMultipleRecipeDefinition(\n @Arg('patches', type => [ScalarObject]) patches: MasterPatch[],\n @Ctx() context: ResolverContext\n ): Promise<RecipeDefinition[]> {\n const { domain, user, tx } = context.state\n const axis = masterAxisOf('recipeDefinition')\n\n const saved = await saveMasterPatches(tx, domain, axis.entity, patches, user, {\n hasEffectivePeriod: axis.hasEffectivePeriod\n })\n\n return saved as RecipeDefinition[]\n }\n}\n\n@Resolver(RouteDefinition)\n@UseMiddleware(SpeakRefusals)\nexport class RouteDefinitionResolver {\n @Directive('@privilege(category: \"ops-master\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(returns => RouteDefinitionList, { description: 'To fetch route definitions' })\n async routeDefinitions(\n @Args(type => ListParam) params: ListParam,\n @Ctx() context: ResolverContext\n ): Promise<RouteDefinitionList> {\n const { domain } = context.state\n const { items, total } = await listMaster('routeDefinition', params, domain)\n\n return { items: items as RouteDefinition[], total }\n }\n\n @Directive('@privilege(category: \"ops-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(returns => [RouteDefinition], { description: 'To create, change or retire route definitions' })\n async updateMultipleRouteDefinition(\n @Arg('patches', type => [ScalarObject]) patches: MasterPatch[],\n @Ctx() context: ResolverContext\n ): Promise<RouteDefinition[]> {\n const { domain, user, tx } = context.state\n const axis = masterAxisOf('routeDefinition')\n\n const saved = await saveMasterPatches(tx, domain, axis.entity, patches, user, {\n hasEffectivePeriod: axis.hasEffectivePeriod\n })\n\n return saved as RouteDefinition[]\n }\n}\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { RecipeDefinition } from './recipe-definition';
|
|
2
|
+
import type { RouteDefinition } from './route-definition';
|
|
3
|
+
/**
|
|
4
|
+
* 트윈 선언의 `recipes`·`routes` 한 항목 — 계약의 `RecipeDef`·`RouteDef` 모양이다.
|
|
5
|
+
*
|
|
6
|
+
* 마스터가 다른 모양으로 들면 옮기는 코드가 두 겹이 되고, 그 코드가 언젠가 어긋난다. 그래서 칸 이름을
|
|
7
|
+
* 계약과 같게 둔다 — 다른 것은 마스터가 `name` 으로 부르는 것을 계약이 `key` 로 부르는 것 하나다.
|
|
8
|
+
*/
|
|
9
|
+
export interface RouteEntry {
|
|
10
|
+
key: string;
|
|
11
|
+
label: string;
|
|
12
|
+
steps: string[];
|
|
13
|
+
procedure?: unknown[];
|
|
14
|
+
effectiveStart?: string;
|
|
15
|
+
effectiveEnd?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface RecipeEntry {
|
|
18
|
+
key: string;
|
|
19
|
+
label: string;
|
|
20
|
+
inputs: unknown[];
|
|
21
|
+
outputs: unknown[];
|
|
22
|
+
route?: string;
|
|
23
|
+
effectiveStart?: string;
|
|
24
|
+
effectiveEnd?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function toRouteEntry(route: RouteDefinition): RouteEntry;
|
|
27
|
+
export declare function toRecipeEntry(recipe: RecipeDefinition): RecipeEntry;
|
|
28
|
+
/**
|
|
29
|
+
* **이 품목을 만드는 레시피들** — 여럿일 수 있다.
|
|
30
|
+
*
|
|
31
|
+
* 하나를 골라 주지 않는다. 대체 레시피가 정상이고(첫 실 연동에서 라우팅이 둘 이상인 레시피가 306/471),
|
|
32
|
+
* 어느 것으로 만들지는 오더가 정하거나 사람이 고른다. 여기서 하나를 골라 주면 그 판정이 숨는다.
|
|
33
|
+
*
|
|
34
|
+
* 유효 기간은 여기서 걸러 내지 않는다 — 「지금 무엇을 쓸 수 있나」와 「그때 무엇을 썼나」가 다른 물음이고,
|
|
35
|
+
* 시각을 아는 것은 부르는 쪽이다.
|
|
36
|
+
*/
|
|
37
|
+
export declare function recipesFor(recipes: RecipeDefinition[], materialDefinitionName: string): RecipeEntry[];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toRouteEntry = toRouteEntry;
|
|
4
|
+
exports.toRecipeEntry = toRecipeEntry;
|
|
5
|
+
exports.recipesFor = recipesFor;
|
|
6
|
+
const resource_class_1 = require("../resource/resource-class");
|
|
7
|
+
function toRouteEntry(route) {
|
|
8
|
+
/* `steps` 를 비울 수 없다 — 단계가 없는 라우팅은 지나갈 곳이 없다. */
|
|
9
|
+
const out = {
|
|
10
|
+
key: route.name,
|
|
11
|
+
label: route.description ?? route.name,
|
|
12
|
+
steps: route.steps ?? []
|
|
13
|
+
};
|
|
14
|
+
(0, resource_class_1.put)(out, 'procedure', route.procedure);
|
|
15
|
+
(0, resource_class_1.put)(out, 'effectiveStart', (0, resource_class_1.iso)(route.effectiveStart));
|
|
16
|
+
(0, resource_class_1.put)(out, 'effectiveEnd', (0, resource_class_1.iso)(route.effectiveEnd));
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
function toRecipeEntry(recipe) {
|
|
20
|
+
/*
|
|
21
|
+
* `inputs` 와 `outputs` 를 비울 수 없다. 산출이 없으면 무엇을 만드는지 알 수 없고, 투입이 없으면
|
|
22
|
+
* 무엇으로 만드는지 알 수 없다 — 둘 중 하나만으로는 레시피가 아니다.
|
|
23
|
+
*/
|
|
24
|
+
const out = {
|
|
25
|
+
key: recipe.name,
|
|
26
|
+
label: recipe.description ?? recipe.name,
|
|
27
|
+
inputs: recipe.inputs ?? [],
|
|
28
|
+
outputs: recipe.outputs ?? []
|
|
29
|
+
};
|
|
30
|
+
(0, resource_class_1.put)(out, 'route', recipe.route);
|
|
31
|
+
(0, resource_class_1.put)(out, 'effectiveStart', (0, resource_class_1.iso)(recipe.effectiveStart));
|
|
32
|
+
(0, resource_class_1.put)(out, 'effectiveEnd', (0, resource_class_1.iso)(recipe.effectiveEnd));
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* **이 품목을 만드는 레시피들** — 여럿일 수 있다.
|
|
37
|
+
*
|
|
38
|
+
* 하나를 골라 주지 않는다. 대체 레시피가 정상이고(첫 실 연동에서 라우팅이 둘 이상인 레시피가 306/471),
|
|
39
|
+
* 어느 것으로 만들지는 오더가 정하거나 사람이 고른다. 여기서 하나를 골라 주면 그 판정이 숨는다.
|
|
40
|
+
*
|
|
41
|
+
* 유효 기간은 여기서 걸러 내지 않는다 — 「지금 무엇을 쓸 수 있나」와 「그때 무엇을 썼나」가 다른 물음이고,
|
|
42
|
+
* 시각을 아는 것은 부르는 쪽이다.
|
|
43
|
+
*/
|
|
44
|
+
function recipesFor(recipes, materialDefinitionName) {
|
|
45
|
+
return recipes.filter(r => r.materialDefinitionName === materialDefinitionName).map(toRecipeEntry);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=recipe-master.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipe-master.js","sourceRoot":"","sources":["../../../server/service/recipe/recipe-master.ts"],"names":[],"mappings":";;AA6BA,oCAWC;AAED,sCAeC;AAWD,gCAEC;AAtED,+DAAqD;AA6BrD,SAAgB,YAAY,CAAC,KAAsB;IACjD,gDAAgD;IAChD,MAAM,GAAG,GAA4B;QACnC,GAAG,EAAE,KAAK,CAAC,IAAI;QACf,KAAK,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,IAAI;QACtC,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;KACzB,CAAA;IACD,IAAA,oBAAG,EAAC,GAAG,EAAE,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IACtC,IAAA,oBAAG,EAAC,GAAG,EAAE,gBAAgB,EAAE,IAAA,oBAAG,EAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAA;IACrD,IAAA,oBAAG,EAAC,GAAG,EAAE,cAAc,EAAE,IAAA,oBAAG,EAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAA;IACjD,OAAO,GAA4B,CAAA;AACrC,CAAC;AAED,SAAgB,aAAa,CAAC,MAAwB;IACpD;;;OAGG;IACH,MAAM,GAAG,GAA4B;QACnC,GAAG,EAAE,MAAM,CAAC,IAAI;QAChB,KAAK,EAAE,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI;QACxC,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;KAC9B,CAAA;IACD,IAAA,oBAAG,EAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IAC/B,IAAA,oBAAG,EAAC,GAAG,EAAE,gBAAgB,EAAE,IAAA,oBAAG,EAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAA;IACtD,IAAA,oBAAG,EAAC,GAAG,EAAE,cAAc,EAAE,IAAA,oBAAG,EAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAA;IAClD,OAAO,GAA6B,CAAA;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,UAAU,CAAC,OAA2B,EAAE,sBAA8B;IACpF,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,KAAK,sBAAsB,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;AACpG,CAAC","sourcesContent":["import { iso, put } from '../resource/resource-class'\nimport type { RecipeDefinition } from './recipe-definition'\nimport type { RouteDefinition } from './route-definition'\n\n/**\n * 트윈 선언의 `recipes`·`routes` 한 항목 — 계약의 `RecipeDef`·`RouteDef` 모양이다.\n *\n * 마스터가 다른 모양으로 들면 옮기는 코드가 두 겹이 되고, 그 코드가 언젠가 어긋난다. 그래서 칸 이름을\n * 계약과 같게 둔다 — 다른 것은 마스터가 `name` 으로 부르는 것을 계약이 `key` 로 부르는 것 하나다.\n */\nexport interface RouteEntry {\n key: string\n label: string\n steps: string[]\n procedure?: unknown[]\n effectiveStart?: string\n effectiveEnd?: string\n}\n\nexport interface RecipeEntry {\n key: string\n label: string\n inputs: unknown[]\n outputs: unknown[]\n route?: string\n effectiveStart?: string\n effectiveEnd?: string\n}\n\nexport function toRouteEntry(route: RouteDefinition): RouteEntry {\n /* `steps` 를 비울 수 없다 — 단계가 없는 라우팅은 지나갈 곳이 없다. */\n const out: Record<string, unknown> = {\n key: route.name,\n label: route.description ?? route.name,\n steps: route.steps ?? []\n }\n put(out, 'procedure', route.procedure)\n put(out, 'effectiveStart', iso(route.effectiveStart))\n put(out, 'effectiveEnd', iso(route.effectiveEnd))\n return out as unknown as RouteEntry\n}\n\nexport function toRecipeEntry(recipe: RecipeDefinition): RecipeEntry {\n /*\n * `inputs` 와 `outputs` 를 비울 수 없다. 산출이 없으면 무엇을 만드는지 알 수 없고, 투입이 없으면\n * 무엇으로 만드는지 알 수 없다 — 둘 중 하나만으로는 레시피가 아니다.\n */\n const out: Record<string, unknown> = {\n key: recipe.name,\n label: recipe.description ?? recipe.name,\n inputs: recipe.inputs ?? [],\n outputs: recipe.outputs ?? []\n }\n put(out, 'route', recipe.route)\n put(out, 'effectiveStart', iso(recipe.effectiveStart))\n put(out, 'effectiveEnd', iso(recipe.effectiveEnd))\n return out as unknown as RecipeEntry\n}\n\n/**\n * **이 품목을 만드는 레시피들** — 여럿일 수 있다.\n *\n * 하나를 골라 주지 않는다. 대체 레시피가 정상이고(첫 실 연동에서 라우팅이 둘 이상인 레시피가 306/471),\n * 어느 것으로 만들지는 오더가 정하거나 사람이 고른다. 여기서 하나를 골라 주면 그 판정이 숨는다.\n *\n * 유효 기간은 여기서 걸러 내지 않는다 — 「지금 무엇을 쓸 수 있나」와 「그때 무엇을 썼나」가 다른 물음이고,\n * 시각을 아는 것은 부르는 쪽이다.\n */\nexport function recipesFor(recipes: RecipeDefinition[], materialDefinitionName: string): RecipeEntry[] {\n return recipes.filter(r => r.materialDefinitionName === materialDefinitionName).map(toRecipeEntry)\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare class RecipeMaster {
|
|
2
|
+
recipes: string;
|
|
3
|
+
routes: string;
|
|
4
|
+
/**
|
|
5
|
+
* 더 있나 — **이 값을 안 보고 쓰면 조용히 잘린 마스터로 트윈을 세우게 된다.**
|
|
6
|
+
*
|
|
7
|
+
* 거짓이 될 때까지 `next` 를 `after` 로 넘겨 이어 받는다.
|
|
8
|
+
*/
|
|
9
|
+
hasMore: boolean;
|
|
10
|
+
/** 이어 받을 자리. 더 없으면 없다. */
|
|
11
|
+
next?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class RecipeQuery {
|
|
14
|
+
/**
|
|
15
|
+
* 레시피와 라우팅을 **한 질의로** 낸다.
|
|
16
|
+
*
|
|
17
|
+
* 따로 물으면 그 사이에 마스터가 바뀌어 레시피가 없는 라우팅을 가리키는 순간이 생긴다. 구조는
|
|
18
|
+
* 서로를 가리키므로 통째로 맞아야 한다 — 마스터를 당겨 가는 다른 축과 같은 규율이다.
|
|
19
|
+
*/
|
|
20
|
+
recipeMaster(after: string | undefined, limit: number | undefined, context: ResolverContext): Promise<RecipeMaster>;
|
|
21
|
+
}
|