@msm-core/jobs 0.1.0 → 0.2.0
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/approval/engine.d.ts +30 -0
- package/dist/approval/engine.d.ts.map +1 -0
- package/dist/approval/engine.js +146 -0
- package/dist/approval/engine.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +20 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/dist/mission/cron.d.ts +23 -0
- package/dist/mission/cron.d.ts.map +1 -0
- package/dist/mission/cron.js +175 -0
- package/dist/mission/cron.js.map +1 -0
- package/dist/mission/scheduler.d.ts +14 -0
- package/dist/mission/scheduler.d.ts.map +1 -0
- package/dist/mission/scheduler.js +185 -0
- package/dist/mission/scheduler.js.map +1 -0
- package/dist/port.d.ts +49 -1
- package/dist/port.d.ts.map +1 -1
- package/dist/port.js.map +1 -1
- package/dist/types.d.ts +65 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ApprovalCreatorPort, ApprovalStore, ClockPort, JobOpsPort, JobStore, QueuePort } from "../port.js";
|
|
2
|
+
import type { JobEngineConfig } from "../config.js";
|
|
3
|
+
import type { ApprovalRecord } from "../types.js";
|
|
4
|
+
export interface ApprovalEngineDeps {
|
|
5
|
+
approvalStore: ApprovalStore;
|
|
6
|
+
jobStore: JobStore;
|
|
7
|
+
queue: QueuePort;
|
|
8
|
+
ops: JobOpsPort;
|
|
9
|
+
clock: ClockPort;
|
|
10
|
+
config: JobEngineConfig;
|
|
11
|
+
genApprovalId: () => string;
|
|
12
|
+
}
|
|
13
|
+
export type ApprovalDecision = "approve" | "reject";
|
|
14
|
+
export interface ResolveApprovalResult {
|
|
15
|
+
approval: ApprovalRecord;
|
|
16
|
+
jobResumed: boolean;
|
|
17
|
+
alreadyResolved: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface ApprovalEngine extends ApprovalCreatorPort {
|
|
20
|
+
resolve(args: {
|
|
21
|
+
approvalId: string;
|
|
22
|
+
tenantId: string;
|
|
23
|
+
decision: ApprovalDecision;
|
|
24
|
+
decidedBy: string;
|
|
25
|
+
updatedParams?: Record<string, unknown> | null;
|
|
26
|
+
}): Promise<ResolveApprovalResult>;
|
|
27
|
+
expireStale(asOf?: Date): Promise<number>;
|
|
28
|
+
}
|
|
29
|
+
export declare function createApprovalEngine(deps: ApprovalEngineDeps): ApprovalEngine;
|
|
30
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/approval/engine.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,UAAU,EACV,QAAQ,EACR,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEpD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD,OAAO,CAAC,IAAI,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,gBAAgB,CAAC;QAC3B,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;KAChD,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACnC,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3C;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CAoJ7E"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// HITL approval engine (S2). `create` is the ApprovalCreatorPort the orchestrator calls when a
|
|
2
|
+
// step transitions to awaiting_approval; `resolve` performs the one-shot CAS on the approval and
|
|
3
|
+
// (on approve) flips the job awaiting_approval→queued + re-enqueues, or (on reject) cancels it —
|
|
4
|
+
// the version guard makes both exactly-once. `expireStale` applies the timeout (→ paused).
|
|
5
|
+
// Ported from kader's approval.service.ts (createJobApproval + approve job-resume path).
|
|
6
|
+
const QUEUE_NAME = "jobs";
|
|
7
|
+
export function createApprovalEngine(deps) {
|
|
8
|
+
const { approvalStore, jobStore, queue, ops, clock, config } = deps;
|
|
9
|
+
async function create(input) {
|
|
10
|
+
const existing = await approvalStore.findPendingForStep(input.tenantId, input.jobId, input.stepNumber);
|
|
11
|
+
if (existing)
|
|
12
|
+
return { approvalId: existing.approvalId, expiresAt: existing.expiresAt };
|
|
13
|
+
const approvalId = deps.genApprovalId();
|
|
14
|
+
const expiresAt = new Date(clock.now().getTime() + (input.approvalTimeoutMs ?? config.defaultApprovalExpiryMs));
|
|
15
|
+
const rec = await approvalStore.create({
|
|
16
|
+
approvalId,
|
|
17
|
+
tenantId: input.tenantId,
|
|
18
|
+
employeeId: input.employeeId,
|
|
19
|
+
jobId: input.jobId,
|
|
20
|
+
jobStepNumber: input.stepNumber,
|
|
21
|
+
jobVersion: input.jobVersion,
|
|
22
|
+
action: {
|
|
23
|
+
toolName: "job_step_approval",
|
|
24
|
+
workflowType: input.workflowType,
|
|
25
|
+
stepType: input.stepType,
|
|
26
|
+
transitionReason: input.transitionReason,
|
|
27
|
+
approvalPolicy: input.approvalPolicy,
|
|
28
|
+
...(input.metadata || {}),
|
|
29
|
+
},
|
|
30
|
+
reasoning: input.reasoning,
|
|
31
|
+
expiresAt,
|
|
32
|
+
});
|
|
33
|
+
ops.record({
|
|
34
|
+
jobId: input.jobId,
|
|
35
|
+
tenantId: input.tenantId,
|
|
36
|
+
source: "approval_service",
|
|
37
|
+
eventType: "job.approval.created",
|
|
38
|
+
status: "awaiting_approval",
|
|
39
|
+
employeeId: input.employeeId,
|
|
40
|
+
metadata: { approvalId: rec.approvalId, stepNumber: input.stepNumber, approvalPolicy: input.approvalPolicy },
|
|
41
|
+
});
|
|
42
|
+
return { approvalId: rec.approvalId, expiresAt: rec.expiresAt };
|
|
43
|
+
}
|
|
44
|
+
async function resolve(args) {
|
|
45
|
+
const toStatus = args.decision === "approve" ? "approved" : "rejected";
|
|
46
|
+
const rec = await approvalStore.resolve({
|
|
47
|
+
approvalId: args.approvalId,
|
|
48
|
+
tenantId: args.tenantId,
|
|
49
|
+
toStatus,
|
|
50
|
+
decidedBy: args.decidedBy,
|
|
51
|
+
decidedAt: clock.now(),
|
|
52
|
+
updatedParams: args.updatedParams ?? null,
|
|
53
|
+
});
|
|
54
|
+
if (!rec) {
|
|
55
|
+
const existing = await approvalStore.getById(args.approvalId, args.tenantId);
|
|
56
|
+
if (!existing)
|
|
57
|
+
throw new Error(`approval not found: ${args.approvalId}`);
|
|
58
|
+
return { approval: existing, jobResumed: false, alreadyResolved: true };
|
|
59
|
+
}
|
|
60
|
+
let jobResumed = false;
|
|
61
|
+
if (rec.jobId && rec.jobVersion !== null) {
|
|
62
|
+
const snap = await jobStore.getJob(rec.jobId, args.tenantId);
|
|
63
|
+
if (snap && snap.status === "awaiting_approval" && snap.version === rec.jobVersion) {
|
|
64
|
+
const stamp = {
|
|
65
|
+
approvalId: rec.approvalId,
|
|
66
|
+
decision: toStatus,
|
|
67
|
+
decidedBy: args.decidedBy,
|
|
68
|
+
decidedAt: clock.now().toISOString(),
|
|
69
|
+
};
|
|
70
|
+
const set = toStatus === "approved"
|
|
71
|
+
? { status: "queued", resumeAt: null, waitEvent: null, state: { ...(snap.state || {}), approval: stamp } }
|
|
72
|
+
: { status: "cancelled", completedAt: clock.now(), state: { ...(snap.state || {}), approval: stamp } };
|
|
73
|
+
const job = await jobStore.claim({
|
|
74
|
+
jobId: rec.jobId,
|
|
75
|
+
tenantId: args.tenantId,
|
|
76
|
+
expectedVersion: snap.version,
|
|
77
|
+
statusIn: ["awaiting_approval"],
|
|
78
|
+
set,
|
|
79
|
+
});
|
|
80
|
+
if (job) {
|
|
81
|
+
if (toStatus === "approved") {
|
|
82
|
+
await queue.enqueue({ jobId: rec.jobId, tenantId: args.tenantId, reason: "approval_resolved", dedupeKey: rec.approvalId });
|
|
83
|
+
jobResumed = true;
|
|
84
|
+
}
|
|
85
|
+
ops.record({
|
|
86
|
+
jobId: rec.jobId,
|
|
87
|
+
tenantId: args.tenantId,
|
|
88
|
+
missionId: job.missionId,
|
|
89
|
+
source: "approval_service",
|
|
90
|
+
eventType: "job.approval.resolved",
|
|
91
|
+
status: job.status,
|
|
92
|
+
queueName: QUEUE_NAME,
|
|
93
|
+
employeeId: job.employeeId,
|
|
94
|
+
correlationId: job.correlationId,
|
|
95
|
+
metadata: { approvalId: rec.approvalId, stepNumber: rec.jobStepNumber, decision: toStatus },
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { approval: rec, jobResumed, alreadyResolved: false };
|
|
101
|
+
}
|
|
102
|
+
async function expireStale(asOf = clock.now()) {
|
|
103
|
+
const expired = await approvalStore.findExpired(asOf, Math.max(1, config.waitReconcileBatchSize));
|
|
104
|
+
let count = 0;
|
|
105
|
+
for (const a of expired) {
|
|
106
|
+
const rec = await approvalStore.resolve({
|
|
107
|
+
approvalId: a.approvalId,
|
|
108
|
+
tenantId: a.tenantId,
|
|
109
|
+
toStatus: "expired",
|
|
110
|
+
decidedBy: "system",
|
|
111
|
+
decidedAt: clock.now(),
|
|
112
|
+
});
|
|
113
|
+
if (!rec)
|
|
114
|
+
continue;
|
|
115
|
+
count += 1;
|
|
116
|
+
if (rec.jobId && rec.jobVersion !== null) {
|
|
117
|
+
const snap = await jobStore.getJob(rec.jobId, rec.tenantId);
|
|
118
|
+
if (snap && snap.status === "awaiting_approval" && snap.version === rec.jobVersion) {
|
|
119
|
+
// Timeout outcome: park the job as paused (a human is needed). The richer
|
|
120
|
+
// escalate / auto-approve variants resolve from the policy in a later pass.
|
|
121
|
+
await jobStore.claim({
|
|
122
|
+
jobId: rec.jobId,
|
|
123
|
+
tenantId: rec.tenantId,
|
|
124
|
+
expectedVersion: snap.version,
|
|
125
|
+
statusIn: ["awaiting_approval"],
|
|
126
|
+
set: { status: "paused", state: { ...(snap.state || {}), approval: { approvalId: a.approvalId, decision: "expired" } } },
|
|
127
|
+
});
|
|
128
|
+
ops.record({
|
|
129
|
+
jobId: rec.jobId,
|
|
130
|
+
tenantId: rec.tenantId,
|
|
131
|
+
missionId: snap.missionId,
|
|
132
|
+
source: "approval_service",
|
|
133
|
+
eventType: "job.approval.expired",
|
|
134
|
+
status: "paused",
|
|
135
|
+
employeeId: snap.employeeId,
|
|
136
|
+
correlationId: snap.correlationId,
|
|
137
|
+
metadata: { approvalId: a.approvalId },
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return count;
|
|
143
|
+
}
|
|
144
|
+
return { create, resolve, expireStale };
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/approval/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface JobEngineConfig {
|
|
|
21
21
|
secret: string;
|
|
22
22
|
ttlSeconds: number;
|
|
23
23
|
};
|
|
24
|
+
/** Default HITL approval expiry when a workflow step omits approvalTimeoutMs (S2). */
|
|
25
|
+
defaultApprovalExpiryMs: number;
|
|
24
26
|
}
|
|
25
27
|
export declare const DEFAULT_JOB_ENGINE_CONFIG: JobEngineConfig;
|
|
26
28
|
export interface OrchestratorRunConfig {
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,4CAA4C;IAC5C,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,eAAe,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,4CAA4C;IAC5C,WAAW,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,sFAAsF;IACtF,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED,eAAO,MAAM,yBAAyB,EAAE,eAQvC,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,qBAAqB,CAK/E"}
|
package/dist/config.js
CHANGED
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,kFAAkF;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,kFAAkF;AA2BlF,MAAM,CAAC,MAAM,yBAAyB,GAAoB;IACxD,eAAe,EAAE,CAAC;IAClB,sBAAsB,EAAE,KAAK;IAC7B,UAAU,EAAE,SAAS;IACrB,aAAa,EAAE,MAAM;IACrB,sBAAsB,EAAE,EAAE;IAC1B,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;IAC/C,uBAAuB,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;CAC7C,CAAC;AAOF,MAAM,UAAU,gBAAgB,CAAC,MAAuB;IACtD,OAAO;QACL,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;QACjE,sBAAsB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,sBAAsB,CAAC;KACnE,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { type Orchestrator, type OrchestrateJobStepInput } from "./orchestrator.js";
|
|
2
2
|
import { type Reconciler } from "./reconciler.js";
|
|
3
3
|
import { type ResumeTokenService } from "./resume-token.js";
|
|
4
|
+
import { type MissionScheduler } from "./mission/scheduler.js";
|
|
5
|
+
import { type ApprovalEngine } from "./approval/engine.js";
|
|
4
6
|
import { DEFAULT_JOB_ENGINE_CONFIG, type JobEngineConfig } from "./config.js";
|
|
5
|
-
import type { ApprovalCreatorPort, ClockPort, JobOpsPort, JobStore, LockPort, NoncePort, QueuePort, StepExecutorPort, WorkflowRegistry } from "./port.js";
|
|
7
|
+
import type { ApprovalCreatorPort, ApprovalStore, ClockPort, JobOpsPort, JobStore, LockPort, MissionStore, NoncePort, QueuePort, StepExecutorPort, WorkflowRegistry } from "./port.js";
|
|
6
8
|
export interface CreateJobEngineDeps {
|
|
7
9
|
jobStore: JobStore;
|
|
8
10
|
queue: QueuePort;
|
|
@@ -13,9 +15,17 @@ export interface CreateJobEngineDeps {
|
|
|
13
15
|
registry: WorkflowRegistry;
|
|
14
16
|
stepExecutor: StepExecutorPort;
|
|
15
17
|
config: JobEngineConfig;
|
|
18
|
+
/** S2: HITL approval persistence. When provided, the engine builds the approval engine and
|
|
19
|
+
* uses it as the approvalCreator automatically (awaiting_approval steps create a record). */
|
|
20
|
+
approvalStore?: ApprovalStore;
|
|
21
|
+
/** S2: mission persistence. When provided, the engine exposes a cron mission scheduler. */
|
|
22
|
+
missionStore?: MissionStore;
|
|
23
|
+
/** Explicit approvalCreator override (else the built approval engine, if approvalStore given). */
|
|
16
24
|
approvalCreator?: ApprovalCreatorPort;
|
|
17
|
-
/** Override
|
|
25
|
+
/** Override id generators (default: crypto.randomUUID). */
|
|
18
26
|
genStepId?: () => string;
|
|
27
|
+
genApprovalId?: () => string;
|
|
28
|
+
genMissionRunId?: () => string;
|
|
19
29
|
/** Reconciler lock TTL (default: derived from the scan interval). */
|
|
20
30
|
reconcileLockTtlMs?: number;
|
|
21
31
|
}
|
|
@@ -23,6 +33,10 @@ export interface JobEngine {
|
|
|
23
33
|
orchestrateJobStep: Orchestrator["orchestrateJobStep"];
|
|
24
34
|
reconcileWaitingTimeJobs: Reconciler["reconcileWaitingTimeJobs"];
|
|
25
35
|
resumeToken: ResumeTokenService;
|
|
36
|
+
/** Present when approvalStore was provided (S2). */
|
|
37
|
+
approval?: ApprovalEngine;
|
|
38
|
+
/** Present when missionStore was provided (S2). */
|
|
39
|
+
missions?: MissionScheduler;
|
|
26
40
|
}
|
|
27
41
|
/** Assemble the durable job engine from ports + config. */
|
|
28
42
|
export declare function createJobEngine(deps: CreateJobEngineDeps): JobEngine;
|
|
@@ -32,6 +46,10 @@ export type { ResumeTokenService };
|
|
|
32
46
|
export { createResumeTokenService, ResumeTokenError, type IssuedResumeToken, type ConsumedResumeToken, } from "./resume-token.js";
|
|
33
47
|
export { createWorkflowRegistry, BUILTIN_JOB_BASIC } from "./workflow/registry.js";
|
|
34
48
|
export type { WaitingTimeReconcileResult } from "./reconciler.js";
|
|
49
|
+
export { createMissionScheduler, type MissionScheduler } from "./mission/scheduler.js";
|
|
50
|
+
export { isMissionCronDueAt, isWithinQuietHours, matchesCronField, parseDurationToMs, } from "./mission/cron.js";
|
|
51
|
+
export { createApprovalEngine, type ApprovalEngine, type ApprovalDecision, type ResolveApprovalResult, } from "./approval/engine.js";
|
|
52
|
+
export type { MissionTrigger, MissionQuietHours, MissionSafety, MissionRecord, MissionRunRecord, MissionSchedulerTickResult, ApprovalRecord, ApprovalStatus, } from "./types.js";
|
|
35
53
|
export { JOB_STATUSES, TERMINAL_JOB_STATUSES, RUNNABLE_JOB_STATUSES, JOB_STEP_TYPES, JOB_STEP_STATUSES, JOB_STEP_TRIGGERED_BY, MISSION_RUN_STATUSES, isTerminalJobStatus, isRunnableJobStatus, type JobStatus, type TerminalJobStatus, type JobStepType, type JobStepStatus, type JobStepTriggeredBy, type MissionRunStatus, } from "./enums.js";
|
|
36
54
|
export type { JobBudget, JobWaitEvent, JobSnapshot, JobStepRecord, JobStepToolCall, CreateJobInput, JobOpsEventInput, WorkflowResolution, WorkflowContext, WorkflowSequenceStep, WorkflowDefinition, } from "./types.js";
|
|
37
55
|
export { JOB_APPROVAL_POLICIES, DEFAULT_JOB_APPROVAL_POLICY, isJobApprovalPolicy, parseJobApprovalPolicy, resolveJobApprovalTimeoutOutcome, type JobApprovalPolicy, type JobApprovalTimeoutOutcome, } from "./approval/policy.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAsB,KAAK,YAAY,EAAE,KAAK,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACxG,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,YAAY,EAAE,gBAAgB,CAAC;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,8 @@ import { randomUUID } from "node:crypto";
|
|
|
5
5
|
import { createOrchestrator } from "./orchestrator.js";
|
|
6
6
|
import { createReconciler } from "./reconciler.js";
|
|
7
7
|
import { createResumeTokenService } from "./resume-token.js";
|
|
8
|
+
import { createMissionScheduler } from "./mission/scheduler.js";
|
|
9
|
+
import { createApprovalEngine } from "./approval/engine.js";
|
|
8
10
|
import { DEFAULT_JOB_ENGINE_CONFIG } from "./config.js";
|
|
9
11
|
/** Assemble the durable job engine from ports + config. */
|
|
10
12
|
export function createJobEngine(deps) {
|
|
@@ -14,6 +16,19 @@ export function createJobEngine(deps) {
|
|
|
14
16
|
ttlSeconds: deps.config.resumeToken.ttlSeconds,
|
|
15
17
|
nonce: deps.nonce,
|
|
16
18
|
});
|
|
19
|
+
// S2: build the approval engine when its store is provided; it doubles as the approvalCreator.
|
|
20
|
+
const approval = deps.approvalStore
|
|
21
|
+
? createApprovalEngine({
|
|
22
|
+
approvalStore: deps.approvalStore,
|
|
23
|
+
jobStore: deps.jobStore,
|
|
24
|
+
queue: deps.queue,
|
|
25
|
+
ops: deps.ops,
|
|
26
|
+
clock: deps.clock,
|
|
27
|
+
config: deps.config,
|
|
28
|
+
genApprovalId: deps.genApprovalId ?? (() => `appr_${randomUUID()}`),
|
|
29
|
+
})
|
|
30
|
+
: undefined;
|
|
31
|
+
const approvalCreator = deps.approvalCreator ?? approval;
|
|
17
32
|
const orchestrator = createOrchestrator({
|
|
18
33
|
jobStore: deps.jobStore,
|
|
19
34
|
queue: deps.queue,
|
|
@@ -24,7 +39,7 @@ export function createJobEngine(deps) {
|
|
|
24
39
|
resumeToken,
|
|
25
40
|
config: deps.config,
|
|
26
41
|
genStepId,
|
|
27
|
-
...(
|
|
42
|
+
...(approvalCreator ? { approvalCreator } : {}),
|
|
28
43
|
});
|
|
29
44
|
const reconciler = createReconciler({
|
|
30
45
|
jobStore: deps.jobStore,
|
|
@@ -35,16 +50,32 @@ export function createJobEngine(deps) {
|
|
|
35
50
|
config: deps.config,
|
|
36
51
|
lockTtlMs: deps.reconcileLockTtlMs ?? 30_000,
|
|
37
52
|
});
|
|
53
|
+
// S2: cron mission scheduler when its store is provided.
|
|
54
|
+
const missions = deps.missionStore
|
|
55
|
+
? createMissionScheduler({
|
|
56
|
+
missionStore: deps.missionStore,
|
|
57
|
+
jobStore: deps.jobStore,
|
|
58
|
+
ops: deps.ops,
|
|
59
|
+
clock: deps.clock,
|
|
60
|
+
genMissionRunId: deps.genMissionRunId ?? (() => `mrun_${randomUUID()}`),
|
|
61
|
+
})
|
|
62
|
+
: undefined;
|
|
38
63
|
return {
|
|
39
64
|
orchestrateJobStep: orchestrator.orchestrateJobStep,
|
|
40
65
|
reconcileWaitingTimeJobs: reconciler.reconcileWaitingTimeJobs,
|
|
41
66
|
resumeToken,
|
|
67
|
+
...(approval ? { approval } : {}),
|
|
68
|
+
...(missions ? { missions } : {}),
|
|
42
69
|
};
|
|
43
70
|
}
|
|
44
71
|
// ── Public surface ──
|
|
45
72
|
export { DEFAULT_JOB_ENGINE_CONFIG };
|
|
46
73
|
export { createResumeTokenService, ResumeTokenError, } from "./resume-token.js";
|
|
47
74
|
export { createWorkflowRegistry, BUILTIN_JOB_BASIC } from "./workflow/registry.js";
|
|
75
|
+
// S2 — missions + approval
|
|
76
|
+
export { createMissionScheduler } from "./mission/scheduler.js";
|
|
77
|
+
export { isMissionCronDueAt, isWithinQuietHours, matchesCronField, parseDurationToMs, } from "./mission/cron.js";
|
|
78
|
+
export { createApprovalEngine, } from "./approval/engine.js";
|
|
48
79
|
// Enums + types
|
|
49
80
|
export { JOB_STATUSES, TERMINAL_JOB_STATUSES, RUNNABLE_JOB_STATUSES, JOB_STEP_TYPES, JOB_STEP_STATUSES, JOB_STEP_TRIGGERED_BY, MISSION_RUN_STATUSES, isTerminalJobStatus, isRunnableJobStatus, } from "./enums.js";
|
|
50
81
|
export { JOB_APPROVAL_POLICIES, DEFAULT_JOB_APPROVAL_POLICY, isJobApprovalPolicy, parseJobApprovalPolicy, resolveJobApprovalTimeoutOutcome, } from "./approval/policy.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,kFAAkF;AAClF,gFAAgF;AAEhF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAmD,MAAM,mBAAmB,CAAC;AACxG,OAAO,EAAE,gBAAgB,EAAmB,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAA2B,MAAM,mBAAmB,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAwB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface ZonedDateParts {
|
|
2
|
+
year: number;
|
|
3
|
+
month: number;
|
|
4
|
+
dayOfMonth: number;
|
|
5
|
+
dayOfWeek: number;
|
|
6
|
+
hour: number;
|
|
7
|
+
minute: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function matchesCronField(field: string, value: number, min: number, max: number): boolean;
|
|
10
|
+
export declare function getZonedDateParts(date: Date, timezone: string): ZonedDateParts;
|
|
11
|
+
export declare function parseDurationToMs(value: string): number;
|
|
12
|
+
export declare function isWithinQuietHours(quietHours: {
|
|
13
|
+
start: string;
|
|
14
|
+
end: string;
|
|
15
|
+
timezone: string;
|
|
16
|
+
}, now: Date): boolean;
|
|
17
|
+
export declare function isMissionCronDueAt(params: {
|
|
18
|
+
cronExpression: string;
|
|
19
|
+
timezone: string;
|
|
20
|
+
now: Date;
|
|
21
|
+
lastTriggeredAt?: Date | null;
|
|
22
|
+
}): boolean;
|
|
23
|
+
//# sourceMappingURL=cron.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/mission/cron.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAgDD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAKhG;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAkB9E;AAgBD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC5D,GAAG,EAAE,IAAI,GACR,OAAO,CAcT;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,IAAI,CAAC;IACV,eAAe,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CAC/B,GAAG,OAAO,CAmCV"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// Pure cron evaluation for missions — zero I/O (only Intl for timezone). Ported verbatim
|
|
2
|
+
// from kader's mission-scheduler.service.ts so the due/quiet-hours semantics are identical:
|
|
3
|
+
// 5-field cron, ranges, lists, `*/n` steps, timezone via Intl, and the standard day-of-month
|
|
4
|
+
// OR day-of-week rule. Exported for direct unit testing.
|
|
5
|
+
const WEEKDAY_TO_NUMBER = {
|
|
6
|
+
Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6,
|
|
7
|
+
};
|
|
8
|
+
function parseNumber(value) {
|
|
9
|
+
const parsed = parseInt(value, 10);
|
|
10
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
11
|
+
}
|
|
12
|
+
function normalizeDayOfWeek(value) {
|
|
13
|
+
return value === 7 ? 0 : value;
|
|
14
|
+
}
|
|
15
|
+
function isValueInRange(value, min, max) {
|
|
16
|
+
return value >= min && value <= max;
|
|
17
|
+
}
|
|
18
|
+
function parseRangeToken(token, min, max) {
|
|
19
|
+
if (token === "*")
|
|
20
|
+
return { start: min, end: max };
|
|
21
|
+
if (token.includes("-")) {
|
|
22
|
+
const [rawStart, rawEnd] = token.split("-", 2);
|
|
23
|
+
if (!rawStart || !rawEnd)
|
|
24
|
+
return null;
|
|
25
|
+
const startParsed = parseNumber(rawStart);
|
|
26
|
+
const endParsed = parseNumber(rawEnd);
|
|
27
|
+
if (startParsed === null || endParsed === null)
|
|
28
|
+
return null;
|
|
29
|
+
const start = min === 0 && max === 6 ? normalizeDayOfWeek(startParsed) : startParsed;
|
|
30
|
+
const end = min === 0 && max === 6 ? normalizeDayOfWeek(endParsed) : endParsed;
|
|
31
|
+
if (!isValueInRange(start, min, max) || !isValueInRange(end, min, max))
|
|
32
|
+
return null;
|
|
33
|
+
if (end < start)
|
|
34
|
+
return null;
|
|
35
|
+
return { start, end };
|
|
36
|
+
}
|
|
37
|
+
const parsed = parseNumber(token);
|
|
38
|
+
if (parsed === null)
|
|
39
|
+
return null;
|
|
40
|
+
const normalized = min === 0 && max === 6 ? normalizeDayOfWeek(parsed) : parsed;
|
|
41
|
+
if (!isValueInRange(normalized, min, max))
|
|
42
|
+
return null;
|
|
43
|
+
return { start: normalized, end: normalized };
|
|
44
|
+
}
|
|
45
|
+
function matchesCronSegment(segment, value, min, max) {
|
|
46
|
+
const [baseToken, stepToken] = segment.split("/", 2);
|
|
47
|
+
if (!baseToken)
|
|
48
|
+
return false;
|
|
49
|
+
const range = parseRangeToken(baseToken, min, max);
|
|
50
|
+
if (!range)
|
|
51
|
+
return false;
|
|
52
|
+
if (!(value >= range.start && value <= range.end))
|
|
53
|
+
return false;
|
|
54
|
+
if (!stepToken)
|
|
55
|
+
return true;
|
|
56
|
+
const step = parseNumber(stepToken);
|
|
57
|
+
if (step === null || step <= 0)
|
|
58
|
+
return false;
|
|
59
|
+
return (value - range.start) % step === 0;
|
|
60
|
+
}
|
|
61
|
+
export function matchesCronField(field, value, min, max) {
|
|
62
|
+
const normalizedValue = min === 0 && max === 6 ? normalizeDayOfWeek(value) : value;
|
|
63
|
+
const segments = field.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
64
|
+
if (segments.length === 0)
|
|
65
|
+
return false;
|
|
66
|
+
return segments.some((segment) => matchesCronSegment(segment, normalizedValue, min, max));
|
|
67
|
+
}
|
|
68
|
+
export function getZonedDateParts(date, timezone) {
|
|
69
|
+
const formatter = new Intl.DateTimeFormat("en-US", {
|
|
70
|
+
timeZone: timezone, year: "numeric", month: "2-digit", day: "2-digit",
|
|
71
|
+
weekday: "short", hour: "2-digit", minute: "2-digit", hourCycle: "h23",
|
|
72
|
+
});
|
|
73
|
+
const values = new Map();
|
|
74
|
+
for (const part of formatter.formatToParts(date)) {
|
|
75
|
+
if (part.type !== "literal")
|
|
76
|
+
values.set(part.type, part.value);
|
|
77
|
+
}
|
|
78
|
+
const weekday = values.get("weekday") || "Sun";
|
|
79
|
+
return {
|
|
80
|
+
year: parseInt(values.get("year") || "1970", 10),
|
|
81
|
+
month: parseInt(values.get("month") || "1", 10),
|
|
82
|
+
dayOfMonth: parseInt(values.get("day") || "1", 10),
|
|
83
|
+
dayOfWeek: WEEKDAY_TO_NUMBER[weekday] ?? 0,
|
|
84
|
+
hour: parseInt(values.get("hour") || "0", 10),
|
|
85
|
+
minute: parseInt(values.get("minute") || "0", 10),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function toMinuteKey(parts) {
|
|
89
|
+
return `${parts.year}-${parts.month}-${parts.dayOfMonth}-${parts.hour}-${parts.minute}`;
|
|
90
|
+
}
|
|
91
|
+
function parseClockTimeToMinutes(value) {
|
|
92
|
+
const match = /^(\d{1,2}):(\d{2})$/.exec(value.trim());
|
|
93
|
+
if (!match)
|
|
94
|
+
return null;
|
|
95
|
+
const hours = parseInt(match[1], 10);
|
|
96
|
+
const minutes = parseInt(match[2], 10);
|
|
97
|
+
if (!Number.isFinite(hours) || !Number.isFinite(minutes))
|
|
98
|
+
return null;
|
|
99
|
+
if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59)
|
|
100
|
+
return null;
|
|
101
|
+
return hours * 60 + minutes;
|
|
102
|
+
}
|
|
103
|
+
export function parseDurationToMs(value) {
|
|
104
|
+
const match = /^(\d+)\s*(ms|s|m|h|d)$/.exec(value.trim().toLowerCase());
|
|
105
|
+
if (!match)
|
|
106
|
+
return 0;
|
|
107
|
+
const amount = parseInt(match[1], 10);
|
|
108
|
+
const unit = match[2];
|
|
109
|
+
if (unit === "ms")
|
|
110
|
+
return amount;
|
|
111
|
+
if (unit === "s")
|
|
112
|
+
return amount * 1000;
|
|
113
|
+
if (unit === "m")
|
|
114
|
+
return amount * 60 * 1000;
|
|
115
|
+
if (unit === "h")
|
|
116
|
+
return amount * 60 * 60 * 1000;
|
|
117
|
+
return amount * 24 * 60 * 60 * 1000;
|
|
118
|
+
}
|
|
119
|
+
export function isWithinQuietHours(quietHours, now) {
|
|
120
|
+
const startMinutes = parseClockTimeToMinutes(quietHours.start);
|
|
121
|
+
const endMinutes = parseClockTimeToMinutes(quietHours.end);
|
|
122
|
+
if (startMinutes === null || endMinutes === null)
|
|
123
|
+
return false;
|
|
124
|
+
if (startMinutes === endMinutes)
|
|
125
|
+
return false;
|
|
126
|
+
let zonedNow;
|
|
127
|
+
try {
|
|
128
|
+
zonedNow = getZonedDateParts(now, quietHours.timezone);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
zonedNow = getZonedDateParts(now, "UTC");
|
|
132
|
+
}
|
|
133
|
+
const nowMinutes = zonedNow.hour * 60 + zonedNow.minute;
|
|
134
|
+
if (startMinutes < endMinutes)
|
|
135
|
+
return nowMinutes >= startMinutes && nowMinutes < endMinutes;
|
|
136
|
+
return nowMinutes >= startMinutes || nowMinutes < endMinutes;
|
|
137
|
+
}
|
|
138
|
+
export function isMissionCronDueAt(params) {
|
|
139
|
+
const fields = params.cronExpression.trim().split(/\s+/).map((v) => v.trim());
|
|
140
|
+
if (fields.length !== 5)
|
|
141
|
+
return false;
|
|
142
|
+
const [minuteField, hourField, dayOfMonthField, monthField, dayOfWeekField] = fields;
|
|
143
|
+
let nowParts;
|
|
144
|
+
try {
|
|
145
|
+
nowParts = getZonedDateParts(params.now, params.timezone);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
nowParts = getZonedDateParts(params.now, "UTC");
|
|
149
|
+
}
|
|
150
|
+
if (params.lastTriggeredAt) {
|
|
151
|
+
let lastParts;
|
|
152
|
+
try {
|
|
153
|
+
lastParts = getZonedDateParts(params.lastTriggeredAt, params.timezone);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
lastParts = getZonedDateParts(params.lastTriggeredAt, "UTC");
|
|
157
|
+
}
|
|
158
|
+
if (toMinuteKey(lastParts) === toMinuteKey(nowParts))
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
if (!matchesCronField(minuteField, nowParts.minute, 0, 59))
|
|
162
|
+
return false;
|
|
163
|
+
if (!matchesCronField(hourField, nowParts.hour, 0, 23))
|
|
164
|
+
return false;
|
|
165
|
+
if (!matchesCronField(monthField, nowParts.month, 1, 12))
|
|
166
|
+
return false;
|
|
167
|
+
const dayOfMonthMatches = matchesCronField(dayOfMonthField, nowParts.dayOfMonth, 1, 31);
|
|
168
|
+
const dayOfWeekMatches = matchesCronField(dayOfWeekField, nowParts.dayOfWeek, 0, 6);
|
|
169
|
+
const dayOfMonthIsWildcard = dayOfMonthField === "*";
|
|
170
|
+
const dayOfWeekIsWildcard = dayOfWeekField === "*";
|
|
171
|
+
if (!dayOfMonthIsWildcard && !dayOfWeekIsWildcard)
|
|
172
|
+
return dayOfMonthMatches || dayOfWeekMatches;
|
|
173
|
+
return dayOfMonthMatches && dayOfWeekMatches;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=cron.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron.js","sourceRoot":"","sources":["../../src/mission/cron.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ClockPort, JobOpsPort, JobStore, MissionStore } from "../port.js";
|
|
2
|
+
import type { MissionSchedulerTickResult } from "../types.js";
|
|
3
|
+
export interface MissionSchedulerDeps {
|
|
4
|
+
missionStore: MissionStore;
|
|
5
|
+
jobStore: JobStore;
|
|
6
|
+
ops: JobOpsPort;
|
|
7
|
+
clock: ClockPort;
|
|
8
|
+
genMissionRunId: () => string;
|
|
9
|
+
}
|
|
10
|
+
export interface MissionScheduler {
|
|
11
|
+
processSchedulerTick(now?: Date): Promise<MissionSchedulerTickResult>;
|
|
12
|
+
}
|
|
13
|
+
export declare function createMissionScheduler(deps: MissionSchedulerDeps): MissionScheduler;
|
|
14
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/mission/scheduler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhF,OAAO,KAAK,EAAiB,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAW7E,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,EAAE,UAAU,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;IACjB,eAAe,EAAE,MAAM,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,oBAAoB,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;CACvE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CA0LnF"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// Mission scheduler — evaluates cron missions and spawns jobs when due. Ported from kader's
|
|
2
|
+
// processMissionSchedulerTick: the cron/quiet-hours/cooldown math is pure (./cron.js); every
|
|
3
|
+
// Mongo call becomes a MissionStore / JobStore port call. Quiet-hours, cooldown, and the
|
|
4
|
+
// overlap policy (skip | merge) are preserved exactly.
|
|
5
|
+
import { isMissionCronDueAt, isWithinQuietHours, parseDurationToMs } from "./cron.js";
|
|
6
|
+
const ACTIVE_JOB_STATUSES = [
|
|
7
|
+
"queued",
|
|
8
|
+
"running",
|
|
9
|
+
"waiting_time",
|
|
10
|
+
"waiting_event",
|
|
11
|
+
"awaiting_approval",
|
|
12
|
+
"paused",
|
|
13
|
+
];
|
|
14
|
+
export function createMissionScheduler(deps) {
|
|
15
|
+
const { missionStore, jobStore, ops, clock } = deps;
|
|
16
|
+
async function createSkippedRun(mission, now, skipReason, metadata) {
|
|
17
|
+
await missionStore.createMissionRun({
|
|
18
|
+
missionRunId: deps.genMissionRunId(),
|
|
19
|
+
missionId: mission.missionId,
|
|
20
|
+
tenantId: mission.tenantId,
|
|
21
|
+
triggerSource: "time",
|
|
22
|
+
status: "skipped",
|
|
23
|
+
spawnedJobId: null,
|
|
24
|
+
skipReason,
|
|
25
|
+
metadata: {
|
|
26
|
+
source: "mission_scheduler",
|
|
27
|
+
cronExpression: mission.trigger.cronExpression,
|
|
28
|
+
timezone: mission.trigger.timezone,
|
|
29
|
+
...(metadata || {}),
|
|
30
|
+
},
|
|
31
|
+
startedAt: now,
|
|
32
|
+
completedAt: now,
|
|
33
|
+
});
|
|
34
|
+
ops.record({
|
|
35
|
+
jobId: `mission:${mission.missionId}`,
|
|
36
|
+
tenantId: mission.tenantId,
|
|
37
|
+
missionId: mission.missionId,
|
|
38
|
+
source: "mission_scheduler",
|
|
39
|
+
eventType: "mission.scheduler.run.skipped",
|
|
40
|
+
status: "skipped",
|
|
41
|
+
employeeId: mission.employeeId,
|
|
42
|
+
metadata: { reason: skipReason, ...(metadata || {}) },
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async function processSchedulerTick(now = clock.now()) {
|
|
46
|
+
const missions = await missionStore.findSchedulableMissions();
|
|
47
|
+
const result = {
|
|
48
|
+
totalEnabled: missions.length,
|
|
49
|
+
cronEvaluated: 0,
|
|
50
|
+
triggered: 0,
|
|
51
|
+
skipped: 0,
|
|
52
|
+
merged: 0,
|
|
53
|
+
failed: 0,
|
|
54
|
+
};
|
|
55
|
+
for (const mission of missions) {
|
|
56
|
+
const cronExpression = mission.trigger?.cronExpression;
|
|
57
|
+
if (!cronExpression || typeof cronExpression !== "string")
|
|
58
|
+
continue;
|
|
59
|
+
result.cronEvaluated += 1;
|
|
60
|
+
const timezone = mission.trigger?.timezone || "UTC";
|
|
61
|
+
if (!isMissionCronDueAt({ cronExpression, timezone, now, lastTriggeredAt: mission.lastTriggeredAt })) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const quiet = mission.safety?.quietHours;
|
|
65
|
+
if (quiet && isWithinQuietHours({ start: quiet.start, end: quiet.end, timezone: quiet.timezone || timezone }, now)) {
|
|
66
|
+
await createSkippedRun(mission, now, "quiet_hours");
|
|
67
|
+
result.skipped += 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const cooldownMs = parseDurationToMs(mission.safety?.cooldownAfterComplete || "0m");
|
|
71
|
+
if (cooldownMs > 0 && mission.lastTriggeredAt &&
|
|
72
|
+
now.getTime() - new Date(mission.lastTriggeredAt).getTime() < cooldownMs) {
|
|
73
|
+
await createSkippedRun(mission, now, "cooldown_active");
|
|
74
|
+
result.skipped += 1;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const activeJobs = await jobStore.countActiveByMission(mission.tenantId, mission.missionId, ACTIVE_JOB_STATUSES);
|
|
78
|
+
const maxConcurrentJobs = Math.max(1, mission.safety?.maxConcurrentJobs || 1);
|
|
79
|
+
if (activeJobs >= maxConcurrentJobs) {
|
|
80
|
+
const overlapPolicy = mission.safety?.overlapPolicy === "merge" ? "merge" : "skip";
|
|
81
|
+
if (overlapPolicy === "merge") {
|
|
82
|
+
const anchor = await jobStore.findActiveMissionAnchor(mission.tenantId, mission.missionId, ACTIVE_JOB_STATUSES);
|
|
83
|
+
if (anchor) {
|
|
84
|
+
const existing = await missionStore.findMergedRun(mission.missionId, mission.tenantId, anchor.jobId);
|
|
85
|
+
if (!existing) {
|
|
86
|
+
await missionStore.createMissionRun({
|
|
87
|
+
missionRunId: deps.genMissionRunId(),
|
|
88
|
+
missionId: mission.missionId,
|
|
89
|
+
tenantId: mission.tenantId,
|
|
90
|
+
triggerSource: "time",
|
|
91
|
+
status: "skipped",
|
|
92
|
+
spawnedJobId: anchor.jobId,
|
|
93
|
+
skipReason: "merged_into_active_job",
|
|
94
|
+
metadata: { source: "mission_scheduler", mergedJobId: anchor.jobId, mergedJobStatus: anchor.status },
|
|
95
|
+
startedAt: now,
|
|
96
|
+
completedAt: now,
|
|
97
|
+
});
|
|
98
|
+
ops.record({
|
|
99
|
+
jobId: anchor.jobId,
|
|
100
|
+
tenantId: mission.tenantId,
|
|
101
|
+
missionId: mission.missionId,
|
|
102
|
+
source: "mission_scheduler",
|
|
103
|
+
eventType: "mission.scheduler.run.merged",
|
|
104
|
+
status: anchor.status,
|
|
105
|
+
queueName: "jobs",
|
|
106
|
+
employeeId: mission.employeeId,
|
|
107
|
+
correlationId: anchor.correlationId,
|
|
108
|
+
metadata: { mergedJobId: anchor.jobId, mergedReason: "max_concurrent_jobs_reached" },
|
|
109
|
+
});
|
|
110
|
+
result.merged += 1;
|
|
111
|
+
}
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
await createSkippedRun(mission, now, "max_concurrent_jobs_reached", { overlapPolicy });
|
|
116
|
+
result.skipped += 1;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const missionRunId = deps.genMissionRunId();
|
|
120
|
+
await missionStore.createMissionRun({
|
|
121
|
+
missionRunId,
|
|
122
|
+
missionId: mission.missionId,
|
|
123
|
+
tenantId: mission.tenantId,
|
|
124
|
+
triggerSource: "time",
|
|
125
|
+
status: "started",
|
|
126
|
+
spawnedJobId: null,
|
|
127
|
+
skipReason: null,
|
|
128
|
+
metadata: { source: "mission_scheduler", cronExpression, timezone },
|
|
129
|
+
startedAt: now,
|
|
130
|
+
completedAt: null,
|
|
131
|
+
});
|
|
132
|
+
try {
|
|
133
|
+
const job = await jobStore.createJob({
|
|
134
|
+
tenantId: mission.tenantId,
|
|
135
|
+
employeeId: mission.employeeId,
|
|
136
|
+
missionId: mission.missionId,
|
|
137
|
+
workflowType: mission.workflowType,
|
|
138
|
+
workflowVersion: mission.workflowVersion,
|
|
139
|
+
state: mission.defaultState,
|
|
140
|
+
...(mission.budget ? { budget: mission.budget } : {}),
|
|
141
|
+
});
|
|
142
|
+
await missionStore.updateMissionRun(missionRunId, {
|
|
143
|
+
status: "completed",
|
|
144
|
+
spawnedJobId: job.jobId,
|
|
145
|
+
completedAt: clock.now(),
|
|
146
|
+
});
|
|
147
|
+
await missionStore.markTriggered(mission.missionId, mission.tenantId, now);
|
|
148
|
+
ops.record({
|
|
149
|
+
jobId: job.jobId,
|
|
150
|
+
tenantId: mission.tenantId,
|
|
151
|
+
missionId: mission.missionId,
|
|
152
|
+
source: "mission_scheduler",
|
|
153
|
+
eventType: "mission.scheduler.run.completed",
|
|
154
|
+
status: "completed",
|
|
155
|
+
queueName: "jobs",
|
|
156
|
+
employeeId: mission.employeeId,
|
|
157
|
+
correlationId: job.correlationId,
|
|
158
|
+
metadata: { missionRunId, triggerSource: "time", cronExpression, timezone },
|
|
159
|
+
});
|
|
160
|
+
result.triggered += 1;
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
await missionStore.updateMissionRun(missionRunId, {
|
|
164
|
+
status: "failed",
|
|
165
|
+
skipReason: error.message,
|
|
166
|
+
completedAt: clock.now(),
|
|
167
|
+
});
|
|
168
|
+
ops.record({
|
|
169
|
+
jobId: `mission:${mission.missionId}`,
|
|
170
|
+
tenantId: mission.tenantId,
|
|
171
|
+
missionId: mission.missionId,
|
|
172
|
+
source: "mission_scheduler",
|
|
173
|
+
eventType: "mission.scheduler.run.failed",
|
|
174
|
+
status: "failed",
|
|
175
|
+
employeeId: mission.employeeId,
|
|
176
|
+
metadata: { error: error.message },
|
|
177
|
+
});
|
|
178
|
+
result.failed += 1;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
return { processSchedulerTick };
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/mission/scheduler.ts"],"names":[],"mappings":"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"}
|
package/dist/port.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CreateJobInput, JobOpsEventInput, JobSnapshot, JobStepRecord, WorkflowContext, WorkflowResolution } from "./types.js";
|
|
1
|
+
import type { ApprovalRecord, ApprovalStatus, CreateJobInput, JobOpsEventInput, JobSnapshot, JobStepRecord, MissionRecord, MissionRunRecord, WorkflowContext, WorkflowResolution } from "./types.js";
|
|
2
2
|
import type { JobStatus, JobStepTriggeredBy, JobStepType } from "./enums.js";
|
|
3
3
|
/** Thrown by `insertStep` when the unique idempotency key already exists. The adapter
|
|
4
4
|
* maps Mongo duplicate-key (code 11000) onto this; the engine never sees `11000`. */
|
|
@@ -46,6 +46,54 @@ export interface JobStore {
|
|
|
46
46
|
findStepByIdempotencyKey(jobId: string, tenantId: string, idempotencyKey: string): Promise<JobStepRecord | null>;
|
|
47
47
|
/** Reconciler scan: waiting_time jobs with a non-null resumeAt <= asOf, oldest first. */
|
|
48
48
|
findDueWaitingTime(asOf: Date, limit: number): Promise<JobSnapshot[]>;
|
|
49
|
+
/** Count this mission's jobs in the given (active) statuses — overlap policy (S2). */
|
|
50
|
+
countActiveByMission(tenantId: string, missionId: string, statuses: JobStatus[]): Promise<number>;
|
|
51
|
+
/** The oldest active job for a mission (the merge anchor) — overlap policy "merge" (S2). */
|
|
52
|
+
findActiveMissionAnchor(tenantId: string, missionId: string, statuses: JobStatus[]): Promise<JobSnapshot | null>;
|
|
53
|
+
}
|
|
54
|
+
/** Mission persistence (S2). The cron tick is pure; these are its store calls. */
|
|
55
|
+
export interface MissionStore {
|
|
56
|
+
/** Enabled, cron/hybrid-triggered missions. */
|
|
57
|
+
findSchedulableMissions(): Promise<MissionRecord[]>;
|
|
58
|
+
/** Stamp lastTriggeredAt after a successful spawn. */
|
|
59
|
+
markTriggered(missionId: string, tenantId: string, at: Date): Promise<void>;
|
|
60
|
+
createMissionRun(run: MissionRunRecord): Promise<void>;
|
|
61
|
+
updateMissionRun(missionRunId: string, patch: Partial<MissionRunRecord>): Promise<void>;
|
|
62
|
+
/** A prior "merged_into_active_job" run for this anchor (merge idempotency). */
|
|
63
|
+
findMergedRun(missionId: string, tenantId: string, mergedJobId: string): Promise<{
|
|
64
|
+
missionRunId: string;
|
|
65
|
+
} | null>;
|
|
66
|
+
}
|
|
67
|
+
/** HITL approval persistence (S2). */
|
|
68
|
+
export interface ApprovalStore {
|
|
69
|
+
create(input: {
|
|
70
|
+
approvalId: string;
|
|
71
|
+
tenantId: string;
|
|
72
|
+
employeeId: string;
|
|
73
|
+
jobId: string;
|
|
74
|
+
jobStepNumber: number;
|
|
75
|
+
jobVersion: number;
|
|
76
|
+
action: Record<string, unknown>;
|
|
77
|
+
reasoning: string;
|
|
78
|
+
expiresAt: Date;
|
|
79
|
+
}): Promise<ApprovalRecord>;
|
|
80
|
+
/** An existing pending approval for this job step (idempotent create). */
|
|
81
|
+
findPendingForStep(tenantId: string, jobId: string, stepNumber: number): Promise<ApprovalRecord | null>;
|
|
82
|
+
/** One-shot CAS resolve: filter on status:'pending', $set decision, $inc version. */
|
|
83
|
+
resolve(args: {
|
|
84
|
+
approvalId: string;
|
|
85
|
+
tenantId: string;
|
|
86
|
+
toStatus: ApprovalStatus;
|
|
87
|
+
decidedBy: string;
|
|
88
|
+
decidedAt: Date;
|
|
89
|
+
updatedParams?: Record<string, unknown> | null;
|
|
90
|
+
}): Promise<ApprovalRecord | null>;
|
|
91
|
+
getById(approvalId: string, tenantId: string): Promise<ApprovalRecord | null>;
|
|
92
|
+
listPending(tenantId: string, opts?: {
|
|
93
|
+
jobId?: string;
|
|
94
|
+
limit?: number;
|
|
95
|
+
}): Promise<ApprovalRecord[]>;
|
|
96
|
+
findExpired(asOf: Date, limit: number): Promise<ApprovalRecord[]>;
|
|
49
97
|
}
|
|
50
98
|
/** Enqueues an orchestrator tick (BullMQ behind this; jobId-based dedup via dedupeKey). */
|
|
51
99
|
export interface QueuePort {
|
package/dist/port.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,eAAe,EACf,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE7E;sFACsF;AACtF,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,SAAsD;CAI1E;AAED,MAAM,WAAW,QAAQ;IACvB,8DAA8D;IAC9D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAErE,gEAAgE;IAChE,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEvD;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,EAAE,SAAS,EAAE,CAAC;QACtB,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;KAC3B,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAEhC;;;;OAIG;IACH,YAAY,CAAC,IAAI,EAAE;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,MAAM,CAAC;QACxB,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtC,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAEhC,+EAA+E;IAC/E,UAAU,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE,yFAAyF;IACzF,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C,wBAAwB,CACtB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAEjC,yFAAyF;IACzF,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":"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"}
|
package/dist/port.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port.js","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,mFAAmF;AACnF,yDAAyD;AACzD,EAAE;AACF,oFAAoF;AACpF,gFAAgF;AAChF,mFAAmF;AACnF,uEAAuE;
|
|
1
|
+
{"version":3,"file":"port.js","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,mFAAmF;AACnF,yDAAyD;AACzD,EAAE;AACF,oFAAoF;AACpF,gFAAgF;AAChF,mFAAmF;AACnF,uEAAuE;AAgBvE;sFACsF;AACtF,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,OAAO,GAAG,mDAAmD;QACvE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { JobStatus, JobStepStatus, JobStepType, JobStepTriggeredBy } from "./enums.js";
|
|
1
|
+
import type { JobStatus, JobStepStatus, JobStepType, JobStepTriggeredBy, MissionRunStatus } from "./enums.js";
|
|
2
2
|
import type { JobApprovalPolicy, JobApprovalTimeoutOutcome } from "./approval/policy.js";
|
|
3
3
|
export interface JobBudget {
|
|
4
4
|
perStep: {
|
|
@@ -131,4 +131,68 @@ export interface WorkflowDefinition {
|
|
|
131
131
|
workflowVersion: string;
|
|
132
132
|
sequence: WorkflowSequenceStep[];
|
|
133
133
|
}
|
|
134
|
+
export interface MissionTrigger {
|
|
135
|
+
cronExpression: string | null;
|
|
136
|
+
timezone: string;
|
|
137
|
+
eventNames?: string[];
|
|
138
|
+
}
|
|
139
|
+
export interface MissionQuietHours {
|
|
140
|
+
start: string;
|
|
141
|
+
end: string;
|
|
142
|
+
timezone: string;
|
|
143
|
+
}
|
|
144
|
+
export interface MissionSafety {
|
|
145
|
+
overlapPolicy: "skip" | "merge";
|
|
146
|
+
maxConcurrentJobs: number;
|
|
147
|
+
cooldownAfterComplete: string;
|
|
148
|
+
quietHours: MissionQuietHours;
|
|
149
|
+
}
|
|
150
|
+
/** A schedulable mission (what MissionStore.findSchedulableMissions returns). */
|
|
151
|
+
export interface MissionRecord {
|
|
152
|
+
missionId: string;
|
|
153
|
+
tenantId: string;
|
|
154
|
+
employeeId: string;
|
|
155
|
+
workflowType: string;
|
|
156
|
+
workflowVersion: string;
|
|
157
|
+
defaultState: Record<string, unknown>;
|
|
158
|
+
trigger: MissionTrigger;
|
|
159
|
+
safety: MissionSafety;
|
|
160
|
+
budget?: Partial<JobBudget>;
|
|
161
|
+
lastTriggeredAt: Date | null;
|
|
162
|
+
}
|
|
163
|
+
export interface MissionRunRecord {
|
|
164
|
+
missionRunId: string;
|
|
165
|
+
missionId: string;
|
|
166
|
+
tenantId: string;
|
|
167
|
+
status: MissionRunStatus;
|
|
168
|
+
triggerSource: "time" | "event" | "manual";
|
|
169
|
+
spawnedJobId: string | null;
|
|
170
|
+
skipReason: string | null;
|
|
171
|
+
metadata?: Record<string, unknown>;
|
|
172
|
+
startedAt: Date;
|
|
173
|
+
completedAt: Date | null;
|
|
174
|
+
}
|
|
175
|
+
export interface MissionSchedulerTickResult {
|
|
176
|
+
totalEnabled: number;
|
|
177
|
+
cronEvaluated: number;
|
|
178
|
+
triggered: number;
|
|
179
|
+
skipped: number;
|
|
180
|
+
merged: number;
|
|
181
|
+
failed: number;
|
|
182
|
+
}
|
|
183
|
+
export type ApprovalStatus = "pending" | "approved" | "rejected" | "expired" | "cancelled";
|
|
184
|
+
export interface ApprovalRecord {
|
|
185
|
+
approvalId: string;
|
|
186
|
+
tenantId: string;
|
|
187
|
+
employeeId: string;
|
|
188
|
+
jobId: string | null;
|
|
189
|
+
jobStepNumber: number | null;
|
|
190
|
+
jobVersion: number | null;
|
|
191
|
+
status: ApprovalStatus;
|
|
192
|
+
version: number;
|
|
193
|
+
decidedBy: string | null;
|
|
194
|
+
decidedAt: Date | null;
|
|
195
|
+
expiresAt: Date | null;
|
|
196
|
+
action?: Record<string, unknown>;
|
|
197
|
+
}
|
|
134
198
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@msm-core/jobs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Durable job/mission orchestration engine (CAS + idempotency state machine, cron missions, HITL approval). Pure decision logic; storage, queue, lock, clock injected via ports (no mongoose/bullmq/ioredis dependency).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|