fix(ql3): keep console task authority lazy

This commit is contained in:
whyour
2026-08-29 10:41:36 +08:00
parent 884912d1c8
commit dc1686bd6f
6 changed files with 29 additions and 22 deletions
@@ -76,7 +76,7 @@ export interface LocalApiTaskPutRouteOptions {
readonly taskDefinitions: TaskDefinitionSource;
readonly taskDefinitionAdministrationForCredential: (
fence: Readonly<AuthenticatedLocalApiRequest['credentialFence']>,
) => TaskDefinitionAdministrationRepository;
) => Promise<TaskDefinitionAdministrationRepository>;
readonly securityAudit: SecurityAuditSink;
readonly presenceProof: LocalPresenceProofManager;
readonly now?: () => number;
@@ -406,11 +406,13 @@ export function createLocalApiTaskPutRoute(
return response(503, { code: 'authentication_unavailable' });
}
try {
const mutations =
await options.taskDefinitionAdministrationForCredential(
request.authenticated.credentialFence,
);
const service = createLocalTaskDefinitionAdministrationService(
options.projectPolicy,
options.taskDefinitionAdministrationForCredential(
request.authenticated.credentialFence,
),
mutations,
options.taskDefinitions,
options.securityAudit,
{ now },
@@ -123,7 +123,7 @@ function fixture(t, overrides = {}) {
const route = createLocalApiTaskPutRoute({
projectPolicy,
taskDefinitions,
taskDefinitionAdministrationForCredential(fence) {
async taskDefinitionAdministrationForCredential(fence) {
calls.push(['credential-fence', fence]);
return {
async appendAuthorizedTaskDefinitionRevision(mutation) {
@@ -51,12 +51,7 @@ import { LocalSqliteApiCredentialRepository } from '../security/apiCredentialRep
import { LocalSqliteOwnerPepperRepository } from '../local-owner/ownerPepperRepository';
import { LocalSqliteOperationAuthority } from '../authority/operationAuthority';
import { LocalSqliteTaskDefinitionRepository } from '../task-definition/taskDefinitionRepository';
import { LocalSqliteTaskDefinitionAdministrationRepository } from '../task-definition/taskDefinitionAdministration';
import {
confirmLocalSqliteAuthenticatedUserCredentialFence,
LocalSqliteAuthenticatedManagementFenceError,
type LocalSqliteAuthenticatedUserCredentialFence,
} from '../administration/packageManagement';
import type { LocalSqliteAuthenticatedUserCredentialFence } from '../administration/packageManagement';
import {
TaskSpecSemanticRegistry,
createBuiltInTaskSpecSemanticRegistry,
@@ -105,7 +100,7 @@ export interface LocalSqliteRuntimeDatabase {
readonly taskDefinitions: LocalSqliteTaskDefinitionRepository;
taskDefinitionAdministrationForCredential(
fence: Readonly<LocalSqliteAuthenticatedUserCredentialFence>,
): TaskDefinitionAdministrationRepository;
): Promise<TaskDefinitionAdministrationRepository>;
readonly triggers: LocalSqliteTriggerRepository;
readonly schedules: LocalSqliteScheduleRepository;
readonly localDispatch: LocalDispatchStore;
@@ -257,9 +252,19 @@ export async function openLocalSqliteRuntimeDatabase(
readiness,
runRepository,
taskDefinitions,
taskDefinitionAdministrationForCredential(
async taskDefinitionAdministrationForCredential(
fence: Readonly<LocalSqliteAuthenticatedUserCredentialFence>,
) {
const [administration, taskAdministration] = await Promise.all([
import('../administration/packageManagement.js'),
import('../task-definition/taskDefinitionAdministration.js'),
]);
const {
confirmLocalSqliteAuthenticatedUserCredentialFence,
LocalSqliteAuthenticatedManagementFenceError,
} = administration;
const { LocalSqliteTaskDefinitionAdministrationRepository } =
taskAdministration;
confirmLocalSqliteAuthenticatedUserCredentialFence(authority, fence);
return new LocalSqliteTaskDefinitionAdministrationRepository(
authority,
@@ -171,12 +171,10 @@ async function fixture(t) {
test('keeps simultaneous Task mutation credentials request-scoped and rechecks both fences in-transaction', async (t) => {
const value = await fixture(t);
const repositoryA = value.runtime.taskDefinitionAdministrationForCredential(
value.fenceA,
);
const repositoryB = value.runtime.taskDefinitionAdministrationForCredential(
value.fenceB,
);
const repositoryA =
await value.runtime.taskDefinitionAdministrationForCredential(value.fenceA);
const repositoryB =
await value.runtime.taskDefinitionAdministrationForCredential(value.fenceB);
const policyA = await value.runtime.projectPolicy.resolve('default', {
type: 'user',
id: 'request-user-a',