@things-factory/ops-master 10.1.203 → 10.1.205

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.
Files changed (34) hide show
  1. package/dist-client/pages/master/revision-comparison.js +5 -2
  2. package/dist-client/pages/master/revision-comparison.js.map +1 -1
  3. package/dist-client/pages/master/revision-view.d.ts +15 -0
  4. package/dist-client/pages/master/revision-view.js +12 -0
  5. package/dist-client/pages/master/revision-view.js.map +1 -1
  6. package/dist-client/pages/master/revision-workspace.js +6 -2
  7. package/dist-client/pages/master/revision-workspace.js.map +1 -1
  8. package/dist-client/tsconfig.tsbuildinfo +1 -1
  9. package/dist-server/service/master-change-approval/approval-input.d.ts +17 -0
  10. package/dist-server/service/master-change-approval/approval-input.js +35 -0
  11. package/dist-server/service/master-change-approval/approval-input.js.map +1 -0
  12. package/dist-server/service/master-change-approval/index.d.ts +1 -0
  13. package/dist-server/service/master-change-approval/index.js +1 -0
  14. package/dist-server/service/master-change-approval/index.js.map +1 -1
  15. package/dist-server/service/material/material-revision-resolver.d.ts +1 -0
  16. package/dist-server/service/material/material-revision-service.d.ts +3 -0
  17. package/dist-server/service/material/material-revision-service.js +18 -5
  18. package/dist-server/service/material/material-revision-service.js.map +1 -1
  19. package/dist-server/service/recipe/recipe-revision-resolver.d.ts +1 -0
  20. package/dist-server/service/recipe/recipe-revision-service.d.ts +3 -0
  21. package/dist-server/service/recipe/recipe-revision-service.js +18 -5
  22. package/dist-server/service/recipe/recipe-revision-service.js.map +1 -1
  23. package/dist-server/service/test-spec/test-spec-revision-resolver.d.ts +1 -0
  24. package/dist-server/service/test-spec/test-spec-revision-service.d.ts +3 -0
  25. package/dist-server/service/test-spec/test-spec-revision-service.js +18 -5
  26. package/dist-server/service/test-spec/test-spec-revision-service.js.map +1 -1
  27. package/dist-server/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +5 -5
  29. package/translations/en.json +2 -0
  30. package/translations/es.json +2 -0
  31. package/translations/ja.json +2 -0
  32. package/translations/ko.json +2 -0
  33. package/translations/ms.json +2 -0
  34. package/translations/zh.json +2 -0
@@ -0,0 +1,17 @@
1
+ /** How a revision was published, as the plan that published it says. A revision is published at most once. */
2
+ export type ReleaseKind = 'approved' | 'policy' | 'baseline';
3
+ /**
4
+ * The publishing kind of each revision, from the plans of one subject: `kindOf(revisionId)` is null until the
5
+ * revision is published.
6
+ */
7
+ export declare function releaseKinds(plans: {
8
+ publishedRevisionId?: string | null;
9
+ releaseKind: ReleaseKind;
10
+ }[]): (revisionId: string) => ReleaseKind | null;
11
+ /**
12
+ * Whether the approval input a work item carries is still what its frozen revision projects to, key by key.
13
+ *
14
+ * One shape only. Work items issued before `before.detail.releaseKind` joined the projection (2026-10-20) are
15
+ * brought up to it by a one-off data fix, not read here in their old shape.
16
+ */
17
+ export declare function approvalInputMatches(carried: Record<string, any>, expected: Record<string, any>): boolean;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.releaseKinds = releaseKinds;
4
+ exports.approvalInputMatches = approvalInputMatches;
5
+ /** Sorted object keys, ordered arrays — the same encoding the axes use for their submission hashes. */
6
+ function canonical(value) {
7
+ if (value === null || typeof value !== 'object')
8
+ return JSON.stringify(value);
9
+ if (Array.isArray(value))
10
+ return '[' + value.map(canonical).join(',') + ']';
11
+ return ('{' +
12
+ Object.keys(value)
13
+ .sort()
14
+ .map(key => JSON.stringify(key) + ':' + canonical(value[key]))
15
+ .join(',') +
16
+ '}');
17
+ }
18
+ /**
19
+ * The publishing kind of each revision, from the plans of one subject: `kindOf(revisionId)` is null until the
20
+ * revision is published.
21
+ */
22
+ function releaseKinds(plans) {
23
+ const kinds = new Map(plans.map(plan => [plan.publishedRevisionId, plan.releaseKind]));
24
+ return (revisionId) => kinds.get(revisionId) ?? null;
25
+ }
26
+ /**
27
+ * Whether the approval input a work item carries is still what its frozen revision projects to, key by key.
28
+ *
29
+ * One shape only. Work items issued before `before.detail.releaseKind` joined the projection (2026-10-20) are
30
+ * brought up to it by a one-off data fix, not read here in their old shape.
31
+ */
32
+ function approvalInputMatches(carried, expected) {
33
+ return Object.keys(expected).every(key => canonical(carried?.[key]) === canonical(expected[key]));
34
+ }
35
+ //# sourceMappingURL=approval-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-input.js","sourceRoot":"","sources":["../../../server/service/master-change-approval/approval-input.ts"],"names":[],"mappings":";;AAqBA,oCAGC;AAQD,oDAEC;AA/BD,uGAAuG;AACvG,SAAS,SAAS,CAAC,KAAU;IAC3B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC7E,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAA;IAC3E,OAAO,CACL,GAAG;QACH,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aACf,IAAI,EAAE;aACN,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;aAC7D,IAAI,CAAC,GAAG,CAAC;QACZ,GAAG,CACJ,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,YAAY,CAAC,KAA0E;IACrG,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;IACtF,OAAO,CAAC,UAAkB,EAAsB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAA;AAClF,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,OAA4B,EAAE,QAA6B;IAC9F,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AACnG,CAAC","sourcesContent":["/** How a revision was published, as the plan that published it says. A revision is published at most once. */\nexport type ReleaseKind = 'approved' | 'policy' | 'baseline'\n\n/** Sorted object keys, ordered arrays — the same encoding the axes use for their submission hashes. */\nfunction canonical(value: any): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return '[' + value.map(canonical).join(',') + ']'\n return (\n '{' +\n Object.keys(value)\n .sort()\n .map(key => JSON.stringify(key) + ':' + canonical(value[key]))\n .join(',') +\n '}'\n )\n}\n\n/**\n * The publishing kind of each revision, from the plans of one subject: `kindOf(revisionId)` is null until the\n * revision is published.\n */\nexport function releaseKinds(plans: { publishedRevisionId?: string | null; releaseKind: ReleaseKind }[]) {\n const kinds = new Map(plans.map(plan => [plan.publishedRevisionId, plan.releaseKind]))\n return (revisionId: string): ReleaseKind | null => kinds.get(revisionId) ?? null\n}\n\n/**\n * Whether the approval input a work item carries is still what its frozen revision projects to, key by key.\n *\n * One shape only. Work items issued before `before.detail.releaseKind` joined the projection (2026-10-20) are\n * brought up to it by a one-off data fix, not read here in their old shape.\n */\nexport function approvalInputMatches(carried: Record<string, any>, expected: Record<string, any>): boolean {\n return Object.keys(expected).every(key => canonical(carried?.[key]) === canonical(expected[key]))\n}\n"]}
@@ -4,6 +4,7 @@ export * from './master-change-axis';
4
4
  export * from './master-change-flow';
5
5
  export * from './builtin-axes';
6
6
  export * from './master-change-resolver';
7
+ export * from './approval-input';
7
8
  /**
8
9
  * Puts an axis on the approval flow: its activity template, and its door — submitting is the act, so an
9
10
  * empty approval line refuses (ADR-0077 `approval-is-the-act`). Registration is at module import; the
@@ -13,6 +13,7 @@ tslib_1.__exportStar(require("./master-change-axis"), exports);
13
13
  tslib_1.__exportStar(require("./master-change-flow"), exports);
14
14
  tslib_1.__exportStar(require("./builtin-axes"), exports);
15
15
  tslib_1.__exportStar(require("./master-change-resolver"), exports);
16
+ tslib_1.__exportStar(require("./approval-input"), exports);
16
17
  /**
17
18
  * Puts an axis on the approval flow: its activity template, and its door — submitting is the act, so an
18
19
  * empty approval line refuses (ADR-0077 `approval-is-the-act`). Registration is at module import; the
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/master-change-approval/index.ts"],"names":[],"mappings":";;;AAkBA,0DAQC;;AA1BD,uDAAmF;AAEnF,sDAAkE;AAClE,iDAAqG;AACrG,6DAAsF;AACtF,6DAAqF;AACrF,qEAAuE;AAEvE,+DAAoC;AACpC,+DAAoC;AACpC,yDAA8B;AAC9B,mEAAwC;AAExC;;;;GAIG;AACH,SAAgB,uBAAuB,CAAC,IAAsB,EAAE,MAAM,GAAG,YAAY;IACnF,IAAA,6CAAwB,EAAC,IAAI,CAAC,CAAA;IAC9B,gCAAqB,CAAC,uBAAuB,CAAC,IAAA,yCAAoB,EAAC,IAAI,CAAQ,CAAC,CAAA;IAChF,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC3G,IAAA,4BAAiB,EAAC;QAChB,MAAM;QACN,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAU,CAAC;KACrI,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAA;AAE3C,KAAK,MAAM,IAAI,IAAI,CAAC,wCAAyB,EAAE,4BAAa,EAAE,yCAA0B,CAAC;IAAE,uBAAuB,CAAC,IAAI,CAAC,CAAA;AAExH,qFAAqF;AACrF,IAAA,+CAA8B,EAAC,6CAAwB,CAAC,CAAA;AAE3C,QAAA,SAAS,GAAG,CAAC,qDAA4B,CAAC,CAAA","sourcesContent":["import { ActivityInstallations, registerWorkDoors } from '@things-factory/worklist'\n\nimport { registerApprovalRouteInspector } from '../approval-route'\nimport { MATERIAL_DEFINITION_CHANGE, RECIPE_CHANGE, TEST_SPECIFICATION_CHANGE } from './builtin-axes'\nimport { registerMasterChangeAxis, type MasterChangeAxis } from './master-change-axis'\nimport { inspectMasterChangeRoute, masterChangeActivity } from './master-change-flow'\nimport { MasterChangeApprovalResolver } from './master-change-resolver'\n\nexport * from './master-change-axis'\nexport * from './master-change-flow'\nexport * from './builtin-axes'\nexport * from './master-change-resolver'\n\n/**\n * Puts an axis on the approval flow: its activity template, and its door — submitting is the act, so an\n * empty approval line refuses (ADR-0077 `approval-is-the-act`). Registration is at module import; the\n * bootstrap hook runs after the schema is built, which is too late.\n */\nexport function installMasterChangeAxis(axis: MasterChangeAxis, module = 'ops-master'): void {\n registerMasterChangeAxis(axis)\n ActivityInstallations.installActivityTemplate(masterChangeActivity(axis) as any)\n doorsOf.set(module, [...(doorsOf.get(module) ?? []).filter(name => name !== axis.activity), axis.activity])\n registerWorkDoors({\n module,\n doors: doorsOf.get(module)!.map(name => ({ name, kind: 'approval', whenNoLine: 'refuse', because: 'approval-is-the-act' }) as const)\n })\n}\n\nconst doorsOf = new Map<string, string[]>()\n\nfor (const axis of [TEST_SPECIFICATION_CHANGE, RECIPE_CHANGE, MATERIAL_DEFINITION_CHANGE]) installMasterChangeAxis(axis)\n\n/* Raising an axis to approval asks whether its activity has someone who approves. */\nregisterApprovalRouteInspector(inspectMasterChangeRoute)\n\nexport const resolvers = [MasterChangeApprovalResolver]\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/service/master-change-approval/index.ts"],"names":[],"mappings":";;;AAmBA,0DAQC;;AA3BD,uDAAmF;AAEnF,sDAAkE;AAClE,iDAAqG;AACrG,6DAAsF;AACtF,6DAAqF;AACrF,qEAAuE;AAEvE,+DAAoC;AACpC,+DAAoC;AACpC,yDAA8B;AAC9B,mEAAwC;AACxC,2DAAgC;AAEhC;;;;GAIG;AACH,SAAgB,uBAAuB,CAAC,IAAsB,EAAE,MAAM,GAAG,YAAY;IACnF,IAAA,6CAAwB,EAAC,IAAI,CAAC,CAAA;IAC9B,gCAAqB,CAAC,uBAAuB,CAAC,IAAA,yCAAoB,EAAC,IAAI,CAAQ,CAAC,CAAA;IAChF,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC3G,IAAA,4BAAiB,EAAC;QAChB,MAAM;QACN,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAU,CAAC;KACrI,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAA;AAE3C,KAAK,MAAM,IAAI,IAAI,CAAC,wCAAyB,EAAE,4BAAa,EAAE,yCAA0B,CAAC;IAAE,uBAAuB,CAAC,IAAI,CAAC,CAAA;AAExH,qFAAqF;AACrF,IAAA,+CAA8B,EAAC,6CAAwB,CAAC,CAAA;AAE3C,QAAA,SAAS,GAAG,CAAC,qDAA4B,CAAC,CAAA","sourcesContent":["import { ActivityInstallations, registerWorkDoors } from '@things-factory/worklist'\n\nimport { registerApprovalRouteInspector } from '../approval-route'\nimport { MATERIAL_DEFINITION_CHANGE, RECIPE_CHANGE, TEST_SPECIFICATION_CHANGE } from './builtin-axes'\nimport { registerMasterChangeAxis, type MasterChangeAxis } from './master-change-axis'\nimport { inspectMasterChangeRoute, masterChangeActivity } from './master-change-flow'\nimport { MasterChangeApprovalResolver } from './master-change-resolver'\n\nexport * from './master-change-axis'\nexport * from './master-change-flow'\nexport * from './builtin-axes'\nexport * from './master-change-resolver'\nexport * from './approval-input'\n\n/**\n * Puts an axis on the approval flow: its activity template, and its door — submitting is the act, so an\n * empty approval line refuses (ADR-0077 `approval-is-the-act`). Registration is at module import; the\n * bootstrap hook runs after the schema is built, which is too late.\n */\nexport function installMasterChangeAxis(axis: MasterChangeAxis, module = 'ops-master'): void {\n registerMasterChangeAxis(axis)\n ActivityInstallations.installActivityTemplate(masterChangeActivity(axis) as any)\n doorsOf.set(module, [...(doorsOf.get(module) ?? []).filter(name => name !== axis.activity), axis.activity])\n registerWorkDoors({\n module,\n doors: doorsOf.get(module)!.map(name => ({ name, kind: 'approval', whenNoLine: 'refuse', because: 'approval-is-the-act' }) as const)\n })\n}\n\nconst doorsOf = new Map<string, string[]>()\n\nfor (const axis of [TEST_SPECIFICATION_CHANGE, RECIPE_CHANGE, MATERIAL_DEFINITION_CHANGE]) installMasterChangeAxis(axis)\n\n/* Raising an axis to approval asks whether its activity has someone who approves. */\nregisterApprovalRouteInspector(inspectMasterChangeRoute)\n\nexport const resolvers = [MasterChangeApprovalResolver]\n"]}
@@ -23,6 +23,7 @@ export declare class MaterialDefinitionRevisionResolver {
23
23
  }[];
