콘텐츠로 이동

@gj-kit/nest-operations-jobs 레시피

각 코드 블록은 패키지 README에서 이미 타입 검사하는 public-contract 예제를 재사용합니다.

trigger route를 노출하기 전에 run store와 명시적인 authentication을 제공합니다.

완료 상태: 앱 소유 실행 저장소로 뒷받침되는 인증된 운영 작업 경계를 만듭니다.

앱 소유 경계: JobRunStore를 구현한 뒤 module을 등록하기 전에 32자 이상의 shared secret 또는 token verifier를 설정합니다.

import { OperationsJobsModule, type JobRunStore } from '@gj-kit/nest-operations-jobs';
declare const store: JobRunStore; // Your database-backed run store.
declare const secret: string; // At least 32 characters; keep it outside source control.
export const operations = OperationsJobsModule.forRoot({
store,
auth: { secret },
trigger: { path: 'internal/jobs' },
});

2. 실제 상태에 따라 job result 읽기

섹션 제목: “2. 실제 상태에 따라 job result 읽기”

분기 전용 error, reason, recording field에 접근하기 전에 status로 분기합니다.

status로 좁히기 전에는 error에 접근할 수 없고, recorded는 모든 분기에 있습니다. 저장된 행이 반환된 status와 어긋나는 상황이야말로 알림을 걸 지점이기 때문입니다.

import type { JobExecutionResult } from '@gj-kit/nest-operations-jobs/core';
declare const result: JobExecutionResult; // await runner.execute(...)
declare function pageOncall(jobKey: string, runId: string): void; // the app owns this
export function report(): void {
// console.error(result.error.code);
// -> error TS2339: Property 'error' does not exist on type 'JobExecutionResult'.
if (result.status === 'TIMED_OUT') {
console.error(result.jobKey, result.error.code); // 'ERR_JOB_TIMEOUT'
} else if (result.status === 'SKIPPED') {
console.warn(result.jobKey, result.reason); // 'overlap' - the only value
}
// `recorded` sits on every branch: 'superseded' means a reaper already
// finalised the row, so a second body may run under a different runId.
if (result.recorded === 'superseded') pageOncall(result.jobKey, result.runId);
}

전체 API reference에서 모든 export와 import path를 확인하세요.