@things-factory/work-shift 10.1.36 → 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/pages/work-shift.js +4 -1
- package/dist-client/pages/work-shift.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/index.js +9 -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/work-shift/index.d.ts +1 -1
- package/dist-server/service/work-shift/work-shift-baseline.d.ts +23 -0
- package/dist-server/service/work-shift/work-shift-baseline.js +54 -0
- package/dist-server/service/work-shift/work-shift-baseline.js.map +1 -0
- package/dist-server/service/work-shift/work-shift-content.d.ts +3 -0
- package/dist-server/service/work-shift/work-shift-content.js +7 -0
- package/dist-server/service/work-shift/work-shift-content.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-lifecycle-resolver.d.ts +9 -2
- package/dist-server/service/work-shift/work-shift-lifecycle-resolver.js +16 -6
- package/dist-server/service/work-shift/work-shift-lifecycle-resolver.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-lifecycle.d.ts +98 -5
- package/dist-server/service/work-shift/work-shift-lifecycle.js +133 -0
- package/dist-server/service/work-shift/work-shift-lifecycle.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-revision-service.d.ts +1 -2
- package/dist-server/service/work-shift/work-shift-revision-service.js +10 -7
- package/dist-server/service/work-shift/work-shift-revision-service.js.map +1 -1
- package/dist-server/service/work-shift/work-shift-revision.d.ts +7 -5
- package/dist-server/service/work-shift/work-shift-revision.js +2 -2
- package/dist-server/service/work-shift/work-shift-revision.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
|
@@ -11,14 +11,18 @@ exports.bindWorkShiftApproval = bindWorkShiftApproval;
|
|
|
11
11
|
exports.publishWorkShiftRevision = publishWorkShiftRevision;
|
|
12
12
|
exports.publishUnregulatedWorkShift = publishUnregulatedWorkShift;
|
|
13
13
|
exports.resolveWorkShift = resolveWorkShift;
|
|
14
|
+
exports.standWorkShiftBaseline = standWorkShiftBaseline;
|
|
14
15
|
exports.workShiftRevisionForBasis = workShiftRevisionForBasis;
|
|
15
16
|
exports.captureWorkShiftBasis = captureWorkShiftBasis;
|
|
16
17
|
exports.workShiftRevisionOverview = workShiftRevisionOverview;
|
|
18
|
+
exports.workShiftOverviewFor = workShiftOverviewFor;
|
|
19
|
+
exports.saveAndPublishWorkShift = saveAndPublishWorkShift;
|
|
17
20
|
const node_crypto_1 = require("node:crypto");
|
|
18
21
|
const typeorm_1 = require("typeorm");
|
|
19
22
|
const shell_1 = require("@things-factory/shell");
|
|
20
23
|
const ops_master_1 = require("@things-factory/ops-master");
|
|
21
24
|
const work_shift_content_1 = require("./work-shift-content");
|
|
25
|
+
const work_shift_1 = require("./work-shift");
|
|
22
26
|
const work_shift_arrangement_1 = require("./work-shift-arrangement");
|
|
23
27
|
const work_shift_revision_1 = require("./work-shift-revision");
|
|
24
28
|
class WorkShiftRefusal extends shell_1.Refusal {
|
|
@@ -441,6 +445,8 @@ async function resolveWorkShift(manager, domainId, arrangementId, businessTime,
|
|
|
441
445
|
if (currentLock(manager).lock)
|
|
442
446
|
query.setLock('pessimistic_write');
|
|
443
447
|
const segments = await query.getMany();
|
|
448
|
+
if (!segments.length)
|
|
449
|
+
await refuseBeforeBaseline(manager, domainId, arrangementId, at);
|
|
444
450
|
if (segments.length !== 1)
|
|
445
451
|
refuse(segments.length ? 'AMBIGUOUS_EFFECTIVITY' : 'NO_EFFECTIVE_REVISION');
|
|
446
452
|
const selected = await revision(manager, domainId, segments[0].revisionId);
|
|
@@ -448,6 +454,102 @@ async function resolveWorkShift(manager, domainId, arrangementId, businessTime,
|
|
|
448
454
|
refuse('REVISION_INTEGRITY_FAILURE');
|
|
449
455
|
return { revision: selected, plan, segment: segments[0] };
|
|
450
456
|
}
|
|
457
|
+
/** 기준선보다 앞선 시각은 모른다고 말한다 — ops-master 의 같은 자리를 보라(2026-09-24). */
|
|
458
|
+
async function refuseBeforeBaseline(manager, domainId, arrangementId, at) {
|
|
459
|
+
const first = await manager.findOneBy(work_shift_revision_1.WorkShiftPlan, {
|
|
460
|
+
domain: { id: domainId }, arrangement: { id: arrangementId }, generation: 1, releaseKind: 'baseline'
|
|
461
|
+
});
|
|
462
|
+
if (!first)
|
|
463
|
+
return;
|
|
464
|
+
const recorded = await manager.findOneBy(work_shift_revision_1.WorkShiftRevision, { domain: { id: domainId }, id: first.publishedRevisionId });
|
|
465
|
+
if (recorded && at < recorded.effectiveFrom)
|
|
466
|
+
throw new shell_1.Refusal('BEFORE_BASELINE', { baselineAt: recorded.effectiveFrom.toISOString() }, `These shifts were first recorded at ${recorded.effectiveFrom.toISOString()}; nothing is known about them before then.`);
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* **편성 개정본이 하나도 없는 사업장**에 지금 서 있는 교대 행들을 첫 개정본으로 적는다 — 기준선
|
|
470
|
+
* (2026-09-24, ops-master `standMasterBaselines` 와 같은 판정). 개정 체계 전부터 있던 교대(`work_shifts`)는
|
|
471
|
+
* 편성으로 한 번도 올라간 적이 없어서, 교대 조회가 빈 목록을 답하고 실적이 교대 없이 적혔다.
|
|
472
|
+
*
|
|
473
|
+
* - 교대 행 전부가 한 벌이다(편성은 사업장마다 하나). 값은 행 그대로, 시간대는 사업장의 것이다.
|
|
474
|
+
* 사업장에 시간대가 없거나 그 벌이 편성 검사를 못 지나면 세우지 않고 까닭을 말한다 — 지어내지 않는다.
|
|
475
|
+
* - 결재 없음 · 발행 종류 `baseline` · 작성자와 발행자는 비고 판이 사유에 남는다. 유효 시작은 세운 시각.
|
|
476
|
+
* - 편성 개정본이 하나라도 있으면 손대지 않는다. 둘이 동시에 돌면 편성의 도메인 유니크 · 개정 번호
|
|
477
|
+
* 유니크 · 세대 조건부 갱신이 둘째를 물린다.
|
|
478
|
+
*/
|
|
479
|
+
async function standWorkShiftBaseline(manager, domainId, at, edition) {
|
|
480
|
+
transaction(manager);
|
|
481
|
+
const outcome = { stood: 0, unreadable: [] };
|
|
482
|
+
const legacy = await manager.find(work_shift_1.WorkShift, { where: { domain: { id: domainId } } });
|
|
483
|
+
if (!legacy.length)
|
|
484
|
+
return outcome;
|
|
485
|
+
let arrangement = await manager.findOneBy(work_shift_arrangement_1.WorkShiftArrangement, { domain: { id: domainId } });
|
|
486
|
+
if (arrangement && (await manager.countBy(work_shift_revision_1.WorkShiftRevision, { domain: { id: domainId }, arrangement: { id: arrangement.id } })))
|
|
487
|
+
return outcome;
|
|
488
|
+
if (arrangement && arrangement.planGeneration !== 0) {
|
|
489
|
+
outcome.unreadable.push({ name: arrangement.name, problem: 'plan without revision' });
|
|
490
|
+
return outcome;
|
|
491
|
+
}
|
|
492
|
+
const domain = await manager.findOneByOrFail(shell_1.Domain, { id: domainId });
|
|
493
|
+
let read;
|
|
494
|
+
try {
|
|
495
|
+
read = (0, work_shift_content_1.shiftDraftContent)({ description: null, timezone: domain.timezone, shifts: (0, work_shift_content_1.shiftSetOf)(legacy) }, true);
|
|
496
|
+
}
|
|
497
|
+
catch (error) {
|
|
498
|
+
outcome.unreadable.push({ name: 'work shifts', problem: error?.message ?? String(error) });
|
|
499
|
+
return outcome;
|
|
500
|
+
}
|
|
501
|
+
const policy = await (0, ops_master_1.masterChangePolicy)(manager, domainId, 'workShift');
|
|
502
|
+
if (!arrangement)
|
|
503
|
+
arrangement = await manager.save(work_shift_arrangement_1.WorkShiftArrangement, manager.create(work_shift_arrangement_1.WorkShiftArrangement, {
|
|
504
|
+
domain: { id: domainId }, name: 'Work shifts', planGeneration: 0, revisionLock: 0
|
|
505
|
+
}));
|
|
506
|
+
const saved = await manager.save(work_shift_revision_1.WorkShiftRevision, manager.create(work_shift_revision_1.WorkShiftRevision, {
|
|
507
|
+
...read,
|
|
508
|
+
effectiveFrom: at,
|
|
509
|
+
reason: `baseline: the shifts as they stood, recorded by ${edition}`,
|
|
510
|
+
policy: { id: policy.id },
|
|
511
|
+
domain: { id: domainId },
|
|
512
|
+
arrangement: { id: arrangement.id },
|
|
513
|
+
baseRevision: null,
|
|
514
|
+
baseGeneration: 0,
|
|
515
|
+
revisionNumber: 1,
|
|
516
|
+
editGeneration: 0,
|
|
517
|
+
creator: null,
|
|
518
|
+
createdAt: at,
|
|
519
|
+
frozenAt: at,
|
|
520
|
+
contentHash: null,
|
|
521
|
+
activityInstanceId: null
|
|
522
|
+
}));
|
|
523
|
+
const stood = await revision(manager, domainId, saved.id);
|
|
524
|
+
const contentHash = workShiftSubmissionHash(stood);
|
|
525
|
+
await manager.update(work_shift_revision_1.WorkShiftRevision, { id: stood.id, domain: { id: domainId } }, { contentHash });
|
|
526
|
+
const plan = await manager.save(work_shift_revision_1.WorkShiftPlan, manager.create(work_shift_revision_1.WorkShiftPlan, {
|
|
527
|
+
domain: { id: domainId },
|
|
528
|
+
arrangement: { id: arrangement.id },
|
|
529
|
+
generation: 1,
|
|
530
|
+
recordedAt: at,
|
|
531
|
+
activityInstanceId: null,
|
|
532
|
+
submissionHash: contentHash,
|
|
533
|
+
approver: null,
|
|
534
|
+
publisher: null,
|
|
535
|
+
releaseKind: 'baseline',
|
|
536
|
+
publishedRevision: { id: stood.id },
|
|
537
|
+
policy: { id: policy.id }
|
|
538
|
+
}));
|
|
539
|
+
await manager.save(work_shift_revision_1.WorkShiftSegment, manager.create(work_shift_revision_1.WorkShiftSegment, {
|
|
540
|
+
domain: { id: domainId },
|
|
541
|
+
arrangement: { id: arrangement.id },
|
|
542
|
+
plan: { id: plan.id },
|
|
543
|
+
revision: { id: stood.id },
|
|
544
|
+
validFrom: at,
|
|
545
|
+
validTo: null
|
|
546
|
+
}));
|
|
547
|
+
const advanced = await manager.update(work_shift_arrangement_1.WorkShiftArrangement, { id: arrangement.id, domain: { id: domainId }, planGeneration: 0 }, { planGeneration: 1 });
|
|
548
|
+
if (advanced.affected !== 1)
|
|
549
|
+
refuse('PLAN_CONFLICT');
|
|
550
|
+
outcome.stood = 1;
|
|
551
|
+
return outcome;
|
|
552
|
+
}
|
|
451
553
|
/** Replay reads verify the captured digest too, not only the currently effective schedule. */
|
|
452
554
|
async function workShiftRevisionForBasis(manager, domainId, basis) {
|
|
453
555
|
if (basis.domainId !== domainId)
|
|
@@ -518,4 +620,35 @@ async function workShiftRevisionOverview(manager, domainId, arrangementId, at =
|
|
|
518
620
|
revisions: revisions.map(item => ({ ...item, state: item.frozenAt ? 'frozen' : 'draft' }))
|
|
519
621
|
};
|
|
520
622
|
}
|
|
623
|
+
/**
|
|
624
|
+
* 교대 화면이 여는 것. **읽기만 한다** — 정책 줄이 없으면 기본값으로 답하고 줄을 세우지 않는다(2026-09-24).
|
|
625
|
+
* 앞서는 `masterChangePolicy` 로 줄을 세우려다 트랜잭션 밖이라 거절했고, 정책 줄이 없는 사업장은 화면이 안
|
|
626
|
+
* 열렸다. 기준선이 못 선 사업장은 줄이 끝내 안 생기므로 그 사업장을 고칠 화면이 영영 안 열렸다.
|
|
627
|
+
*/
|
|
628
|
+
async function workShiftOverviewFor(manager, domain) {
|
|
629
|
+
const policy = (await (0, ops_master_1.standingPolicies)(manager, domain.id)).get('workShift');
|
|
630
|
+
const root = await manager.findOneBy(work_shift_arrangement_1.WorkShiftArrangement, { domain: { id: domain.id } });
|
|
631
|
+
const overview = root ? await workShiftRevisionOverview(manager, domain.id, root.id) : { revisions: [], schedule: [], generation: 0 };
|
|
632
|
+
/*
|
|
633
|
+
* 편성 개정본이 하나도 없으면 **개정 체계 전부터 있던 교대**를 싣는다 — 화면이 첫 초안을 그것으로 채운다
|
|
634
|
+
* (2026-09-24). 기준선이 그 교대를 못 세운 사업장(겹침 등)에서 운영자가 옛 교대를 보고 고쳐 올리는 길이다.
|
|
635
|
+
* 개정본이 서면 싣지 않는다 — 그 뒤로 옛 행은 아무것도 정하지 않는다.
|
|
636
|
+
*/
|
|
637
|
+
const legacyShifts = overview.revisions.length
|
|
638
|
+
? undefined
|
|
639
|
+
: (0, work_shift_content_1.shiftSetOf)(await manager.find(work_shift_1.WorkShift, { where: { domain: { id: domain.id } } }));
|
|
640
|
+
return { ...overview, ...(legacyShifts?.length ? { legacyShifts } : {}),
|
|
641
|
+
approvalRequired: policy?.approvalRequired ?? ops_master_1.DEFAULT_APPROVAL_REQUIRED, timezone: domain.timezone || 'UTC' };
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* **비규제 사업장의 「저장」 한 번** — 초안을 만들고 바로 발행한다, 한 트랜잭션에서(ADR-0086 09-22 보탬).
|
|
645
|
+
* 비규제면 사람이 누를 것은 저장 하나다. 두 걸음(초안 저장 → 발행)이 구조상 필연인 것처럼 보이게 하지 않는다.
|
|
646
|
+
* 이 축이 승인제면 발행이 `MASTER_APPROVAL_REQUIRED` 로 거절되고, 같은 트랜잭션이라 초안도 함께 물러난다 —
|
|
647
|
+
* 반쯤 저장된 것이 남지 않는다. 개정본 · 적용계획 · 구간은 두 걸음 때와 똑같이 선다.
|
|
648
|
+
*/
|
|
649
|
+
async function saveAndPublishWorkShift(manager, domainId, actorId, asked) {
|
|
650
|
+
const draft = await createWorkShiftDraft(manager, domainId, actorId, asked);
|
|
651
|
+
const plan = await publishUnregulatedWorkShift(manager, domainId, actorId, draft.id, draft.editGeneration);
|
|
652
|
+
return { revision: await revision(manager, domainId, draft.id, false), plan };
|
|
653
|
+
}
|
|
521
654
|
//# sourceMappingURL=work-shift-lifecycle.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work-shift-lifecycle.js","sourceRoot":"","sources":["../../../server/service/work-shift/work-shift-lifecycle.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 '@things-factory/ops-master'\nimport { shiftDraftContent } from './work-shift-content'\nimport { WorkShiftArrangement } from './work-shift-arrangement'\nimport {\n WorkShiftBasis,\n WorkShiftPlan,\n WorkShiftRevision,\n WorkShiftSegment\n} from './work-shift-revision'\n\nexport class WorkShiftRefusal extends Refusal {\n constructor(code: string, detail?: string) {\n super(\n code,\n {},\n detail ?? WORK_SHIFT_REFUSALS[code] ?? 'The arrangement definition change could not be applied.'\n )\n }\n}\nconst WORK_SHIFT_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 arrangement content is invalid.',\n ARRANGEMENT_NOT_FOUND: 'The arrangement 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 arrangement definitions already used by recorded transactions.',\n FUTURE_PLAN_CONFLICT: 'This change conflicts with an approved future schedule.',\n NO_EFFECTIVE_REVISION: 'There is no published revision effective at the business time.',\n AMBIGUOUS_EFFECTIVITY: 'More than one revision is effective at the business time.',\n REVISION_INTEGRITY_FAILURE: 'The stored revision does not match its signed content.',\n BASIS_CONFLICT: 'This transaction already has a different arrangement or business time.',\n APPROVAL_LINE_REQUIRED: 'Configure an approval line before submitting this change.',\n REVISION_REQUIRED: 'Change the arrangement through a revision draft.'\n}\nfunction refuse(code: string, detail?: string): never {\n throw new WorkShiftRefusal(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 workShiftSubmissionHash(revision: WorkShiftRevision): 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 arrangementId: revision.arrangementId,\n baseRevisionId: revision.baseRevisionId,\n baseGeneration: revision.baseGeneration,\n description: revision.description,\n timezone: revision.timezone,\n shifts: revision.shifts,\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 workShiftApprovalInput(manager: EntityManager, domainId: string, revisionId: string) {\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.contentHash !== workShiftSubmissionHash(draft)) refuse('INVALID_SUBMISSION')\n const arrangement = await subject(manager, domainId, draft.arrangementId)\n const base = draft.baseRevisionId ? await revision(manager, domainId, draft.baseRevisionId) : null\n const plan = base ? await manager.findOneBy(WorkShiftPlan, {\n domain: { id: domainId }, arrangement: { id: draft.arrangementId }, generation: draft.baseGeneration\n }) : null\n const segment = plan && base ? await manager.findOneBy(WorkShiftSegment, {\n domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }\n }) : null\n const values = (row: WorkShiftRevision) => ({\n revisionNumber: row.revisionNumber,\n detail: {\n revisionId: row.id, createdAt: row.createdAt.toISOString(), frozenAt: row.frozenAt?.toISOString(),\n effectiveFrom: row.effectiveFrom.toISOString(), reason: row.reason,\n ...(row.id === base?.id && segment ? { validFrom: segment.validFrom.toISOString(), validTo: segment.validTo?.toISOString() ?? null } : {})\n },\n description: row.description,\n timezone: row.timezone,\n shifts: row.shifts\n })\n return {\n headline: arrangement.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 arrangementId: draft.arrangementId,\n baseGeneration: draft.baseGeneration\n }\n }\n}\n\nexport async function assertWorkShiftApprovalInput(\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 workShiftApprovalInput(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 WorkShiftDraftContent {\n description?: string\n timezone: string\n shifts: import('./work-shift-content').ShiftDefinition[]\n effectiveFrom: Date | string\n reason: string\n}\nfunction content(input: WorkShiftDraftContent) {\n return { ...shiftDraftContent(input), effectiveFrom: instant(input.effectiveFrom), reason: text(input.reason, 'reason') }\n}\nasync function subject(manager: EntityManager, domainId: string, arrangementId: string) {\n const arrangement = await manager.findOne(WorkShiftArrangement, {\n where: { id: arrangementId, domain: { id: domainId } },\n ...currentLock(manager)\n })\n if (!arrangement) refuse('ARRANGEMENT_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(WorkShiftArrangement, 'head')\n .leftJoin(WorkShiftPlan, 'plan', 'plan.arrangement = head.id AND plan.domain = head.domain')\n .select('head.planGeneration', 'generation')\n .addSelect('MAX(plan.generation)', 'latest')\n .where({ id: arrangementId, 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 arrangement\n}\nasync function revision(manager: EntityManager, domainId: string, revisionId: string, locked = true) {\n const found = await manager.findOne(WorkShiftRevision, {\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, arrangementId: string) {\n transaction(manager)\n const locked = await manager\n .createQueryBuilder()\n .update(WorkShiftArrangement)\n .set({ revisionLock: () => 'revision_lock + 1' })\n .where({ id: arrangementId, domain: { id: domainId } })\n .execute()\n if (locked.affected !== 1) refuse('ARRANGEMENT_NOT_FOUND')\n return subject(manager, domainId, arrangementId)\n}\n\nexport async function createWorkShiftDraft(\n manager: EntityManager,\n domainId: string,\n creatorId: string,\n asked: { arrangementId?: string; name?: string; baseRevisionId?: string; content: WorkShiftDraftContent }\n) {\n transaction(manager)\n const accepted = content(asked.content)\n const policy = await masterChangePolicy(manager, domainId, 'workShift')\n let arrangement = await manager.findOneBy(WorkShiftArrangement, { domain: { id: domainId } })\n if (!arrangement) arrangement = await manager.save(WorkShiftArrangement, manager.create(WorkShiftArrangement, {\n domain: { id: domainId }, name: 'Work shifts', planGeneration: 0, revisionLock: 0\n }))\n if (asked.arrangementId && asked.arrangementId !== arrangement.id) refuse('ARRANGEMENT_NOT_FOUND')\n arrangement = await lockSubject(manager, domainId, arrangement.id)\n const previous = await manager.findOne(WorkShiftRevision, {\n where: { domain: { id: domainId }, arrangement: { id: arrangement.id } }, order: { revisionNumber: 'DESC' },\n ...currentLock(manager)\n })\n const revisionNumber = (previous?.revisionNumber ?? 0) + 1\n let baseRevisionId: string | null = null\n if (arrangement.planGeneration > 0) {\n baseRevisionId = (await resolveWorkShift(manager, domainId, arrangement.id, accepted.effectiveFrom)).revision.id\n }\n if (asked.baseRevisionId && asked.baseRevisionId !== baseRevisionId) refuse('INVALID_BASE_REVISION')\n const saved = await manager.save(\n WorkShiftRevision,\n manager.create(WorkShiftRevision, {\n ...accepted,\n policy: { id: policy.id },\n domain: { id: domainId },\n arrangement: { id: arrangement.id },\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n baseGeneration: arrangement.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 editWorkShiftDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number,\n input: WorkShiftDraftContent\n) {\n transaction(manager)\n const accepted = content(input)\n const initial = await revision(manager, domainId, revisionId, false)\n const arrangement = await lockSubject(manager, domainId, initial.arrangementId)\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 !== arrangement.planGeneration) refuse('PLAN_CONFLICT')\n // Moving the effective date across a scheduled boundary changes the before-image.\n const baseRevisionId =\n arrangement.planGeneration > 0\n ? (await resolveWorkShift(manager, domainId, arrangement.id, accepted.effectiveFrom)).revision.id\n : null\n const updated = await manager\n .createQueryBuilder()\n .update(WorkShiftRevision)\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 freezeWorkShiftDraft(\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 arrangement = await lockSubject(manager, domainId, initial.arrangementId)\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 !== arrangement.planGeneration) refuse('PLAN_CONFLICT')\n const policy = await masterChangePolicy(manager, domainId, 'workShift')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n shiftDraftContent(draft, true)\n const contentHash = workShiftSubmissionHash(draft)\n await manager.update(\n WorkShiftRevision,\n { id: revisionId, domain: { id: domainId } },\n { frozenAt: new Date(), contentHash }\n )\n return revision(manager, domainId, revisionId)\n}\n\nexport async function bindWorkShiftApproval(\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.arrangementId)\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.activityInstanceId) refuse('INVALID_SUBMISSION')\n await manager.update(\n WorkShiftRevision,\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 publishWorkShiftRevision(\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 publishUnregulatedWorkShift(\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.arrangementId)\n const policy = await masterChangePolicy(manager, domainId, 'workShift')\n if (policy.approvalRequired)\n throw new Refusal('MASTER_APPROVAL_REQUIRED', {}, 'This change requires product approval.')\n const prior = await manager.findOneBy(WorkShiftPlan, {\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 freezeWorkShiftDraft(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 arrangement = await lockSubject(manager, domainId, initial.arrangementId)\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 workShiftSubmissionHash(draft) !== decision.submissionHash\n )\n refuse('INVALID_SUBMISSION')\n const policy = await masterChangePolicy(manager, domainId, 'workShift')\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(WorkShiftPlan, {\n where: { domain: { id: domainId }, publishedRevision: { id: revisionId } },\n ...currentLock(manager)\n })\n if (previousDecision) return previousDecision\n if (draft.baseGeneration !== arrangement.planGeneration) refuse('PLAN_CONFLICT')\n // Only replacement from effectiveFrom onward is supported in this slice, not arbitrary rescheduling.\n if (\n await manager.findOne(WorkShiftBasis, {\n where: { domain: { id: domainId }, arrangement: { id: arrangement.id }, businessTime: MoreThanOrEqual(draft.effectiveFrom) },\n ...currentLock(manager)\n })\n )\n refuse('RETROACTIVE_IMPACT')\n const oldPlan = await manager.findOne(WorkShiftPlan, {\n where: { domain: { id: domainId }, arrangement: { id: arrangement.id }, generation: arrangement.planGeneration },\n ...currentLock(manager)\n })\n if (arrangement.planGeneration > 0 && !oldPlan) refuse('PLAN_CONFLICT')\n const oldSegments = oldPlan\n ? await manager.find(WorkShiftSegment, {\n where: { domain: { id: domainId }, arrangement: { id: arrangement.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 WorkShiftPlan,\n manager.create(WorkShiftPlan, {\n domain: { id: domainId },\n arrangement: { id: arrangement.id },\n generation: arrangement.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 WorkShiftSegment,\n manager.create(WorkShiftSegment, {\n domain: { id: domainId },\n arrangement: { id: arrangement.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 WorkShiftSegment,\n manager.create(WorkShiftSegment, {\n domain: { id: domainId },\n arrangement: { id: arrangement.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 WorkShiftArrangement,\n { id: arrangement.id, domain: { id: domainId }, planGeneration: arrangement.planGeneration },\n { planGeneration: plan.generation }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n return plan\n}\n\nexport async function resolveWorkShift(\n manager: EntityManager,\n domainId: string,\n arrangementId: 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(WorkShiftPlan, {\n where: { domain: { id: domainId }, arrangement: { id: arrangementId }, recordedAt: LessThanOrEqual(known) },\n order: { generation: 'DESC' },\n ...currentLock(manager)\n })\n if (!plan) refuse('NO_EFFECTIVE_REVISION')\n await subject(manager, domainId, arrangementId)\n const query = manager\n .createQueryBuilder(WorkShiftSegment, 'segment')\n .where({ domain: { id: domainId }, arrangement: { id: arrangementId }, 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 !== workShiftSubmissionHash(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 workShiftRevisionForBasis(manager: EntityManager, domainId: string, basis: WorkShiftBasis) {\n if (basis.domainId !== domainId) refuse('BASIS_CONFLICT')\n const selected = await revision(manager, domainId, basis.revisionId)\n if (selected.arrangementId !== basis.arrangementId || !selected.frozenAt || selected.contentHash !== basis.contentHash || workShiftSubmissionHash(selected) !== basis.contentHash) {\n refuse('REVISION_INTEGRITY_FAILURE')\n }\n const plan = await manager.findOneBy(WorkShiftPlan, { id: basis.planId, domain: { id: domainId }, arrangement: { id: basis.arrangementId } })\n const segments = await manager.findBy(WorkShiftSegment, { domain: { id: domainId }, arrangement: { id: basis.arrangementId }, plan: { id: basis.planId } })\n const matching = segments.filter(s => s.validFrom <= basis.businessTime && (!s.validTo || s.validTo > basis.businessTime))\n if (!plan || plan.recordedAt > basis.resolvedAt || matching.length !== 1 || matching[0].revisionId !== basis.revisionId) refuse('BASIS_CONFLICT')\n return selected\n}\n\n/** Must run inside the transaction that writes the business record. */\nexport async function captureWorkShiftBasis(\n manager: EntityManager,\n domainId: string,\n arrangementId: string,\n recordKey: string,\n businessTime: Date | string\n) {\n const at = instant(businessTime)\n await lockSubject(manager, domainId, arrangementId)\n const existing = await manager.findOne(WorkShiftBasis, {\n where: { domain: { id: domainId }, recordKey },\n ...currentLock(manager)\n })\n if (existing) {\n if (existing.arrangementId !== arrangementId || existing.businessTime.getTime() !== at.getTime()) refuse('BASIS_CONFLICT')\n await workShiftRevisionForBasis(manager, domainId, existing)\n return existing\n }\n const resolvedAt = new Date()\n const selected = await resolveWorkShift(manager, domainId, arrangementId, at, resolvedAt)\n const saved = await manager.save(\n WorkShiftBasis,\n manager.create(WorkShiftBasis, {\n domain: { id: domainId },\n arrangement: { id: arrangementId },\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(WorkShiftBasis, { id: saved.id, domain: { id: domainId } })\n}\n\nexport async function workShiftRevisionOverview(\n manager: EntityManager,\n domainId: string,\n arrangementId: string,\n at = new Date()\n) {\n const arrangement = await subject(manager, domainId, arrangementId)\n const revisions = await manager.find(WorkShiftRevision, {\n where: { domain: { id: domainId }, arrangement: { id: arrangementId } },\n order: { createdAt: 'ASC', id: 'ASC' }\n })\n const plan = await manager.findOne(WorkShiftPlan, {\n where: { domain: { id: domainId }, arrangement: { id: arrangementId }, generation: arrangement.planGeneration }\n })\n const schedule = plan\n ? await manager.find(WorkShiftSegment, {\n where: { domain: { id: domainId }, arrangement: { id: arrangementId }, plan: { id: plan.id } },\n order: { validFrom: 'ASC' }\n })\n : []\n return {\n arrangementId,\n name: arrangement.name,\n generation: arrangement.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"]}
|
|
1
|
+
{"version":3,"file":"work-shift-lifecycle.js","sourceRoot":"","sources":["../../../server/service/work-shift/work-shift-lifecycle.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto'\nimport { EntityManager, LessThanOrEqual, MoreThanOrEqual } from 'typeorm'\nimport { Domain, Refusal } from '@things-factory/shell'\nimport { DEFAULT_APPROVAL_REQUIRED, masterChangePolicy, standingPolicies } from '@things-factory/ops-master'\nimport { shiftDraftContent, shiftSetOf } from './work-shift-content'\nimport { WorkShift } from './work-shift'\nimport { WorkShiftArrangement } from './work-shift-arrangement'\nimport {\n WorkShiftBasis,\n WorkShiftPlan,\n WorkShiftRevision,\n WorkShiftSegment\n} from './work-shift-revision'\n\nexport class WorkShiftRefusal extends Refusal {\n constructor(code: string, detail?: string) {\n super(\n code,\n {},\n detail ?? WORK_SHIFT_REFUSALS[code] ?? 'The arrangement definition change could not be applied.'\n )\n }\n}\nconst WORK_SHIFT_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 arrangement content is invalid.',\n ARRANGEMENT_NOT_FOUND: 'The arrangement 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 arrangement definitions already used by recorded transactions.',\n FUTURE_PLAN_CONFLICT: 'This change conflicts with an approved future schedule.',\n NO_EFFECTIVE_REVISION: 'There is no published revision effective at the business time.',\n AMBIGUOUS_EFFECTIVITY: 'More than one revision is effective at the business time.',\n REVISION_INTEGRITY_FAILURE: 'The stored revision does not match its signed content.',\n BASIS_CONFLICT: 'This transaction already has a different arrangement or business time.',\n APPROVAL_LINE_REQUIRED: 'Configure an approval line before submitting this change.',\n REVISION_REQUIRED: 'Change the arrangement through a revision draft.'\n}\nfunction refuse(code: string, detail?: string): never {\n throw new WorkShiftRefusal(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 workShiftSubmissionHash(revision: WorkShiftRevision): 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 arrangementId: revision.arrangementId,\n baseRevisionId: revision.baseRevisionId,\n baseGeneration: revision.baseGeneration,\n description: revision.description,\n timezone: revision.timezone,\n shifts: revision.shifts,\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 workShiftApprovalInput(manager: EntityManager, domainId: string, revisionId: string) {\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.contentHash !== workShiftSubmissionHash(draft)) refuse('INVALID_SUBMISSION')\n const arrangement = await subject(manager, domainId, draft.arrangementId)\n const base = draft.baseRevisionId ? await revision(manager, domainId, draft.baseRevisionId) : null\n const plan = base ? await manager.findOneBy(WorkShiftPlan, {\n domain: { id: domainId }, arrangement: { id: draft.arrangementId }, generation: draft.baseGeneration\n }) : null\n const segment = plan && base ? await manager.findOneBy(WorkShiftSegment, {\n domain: { id: domainId }, plan: { id: plan.id }, revision: { id: base.id }\n }) : null\n const values = (row: WorkShiftRevision) => ({\n revisionNumber: row.revisionNumber,\n detail: {\n revisionId: row.id, createdAt: row.createdAt.toISOString(), frozenAt: row.frozenAt?.toISOString(),\n effectiveFrom: row.effectiveFrom.toISOString(), reason: row.reason,\n ...(row.id === base?.id && segment ? { validFrom: segment.validFrom.toISOString(), validTo: segment.validTo?.toISOString() ?? null } : {})\n },\n description: row.description,\n timezone: row.timezone,\n shifts: row.shifts\n })\n return {\n headline: arrangement.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 arrangementId: draft.arrangementId,\n baseGeneration: draft.baseGeneration\n }\n }\n}\n\nexport async function assertWorkShiftApprovalInput(\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 workShiftApprovalInput(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 WorkShiftDraftContent {\n description?: string\n timezone: string\n shifts: import('./work-shift-content').ShiftDefinition[]\n effectiveFrom: Date | string\n reason: string\n}\nfunction content(input: WorkShiftDraftContent) {\n return { ...shiftDraftContent(input), effectiveFrom: instant(input.effectiveFrom), reason: text(input.reason, 'reason') }\n}\nasync function subject(manager: EntityManager, domainId: string, arrangementId: string) {\n const arrangement = await manager.findOne(WorkShiftArrangement, {\n where: { id: arrangementId, domain: { id: domainId } },\n ...currentLock(manager)\n })\n if (!arrangement) refuse('ARRANGEMENT_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(WorkShiftArrangement, 'head')\n .leftJoin(WorkShiftPlan, 'plan', 'plan.arrangement = head.id AND plan.domain = head.domain')\n .select('head.planGeneration', 'generation')\n .addSelect('MAX(plan.generation)', 'latest')\n .where({ id: arrangementId, 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 arrangement\n}\nasync function revision(manager: EntityManager, domainId: string, revisionId: string, locked = true) {\n const found = await manager.findOne(WorkShiftRevision, {\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, arrangementId: string) {\n transaction(manager)\n const locked = await manager\n .createQueryBuilder()\n .update(WorkShiftArrangement)\n .set({ revisionLock: () => 'revision_lock + 1' })\n .where({ id: arrangementId, domain: { id: domainId } })\n .execute()\n if (locked.affected !== 1) refuse('ARRANGEMENT_NOT_FOUND')\n return subject(manager, domainId, arrangementId)\n}\n\nexport async function createWorkShiftDraft(\n manager: EntityManager,\n domainId: string,\n creatorId: string,\n asked: { arrangementId?: string; name?: string; baseRevisionId?: string; content: WorkShiftDraftContent }\n) {\n transaction(manager)\n const accepted = content(asked.content)\n const policy = await masterChangePolicy(manager, domainId, 'workShift')\n let arrangement = await manager.findOneBy(WorkShiftArrangement, { domain: { id: domainId } })\n if (!arrangement) arrangement = await manager.save(WorkShiftArrangement, manager.create(WorkShiftArrangement, {\n domain: { id: domainId }, name: 'Work shifts', planGeneration: 0, revisionLock: 0\n }))\n if (asked.arrangementId && asked.arrangementId !== arrangement.id) refuse('ARRANGEMENT_NOT_FOUND')\n arrangement = await lockSubject(manager, domainId, arrangement.id)\n const previous = await manager.findOne(WorkShiftRevision, {\n where: { domain: { id: domainId }, arrangement: { id: arrangement.id } }, order: { revisionNumber: 'DESC' },\n ...currentLock(manager)\n })\n const revisionNumber = (previous?.revisionNumber ?? 0) + 1\n let baseRevisionId: string | null = null\n if (arrangement.planGeneration > 0) {\n baseRevisionId = (await resolveWorkShift(manager, domainId, arrangement.id, accepted.effectiveFrom)).revision.id\n }\n if (asked.baseRevisionId && asked.baseRevisionId !== baseRevisionId) refuse('INVALID_BASE_REVISION')\n const saved = await manager.save(\n WorkShiftRevision,\n manager.create(WorkShiftRevision, {\n ...accepted,\n policy: { id: policy.id },\n domain: { id: domainId },\n arrangement: { id: arrangement.id },\n baseRevision: baseRevisionId ? { id: baseRevisionId } : null,\n baseGeneration: arrangement.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 editWorkShiftDraft(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n revisionId: string,\n expectedEditGeneration: number,\n input: WorkShiftDraftContent\n) {\n transaction(manager)\n const accepted = content(input)\n const initial = await revision(manager, domainId, revisionId, false)\n const arrangement = await lockSubject(manager, domainId, initial.arrangementId)\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 !== arrangement.planGeneration) refuse('PLAN_CONFLICT')\n // Moving the effective date across a scheduled boundary changes the before-image.\n const baseRevisionId =\n arrangement.planGeneration > 0\n ? (await resolveWorkShift(manager, domainId, arrangement.id, accepted.effectiveFrom)).revision.id\n : null\n const updated = await manager\n .createQueryBuilder()\n .update(WorkShiftRevision)\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 freezeWorkShiftDraft(\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 arrangement = await lockSubject(manager, domainId, initial.arrangementId)\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 !== arrangement.planGeneration) refuse('PLAN_CONFLICT')\n const policy = await masterChangePolicy(manager, domainId, 'workShift')\n if (draft.policyId !== policy.id) refuse('PLAN_CONFLICT')\n shiftDraftContent(draft, true)\n const contentHash = workShiftSubmissionHash(draft)\n await manager.update(\n WorkShiftRevision,\n { id: revisionId, domain: { id: domainId } },\n { frozenAt: new Date(), contentHash }\n )\n return revision(manager, domainId, revisionId)\n}\n\nexport async function bindWorkShiftApproval(\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.arrangementId)\n const draft = await revision(manager, domainId, revisionId)\n if (!draft.frozenAt || draft.activityInstanceId) refuse('INVALID_SUBMISSION')\n await manager.update(\n WorkShiftRevision,\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 publishWorkShiftRevision(\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 publishUnregulatedWorkShift(\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.arrangementId)\n const policy = await masterChangePolicy(manager, domainId, 'workShift')\n if (policy.approvalRequired)\n throw new Refusal('MASTER_APPROVAL_REQUIRED', {}, 'This change requires product approval.')\n const prior = await manager.findOneBy(WorkShiftPlan, {\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 freezeWorkShiftDraft(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 arrangement = await lockSubject(manager, domainId, initial.arrangementId)\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 workShiftSubmissionHash(draft) !== decision.submissionHash\n )\n refuse('INVALID_SUBMISSION')\n const policy = await masterChangePolicy(manager, domainId, 'workShift')\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(WorkShiftPlan, {\n where: { domain: { id: domainId }, publishedRevision: { id: revisionId } },\n ...currentLock(manager)\n })\n if (previousDecision) return previousDecision\n if (draft.baseGeneration !== arrangement.planGeneration) refuse('PLAN_CONFLICT')\n // Only replacement from effectiveFrom onward is supported in this slice, not arbitrary rescheduling.\n if (\n await manager.findOne(WorkShiftBasis, {\n where: { domain: { id: domainId }, arrangement: { id: arrangement.id }, businessTime: MoreThanOrEqual(draft.effectiveFrom) },\n ...currentLock(manager)\n })\n )\n refuse('RETROACTIVE_IMPACT')\n const oldPlan = await manager.findOne(WorkShiftPlan, {\n where: { domain: { id: domainId }, arrangement: { id: arrangement.id }, generation: arrangement.planGeneration },\n ...currentLock(manager)\n })\n if (arrangement.planGeneration > 0 && !oldPlan) refuse('PLAN_CONFLICT')\n const oldSegments = oldPlan\n ? await manager.find(WorkShiftSegment, {\n where: { domain: { id: domainId }, arrangement: { id: arrangement.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 WorkShiftPlan,\n manager.create(WorkShiftPlan, {\n domain: { id: domainId },\n arrangement: { id: arrangement.id },\n generation: arrangement.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 WorkShiftSegment,\n manager.create(WorkShiftSegment, {\n domain: { id: domainId },\n arrangement: { id: arrangement.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 WorkShiftSegment,\n manager.create(WorkShiftSegment, {\n domain: { id: domainId },\n arrangement: { id: arrangement.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 WorkShiftArrangement,\n { id: arrangement.id, domain: { id: domainId }, planGeneration: arrangement.planGeneration },\n { planGeneration: plan.generation }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n return plan\n}\n\nexport async function resolveWorkShift(\n manager: EntityManager,\n domainId: string,\n arrangementId: 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(WorkShiftPlan, {\n where: { domain: { id: domainId }, arrangement: { id: arrangementId }, recordedAt: LessThanOrEqual(known) },\n order: { generation: 'DESC' },\n ...currentLock(manager)\n })\n if (!plan) refuse('NO_EFFECTIVE_REVISION')\n await subject(manager, domainId, arrangementId)\n const query = manager\n .createQueryBuilder(WorkShiftSegment, 'segment')\n .where({ domain: { id: domainId }, arrangement: { id: arrangementId }, 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, arrangementId, 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 !== workShiftSubmissionHash(selected))\n refuse('REVISION_INTEGRITY_FAILURE')\n return { revision: selected, plan, segment: segments[0] }\n}\n\n/** 기준선보다 앞선 시각은 모른다고 말한다 — ops-master 의 같은 자리를 보라(2026-09-24). */\nasync function refuseBeforeBaseline(manager: EntityManager, domainId: string, arrangementId: string, at: Date) {\n const first = await manager.findOneBy(WorkShiftPlan, {\n domain: { id: domainId }, arrangement: { id: arrangementId }, generation: 1, releaseKind: 'baseline'\n })\n if (!first) return\n const recorded = await manager.findOneBy(WorkShiftRevision, { 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 `These shifts were first recorded at ${recorded.effectiveFrom.toISOString()}; nothing is known about them before then.`\n )\n}\n\n/**\n * **편성 개정본이 하나도 없는 사업장**에 지금 서 있는 교대 행들을 첫 개정본으로 적는다 — 기준선\n * (2026-09-24, ops-master `standMasterBaselines` 와 같은 판정). 개정 체계 전부터 있던 교대(`work_shifts`)는\n * 편성으로 한 번도 올라간 적이 없어서, 교대 조회가 빈 목록을 답하고 실적이 교대 없이 적혔다.\n *\n * - 교대 행 전부가 한 벌이다(편성은 사업장마다 하나). 값은 행 그대로, 시간대는 사업장의 것이다.\n * 사업장에 시간대가 없거나 그 벌이 편성 검사를 못 지나면 세우지 않고 까닭을 말한다 — 지어내지 않는다.\n * - 결재 없음 · 발행 종류 `baseline` · 작성자와 발행자는 비고 판이 사유에 남는다. 유효 시작은 세운 시각.\n * - 편성 개정본이 하나라도 있으면 손대지 않는다. 둘이 동시에 돌면 편성의 도메인 유니크 · 개정 번호\n * 유니크 · 세대 조건부 갱신이 둘째를 물린다.\n */\nexport async function standWorkShiftBaseline(manager: EntityManager, domainId: string, at: Date, edition: string) {\n transaction(manager)\n const outcome = { stood: 0, unreadable: [] as { name: string; problem: string }[] }\n const legacy = await manager.find(WorkShift, { where: { domain: { id: domainId } } })\n if (!legacy.length) return outcome\n let arrangement = await manager.findOneBy(WorkShiftArrangement, { domain: { id: domainId } })\n if (arrangement && (await manager.countBy(WorkShiftRevision, { domain: { id: domainId }, arrangement: { id: arrangement.id } })))\n return outcome\n if (arrangement && arrangement.planGeneration !== 0) {\n outcome.unreadable.push({ name: arrangement.name, problem: 'plan without revision' })\n return outcome\n }\n const domain = await manager.findOneByOrFail(Domain, { id: domainId })\n let read: ReturnType<typeof shiftDraftContent>\n try {\n read = shiftDraftContent({ description: null, timezone: domain.timezone, shifts: shiftSetOf(legacy) }, true)\n } catch (error: any) {\n outcome.unreadable.push({ name: 'work shifts', problem: error?.message ?? String(error) })\n return outcome\n }\n const policy = await masterChangePolicy(manager, domainId, 'workShift')\n if (!arrangement)\n arrangement = await manager.save(WorkShiftArrangement, manager.create(WorkShiftArrangement, {\n domain: { id: domainId }, name: 'Work shifts', planGeneration: 0, revisionLock: 0\n }))\n const saved = await manager.save(\n WorkShiftRevision,\n manager.create(WorkShiftRevision, {\n ...read,\n effectiveFrom: at,\n reason: `baseline: the shifts as they stood, recorded by ${edition}`,\n policy: { id: policy.id },\n domain: { id: domainId },\n arrangement: { id: arrangement.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 = workShiftSubmissionHash(stood)\n await manager.update(WorkShiftRevision, { id: stood.id, domain: { id: domainId } }, { contentHash })\n const plan = await manager.save(\n WorkShiftPlan,\n manager.create(WorkShiftPlan, {\n domain: { id: domainId },\n arrangement: { id: arrangement.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 await manager.save(\n WorkShiftSegment,\n manager.create(WorkShiftSegment, {\n domain: { id: domainId },\n arrangement: { id: arrangement.id },\n plan: { id: plan.id },\n revision: { id: stood.id },\n validFrom: at,\n validTo: null\n })\n )\n const advanced = await manager.update(\n WorkShiftArrangement,\n { id: arrangement.id, domain: { id: domainId }, planGeneration: 0 },\n { planGeneration: 1 }\n )\n if (advanced.affected !== 1) refuse('PLAN_CONFLICT')\n outcome.stood = 1\n return outcome\n}\n\n/** Replay reads verify the captured digest too, not only the currently effective schedule. */\nexport async function workShiftRevisionForBasis(manager: EntityManager, domainId: string, basis: WorkShiftBasis) {\n if (basis.domainId !== domainId) refuse('BASIS_CONFLICT')\n const selected = await revision(manager, domainId, basis.revisionId)\n if (selected.arrangementId !== basis.arrangementId || !selected.frozenAt || selected.contentHash !== basis.contentHash || workShiftSubmissionHash(selected) !== basis.contentHash) {\n refuse('REVISION_INTEGRITY_FAILURE')\n }\n const plan = await manager.findOneBy(WorkShiftPlan, { id: basis.planId, domain: { id: domainId }, arrangement: { id: basis.arrangementId } })\n const segments = await manager.findBy(WorkShiftSegment, { domain: { id: domainId }, arrangement: { id: basis.arrangementId }, plan: { id: basis.planId } })\n const matching = segments.filter(s => s.validFrom <= basis.businessTime && (!s.validTo || s.validTo > basis.businessTime))\n if (!plan || plan.recordedAt > basis.resolvedAt || matching.length !== 1 || matching[0].revisionId !== basis.revisionId) refuse('BASIS_CONFLICT')\n return selected\n}\n\n/** Must run inside the transaction that writes the business record. */\nexport async function captureWorkShiftBasis(\n manager: EntityManager,\n domainId: string,\n arrangementId: string,\n recordKey: string,\n businessTime: Date | string\n) {\n const at = instant(businessTime)\n await lockSubject(manager, domainId, arrangementId)\n const existing = await manager.findOne(WorkShiftBasis, {\n where: { domain: { id: domainId }, recordKey },\n ...currentLock(manager)\n })\n if (existing) {\n if (existing.arrangementId !== arrangementId || existing.businessTime.getTime() !== at.getTime()) refuse('BASIS_CONFLICT')\n await workShiftRevisionForBasis(manager, domainId, existing)\n return existing\n }\n const resolvedAt = new Date()\n const selected = await resolveWorkShift(manager, domainId, arrangementId, at, resolvedAt)\n const saved = await manager.save(\n WorkShiftBasis,\n manager.create(WorkShiftBasis, {\n domain: { id: domainId },\n arrangement: { id: arrangementId },\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(WorkShiftBasis, { id: saved.id, domain: { id: domainId } })\n}\n\nexport async function workShiftRevisionOverview(\n manager: EntityManager,\n domainId: string,\n arrangementId: string,\n at = new Date()\n) {\n const arrangement = await subject(manager, domainId, arrangementId)\n const revisions = await manager.find(WorkShiftRevision, {\n where: { domain: { id: domainId }, arrangement: { id: arrangementId } },\n order: { createdAt: 'ASC', id: 'ASC' }\n })\n const plan = await manager.findOne(WorkShiftPlan, {\n where: { domain: { id: domainId }, arrangement: { id: arrangementId }, generation: arrangement.planGeneration }\n })\n const schedule = plan\n ? await manager.find(WorkShiftSegment, {\n where: { domain: { id: domainId }, arrangement: { id: arrangementId }, plan: { id: plan.id } },\n order: { validFrom: 'ASC' }\n })\n : []\n return {\n arrangementId,\n name: arrangement.name,\n generation: arrangement.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/**\n * 교대 화면이 여는 것. **읽기만 한다** — 정책 줄이 없으면 기본값으로 답하고 줄을 세우지 않는다(2026-09-24).\n * 앞서는 `masterChangePolicy` 로 줄을 세우려다 트랜잭션 밖이라 거절했고, 정책 줄이 없는 사업장은 화면이 안\n * 열렸다. 기준선이 못 선 사업장은 줄이 끝내 안 생기므로 그 사업장을 고칠 화면이 영영 안 열렸다.\n */\nexport async function workShiftOverviewFor(manager: EntityManager, domain: Domain) {\n const policy = (await standingPolicies(manager, domain.id)).get('workShift')\n const root = await manager.findOneBy(WorkShiftArrangement, { domain: { id: domain.id } })\n const overview = root ? await workShiftRevisionOverview(manager, domain.id, root.id) : { revisions: [], schedule: [], generation: 0 }\n /*\n * 편성 개정본이 하나도 없으면 **개정 체계 전부터 있던 교대**를 싣는다 — 화면이 첫 초안을 그것으로 채운다\n * (2026-09-24). 기준선이 그 교대를 못 세운 사업장(겹침 등)에서 운영자가 옛 교대를 보고 고쳐 올리는 길이다.\n * 개정본이 서면 싣지 않는다 — 그 뒤로 옛 행은 아무것도 정하지 않는다.\n */\n const legacyShifts = overview.revisions.length\n ? undefined\n : shiftSetOf(await manager.find(WorkShift, { where: { domain: { id: domain.id } } }))\n return { ...overview, ...(legacyShifts?.length ? { legacyShifts } : {}),\n approvalRequired: policy?.approvalRequired ?? DEFAULT_APPROVAL_REQUIRED, timezone: domain.timezone || 'UTC' }\n}\n\n/**\n * **비규제 사업장의 「저장」 한 번** — 초안을 만들고 바로 발행한다, 한 트랜잭션에서(ADR-0086 09-22 보탬).\n * 비규제면 사람이 누를 것은 저장 하나다. 두 걸음(초안 저장 → 발행)이 구조상 필연인 것처럼 보이게 하지 않는다.\n * 이 축이 승인제면 발행이 `MASTER_APPROVAL_REQUIRED` 로 거절되고, 같은 트랜잭션이라 초안도 함께 물러난다 —\n * 반쯤 저장된 것이 남지 않는다. 개정본 · 적용계획 · 구간은 두 걸음 때와 똑같이 선다.\n */\nexport async function saveAndPublishWorkShift(\n manager: EntityManager,\n domainId: string,\n actorId: string,\n asked: { arrangementId?: string; baseRevisionId?: string; content: WorkShiftDraftContent }\n) {\n const draft = await createWorkShiftDraft(manager, domainId, actorId, asked)\n const plan = await publishUnregulatedWorkShift(manager, domainId, actorId, draft.id, draft.editGeneration)\n return { revision: await revision(manager, domainId, draft.id, false), plan }\n}\n"]}
|
|
@@ -2,8 +2,7 @@ import { EntityManager } from 'typeorm';
|
|
|
2
2
|
import { Domain } from '@things-factory/shell';
|
|
3
3
|
import { WorkShift } from './work-shift';
|
|
4
4
|
import { WorkShiftSegment } from './work-shift-revision';
|
|
5
|
-
|
|
6
|
-
export declare function shiftSetOf(shifts: Partial<WorkShift>[]): Record<string, unknown>[];
|
|
5
|
+
export { shiftSetOf } from './work-shift-content';
|
|
7
6
|
export declare function sameShiftSet(a: Record<string, unknown>[], b: Record<string, unknown>[]): boolean;
|
|
8
7
|
export declare function shiftsInForceAt(manager: EntityManager, domain: Domain, at: Date): Promise<{
|
|
9
8
|
shifts: import("./work-shift-content").ShiftDefinition[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.shiftSetOf =
|
|
3
|
+
exports.shiftSetOf = void 0;
|
|
4
4
|
exports.sameShiftSet = sameShiftSet;
|
|
5
5
|
exports.shiftsInForceAt = shiftsInForceAt;
|
|
6
6
|
exports.effectiveWorkShifts = effectiveWorkShifts;
|
|
@@ -15,12 +15,9 @@ const work_shift_revision_1 = require("./work-shift-revision");
|
|
|
15
15
|
const work_shift_lifecycle_1 = require("./work-shift-lifecycle");
|
|
16
16
|
const shift_occurrence_1 = require("./shift-occurrence");
|
|
17
17
|
const moment_timezone_1 = tslib_1.__importDefault(require("moment-timezone"));
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
fromTime: s.fromTime, toDate: s.toDate, toTime: s.toTime, daysOfWeek: s.daysOfWeek ?? '' }))
|
|
22
|
-
.sort((a, b) => a.fromDate - b.fromDate || a.fromTime.localeCompare(b.fromTime));
|
|
23
|
-
}
|
|
18
|
+
/* shiftSetOf lives with the content rules now; re-exported so callers keep their import. */
|
|
19
|
+
var work_shift_content_1 = require("./work-shift-content");
|
|
20
|
+
Object.defineProperty(exports, "shiftSetOf", { enumerable: true, get: function () { return work_shift_content_1.shiftSetOf; } });
|
|
24
21
|
function sameShiftSet(a, b) { return JSON.stringify(a) === JSON.stringify(b); }
|
|
25
22
|
async function shiftsInForceAt(manager, domain, at) {
|
|
26
23
|
const root = await manager.findOneBy(work_shift_arrangement_1.WorkShiftArrangement, { domain: { id: domain.id } });
|
|
@@ -36,6 +33,12 @@ async function shiftsInForceAt(manager, domain, at) {
|
|
|
36
33
|
catch (error) {
|
|
37
34
|
if (error instanceof work_shift_lifecycle_1.WorkShiftRefusal && error.code === 'NO_EFFECTIVE_REVISION')
|
|
38
35
|
return undefined;
|
|
36
|
+
/*
|
|
37
|
+
* 기준선 앞의 시각 — 그때의 교대는 기록된 적이 없다. 기준선 전과 같이 「알려진 편성 없음」으로 답한다.
|
|
38
|
+
* 「모름」과 「계획 0」을 가르는 일은 ADR-0090 ㉮ 의 나머지다(2026-09-24).
|
|
39
|
+
*/
|
|
40
|
+
if (error?.code === 'BEFORE_BASELINE')
|
|
41
|
+
return undefined;
|
|
39
42
|
throw error;
|
|
40
43
|
}
|
|
41
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work-shift-revision-service.js","sourceRoot":"","sources":["../../../server/service/work-shift/work-shift-revision-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager } from 'typeorm'\nimport { Domain } from '@things-factory/shell'\nimport { WorkShift } from './work-shift'\nimport { WorkShiftArrangement } from './work-shift-arrangement'\nimport { WorkShiftPlan, WorkShiftSegment } from './work-shift-revision'\nimport { WorkShiftRefusal, resolveWorkShift, workShiftSubmissionHash } from './work-shift-lifecycle'\nimport { shiftOccurrence } from './shift-occurrence'\nimport moment from 'moment-timezone'\n\n/** Every field affecting execution belongs to the signed arrangement. */\nexport function shiftSetOf(shifts: Partial<WorkShift>[]): Record<string, unknown>[] {\n return shifts.map(s => ({ name: s.name, description: s.description ?? '', fromDate: s.fromDate,\n fromTime: s.fromTime, toDate: s.toDate, toTime: s.toTime, daysOfWeek: s.daysOfWeek ?? '' }))\n .sort((a,b) => a.fromDate - b.fromDate || a.fromTime.localeCompare(b.fromTime))\n}\nexport function sameShiftSet(a: Record<string, unknown>[], b: Record<string, unknown>[]) { return JSON.stringify(a) === JSON.stringify(b) }\nexport async function shiftsInForceAt(manager: EntityManager, domain: Domain, at: Date) {\n const root = await manager.findOneBy(WorkShiftArrangement, { domain: { id: domain.id } })\n if (!root || !root.planGeneration) return undefined\n try {\n const selected = await resolveWorkShift(manager, domain.id, root.id, at)\n return { shifts: selected.revision.shifts, timezone: selected.revision.timezone,\n origin: 'revision' as const, from: selected.segment.validFrom, to: selected.segment.validTo,\n revisionId: selected.revision.id, revisionNumber: selected.revision.revisionNumber,\n creatorId: selected.revision.creatorId, createdAt: selected.revision.createdAt }\n } catch (error) {\n if (error instanceof WorkShiftRefusal && error.code === 'NO_EFFECTIVE_REVISION') return undefined\n throw error\n }\n}\n\nexport async function effectiveWorkShifts(manager: EntityManager, domain: Domain, at = new Date()): Promise<WorkShift[]> {\n const selected = await shiftsInForceAt(manager, domain, at)\n return (selected?.shifts ?? []).map(shift => Object.assign(new WorkShift(), shift, {\n id: selected.revisionId + '/' + shift.name, domain, domainId: domain.id,\n creatorId: selected.creatorId, updaterId: selected.creatorId,\n createdAt: selected.createdAt, updatedAt: selected.createdAt\n }))\n}\n\n/** Bounded expansion for OEE/planning windows; absolute intervals preserve zone/DST and revision boundaries. */\nexport async function shiftArrangementsDuring(manager: EntityManager, domain: Domain, from: Date, to: Date) {\n if (!(to > from) || to.getTime() - from.getTime() > 366 * 86400000) throw new WorkShiftRefusal('INVALID_INSTANT', 'Choose a window of at most 366 days.')\n const root = await manager.findOneBy(WorkShiftArrangement, { domain: { id: domain.id } })\n if (!root?.planGeneration) return []\n const plan = await manager.findOneByOrFail(WorkShiftPlan, { domain: { id: domain.id }, arrangement: { id: root.id }, generation: root.planGeneration })\n const segments = await manager.createQueryBuilder(WorkShiftSegment, 's').innerJoinAndSelect('s.revision', 'r')\n .where('s.plan_id = :id AND s.domain_id = :domainId', { id: plan.id, domainId: domain.id })\n .andWhere('s.validFrom < :to AND (s.validTo IS NULL OR s.validTo > :from)', { from, to }).getMany()\n return segments.map(segment => {\n const revision = segment.revision\n if (!revision.frozenAt || revision.contentHash !== workShiftSubmissionHash(revision)) throw new WorkShiftRefusal('REVISION_INTEGRITY_FAILURE')\n const begin = new Date(Math.max(from.getTime(), segment.validFrom.getTime()))\n const end = new Date(Math.min(to.getTime(), segment.validTo?.getTime() ?? Infinity))\n const cursor = moment(begin).tz(revision.timezone).startOf('day').subtract(1, 'day')\n const last = moment(end).tz(revision.timezone).startOf('day').add(1, 'day')\n const occurrences: { name: string; from: Date; to: Date }[] = []\n for (; cursor <= last; cursor.add(1, 'day')) for (const shift of revision.shifts) {\n const w = shiftOccurrence(shift, cursor.format('YYYY-MM-DD'), revision.timezone)\n if (!w) continue\n const left = new Date(Math.max(begin.getTime(), w.from.getTime())), right = new Date(Math.min(end.getTime(), w.to.getTime()))\n if (right > left) occurrences.push({ name: w.name, from: left, to: right })\n }\n return { revision, segment, occurrences }\n })\n}\n/** Old mutation/service entry points must never rewrite a signed schedule. */\nexport async function recordRevision(..._args: any[]): Promise<never> { throw new WorkShiftRefusal('REVISION_REQUIRED') }\nexport async function announceShiftSet(..._args: any[]): Promise<never> { throw new WorkShiftRefusal('REVISION_REQUIRED') }\nexport async function cancelAnnouncement(..._args: any[]): Promise<never> { throw new WorkShiftRefusal('REVISION_REQUIRED') }\n"]}
|
|
1
|
+
{"version":3,"file":"work-shift-revision-service.js","sourceRoot":"","sources":["../../../server/service/work-shift/work-shift-revision-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { EntityManager } from 'typeorm'\nimport { Domain } from '@things-factory/shell'\nimport { WorkShift } from './work-shift'\nimport { WorkShiftArrangement } from './work-shift-arrangement'\nimport { WorkShiftPlan, WorkShiftSegment } from './work-shift-revision'\nimport { WorkShiftRefusal, resolveWorkShift, workShiftSubmissionHash } from './work-shift-lifecycle'\nimport { shiftOccurrence } from './shift-occurrence'\nimport moment from 'moment-timezone'\n\n/* shiftSetOf lives with the content rules now; re-exported so callers keep their import. */\nexport { shiftSetOf } from './work-shift-content'\nexport function sameShiftSet(a: Record<string, unknown>[], b: Record<string, unknown>[]) { return JSON.stringify(a) === JSON.stringify(b) }\nexport async function shiftsInForceAt(manager: EntityManager, domain: Domain, at: Date) {\n const root = await manager.findOneBy(WorkShiftArrangement, { domain: { id: domain.id } })\n if (!root || !root.planGeneration) return undefined\n try {\n const selected = await resolveWorkShift(manager, domain.id, root.id, at)\n return { shifts: selected.revision.shifts, timezone: selected.revision.timezone,\n origin: 'revision' as const, from: selected.segment.validFrom, to: selected.segment.validTo,\n revisionId: selected.revision.id, revisionNumber: selected.revision.revisionNumber,\n creatorId: selected.revision.creatorId, createdAt: selected.revision.createdAt }\n } catch (error) {\n if (error instanceof WorkShiftRefusal && error.code === 'NO_EFFECTIVE_REVISION') return undefined\n /*\n * 기준선 앞의 시각 — 그때의 교대는 기록된 적이 없다. 기준선 전과 같이 「알려진 편성 없음」으로 답한다.\n * 「모름」과 「계획 0」을 가르는 일은 ADR-0090 ㉮ 의 나머지다(2026-09-24).\n */\n if ((error as any)?.code === 'BEFORE_BASELINE') return undefined\n throw error\n }\n}\n\nexport async function effectiveWorkShifts(manager: EntityManager, domain: Domain, at = new Date()): Promise<WorkShift[]> {\n const selected = await shiftsInForceAt(manager, domain, at)\n return (selected?.shifts ?? []).map(shift => Object.assign(new WorkShift(), shift, {\n id: selected.revisionId + '/' + shift.name, domain, domainId: domain.id,\n creatorId: selected.creatorId, updaterId: selected.creatorId,\n createdAt: selected.createdAt, updatedAt: selected.createdAt\n }))\n}\n\n/** Bounded expansion for OEE/planning windows; absolute intervals preserve zone/DST and revision boundaries. */\nexport async function shiftArrangementsDuring(manager: EntityManager, domain: Domain, from: Date, to: Date) {\n if (!(to > from) || to.getTime() - from.getTime() > 366 * 86400000) throw new WorkShiftRefusal('INVALID_INSTANT', 'Choose a window of at most 366 days.')\n const root = await manager.findOneBy(WorkShiftArrangement, { domain: { id: domain.id } })\n if (!root?.planGeneration) return []\n const plan = await manager.findOneByOrFail(WorkShiftPlan, { domain: { id: domain.id }, arrangement: { id: root.id }, generation: root.planGeneration })\n const segments = await manager.createQueryBuilder(WorkShiftSegment, 's').innerJoinAndSelect('s.revision', 'r')\n .where('s.plan_id = :id AND s.domain_id = :domainId', { id: plan.id, domainId: domain.id })\n .andWhere('s.validFrom < :to AND (s.validTo IS NULL OR s.validTo > :from)', { from, to }).getMany()\n return segments.map(segment => {\n const revision = segment.revision\n if (!revision.frozenAt || revision.contentHash !== workShiftSubmissionHash(revision)) throw new WorkShiftRefusal('REVISION_INTEGRITY_FAILURE')\n const begin = new Date(Math.max(from.getTime(), segment.validFrom.getTime()))\n const end = new Date(Math.min(to.getTime(), segment.validTo?.getTime() ?? Infinity))\n const cursor = moment(begin).tz(revision.timezone).startOf('day').subtract(1, 'day')\n const last = moment(end).tz(revision.timezone).startOf('day').add(1, 'day')\n const occurrences: { name: string; from: Date; to: Date }[] = []\n for (; cursor <= last; cursor.add(1, 'day')) for (const shift of revision.shifts) {\n const w = shiftOccurrence(shift, cursor.format('YYYY-MM-DD'), revision.timezone)\n if (!w) continue\n const left = new Date(Math.max(begin.getTime(), w.from.getTime())), right = new Date(Math.min(end.getTime(), w.to.getTime()))\n if (right > left) occurrences.push({ name: w.name, from: left, to: right })\n }\n return { revision, segment, occurrences }\n })\n}\n/** Old mutation/service entry points must never rewrite a signed schedule. */\nexport async function recordRevision(..._args: any[]): Promise<never> { throw new WorkShiftRefusal('REVISION_REQUIRED') }\nexport async function announceShiftSet(..._args: any[]): Promise<never> { throw new WorkShiftRefusal('REVISION_REQUIRED') }\nexport async function cancelAnnouncement(..._args: any[]): Promise<never> { throw new WorkShiftRefusal('REVISION_REQUIRED') }\n"]}
|
|
@@ -22,8 +22,9 @@ export declare class WorkShiftRevision {
|
|
|
22
22
|
shifts: import('./work-shift-content').ShiftDefinition[];
|
|
23
23
|
effectiveFrom: Date;
|
|
24
24
|
reason: string;
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
/** Empty only on a baseline: nobody wrote it, it records the shifts as they already stood. */
|
|
26
|
+
creator: User | null;
|
|
27
|
+
creatorId: string | null;
|
|
27
28
|
createdAt: Date;
|
|
28
29
|
frozenAt: Date | null;
|
|
29
30
|
contentHash: string | null;
|
|
@@ -36,9 +37,10 @@ export declare class WorkShiftPlan {
|
|
|
36
37
|
policyId: string;
|
|
37
38
|
publishedRevision: WorkShiftRevision;
|
|
38
39
|
publishedRevisionId: string;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
/** `baseline`: stood at boot from shifts that predate revisions. No approver, no publisher. */
|
|
41
|
+
releaseKind: 'approved' | 'policy' | 'baseline';
|
|
42
|
+
publisher: User | null;
|
|
43
|
+
publisherId: string | null;
|
|
42
44
|
id: string;
|
|
43
45
|
domain: Domain;
|
|
44
46
|
domainId: string;
|
|
@@ -83,7 +83,7 @@ tslib_1.__decorate([
|
|
|
83
83
|
tslib_1.__metadata("design:type", String)
|
|
84
84
|
], WorkShiftRevision.prototype, "reason", void 0);
|
|
85
85
|
tslib_1.__decorate([
|
|
86
|
-
(0, typeorm_1.ManyToOne)(() => auth_base_1.User, { nullable:
|
|
86
|
+
(0, typeorm_1.ManyToOne)(() => auth_base_1.User, { nullable: true }),
|
|
87
87
|
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
88
88
|
], WorkShiftRevision.prototype, "creator", void 0);
|
|
89
89
|
tslib_1.__decorate([
|
|
@@ -142,7 +142,7 @@ tslib_1.__decorate([
|
|
|
142
142
|
tslib_1.__metadata("design:type", String)
|
|
143
143
|
], WorkShiftPlan.prototype, "releaseKind", void 0);
|
|
144
144
|
tslib_1.__decorate([
|
|
145
|
-
(0, typeorm_1.ManyToOne)(() => auth_base_1.User, { nullable:
|
|
145
|
+
(0, typeorm_1.ManyToOne)(() => auth_base_1.User, { nullable: true }),
|
|
146
146
|
tslib_1.__metadata("design:type", auth_base_1.User)
|
|
147
147
|
], WorkShiftPlan.prototype, "publisher", void 0);
|
|
148
148
|
tslib_1.__decorate([
|