24
24
  revisions: {
25
25
  state: string;
26
+ releaseKind: import("..").ReleaseKind;
26
27
  revisionNumber: number;
27
28
  policy: import("..").MasterChangePolicy;
28
29
  policyId: string;
@@ -16,6 +16,7 @@ export declare function materialDefinitionApprovalInput(manager: EntityManager,
16
16
  detail: {
17
17
  validFrom?: string;
18
18
  validTo?: string;
19
+ releaseKind?: "policy" | "approved" | "baseline";
19
20
  revisionId: string;
20
21
  createdAt: string;
21
22
  frozenAt: string;
@@ -32,6 +33,7 @@ export declare function materialDefinitionApprovalInput(manager: EntityManager,
32
33
  detail: {
33
34
  validFrom?: string;
34
35
  validTo?: string;
36
+ releaseKind?: "policy" | "approved" | "baseline";
35
37
  revisionId: string;
36
38
  createdAt: string;
37
39
  frozenAt: string;
@@ -121,6 +123,7 @@ export declare function materialDefinitionRevisionOverview(manager: EntityManage
121
123
  }[];
122
124
  revisions: {
123
125
  state: string;
126
+ releaseKind: import("../master-change-approval/approval-input").ReleaseKind;
124
127
  revisionNumber: number;
125
128
  policy: import("../master-change-policy").MasterChangePolicy;
126
129
  policyId: string;
@@ -26,6 +26,7 @@ const material_definition_1 = require("./material-definition");
26
26
  const material_class_1 = require("./material-class");
27
27
  const test_specification_1 = require("../test-spec/test-specification");
28
28
  const material_revision_1 = require("./material-revision");
29
+ const approval_input_1 = require("../master-change-approval/approval-input");
29
30
  class MaterialDefinitionRefusal extends shell_1.Refusal {
30
31
  constructor(code, detail) {
31
32
  super(code, {}, detail ?? MATERIAL_DEFINITION_REFUSALS[code] ?? 'The material definition change could not be applied.');
@@ -123,11 +124,18 @@ async function materialDefinitionApprovalInput(manager, domainId, revisionId) {
123
124
  const segment = plan && base ? await manager.findOneBy(material_revision_1.MaterialDefinitionSegment, {
124
125
  domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }
125
126
  }) : null;
127
+ /*
128
+ * How the base was published (2026-10-20) — the approval screen names a baseline base in plain words. Only the
129
+ * base carries it: it was published before this draft existed and never changes, so the snapshot stays pinned.
130
+ * The proposal is unpublished here and would read differently once published.
131
+ */
132
+ const basePlan = base ? await manager.findOneBy(material_revision_1.MaterialDefinitionPlan, { domain: { id: domainId }, publishedRevision: { id: base.id } }) : null;
126
133
  const values = (row) => ({
127
134
  revisionNumber: row.revisionNumber,
128
135
  detail: {
129
136
  revisionId: row.id, createdAt: row.createdAt.toISOString(), frozenAt: row.frozenAt?.toISOString(),
130
137
  effectiveFrom: row.effectiveFrom.toISOString(), reason: row.reason,
138
+ ...(row.id === base?.id ? { releaseKind: basePlan?.releaseKind ?? null } : {}),
131
139
  ...(row.id === base?.id && segment ? { validFrom: segment.validFrom.toISOString(), validTo: segment.validTo?.toISOString() ?? null } : {})
132
140
  },
133
141
  description: row.description,
@@ -154,10 +162,8 @@ async function assertMaterialDefinitionApprovalInput(manager, domainId, input) {
154
162
  if (typeof reference?.revisionId !== 'string')
155
163
  refuse('INVALID_SUBMISSION');
156
164
  const expected = await materialDefinitionApprovalInput(manager, domainId, reference.revisionId);
157
- for (const key of Object.keys(expected)) {
158
- if (canonical(input[key]) !== canonical(expected[key]))
159
- refuse('INVALID_SUBMISSION');
160
- }
165
+ if (!(0, approval_input_1.approvalInputMatches)(input, expected))
166
+ refuse('INVALID_SUBMISSION');
161
167
  }
162
168
  function content(input) {
163
169
  return { ...(0, material_revision_content_1.materialDraftContent)(input), effectiveFrom: instant(input.effectiveFrom), reason: text(input.reason, 'reason') };
@@ -634,6 +640,12 @@ async function materialDefinitionRevisionOverview(manager, domainId, materialId,
634
640
  order: { validFrom: 'ASC' }
635
641
  })
636
642
  : [];
643
+ /*
644
+ * 개정본마다 **어떻게 발행됐는지**(`releaseKind`)를 함께 싣는다 — 발행한 적용계획의 값 그대로(2026-10-20).
645
+ * 화면은 이것으로 기준선을 알아보고 사람의 말(「최초 기록」)로 적는다. 기준선의 사유는 서버가 쓴 기록
646
+ * 문장인데 해시에 들어가 바꿀 수 없고, 문구로 알아보면 깨지기 쉽다. 발행 전 개정본은 null.
647
+ */
648
+ const kindOf = (0, approval_input_1.releaseKinds)(await manager.findBy(material_revision_1.MaterialDefinitionPlan, { domain: { id: domainId }, material: { id: materialId } }));
637
649
  return {
638
650
  materialId,
639
651
  name: material.name,
@@ -643,7 +655,8 @@ async function materialDefinitionRevisionOverview(manager, domainId, materialId,
643
655
  ...segment,
644
656
  state: segment.validFrom > at ? 'scheduled' : segment.validTo && segment.validTo <= at ? 'expired' : 'current'
645
657
  })),
646
- revisions: revisions.map(item => ({ ...item, state: item.frozenAt ? 'frozen' : 'draft' }))
658
+ revisions: revisions.map(item => ({ ...item, state: item.frozenAt ? 'frozen' : 'draft',
659
+ releaseKind: kindOf(item.id) }))
647
660
  };
648
661
  }
649
662
  /** Read-time projection, never a clock-driven rewrite of the identity row. */
@@ -1 +1 @@
1
- {"version":3,"file":"material-revision-service.js","sourceRoot":"","sources":["../../../server/service/material/material-revision-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto'\nimport { EntityManager, LessThanOrEqual, MoreThanOrEqual } from 'typeorm'\nimport { Refusal, writeLockSupported } from '@things-factory/shell'\nimport { masterChangePolicy } from '../master-change-policy'\nimport { materialDraftContent, validateMaterialReferences } from './material-revision-content'\nimport { MaterialDefinition } from './material-definition'\nimport { MaterialClass } from './material-class'\nimport { TestSpecification } from '../test-spec/test-specification'\nimport {\n MaterialDefinitionBasis,\n MaterialDefinitionPlan,\n MaterialDefinitionRevision,\n MaterialDefinitionSegment\n} from './material-revision'\n\nexport class MaterialDefinitionRefusal extends Refusal {\n constructor(code: string, detail?: string) {\n super(\n code,\n {},\n detail ?? MATERIAL_DEFINITION_REFUSALS[code] ?? 'The material definition change could not be applied.'\n )\n }\n}\nconst MATERIAL_DEFINITION_REFUSALS: Record<string, string> = {\n TRANSACTION_REQUIRED: 'This change requires a transaction.',\n INVALID_INSTANT: 'Enter a valid date and time including its time zone.',\n INVALID_CONTENT: 'The proposed material content is invalid.',\n MATERIAL_NOT_FOUND: 'The material does not exist in this domain.',\n REVISION_NOT_FOUND: 'The revision does not exist in this domain.',\n INVALID_BASE_REVISION: 'The proposed change is based on a different revision.',\n DRAFT_NOT_OWNED: 'Only the draft author can edit or submit it.',\n REVISION_FROZEN: 'This submitted revision cannot be edited. Create another draft.',\n DRAFT_CONFLICT: 'The draft changed. Reload it before saving.',\n PLAN_CONFLICT: 'The approved schedule changed. Review and submit a new draft.',\n INVALID_SUBMISSION: 'The submitted content does not match the frozen revision.',\n AUTHOR_CANNOT_APPROVE: 'The author cannot approve their own change.',\n RETROACTIVE_IMPACT: 'This change would alter material definitions already used by recorded transactions.',\n FUTURE_PLAN_CONFLICT: 'This change conflicts with an approved future schedule.',\n NO_EFFECTIVE_REVISION: 'There is no published revision effective at the business time.',\n AMBIGUOUS_EFFECTIVITY: 'More than one revision is effective at the business time.',\n REVISION_INTEGRITY_FAILURE: 'The stored revision does not match its signed content.',\n BASIS_CONFLICT: 'This transaction already has a different material or business time.',\n APPROVAL_LINE_REQUIRED: 'Configure an approval line before submitting this change.',\n REVISION_REQUIRED: 'Change the material through a revision draft.'\n}\nfunction refuse(code: string, detail?: string): never {\n throw new MaterialDefinitionRefusal(code, detail)\n}\nfunction transaction(manager: EntityManager) {\n if (!manager.queryRunner?.isTransactionActive) refuse('TRANSACTION_REQUIRED')\n}\n/** Current reads are required after waiting for the subject lock, including MySQL REPEATABLE READ. */\nfunction currentLock(manager: EntityManager) {\n return writeLockSupported(manager) ? { lock: { mode: 'pessimistic_write' as const } } : {}\n}\nfunction instant(value: Date | string): Date {\n if (!(value instanceof Date) && (typeof value !== 'string' || !/(Z|[+-]\\d{2}:\\d{2})$/.test(value)))\n refuse('INVALID_INSTANT')\n const result = new Date(value)\n if (!Number.isFinite(result.getTime())) refuse('INVALID_INSTANT')\n return result\n}\nfunction text(value: unknown, field: string): string {\n if (typeof value !== 'string' || !value.trim()) refuse('INVALID_CONTENT', field)\n return value.trim()\n}\n/** Sorted object keys, ordered arrays, ISO instants. This is the v1 submission encoding. */\nfunction canonical(value: any): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return '[' + value.map(canonical).join(',') + ']'\n return (\n '{' +\n Object.keys(value)\n .sort()\n .map(key => JSON.stringify(key) + ':' + canonical(value[key]))\n .join(',') +\n '}'\n )\n}\nexport function materialDefinitionSubmissionHash(revision: MaterialDefinitionRevision): string {\n return createHash('sha256')\n .update(\n canonical({\n schemaVersion: 1,\n revisionNumber: revision.revisionNumber,\n policyId: revision.policyId,\n domainId: revision.domainId,\n materialId: revision.materialId,\n baseRevisionId: revision.baseRevisionId,\n baseGeneration: revision.baseGeneration,\n description: revision.description,\n materialClassIds: revision.materialClassIds,\n properties: revision.properties,\n testSpecificationIds: revision.testSpecificationIds,\n effectiveFrom: revision.effectiveFrom.toISOString(),\n reason: revision.reason\n })\n )\n .digest('hex')\n}\n\n/** Display values are a checked projection of the frozen revision, never a second editable source. */\nexport async function materialDefinitionApprovalInput(manager: EntityManager, domainId: string, revisionId: string) {\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.contentHash !== materialDefinitionSubmissionHash(draft)) refuse('INVALID_SUBMISSION')\n const material = await subject(manager, domainId, draft.materialId)\n const base = draft.baseRevisionId ? await revision(manager, domainId, draft.baseRevisionId) : null\n const plan = base ? await manager.findOneBy(MaterialDefinitionPlan, {\n domain: { id: domainId }, material: { id: draft.materialId }, generation: draft.baseGeneration\n }) : null\n const segment = plan && base ? await manager.findOneBy(MaterialDefinitionSegment, {\n domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }\n }) : null\n const values = (row: MaterialDefinitionRevision) => ({\n revisionNumber: row.revisionNumber,\n detail: {\n revisionId: row.id, createdAt: row.createdAt.toISOString(), frozenAt: row.frozenAt?.toISOString(),\n effectiveFrom: row.effectiveFrom.toISOString(), reason: row.reason,\n ...(row.id === base?.id && segment ? { validFrom: segment.validFrom.toISOString(), validTo: segment.validTo?.toISOString() ?? null } : {})\n },\n description: row.description,\n materialClassIds: row.materialClassIds,\n properties: row.properties,\n testSpecificationIds: row.testSpecificationIds\n })\n return {\n headline: material.name,\n reason: draft.reason,\n effectiveFrom: draft.effectiveFrom.toISOString(),\n before: base ? values(base) : null,\n after: values(draft),\n revision: {\n revisionId: draft.id,\n hash: draft.contentHash,\n materialId: draft.materialId,\n baseGeneration: draft.baseGeneration\n }\n }\n}\n\nexport async function assertMaterialDefinitionApprovalInput(\n manager: EntityManager,\n domainId: string,\n input: Record<string, unknown>\n) {\n const reference = input?.revision as { revisionId?: string }\n if (typeof reference?.revisionId !== 'string') refuse('INVALID_SUBMISSION')\n const expected = await materialDefinitionApprovalInput(manager, domainId, reference.revisionId)\n for (const key of Object.keys(expected)) {\n if (canonical(input[key]) !== canonical(expected[key])) refuse('INVALID_SUBMISSION')\n }\n}\n\nexport interface MaterialDefinitionDraftContent {\n description?: string\n materialClassIds?: string[]\n properties?: Record<string, unknown>[]\n testSpecificationIds?: string[]\n effectiveFrom: Date | string\n reason: string\n}\nfunction content(input: MaterialDefinitionDraftContent) {\n return { ...materialDraftContent(input), effectiveFrom: instant(input.effectiveFrom), reason: text(input.reason, 'reason') }\n}\nasync function subject(manager: EntityManager, domainId: string, materialId: string) {\n const material = await manager.findOne(MaterialDefinition, {\n where: { id: materialId, domain: { id: domainId } },\n ...currentLock(manager)\n })\n if (!material) refuse('MATERIAL_NOT_FOUND')\n // Compare the current head and latest persisted plan in one SQL snapshot. A historical\n // knownAt query must not compare its selected old plan with the current head.\n const head = await manager.createQueryBuilder(MaterialDefinition, 'head')\n .leftJoin(MaterialDefinitionPlan, 'plan', 'plan.material = head.id AND plan.domain = head.domain')\n .select('head.planGeneration', 'generation')\n .addSelect('MAX(plan.generation)', 'latest')\n .where({ id: materialId, domain: { id: domainId } })\n .groupBy('head.id').addGroupBy('head.planGeneration')\n .getRawOne()\n if (!head || Number(head.generation) !== Number(head.latest ?? 0)) {\n throw new Refusal('PLAN_INTEGRITY_FAILURE', {}, 'The current plan generation does not match the latest published plan. Contact an administrator.')\n }\n return material\n}\nasync function revision(manager: EntityManager, domainId: string, revisionId: string, locked = true) {\n const found = await manager.findOne(MaterialDefinitionRevision, {\n where: { id: revisionId, domain: { id: domainId } },\n ...(locked ? currentLock(manager) : {})\n })\n if (!found) refuse('REVISION_NOT_FOUND')\n return found\n}\n/** A write lock valid on every supported SQL backend, including SQLite (no SELECT FOR UPDATE). */\nasync function lockSubject(manager: EntityManager, domainId: string, materialId: string) {\n transaction(manager)\n const locked = await manager\n .createQueryBuilder()\n .update(MaterialDefinition)\n .set({ revisionLock: () => 'revision_lock + 1' })\n .where({ id: materialId, domain: { id: domainId } })\n .execute()\n if (locked.affected !== 1) refuse('MATERIAL_NOT_FOUND')\n return subject(manager, domainId, materialId)\n}\n\nexport async function createMaterialDefinitionDraft(\n manager: EntityManager,\n domainId: string,\n creatorId: string,\n asked: { materialId?: string; name?: string; baseRevisionId?: string; content: MaterialDefinitionDraftContent }\n) {\n transaction(manager)\n const accepted = content(asked.content)\n await validateMaterialReferences(manager, domainId, accepted)\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n let material: MaterialDefinition\n if (asked.materialId) {\n material = await lockSubject(manager, domainId, asked.materialId)\n } else {\n material = await manager.save(\n MaterialDefinition,\n manager.create(MaterialDefinition, {\n domain: { id: domainId },\n name: text(asked.name, 'name'),\n planGeneration: 0,\n revisionLock: 0,\n creator: { id: creatorId },\n updater: { id: creatorId }\n })\n )\n }\n const previous = await manager.findOne(MaterialDefinitionRevision, {\n where: { domain: { id: domainId }, material: { id: material.id } }, order: { revisionNumber: 'DESC' },\n ...currentLock(manager)\n })\n const revisionNumber = (previous?.revisionNumber ?? 0) + 1\n let baseRevisionId: string | null = null\n if (material.planGeneration > 0) {\n baseRevisionId = (await resolveMaterialDefinition(manager, domainId, material.id, accepted.effectiveFrom)).revision.id\n }\n if (asked.baseRevisionId && asked.baseRevisionId !== baseRevisionId) refuse('INVALID_BASE_REVISION')\n const saved = await manager.save(\n MaterialDefinitionRevision,\n manager.create(MaterialDefinitionRevision, {\n ...accepted,\n policy: { id: policy.id },\n domain: { id: domainId },\n material: { id: material.id },\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n baseGeneration: material.planGeneration,\n revisionNumber,\n editGeneration: 0,\n creator: { id: creatorId },\n createdAt: new Date(),\n frozenAt: null,\n contentHash: null,\n activityInstanceId: null\n })\n )\n return revision(manager, domainId, saved.id)\n}\n\nexport async function editMaterialDefinitionDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number,\n input: MaterialDefinitionDraftContent\n) {\n transaction(manager)\n const accepted = content(input)\n await validateMaterialReferences(manager, domainId, accepted)\n const initial = await revision(manager, domainId, revisionId, false)\n const material = await lockSubject(manager, domainId, initial.materialId)\n const draft = await revision(manager, domainId, revisionId)\n if (draft.creatorId !== actorId) refuse('DRAFT_NOT_OWNED')\n if (draft.frozenAt) refuse('REVISION_FROZEN')\n if (draft.baseGeneration !== material.planGeneration) refuse('PLAN_CONFLICT')\n // Moving the effective date across a scheduled boundary changes the before-image.\n const baseRevisionId =\n material.planGeneration > 0\n ? (await resolveMaterialDefinition(manager, domainId, material.id, accepted.effectiveFrom)).revision.id\n : null\n const updated = await manager\n .createQueryBuilder()\n .update(MaterialDefinitionRevision)\n .set({\n ...accepted,\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n editGeneration: expectedEditGeneration + 1\n })\n .where({\n id: revisionId,\n domain: { id: domainId },\n creator: { id: actorId },\n editGeneration: expectedEditGeneration\n })\n .andWhere('frozen_at IS NULL')\n .execute()\n if (updated.affected !== 1) refuse('DRAFT_CONFLICT')\n return revision(manager, domainId, revisionId)\n}\n\n/** Product calls this in the same transaction as issuing its worklist approval. */\nexport async function freezeMaterialDefinitionDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number\n) {\n const initial = await revision(manager, domainId, revisionId, false)\n const material = await lockSubject(manager, domainId, initial.materialId)\n const draft = await revision(manager, domainId, revisionId)\n if (draft.creatorId !== actorId) refuse('DRAFT_NOT_OWNED')\n if (draft.frozenAt) refuse('REVISION_FROZEN')\n if (draft.editGeneration !== expectedEditGeneration) refuse('DRAFT_CONFLICT')\n if (draft.baseGeneration !== material.planGeneration) refuse('PLAN_CONFLICT')\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n materialDraftContent(draft, true)\n await validateMaterialReferences(manager, domainId, draft)\n const contentHash = materialDefinitionSubmissionHash(draft)\n await manager.update(\n MaterialDefinitionRevision,\n { id: revisionId, domain: { id: domainId } },\n { frozenAt: new Date(), contentHash }\n )\n return revision(manager, domainId, revisionId)\n}\n\nexport async function bindMaterialDefinitionApproval(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n activityInstanceId: string\n) {\n transaction(manager)\n const initial = await revision(manager, domainId, revisionId, false)\n await lockSubject(manager, domainId, initial.materialId)\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.activityInstanceId) refuse('INVALID_SUBMISSION')\n await manager.update(\n MaterialDefinitionRevision,\n { id: revisionId, domain: { id: domainId } },\n { activityInstanceId: text(activityInstanceId, 'activityInstanceId') }\n )\n}\n\n/** Internal completion callback only. Never expose this as an approved=true mutation. */\nexport async function publishMaterialDefinitionRevision(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n decision: { activityInstanceId: string; approverId: string; submissionHash: string }\n) {\n return publishRevision(manager, domainId, revisionId, {\n kind: 'approved',\n activityInstanceId: decision.activityInstanceId,\n actorId: decision.approverId,\n submissionHash: decision.submissionHash\n })\n}\n\nexport async function publishUnregulatedMaterialDefinition(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n editGeneration: number\n) {\n transaction(manager)\n const initial = await revision(manager, domainId, revisionId, false)\n await lockSubject(manager, domainId, initial.materialId)\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n if (policy.approvalRequired)\n throw new Refusal('MASTER_APPROVAL_REQUIRED', {}, 'This change requires product approval.')\n const prior = await manager.findOneBy(MaterialDefinitionPlan, {\n domain: { id: domainId },\n publishedRevision: { id: revisionId },\n releaseKind: 'policy'\n })\n if (prior) {\n if (prior.publisherId !== actorId) refuse('DRAFT_NOT_OWNED')\n return prior\n }\n const frozen = await freezeMaterialDefinitionDraft(manager, domainId, actorId, revisionId, editGeneration)\n return publishRevision(manager, domainId, revisionId, { kind: 'policy', actorId, submissionHash: frozen.contentHash })\n}\n\nasync function publishRevision(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n decision: { kind: 'approved' | 'policy'; activityInstanceId?: string; actorId: string; submissionHash: string }\n) {\n const initial = await revision(manager, domainId, revisionId, false)\n const material = await lockSubject(manager, domainId, initial.materialId)\n const draft = await revision(manager, domainId, revisionId)\n if (\n !draft.frozenAt ||\n (decision.kind === 'approved'\n ? draft.activityInstanceId !== decision.activityInstanceId\n : !!draft.activityInstanceId) ||\n draft.contentHash !== decision.submissionHash ||\n materialDefinitionSubmissionHash(draft) !== decision.submissionHash\n )\n refuse('INVALID_SUBMISSION')\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n if (policy.approvalRequired !== (decision.kind === 'approved'))\n throw new Refusal('MASTER_APPROVAL_POLICY_MISMATCH', {}, 'Use the publication path required by the domain policy.')\n if (decision.kind === 'approved' && draft.creatorId === decision.actorId) refuse('AUTHOR_CANNOT_APPROVE')\n text(decision.actorId, 'publisher')\n const previousDecision = await manager.findOne(MaterialDefinitionPlan, {\n where: { domain: { id: domainId }, publishedRevision: { id: revisionId } },\n ...currentLock(manager)\n })\n if (previousDecision) return previousDecision\n if (draft.baseGeneration !== material.planGeneration) refuse('PLAN_CONFLICT')\n // Only replacement from effectiveFrom onward is supported in this slice, not arbitrary rescheduling.\n await validateMaterialReferences(manager, domainId, draft)\n if (\n await manager.findOne(MaterialDefinitionBasis, {\n where: { domain: { id: domainId }, material: { id: material.id }, businessTime: MoreThanOrEqual(draft.effectiveFrom) },\n ...currentLock(manager)\n })\n )\n refuse('RETROACTIVE_IMPACT')\n const oldPlan = await manager.findOne(MaterialDefinitionPlan, {\n where: { domain: { id: domainId }, material: { id: material.id }, generation: material.planGeneration },\n ...currentLock(manager)\n })\n if (material.planGeneration > 0 && !oldPlan) refuse('PLAN_CONFLICT')\n const oldSegments = oldPlan\n ? await manager.find(MaterialDefinitionSegment, {\n where: { domain: { id: domainId }, material: { id: material.id }, plan: { id: oldPlan.id } },\n order: { validFrom: 'ASC' },\n ...currentLock(manager)\n })\n : []\n // Do not silently erase an already approved future appointment.\n if (oldSegments.some(segment => segment.validFrom >= draft.effectiveFrom)) refuse('FUTURE_PLAN_CONFLICT')\n const recordedAt = new Date()\n const plan = await manager.save(\n MaterialDefinitionPlan,\n manager.create(MaterialDefinitionPlan, {\n domain: { id: domainId },\n material: { id: material.id },\n generation: material.planGeneration + 1,\n recordedAt,\n activityInstanceId: decision.activityInstanceId ?? null,\n submissionHash: decision.submissionHash,\n approver: decision.kind === 'approved' ? { id: decision.actorId } : null,\n publisher: { id: decision.actorId },\n releaseKind: decision.kind,\n publishedRevision: { id: revisionId },\n policy: { id: policy.id }\n })\n )\n for (const old of oldSegments) {\n await manager.save(\n MaterialDefinitionSegment,\n manager.create(MaterialDefinitionSegment, {\n domain: { id: domainId },\n material: { id: material.id },\n plan: { id: plan.id },\n revision: { id: old.revisionId },\n validFrom: old.validFrom,\n validTo: !old.validTo || old.validTo > draft.effectiveFrom ? draft.effectiveFrom : old.validTo\n })\n )\n }\n await manager.save(\n MaterialDefinitionSegment,\n manager.create(MaterialDefinitionSegment, {\n domain: { id: domainId },\n material: { id: material.id },\n plan: { id: plan.id },\n revision: { id: revisionId },\n validFrom: draft.effectiveFrom,\n validTo: null\n })\n )\n const advanced = await manager.update(\n MaterialDefinition,\n { id: material.id, domain: { id: domainId }, planGeneration: material.planGeneration },\n { planGeneration: plan.generation }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n return plan\n}\n\nexport async function resolveMaterialDefinition(\n manager: EntityManager,\n domainId: string,\n materialId: string,\n businessTime: Date | string,\n knownAt: Date | string = new Date()\n) {\n const at = instant(businessTime)\n const known = instant(knownAt)\n const plan = await manager.findOne(MaterialDefinitionPlan, {\n where: { domain: { id: domainId }, material: { id: materialId }, recordedAt: LessThanOrEqual(known) },\n order: { generation: 'DESC' },\n ...currentLock(manager)\n })\n if (!plan) refuse('NO_EFFECTIVE_REVISION')\n await subject(manager, domainId, materialId)\n const query = manager\n .createQueryBuilder(MaterialDefinitionSegment, 'segment')\n .where({ domain: { id: domainId }, material: { id: materialId }, plan: { id: plan.id } })\n .andWhere('segment.validFrom <= :at', { at })\n .andWhere('(segment.validTo IS NULL OR segment.validTo > :at)', { at })\n if (currentLock(manager).lock) query.setLock('pessimistic_write')\n const segments = await query.getMany()\n if (!segments.length) await refuseBeforeBaseline(manager, domainId, materialId, at)\n if (segments.length !== 1) refuse(segments.length ? 'AMBIGUOUS_EFFECTIVITY' : 'NO_EFFECTIVE_REVISION')\n const selected = await revision(manager, domainId, segments[0].revisionId)\n if (!selected.frozenAt || selected.contentHash !== materialDefinitionSubmissionHash(selected))\n refuse('REVISION_INTEGRITY_FAILURE')\n return { revision: selected, plan, segment: segments[0] }\n}\n\n/** 기준선보다 앞선 시각은 모른다고 말한다 — 검사 명세의 같은 자리를 보라(2026-09-24). */\nasync function refuseBeforeBaseline(manager: EntityManager, domainId: string, materialId: string, at: Date) {\n const first = await manager.findOneBy(MaterialDefinitionPlan, {\n domain: { id: domainId }, material: { id: materialId }, generation: 1, releaseKind: 'baseline'\n })\n if (!first) return\n const recorded = await manager.findOneBy(MaterialDefinitionRevision, { domain: { id: domainId }, id: first.publishedRevisionId })\n if (recorded && at < recorded.effectiveFrom)\n throw new Refusal(\n 'BEFORE_BASELINE',\n { baselineAt: recorded.effectiveFrom.toISOString() },\n `This master was first recorded at ${recorded.effectiveFrom.toISOString()}; nothing is known about it before then.`\n )\n}\n\n/**\n * **개정본이 하나도 없는 품목**마다 지금 서 있는 행을 첫 개정본으로 적는다 — 기준선(2026-09-24).\n * 규칙은 검사 명세의 `standTestSpecificationBaselines` 와 같다. 품목만의 것 둘:\n *\n * - 등급 · 검사 명세는 **이름으로** 가리킨다. 그 이름이 이 사업장에 없으면 세우지 않고 까닭을 남긴다 —\n * 없는 것을 가리키는 개정본은 새 지시가 쓰는 순간 거절된다. 이름은 사업장마다 한 번 읽어 대조한다.\n * - 행의 `testResults` 는 개정본 내용이 아니다. 루트에 그대로 남는다.\n */\nexport async function standMaterialDefinitionBaselines(manager: EntityManager, domainId: string, at: Date, edition: string) {\n transaction(manager)\n const roots = await manager\n .createQueryBuilder(MaterialDefinition, 'material')\n .leftJoin(MaterialDefinitionRevision, 'rev', 'rev.material_id = material.id AND rev.domain_id = material.domain_id')\n .where('material.domain_id = :domainId', { domainId })\n .andWhere('rev.id IS NULL')\n .getMany()\n const outcome = { stood: 0, unreadable: [] as { name: string; problem: string }[] }\n if (!roots.length) return outcome\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n const namesOf = async (entity: any) =>\n new Set((await manager.getRepository(entity).find({ where: { domain: { id: domainId } }, select: ['name'] as any })).map((one: any) => one.name))\n const classNames = await namesOf(MaterialClass)\n const specNames = await namesOf(TestSpecification)\n for (const root of roots) {\n if (root.planGeneration !== 0) {\n outcome.unreadable.push({ name: root.name, problem: 'plan without revision' })\n continue\n }\n let read: ReturnType<typeof materialDraftContent>\n try {\n read = materialDraftContent(\n {\n description: root.description ?? null,\n materialClassIds: root.materialClassIds ?? [],\n properties: root.properties ?? [],\n testSpecificationIds: root.testSpecificationIds ?? []\n },\n true\n )\n } catch (error: any) {\n outcome.unreadable.push({ name: root.name, problem: error?.message ?? String(error) })\n continue\n }\n const missing = [\n ...read.materialClassIds.filter(name => !classNames.has(name)).map(name => `material class ${name}`),\n ...read.testSpecificationIds.filter(name => !specNames.has(name)).map(name => `test specification ${name}`)\n ]\n if (missing.length) {\n outcome.unreadable.push({ name: root.name, problem: 'points at what this domain does not have: ' + missing.join(', ') })\n continue\n }\n const validFrom = root.effectiveStart && root.effectiveStart > at ? root.effectiveStart : at\n const validTo = root.effectiveEnd ?? null\n const saved = await manager.save(\n MaterialDefinitionRevision,\n manager.create(MaterialDefinitionRevision, {\n ...read,\n effectiveFrom: validFrom,\n reason: `baseline: the row as it stood, recorded by ${edition}`,\n policy: { id: policy.id },\n domain: { id: domainId },\n material: { id: root.id },\n baseRevision: null,\n baseGeneration: 0,\n revisionNumber: 1,\n editGeneration: 0,\n creator: null,\n createdAt: at,\n frozenAt: at,\n contentHash: null,\n activityInstanceId: null\n })\n )\n const stood = await revision(manager, domainId, saved.id)\n const contentHash = materialDefinitionSubmissionHash(stood)\n await manager.update(MaterialDefinitionRevision, { id: stood.id, domain: { id: domainId } }, { contentHash })\n const plan = await manager.save(\n MaterialDefinitionPlan,\n manager.create(MaterialDefinitionPlan, {\n domain: { id: domainId },\n material: { id: root.id },\n generation: 1,\n recordedAt: at,\n activityInstanceId: null,\n submissionHash: contentHash,\n approver: null,\n publisher: null,\n releaseKind: 'baseline',\n publishedRevision: { id: stood.id },\n policy: { id: policy.id }\n })\n )\n if (!validTo || validTo > validFrom) {\n await manager.save(\n MaterialDefinitionSegment,\n manager.create(MaterialDefinitionSegment, {\n domain: { id: domainId },\n material: { id: root.id },\n plan: { id: plan.id },\n revision: { id: stood.id },\n validFrom,\n validTo\n })\n )\n }\n const advanced = await manager.update(\n MaterialDefinition,\n { id: root.id, domain: { id: domainId }, planGeneration: 0 },\n { planGeneration: 1 }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n outcome.stood++\n }\n return outcome\n}\n\n/** Replay reads verify the captured digest too, not only the currently effective schedule. */\nexport async function materialDefinitionRevisionForBasis(manager: EntityManager, domainId: string, basis: MaterialDefinitionBasis) {\n if (basis.domainId !== domainId) refuse('BASIS_CONFLICT')\n const selected = await revision(manager, domainId, basis.revisionId)\n if (selected.materialId !== basis.materialId || !selected.frozenAt || selected.contentHash !== basis.contentHash || materialDefinitionSubmissionHash(selected) !== basis.contentHash) {\n refuse('REVISION_INTEGRITY_FAILURE')\n }\n const plan = await manager.findOneBy(MaterialDefinitionPlan, { id: basis.planId, domain: { id: domainId }, material: { id: basis.materialId } })\n const segments = await manager.findBy(MaterialDefinitionSegment, { domain: { id: domainId }, material: { id: basis.materialId }, plan: { id: basis.planId } })\n const matching = segments.filter(s => s.validFrom <= basis.businessTime && (!s.validTo || s.validTo > basis.businessTime))\n if (!plan || plan.recordedAt > basis.resolvedAt || matching.length !== 1 || matching[0].revisionId !== basis.revisionId) refuse('BASIS_CONFLICT')\n return selected\n}\n\n/** Must run inside the transaction that writes the business record. */\nexport async function captureMaterialDefinitionBasis(\n manager: EntityManager,\n domainId: string,\n materialId: string,\n recordKey: string,\n businessTime: Date | string\n) {\n const at = instant(businessTime)\n await lockSubject(manager, domainId, materialId)\n const existing = await manager.findOne(MaterialDefinitionBasis, {\n where: { domain: { id: domainId }, recordKey },\n ...currentLock(manager)\n })\n if (existing) {\n if (existing.materialId !== materialId || existing.businessTime.getTime() !== at.getTime()) refuse('BASIS_CONFLICT')\n await materialDefinitionRevisionForBasis(manager, domainId, existing)\n return existing\n }\n const resolvedAt = new Date()\n const selected = await resolveMaterialDefinition(manager, domainId, materialId, at, resolvedAt)\n const saved = await manager.save(\n MaterialDefinitionBasis,\n manager.create(MaterialDefinitionBasis, {\n domain: { id: domainId },\n material: { id: materialId },\n recordKey: text(recordKey, 'recordKey'),\n businessTime: at,\n resolvedAt,\n revision: { id: selected.revision.id },\n contentHash: selected.revision.contentHash,\n plan: { id: selected.plan.id }\n })\n )\n return manager.findOneByOrFail(MaterialDefinitionBasis, { id: saved.id, domain: { id: domainId } })\n}\n\nexport async function materialDefinitionRevisionOverview(\n manager: EntityManager,\n domainId: string,\n materialId: string,\n at = new Date()\n) {\n const material = await subject(manager, domainId, materialId)\n const revisions = await manager.find(MaterialDefinitionRevision, {\n where: { domain: { id: domainId }, material: { id: materialId } },\n order: { createdAt: 'ASC', id: 'ASC' }\n })\n const plan = await manager.findOne(MaterialDefinitionPlan, {\n where: { domain: { id: domainId }, material: { id: materialId }, generation: material.planGeneration }\n })\n const schedule = plan\n ? await manager.find(MaterialDefinitionSegment, {\n where: { domain: { id: domainId }, material: { id: materialId }, plan: { id: plan.id } },\n order: { validFrom: 'ASC' }\n })\n : []\n return {\n materialId,\n name: material.name,\n generation: material.planGeneration,\n at: at.toISOString(),\n schedule: schedule.map(segment => ({\n ...segment,\n state: segment.validFrom > at ? 'scheduled' : segment.validTo && segment.validTo <= at ? 'expired' : 'current'\n })),\n revisions: revisions.map(item => ({ ...item, state: item.frozenAt ? 'frozen' : 'draft' }))\n }\n}\n\n/** Read-time projection, never a clock-driven rewrite of the identity row. */\nexport async function effectiveMaterialDefinition(\n manager: EntityManager,\n domainId: string,\n material: MaterialDefinition,\n at = new Date()\n) {\n const selected = await resolveMaterialDefinition(manager, domainId, material.id, at)\n return Object.assign(new MaterialDefinition(), material, {\n revisionNumber: selected.revision.revisionNumber,\n description: selected.revision.description,\n materialClassIds: selected.revision.materialClassIds,\n properties: selected.revision.properties,\n testSpecificationIds: selected.revision.testSpecificationIds,\n effectiveStart: selected.segment.validFrom,\n effectiveEnd: selected.segment.validTo ?? undefined\n })\n}\n\n/**\n * **비규제 사업장의 「저장」 한 번** — 초안을 만들고 바로 발행한다, 한 트랜잭션에서(ADR-0086 09-22 보탬).\n * 비규제면 사람이 누를 것은 저장 하나다. 두 걸음(초안 저장 → 발행)이 구조상 필연인 것처럼 보이게 하지 않는다.\n * 이 축이 승인제면 발행이 `MASTER_APPROVAL_REQUIRED` 로 거절되고, 같은 트랜잭션이라 초안도 함께 물러난다 —\n * 반쯤 저장된 것이 남지 않는다. 개정본 · 적용계획 · 구간은 두 걸음 때와 똑같이 선다.\n */\nexport async function saveAndPublishMaterialDefinition(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n asked: { materialId?: string; name?: string; baseRevisionId?: string; content: MaterialDefinitionDraftContent; revisionId?: string; editGeneration?: number }\n) {\n // Reuse the owned draft and its concurrency guard; publishing failure rolls back the edit too.\n if (asked.revisionId && !Number.isInteger(asked.editGeneration)) refuse('DRAFT_CONFLICT')\n const draft = asked.revisionId\n ? await editMaterialDefinitionDraft(manager, domainId, actorId, asked.revisionId, asked.editGeneration!, asked.content)\n : await createMaterialDefinitionDraft(manager, domainId, actorId, asked)\n const plan = await publishUnregulatedMaterialDefinition(manager, domainId, actorId, draft.id, draft.editGeneration)\n return { revision: await revision(manager, domainId, draft.id, false), plan }\n}\n"]}
1
+ {"version":3,"file":"material-revision-service.js","sourceRoot":"","sources":["../../../server/service/material/material-revision-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto'\nimport { EntityManager, LessThanOrEqual, MoreThanOrEqual } from 'typeorm'\nimport { Refusal, writeLockSupported } from '@things-factory/shell'\nimport { masterChangePolicy } from '../master-change-policy'\nimport { materialDraftContent, validateMaterialReferences } from './material-revision-content'\nimport { MaterialDefinition } from './material-definition'\nimport { MaterialClass } from './material-class'\nimport { TestSpecification } from '../test-spec/test-specification'\nimport {\n MaterialDefinitionBasis,\n MaterialDefinitionPlan,\n MaterialDefinitionRevision,\n MaterialDefinitionSegment\n} from './material-revision'\nimport { approvalInputMatches, releaseKinds } from '../master-change-approval/approval-input'\n\nexport class MaterialDefinitionRefusal extends Refusal {\n constructor(code: string, detail?: string) {\n super(\n code,\n {},\n detail ?? MATERIAL_DEFINITION_REFUSALS[code] ?? 'The material definition change could not be applied.'\n )\n }\n}\nconst MATERIAL_DEFINITION_REFUSALS: Record<string, string> = {\n TRANSACTION_REQUIRED: 'This change requires a transaction.',\n INVALID_INSTANT: 'Enter a valid date and time including its time zone.',\n INVALID_CONTENT: 'The proposed material content is invalid.',\n MATERIAL_NOT_FOUND: 'The material does not exist in this domain.',\n REVISION_NOT_FOUND: 'The revision does not exist in this domain.',\n INVALID_BASE_REVISION: 'The proposed change is based on a different revision.',\n DRAFT_NOT_OWNED: 'Only the draft author can edit or submit it.',\n REVISION_FROZEN: 'This submitted revision cannot be edited. Create another draft.',\n DRAFT_CONFLICT: 'The draft changed. Reload it before saving.',\n PLAN_CONFLICT: 'The approved schedule changed. Review and submit a new draft.',\n INVALID_SUBMISSION: 'The submitted content does not match the frozen revision.',\n AUTHOR_CANNOT_APPROVE: 'The author cannot approve their own change.',\n RETROACTIVE_IMPACT: 'This change would alter material definitions already used by recorded transactions.',\n FUTURE_PLAN_CONFLICT: 'This change conflicts with an approved future schedule.',\n NO_EFFECTIVE_REVISION: 'There is no published revision effective at the business time.',\n AMBIGUOUS_EFFECTIVITY: 'More than one revision is effective at the business time.',\n REVISION_INTEGRITY_FAILURE: 'The stored revision does not match its signed content.',\n BASIS_CONFLICT: 'This transaction already has a different material or business time.',\n APPROVAL_LINE_REQUIRED: 'Configure an approval line before submitting this change.',\n REVISION_REQUIRED: 'Change the material through a revision draft.'\n}\nfunction refuse(code: string, detail?: string): never {\n throw new MaterialDefinitionRefusal(code, detail)\n}\nfunction transaction(manager: EntityManager) {\n if (!manager.queryRunner?.isTransactionActive) refuse('TRANSACTION_REQUIRED')\n}\n/** Current reads are required after waiting for the subject lock, including MySQL REPEATABLE READ. */\nfunction currentLock(manager: EntityManager) {\n return writeLockSupported(manager) ? { lock: { mode: 'pessimistic_write' as const } } : {}\n}\nfunction instant(value: Date | string): Date {\n if (!(value instanceof Date) && (typeof value !== 'string' || !/(Z|[+-]\\d{2}:\\d{2})$/.test(value)))\n refuse('INVALID_INSTANT')\n const result = new Date(value)\n if (!Number.isFinite(result.getTime())) refuse('INVALID_INSTANT')\n return result\n}\nfunction text(value: unknown, field: string): string {\n if (typeof value !== 'string' || !value.trim()) refuse('INVALID_CONTENT', field)\n return value.trim()\n}\n/** Sorted object keys, ordered arrays, ISO instants. This is the v1 submission encoding. */\nfunction canonical(value: any): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return '[' + value.map(canonical).join(',') + ']'\n return (\n '{' +\n Object.keys(value)\n .sort()\n .map(key => JSON.stringify(key) + ':' + canonical(value[key]))\n .join(',') +\n '}'\n )\n}\nexport function materialDefinitionSubmissionHash(revision: MaterialDefinitionRevision): string {\n return createHash('sha256')\n .update(\n canonical({\n schemaVersion: 1,\n revisionNumber: revision.revisionNumber,\n policyId: revision.policyId,\n domainId: revision.domainId,\n materialId: revision.materialId,\n baseRevisionId: revision.baseRevisionId,\n baseGeneration: revision.baseGeneration,\n description: revision.description,\n materialClassIds: revision.materialClassIds,\n properties: revision.properties,\n testSpecificationIds: revision.testSpecificationIds,\n effectiveFrom: revision.effectiveFrom.toISOString(),\n reason: revision.reason\n })\n )\n .digest('hex')\n}\n\n/** Display values are a checked projection of the frozen revision, never a second editable source. */\nexport async function materialDefinitionApprovalInput(manager: EntityManager, domainId: string, revisionId: string) {\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.contentHash !== materialDefinitionSubmissionHash(draft)) refuse('INVALID_SUBMISSION')\n const material = await subject(manager, domainId, draft.materialId)\n const base = draft.baseRevisionId ? await revision(manager, domainId, draft.baseRevisionId) : null\n const plan = base ? await manager.findOneBy(MaterialDefinitionPlan, {\n domain: { id: domainId }, material: { id: draft.materialId }, generation: draft.baseGeneration\n }) : null\n const segment = plan && base ? await manager.findOneBy(MaterialDefinitionSegment, {\n domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }\n }) : null\n /*\n * How the base was published (2026-10-20) — the approval screen names a baseline base in plain words. Only the\n * base carries it: it was published before this draft existed and never changes, so the snapshot stays pinned.\n * The proposal is unpublished here and would read differently once published.\n */\n const basePlan = base ? await manager.findOneBy(MaterialDefinitionPlan, { domain: { id: domainId }, publishedRevision: { id: base.id } }) : null\n const values = (row: MaterialDefinitionRevision) => ({\n revisionNumber: row.revisionNumber,\n detail: {\n revisionId: row.id, createdAt: row.createdAt.toISOString(), frozenAt: row.frozenAt?.toISOString(),\n effectiveFrom: row.effectiveFrom.toISOString(), reason: row.reason,\n ...(row.id === base?.id ? { releaseKind: basePlan?.releaseKind ?? null } : {}),\n ...(row.id === base?.id && segment ? { validFrom: segment.validFrom.toISOString(), validTo: segment.validTo?.toISOString() ?? null } : {})\n },\n description: row.description,\n materialClassIds: row.materialClassIds,\n properties: row.properties,\n testSpecificationIds: row.testSpecificationIds\n })\n return {\n headline: material.name,\n reason: draft.reason,\n effectiveFrom: draft.effectiveFrom.toISOString(),\n before: base ? values(base) : null,\n after: values(draft),\n revision: {\n revisionId: draft.id,\n hash: draft.contentHash,\n materialId: draft.materialId,\n baseGeneration: draft.baseGeneration\n }\n }\n}\n\nexport async function assertMaterialDefinitionApprovalInput(\n manager: EntityManager,\n domainId: string,\n input: Record<string, unknown>\n) {\n const reference = input?.revision as { revisionId?: string }\n if (typeof reference?.revisionId !== 'string') refuse('INVALID_SUBMISSION')\n const expected = await materialDefinitionApprovalInput(manager, domainId, reference.revisionId)\n if (!approvalInputMatches(input, expected)) refuse('INVALID_SUBMISSION')\n}\n\nexport interface MaterialDefinitionDraftContent {\n description?: string\n materialClassIds?: string[]\n properties?: Record<string, unknown>[]\n testSpecificationIds?: string[]\n effectiveFrom: Date | string\n reason: string\n}\nfunction content(input: MaterialDefinitionDraftContent) {\n return { ...materialDraftContent(input), effectiveFrom: instant(input.effectiveFrom), reason: text(input.reason, 'reason') }\n}\nasync function subject(manager: EntityManager, domainId: string, materialId: string) {\n const material = await manager.findOne(MaterialDefinition, {\n where: { id: materialId, domain: { id: domainId } },\n ...currentLock(manager)\n })\n if (!material) refuse('MATERIAL_NOT_FOUND')\n // Compare the current head and latest persisted plan in one SQL snapshot. A historical\n // knownAt query must not compare its selected old plan with the current head.\n const head = await manager.createQueryBuilder(MaterialDefinition, 'head')\n .leftJoin(MaterialDefinitionPlan, 'plan', 'plan.material = head.id AND plan.domain = head.domain')\n .select('head.planGeneration', 'generation')\n .addSelect('MAX(plan.generation)', 'latest')\n .where({ id: materialId, domain: { id: domainId } })\n .groupBy('head.id').addGroupBy('head.planGeneration')\n .getRawOne()\n if (!head || Number(head.generation) !== Number(head.latest ?? 0)) {\n throw new Refusal('PLAN_INTEGRITY_FAILURE', {}, 'The current plan generation does not match the latest published plan. Contact an administrator.')\n }\n return material\n}\nasync function revision(manager: EntityManager, domainId: string, revisionId: string, locked = true) {\n const found = await manager.findOne(MaterialDefinitionRevision, {\n where: { id: revisionId, domain: { id: domainId } },\n ...(locked ? currentLock(manager) : {})\n })\n if (!found) refuse('REVISION_NOT_FOUND')\n return found\n}\n/** A write lock valid on every supported SQL backend, including SQLite (no SELECT FOR UPDATE). */\nasync function lockSubject(manager: EntityManager, domainId: string, materialId: string) {\n transaction(manager)\n const locked = await manager\n .createQueryBuilder()\n .update(MaterialDefinition)\n .set({ revisionLock: () => 'revision_lock + 1' })\n .where({ id: materialId, domain: { id: domainId } })\n .execute()\n if (locked.affected !== 1) refuse('MATERIAL_NOT_FOUND')\n return subject(manager, domainId, materialId)\n}\n\nexport async function createMaterialDefinitionDraft(\n manager: EntityManager,\n domainId: string,\n creatorId: string,\n asked: { materialId?: string; name?: string; baseRevisionId?: string; content: MaterialDefinitionDraftContent }\n) {\n transaction(manager)\n const accepted = content(asked.content)\n await validateMaterialReferences(manager, domainId, accepted)\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n let material: MaterialDefinition\n if (asked.materialId) {\n material = await lockSubject(manager, domainId, asked.materialId)\n } else {\n material = await manager.save(\n MaterialDefinition,\n manager.create(MaterialDefinition, {\n domain: { id: domainId },\n name: text(asked.name, 'name'),\n planGeneration: 0,\n revisionLock: 0,\n creator: { id: creatorId },\n updater: { id: creatorId }\n })\n )\n }\n const previous = await manager.findOne(MaterialDefinitionRevision, {\n where: { domain: { id: domainId }, material: { id: material.id } }, order: { revisionNumber: 'DESC' },\n ...currentLock(manager)\n })\n const revisionNumber = (previous?.revisionNumber ?? 0) + 1\n let baseRevisionId: string | null = null\n if (material.planGeneration > 0) {\n baseRevisionId = (await resolveMaterialDefinition(manager, domainId, material.id, accepted.effectiveFrom)).revision.id\n }\n if (asked.baseRevisionId && asked.baseRevisionId !== baseRevisionId) refuse('INVALID_BASE_REVISION')\n const saved = await manager.save(\n MaterialDefinitionRevision,\n manager.create(MaterialDefinitionRevision, {\n ...accepted,\n policy: { id: policy.id },\n domain: { id: domainId },\n material: { id: material.id },\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n baseGeneration: material.planGeneration,\n revisionNumber,\n editGeneration: 0,\n creator: { id: creatorId },\n createdAt: new Date(),\n frozenAt: null,\n contentHash: null,\n activityInstanceId: null\n })\n )\n return revision(manager, domainId, saved.id)\n}\n\nexport async function editMaterialDefinitionDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number,\n input: MaterialDefinitionDraftContent\n) {\n transaction(manager)\n const accepted = content(input)\n await validateMaterialReferences(manager, domainId, accepted)\n const initial = await revision(manager, domainId, revisionId, false)\n const material = await lockSubject(manager, domainId, initial.materialId)\n const draft = await revision(manager, domainId, revisionId)\n if (draft.creatorId !== actorId) refuse('DRAFT_NOT_OWNED')\n if (draft.frozenAt) refuse('REVISION_FROZEN')\n if (draft.baseGeneration !== material.planGeneration) refuse('PLAN_CONFLICT')\n // Moving the effective date across a scheduled boundary changes the before-image.\n const baseRevisionId =\n material.planGeneration > 0\n ? (await resolveMaterialDefinition(manager, domainId, material.id, accepted.effectiveFrom)).revision.id\n : null\n const updated = await manager\n .createQueryBuilder()\n .update(MaterialDefinitionRevision)\n .set({\n ...accepted,\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n editGeneration: expectedEditGeneration + 1\n })\n .where({\n id: revisionId,\n domain: { id: domainId },\n creator: { id: actorId },\n editGeneration: expectedEditGeneration\n })\n .andWhere('frozen_at IS NULL')\n .execute()\n if (updated.affected !== 1) refuse('DRAFT_CONFLICT')\n return revision(manager, domainId, revisionId)\n}\n\n/** Product calls this in the same transaction as issuing its worklist approval. */\nexport async function freezeMaterialDefinitionDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number\n) {\n const initial = await revision(manager, domainId, revisionId, false)\n const material = await lockSubject(manager, domainId, initial.materialId)\n const draft = await revision(manager, domainId, revisionId)\n if (draft.creatorId !== actorId) refuse('DRAFT_NOT_OWNED')\n if (draft.frozenAt) refuse('REVISION_FROZEN')\n if (draft.editGeneration !== expectedEditGeneration) refuse('DRAFT_CONFLICT')\n if (draft.baseGeneration !== material.planGeneration) refuse('PLAN_CONFLICT')\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n materialDraftContent(draft, true)\n await validateMaterialReferences(manager, domainId, draft)\n const contentHash = materialDefinitionSubmissionHash(draft)\n await manager.update(\n MaterialDefinitionRevision,\n { id: revisionId, domain: { id: domainId } },\n { frozenAt: new Date(), contentHash }\n )\n return revision(manager, domainId, revisionId)\n}\n\nexport async function bindMaterialDefinitionApproval(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n activityInstanceId: string\n) {\n transaction(manager)\n const initial = await revision(manager, domainId, revisionId, false)\n await lockSubject(manager, domainId, initial.materialId)\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.activityInstanceId) refuse('INVALID_SUBMISSION')\n await manager.update(\n MaterialDefinitionRevision,\n { id: revisionId, domain: { id: domainId } },\n { activityInstanceId: text(activityInstanceId, 'activityInstanceId') }\n )\n}\n\n/** Internal completion callback only. Never expose this as an approved=true mutation. */\nexport async function publishMaterialDefinitionRevision(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n decision: { activityInstanceId: string; approverId: string; submissionHash: string }\n) {\n return publishRevision(manager, domainId, revisionId, {\n kind: 'approved',\n activityInstanceId: decision.activityInstanceId,\n actorId: decision.approverId,\n submissionHash: decision.submissionHash\n })\n}\n\nexport async function publishUnregulatedMaterialDefinition(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n editGeneration: number\n) {\n transaction(manager)\n const initial = await revision(manager, domainId, revisionId, false)\n await lockSubject(manager, domainId, initial.materialId)\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n if (policy.approvalRequired)\n throw new Refusal('MASTER_APPROVAL_REQUIRED', {}, 'This change requires product approval.')\n const prior = await manager.findOneBy(MaterialDefinitionPlan, {\n domain: { id: domainId },\n publishedRevision: { id: revisionId },\n releaseKind: 'policy'\n })\n if (prior) {\n if (prior.publisherId !== actorId) refuse('DRAFT_NOT_OWNED')\n return prior\n }\n const frozen = await freezeMaterialDefinitionDraft(manager, domainId, actorId, revisionId, editGeneration)\n return publishRevision(manager, domainId, revisionId, { kind: 'policy', actorId, submissionHash: frozen.contentHash })\n}\n\nasync function publishRevision(\n manager: EntityManager,\n domainId: string,\n revisionId: string,\n decision: { kind: 'approved' | 'policy'; activityInstanceId?: string; actorId: string; submissionHash: string }\n) {\n const initial = await revision(manager, domainId, revisionId, false)\n const material = await lockSubject(manager, domainId, initial.materialId)\n const draft = await revision(manager, domainId, revisionId)\n if (\n !draft.frozenAt ||\n (decision.kind === 'approved'\n ? draft.activityInstanceId !== decision.activityInstanceId\n : !!draft.activityInstanceId) ||\n draft.contentHash !== decision.submissionHash ||\n materialDefinitionSubmissionHash(draft) !== decision.submissionHash\n )\n refuse('INVALID_SUBMISSION')\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n if (policy.approvalRequired !== (decision.kind === 'approved'))\n throw new Refusal('MASTER_APPROVAL_POLICY_MISMATCH', {}, 'Use the publication path required by the domain policy.')\n if (decision.kind === 'approved' && draft.creatorId === decision.actorId) refuse('AUTHOR_CANNOT_APPROVE')\n text(decision.actorId, 'publisher')\n const previousDecision = await manager.findOne(MaterialDefinitionPlan, {\n where: { domain: { id: domainId }, publishedRevision: { id: revisionId } },\n ...currentLock(manager)\n })\n if (previousDecision) return previousDecision\n if (draft.baseGeneration !== material.planGeneration) refuse('PLAN_CONFLICT')\n // Only replacement from effectiveFrom onward is supported in this slice, not arbitrary rescheduling.\n await validateMaterialReferences(manager, domainId, draft)\n if (\n await manager.findOne(MaterialDefinitionBasis, {\n where: { domain: { id: domainId }, material: { id: material.id }, businessTime: MoreThanOrEqual(draft.effectiveFrom) },\n ...currentLock(manager)\n })\n )\n refuse('RETROACTIVE_IMPACT')\n const oldPlan = await manager.findOne(MaterialDefinitionPlan, {\n where: { domain: { id: domainId }, material: { id: material.id }, generation: material.planGeneration },\n ...currentLock(manager)\n })\n if (material.planGeneration > 0 && !oldPlan) refuse('PLAN_CONFLICT')\n const oldSegments = oldPlan\n ? await manager.find(MaterialDefinitionSegment, {\n where: { domain: { id: domainId }, material: { id: material.id }, plan: { id: oldPlan.id } },\n order: { validFrom: 'ASC' },\n ...currentLock(manager)\n })\n : []\n // Do not silently erase an already approved future appointment.\n if (oldSegments.some(segment => segment.validFrom >= draft.effectiveFrom)) refuse('FUTURE_PLAN_CONFLICT')\n const recordedAt = new Date()\n const plan = await manager.save(\n MaterialDefinitionPlan,\n manager.create(MaterialDefinitionPlan, {\n domain: { id: domainId },\n material: { id: material.id },\n generation: material.planGeneration + 1,\n recordedAt,\n activityInstanceId: decision.activityInstanceId ?? null,\n submissionHash: decision.submissionHash,\n approver: decision.kind === 'approved' ? { id: decision.actorId } : null,\n publisher: { id: decision.actorId },\n releaseKind: decision.kind,\n publishedRevision: { id: revisionId },\n policy: { id: policy.id }\n })\n )\n for (const old of oldSegments) {\n await manager.save(\n MaterialDefinitionSegment,\n manager.create(MaterialDefinitionSegment, {\n domain: { id: domainId },\n material: { id: material.id },\n plan: { id: plan.id },\n revision: { id: old.revisionId },\n validFrom: old.validFrom,\n validTo: !old.validTo || old.validTo > draft.effectiveFrom ? draft.effectiveFrom : old.validTo\n })\n )\n }\n await manager.save(\n MaterialDefinitionSegment,\n manager.create(MaterialDefinitionSegment, {\n domain: { id: domainId },\n material: { id: material.id },\n plan: { id: plan.id },\n revision: { id: revisionId },\n validFrom: draft.effectiveFrom,\n validTo: null\n })\n )\n const advanced = await manager.update(\n MaterialDefinition,\n { id: material.id, domain: { id: domainId }, planGeneration: material.planGeneration },\n { planGeneration: plan.generation }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n return plan\n}\n\nexport async function resolveMaterialDefinition(\n manager: EntityManager,\n domainId: string,\n materialId: string,\n businessTime: Date | string,\n knownAt: Date | string = new Date()\n) {\n const at = instant(businessTime)\n const known = instant(knownAt)\n const plan = await manager.findOne(MaterialDefinitionPlan, {\n where: { domain: { id: domainId }, material: { id: materialId }, recordedAt: LessThanOrEqual(known) },\n order: { generation: 'DESC' },\n ...currentLock(manager)\n })\n if (!plan) refuse('NO_EFFECTIVE_REVISION')\n await subject(manager, domainId, materialId)\n const query = manager\n .createQueryBuilder(MaterialDefinitionSegment, 'segment')\n .where({ domain: { id: domainId }, material: { id: materialId }, plan: { id: plan.id } })\n .andWhere('segment.validFrom <= :at', { at })\n .andWhere('(segment.validTo IS NULL OR segment.validTo > :at)', { at })\n if (currentLock(manager).lock) query.setLock('pessimistic_write')\n const segments = await query.getMany()\n if (!segments.length) await refuseBeforeBaseline(manager, domainId, materialId, at)\n if (segments.length !== 1) refuse(segments.length ? 'AMBIGUOUS_EFFECTIVITY' : 'NO_EFFECTIVE_REVISION')\n const selected = await revision(manager, domainId, segments[0].revisionId)\n if (!selected.frozenAt || selected.contentHash !== materialDefinitionSubmissionHash(selected))\n refuse('REVISION_INTEGRITY_FAILURE')\n return { revision: selected, plan, segment: segments[0] }\n}\n\n/** 기준선보다 앞선 시각은 모른다고 말한다 — 검사 명세의 같은 자리를 보라(2026-09-24). */\nasync function refuseBeforeBaseline(manager: EntityManager, domainId: string, materialId: string, at: Date) {\n const first = await manager.findOneBy(MaterialDefinitionPlan, {\n domain: { id: domainId }, material: { id: materialId }, generation: 1, releaseKind: 'baseline'\n })\n if (!first) return\n const recorded = await manager.findOneBy(MaterialDefinitionRevision, { domain: { id: domainId }, id: first.publishedRevisionId })\n if (recorded && at < recorded.effectiveFrom)\n throw new Refusal(\n 'BEFORE_BASELINE',\n { baselineAt: recorded.effectiveFrom.toISOString() },\n `This master was first recorded at ${recorded.effectiveFrom.toISOString()}; nothing is known about it before then.`\n )\n}\n\n/**\n * **개정본이 하나도 없는 품목**마다 지금 서 있는 행을 첫 개정본으로 적는다 — 기준선(2026-09-24).\n * 규칙은 검사 명세의 `standTestSpecificationBaselines` 와 같다. 품목만의 것 둘:\n *\n * - 등급 · 검사 명세는 **이름으로** 가리킨다. 그 이름이 이 사업장에 없으면 세우지 않고 까닭을 남긴다 —\n * 없는 것을 가리키는 개정본은 새 지시가 쓰는 순간 거절된다. 이름은 사업장마다 한 번 읽어 대조한다.\n * - 행의 `testResults` 는 개정본 내용이 아니다. 루트에 그대로 남는다.\n */\nexport async function standMaterialDefinitionBaselines(manager: EntityManager, domainId: string, at: Date, edition: string) {\n transaction(manager)\n const roots = await manager\n .createQueryBuilder(MaterialDefinition, 'material')\n .leftJoin(MaterialDefinitionRevision, 'rev', 'rev.material_id = material.id AND rev.domain_id = material.domain_id')\n .where('material.domain_id = :domainId', { domainId })\n .andWhere('rev.id IS NULL')\n .getMany()\n const outcome = { stood: 0, unreadable: [] as { name: string; problem: string }[] }\n if (!roots.length) return outcome\n const policy = await masterChangePolicy(manager, domainId, 'materialDefinition')\n const namesOf = async (entity: any) =>\n new Set((await manager.getRepository(entity).find({ where: { domain: { id: domainId } }, select: ['name'] as any })).map((one: any) => one.name))\n const classNames = await namesOf(MaterialClass)\n const specNames = await namesOf(TestSpecification)\n for (const root of roots) {\n if (root.planGeneration !== 0) {\n outcome.unreadable.push({ name: root.name, problem: 'plan without revision' })\n continue\n }\n let read: ReturnType<typeof materialDraftContent>\n try {\n read = materialDraftContent(\n {\n description: root.description ?? null,\n materialClassIds: root.materialClassIds ?? [],\n properties: root.properties ?? [],\n testSpecificationIds: root.testSpecificationIds ?? []\n },\n true\n )\n } catch (error: any) {\n outcome.unreadable.push({ name: root.name, problem: error?.message ?? String(error) })\n continue\n }\n const missing = [\n ...read.materialClassIds.filter(name => !classNames.has(name)).map(name => `material class ${name}`),\n ...read.testSpecificationIds.filter(name => !specNames.has(name)).map(name => `test specification ${name}`)\n ]\n if (missing.length) {\n outcome.unreadable.push({ name: root.name, problem: 'points at what this domain does not have: ' + missing.join(', ') })\n continue\n }\n const validFrom = root.effectiveStart && root.effectiveStart > at ? root.effectiveStart : at\n const validTo = root.effectiveEnd ?? null\n const saved = await manager.save(\n MaterialDefinitionRevision,\n manager.create(MaterialDefinitionRevision, {\n ...read,\n effectiveFrom: validFrom,\n reason: `baseline: the row as it stood, recorded by ${edition}`,\n policy: { id: policy.id },\n domain: { id: domainId },\n material: { id: root.id },\n baseRevision: null,\n baseGeneration: 0,\n revisionNumber: 1,\n editGeneration: 0,\n creator: null,\n createdAt: at,\n frozenAt: at,\n contentHash: null,\n activityInstanceId: null\n })\n )\n const stood = await revision(manager, domainId, saved.id)\n const contentHash = materialDefinitionSubmissionHash(stood)\n await manager.update(MaterialDefinitionRevision, { id: stood.id, domain: { id: domainId } }, { contentHash })\n const plan = await manager.save(\n MaterialDefinitionPlan,\n manager.create(MaterialDefinitionPlan, {\n domain: { id: domainId },\n material: { id: root.id },\n generation: 1,\n recordedAt: at,\n activityInstanceId: null,\n submissionHash: contentHash,\n approver: null,\n publisher: null,\n releaseKind: 'baseline',\n publishedRevision: { id: stood.id },\n policy: { id: policy.id }\n })\n )\n if (!validTo || validTo > validFrom) {\n await manager.save(\n MaterialDefinitionSegment,\n manager.create(MaterialDefinitionSegment, {\n domain: { id: domainId },\n material: { id: root.id },\n plan: { id: plan.id },\n revision: { id: stood.id },\n validFrom,\n validTo\n })\n )\n }\n const advanced = await manager.update(\n MaterialDefinition,\n { id: root.id, domain: { id: domainId }, planGeneration: 0 },\n { planGeneration: 1 }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n outcome.stood++\n }\n return outcome\n}\n\n/** Replay reads verify the captured digest too, not only the currently effective schedule. */\nexport async function materialDefinitionRevisionForBasis(manager: EntityManager, domainId: string, basis: MaterialDefinitionBasis) {\n if (basis.domainId !== domainId) refuse('BASIS_CONFLICT')\n const selected = await revision(manager, domainId, basis.revisionId)\n if (selected.materialId !== basis.materialId || !selected.frozenAt || selected.contentHash !== basis.contentHash || materialDefinitionSubmissionHash(selected) !== basis.contentHash) {\n refuse('REVISION_INTEGRITY_FAILURE')\n }\n const plan = await manager.findOneBy(MaterialDefinitionPlan, { id: basis.planId, domain: { id: domainId }, material: { id: basis.materialId } })\n const segments = await manager.findBy(MaterialDefinitionSegment, { domain: { id: domainId }, material: { id: basis.materialId }, plan: { id: basis.planId } })\n const matching = segments.filter(s => s.validFrom <= basis.businessTime && (!s.validTo || s.validTo > basis.businessTime))\n if (!plan || plan.recordedAt > basis.resolvedAt || matching.length !== 1 || matching[0].revisionId !== basis.revisionId) refuse('BASIS_CONFLICT')\n return selected\n}\n\n/** Must run inside the transaction that writes the business record. */\nexport async function captureMaterialDefinitionBasis(\n manager: EntityManager,\n domainId: string,\n materialId: string,\n recordKey: string,\n businessTime: Date | string\n) {\n const at = instant(businessTime)\n await lockSubject(manager, domainId, materialId)\n const existing = await manager.findOne(MaterialDefinitionBasis, {\n where: { domain: { id: domainId }, recordKey },\n ...currentLock(manager)\n })\n if (existing) {\n if (existing.materialId !== materialId || existing.businessTime.getTime() !== at.getTime()) refuse('BASIS_CONFLICT')\n await materialDefinitionRevisionForBasis(manager, domainId, existing)\n return existing\n }\n const resolvedAt = new Date()\n const selected = await resolveMaterialDefinition(manager, domainId, materialId, at, resolvedAt)\n const saved = await manager.save(\n MaterialDefinitionBasis,\n manager.create(MaterialDefinitionBasis, {\n domain: { id: domainId },\n material: { id: materialId },\n recordKey: text(recordKey, 'recordKey'),\n businessTime: at,\n resolvedAt,\n revision: { id: selected.revision.id },\n contentHash: selected.revision.contentHash,\n plan: { id: selected.plan.id }\n })\n )\n return manager.findOneByOrFail(MaterialDefinitionBasis, { id: saved.id, domain: { id: domainId } })\n}\n\nexport async function materialDefinitionRevisionOverview(\n manager: EntityManager,\n domainId: string,\n materialId: string,\n at = new Date()\n) {\n const material = await subject(manager, domainId, materialId)\n const revisions = await manager.find(MaterialDefinitionRevision, {\n where: { domain: { id: domainId }, material: { id: materialId } },\n order: { createdAt: 'ASC', id: 'ASC' }\n })\n const plan = await manager.findOne(MaterialDefinitionPlan, {\n where: { domain: { id: domainId }, material: { id: materialId }, generation: material.planGeneration }\n })\n const schedule = plan\n ? await manager.find(MaterialDefinitionSegment, {\n where: { domain: { id: domainId }, material: { id: materialId }, plan: { id: plan.id } },\n order: { validFrom: 'ASC' }\n })\n : []\n /*\n * 개정본마다 **어떻게 발행됐는지**(`releaseKind`)를 함께 싣는다 — 발행한 적용계획의 값 그대로(2026-10-20).\n * 화면은 이것으로 기준선을 알아보고 사람의 말(「최초 기록」)로 적는다. 기준선의 사유는 서버가 쓴 기록\n * 문장인데 해시에 들어가 바꿀 수 없고, 문구로 알아보면 깨지기 쉽다. 발행 전 개정본은 null.\n */\n const kindOf = releaseKinds(await manager.findBy(MaterialDefinitionPlan, { domain: { id: domainId }, material: { id: materialId } }))\n return {\n materialId,\n name: material.name,\n generation: material.planGeneration,\n at: at.toISOString(),\n schedule: schedule.map(segment => ({\n ...segment,\n state: segment.validFrom > at ? 'scheduled' : segment.validTo && segment.validTo <= at ? 'expired' : 'current'\n })),\n revisions: revisions.map(item => ({ ...item, state: item.frozenAt ? 'frozen' : 'draft',\n releaseKind: kindOf(item.id) }))\n }\n}\n\n/** Read-time projection, never a clock-driven rewrite of the identity row. */\nexport async function effectiveMaterialDefinition(\n manager: EntityManager,\n domainId: string,\n material: MaterialDefinition,\n at = new Date()\n) {\n const selected = await resolveMaterialDefinition(manager, domainId, material.id, at)\n return Object.assign(new MaterialDefinition(), material, {\n revisionNumber: selected.revision.revisionNumber,\n description: selected.revision.description,\n materialClassIds: selected.revision.materialClassIds,\n properties: selected.revision.properties,\n testSpecificationIds: selected.revision.testSpecificationIds,\n effectiveStart: selected.segment.validFrom,\n effectiveEnd: selected.segment.validTo ?? undefined\n })\n}\n\n/**\n * **비규제 사업장의 「저장」 한 번** — 초안을 만들고 바로 발행한다, 한 트랜잭션에서(ADR-0086 09-22 보탬).\n * 비규제면 사람이 누를 것은 저장 하나다. 두 걸음(초안 저장 → 발행)이 구조상 필연인 것처럼 보이게 하지 않는다.\n * 이 축이 승인제면 발행이 `MASTER_APPROVAL_REQUIRED` 로 거절되고, 같은 트랜잭션이라 초안도 함께 물러난다 —\n * 반쯤 저장된 것이 남지 않는다. 개정본 · 적용계획 · 구간은 두 걸음 때와 똑같이 선다.\n */\nexport async function saveAndPublishMaterialDefinition(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n asked: { materialId?: string; name?: string; baseRevisionId?: string; content: MaterialDefinitionDraftContent; revisionId?: string; editGeneration?: number }\n) {\n // Reuse the owned draft and its concurrency guard; publishing failure rolls back the edit too.\n if (asked.revisionId && !Number.isInteger(asked.editGeneration)) refuse('DRAFT_CONFLICT')\n const draft = asked.revisionId\n ? await editMaterialDefinitionDraft(manager, domainId, actorId, asked.revisionId, asked.editGeneration!, asked.content)\n : await createMaterialDefinitionDraft(manager, domainId, actorId, asked)\n const plan = await publishUnregulatedMaterialDefinition(manager, domainId, actorId, draft.id, draft.editGeneration)\n return { revision: await revision(manager, domainId, draft.id, false), plan }\n}\n"]}
@@ -25,6 +25,7 @@ export declare class RecipeRevisionResolver {
25
25
  inputs: import("./recipe-revision-line").RecipeRevisionInput[];
26
26
  outputs: import("./recipe-revision-line").RecipeRevisionOutput[];
27
27
  state: string;
28
+ releaseKind: import("..").ReleaseKind;
28
29
  revisionNumber: number;
29
30
  policy: import("..").MasterChangePolicy;
30
31
  policyId: string;
@@ -19,6 +19,7 @@ export declare function recipeApprovalInput(manager: EntityManager, domainId: st
19
19
  detail: {
20
20
  validFrom?: string;
21
21
  validTo?: string;
22
+ releaseKind?: "policy" | "approved" | "baseline";
22
23
  revisionId: string;
23
24
  createdAt: string;
24
25
  frozenAt: string;
@@ -36,6 +37,7 @@ export declare function recipeApprovalInput(manager: EntityManager, domainId: st
36
37
  detail: {
37
38
  validFrom?: string;
38
39
  validTo?: string;
40
+ releaseKind?: "policy" | "approved" | "baseline";
39
41
  revisionId: string;
40
42
  createdAt: string;
41
43
  frozenAt: string;
@@ -122,6 +124,7 @@ export declare function recipeRevisionOverview(manager: EntityManager, domainId:
122
124
  inputs: RecipeRevisionInput[];
123
125
  outputs: RecipeRevisionOutput[];
124
126
  state: string;
127
+ releaseKind: import("../master-change-approval/approval-input").ReleaseKind;
125
128
  revisionNumber: number;
126
129
  policy: import("../master-change-policy").MasterChangePolicy;
127
130
  policyId: string;
@@ -28,6 +28,7 @@ const operation_definition_1 = require("../operation/operation-definition");
28
28
  const route_definition_1 = require("./route-definition");
29
29
  const recipe_revision_content_1 = require("./recipe-revision-content");
30
30
  const recipe_revision_1 = require("./recipe-revision");
31
+ const approval_input_1 = require("../master-change-approval/approval-input");
31
32
  async function saveLines(manager, domainId, recipeId, revisionId, inputs, outputs) {
32
33
  const header = await manager.findOneByOrFail(recipe_revision_1.RecipeRevision, { id: revisionId, domain: { id: domainId } });
33
34
  const route = header.route ? await manager.findOneBy(route_definition_1.RouteDefinition, { domain: { id: domainId }, name: header.route }) : null;
@@ -163,11 +164,18 @@ async function recipeApprovalInput(manager, domainId, revisionId) {
163
164
  const segment = plan && base ? await manager.findOneBy(recipe_revision_1.RecipeSegment, {
164
165
  domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }
165
166
  }) : null;
167
+ /*
168
+ * How the base was published (2026-10-20) — the approval screen names a baseline base in plain words. Only the
169
+ * base carries it: it was published before this draft existed and never changes, so the snapshot stays pinned.
170
+ * The proposal is unpublished here and would read differently once published.
171
+ */
172
+ const basePlan = base ? await manager.findOneBy(recipe_revision_1.RecipePlan, { domain: { id: domainId }, publishedRevision: { id: base.id } }) : null;
166
173
  const values = (row) => ({
167
174
  revisionNumber: row.revisionNumber, ...(0, recipe_revision_content_1.recipeContentValues)(row),
168
175
  detail: {
169
176
  revisionId: row.id, createdAt: row.createdAt.toISOString(), frozenAt: row.frozenAt?.toISOString(),
170
177
  effectiveFrom: row.effectiveFrom.toISOString(), reason: row.reason,
178
+ ...(row.id === base?.id ? { releaseKind: basePlan?.releaseKind ?? null } : {}),
171
179
  ...(row.id === base?.id && segment ? { validFrom: segment.validFrom.toISOString(), validTo: segment.validTo?.toISOString() ?? null } : {})
172
180
  }
173
181
  });
@@ -190,10 +198,8 @@ async function assertRecipeApprovalInput(manager, domainId, input) {
190
198
  if (typeof reference?.revisionId !== 'string')
191
199
  refuse('INVALID_SUBMISSION');
192
200
  const expected = await recipeApprovalInput(manager, domainId, reference.revisionId);
193
- for (const key of Object.keys(expected)) {
194
- if (canonical(input[key]) !== canonical(expected[key]))
195
- refuse('INVALID_SUBMISSION');
196
- }
201
+ if (!(0, approval_input_1.approvalInputMatches)(input, expected))
202
+ refuse('INVALID_SUBMISSION');
197
203
  }
198
204
  async function subject(manager, domainId, recipeId) {
199
205
  const recipe = await manager.findOne(recipe_definition_1.RecipeDefinition, {
@@ -701,6 +707,12 @@ async function recipeRevisionOverview(manager, domainId, recipeId, at = new Date
701
707
  order: { validFrom: 'ASC' }
702
708
  })
703
709
  : [];
710
+ /*
711
+ * 개정본마다 **어떻게 발행됐는지**(`releaseKind`)를 함께 싣는다 — 발행한 적용계획의 값 그대로(2026-10-20).
712
+ * 화면은 이것으로 기준선을 알아보고 사람의 말(「최초 기록」)로 적는다. 기준선의 사유는 서버가 쓴 기록
713
+ * 문장인데 해시에 들어가 바꿀 수 없고, 문구로 알아보면 깨지기 쉽다. 발행 전 개정본은 null.
714
+ */
715
+ const kindOf = (0, approval_input_1.releaseKinds)(await manager.findBy(recipe_revision_1.RecipePlan, { domain: { id: domainId }, recipe: { id: recipeId } }));
704
716
  return {
705
717
  recipeId,
706
718
  name: recipe.name,
@@ -713,7 +725,8 @@ async function recipeRevisionOverview(manager, domainId, recipeId, at = new Date
713
725
  revisions: revisions.map(item => ({ ...item,
714
726
  inputs: item.inputs.sort((a, b) => a.position - b.position),
715
727
  outputs: item.outputs.sort((a, b) => a.position - b.position),
716
- state: item.frozenAt ? 'frozen' : 'draft' }))
728
+ state: item.frozenAt ? 'frozen' : 'draft',
729
+ releaseKind: kindOf(item.id) }))
717
730
  };
718
731
  }
719
732
  /** Read-time projection, never a clock-driven rewrite of the identity row. */