Files
EpicNext-Cms/src/features/housekeeping/foundation/contracts/result.ts
T

71 lines
1.5 KiB
TypeScript

import { createCorrelationId } from "../correlation";
export type HousekeepingErrorCode =
| "UNAUTHENTICATED"
| "FORBIDDEN"
| "VALIDATION"
| "NOT_FOUND"
| "CONFLICT"
| "RATE_LIMITED"
| "DEPENDENCY_UNAVAILABLE"
| "TIMEOUT"
| "INTERNAL";
export interface HousekeepingError {
code: HousekeepingErrorCode;
messageKey: string;
fieldErrors?: Readonly<Record<string, readonly string[]>>;
}
export interface HousekeepingPartialCompletion {
readonly status: "partial";
readonly external: "not-required" | "completed" | "failed";
readonly audit: "persisted" | "unavailable";
}
export type HousekeepingResult<T> =
| {
ok: true;
data: T;
correlationId: string;
completion?: HousekeepingPartialCompletion;
}
| { ok: false; error: HousekeepingError; correlationId: string };
export function ok<T>(
data: T,
correlationId: string,
completion?: HousekeepingPartialCompletion,
): HousekeepingResult<T> {
return {
ok: true,
data,
correlationId,
...(completion === undefined ? {} : { completion }),
};
}
export function fail(
code: HousekeepingErrorCode,
messageKey: string,
correlationId: string,
fieldErrors?: Readonly<Record<string, readonly string[]>>,
): HousekeepingResult<never> {
return {
ok: false,
error: {
code,
messageKey,
...(fieldErrors === undefined ? {} : { fieldErrors }),
},
correlationId,
};
}
export function mapUnknownError(
_error: unknown,
correlationId = createCorrelationId(),
): HousekeepingResult<never> {
return fail("INTERNAL", "errors.housekeeping.internal", correlationId);
}