feat(ql3): establish 3.0 incubation baseline

This commit is contained in:
whyour
2026-08-12 00:25:26 +08:00
parent 4bf92dcfeb
commit c699c32461
2817 changed files with 779642 additions and 653 deletions
@@ -0,0 +1,102 @@
import {
RUN_CANCELLATION_SCHEMA,
InvalidRunCancellationError,
RunCancellationFenceRejectedError,
RunCancellationNotFoundError,
RunCancellationUnavailableError,
createRunCancellationResponseBody,
parseRunCancellationRequestBody,
type RunCancellationRepository,
} from '@qinglong/runtime-core/run-cancellation';
import type {
SecurityPolicyFence,
SecurityPrincipal,
} from '@qinglong/runtime-core/security';
import type { LocalApiResponse } from '../transport/contract';
export interface LocalApiRunCancellationRequest {
readonly projectId: string;
readonly runId: string;
readonly body: unknown | null;
readonly principal: Readonly<SecurityPrincipal>;
readonly policyFence: Readonly<SecurityPolicyFence> | null;
}
export interface LocalApiRunCancellationRoute {
handle(
request: Readonly<LocalApiRunCancellationRequest>,
): Promise<LocalApiResponse>;
}
export type LocalApiRunCancellationEventIdFactory = () => string;
function response(
statusCode: number,
body: Readonly<Record<string, unknown>>,
): LocalApiResponse {
return Object.freeze({ statusCode, body: Object.freeze(body) });
}
export function createLocalApiRunCancellationRoute(
repository: RunCancellationRepository,
createEventId: LocalApiRunCancellationEventIdFactory,
): Readonly<LocalApiRunCancellationRoute> {
if (
!repository ||
typeof repository.requestUserCancellation !== 'function' ||
typeof createEventId !== 'function'
) {
throw new TypeError('Local API Run cancellation route is invalid');
}
return Object.freeze({
async handle(request: Readonly<LocalApiRunCancellationRequest>) {
let body;
try {
body = parseRunCancellationRequestBody(request.body);
} catch (error) {
if (error instanceof InvalidRunCancellationError) {
return response(400, {
code: 'invalid_run_cancellation_request',
schema: RUN_CANCELLATION_SCHEMA,
});
}
return response(503, { code: 'run_cancellation_unavailable' });
}
if (!request.policyFence || request.policyFence.bindingVersion === null) {
return response(503, { code: 'run_cancellation_unavailable' });
}
try {
const result = await repository.requestUserCancellation({
projectId: request.projectId,
runId: request.runId,
mutationId: body.mutationId,
eventId: createEventId(),
subject: request.principal.subject,
policyFence: request.policyFence,
});
return response(
result.status === 'accepted' ? 202 : 200,
createRunCancellationResponseBody(result),
);
} catch (error) {
if (error instanceof RunCancellationNotFoundError) {
return response(404, { code: 'run_not_found' });
}
if (error instanceof RunCancellationFenceRejectedError) {
return response(409, {
code: 'run_cancellation_fence_rejected',
reason: error.reason,
});
}
if (
error instanceof InvalidRunCancellationError ||
error instanceof RunCancellationUnavailableError
) {
return response(503, { code: 'run_cancellation_unavailable' });
}
return response(503, { code: 'run_cancellation_unavailable' });
}
},
});
}
@@ -0,0 +1,65 @@
import {
BoundedRunEventListProjectionUnavailableError,
InvalidBoundedRunEventListProjectionError,
executeBoundedRunEventListProjection,
type BoundedRunEventListInput,
} from '@qinglong/runtime-core/bounded-run-event-list-projection';
import type { RunRepositoryReader } from '@qinglong/runtime-core/run-repository';
import type { LocalApiResponse } from '../transport/contract';
export interface LocalApiRunEventListRequest {
readonly projectId: string;
readonly runId: string;
readonly input: Readonly<BoundedRunEventListInput>;
}
export interface LocalApiRunEventListRoute {
handle(
request: Readonly<LocalApiRunEventListRequest>,
): Promise<LocalApiResponse>;
}
function response(
statusCode: number,
body: Readonly<Record<string, unknown>>,
): LocalApiResponse {
return Object.freeze({ statusCode, body: Object.freeze(body) });
}
export function createLocalApiRunEventListRoute(
runs: Pick<RunRepositoryReader, 'findRunById' | 'listEvents'>,
): Readonly<LocalApiRunEventListRoute> {
if (
!runs ||
typeof runs.findRunById !== 'function' ||
typeof runs.listEvents !== 'function'
) {
throw new TypeError('Local API Run event list repository is invalid');
}
return Object.freeze({
async handle(request: Readonly<LocalApiRunEventListRequest>) {
try {
const result = await executeBoundedRunEventListProjection(
runs,
request.projectId,
request.runId,
request.input,
);
if (!result.found) {
return response(404, { code: 'run_not_found' });
}
const { found: _found, ...timeline } = result;
return response(200, { ...timeline });
} catch (error) {
if (
error instanceof InvalidBoundedRunEventListProjectionError ||
error instanceof BoundedRunEventListProjectionUnavailableError
) {
return response(503, { code: 'run_event_list_unavailable' });
}
throw error;
}
},
});
}
@@ -0,0 +1,56 @@
import {
BoundedRunListProjectionUnavailableError,
InvalidBoundedRunListProjectionError,
executeBoundedRunListProjection,
type BoundedRunListInput,
} from '@qinglong/runtime-core/bounded-run-list-projection';
import type { ProjectRunListReader } from '@qinglong/runtime-core/project-run-list';
import type { LocalApiResponse } from '../transport/contract';
export interface LocalApiRunListRequest {
readonly projectId: string;
readonly input: Readonly<BoundedRunListInput>;
}
export interface LocalApiRunListRoute {
handle(request: Readonly<LocalApiRunListRequest>): Promise<LocalApiResponse>;
}
function unavailable(): LocalApiResponse {
return Object.freeze({
statusCode: 503,
body: Object.freeze({ code: 'run_list_unavailable' }),
});
}
export function createLocalApiRunListRoute(
runs: ProjectRunListReader,
): Readonly<LocalApiRunListRoute> {
if (!runs || typeof runs.listRunsByProject !== 'function') {
throw new TypeError('Local API Run list repository is invalid');
}
return Object.freeze({
async handle(request: Readonly<LocalApiRunListRequest>) {
try {
const result = await executeBoundedRunListProjection(
runs,
request.projectId,
request.input,
);
return Object.freeze({
statusCode: 200,
body: Object.freeze({ ...result }),
});
} catch (error) {
if (
error instanceof InvalidBoundedRunListProjectionError ||
error instanceof BoundedRunListProjectionUnavailableError
) {
return unavailable();
}
throw error;
}
},
});
}
@@ -0,0 +1,57 @@
import {
BoundedRunReadProjectionUnavailableError,
executeBoundedRunReadProjection,
} from '@qinglong/runtime-core/bounded-run-read-projection';
import type { RunRepositoryReader } from '@qinglong/runtime-core/run-repository';
import type { LocalApiResponse } from '../transport/contract';
export interface LocalApiRunReadRequest {
readonly projectId: string;
readonly runId: string;
}
export interface LocalApiRunReadRoute {
handle(request: Readonly<LocalApiRunReadRequest>): Promise<LocalApiResponse>;
}
function response(
statusCode: number,
body: Readonly<Record<string, unknown>>,
): LocalApiResponse {
return Object.freeze({ statusCode, body: Object.freeze(body) });
}
export function createLocalApiRunReadRoute(
runs: Pick<RunRepositoryReader, 'findRunById'>,
): Readonly<LocalApiRunReadRoute> {
if (!runs || typeof runs.findRunById !== 'function') {
throw new TypeError('Local API Run read repository is invalid');
}
return Object.freeze({
async handle(request: Readonly<LocalApiRunReadRequest>) {
try {
const projection = await executeBoundedRunReadProjection(
runs,
request.projectId,
request.runId,
);
if (projection.found !== true) {
return response(404, { code: 'run_not_found' });
}
const { found: _found, ...view } = projection;
return response(200, {
run: Object.freeze({ projectId: request.projectId, ...view }),
});
} catch (error) {
if (
error instanceof BoundedRunReadProjectionUnavailableError ||
error instanceof TypeError
) {
return response(503, { code: 'run_query_unavailable' });
}
return response(503, { code: 'run_query_unavailable' });
}
},
});
}
@@ -0,0 +1,69 @@
import {
BoundedRunStepListProjectionUnavailableError,
InvalidBoundedRunStepListProjectionError,
executeBoundedRunStepListProjection,
type BoundedRunStepListInput,
} from '@qinglong/runtime-core/bounded-run-step-list-projection';
import type { RunRepositoryReader } from '@qinglong/runtime-core/run-repository';
import type { StepRunRepository } from '@qinglong/runtime-core/step-run';
import type { LocalApiResponse } from '../transport/contract';
export interface LocalApiRunStepListRequest {
readonly projectId: string;
readonly runId: string;
readonly input: Readonly<BoundedRunStepListInput>;
}
export interface LocalApiRunStepListRoute {
handle(
request: Readonly<LocalApiRunStepListRequest>,
): Promise<LocalApiResponse>;
}
function response(
statusCode: number,
body: Readonly<Record<string, unknown>>,
): LocalApiResponse {
return Object.freeze({ statusCode, body: Object.freeze(body) });
}
export function createLocalApiRunStepListRoute(
runs: Pick<RunRepositoryReader, 'findRunById'>,
stepRuns: Pick<StepRunRepository, 'listByRun'>,
): Readonly<LocalApiRunStepListRoute> {
if (
!runs ||
typeof runs.findRunById !== 'function' ||
!stepRuns ||
typeof stepRuns.listByRun !== 'function'
) {
throw new TypeError('Local API Run Step list repository is invalid');
}
return Object.freeze({
async handle(request: Readonly<LocalApiRunStepListRequest>) {
try {
const result = await executeBoundedRunStepListProjection(
runs,
stepRuns,
request.projectId,
request.runId,
request.input,
);
if (!result.found) {
return response(404, { code: 'run_not_found' });
}
const { found: _found, ...page } = result;
return response(200, { ...page });
} catch (error) {
if (
error instanceof InvalidBoundedRunStepListProjectionError ||
error instanceof BoundedRunStepListProjectionUnavailableError
) {
return response(503, { code: 'run_step_list_unavailable' });
}
throw error;
}
},
});
}