@codemem/server 0.47.2 → 0.47.3
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/index.js +181 -72
- package/dist/index.js.map +1 -1
- package/dist/routes/team-setup-view.d.ts +1 -0
- package/dist/routes/team-setup-view.d.ts.map +1 -1
- package/dist/routes/team-setup.d.ts.map +1 -1
- package/package.json +2 -2
- package/static/app.js +25 -25
- package/static/app.js.br +0 -0
- package/static/app.js.gz +0 -0
- package/static/index.html +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { closeSync, existsSync, fstatSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
|
|
3
|
-
import { ACCESS_CLEANUP_OP_TYPE, CodememConfigMutationError, CoordinatorAccountLinkError, CoordinatorReciprocalApprovalRequestChangedError, DEFAULT_TIME_WINDOW_S, FILE_CONTEXT_TRANSPORT_MAX_BYTES, LEGACY_SHARED_REVIEW_SCOPE_ID, LOCAL_DEFAULT_SCOPE_ID, LOCAL_SYNC_CAPABILITY, LOCAL_SYNC_FEATURES, LegacyTeamSetupAdditiveConvergenceError, LegacyTeamSetupRosterCapacityError, MEMORY_FILTER_FIELD_TYPES, MEMORY_FILTER_NAMES, MEMORY_KIND_DESCRIPTIONS, MemoryStore, ObserverClient, PROMPT_TRANSPORT_PROTOCOL_RANGE, REMEMBER_MEMORY_KINDS, RICH_TIER_ANTHROPIC_DEFAULTS, RICH_TIER_DEFAULTS, RawEventIngestValidationError, RecipientPolicyEdgeRequestError, RecipientPolicyTeamRenameError, RemoteCoordinatorRequestError, SCOPE_MEMBERSHIP_REVOCATION_LIMITATION, SIMPLE_TIER_ANTHROPIC_DEFAULTS, SIMPLE_TIER_DEFAULTS, SYNC_AUTHORIZATION_REFRESH_HEADER, SYNC_CAPABILITY_HEADER, SYNC_FEATURES_HEADER, SYNC_SCOPE_QUERY_PARAM, VERSION, VERSION as VERSION$1, VIEWER_IDENTITY_TARGET_KEYS, VIEWER_SERVICE_DISCRIMINATOR, addSyncScopeToBoundary, analyzeProjectScopeMappingChangeGuardrails, analyzeProjectScopeMappingChangesGuardrails, analyzeProjectScopeMappingDeletionGuardrails, applyLegacyTeamSetupCompletionManifest, applyLegacyTeamSetupCompletionManifestAndReturnActivation, applyLocalIdentitySwitch, applyReplicationOps, areLegacyTeamSetupCompletionPolicyFactsAdditivelyCompatible, assertNoLocalIdentityOverride, automaticRecallHealth, buildAuthHeaders, buildBaseUrl, buildDirectPeerAuthHeaders, buildDistillReport, buildFilterBranchesWithContext, buildFilterClausesWithContext, buildPiFlushSignalFromEvent, buildRawEventEnvelopeFromCodexHook, buildRawEventEnvelopeFromHook, buildRawEventEnvelopeFromPiEvent, buildViewerIdentityTarget, canonicalCoordinatorLegacyTeamCompletionManifestJson, canonicalMemoryKind, canonicalRepositoryProjectIdentity, canonicalWorkspaceIdentity, captureAccountOwnerProfilePins, changeCoordinatorAccount, claimRecipientPolicyActorMutations, claimRecipientPolicyPublicationMutation, classifyRecordedSyncFailure, cleanupNonces, clearLegacyTeamSetupDeviceDecision, clonePromptPackAttempt, coerceObserverCommand, commitDeviceIdentityBindings, commitRecipientPolicyEdges, completeLocalIdentitySwitch, containLegacyTeamSetupCompletionConflict, coordinatorArchiveGroupAction, coordinatorAuthControllerReviewAction, coordinatorCreateAddDeviceInviteAction, coordinatorCreateGroupAction, coordinatorCreateInviteAction, coordinatorCreateLegacyTeamCompletionAction, coordinatorCreateScopeAction, coordinatorDisableDeviceAction, coordinatorEnableDeviceAction, coordinatorGetLegacyTeamCompletionAction, coordinatorGrantScopeMembershipAction, coordinatorImportInviteAction, coordinatorListBootstrapGrantsAction, coordinatorListConsumedTeamInvitesAction, coordinatorListDevicesAction, coordinatorListGroupsAction, coordinatorListJoinRequestsAction, coordinatorListLegacyTeamCompletionsAction, coordinatorListReviewedRecipientInviteEvidenceAction, coordinatorListScopeMembershipsAction, coordinatorListScopesAction, coordinatorRemoveDeviceAction, coordinatorRenameDeviceAction, coordinatorRenameGroupAction, coordinatorReviewJoinRequestAction, coordinatorRevokeBootstrapGrantAction, coordinatorRevokeScopeMembershipAction, coordinatorStatusSnapshot, coordinatorUnarchiveGroupAction, coordinatorUpdateScopeAction, countShareableProjectMemories, createCoordinatorReciprocalApproval, decodeInvitePayload, dedupeOrderedIds, defaultSpaceScopeIdForGroup, deleteProjectScopeSettingsMapping, deriveLegacyTeamSetupCompletionManifest, detectInstallKind, deterministicPolicyTeamId, diagnoseStalePeerReceivedRows, discoverLegacyTeamCandidates, dispatchFileContextTransport, ensureDeviceIdentity, executeShareProvisioning, extractInvitePayload, extractReplicationOps, filterReplicationOpsForSyncWithStatus, fingerprintPublicKey, formatHostPort, friendlyDeviceName, fromJson, generateWithOpenCodeV2, getCodememConfigPath, getCodememEnvOverrideValues, getCodememEnvOverrides, getCoordinatorEnrollmentReconciliationIssueSummary, getCoordinatorGroupPreference, getEffectiveCachedScopeAuthorization, getLegacyTeamSetupDraft, getRecipientPolicyAuthorityState, getSemanticIndexDiagnostics, getSyncResetState, getUpdateStatus, ingestRawEvents, inspectFreshLegacyTeamSetupActivation, inspectLegacyTeamSetupActivation, inviteTokenDigest, isAutomaticRecallMeasurement, isLegacyTeamCandidateSelectable, isLegacyTeamSetupProjectMappingIdentity, isPeerTrustBindingCompatible, isProjectSyncEnablementError, isScopedSyncCapability, judgeDistillReport, legacyDecisionCountsAsOwner, legacyTeamCandidateId, legacyTeamCandidateProjectInventory, legacyTeamCanonicalProjectRef, legacyTeamDeviceRef, legacyTeamResolvedProjectRef, legacyTeamSetupApiErrorCode, linkCoordinatorAccount, listAuthorizedScopesForPeer, listCoordinatorJoinRequests, listDeviceIdentityInventory, listInboundScopeRejections, listLegacyRecipientPolicyProjections, listMaintenanceJobs, listObserverProviderOptions, listOpenCodeV2Models, listPerPeerScopeSyncState, listProjectScopeCandidates, listProjectScopeInventory, listProjectScopeSettingsMappings, listRecipientPolicyIntent, listRecipientPolicyReview, listSharingDomainSettingsScopes, loadMemorySnapshotPageForPeer, loadPublicKey, loadReplicationOpsForPeer, loadRuntimeSigningPublicKey, lookupCoordinatorPeers, markLocalIdentitySwitchBound, markLocalIdentitySwitchNotCommitted, memoryFilterValueMatchesType, mergeAddresses, migrateRecipientPolicyIntent, mutateCodememConfigFile, negotiateSyncCapability, normalizeAddress, normalizeCoordinatorAccountLinkOrigin, normalizeCoordinatorLegacyTeamCompletionManifest, normalizeHumanPresentationName, normalizeSyncCapability, normalizeSyncFeatures, normalizeTeammateName, parseAcceptedProjectIntent, parseBootstrapExpiry, parseFileContextTransportRequest, parsePositiveMemoryId, parseReassignScopePayload, parseRecipientPolicyEdgeCommitRequest, parseStrictInteger, parseSyncScopeRequest, persistShareOperation, personalScopeGrantStatusForPeer, planShareOperation, previewDeviceIdentityBindings, previewLegacyTeamSetupActivation, previewRecipientPolicyEdges, previewRecipientPolicyOnboarding, previewRecipientPolicyOnboardingFromReviewedIntent, probeAvailableCredentials, projectMatchesFilter, projectShareLifecycle, promptPackArtifactFingerprint, readAccountLinkDevice, readAccountOwnerAssociation, readAccountOwnerAssociationRetainedAtMs, readCodememConfigFile, readCompletedLocalIdentitySwitches, readCoordinatorAccountChangeCapabilities, readCoordinatorAccountLinkStatus, readCoordinatorResolvedAccountOwnerReceiptStatus, readCoordinatorResolvedAccountOwnerStatus, readCoordinatorSyncConfig, readOpenLocalIdentitySwitch, reassignProjectScopeInventoryProject, recipientInviteAuthoritativeIdentityId, recipientPolicyDigest, recipientReviewedIntentDigest, reconcileCoordinatorEnrollmentSnapshot, reconcileRecipientPolicyProject, reconcileShareOperationAcceptance, reconstructLegacyTeamSetupCompletionManifest, recordAutomaticRecall, recordHighestObservedDirectSignatureVersion, recordLocalIdentitySwitch, recordNonce, recordPromptPackArtifacts, recordPromptPackTerminal, refreshAuthorizedCoordinatorPeerTrust, refreshConfiguredScopeMembershipCache, refreshLegacyTeamCandidate, rejectInboundScopeFailures, renameRecipientPolicyTeam, replayLegacyTeamSetupActivation, repositoryIdentitiesByWorkspace, repositoryIdentityForWorkspace, requestJson, requireLegacyTeamSetupAccessDeltaWithinLimit, resolveCodememConfigPath, resolveDbPath, resolveObserverDefaultModel, resolveObserverRuntime, resolveProject, resolveProjectRoot, resolveRecipientPolicyReview, resolveRecipientPolicyReviewBulk, resolveVisibleScopeIds, resumeDeviceRebind, runDeviceRebind, runSyncPass, schema, scopeAuthorizationFailureReason, searchPiSessions, serializeRecipientPolicyCoordinatorGroupMutation, serializeRecipientPolicyPublicationMutation, serializeRecipientPolicyTeamMutation, setLegacyTeamSetupDeviceAssignment, setLegacyTeamSetupDeviceDecision, setLegacyTeamSetupProjectMapping, summarizeInboundScopeRejections, summaryLikeSqlPredicate, supportsSyncFeature, syncScopeResetRequiredPayload, toJson, tryUpdateRetrievalDelivery, updatePeerAddresses, upsertCoordinatorGroupPreference, upsertProjectScopeSettingsMappings, validateLegacyTeamSetupCompletionManifest, validateLegacyTeamSetupCompletionManifestBinding, validateRawEvents, verifyDirectPeerSignature, verifyRecipientReviewedIntent, verifySignature, wakeRecipientPoliciesForIdentities, wakeRecipientPoliciesForProjectIdentities } from "@codemem/core";
|
|
3
|
+
import { ACCESS_CLEANUP_OP_TYPE, CodememConfigMutationError, CoordinatorAccountLinkError, CoordinatorReciprocalApprovalRequestChangedError, DEFAULT_TIME_WINDOW_S, FILE_CONTEXT_TRANSPORT_MAX_BYTES, LEGACY_SHARED_REVIEW_SCOPE_ID, LOCAL_DEFAULT_SCOPE_ID, LOCAL_SYNC_CAPABILITY, LOCAL_SYNC_FEATURES, LegacyTeamSetupAdditiveConvergenceError, LegacyTeamSetupRosterCapacityError, MEMORY_FILTER_FIELD_TYPES, MEMORY_FILTER_NAMES, MEMORY_KIND_DESCRIPTIONS, MemoryStore, ObserverClient, PROMPT_TRANSPORT_PROTOCOL_RANGE, REMEMBER_MEMORY_KINDS, RICH_TIER_ANTHROPIC_DEFAULTS, RICH_TIER_DEFAULTS, RawEventIngestValidationError, RecipientPolicyEdgeRequestError, RecipientPolicyTeamRenameError, RemoteCoordinatorRequestError, SCOPE_MEMBERSHIP_REVOCATION_LIMITATION, SIMPLE_TIER_ANTHROPIC_DEFAULTS, SIMPLE_TIER_DEFAULTS, SYNC_AUTHORIZATION_REFRESH_HEADER, SYNC_CAPABILITY_HEADER, SYNC_FEATURES_HEADER, SYNC_SCOPE_QUERY_PARAM, VERSION, VERSION as VERSION$1, VIEWER_IDENTITY_TARGET_KEYS, VIEWER_SERVICE_DISCRIMINATOR, addSyncScopeToBoundary, analyzeProjectScopeMappingChangeGuardrails, analyzeProjectScopeMappingChangesGuardrails, analyzeProjectScopeMappingDeletionGuardrails, applyLegacyTeamSetupCompletionManifest, applyLegacyTeamSetupCompletionManifestAndReturnActivation, applyLocalIdentitySwitch, applyReplicationOps, areLegacyTeamSetupCompletionPolicyFactsAdditivelyCompatible, assertNoLocalIdentityOverride, automaticRecallHealth, buildAuthHeaders, buildBaseUrl, buildDirectPeerAuthHeaders, buildDistillReport, buildFilterBranchesWithContext, buildFilterClausesWithContext, buildPiFlushSignalFromEvent, buildRawEventEnvelopeFromCodexHook, buildRawEventEnvelopeFromHook, buildRawEventEnvelopeFromPiEvent, buildViewerIdentityTarget, canonicalCoordinatorLegacyTeamCompletionManifestJson, canonicalMemoryKind, canonicalRepositoryProjectIdentity, canonicalWorkspaceIdentity, captureAccountOwnerProfilePins, changeCoordinatorAccount, claimRecipientPolicyActorMutations, claimRecipientPolicyPublicationMutation, classifyRecordedSyncFailure, cleanupNonces, clearLegacyTeamSetupDeviceDecision, clonePromptPackAttempt, coerceObserverCommand, commitDeviceIdentityBindings, commitRecipientPolicyEdges, completeLocalIdentitySwitch, containLegacyTeamSetupCompletionConflict, coordinatorArchiveGroupAction, coordinatorAuthControllerReviewAction, coordinatorCreateAddDeviceInviteAction, coordinatorCreateGroupAction, coordinatorCreateInviteAction, coordinatorCreateLegacyTeamCompletionAction, coordinatorCreateScopeAction, coordinatorDisableDeviceAction, coordinatorEnableDeviceAction, coordinatorGetLegacyTeamCompletionAction, coordinatorGrantScopeMembershipAction, coordinatorImportInviteAction, coordinatorListBootstrapGrantsAction, coordinatorListConsumedTeamInvitesAction, coordinatorListDevicesAction, coordinatorListGroupsAction, coordinatorListJoinRequestsAction, coordinatorListLegacyTeamCompletionsAction, coordinatorListReviewedRecipientInviteEvidenceAction, coordinatorListScopeMembershipsAction, coordinatorListScopesAction, coordinatorRemoveDeviceAction, coordinatorRenameDeviceAction, coordinatorRenameGroupAction, coordinatorReviewJoinRequestAction, coordinatorRevokeBootstrapGrantAction, coordinatorRevokeScopeMembershipAction, coordinatorStatusSnapshot, coordinatorUnarchiveGroupAction, coordinatorUpdateScopeAction, countShareableProjectMemories, createCoordinatorReciprocalApproval, decodeInvitePayload, dedupeOrderedIds, defaultSpaceScopeIdForGroup, deleteProjectScopeSettingsMapping, deriveLegacyTeamSetupCompletionManifest, detectInstallKind, deterministicPolicyTeamId, diagnoseStalePeerReceivedRows, discoverLegacyTeamCandidates, dispatchFileContextTransport, ensureDeviceIdentity, executeShareProvisioning, extractInvitePayload, extractReplicationOps, filterReplicationOpsForSyncWithStatus, fingerprintPublicKey, formatHostPort, friendlyDeviceName, fromJson, generateWithOpenCodeV2, getCodememConfigPath, getCodememEnvOverrideValues, getCodememEnvOverrides, getCoordinatorEnrollmentReconciliationIssueSummary, getCoordinatorGroupPreference, getEffectiveCachedScopeAuthorization, getLegacyTeamSetupDraft, getRecipientPolicyAuthorityState, getSemanticIndexDiagnostics, getSyncResetState, getUpdateStatus, ingestRawEvents, inspectFreshLegacyTeamSetupActivation, inspectLegacyTeamSetupActivation, inviteTokenDigest, isAutomaticRecallMeasurement, isLegacyTeamCandidateSelectable, isLegacyTeamSetupProjectMappingIdentity, isPeerTrustBindingCompatible, isProjectSyncEnablementError, isScopedSyncCapability, judgeDistillReport, legacyDecisionCountsAsOwner, legacyTeamCandidateId, legacyTeamCandidateProjectInventory, legacyTeamCanonicalProjectRef, legacyTeamDeviceRef, legacyTeamResolvedProjectRef, legacyTeamSetupApiErrorCode, legacyTeamSetupCompletionActorIds, legacyTeamSetupFailureCheck, linkCoordinatorAccount, listAuthorizedScopesForPeer, listCoordinatorJoinRequests, listDeviceIdentityInventory, listInboundScopeRejections, listLegacyRecipientPolicyProjections, listMaintenanceJobs, listObserverProviderOptions, listOpenCodeV2Models, listPerPeerScopeSyncState, listProjectScopeCandidates, listProjectScopeInventory, listProjectScopeSettingsMappings, listRecipientPolicyIntent, listRecipientPolicyReview, listSharingDomainSettingsScopes, loadMemorySnapshotPageForPeer, loadPublicKey, loadReplicationOpsForPeer, loadRuntimeSigningPublicKey, lookupCoordinatorPeers, markLocalIdentitySwitchBound, markLocalIdentitySwitchNotCommitted, memoryFilterValueMatchesType, mergeAddresses, migrateRecipientPolicyIntent, mutateCodememConfigFile, negotiateSyncCapability, normalizeAddress, normalizeCoordinatorAccountLinkOrigin, normalizeCoordinatorLegacyTeamCompletionManifest, normalizeHumanPresentationName, normalizeSyncCapability, normalizeSyncFeatures, normalizeTeammateName, parseAcceptedProjectIntent, parseBootstrapExpiry, parseFileContextTransportRequest, parsePositiveMemoryId, parseReassignScopePayload, parseRecipientPolicyEdgeCommitRequest, parseStrictInteger, parseSyncScopeRequest, persistShareOperation, personalScopeGrantStatusForPeer, planShareOperation, previewDeviceIdentityBindings, previewLegacyTeamSetupActivation, previewRecipientPolicyEdges, previewRecipientPolicyOnboarding, previewRecipientPolicyOnboardingFromReviewedIntent, probeAvailableCredentials, projectMatchesFilter, projectShareLifecycle, promptPackArtifactFingerprint, readAccountLinkDevice, readAccountOwnerAssociation, readAccountOwnerAssociationRetainedAtMs, readCodememConfigFile, readCompletedLocalIdentitySwitches, readCoordinatorAccountChangeCapabilities, readCoordinatorAccountLinkStatus, readCoordinatorResolvedAccountOwnerReceiptStatus, readCoordinatorResolvedAccountOwnerStatus, readCoordinatorSyncConfig, readOpenLocalIdentitySwitch, reassignProjectScopeInventoryProject, recipientInviteAuthoritativeIdentityId, recipientPolicyDigest, recipientReviewedIntentDigest, reconcileCoordinatorEnrollmentSnapshot, reconcileRecipientPolicyProject, reconcileShareOperationAcceptance, reconstructLegacyTeamSetupCompletionManifest, recordAutomaticRecall, recordHighestObservedDirectSignatureVersion, recordLocalIdentitySwitch, recordNonce, recordPromptPackArtifacts, recordPromptPackTerminal, refreshAuthorizedCoordinatorPeerTrust, refreshConfiguredScopeMembershipCache, refreshLegacyTeamCandidate, rejectInboundScopeFailures, renameRecipientPolicyTeam, replayLegacyTeamSetupActivation, repositoryIdentitiesByWorkspace, repositoryIdentityForWorkspace, requestJson, requireLegacyTeamSetupAccessDeltaWithinLimit, resolveCodememConfigPath, resolveDbPath, resolveObserverDefaultModel, resolveObserverRuntime, resolveProject, resolveProjectRoot, resolveRecipientPolicyReview, resolveRecipientPolicyReviewBulk, resolveVisibleScopeIds, resumeDeviceRebind, runDeviceRebind, runSyncPass, schema, scopeAuthorizationFailureReason, searchPiSessions, serializeRecipientPolicyActorMutations, serializeRecipientPolicyCoordinatorGroupMutation, serializeRecipientPolicyPublicationMutation, serializeRecipientPolicyTeamMutation, setLegacyTeamSetupDeviceAssignment, setLegacyTeamSetupDeviceDecision, setLegacyTeamSetupProjectMapping, summarizeInboundScopeRejections, summaryLikeSqlPredicate, supportsSyncFeature, syncScopeResetRequiredPayload, toJson, tryUpdateRetrievalDelivery, updatePeerAddresses, upsertCoordinatorGroupPreference, upsertProjectScopeSettingsMappings, validateLegacyTeamSetupCompletionManifest, validateLegacyTeamSetupCompletionManifestBinding, validateRawEvents, verifyDirectPeerSignature, verifyRecipientReviewedIntent, verifySignature, wakeRecipientPoliciesForIdentities, wakeRecipientPoliciesForProjectIdentities } from "@codemem/core";
|
|
4
4
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
5
5
|
import { Hono } from "hono";
|
|
6
6
|
import { createCipheriv, createDecipheriv, createHash, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -6360,6 +6360,23 @@ var MAX_PROJECT_MAPPING_METADATA_ROWS = 1e4;
|
|
|
6360
6360
|
var MAX_MUTATION_BODY_BYTES = 8192;
|
|
6361
6361
|
var SUMMARY_SNAPSHOT_CACHE_TTL_MS = 3e4;
|
|
6362
6362
|
var COORDINATOR_ROSTER_READ_BUDGET_MS = 6e4;
|
|
6363
|
+
function serializeCanonicalManifestMutation(store, groupId, manifest, operation) {
|
|
6364
|
+
return serializeRecipientPolicyPublicationMutation(store.db, () => {
|
|
6365
|
+
const actorIds = legacyTeamSetupCompletionActorIds(store.db, manifest);
|
|
6366
|
+
return serializeRecipientPolicyActorMutations(store.db, actorIds, () => serializeRecipientPolicyTeamMutation(store.db, manifest.team_id, () => serializeRecipientPolicyCoordinatorGroupMutation(store.db, groupId, () => operation(actorIds))));
|
|
6367
|
+
});
|
|
6368
|
+
}
|
|
6369
|
+
function finishDraftActorIds(draft) {
|
|
6370
|
+
return draft.devices.flatMap((device) => [...device.decision === "included" && device.targetIdentityId ? [device.targetIdentityId] : [], ...device.existingIdentityId ? [device.existingIdentityId] : []]);
|
|
6371
|
+
}
|
|
6372
|
+
function completionRecipientPolicyLocksHeld(actorIds) {
|
|
6373
|
+
return {
|
|
6374
|
+
publication: true,
|
|
6375
|
+
actors: actorIds,
|
|
6376
|
+
team: true,
|
|
6377
|
+
coordinatorGroup: true
|
|
6378
|
+
};
|
|
6379
|
+
}
|
|
6363
6380
|
var TEAM_SETUP_ROUTE_PREFIX = "/api/sync/team-setup/v1";
|
|
6364
6381
|
var CANDIDATE_REF_PATTERN = /^legacy-team-candidate:[0-9a-f]{32}$/u;
|
|
6365
6382
|
var DEVICE_REF_PATTERN = /^legacy-team-device-ref-v1:[0-9a-f]{64}$/u;
|
|
@@ -6405,6 +6422,47 @@ async function runCandidateMutation(db, candidateRef, operation) {
|
|
|
6405
6422
|
release();
|
|
6406
6423
|
}
|
|
6407
6424
|
}
|
|
6425
|
+
function completionFailureHandlers(options) {
|
|
6426
|
+
const handledGroupIds = /* @__PURE__ */ new Set();
|
|
6427
|
+
const reportFailure = (group, error) => {
|
|
6428
|
+
handledGroupIds.add(group.groupId);
|
|
6429
|
+
options.onFailure?.(group, error);
|
|
6430
|
+
};
|
|
6431
|
+
const handleFailure = (group, error) => {
|
|
6432
|
+
if (!options.isolateApplyFailures) throw error;
|
|
6433
|
+
reportFailure(group, error);
|
|
6434
|
+
};
|
|
6435
|
+
return {
|
|
6436
|
+
handledGroupIds,
|
|
6437
|
+
handleFailure,
|
|
6438
|
+
reportFailure
|
|
6439
|
+
};
|
|
6440
|
+
}
|
|
6441
|
+
function completionConflictError(cause) {
|
|
6442
|
+
return new Error("team_setup_completion_conflict", { cause });
|
|
6443
|
+
}
|
|
6444
|
+
function addFreshCompletionGroups(index, groups, keyOf) {
|
|
6445
|
+
for (const group of groups) {
|
|
6446
|
+
if (!group) continue;
|
|
6447
|
+
const key = keyOf(group);
|
|
6448
|
+
if (index.has(key)) throw new Error("team_setup_completion_invalid");
|
|
6449
|
+
index.set(key, group);
|
|
6450
|
+
}
|
|
6451
|
+
}
|
|
6452
|
+
function groupCompletionFailureHandler(groups, handleFailure) {
|
|
6453
|
+
return (groupId, error) => {
|
|
6454
|
+
const group = groups.get(groupId);
|
|
6455
|
+
if (group) handleFailure(group, error);
|
|
6456
|
+
};
|
|
6457
|
+
}
|
|
6458
|
+
function summaryReconciliationOptions(blockingErrors) {
|
|
6459
|
+
return {
|
|
6460
|
+
isolateApplyFailures: true,
|
|
6461
|
+
onFailure: (group, error) => {
|
|
6462
|
+
blockingErrors.set(legacyTeamCandidateId(group.coordinatorId, group.groupId), apiErrorCode(new Error(completionApiError(error))));
|
|
6463
|
+
}
|
|
6464
|
+
};
|
|
6465
|
+
}
|
|
6408
6466
|
var defaultCompletionDependencies = {
|
|
6409
6467
|
create: coordinatorCreateLegacyTeamCompletionAction,
|
|
6410
6468
|
get: coordinatorGetLegacyTeamCompletionAction,
|
|
@@ -6496,13 +6554,17 @@ function isUnsupportedCompletionQuery(error) {
|
|
|
6496
6554
|
function isUnattributableCompletionBatchError(error) {
|
|
6497
6555
|
return error instanceof Error && (error.message === "coordinator_completion_response_malformed" || error.message === "coordinator_completion_group_mismatch");
|
|
6498
6556
|
}
|
|
6499
|
-
async function listCompletionRecordsPerGroup(groupIds, list) {
|
|
6500
|
-
if (groupIds.length
|
|
6557
|
+
async function listCompletionRecordsPerGroup(groupIds, list, onFailure, batchError) {
|
|
6558
|
+
if (groupIds.length === 1) {
|
|
6559
|
+
onFailure(groupIds[0], batchError);
|
|
6560
|
+
return [];
|
|
6561
|
+
}
|
|
6501
6562
|
const records = [];
|
|
6502
6563
|
for (const groupId of groupIds) try {
|
|
6503
6564
|
records.push(...await list([groupId]));
|
|
6504
6565
|
} catch (error) {
|
|
6505
6566
|
if (!isUnattributableCompletionBatchError(error)) throw error;
|
|
6567
|
+
onFailure(groupId, error);
|
|
6506
6568
|
}
|
|
6507
6569
|
return records;
|
|
6508
6570
|
}
|
|
@@ -6736,6 +6798,55 @@ function candidateFromDraft(draft) {
|
|
|
6736
6798
|
unresolvedProjectCount: draft.unresolvedProjectCount
|
|
6737
6799
|
};
|
|
6738
6800
|
}
|
|
6801
|
+
function blockedCandidateSummary(store, group, blockingError) {
|
|
6802
|
+
const candidateRef = legacyTeamCandidateId(group.coordinatorId, group.groupId);
|
|
6803
|
+
const draft = getLegacyTeamSetupDraft(store.db, candidateRef);
|
|
6804
|
+
if (draft) return {
|
|
6805
|
+
...candidateSummary(candidateFromDraft(draft)),
|
|
6806
|
+
status: "stale",
|
|
6807
|
+
blockingError
|
|
6808
|
+
};
|
|
6809
|
+
const forbiddenIds = [
|
|
6810
|
+
group.coordinatorId,
|
|
6811
|
+
group.groupId,
|
|
6812
|
+
candidateRef,
|
|
6813
|
+
...group.devices.flatMap((device) => [
|
|
6814
|
+
device.deviceId,
|
|
6815
|
+
device.fingerprint,
|
|
6816
|
+
...device.labelRedactionIds ?? []
|
|
6817
|
+
])
|
|
6818
|
+
];
|
|
6819
|
+
return {
|
|
6820
|
+
candidateRef,
|
|
6821
|
+
displayName: safeChoiceLabel(group.displayName, "Legacy Team", forbiddenIds),
|
|
6822
|
+
status: "stale",
|
|
6823
|
+
blockingError,
|
|
6824
|
+
deviceCount: group.devices.length,
|
|
6825
|
+
projectCount: 0,
|
|
6826
|
+
unresolvedDeviceCount: 0,
|
|
6827
|
+
unresolvedProjectCount: 0
|
|
6828
|
+
};
|
|
6829
|
+
}
|
|
6830
|
+
function pendingCandidateSummaries(store, groups, blockingErrors) {
|
|
6831
|
+
const pending = readPureCandidateViews(store, groups.filter((group) => !blockingErrors.has(legacyTeamCandidateId(group.coordinatorId, group.groupId)))).map(candidateSummary).filter((candidate) => candidate.status !== "ready");
|
|
6832
|
+
const blocked = groups.flatMap((group) => {
|
|
6833
|
+
const error = blockingErrors.get(legacyTeamCandidateId(group.coordinatorId, group.groupId));
|
|
6834
|
+
return error ? [blockedCandidateSummary(store, group, error)] : [];
|
|
6835
|
+
});
|
|
6836
|
+
return [...pending, ...blocked].toSorted((left, right) => {
|
|
6837
|
+
if (left.candidateRef < right.candidateRef) return -1;
|
|
6838
|
+
return left.candidateRef > right.candidateRef ? 1 : 0;
|
|
6839
|
+
});
|
|
6840
|
+
}
|
|
6841
|
+
async function reconcileSummaryCandidates(store, groups, reconcile) {
|
|
6842
|
+
readPureCandidateViews(store, groups);
|
|
6843
|
+
const blockingErrors = /* @__PURE__ */ new Map();
|
|
6844
|
+
await reconcile(store, groups, summaryReconciliationOptions(blockingErrors));
|
|
6845
|
+
return {
|
|
6846
|
+
version: TEAM_SETUP_VERSION,
|
|
6847
|
+
candidates: pendingCandidateSummaries(store, groups, blockingErrors)
|
|
6848
|
+
};
|
|
6849
|
+
}
|
|
6739
6850
|
function readPureCandidateViews(store, groups) {
|
|
6740
6851
|
const existing = [];
|
|
6741
6852
|
const discoverable = [];
|
|
@@ -7100,6 +7211,20 @@ function apiErrorCode(error) {
|
|
|
7100
7211
|
const code = legacyTeamSetupApiErrorCode(error);
|
|
7101
7212
|
return code === "team_setup_projection_changed" ? "team_setup_conflict" : code;
|
|
7102
7213
|
}
|
|
7214
|
+
/**
|
|
7215
|
+
* Maps a setup failure to its API code and logs the internal check that raised
|
|
7216
|
+
* it. Dozens of checks share each public code, so the log is the only place an
|
|
7217
|
+
* operator can see which one failed.
|
|
7218
|
+
*/
|
|
7219
|
+
function teamSetupFailure(error, route) {
|
|
7220
|
+
const code = apiErrorCode(error);
|
|
7221
|
+
const check = legacyTeamSetupFailureCheck(error);
|
|
7222
|
+
console.warn(`[team-setup] route=${route} apiCode=${code}${check ? ` check=${check}` : ""}`);
|
|
7223
|
+
return {
|
|
7224
|
+
code,
|
|
7225
|
+
status: errorStatus$1(code)
|
|
7226
|
+
};
|
|
7227
|
+
}
|
|
7103
7228
|
function completionApiError(error) {
|
|
7104
7229
|
const code = legacyTeamSetupApiErrorCode(error);
|
|
7105
7230
|
return code === "team_setup_failed" ? "team_setup_completion_unavailable" : code;
|
|
@@ -7438,29 +7563,26 @@ function teamSetupRoutes(options) {
|
|
|
7438
7563
|
*/
|
|
7439
7564
|
async function applyCanonicalManifestIfStillAuthorized(store, authorization, group, manifest, freshRoster) {
|
|
7440
7565
|
let outcome = "unauthorized";
|
|
7441
|
-
return await runCandidateMutation(store.db, legacyTeamCandidateId(group.coordinatorId, group.groupId), () =>
|
|
7566
|
+
return await runCandidateMutation(store.db, legacyTeamCandidateId(group.coordinatorId, group.groupId), () => serializeCanonicalManifestMutation(store, group.groupId, manifest, async (actorIds) => {
|
|
7442
7567
|
if (!stillAuthorizesGroup(authorization, group)) return;
|
|
7443
7568
|
await applyLegacyTeamSetupCompletionManifest(store.db, {
|
|
7444
7569
|
coordinatorId: group.coordinatorId,
|
|
7445
7570
|
groupId: group.groupId,
|
|
7446
7571
|
manifest,
|
|
7447
7572
|
freshRoster,
|
|
7448
|
-
recipientPolicyLocksHeld:
|
|
7449
|
-
publication: true,
|
|
7450
|
-
team: true,
|
|
7451
|
-
coordinatorGroup: true
|
|
7452
|
-
}
|
|
7573
|
+
recipientPolicyLocksHeld: completionRecipientPolicyLocksHeld(actorIds)
|
|
7453
7574
|
});
|
|
7454
7575
|
outcome = "applied";
|
|
7455
|
-
}))
|
|
7576
|
+
})) ? outcome : "claimed";
|
|
7456
7577
|
}
|
|
7457
7578
|
async function reconcileCompletions(store, groups, reconciliationOptions = {}) {
|
|
7579
|
+
const { handledGroupIds, handleFailure, reportFailure } = completionFailureHandlers(reconciliationOptions);
|
|
7458
7580
|
if (!completionDependencies || groups.length === 0) return;
|
|
7459
7581
|
let authorization;
|
|
7460
7582
|
try {
|
|
7461
7583
|
authorization = currentCompletionAuthorization();
|
|
7462
7584
|
} catch (error) {
|
|
7463
|
-
throw new Error(completionApiError(error));
|
|
7585
|
+
throw new Error(completionApiError(error), { cause: error });
|
|
7464
7586
|
}
|
|
7465
7587
|
if (!authorization) return;
|
|
7466
7588
|
const { config, remoteUrl } = authorization;
|
|
@@ -7482,30 +7604,25 @@ function teamSetupRoutes(options) {
|
|
|
7482
7604
|
records = await listCompletionRecords(scopedGroupIds);
|
|
7483
7605
|
} catch (error) {
|
|
7484
7606
|
if (isUnsupportedCompletionQuery(error)) records = [];
|
|
7485
|
-
else if (reconciliationOptions.isolateApplyFailures && isUnattributableCompletionBatchError(error)) records = await listCompletionRecordsPerGroup(scopedGroupIds, listCompletionRecords);
|
|
7607
|
+
else if (reconciliationOptions.isolateApplyFailures && isUnattributableCompletionBatchError(error)) records = await listCompletionRecordsPerGroup(scopedGroupIds, listCompletionRecords, groupCompletionFailureHandler(groupById, handleFailure), error);
|
|
7486
7608
|
else throw error;
|
|
7487
7609
|
}
|
|
7488
7610
|
const freshGroupByKey = /* @__PURE__ */ new Map();
|
|
7489
7611
|
if (records.length > 0) try {
|
|
7490
7612
|
const onlyGroup = scopedGroups.length === 1 ? scopedGroups[0] : void 0;
|
|
7491
|
-
|
|
7492
|
-
for (const freshGroup of freshGroups) {
|
|
7493
|
-
if (!freshGroup) continue;
|
|
7494
|
-
const key = freshGroupKey(freshGroup);
|
|
7495
|
-
if (freshGroupByKey.has(key)) throw new Error("team_setup_completion_invalid");
|
|
7496
|
-
freshGroupByKey.set(key, freshGroup);
|
|
7497
|
-
}
|
|
7613
|
+
addFreshCompletionGroups(freshGroupByKey, onlyGroup ? [await loadFreshGroupSnapshot(onlyGroup, remoteUrl, reconciliationDeadlineMs)] : await loadedSnapshots(void 0, reconciliationDeadlineMs), freshGroupKey);
|
|
7498
7614
|
} catch (error) {
|
|
7499
7615
|
for (const record of records) {
|
|
7500
7616
|
const group = groupById.get(record.group_id);
|
|
7501
7617
|
if (!group || !belongsToGroupCandidate(record, group)) continue;
|
|
7618
|
+
reportFailure(group, error);
|
|
7502
7619
|
try {
|
|
7503
7620
|
validateLegacyTeamSetupCompletionManifestBinding(record.manifest, {
|
|
7504
7621
|
coordinatorId: group.coordinatorId,
|
|
7505
7622
|
groupId: group.groupId
|
|
7506
7623
|
});
|
|
7507
7624
|
} catch (bindingError) {
|
|
7508
|
-
|
|
7625
|
+
handleFailure(group, bindingError);
|
|
7509
7626
|
continue;
|
|
7510
7627
|
}
|
|
7511
7628
|
let canonicalManifest;
|
|
@@ -7515,16 +7632,17 @@ function teamSetupRoutes(options) {
|
|
|
7515
7632
|
groupId: group.groupId
|
|
7516
7633
|
});
|
|
7517
7634
|
} catch (validationError) {
|
|
7635
|
+
reportFailure(group, validationError);
|
|
7518
7636
|
try {
|
|
7519
7637
|
if (!await runCandidateMutation(store.db, legacyTeamCandidateId(group.coordinatorId, group.groupId), () => containLegacyTeamSetupCompletionConflict(store.db, {
|
|
7520
7638
|
coordinatorId: group.coordinatorId,
|
|
7521
7639
|
groupId: group.groupId
|
|
7522
7640
|
}))) {
|
|
7523
|
-
|
|
7641
|
+
handleFailure(group, validationError);
|
|
7524
7642
|
continue;
|
|
7525
7643
|
}
|
|
7526
7644
|
} catch (containmentError) {
|
|
7527
|
-
|
|
7645
|
+
handleFailure(group, containmentError);
|
|
7528
7646
|
}
|
|
7529
7647
|
if (!reconciliationOptions.isolateApplyFailures) throw validationError;
|
|
7530
7648
|
continue;
|
|
@@ -7540,13 +7658,12 @@ function teamSetupRoutes(options) {
|
|
|
7540
7658
|
groupId: group.groupId
|
|
7541
7659
|
}));
|
|
7542
7660
|
} catch (containmentError) {
|
|
7543
|
-
|
|
7661
|
+
handleFailure(group, containmentError);
|
|
7544
7662
|
}
|
|
7545
7663
|
}
|
|
7546
7664
|
if (!reconciliationOptions.isolateApplyFailures) throw error;
|
|
7547
7665
|
return;
|
|
7548
7666
|
}
|
|
7549
|
-
const coordinatorCompletionGroupIds = /* @__PURE__ */ new Set();
|
|
7550
7667
|
for (const record of records) {
|
|
7551
7668
|
const group = groupById.get(record.group_id);
|
|
7552
7669
|
if (!group) throw new Error("team_setup_completion_invalid");
|
|
@@ -7557,7 +7674,7 @@ function teamSetupRoutes(options) {
|
|
|
7557
7674
|
groupId: group.groupId
|
|
7558
7675
|
});
|
|
7559
7676
|
} catch (bindingError) {
|
|
7560
|
-
|
|
7677
|
+
handleFailure(group, bindingError);
|
|
7561
7678
|
continue;
|
|
7562
7679
|
}
|
|
7563
7680
|
let canonicalManifest;
|
|
@@ -7567,18 +7684,19 @@ function teamSetupRoutes(options) {
|
|
|
7567
7684
|
groupId: group.groupId
|
|
7568
7685
|
});
|
|
7569
7686
|
} catch (validationError) {
|
|
7687
|
+
reportFailure(group, validationError);
|
|
7570
7688
|
try {
|
|
7571
7689
|
await runCandidateMutation(store.db, legacyTeamCandidateId(group.coordinatorId, group.groupId), () => containLegacyTeamSetupCompletionConflict(store.db, {
|
|
7572
7690
|
coordinatorId: group.coordinatorId,
|
|
7573
7691
|
groupId: group.groupId
|
|
7574
7692
|
}));
|
|
7575
7693
|
} catch (containmentError) {
|
|
7576
|
-
|
|
7694
|
+
handleFailure(group, containmentError);
|
|
7577
7695
|
}
|
|
7578
7696
|
if (!reconciliationOptions.isolateApplyFailures) throw validationError;
|
|
7579
7697
|
continue;
|
|
7580
7698
|
}
|
|
7581
|
-
|
|
7699
|
+
handledGroupIds.add(record.group_id);
|
|
7582
7700
|
try {
|
|
7583
7701
|
let freshGroup = freshGroupByKey.get(freshGroupKey(group));
|
|
7584
7702
|
if (!freshGroup && scopedGroups.length > 1) {
|
|
@@ -7590,18 +7708,18 @@ function teamSetupRoutes(options) {
|
|
|
7590
7708
|
coordinatorId: group.coordinatorId,
|
|
7591
7709
|
groupId: group.groupId
|
|
7592
7710
|
}))) {
|
|
7593
|
-
|
|
7711
|
+
handleFailure(group, /* @__PURE__ */ new Error("team_setup_completion_invalid"));
|
|
7594
7712
|
continue;
|
|
7595
7713
|
}
|
|
7596
7714
|
throw new Error("team_setup_completion_invalid");
|
|
7597
7715
|
}
|
|
7598
7716
|
if (await applyCanonicalManifestIfStillAuthorized(store, authorization, group, canonicalManifest, freshGroup.devices) !== "applied") continue;
|
|
7599
7717
|
} catch (error) {
|
|
7600
|
-
|
|
7718
|
+
handleFailure(group, error);
|
|
7601
7719
|
}
|
|
7602
7720
|
}
|
|
7603
7721
|
for (const group of scopedGroups) {
|
|
7604
|
-
if (
|
|
7722
|
+
if (handledGroupIds.has(group.groupId)) continue;
|
|
7605
7723
|
const publicationTimeoutS = remainingCoordinatorTimeoutS(timeoutS, reconciliationDeadlineMs);
|
|
7606
7724
|
if (publicationTimeoutS == null) break;
|
|
7607
7725
|
if (!hasCompletedLegacyTeamSetup(store, legacyTeamCandidateId(group.coordinatorId, group.groupId))) continue;
|
|
@@ -7648,14 +7766,14 @@ function teamSetupRoutes(options) {
|
|
|
7648
7766
|
coordinatorId: group.coordinatorId,
|
|
7649
7767
|
groupId: group.groupId
|
|
7650
7768
|
}))) {
|
|
7651
|
-
|
|
7769
|
+
handleFailure(group, /* @__PURE__ */ new Error("team_setup_completion_conflict"));
|
|
7652
7770
|
continue;
|
|
7653
7771
|
}
|
|
7654
7772
|
} catch (containmentError) {
|
|
7655
|
-
|
|
7773
|
+
handleFailure(group, containmentError);
|
|
7656
7774
|
continue;
|
|
7657
7775
|
}
|
|
7658
|
-
|
|
7776
|
+
handleFailure(group, /* @__PURE__ */ new Error("team_setup_completion_conflict"));
|
|
7659
7777
|
continue;
|
|
7660
7778
|
}
|
|
7661
7779
|
try {
|
|
@@ -7664,7 +7782,7 @@ function teamSetupRoutes(options) {
|
|
|
7664
7782
|
if (await applyCanonicalManifestIfStillAuthorized(store, authorization, group, canonicalManifest, freshGroup.devices) !== "applied") continue;
|
|
7665
7783
|
} catch (applyError) {
|
|
7666
7784
|
if (applyError instanceof LegacyTeamSetupAdditiveConvergenceError) {
|
|
7667
|
-
|
|
7785
|
+
handleFailure(group, applyError);
|
|
7668
7786
|
continue;
|
|
7669
7787
|
}
|
|
7670
7788
|
try {
|
|
@@ -7672,19 +7790,19 @@ function teamSetupRoutes(options) {
|
|
|
7672
7790
|
coordinatorId: group.coordinatorId,
|
|
7673
7791
|
groupId: group.groupId
|
|
7674
7792
|
}))) {
|
|
7675
|
-
|
|
7793
|
+
handleFailure(group, completionConflictError(applyError));
|
|
7676
7794
|
continue;
|
|
7677
7795
|
}
|
|
7678
7796
|
} catch (containmentError) {
|
|
7679
|
-
|
|
7797
|
+
handleFailure(group, containmentError);
|
|
7680
7798
|
continue;
|
|
7681
7799
|
}
|
|
7682
|
-
|
|
7800
|
+
handleFailure(group, completionConflictError(applyError));
|
|
7683
7801
|
}
|
|
7684
7802
|
}
|
|
7685
7803
|
}
|
|
7686
7804
|
} catch (error) {
|
|
7687
|
-
throw new Error(completionApiError(error));
|
|
7805
|
+
throw new Error(completionApiError(error), { cause: error });
|
|
7688
7806
|
}
|
|
7689
7807
|
}
|
|
7690
7808
|
async function loadedCandidateSnapshots(candidateRef, loadOptions = {}) {
|
|
@@ -7718,21 +7836,15 @@ function teamSetupRoutes(options) {
|
|
|
7718
7836
|
try {
|
|
7719
7837
|
groups = await loadedSummarySnapshots();
|
|
7720
7838
|
} catch (error) {
|
|
7721
|
-
const
|
|
7722
|
-
return c.json({ error: code },
|
|
7839
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7840
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7723
7841
|
}
|
|
7724
7842
|
try {
|
|
7725
|
-
const
|
|
7726
|
-
readPureCandidateViews(store, groups);
|
|
7727
|
-
await reconcileCompletions(store, groups, { isolateApplyFailures: true });
|
|
7728
|
-
const response = {
|
|
7729
|
-
version: TEAM_SETUP_VERSION,
|
|
7730
|
-
candidates: readPureCandidateViews(store, groups).map(candidateSummary).filter((candidate) => candidate.status !== "ready")
|
|
7731
|
-
};
|
|
7843
|
+
const response = await reconcileSummaryCandidates(options.getStore(), groups, reconcileCompletions);
|
|
7732
7844
|
return c.json(response);
|
|
7733
7845
|
} catch (error) {
|
|
7734
|
-
const
|
|
7735
|
-
return c.json({ error: code },
|
|
7846
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7847
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7736
7848
|
}
|
|
7737
7849
|
});
|
|
7738
7850
|
app.get("/api/sync/team-setup/v1/:candidateRef", async (c) => {
|
|
@@ -7778,8 +7890,8 @@ function teamSetupRoutes(options) {
|
|
|
7778
7890
|
if (completionGroups) candidate = candidateFromDraft(draft);
|
|
7779
7891
|
return c.json(detailResponse(store, draft, candidate));
|
|
7780
7892
|
} catch (error) {
|
|
7781
|
-
const
|
|
7782
|
-
return c.json({ error: code },
|
|
7893
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7894
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7783
7895
|
}
|
|
7784
7896
|
});
|
|
7785
7897
|
app.put("/api/sync/team-setup/v1/:candidateRef/devices/:deviceRef/assignment", async (c) => {
|
|
@@ -7824,8 +7936,8 @@ function teamSetupRoutes(options) {
|
|
|
7824
7936
|
releaseMutation();
|
|
7825
7937
|
}
|
|
7826
7938
|
} catch (error) {
|
|
7827
|
-
const
|
|
7828
|
-
return c.json({ error: code },
|
|
7939
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7940
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7829
7941
|
}
|
|
7830
7942
|
});
|
|
7831
7943
|
app.put("/api/sync/team-setup/v1/:candidateRef/devices/:deviceRef/decision", async (c) => {
|
|
@@ -7866,8 +7978,8 @@ function teamSetupRoutes(options) {
|
|
|
7866
7978
|
releaseMutation();
|
|
7867
7979
|
}
|
|
7868
7980
|
} catch (error) {
|
|
7869
|
-
const
|
|
7870
|
-
return c.json({ error: code },
|
|
7981
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7982
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7871
7983
|
}
|
|
7872
7984
|
});
|
|
7873
7985
|
app.delete("/api/sync/team-setup/v1/:candidateRef/devices/:deviceRef/decision", async (c) => {
|
|
@@ -7897,8 +8009,8 @@ function teamSetupRoutes(options) {
|
|
|
7897
8009
|
releaseMutation();
|
|
7898
8010
|
}
|
|
7899
8011
|
} catch (error) {
|
|
7900
|
-
const
|
|
7901
|
-
return c.json({ error: code },
|
|
8012
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8013
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7902
8014
|
}
|
|
7903
8015
|
});
|
|
7904
8016
|
app.put("/api/sync/team-setup/v1/:candidateRef/projects/:projectRef/mapping", async (c) => {
|
|
@@ -7933,8 +8045,8 @@ function teamSetupRoutes(options) {
|
|
|
7933
8045
|
releaseMutation();
|
|
7934
8046
|
}
|
|
7935
8047
|
} catch (error) {
|
|
7936
|
-
const
|
|
7937
|
-
return c.json({ error: code },
|
|
8048
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8049
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7938
8050
|
}
|
|
7939
8051
|
});
|
|
7940
8052
|
app.post("/api/sync/team-setup/v1/:candidateRef/refresh", async (c) => {
|
|
@@ -7947,15 +8059,15 @@ function teamSetupRoutes(options) {
|
|
|
7947
8059
|
store = options.getStore();
|
|
7948
8060
|
if (getLegacyTeamSetupDraft(store.db, candidateRef)?.state === "completed" || hasCompletedLegacyTeamSetup(store, candidateRef)) return c.json({ error: "team_setup_confirmation_stale" }, 409);
|
|
7949
8061
|
} catch (error) {
|
|
7950
|
-
const
|
|
7951
|
-
return c.json({ error: code },
|
|
8062
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8063
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7952
8064
|
}
|
|
7953
8065
|
let groups;
|
|
7954
8066
|
try {
|
|
7955
8067
|
groups = await loadMutableCandidateSnapshots(store, candidateRef, () => loadedCandidateSnapshots(candidateRef));
|
|
7956
8068
|
} catch (error) {
|
|
7957
|
-
const
|
|
7958
|
-
return c.json({ error: code },
|
|
8069
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8070
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7959
8071
|
}
|
|
7960
8072
|
if (groups.filter((group) => legacyTeamCandidateId(group.coordinatorId, group.groupId) === candidateRef).length === 0) return c.json({ error: "team_setup_confirmation_stale" }, 404);
|
|
7961
8073
|
try {
|
|
@@ -7973,8 +8085,8 @@ function teamSetupRoutes(options) {
|
|
|
7973
8085
|
releaseMutation();
|
|
7974
8086
|
}
|
|
7975
8087
|
} catch (error) {
|
|
7976
|
-
const
|
|
7977
|
-
return c.json({ error: code },
|
|
8088
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8089
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7978
8090
|
}
|
|
7979
8091
|
});
|
|
7980
8092
|
app.post("/api/sync/team-setup/v1/:candidateRef/finish", async (c) => {
|
|
@@ -8046,13 +8158,14 @@ function teamSetupRoutes(options) {
|
|
|
8046
8158
|
if (!claimedDraft || claimedDraft.attemptId !== attemptId) return c.json({ error: "team_setup_confirmation_stale" }, 409);
|
|
8047
8159
|
const publicationDeadlineMs = Date.now() + COORDINATOR_ROSTER_READ_BUDGET_MS;
|
|
8048
8160
|
releasePublicationMutation = await claimRecipientPolicyPublicationMutation(store.db);
|
|
8049
|
-
|
|
8161
|
+
const claimedActorIds = finishDraftActorIds(claimedDraft);
|
|
8162
|
+
releaseActorMutations = await claimRecipientPolicyActorMutations(store.db, claimedActorIds);
|
|
8050
8163
|
return await serializeRecipientPolicyTeamMutation(store.db, deterministicPolicyTeamId(candidateRef), () => serializeRecipientPolicyCoordinatorGroupMutation(store.db, group.groupId, async () => {
|
|
8051
8164
|
let authorization;
|
|
8052
8165
|
try {
|
|
8053
8166
|
authorization = currentCompletionAuthorization();
|
|
8054
8167
|
} catch (error) {
|
|
8055
|
-
throw new Error(completionApiError(error));
|
|
8168
|
+
throw new Error(completionApiError(error), { cause: error });
|
|
8056
8169
|
}
|
|
8057
8170
|
if (!completionDependencies || !authorization) throw new Error("team_setup_completion_unavailable");
|
|
8058
8171
|
if (!authorizesGroup(authorization, group)) throw new Error("team_setup_completion_invalid");
|
|
@@ -8143,11 +8256,7 @@ function teamSetupRoutes(options) {
|
|
|
8143
8256
|
freshRoster: postPublicationGroup.devices,
|
|
8144
8257
|
manifest: canonicalManifest,
|
|
8145
8258
|
expectedDraftManifest: proposedManifest,
|
|
8146
|
-
recipientPolicyLocksHeld:
|
|
8147
|
-
publication: true,
|
|
8148
|
-
team: true,
|
|
8149
|
-
coordinatorGroup: true
|
|
8150
|
-
}
|
|
8259
|
+
recipientPolicyLocksHeld: completionRecipientPolicyLocksHeld(claimedActorIds)
|
|
8151
8260
|
});
|
|
8152
8261
|
return c.json(finishResponse(candidateRef, result));
|
|
8153
8262
|
}));
|