@things-factory/ops-master 10.1.37 → 10.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/bootstrap.js +8 -22
- package/dist-client/bootstrap.js.map +1 -1
- package/dist-client/master-change-policy-axes.d.ts +17 -0
- package/dist-client/master-change-policy-axes.js +17 -0
- package/dist-client/master-change-policy-axes.js.map +1 -1
- package/dist-client/master-change-policy-panel.d.ts +10 -0
- package/dist-client/master-change-policy-panel.js +79 -20
- package/dist-client/master-change-policy-panel.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/index.js +10 -0
- package/dist-server/index.js.map +1 -1
- package/dist-server/service/index.d.ts +2 -1
- package/dist-server/service/index.js +1 -0
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/master-axis.d.ts +14 -3
- package/dist-server/service/master-axis.js +16 -15
- package/dist-server/service/master-axis.js.map +1 -1
- package/dist-server/service/master-change-policy.d.ts +9 -0
- package/dist-server/service/master-change-policy.js +21 -0
- package/dist-server/service/master-change-policy.js.map +1 -1
- package/dist-server/service/material/material-revision-resolver.d.ts +7 -2
- package/dist-server/service/material/material-revision-resolver.js +18 -0
- package/dist-server/service/material/material-revision-resolver.js.map +1 -1
- package/dist-server/service/material/material-revision-service.d.ts +32 -2
- package/dist-server/service/material/material-revision-service.js +129 -0
- package/dist-server/service/material/material-revision-service.js.map +1 -1
- package/dist-server/service/material/material-revision.d.ts +7 -5
- package/dist-server/service/material/material-revision.js +2 -2
- package/dist-server/service/material/material-revision.js.map +1 -1
- package/dist-server/service/recipe/index.d.ts +1 -1
- package/dist-server/service/recipe/recipe-revision-resolver.d.ts +7 -2
- package/dist-server/service/recipe/recipe-revision-resolver.js +18 -0
- package/dist-server/service/recipe/recipe-revision-resolver.js.map +1 -1
- package/dist-server/service/recipe/recipe-revision-service.d.ts +33 -2
- package/dist-server/service/recipe/recipe-revision-service.js +139 -0
- package/dist-server/service/recipe/recipe-revision-service.js.map +1 -1
- package/dist-server/service/recipe/recipe-revision.d.ts +8 -6
- package/dist-server/service/recipe/recipe-revision.js +2 -2
- package/dist-server/service/recipe/recipe-revision.js.map +1 -1
- package/dist-server/service/revision-baseline.d.ts +63 -0
- package/dist-server/service/revision-baseline.js +72 -0
- package/dist-server/service/revision-baseline.js.map +1 -0
- package/dist-server/service/test-spec/test-spec-revision-resolver.d.ts +7 -2
- package/dist-server/service/test-spec/test-spec-revision-resolver.js +18 -0
- package/dist-server/service/test-spec/test-spec-revision-resolver.js.map +1 -1
- package/dist-server/service/test-spec/test-spec-revision-service.d.ts +37 -2
- package/dist-server/service/test-spec/test-spec-revision-service.js +122 -0
- package/dist-server/service/test-spec/test-spec-revision-service.js.map +1 -1
- package/dist-server/service/test-spec/test-spec-revision.d.ts +7 -5
- package/dist-server/service/test-spec/test-spec-revision.js +2 -2
- package/dist-server/service/test-spec/test-spec-revision.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -5
- package/translations/en.json +5 -1
- package/translations/ja.json +5 -1
- package/translations/ko.json +5 -1
- package/translations/ms.json +5 -1
- package/translations/zh.json +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revision-baseline.js","sourceRoot":"","sources":["../../server/service/revision-baseline.ts"],"names":[],"mappings":"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","sourcesContent":["import { DataSource, EntityManager } from 'typeorm'\nimport { Domain } from '@things-factory/shell'\n\nimport { standMaterialDefinitionBaselines } from './material/material-revision-service'\nimport { standRecipeBaselines } from './recipe/recipe-revision-service'\nimport { standTestSpecificationBaselines } from './test-spec/test-spec-revision-service'\n\n/**\n * **판을 올린 설치본의 기준정보에 첫 개정본을 세운다** — 기준선(2026-09-24, 수석 아키텍트 판정).\n *\n * ── 왜 필요한가 ────────────────────────────────────────────────────────────\n * 개정 체계(10.1.35)는 새로 만드는 기준정보만 개정본으로 받았고, **그 전부터 있던 행을 들이는 길이\n * 없었다.** 그래서 판을 올린 설치본은 레시피 · 품목 · 검사 명세의 개정본이 0 이고, 새 지시가 레시피를\n * 못 고르고 품목 근거를 못 찍어 **새 생산이 한 건도 안 섰다.**\n *\n * ── 왜 결재 없이, 왜 기동 때인가 ───────────────────────────────────────────\n * 첫 개정본이 단정하는 것은 「지금 이 값으로 돌고 있다」뿐이고, 시스템이 이미 그렇게 돌고 있다. 누를\n * 사람이 판단할 것이 없다. 그리고 **유효 시작이 이를수록 「모른다」 구간이 좁다** — 처음 쓰일 때 세우면\n * 판 올린 뒤부터 첫 사용까지가 모르는 구간이 된다. 규제 축도 같다 — 통제하는 것은 **바꾸는 일**이고\n * 기준선은 아무것도 안 바꾼다. 대신 자기 성격을 이름으로 댄다(발행 종류 `baseline`, 결재자 없음).\n *\n * ── 지키는 것 ──────────────────────────────────────────────────────────────\n * - 개정본이 0 인 루트만. 찾는 것은 축마다 질의 하나다.\n * - 두 번 돌아도, 서버 둘이 동시에 떠도 하나만 선다 — 개정 번호 유니크와 루트의 세대 조건부 갱신이 막는다.\n * - **도메인 × 축마다 트랜잭션 하나.** 하나가 실패해도 나머지는 선다. 실패한 도메인과 축을 크게 말한다.\n * - 세운 시각은 서버가 정한다 — 도메인마다 한 순간.\n * - 읽는 길에서 쓰지 않는다. 이 자리 하나만 세운다.\n */\n\nexport type BaselineAxis = 'testSpecification' | 'materialDefinition' | 'recipeDefinition'\n\ntype Stand = (manager: EntityManager, domainId: string, at: Date, edition: string) => Promise<{\n stood: number\n unreadable: { name: string; problem: string }[]\n}>\n\n/** 차례가 있다 — 품목이 검사 명세를, 제조법이 품목을 이름으로 가리킨다(이름은 기준선과 무관하게 있다). */\nexport const BASELINE_AXES: readonly { axis: BaselineAxis; stand: Stand }[] = [\n { axis: 'testSpecification', stand: standTestSpecificationBaselines },\n { axis: 'materialDefinition', stand: standMaterialDefinitionBaselines },\n { axis: 'recipeDefinition', stand: standRecipeBaselines }\n]\n\nexport interface BaselineReport {\n domain: string\n axis: BaselineAxis\n stood: number\n unreadable: { name: string; problem: string }[]\n /** 이 축의 트랜잭션이 통째로 실패했다 — 그 도메인의 그 축은 아무것도 안 섰다. */\n failed?: string\n}\n\n/** 이 판의 이름 — 기준선의 사유에 남는다. */\nexport function baselineEdition(): string {\n try {\n return `@things-factory/ops-master ${require('../../package.json').version}`\n } catch {\n return '@things-factory/ops-master'\n }\n}\n\nexport async function standMasterBaselines(\n dataSource: DataSource,\n options: { edition?: string; domains?: Domain[]; axes?: readonly { axis: BaselineAxis; stand: Stand }[] } = {}\n): Promise<BaselineReport[]> {\n const edition = options.edition ?? baselineEdition()\n const domains = options.domains ?? (await dataSource.getRepository(Domain).find())\n const axes = options.axes ?? BASELINE_AXES\n const reports: BaselineReport[] = []\n\n for (const domain of domains) {\n const at = new Date()\n for (const { axis, stand } of axes) {\n try {\n const outcome = await dataSource.transaction(manager => stand(manager, domain.id, at, edition))\n reports.push({ domain: domain.name, axis, ...outcome })\n } catch (error: any) {\n reports.push({ domain: domain.name, axis, stood: 0, unreadable: [], failed: error?.code ?? error?.message ?? String(error) })\n }\n }\n }\n return reports\n}\n\n/**\n * 기동 때 부른다. **서버를 반쯤 뜬 채로 두지 않는다** — 여기서 무엇이 실패해도 던지지 않고 말한다.\n * 한 도메인의 실패는 그 도메인만의 것이다.\n */\nexport async function standMasterBaselinesAtBoot(dataSource: DataSource) {\n let reports: BaselineReport[]\n try {\n reports = await standMasterBaselines(dataSource)\n } catch (error: any) {\n console.error(`[ops-master] 기준선을 세우지 못했습니다 — 도메인을 읽지 못함: ${error?.message ?? error}`)\n return []\n }\n for (const report of reports) {\n const where = `${report.domain} · ${report.axis}`\n if (report.failed) {\n console.error(`[ops-master] ⚠ 기준선을 세우지 못했습니다 — ${where}: ${report.failed}. 이 사업장의 이 기준정보는 새 업무가 고를 것이 없습니다.`)\n continue\n }\n if (report.stood) console.info(`[ops-master] 기준선 ${where}: ${report.stood} 건을 첫 개정본으로 세웠습니다`)\n for (const one of report.unreadable) {\n console.warn(`[ops-master] ⚠ 기준선을 못 세운 행 — ${where} · ${one.name}: ${one.problem}`)\n }\n }\n return reports\n}\n"]}
|
|
@@ -40,8 +40,8 @@ export declare class TestSpecificationRevisionResolver {
|
|
|
40
40
|
criteria: import("@operato/ops-contract").TestSpecificationCriterion[];
|
|
41
41
|
effectiveFrom: Date;
|
|
42
42
|
reason: string;
|
|
43
|
-
creator: import("@things-factory/auth-base").User;
|
|
44
|
-
creatorId: string;
|
|
43
|
+
creator: import("@things-factory/auth-base").User | null;
|
|
44
|
+
creatorId: string | null;
|
|
45
45
|
createdAt: Date;
|
|
46
46
|
frozenAt: Date | null;
|
|
47
47
|
contentHash: string | null;
|
|
@@ -50,4 +50,9 @@ export declare class TestSpecificationRevisionResolver {
|
|
|
50
50
|
}>;
|
|
51
51
|
createTestSpecificationDraft(content: TestSpecificationDraftContent, specId: string, name: string, baseRevisionId: string, context: ResolverContext): Promise<import("./test-spec-revision").TestSpecificationRevision>;
|
|
52
52
|
editTestSpecificationDraft(revisionId: string, editGeneration: number, content: TestSpecificationDraftContent, context: ResolverContext): Promise<import("./test-spec-revision").TestSpecificationRevision>;
|
|
53
|
+
/** 비규제 사업장의 저장 한 번 — 초안과 발행이 한 트랜잭션이다. 승인제면 거절되고 아무것도 안 남는다. */
|
|
54
|
+
saveAndPublishTestSpecification(content: TestSpecificationDraftContent, specId: string, name: string, baseRevisionId: string, context: ResolverContext): Promise<{
|
|
55
|
+
revision: import("./test-spec-revision").TestSpecificationRevision;
|
|
56
|
+
plan: import("./test-spec-revision").TestSpecificationPlan;
|
|
57
|
+
}>;
|
|
53
58
|
}
|
|
@@ -22,6 +22,11 @@ let TestSpecificationRevisionResolver = class TestSpecificationRevisionResolver
|
|
|
22
22
|
const { tx, domain, user } = context.state;
|
|
23
23
|
return (0, test_spec_revision_service_1.editTestSpecificationDraft)(tx, domain.id, user.id, revisionId, editGeneration, content);
|
|
24
24
|
}
|
|
25
|
+
/** 비규제 사업장의 저장 한 번 — 초안과 발행이 한 트랜잭션이다. 승인제면 거절되고 아무것도 안 남는다. */
|
|
26
|
+
async saveAndPublishTestSpecification(content, specId, name, baseRevisionId, context) {
|
|
27
|
+
const { tx, domain, user } = context.state;
|
|
28
|
+
return (0, test_spec_revision_service_1.saveAndPublishTestSpecification)(tx, domain.id, user.id, { specId, name, baseRevisionId, content });
|
|
29
|
+
}
|
|
25
30
|
};
|
|
26
31
|
exports.TestSpecificationRevisionResolver = TestSpecificationRevisionResolver;
|
|
27
32
|
tslib_1.__decorate([
|
|
@@ -69,6 +74,19 @@ tslib_1.__decorate([
|
|
|
69
74
|
tslib_1.__metadata("design:paramtypes", [String, Number, Object, Object]),
|
|
70
75
|
tslib_1.__metadata("design:returntype", Promise)
|
|
71
76
|
], TestSpecificationRevisionResolver.prototype, "editTestSpecificationDraft", null);
|
|
77
|
+
tslib_1.__decorate([
|
|
78
|
+
(0, type_graphql_1.Directive)('@privilege(category: "ops-master", privilege: "mutation", domainOwnerGranted: true)'),
|
|
79
|
+
(0, type_graphql_1.Directive)('@transaction'),
|
|
80
|
+
(0, type_graphql_1.Mutation)(() => shell_1.ScalarObject),
|
|
81
|
+
tslib_1.__param(0, (0, type_graphql_1.Arg)('content', () => shell_1.ScalarObject)),
|
|
82
|
+
tslib_1.__param(1, (0, type_graphql_1.Arg)('specId', () => String, { nullable: true })),
|
|
83
|
+
tslib_1.__param(2, (0, type_graphql_1.Arg)('name', () => String, { nullable: true })),
|
|
84
|
+
tslib_1.__param(3, (0, type_graphql_1.Arg)('baseRevisionId', () => String, { nullable: true })),
|
|
85
|
+
tslib_1.__param(4, (0, type_graphql_1.Ctx)()),
|
|
86
|
+
tslib_1.__metadata("design:type", Function),
|
|
87
|
+
tslib_1.__metadata("design:paramtypes", [Object, String, String, String, Object]),
|
|
88
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
89
|
+
], TestSpecificationRevisionResolver.prototype, "saveAndPublishTestSpecification", null);
|
|
72
90
|
exports.TestSpecificationRevisionResolver = TestSpecificationRevisionResolver = tslib_1.__decorate([
|
|
73
91
|
(0, type_graphql_1.Resolver)(),
|
|
74
92
|
(0, type_graphql_1.UseMiddleware)(shell_1.SpeakRefusals)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-spec-revision-resolver.js","sourceRoot":"","sources":["../../../server/service/test-spec/test-spec-revision-resolver.ts"],"names":[],"mappings":";;;;AAAA,+CAAiG;AACjG,iDAAkF;AAClF,6DAAwD;AACxD,
|
|
1
|
+
{"version":3,"file":"test-spec-revision-resolver.js","sourceRoot":"","sources":["../../../server/service/test-spec/test-spec-revision-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { Arg, Ctx, Directive, Int, Mutation, Query, Resolver, UseMiddleware } from 'type-graphql'\nimport { getRepository, ScalarObject, SpeakRefusals } from '@things-factory/shell'\nimport { TestSpecification } from './test-specification'\nimport { saveAndPublishTestSpecification, createTestSpecificationDraft, editTestSpecificationDraft, publishUnregulatedTestSpecification, testSpecificationRevisionOverview, TestSpecificationDraftContent } from './test-spec-revision-service'\n\n@Resolver()\n@UseMiddleware(SpeakRefusals)\nexport class TestSpecificationRevisionResolver {\n @Directive('@privilege(category: \"ops-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(() => ScalarObject)\n async publishTestSpecificationDraft(@Arg('revisionId') revisionId: string, @Arg('editGeneration', () => Int) editGeneration: number, @Ctx() context: ResolverContext) {\n const { tx, domain, user } = context.state\n return publishUnregulatedTestSpecification(tx, domain.id, user.id, revisionId, editGeneration)\n }\n @Directive('@privilege(category: \"ops-master\", privilege: \"query\", domainOwnerGranted: true)')\n @Query(() => ScalarObject)\n async testSpecificationRevisions(@Arg('specId') specId: string, @Ctx() context: ResolverContext) {\n return testSpecificationRevisionOverview(getRepository(TestSpecification).manager, context.state.domain.id, specId)\n }\n\n @Directive('@privilege(category: \"ops-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(() => ScalarObject)\n async createTestSpecificationDraft(\n @Arg('content', () => ScalarObject) content: TestSpecificationDraftContent,\n @Arg('specId', () => String, { nullable: true }) specId: string,\n @Arg('name', () => String, { nullable: true }) name: string,\n @Arg('baseRevisionId', () => String, { nullable: true }) baseRevisionId: string,\n @Ctx() context: ResolverContext\n ) {\n const { tx, domain, user } = context.state\n return createTestSpecificationDraft(tx, domain.id, user.id, { specId, name, baseRevisionId, content })\n }\n\n @Directive('@privilege(category: \"ops-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(() => ScalarObject)\n async editTestSpecificationDraft(\n @Arg('revisionId') revisionId: string,\n @Arg('editGeneration', () => Int) editGeneration: number,\n @Arg('content', () => ScalarObject) content: TestSpecificationDraftContent,\n @Ctx() context: ResolverContext\n ) {\n const { tx, domain, user } = context.state\n return editTestSpecificationDraft(tx, domain.id, user.id, revisionId, editGeneration, content)\n }\n\n /** 비규제 사업장의 저장 한 번 — 초안과 발행이 한 트랜잭션이다. 승인제면 거절되고 아무것도 안 남는다. */\n @Directive('@privilege(category: \"ops-master\", privilege: \"mutation\", domainOwnerGranted: true)')\n @Directive('@transaction')\n @Mutation(() => ScalarObject)\n async saveAndPublishTestSpecification(\n @Arg('content', () => ScalarObject) content: TestSpecificationDraftContent,\n @Arg('specId', () => String, { nullable: true }) specId: string,\n @Arg('name', () => String, { nullable: true }) name: string,\n @Arg('baseRevisionId', () => String, { nullable: true }) baseRevisionId: string,\n @Ctx() context: ResolverContext\n ) {\n const { tx, domain, user } = context.state\n return saveAndPublishTestSpecification(tx, domain.id, user.id, { specId, name, baseRevisionId, content })\n }\n}\n"]}
|
|
@@ -78,6 +78,26 @@ export declare function resolveTestSpecification(manager: EntityManager, domainI
|
|
|
78
78
|
plan: TestSpecificationPlan;
|
|
79
79
|
segment: TestSpecificationSegment;
|
|
80
80
|
}>;
|
|
81
|
+
/**
|
|
82
|
+
* **개정본이 하나도 없는 명세**마다 지금 서 있는 행을 첫 개정본으로 적는다 — 기준선(2026-09-24).
|
|
83
|
+
*
|
|
84
|
+
* 개정 체계보다 먼저 있던 행은 한 번도 개정본을 가진 적이 없어서, 새 검사가 고를 것이 없었다. 기준선은
|
|
85
|
+
* 변경이 아니라 **지금 이 값으로 돌고 있다는 기록**이라 결재를 안 탄다. 대신 자기 성격을 이름으로 댄다 —
|
|
86
|
+
* 발행 종류 `baseline`, 결재자·작성자·발행자는 비고, 세운 시각과 판(`edition`)이 사유에 남는다.
|
|
87
|
+
*
|
|
88
|
+
* - 값은 행에 있는 그대로다. 고치지 않는다.
|
|
89
|
+
* - 유효 시작은 **세운 시각**이다(`at` — 서버가 정한다). 앞으로 소급하지 않는다. 그 앞은 모른다.
|
|
90
|
+
* - 행에 끝(`effectiveEnd`)이 적혀 있으면 그때 끝난다. 이미 지났으면 개정본만 서고 유효 구간은 없다.
|
|
91
|
+
* - 개정본이 하나라도 있는 명세는 손대지 않는다. 찾는 것은 질의 하나다.
|
|
92
|
+
* - 둘이 동시에 돌아도 하나만 선다 — 개정 번호 유니크와 루트의 세대 조건부 갱신이 막는다.
|
|
93
|
+
*/
|
|
94
|
+
export declare function standTestSpecificationBaselines(manager: EntityManager, domainId: string, at: Date, edition: string): Promise<{
|
|
95
|
+
stood: number;
|
|
96
|
+
unreadable: {
|
|
97
|
+
name: string;
|
|
98
|
+
problem: string;
|
|
99
|
+
}[];
|
|
100
|
+
}>;
|
|
81
101
|
/** Replay reads verify the captured digest too, not only the currently effective schedule. */
|
|
82
102
|
export declare function testSpecificationRevisionForBasis(manager: EntityManager, domainId: string, basis: TestSpecificationBasis): Promise<TestSpecificationRevision>;
|
|
83
103
|
/** Must run inside the transaction that writes the inspection result. */
|
|
@@ -120,8 +140,8 @@ export declare function testSpecificationRevisionOverview(manager: EntityManager
|
|
|
120
140
|
criteria: import("@operato/ops-contract").TestSpecificationCriterion[];
|
|
121
141
|
effectiveFrom: Date;
|
|
122
142
|
reason: string;
|
|
123
|
-
creator: import("@things-factory/auth-base").User;
|
|
124
|
-
creatorId: string;
|
|
143
|
+
creator: import("@things-factory/auth-base").User | null;
|
|
144
|
+
creatorId: string | null;
|
|
125
145
|
createdAt: Date;
|
|
126
146
|
frozenAt: Date | null;
|
|
127
147
|
contentHash: string | null;
|
|
@@ -136,3 +156,18 @@ export declare function effectiveTestSpecification(manager: EntityManager, domai
|
|
|
136
156
|
effectiveStart: Date;
|
|
137
157
|
effectiveEnd: Date;
|
|
138
158
|
}>;
|
|
159
|
+
/**
|
|
160
|
+
* **비규제 사업장의 「저장」 한 번** — 초안을 만들고 바로 발행한다, 한 트랜잭션에서(ADR-0086 09-22 보탬).
|
|
161
|
+
* 비규제면 사람이 누를 것은 저장 하나다. 두 걸음(초안 저장 → 발행)이 구조상 필연인 것처럼 보이게 하지 않는다.
|
|
162
|
+
* 이 축이 승인제면 발행이 `MASTER_APPROVAL_REQUIRED` 로 거절되고, 같은 트랜잭션이라 초안도 함께 물러난다 —
|
|
163
|
+
* 반쯤 저장된 것이 남지 않는다. 개정본 · 적용계획 · 구간은 두 걸음 때와 똑같이 선다.
|
|
164
|
+
*/
|
|
165
|
+
export declare function saveAndPublishTestSpecification(manager: EntityManager, domainId: string, actorId: string, asked: {
|
|
166
|
+
specId?: string;
|
|
167
|
+
name?: string;
|
|
168
|
+
baseRevisionId?: string;
|
|
169
|
+
content: TestSpecificationDraftContent;
|
|
170
|
+
}): Promise<{
|
|
171
|
+
revision: TestSpecificationRevision;
|
|
172
|
+
plan: TestSpecificationPlan;
|
|
173
|
+
}>;
|
|
@@ -11,10 +11,12 @@ exports.bindTestSpecificationApproval = bindTestSpecificationApproval;
|
|
|
11
11
|
exports.publishTestSpecificationRevision = publishTestSpecificationRevision;
|
|
12
12
|
exports.publishUnregulatedTestSpecification = publishUnregulatedTestSpecification;
|
|
13
13
|
exports.resolveTestSpecification = resolveTestSpecification;
|
|
14
|
+
exports.standTestSpecificationBaselines = standTestSpecificationBaselines;
|
|
14
15
|
exports.testSpecificationRevisionForBasis = testSpecificationRevisionForBasis;
|
|
15
16
|
exports.captureTestSpecificationBasis = captureTestSpecificationBasis;
|
|
16
17
|
exports.testSpecificationRevisionOverview = testSpecificationRevisionOverview;
|
|
17
18
|
exports.effectiveTestSpecification = effectiveTestSpecification;
|
|
19
|
+
exports.saveAndPublishTestSpecification = saveAndPublishTestSpecification;
|
|
18
20
|
const node_crypto_1 = require("node:crypto");
|
|
19
21
|
const typeorm_1 = require("typeorm");
|
|
20
22
|
const shell_1 = require("@things-factory/shell");
|
|
@@ -466,6 +468,8 @@ async function resolveTestSpecification(manager, domainId, specId, businessTime,
|
|
|
466
468
|
if (currentLock(manager).lock)
|
|
467
469
|
query.setLock('pessimistic_write');
|
|
468
470
|
const segments = await query.getMany();
|
|
471
|
+
if (!segments.length)
|
|
472
|
+
await refuseBeforeBaseline(manager, domainId, specId, at);
|
|
469
473
|
if (segments.length !== 1)
|
|
470
474
|
refuse(segments.length ? 'AMBIGUOUS_EFFECTIVITY' : 'NO_EFFECTIVE_REVISION');
|
|
471
475
|
const selected = await revision(manager, domainId, segments[0].revisionId);
|
|
@@ -473,6 +477,113 @@ async function resolveTestSpecification(manager, domainId, specId, businessTime,
|
|
|
473
477
|
refuse('REVISION_INTEGRITY_FAILURE');
|
|
474
478
|
return { revision: selected, plan, segment: segments[0] };
|
|
475
479
|
}
|
|
480
|
+
/**
|
|
481
|
+
* 기준선보다 앞선 시각을 물으면 **모른다고 말한다**(2026-09-24). 그 시각의 내용은 기록된 적이 없다 —
|
|
482
|
+
* 행이 제자리에서 덮어써졌기 때문이다. 오늘 값이나 「유효한 것 없음」으로 답하지 않는다.
|
|
483
|
+
*/
|
|
484
|
+
async function refuseBeforeBaseline(manager, domainId, specId, at) {
|
|
485
|
+
const first = await manager.findOneBy(test_spec_revision_1.TestSpecificationPlan, {
|
|
486
|
+
domain: { id: domainId }, spec: { id: specId }, generation: 1, releaseKind: 'baseline'
|
|
487
|
+
});
|
|
488
|
+
if (!first)
|
|
489
|
+
return;
|
|
490
|
+
const recorded = await manager.findOneBy(test_spec_revision_1.TestSpecificationRevision, { domain: { id: domainId }, id: first.publishedRevisionId });
|
|
491
|
+
if (recorded && at < recorded.effectiveFrom)
|
|
492
|
+
throw new shell_1.Refusal('BEFORE_BASELINE', { baselineAt: recorded.effectiveFrom.toISOString() }, `This master was first recorded at ${recorded.effectiveFrom.toISOString()}; nothing is known about it before then.`);
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* **개정본이 하나도 없는 명세**마다 지금 서 있는 행을 첫 개정본으로 적는다 — 기준선(2026-09-24).
|
|
496
|
+
*
|
|
497
|
+
* 개정 체계보다 먼저 있던 행은 한 번도 개정본을 가진 적이 없어서, 새 검사가 고를 것이 없었다. 기준선은
|
|
498
|
+
* 변경이 아니라 **지금 이 값으로 돌고 있다는 기록**이라 결재를 안 탄다. 대신 자기 성격을 이름으로 댄다 —
|
|
499
|
+
* 발행 종류 `baseline`, 결재자·작성자·발행자는 비고, 세운 시각과 판(`edition`)이 사유에 남는다.
|
|
500
|
+
*
|
|
501
|
+
* - 값은 행에 있는 그대로다. 고치지 않는다.
|
|
502
|
+
* - 유효 시작은 **세운 시각**이다(`at` — 서버가 정한다). 앞으로 소급하지 않는다. 그 앞은 모른다.
|
|
503
|
+
* - 행에 끝(`effectiveEnd`)이 적혀 있으면 그때 끝난다. 이미 지났으면 개정본만 서고 유효 구간은 없다.
|
|
504
|
+
* - 개정본이 하나라도 있는 명세는 손대지 않는다. 찾는 것은 질의 하나다.
|
|
505
|
+
* - 둘이 동시에 돌아도 하나만 선다 — 개정 번호 유니크와 루트의 세대 조건부 갱신이 막는다.
|
|
506
|
+
*/
|
|
507
|
+
async function standTestSpecificationBaselines(manager, domainId, at, edition) {
|
|
508
|
+
transaction(manager);
|
|
509
|
+
const roots = await manager
|
|
510
|
+
.createQueryBuilder(test_specification_1.TestSpecification, 'spec')
|
|
511
|
+
.leftJoin(test_spec_revision_1.TestSpecificationRevision, 'rev', 'rev.spec_id = spec.id AND rev.domain_id = spec.domain_id')
|
|
512
|
+
.where('spec.domain_id = :domainId', { domainId })
|
|
513
|
+
.andWhere('rev.id IS NULL')
|
|
514
|
+
.getMany();
|
|
515
|
+
const outcome = { stood: 0, unreadable: [] };
|
|
516
|
+
if (!roots.length)
|
|
517
|
+
return outcome;
|
|
518
|
+
const policy = await (0, master_change_policy_1.masterChangePolicy)(manager, domainId, 'testSpecification');
|
|
519
|
+
for (const root of roots) {
|
|
520
|
+
if (root.planGeneration !== 0) {
|
|
521
|
+
outcome.unreadable.push({ name: root.name, problem: 'plan without revision' });
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
const read = (0, criteria_check_1.readCriteria)(root.criteria ?? []);
|
|
525
|
+
const judged = read.read === 'failed' ? { ok: false, problems: [read.detail] } : (0, criteria_check_1.judgeCriteria)(read.criteria);
|
|
526
|
+
if (read.read === 'failed' || !judged.ok || !root.version?.trim()) {
|
|
527
|
+
outcome.unreadable.push({
|
|
528
|
+
name: root.name,
|
|
529
|
+
problem: !root.version?.trim() ? 'no version' : judged.problems.join('; ')
|
|
530
|
+
});
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
const validFrom = root.effectiveStart && root.effectiveStart > at ? root.effectiveStart : at;
|
|
534
|
+
const validTo = root.effectiveEnd ?? null;
|
|
535
|
+
const saved = await manager.save(test_spec_revision_1.TestSpecificationRevision, manager.create(test_spec_revision_1.TestSpecificationRevision, {
|
|
536
|
+
version: root.version.trim(),
|
|
537
|
+
description: root.description ?? null,
|
|
538
|
+
criteria: JSON.parse(JSON.stringify(read.criteria)),
|
|
539
|
+
effectiveFrom: validFrom,
|
|
540
|
+
reason: `baseline: the row as it stood, recorded by ${edition}`,
|
|
541
|
+
policy: { id: policy.id },
|
|
542
|
+
domain: { id: domainId },
|
|
543
|
+
spec: { id: root.id },
|
|
544
|
+
baseRevision: null,
|
|
545
|
+
baseGeneration: 0,
|
|
546
|
+
revisionNumber: 1,
|
|
547
|
+
editGeneration: 0,
|
|
548
|
+
creator: null,
|
|
549
|
+
createdAt: at,
|
|
550
|
+
frozenAt: at,
|
|
551
|
+
contentHash: null,
|
|
552
|
+
activityInstanceId: null
|
|
553
|
+
}));
|
|
554
|
+
const stood = await revision(manager, domainId, saved.id);
|
|
555
|
+
const contentHash = testSpecificationSubmissionHash(stood);
|
|
556
|
+
await manager.update(test_spec_revision_1.TestSpecificationRevision, { id: stood.id, domain: { id: domainId } }, { contentHash });
|
|
557
|
+
const plan = await manager.save(test_spec_revision_1.TestSpecificationPlan, manager.create(test_spec_revision_1.TestSpecificationPlan, {
|
|
558
|
+
domain: { id: domainId },
|
|
559
|
+
spec: { id: root.id },
|
|
560
|
+
generation: 1,
|
|
561
|
+
recordedAt: at,
|
|
562
|
+
activityInstanceId: null,
|
|
563
|
+
submissionHash: contentHash,
|
|
564
|
+
approver: null,
|
|
565
|
+
publisher: null,
|
|
566
|
+
releaseKind: 'baseline',
|
|
567
|
+
publishedRevision: { id: stood.id },
|
|
568
|
+
policy: { id: policy.id }
|
|
569
|
+
}));
|
|
570
|
+
if (!validTo || validTo > validFrom) {
|
|
571
|
+
await manager.save(test_spec_revision_1.TestSpecificationSegment, manager.create(test_spec_revision_1.TestSpecificationSegment, {
|
|
572
|
+
domain: { id: domainId },
|
|
573
|
+
spec: { id: root.id },
|
|
574
|
+
plan: { id: plan.id },
|
|
575
|
+
revision: { id: stood.id },
|
|
576
|
+
validFrom,
|
|
577
|
+
validTo
|
|
578
|
+
}));
|
|
579
|
+
}
|
|
580
|
+
const advanced = await manager.update(test_specification_1.TestSpecification, { id: root.id, domain: { id: domainId }, planGeneration: 0 }, { planGeneration: 1 });
|
|
581
|
+
if (advanced.affected !== 1)
|
|
582
|
+
refuse('PLAN_CONFLICT');
|
|
583
|
+
outcome.stood++;
|
|
584
|
+
}
|
|
585
|
+
return outcome;
|
|
586
|
+
}
|
|
476
587
|
/** Replay reads verify the captured digest too, not only the currently effective schedule. */
|
|
477
588
|
async function testSpecificationRevisionForBasis(manager, domainId, basis) {
|
|
478
589
|
if (basis.domainId !== domainId)
|
|
@@ -549,4 +660,15 @@ async function effectiveTestSpecification(manager, domainId, spec, at = new Date
|
|
|
549
660
|
effectiveEnd: selected.segment.validTo ?? undefined
|
|
550
661
|
});
|
|
551
662
|
}
|
|
663
|
+
/**
|
|
664
|
+
* **비규제 사업장의 「저장」 한 번** — 초안을 만들고 바로 발행한다, 한 트랜잭션에서(ADR-0086 09-22 보탬).
|
|
665
|
+
* 비규제면 사람이 누를 것은 저장 하나다. 두 걸음(초안 저장 → 발행)이 구조상 필연인 것처럼 보이게 하지 않는다.
|
|
666
|
+
* 이 축이 승인제면 발행이 `MASTER_APPROVAL_REQUIRED` 로 거절되고, 같은 트랜잭션이라 초안도 함께 물러난다 —
|
|
667
|
+
* 반쯤 저장된 것이 남지 않는다. 개정본 · 적용계획 · 구간은 두 걸음 때와 똑같이 선다.
|
|
668
|
+
*/
|
|
669
|
+
async function saveAndPublishTestSpecification(manager, domainId, actorId, asked) {
|
|
670
|
+
const draft = await createTestSpecificationDraft(manager, domainId, actorId, asked);
|
|
671
|
+
const plan = await publishUnregulatedTestSpecification(manager, domainId, actorId, draft.id, draft.editGeneration);
|
|
672
|
+
return { revision: await revision(manager, domainId, draft.id, false), plan };
|
|
673
|
+
}
|
|
552
674
|
//# sourceMappingURL=test-spec-revision-service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-spec-revision-service.js","sourceRoot":"","sources":["../../../server/service/test-spec/test-spec-revision-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto'\nimport { EntityManager, LessThanOrEqual, MoreThanOrEqual } from 'typeorm'\nimport { Refusal } from '@things-factory/shell'\nimport { masterChangePolicy } from '../master-change-policy'\nimport { judgeCriteria, readCriteria } from './criteria-check'\nimport { TestSpecification } from './test-specification'\nimport {\n TestSpecificationBasis,\n TestSpecificationPlan,\n TestSpecificationRevision,\n TestSpecificationSegment\n} from './test-spec-revision'\n\nexport class TestSpecificationRefusal extends Refusal {\n constructor(code: string, detail?: string) {\n super(\n code,\n {},\n detail ?? TEST_SPECIFICATION_REFUSALS[code] ?? 'The test specification change could not be applied.'\n )\n }\n}\nconst TEST_SPECIFICATION_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 specification content is invalid.',\n INVALID_CRITERIA: 'The proposed inspection criteria are invalid.',\n SPECIFICATION_NOT_FOUND: 'The specification 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 criteria already used by recorded inspections.',\n FUTURE_PLAN_CONFLICT: 'This change conflicts with an approved future schedule.',\n NO_EFFECTIVE_REVISION: 'There is no published revision effective at the inspection time.',\n AMBIGUOUS_EFFECTIVITY: 'More than one revision is effective at the inspection time.',\n REVISION_INTEGRITY_FAILURE: 'The stored revision does not match its signed content.',\n BASIS_CONFLICT: 'This inspection already has a different specification or inspection time.',\n APPROVAL_LINE_REQUIRED: 'Configure an approval line before submitting this change.',\n REVISION_REQUIRED: 'Change the specification through a revision draft.'\n}\nfunction refuse(code: string, detail?: string): never {\n throw new TestSpecificationRefusal(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 const driver = manager.connection.options.type\n return manager.queryRunner?.isTransactionActive && !['sqlite', 'better-sqlite3', 'sqljs'].includes(driver)\n ? { lock: { mode: 'pessimistic_write' as const } }\n : {}\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 testSpecificationSubmissionHash(revision: TestSpecificationRevision): 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 specId: revision.specId,\n baseRevisionId: revision.baseRevisionId,\n baseGeneration: revision.baseGeneration,\n version: revision.version,\n description: revision.description,\n criteria: revision.criteria,\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 testSpecificationApprovalInput(manager: EntityManager, domainId: string, revisionId: string) {\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.contentHash !== testSpecificationSubmissionHash(draft)) refuse('INVALID_SUBMISSION')\n const spec = await subject(manager, domainId, draft.specId)\n const base = draft.baseRevisionId ? await revision(manager, domainId, draft.baseRevisionId) : null\n const plan = base ? await manager.findOneBy(TestSpecificationPlan, {\n domain: { id: domainId }, spec: { id: draft.specId }, generation: draft.baseGeneration\n }) : null\n const segment = plan && base ? await manager.findOneBy(TestSpecificationSegment, {\n domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }\n }) : null\n const values = (row: TestSpecificationRevision) => ({\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 version: row.version,\n description: row.description,\n criteria: row.criteria\n })\n return {\n headline: spec.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 specId: draft.specId,\n baseGeneration: draft.baseGeneration\n }\n }\n}\n\nexport async function assertTestSpecificationApprovalInput(\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 testSpecificationApprovalInput(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 TestSpecificationDraftContent {\n version: string\n description?: string\n criteria: unknown\n effectiveFrom: Date | string\n reason: string\n}\nfunction content(input: TestSpecificationDraftContent) {\n const read = readCriteria(input.criteria)\n if (read.read === 'failed') refuse('INVALID_CRITERIA', read.detail)\n const judged = judgeCriteria(read.criteria)\n if (!judged.ok) refuse('INVALID_CRITERIA', judged.problems.join('\\n'))\n // A JSON round trip makes the accepted value exactly the persisted value, not a caller-owned object.\n const criteria = JSON.parse(JSON.stringify(read.criteria))\n if (input.description != null && typeof input.description !== 'string') refuse('INVALID_CONTENT', 'description')\n return {\n version: text(input.version, 'version'),\n description: input.description ?? null,\n criteria,\n effectiveFrom: instant(input.effectiveFrom),\n reason: text(input.reason, 'reason')\n }\n}\nasync function subject(manager: EntityManager, domainId: string, specId: string) {\n const spec = await manager.findOne(TestSpecification, {\n where: { id: specId, domain: { id: domainId } },\n ...currentLock(manager)\n })\n if (!spec) refuse('SPECIFICATION_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(TestSpecification, 'head')\n .leftJoin(TestSpecificationPlan, 'plan', 'plan.spec = head.id AND plan.domain = head.domain')\n .select('head.planGeneration', 'generation')\n .addSelect('MAX(plan.generation)', 'latest')\n .where({ id: specId, 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 spec\n}\nasync function revision(manager: EntityManager, domainId: string, revisionId: string, locked = true) {\n const found = await manager.findOne(TestSpecificationRevision, {\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, specId: string) {\n transaction(manager)\n const locked = await manager\n .createQueryBuilder()\n .update(TestSpecification)\n .set({ revisionLock: () => 'revision_lock + 1' })\n .where({ id: specId, domain: { id: domainId } })\n .execute()\n if (locked.affected !== 1) refuse('SPECIFICATION_NOT_FOUND')\n return subject(manager, domainId, specId)\n}\n\nexport async function createTestSpecificationDraft(\n manager: EntityManager,\n domainId: string,\n creatorId: string,\n asked: { specId?: string; name?: string; baseRevisionId?: string; content: TestSpecificationDraftContent }\n) {\n transaction(manager)\n const accepted = content(asked.content)\n const policy = await masterChangePolicy(manager, domainId, 'testSpecification')\n let spec: TestSpecification\n if (asked.specId) {\n spec = await lockSubject(manager, domainId, asked.specId)\n } else {\n spec = await manager.save(\n TestSpecification,\n manager.create(TestSpecification, {\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(TestSpecificationRevision, {\n where: { domain: { id: domainId }, spec: { id: spec.id } }, order: { revisionNumber: 'DESC' },\n ...currentLock(manager)\n })\n const revisionNumber = (previous?.revisionNumber ?? 0) + 1\n let baseRevisionId: string | null = null\n if (spec.planGeneration > 0) {\n baseRevisionId = (await resolveTestSpecification(manager, domainId, spec.id, accepted.effectiveFrom)).revision.id\n }\n if (asked.baseRevisionId && asked.baseRevisionId !== baseRevisionId) refuse('INVALID_BASE_REVISION')\n const saved = await manager.save(\n TestSpecificationRevision,\n manager.create(TestSpecificationRevision, {\n ...accepted,\n policy: { id: policy.id },\n domain: { id: domainId },\n spec: { id: spec.id },\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n baseGeneration: spec.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 editTestSpecificationDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number,\n input: TestSpecificationDraftContent\n) {\n transaction(manager)\n const accepted = content(input)\n const initial = await revision(manager, domainId, revisionId, false)\n const spec = await lockSubject(manager, domainId, initial.specId)\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 !== spec.planGeneration) refuse('PLAN_CONFLICT')\n // Moving the effective date across a scheduled boundary changes the before-image.\n const baseRevisionId =\n spec.planGeneration > 0\n ? (await resolveTestSpecification(manager, domainId, spec.id, accepted.effectiveFrom)).revision.id\n : null\n const updated = await manager\n .createQueryBuilder()\n .update(TestSpecificationRevision)\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 freezeTestSpecificationDraft(\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 spec = await lockSubject(manager, domainId, initial.specId)\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 !== spec.planGeneration) refuse('PLAN_CONFLICT')\n const policy = await masterChangePolicy(manager, domainId, 'testSpecification')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n content(draft)\n const contentHash = testSpecificationSubmissionHash(draft)\n await manager.update(\n TestSpecificationRevision,\n { id: revisionId, domain: { id: domainId } },\n { frozenAt: new Date(), contentHash }\n )\n return revision(manager, domainId, revisionId)\n}\n\nexport async function bindTestSpecificationApproval(\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.specId)\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.activityInstanceId) refuse('INVALID_SUBMISSION')\n await manager.update(\n TestSpecificationRevision,\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 publishTestSpecificationRevision(\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 publishUnregulatedTestSpecification(\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.specId)\n const policy = await masterChangePolicy(manager, domainId, 'testSpecification')\n if (policy.approvalRequired)\n throw new Refusal('MASTER_APPROVAL_REQUIRED', {}, 'This change requires product approval.')\n const prior = await manager.findOneBy(TestSpecificationPlan, {\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 freezeTestSpecificationDraft(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 spec = await lockSubject(manager, domainId, initial.specId)\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 testSpecificationSubmissionHash(draft) !== decision.submissionHash\n )\n refuse('INVALID_SUBMISSION')\n const policy = await masterChangePolicy(manager, domainId, 'testSpecification')\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(TestSpecificationPlan, {\n where: { domain: { id: domainId }, publishedRevision: { id: revisionId } },\n ...currentLock(manager)\n })\n if (previousDecision) return previousDecision\n if (draft.baseGeneration !== spec.planGeneration) refuse('PLAN_CONFLICT')\n // Only replacement from effectiveFrom onward is supported in this slice, not arbitrary rescheduling.\n if (\n await manager.findOne(TestSpecificationBasis, {\n where: { domain: { id: domainId }, spec: { id: spec.id }, businessTime: MoreThanOrEqual(draft.effectiveFrom) },\n ...currentLock(manager)\n })\n )\n refuse('RETROACTIVE_IMPACT')\n const oldPlan = await manager.findOne(TestSpecificationPlan, {\n where: { domain: { id: domainId }, spec: { id: spec.id }, generation: spec.planGeneration },\n ...currentLock(manager)\n })\n if (spec.planGeneration > 0 && !oldPlan) refuse('PLAN_CONFLICT')\n const oldSegments = oldPlan\n ? await manager.find(TestSpecificationSegment, {\n where: { domain: { id: domainId }, spec: { id: spec.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 TestSpecificationPlan,\n manager.create(TestSpecificationPlan, {\n domain: { id: domainId },\n spec: { id: spec.id },\n generation: spec.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 TestSpecificationSegment,\n manager.create(TestSpecificationSegment, {\n domain: { id: domainId },\n spec: { id: spec.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 TestSpecificationSegment,\n manager.create(TestSpecificationSegment, {\n domain: { id: domainId },\n spec: { id: spec.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 TestSpecification,\n { id: spec.id, domain: { id: domainId }, planGeneration: spec.planGeneration },\n { planGeneration: plan.generation }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n return plan\n}\n\nexport async function resolveTestSpecification(\n manager: EntityManager,\n domainId: string,\n specId: 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(TestSpecificationPlan, {\n where: { domain: { id: domainId }, spec: { id: specId }, recordedAt: LessThanOrEqual(known) },\n order: { generation: 'DESC' },\n ...currentLock(manager)\n })\n if (!plan) refuse('NO_EFFECTIVE_REVISION')\n /* 실행 조회도 뿌리와 최신 Plan 의 불변식을 지난다 — material·recipe 와 같은 자리다. */\n await subject(manager, domainId, specId)\n const query = manager\n .createQueryBuilder(TestSpecificationSegment, 'segment')\n .where({ domain: { id: domainId }, spec: { id: specId }, 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 !== 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 !== testSpecificationSubmissionHash(selected))\n refuse('REVISION_INTEGRITY_FAILURE')\n return { revision: selected, plan, segment: segments[0] }\n}\n\n/** Replay reads verify the captured digest too, not only the currently effective schedule. */\nexport async function testSpecificationRevisionForBasis(manager: EntityManager, domainId: string, basis: TestSpecificationBasis) {\n if (basis.domainId !== domainId) refuse('BASIS_CONFLICT')\n const selected = await revision(manager, domainId, basis.revisionId)\n if (selected.specId !== basis.specId || !selected.frozenAt || selected.contentHash !== basis.contentHash || testSpecificationSubmissionHash(selected) !== basis.contentHash) {\n refuse('REVISION_INTEGRITY_FAILURE')\n }\n return selected\n}\n\n/** Must run inside the transaction that writes the inspection result. */\nexport async function captureTestSpecificationBasis(\n manager: EntityManager,\n domainId: string,\n specId: string,\n recordKey: string,\n businessTime: Date | string\n) {\n const at = instant(businessTime)\n await lockSubject(manager, domainId, specId)\n const existing = await manager.findOne(TestSpecificationBasis, {\n where: { domain: { id: domainId }, recordKey },\n ...currentLock(manager)\n })\n if (existing) {\n if (existing.specId !== specId || existing.businessTime.getTime() !== at.getTime()) refuse('BASIS_CONFLICT')\n await testSpecificationRevisionForBasis(manager, domainId, existing)\n return existing\n }\n const resolvedAt = new Date()\n const selected = await resolveTestSpecification(manager, domainId, specId, at, resolvedAt)\n const saved = await manager.save(\n TestSpecificationBasis,\n manager.create(TestSpecificationBasis, {\n domain: { id: domainId },\n spec: { id: specId },\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(TestSpecificationBasis, { id: saved.id, domain: { id: domainId } })\n}\n\nexport async function testSpecificationRevisionOverview(\n manager: EntityManager,\n domainId: string,\n specId: string,\n at = new Date()\n) {\n const spec = await subject(manager, domainId, specId)\n const revisions = await manager.find(TestSpecificationRevision, {\n where: { domain: { id: domainId }, spec: { id: specId } },\n order: { createdAt: 'ASC', id: 'ASC' }\n })\n const plan = await manager.findOne(TestSpecificationPlan, {\n where: { domain: { id: domainId }, spec: { id: specId }, generation: spec.planGeneration }\n })\n const schedule = plan\n ? await manager.find(TestSpecificationSegment, {\n where: { domain: { id: domainId }, spec: { id: specId }, plan: { id: plan.id } },\n order: { validFrom: 'ASC' }\n })\n : []\n return {\n specId,\n name: spec.name,\n generation: spec.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 effectiveTestSpecification(\n manager: EntityManager,\n domainId: string,\n spec: TestSpecification,\n at = new Date()\n) {\n const selected = await resolveTestSpecification(manager, domainId, spec.id, at)\n return Object.assign(new TestSpecification(), spec, {\n version: selected.revision.version,\n description: selected.revision.description,\n criteria: selected.revision.criteria,\n effectiveStart: selected.segment.validFrom,\n effectiveEnd: selected.segment.validTo ?? undefined\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"test-spec-revision-service.js","sourceRoot":"","sources":["../../../server/service/test-spec/test-spec-revision-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto'\nimport { EntityManager, LessThanOrEqual, MoreThanOrEqual } from 'typeorm'\nimport { Refusal } from '@things-factory/shell'\nimport { masterChangePolicy } from '../master-change-policy'\nimport { judgeCriteria, readCriteria } from './criteria-check'\nimport { TestSpecification } from './test-specification'\nimport {\n TestSpecificationBasis,\n TestSpecificationPlan,\n TestSpecificationRevision,\n TestSpecificationSegment\n} from './test-spec-revision'\n\nexport class TestSpecificationRefusal extends Refusal {\n constructor(code: string, detail?: string) {\n super(\n code,\n {},\n detail ?? TEST_SPECIFICATION_REFUSALS[code] ?? 'The test specification change could not be applied.'\n )\n }\n}\nconst TEST_SPECIFICATION_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 specification content is invalid.',\n INVALID_CRITERIA: 'The proposed inspection criteria are invalid.',\n SPECIFICATION_NOT_FOUND: 'The specification 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 criteria already used by recorded inspections.',\n FUTURE_PLAN_CONFLICT: 'This change conflicts with an approved future schedule.',\n NO_EFFECTIVE_REVISION: 'There is no published revision effective at the inspection time.',\n AMBIGUOUS_EFFECTIVITY: 'More than one revision is effective at the inspection time.',\n REVISION_INTEGRITY_FAILURE: 'The stored revision does not match its signed content.',\n BASIS_CONFLICT: 'This inspection already has a different specification or inspection time.',\n APPROVAL_LINE_REQUIRED: 'Configure an approval line before submitting this change.',\n REVISION_REQUIRED: 'Change the specification through a revision draft.'\n}\nfunction refuse(code: string, detail?: string): never {\n throw new TestSpecificationRefusal(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 const driver = manager.connection.options.type\n return manager.queryRunner?.isTransactionActive && !['sqlite', 'better-sqlite3', 'sqljs'].includes(driver)\n ? { lock: { mode: 'pessimistic_write' as const } }\n : {}\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 testSpecificationSubmissionHash(revision: TestSpecificationRevision): 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 specId: revision.specId,\n baseRevisionId: revision.baseRevisionId,\n baseGeneration: revision.baseGeneration,\n version: revision.version,\n description: revision.description,\n criteria: revision.criteria,\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 testSpecificationApprovalInput(manager: EntityManager, domainId: string, revisionId: string) {\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.contentHash !== testSpecificationSubmissionHash(draft)) refuse('INVALID_SUBMISSION')\n const spec = await subject(manager, domainId, draft.specId)\n const base = draft.baseRevisionId ? await revision(manager, domainId, draft.baseRevisionId) : null\n const plan = base ? await manager.findOneBy(TestSpecificationPlan, {\n domain: { id: domainId }, spec: { id: draft.specId }, generation: draft.baseGeneration\n }) : null\n const segment = plan && base ? await manager.findOneBy(TestSpecificationSegment, {\n domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }\n }) : null\n const values = (row: TestSpecificationRevision) => ({\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 version: row.version,\n description: row.description,\n criteria: row.criteria\n })\n return {\n headline: spec.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 specId: draft.specId,\n baseGeneration: draft.baseGeneration\n }\n }\n}\n\nexport async function assertTestSpecificationApprovalInput(\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 testSpecificationApprovalInput(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 TestSpecificationDraftContent {\n version: string\n description?: string\n criteria: unknown\n effectiveFrom: Date | string\n reason: string\n}\nfunction content(input: TestSpecificationDraftContent) {\n const read = readCriteria(input.criteria)\n if (read.read === 'failed') refuse('INVALID_CRITERIA', read.detail)\n const judged = judgeCriteria(read.criteria)\n if (!judged.ok) refuse('INVALID_CRITERIA', judged.problems.join('\\n'))\n // A JSON round trip makes the accepted value exactly the persisted value, not a caller-owned object.\n const criteria = JSON.parse(JSON.stringify(read.criteria))\n if (input.description != null && typeof input.description !== 'string') refuse('INVALID_CONTENT', 'description')\n return {\n version: text(input.version, 'version'),\n description: input.description ?? null,\n criteria,\n effectiveFrom: instant(input.effectiveFrom),\n reason: text(input.reason, 'reason')\n }\n}\nasync function subject(manager: EntityManager, domainId: string, specId: string) {\n const spec = await manager.findOne(TestSpecification, {\n where: { id: specId, domain: { id: domainId } },\n ...currentLock(manager)\n })\n if (!spec) refuse('SPECIFICATION_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(TestSpecification, 'head')\n .leftJoin(TestSpecificationPlan, 'plan', 'plan.spec = head.id AND plan.domain = head.domain')\n .select('head.planGeneration', 'generation')\n .addSelect('MAX(plan.generation)', 'latest')\n .where({ id: specId, 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 spec\n}\nasync function revision(manager: EntityManager, domainId: string, revisionId: string, locked = true) {\n const found = await manager.findOne(TestSpecificationRevision, {\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, specId: string) {\n transaction(manager)\n const locked = await manager\n .createQueryBuilder()\n .update(TestSpecification)\n .set({ revisionLock: () => 'revision_lock + 1' })\n .where({ id: specId, domain: { id: domainId } })\n .execute()\n if (locked.affected !== 1) refuse('SPECIFICATION_NOT_FOUND')\n return subject(manager, domainId, specId)\n}\n\nexport async function createTestSpecificationDraft(\n manager: EntityManager,\n domainId: string,\n creatorId: string,\n asked: { specId?: string; name?: string; baseRevisionId?: string; content: TestSpecificationDraftContent }\n) {\n transaction(manager)\n const accepted = content(asked.content)\n const policy = await masterChangePolicy(manager, domainId, 'testSpecification')\n let spec: TestSpecification\n if (asked.specId) {\n spec = await lockSubject(manager, domainId, asked.specId)\n } else {\n spec = await manager.save(\n TestSpecification,\n manager.create(TestSpecification, {\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(TestSpecificationRevision, {\n where: { domain: { id: domainId }, spec: { id: spec.id } }, order: { revisionNumber: 'DESC' },\n ...currentLock(manager)\n })\n const revisionNumber = (previous?.revisionNumber ?? 0) + 1\n let baseRevisionId: string | null = null\n if (spec.planGeneration > 0) {\n baseRevisionId = (await resolveTestSpecification(manager, domainId, spec.id, accepted.effectiveFrom)).revision.id\n }\n if (asked.baseRevisionId && asked.baseRevisionId !== baseRevisionId) refuse('INVALID_BASE_REVISION')\n const saved = await manager.save(\n TestSpecificationRevision,\n manager.create(TestSpecificationRevision, {\n ...accepted,\n policy: { id: policy.id },\n domain: { id: domainId },\n spec: { id: spec.id },\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n baseGeneration: spec.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 editTestSpecificationDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number,\n input: TestSpecificationDraftContent\n) {\n transaction(manager)\n const accepted = content(input)\n const initial = await revision(manager, domainId, revisionId, false)\n const spec = await lockSubject(manager, domainId, initial.specId)\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 !== spec.planGeneration) refuse('PLAN_CONFLICT')\n // Moving the effective date across a scheduled boundary changes the before-image.\n const baseRevisionId =\n spec.planGeneration > 0\n ? (await resolveTestSpecification(manager, domainId, spec.id, accepted.effectiveFrom)).revision.id\n : null\n const updated = await manager\n .createQueryBuilder()\n .update(TestSpecificationRevision)\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 freezeTestSpecificationDraft(\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 spec = await lockSubject(manager, domainId, initial.specId)\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 !== spec.planGeneration) refuse('PLAN_CONFLICT')\n const policy = await masterChangePolicy(manager, domainId, 'testSpecification')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n content(draft)\n const contentHash = testSpecificationSubmissionHash(draft)\n await manager.update(\n TestSpecificationRevision,\n { id: revisionId, domain: { id: domainId } },\n { frozenAt: new Date(), contentHash }\n )\n return revision(manager, domainId, revisionId)\n}\n\nexport async function bindTestSpecificationApproval(\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.specId)\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.activityInstanceId) refuse('INVALID_SUBMISSION')\n await manager.update(\n TestSpecificationRevision,\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 publishTestSpecificationRevision(\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 publishUnregulatedTestSpecification(\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.specId)\n const policy = await masterChangePolicy(manager, domainId, 'testSpecification')\n if (policy.approvalRequired)\n throw new Refusal('MASTER_APPROVAL_REQUIRED', {}, 'This change requires product approval.')\n const prior = await manager.findOneBy(TestSpecificationPlan, {\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 freezeTestSpecificationDraft(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 spec = await lockSubject(manager, domainId, initial.specId)\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 testSpecificationSubmissionHash(draft) !== decision.submissionHash\n )\n refuse('INVALID_SUBMISSION')\n const policy = await masterChangePolicy(manager, domainId, 'testSpecification')\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(TestSpecificationPlan, {\n where: { domain: { id: domainId }, publishedRevision: { id: revisionId } },\n ...currentLock(manager)\n })\n if (previousDecision) return previousDecision\n if (draft.baseGeneration !== spec.planGeneration) refuse('PLAN_CONFLICT')\n // Only replacement from effectiveFrom onward is supported in this slice, not arbitrary rescheduling.\n if (\n await manager.findOne(TestSpecificationBasis, {\n where: { domain: { id: domainId }, spec: { id: spec.id }, businessTime: MoreThanOrEqual(draft.effectiveFrom) },\n ...currentLock(manager)\n })\n )\n refuse('RETROACTIVE_IMPACT')\n const oldPlan = await manager.findOne(TestSpecificationPlan, {\n where: { domain: { id: domainId }, spec: { id: spec.id }, generation: spec.planGeneration },\n ...currentLock(manager)\n })\n if (spec.planGeneration > 0 && !oldPlan) refuse('PLAN_CONFLICT')\n const oldSegments = oldPlan\n ? await manager.find(TestSpecificationSegment, {\n where: { domain: { id: domainId }, spec: { id: spec.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 TestSpecificationPlan,\n manager.create(TestSpecificationPlan, {\n domain: { id: domainId },\n spec: { id: spec.id },\n generation: spec.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 TestSpecificationSegment,\n manager.create(TestSpecificationSegment, {\n domain: { id: domainId },\n spec: { id: spec.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 TestSpecificationSegment,\n manager.create(TestSpecificationSegment, {\n domain: { id: domainId },\n spec: { id: spec.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 TestSpecification,\n { id: spec.id, domain: { id: domainId }, planGeneration: spec.planGeneration },\n { planGeneration: plan.generation }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n return plan\n}\n\nexport async function resolveTestSpecification(\n manager: EntityManager,\n domainId: string,\n specId: 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(TestSpecificationPlan, {\n where: { domain: { id: domainId }, spec: { id: specId }, recordedAt: LessThanOrEqual(known) },\n order: { generation: 'DESC' },\n ...currentLock(manager)\n })\n if (!plan) refuse('NO_EFFECTIVE_REVISION')\n /* 실행 조회도 뿌리와 최신 Plan 의 불변식을 지난다 — material·recipe 와 같은 자리다. */\n await subject(manager, domainId, specId)\n const query = manager\n .createQueryBuilder(TestSpecificationSegment, 'segment')\n .where({ domain: { id: domainId }, spec: { id: specId }, 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, specId, 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 !== testSpecificationSubmissionHash(selected))\n refuse('REVISION_INTEGRITY_FAILURE')\n return { revision: selected, plan, segment: segments[0] }\n}\n\n/**\n * 기준선보다 앞선 시각을 물으면 **모른다고 말한다**(2026-09-24). 그 시각의 내용은 기록된 적이 없다 —\n * 행이 제자리에서 덮어써졌기 때문이다. 오늘 값이나 「유효한 것 없음」으로 답하지 않는다.\n */\nasync function refuseBeforeBaseline(manager: EntityManager, domainId: string, specId: string, at: Date) {\n const first = await manager.findOneBy(TestSpecificationPlan, {\n domain: { id: domainId }, spec: { id: specId }, generation: 1, releaseKind: 'baseline'\n })\n if (!first) return\n const recorded = await manager.findOneBy(TestSpecificationRevision, { 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 *\n * 개정 체계보다 먼저 있던 행은 한 번도 개정본을 가진 적이 없어서, 새 검사가 고를 것이 없었다. 기준선은\n * 변경이 아니라 **지금 이 값으로 돌고 있다는 기록**이라 결재를 안 탄다. 대신 자기 성격을 이름으로 댄다 —\n * 발행 종류 `baseline`, 결재자·작성자·발행자는 비고, 세운 시각과 판(`edition`)이 사유에 남는다.\n *\n * - 값은 행에 있는 그대로다. 고치지 않는다.\n * - 유효 시작은 **세운 시각**이다(`at` — 서버가 정한다). 앞으로 소급하지 않는다. 그 앞은 모른다.\n * - 행에 끝(`effectiveEnd`)이 적혀 있으면 그때 끝난다. 이미 지났으면 개정본만 서고 유효 구간은 없다.\n * - 개정본이 하나라도 있는 명세는 손대지 않는다. 찾는 것은 질의 하나다.\n * - 둘이 동시에 돌아도 하나만 선다 — 개정 번호 유니크와 루트의 세대 조건부 갱신이 막는다.\n */\nexport async function standTestSpecificationBaselines(manager: EntityManager, domainId: string, at: Date, edition: string) {\n transaction(manager)\n const roots = await manager\n .createQueryBuilder(TestSpecification, 'spec')\n .leftJoin(TestSpecificationRevision, 'rev', 'rev.spec_id = spec.id AND rev.domain_id = spec.domain_id')\n .where('spec.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, '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 const read = readCriteria(root.criteria ?? [])\n const judged = read.read === 'failed' ? { ok: false, problems: [read.detail] } : judgeCriteria(read.criteria)\n if (read.read === 'failed' || !judged.ok || !root.version?.trim()) {\n outcome.unreadable.push({\n name: root.name,\n problem: !root.version?.trim() ? 'no version' : (judged as any).problems.join('; ')\n })\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 TestSpecificationRevision,\n manager.create(TestSpecificationRevision, {\n version: root.version.trim(),\n description: root.description ?? null,\n criteria: JSON.parse(JSON.stringify((read as any).criteria)),\n effectiveFrom: validFrom,\n reason: `baseline: the row as it stood, recorded by ${edition}`,\n policy: { id: policy.id },\n domain: { id: domainId },\n spec: { 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 = testSpecificationSubmissionHash(stood)\n await manager.update(TestSpecificationRevision, { id: stood.id, domain: { id: domainId } }, { contentHash })\n const plan = await manager.save(\n TestSpecificationPlan,\n manager.create(TestSpecificationPlan, {\n domain: { id: domainId },\n spec: { 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 TestSpecificationSegment,\n manager.create(TestSpecificationSegment, {\n domain: { id: domainId },\n spec: { 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 TestSpecification,\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 testSpecificationRevisionForBasis(manager: EntityManager, domainId: string, basis: TestSpecificationBasis) {\n if (basis.domainId !== domainId) refuse('BASIS_CONFLICT')\n const selected = await revision(manager, domainId, basis.revisionId)\n if (selected.specId !== basis.specId || !selected.frozenAt || selected.contentHash !== basis.contentHash || testSpecificationSubmissionHash(selected) !== basis.contentHash) {\n refuse('REVISION_INTEGRITY_FAILURE')\n }\n return selected\n}\n\n/** Must run inside the transaction that writes the inspection result. */\nexport async function captureTestSpecificationBasis(\n manager: EntityManager,\n domainId: string,\n specId: string,\n recordKey: string,\n businessTime: Date | string\n) {\n const at = instant(businessTime)\n await lockSubject(manager, domainId, specId)\n const existing = await manager.findOne(TestSpecificationBasis, {\n where: { domain: { id: domainId }, recordKey },\n ...currentLock(manager)\n })\n if (existing) {\n if (existing.specId !== specId || existing.businessTime.getTime() !== at.getTime()) refuse('BASIS_CONFLICT')\n await testSpecificationRevisionForBasis(manager, domainId, existing)\n return existing\n }\n const resolvedAt = new Date()\n const selected = await resolveTestSpecification(manager, domainId, specId, at, resolvedAt)\n const saved = await manager.save(\n TestSpecificationBasis,\n manager.create(TestSpecificationBasis, {\n domain: { id: domainId },\n spec: { id: specId },\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(TestSpecificationBasis, { id: saved.id, domain: { id: domainId } })\n}\n\nexport async function testSpecificationRevisionOverview(\n manager: EntityManager,\n domainId: string,\n specId: string,\n at = new Date()\n) {\n const spec = await subject(manager, domainId, specId)\n const revisions = await manager.find(TestSpecificationRevision, {\n where: { domain: { id: domainId }, spec: { id: specId } },\n order: { createdAt: 'ASC', id: 'ASC' }\n })\n const plan = await manager.findOne(TestSpecificationPlan, {\n where: { domain: { id: domainId }, spec: { id: specId }, generation: spec.planGeneration }\n })\n const schedule = plan\n ? await manager.find(TestSpecificationSegment, {\n where: { domain: { id: domainId }, spec: { id: specId }, plan: { id: plan.id } },\n order: { validFrom: 'ASC' }\n })\n : []\n return {\n specId,\n name: spec.name,\n generation: spec.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 effectiveTestSpecification(\n manager: EntityManager,\n domainId: string,\n spec: TestSpecification,\n at = new Date()\n) {\n const selected = await resolveTestSpecification(manager, domainId, spec.id, at)\n return Object.assign(new TestSpecification(), spec, {\n version: selected.revision.version,\n description: selected.revision.description,\n criteria: selected.revision.criteria,\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 saveAndPublishTestSpecification(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n asked: { specId?: string; name?: string; baseRevisionId?: string; content: TestSpecificationDraftContent }\n) {\n const draft = await createTestSpecificationDraft(manager, domainId, actorId, asked)\n const plan = await publishUnregulatedTestSpecification(manager, domainId, actorId, draft.id, draft.editGeneration)\n return { revision: await revision(manager, domainId, draft.id, false), plan }\n}\n"]}
|
|
@@ -23,8 +23,9 @@ export declare class TestSpecificationRevision {
|
|
|
23
23
|
criteria: TestSpecificationCriterion[];
|
|
24
24
|
effectiveFrom: Date;
|
|
25
25
|
reason: string;
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
/** Empty only on a baseline: nobody wrote it, it records the row as it already stood. */
|
|
27
|
+
creator: User | null;
|
|
28
|
+
creatorId: string | null;
|
|
28
29
|
createdAt: Date;
|
|
29
30
|
frozenAt: Date | null;
|
|
30
31
|
contentHash: string | null;
|
|
@@ -37,9 +38,10 @@ export declare class TestSpecificationPlan {
|
|
|
37
38
|
policyId: string;
|
|
38
39
|
publishedRevision: TestSpecificationRevision;
|
|
39
40
|
publishedRevisionId: string;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
/** `baseline`: stood at boot from a row that predates revisions. No approver, no publisher. */
|
|
42
|
+
releaseKind: 'approved' | 'policy' | 'baseline';
|
|
43
|
+
publisher: User | null;
|
|
44
|
+
publisherId: string | null;
|
|
43
45
|
id: string;
|
|
44
46
|
domain: Domain;
|
|
45
47
|
domainId: string;
|