@things-factory/ops-master 10.1.38 → 10.1.40
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/tsconfig.tsbuildinfo +1 -1
- package/dist-server/index.js +5 -1
- package/dist-server/index.js.map +1 -1
- package/dist-server/service/revision-baseline.d.ts +8 -0
- package/dist-server/service/revision-baseline.js +16 -1
- package/dist-server/service/revision-baseline.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/translations/en.json +8 -0
- package/translations/ja.json +8 -0
- package/translations/ko.json +8 -0
- package/translations/ms.json +8 -0
- package/translations/zh.json +8 -2
package/dist-server/index.js
CHANGED
|
@@ -10,6 +10,10 @@ tslib_1.__exportStar(require("./service"), exports);
|
|
|
10
10
|
* (§`revision-baseline`).
|
|
11
11
|
*/
|
|
12
12
|
process.on('bootstrap-module-start', () => {
|
|
13
|
-
|
|
13
|
+
/*
|
|
14
|
+
* **기동의 한 줄에 선다**(`inBootTurn`, shell). 기준선은 도메인 · 축마다 트랜잭션을 여는데, 다른 모듈의 기동
|
|
15
|
+
* 트랜잭션과 같은 SQLite 연결에서 겹치면 서로를 깨뜨린다(2026-09-24 — ops-master 와 work-shift 가 그랬다).
|
|
16
|
+
*/
|
|
17
|
+
(0, shell_1.inBootTurn)(() => (0, revision_baseline_1.standMasterBaselinesAtBoot)((0, shell_1.getDataSource)())).catch(error => console.error(`[ops-master] 기준선을 세우지 못했습니다 — ${error?.message ?? error}`));
|
|
14
18
|
});
|
|
15
19
|
//# sourceMappingURL=index.js.map
|
package/dist-server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../server/index.ts"],"names":[],"mappings":";;;AAAA,iDAAiE;AAEjE,mEAAwE;AAExE,oDAAyB;AAEzB;;;;GAIG;AACH,OAAO,CAAC,EAAE,CAAC,wBAA+B,EAAE,GAAG,EAAE;IAC/C;;;OAGG;IACH,IAAA,kBAAU,EAAC,GAAG,EAAE,CAAC,IAAA,8CAA0B,EAAC,IAAA,qBAAa,GAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAC1E,OAAO,CAAC,KAAK,CAAC,iCAAiC,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,CAC1E,CAAA;AACH,CAAC,CAAC,CAAA","sourcesContent":["import { getDataSource, inBootTurn } from '@things-factory/shell'\n\nimport { standMasterBaselinesAtBoot } from './service/revision-baseline'\n\nexport * from './service'\n\n/*\n * 판을 올린 설치본의 기준정보에 첫 개정본을 세운다(2026-09-24). 개정본이 이미 있는 것은 손대지 않으므로\n * 기동마다 불러도 된다. 무엇이 실패해도 던지지 않는다 — 서버를 반쯤 뜬 채로 두지 않는다\n * (§`revision-baseline`).\n */\nprocess.on('bootstrap-module-start' as any, () => {\n /*\n * **기동의 한 줄에 선다**(`inBootTurn`, shell). 기준선은 도메인 · 축마다 트랜잭션을 여는데, 다른 모듈의 기동\n * 트랜잭션과 같은 SQLite 연결에서 겹치면 서로를 깨뜨린다(2026-09-24 — ops-master 와 work-shift 가 그랬다).\n */\n inBootTurn(() => standMasterBaselinesAtBoot(getDataSource())).catch(error =>\n console.error(`[ops-master] 기준선을 세우지 못했습니다 — ${error?.message ?? error}`)\n )\n})\n"]}
|
|
@@ -47,6 +47,14 @@ export interface BaselineReport {
|
|
|
47
47
|
}
|
|
48
48
|
/** 이 판의 이름 — 기준선의 사유에 남는다. */
|
|
49
49
|
export declare function baselineEdition(): string;
|
|
50
|
+
/**
|
|
51
|
+
* 기준선이 실패한 까닭을 **사람이 읽을 수 있게** — 코드만이 아니라 본문을 싣는다.
|
|
52
|
+
*
|
|
53
|
+
* 앞서는 `error.code` 가 있으면 그것만 적었다. SQLite 의 실패는 코드가 늘 `SQLITE_ERROR` 라 기동 로그에
|
|
54
|
+
* 「MIRATEK · SYSTEM: SQLITE_ERROR」만 남았고, 무엇이 실패했는지(「transaction within a transaction」)는 어디에도
|
|
55
|
+
* 없었다(2026-09-24). 교대 기준선도 이 함수로 적는다.
|
|
56
|
+
*/
|
|
57
|
+
export declare function baselineFailureText(error: any): string;
|
|
50
58
|
export declare function standMasterBaselines(dataSource: DataSource, options?: {
|
|
51
59
|
edition?: string;
|
|
52
60
|
domains?: Domain[];
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BASELINE_AXES = void 0;
|
|
4
4
|
exports.baselineEdition = baselineEdition;
|
|
5
|
+
exports.baselineFailureText = baselineFailureText;
|
|
5
6
|
exports.standMasterBaselines = standMasterBaselines;
|
|
6
7
|
exports.standMasterBaselinesAtBoot = standMasterBaselinesAtBoot;
|
|
7
8
|
const shell_1 = require("@things-factory/shell");
|
|
@@ -23,6 +24,20 @@ function baselineEdition() {
|
|
|
23
24
|
return '@things-factory/ops-master';
|
|
24
25
|
}
|
|
25
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* 기준선이 실패한 까닭을 **사람이 읽을 수 있게** — 코드만이 아니라 본문을 싣는다.
|
|
29
|
+
*
|
|
30
|
+
* 앞서는 `error.code` 가 있으면 그것만 적었다. SQLite 의 실패는 코드가 늘 `SQLITE_ERROR` 라 기동 로그에
|
|
31
|
+
* 「MIRATEK · SYSTEM: SQLITE_ERROR」만 남았고, 무엇이 실패했는지(「transaction within a transaction」)는 어디에도
|
|
32
|
+
* 없었다(2026-09-24). 교대 기준선도 이 함수로 적는다.
|
|
33
|
+
*/
|
|
34
|
+
function baselineFailureText(error) {
|
|
35
|
+
const message = error?.message ? String(error.message) : '';
|
|
36
|
+
const code = error?.code ? String(error.code) : '';
|
|
37
|
+
if (message && code && !message.includes(code))
|
|
38
|
+
return `${code}: ${message}`;
|
|
39
|
+
return message || code || String(error);
|
|
40
|
+
}
|
|
26
41
|
async function standMasterBaselines(dataSource, options = {}) {
|
|
27
42
|
const edition = options.edition ?? baselineEdition();
|
|
28
43
|
const domains = options.domains ?? (await dataSource.getRepository(shell_1.Domain).find());
|
|
@@ -36,7 +51,7 @@ async function standMasterBaselines(dataSource, options = {}) {
|
|
|
36
51
|
reports.push({ domain: domain.name, axis, ...outcome });
|
|
37
52
|
}
|
|
38
53
|
catch (error) {
|
|
39
|
-
reports.push({ domain: domain.name, axis, stood: 0, unreadable: [], failed:
|
|
54
|
+
reports.push({ domain: domain.name, axis, stood: 0, unreadable: [], failed: baselineFailureText(error) });
|
|
40
55
|
}
|
|
41
56
|
}
|
|
42
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revision-baseline.js","sourceRoot":"","sources":["../../server/service/revision-baseline.ts"],"names":[],"mappings":";;;AAqDA,0CAMC;AAED,oDAqBC;AAMD,gEAoBC;
|
|
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\n/**\n * 기준선이 실패한 까닭을 **사람이 읽을 수 있게** — 코드만이 아니라 본문을 싣는다.\n *\n * 앞서는 `error.code` 가 있으면 그것만 적었다. SQLite 의 실패는 코드가 늘 `SQLITE_ERROR` 라 기동 로그에\n * 「MIRATEK · SYSTEM: SQLITE_ERROR」만 남았고, 무엇이 실패했는지(「transaction within a transaction」)는 어디에도\n * 없었다(2026-09-24). 교대 기준선도 이 함수로 적는다.\n */\nexport function baselineFailureText(error: any): string {\n const message = error?.message ? String(error.message) : ''\n const code = error?.code ? String(error.code) : ''\n\n if (message && code && !message.includes(code)) return `${code}: ${message}`\n\n return message || code || String(error)\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: baselineFailureText(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"]}
|